API: Use string type instead of u8.
[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 = vl_api_string_len (&mp->reply);
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),
1117                    vl_api_from_api_string (&mp->reply), length);
1118       vam->cmd_reply[length] = 0;
1119     }
1120   vam->result_ready = 1;
1121 }
1122
1123 static void
1124 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1125 {
1126   vat_main_t *vam = &vat_main;
1127   vat_json_node_t node;
1128
1129   vec_reset_length (vam->cmd_reply);
1130
1131   vat_json_init_object (&node);
1132   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1133   vat_json_object_add_string_copy (&node, "reply",
1134                                    vl_api_from_api_string (&mp->reply));
1135
1136   vat_json_print (vam->ofp, &node);
1137   vat_json_free (&node);
1138
1139   vam->retval = ntohl (mp->retval);
1140   vam->result_ready = 1;
1141 }
1142
1143 static void vl_api_classify_add_del_table_reply_t_handler
1144   (vl_api_classify_add_del_table_reply_t * mp)
1145 {
1146   vat_main_t *vam = &vat_main;
1147   i32 retval = ntohl (mp->retval);
1148   if (vam->async_mode)
1149     {
1150       vam->async_errors += (retval < 0);
1151     }
1152   else
1153     {
1154       vam->retval = retval;
1155       if (retval == 0 &&
1156           ((mp->new_table_index != 0xFFFFFFFF) ||
1157            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1158            (mp->match_n_vectors != 0xFFFFFFFF)))
1159         /*
1160          * Note: this is just barely thread-safe, depends on
1161          * the main thread spinning waiting for an answer...
1162          */
1163         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1164                 ntohl (mp->new_table_index),
1165                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1166       vam->result_ready = 1;
1167     }
1168 }
1169
1170 static void vl_api_classify_add_del_table_reply_t_handler_json
1171   (vl_api_classify_add_del_table_reply_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   vat_json_node_t node;
1175
1176   vat_json_init_object (&node);
1177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1178   vat_json_object_add_uint (&node, "new_table_index",
1179                             ntohl (mp->new_table_index));
1180   vat_json_object_add_uint (&node, "skip_n_vectors",
1181                             ntohl (mp->skip_n_vectors));
1182   vat_json_object_add_uint (&node, "match_n_vectors",
1183                             ntohl (mp->match_n_vectors));
1184
1185   vat_json_print (vam->ofp, &node);
1186   vat_json_free (&node);
1187
1188   vam->retval = ntohl (mp->retval);
1189   vam->result_ready = 1;
1190 }
1191
1192 static void vl_api_get_node_index_reply_t_handler
1193   (vl_api_get_node_index_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   i32 retval = ntohl (mp->retval);
1197   if (vam->async_mode)
1198     {
1199       vam->async_errors += (retval < 0);
1200     }
1201   else
1202     {
1203       vam->retval = retval;
1204       if (retval == 0)
1205         errmsg ("node index %d", ntohl (mp->node_index));
1206       vam->result_ready = 1;
1207     }
1208 }
1209
1210 static void vl_api_get_node_index_reply_t_handler_json
1211   (vl_api_get_node_index_reply_t * mp)
1212 {
1213   vat_main_t *vam = &vat_main;
1214   vat_json_node_t node;
1215
1216   vat_json_init_object (&node);
1217   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1218   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1219
1220   vat_json_print (vam->ofp, &node);
1221   vat_json_free (&node);
1222
1223   vam->retval = ntohl (mp->retval);
1224   vam->result_ready = 1;
1225 }
1226
1227 static void vl_api_get_next_index_reply_t_handler
1228   (vl_api_get_next_index_reply_t * mp)
1229 {
1230   vat_main_t *vam = &vat_main;
1231   i32 retval = ntohl (mp->retval);
1232   if (vam->async_mode)
1233     {
1234       vam->async_errors += (retval < 0);
1235     }
1236   else
1237     {
1238       vam->retval = retval;
1239       if (retval == 0)
1240         errmsg ("next node index %d", ntohl (mp->next_index));
1241       vam->result_ready = 1;
1242     }
1243 }
1244
1245 static void vl_api_get_next_index_reply_t_handler_json
1246   (vl_api_get_next_index_reply_t * mp)
1247 {
1248   vat_main_t *vam = &vat_main;
1249   vat_json_node_t node;
1250
1251   vat_json_init_object (&node);
1252   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1253   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1254
1255   vat_json_print (vam->ofp, &node);
1256   vat_json_free (&node);
1257
1258   vam->retval = ntohl (mp->retval);
1259   vam->result_ready = 1;
1260 }
1261
1262 static void vl_api_add_node_next_reply_t_handler
1263   (vl_api_add_node_next_reply_t * mp)
1264 {
1265   vat_main_t *vam = &vat_main;
1266   i32 retval = ntohl (mp->retval);
1267   if (vam->async_mode)
1268     {
1269       vam->async_errors += (retval < 0);
1270     }
1271   else
1272     {
1273       vam->retval = retval;
1274       if (retval == 0)
1275         errmsg ("next index %d", ntohl (mp->next_index));
1276       vam->result_ready = 1;
1277     }
1278 }
1279
1280 static void vl_api_add_node_next_reply_t_handler_json
1281   (vl_api_add_node_next_reply_t * mp)
1282 {
1283   vat_main_t *vam = &vat_main;
1284   vat_json_node_t node;
1285
1286   vat_json_init_object (&node);
1287   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1288   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1289
1290   vat_json_print (vam->ofp, &node);
1291   vat_json_free (&node);
1292
1293   vam->retval = ntohl (mp->retval);
1294   vam->result_ready = 1;
1295 }
1296
1297 static void vl_api_show_version_reply_t_handler
1298   (vl_api_show_version_reply_t * mp)
1299 {
1300   vat_main_t *vam = &vat_main;
1301   i32 retval = ntohl (mp->retval);
1302
1303   if (retval >= 0)
1304     {
1305       char *p = (char *) &mp->program;
1306       errmsg ("        program: %s\n",
1307               vl_api_from_api_string ((vl_api_string_t *) p));
1308       p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1309       errmsg ("        version: %s\n",
1310               vl_api_from_api_string ((vl_api_string_t *) p));
1311       p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1312       errmsg ("     build date: %s\n",
1313               vl_api_from_api_string ((vl_api_string_t *) p));
1314       p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1315       errmsg ("build directory: %s\n",
1316               vl_api_from_api_string ((vl_api_string_t *) p));
1317     }
1318   vam->retval = retval;
1319   vam->result_ready = 1;
1320 }
1321
1322 static void vl_api_show_version_reply_t_handler_json
1323   (vl_api_show_version_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   vat_json_node_t node;
1327
1328   vat_json_init_object (&node);
1329   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1330   char *p = (char *) &mp->program;
1331   vat_json_object_add_string_copy (&node, "program",
1332                                    vl_api_from_api_string ((vl_api_string_t *)
1333                                                            p));
1334   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1335   vat_json_object_add_string_copy (&node, "version",
1336                                    vl_api_from_api_string ((vl_api_string_t *)
1337                                                            p));
1338   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1339   vat_json_object_add_string_copy (&node, "build_date",
1340                                    vl_api_from_api_string ((vl_api_string_t *)
1341                                                            p));
1342   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1343   vat_json_object_add_string_copy (&node, "build_directory",
1344                                    vl_api_from_api_string ((vl_api_string_t *)
1345                                                            p));
1346
1347   vat_json_print (vam->ofp, &node);
1348   vat_json_free (&node);
1349
1350   vam->retval = ntohl (mp->retval);
1351   vam->result_ready = 1;
1352 }
1353
1354 static void vl_api_show_threads_reply_t_handler
1355   (vl_api_show_threads_reply_t * mp)
1356 {
1357   vat_main_t *vam = &vat_main;
1358   i32 retval = ntohl (mp->retval);
1359   int i, count = 0;
1360
1361   if (retval >= 0)
1362     count = ntohl (mp->count);
1363
1364   for (i = 0; i < count; i++)
1365     print (vam->ofp,
1366            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1367            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1368            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1369            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1370            ntohl (mp->thread_data[i].cpu_socket));
1371
1372   vam->retval = retval;
1373   vam->result_ready = 1;
1374 }
1375
1376 static void vl_api_show_threads_reply_t_handler_json
1377   (vl_api_show_threads_reply_t * mp)
1378 {
1379   vat_main_t *vam = &vat_main;
1380   vat_json_node_t node;
1381   vl_api_thread_data_t *td;
1382   i32 retval = ntohl (mp->retval);
1383   int i, count = 0;
1384
1385   if (retval >= 0)
1386     count = ntohl (mp->count);
1387
1388   vat_json_init_object (&node);
1389   vat_json_object_add_int (&node, "retval", retval);
1390   vat_json_object_add_uint (&node, "count", count);
1391
1392   for (i = 0; i < count; i++)
1393     {
1394       td = &mp->thread_data[i];
1395       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1396       vat_json_object_add_string_copy (&node, "name", td->name);
1397       vat_json_object_add_string_copy (&node, "type", td->type);
1398       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1399       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1400       vat_json_object_add_int (&node, "core", ntohl (td->id));
1401       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1402     }
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = retval;
1408   vam->result_ready = 1;
1409 }
1410
1411 static int
1412 api_show_threads (vat_main_t * vam)
1413 {
1414   vl_api_show_threads_t *mp;
1415   int ret;
1416
1417   print (vam->ofp,
1418          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1419          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1420
1421   M (SHOW_THREADS, mp);
1422
1423   S (mp);
1424   W (ret);
1425   return ret;
1426 }
1427
1428 static void
1429 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1430 {
1431   u32 sw_if_index = ntohl (mp->sw_if_index);
1432   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1433           mp->mac_ip ? "mac/ip binding" : "address resolution",
1434           ntohl (mp->pid), format_ip4_address, &mp->address,
1435           format_ethernet_address, mp->new_mac, sw_if_index);
1436 }
1437
1438 static void
1439 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1440 {
1441   /* JSON output not supported */
1442 }
1443
1444 static void
1445 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1446 {
1447   u32 sw_if_index = ntohl (mp->sw_if_index);
1448   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1449           mp->mac_ip ? "mac/ip binding" : "address resolution",
1450           ntohl (mp->pid), format_ip6_address, mp->address,
1451           format_ethernet_address, mp->new_mac, sw_if_index);
1452 }
1453
1454 static void
1455 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1456 {
1457   /* JSON output not supported */
1458 }
1459
1460 static void
1461 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1462 {
1463   u32 n_macs = ntohl (mp->n_macs);
1464   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1465           ntohl (mp->pid), mp->client_index, n_macs);
1466   int i;
1467   for (i = 0; i < n_macs; i++)
1468     {
1469       vl_api_mac_entry_t *mac = &mp->mac[i];
1470       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1471               i + 1, ntohl (mac->sw_if_index),
1472               format_ethernet_address, mac->mac_addr, mac->action);
1473       if (i == 1000)
1474         break;
1475     }
1476 }
1477
1478 static void
1479 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1480 {
1481   /* JSON output not supported */
1482 }
1483
1484 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1485 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1486
1487 /*
1488  * Special-case: build the bridge domain table, maintain
1489  * the next bd id vbl.
1490  */
1491 static void vl_api_bridge_domain_details_t_handler
1492   (vl_api_bridge_domain_details_t * mp)
1493 {
1494   vat_main_t *vam = &vat_main;
1495   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1496   int i;
1497
1498   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1499          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1500
1501   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1502          ntohl (mp->bd_id), mp->learn, mp->forward,
1503          mp->flood, ntohl (mp->bvi_sw_if_index),
1504          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1505
1506   if (n_sw_ifs)
1507     {
1508       vl_api_bridge_domain_sw_if_t *sw_ifs;
1509       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1510              "Interface Name");
1511
1512       sw_ifs = mp->sw_if_details;
1513       for (i = 0; i < n_sw_ifs; i++)
1514         {
1515           u8 *sw_if_name = 0;
1516           u32 sw_if_index;
1517           hash_pair_t *p;
1518
1519           sw_if_index = ntohl (sw_ifs->sw_if_index);
1520
1521           /* *INDENT-OFF* */
1522           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1523                              ({
1524                                if ((u32) p->value[0] == sw_if_index)
1525                                  {
1526                                    sw_if_name = (u8 *)(p->key);
1527                                    break;
1528                                  }
1529                              }));
1530           /* *INDENT-ON* */
1531           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1532                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1533                  "sw_if_index not found!");
1534
1535           sw_ifs++;
1536         }
1537     }
1538 }
1539
1540 static void vl_api_bridge_domain_details_t_handler_json
1541   (vl_api_bridge_domain_details_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   vat_json_node_t *node, *array = NULL;
1545   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1546
1547   if (VAT_JSON_ARRAY != vam->json_tree.type)
1548     {
1549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1550       vat_json_init_array (&vam->json_tree);
1551     }
1552   node = vat_json_array_add (&vam->json_tree);
1553
1554   vat_json_init_object (node);
1555   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1556   vat_json_object_add_uint (node, "flood", mp->flood);
1557   vat_json_object_add_uint (node, "forward", mp->forward);
1558   vat_json_object_add_uint (node, "learn", mp->learn);
1559   vat_json_object_add_uint (node, "bvi_sw_if_index",
1560                             ntohl (mp->bvi_sw_if_index));
1561   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1562   array = vat_json_object_add (node, "sw_if");
1563   vat_json_init_array (array);
1564
1565
1566
1567   if (n_sw_ifs)
1568     {
1569       vl_api_bridge_domain_sw_if_t *sw_ifs;
1570       int i;
1571
1572       sw_ifs = mp->sw_if_details;
1573       for (i = 0; i < n_sw_ifs; i++)
1574         {
1575           node = vat_json_array_add (array);
1576           vat_json_init_object (node);
1577           vat_json_object_add_uint (node, "sw_if_index",
1578                                     ntohl (sw_ifs->sw_if_index));
1579           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1580           sw_ifs++;
1581         }
1582     }
1583 }
1584
1585 static void vl_api_control_ping_reply_t_handler
1586   (vl_api_control_ping_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   i32 retval = ntohl (mp->retval);
1590   if (vam->async_mode)
1591     {
1592       vam->async_errors += (retval < 0);
1593     }
1594   else
1595     {
1596       vam->retval = retval;
1597       vam->result_ready = 1;
1598     }
1599   if (vam->socket_client_main)
1600     vam->socket_client_main->control_pings_outstanding--;
1601 }
1602
1603 static void vl_api_control_ping_reply_t_handler_json
1604   (vl_api_control_ping_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   i32 retval = ntohl (mp->retval);
1608
1609   if (VAT_JSON_NONE != vam->json_tree.type)
1610     {
1611       vat_json_print (vam->ofp, &vam->json_tree);
1612       vat_json_free (&vam->json_tree);
1613       vam->json_tree.type = VAT_JSON_NONE;
1614     }
1615   else
1616     {
1617       /* just print [] */
1618       vat_json_init_array (&vam->json_tree);
1619       vat_json_print (vam->ofp, &vam->json_tree);
1620       vam->json_tree.type = VAT_JSON_NONE;
1621     }
1622
1623   vam->retval = retval;
1624   vam->result_ready = 1;
1625 }
1626
1627 static void
1628   vl_api_bridge_domain_set_mac_age_reply_t_handler
1629   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   i32 retval = ntohl (mp->retval);
1633   if (vam->async_mode)
1634     {
1635       vam->async_errors += (retval < 0);
1636     }
1637   else
1638     {
1639       vam->retval = retval;
1640       vam->result_ready = 1;
1641     }
1642 }
1643
1644 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1645   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   vat_json_node_t node;
1649
1650   vat_json_init_object (&node);
1651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void
1661 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_l2_flags_reply_t_handler_json
1677   (vl_api_l2_flags_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1685                             ntohl (mp->resulting_feature_bitmap));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void vl_api_bridge_flags_reply_t_handler
1695   (vl_api_bridge_flags_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   i32 retval = ntohl (mp->retval);
1699   if (vam->async_mode)
1700     {
1701       vam->async_errors += (retval < 0);
1702     }
1703   else
1704     {
1705       vam->retval = retval;
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_bridge_flags_reply_t_handler_json
1711   (vl_api_bridge_flags_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1719                             ntohl (mp->resulting_feature_bitmap));
1720
1721   vat_json_print (vam->ofp, &node);
1722   vat_json_free (&node);
1723
1724   vam->retval = ntohl (mp->retval);
1725   vam->result_ready = 1;
1726 }
1727
1728 static void vl_api_tap_connect_reply_t_handler
1729   (vl_api_tap_connect_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   i32 retval = ntohl (mp->retval);
1733   if (vam->async_mode)
1734     {
1735       vam->async_errors += (retval < 0);
1736     }
1737   else
1738     {
1739       vam->retval = retval;
1740       vam->sw_if_index = ntohl (mp->sw_if_index);
1741       vam->result_ready = 1;
1742     }
1743
1744 }
1745
1746 static void vl_api_tap_connect_reply_t_handler_json
1747   (vl_api_tap_connect_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   vat_json_node_t node;
1751
1752   vat_json_init_object (&node);
1753   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1754   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1755
1756   vat_json_print (vam->ofp, &node);
1757   vat_json_free (&node);
1758
1759   vam->retval = ntohl (mp->retval);
1760   vam->result_ready = 1;
1761
1762 }
1763
1764 static void
1765 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->sw_if_index = ntohl (mp->sw_if_index);
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_tap_modify_reply_t_handler_json
1782   (vl_api_tap_modify_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void
1799 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->result_ready = 1;
1811     }
1812 }
1813
1814 static void vl_api_tap_delete_reply_t_handler_json
1815   (vl_api_tap_delete_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   vat_json_node_t node;
1819
1820   vat_json_init_object (&node);
1821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1822
1823   vat_json_print (vam->ofp, &node);
1824   vat_json_free (&node);
1825
1826   vam->retval = ntohl (mp->retval);
1827   vam->result_ready = 1;
1828 }
1829
1830 static void
1831 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1832 {
1833   vat_main_t *vam = &vat_main;
1834   i32 retval = ntohl (mp->retval);
1835   if (vam->async_mode)
1836     {
1837       vam->async_errors += (retval < 0);
1838     }
1839   else
1840     {
1841       vam->retval = retval;
1842       vam->sw_if_index = ntohl (mp->sw_if_index);
1843       vam->result_ready = 1;
1844     }
1845
1846 }
1847
1848 static void vl_api_tap_create_v2_reply_t_handler_json
1849   (vl_api_tap_create_v2_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   vat_json_node_t node;
1853
1854   vat_json_init_object (&node);
1855   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1856   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1857
1858   vat_json_print (vam->ofp, &node);
1859   vat_json_free (&node);
1860
1861   vam->retval = ntohl (mp->retval);
1862   vam->result_ready = 1;
1863
1864 }
1865
1866 static void
1867 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   i32 retval = ntohl (mp->retval);
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->result_ready = 1;
1879     }
1880 }
1881
1882 static void vl_api_tap_delete_v2_reply_t_handler_json
1883   (vl_api_tap_delete_v2_reply_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   vat_json_node_t node;
1887
1888   vat_json_init_object (&node);
1889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1890
1891   vat_json_print (vam->ofp, &node);
1892   vat_json_free (&node);
1893
1894   vam->retval = ntohl (mp->retval);
1895   vam->result_ready = 1;
1896 }
1897
1898 static void
1899 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   i32 retval = ntohl (mp->retval);
1903
1904   if (vam->async_mode)
1905     {
1906       vam->async_errors += (retval < 0);
1907     }
1908   else
1909     {
1910       vam->retval = retval;
1911       vam->sw_if_index = ntohl (mp->sw_if_index);
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_bond_create_reply_t_handler_json
1917   (vl_api_bond_create_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921
1922   vat_json_init_object (&node);
1923   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1924   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1925
1926   vat_json_print (vam->ofp, &node);
1927   vat_json_free (&node);
1928
1929   vam->retval = ntohl (mp->retval);
1930   vam->result_ready = 1;
1931 }
1932
1933 static void
1934 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   i32 retval = ntohl (mp->retval);
1938
1939   if (vam->async_mode)
1940     {
1941       vam->async_errors += (retval < 0);
1942     }
1943   else
1944     {
1945       vam->retval = retval;
1946       vam->result_ready = 1;
1947     }
1948 }
1949
1950 static void vl_api_bond_delete_reply_t_handler_json
1951   (vl_api_bond_delete_reply_t * mp)
1952 {
1953   vat_main_t *vam = &vat_main;
1954   vat_json_node_t node;
1955
1956   vat_json_init_object (&node);
1957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1958
1959   vat_json_print (vam->ofp, &node);
1960   vat_json_free (&node);
1961
1962   vam->retval = ntohl (mp->retval);
1963   vam->result_ready = 1;
1964 }
1965
1966 static void
1967 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1968 {
1969   vat_main_t *vam = &vat_main;
1970   i32 retval = ntohl (mp->retval);
1971
1972   if (vam->async_mode)
1973     {
1974       vam->async_errors += (retval < 0);
1975     }
1976   else
1977     {
1978       vam->retval = retval;
1979       vam->result_ready = 1;
1980     }
1981 }
1982
1983 static void vl_api_bond_enslave_reply_t_handler_json
1984   (vl_api_bond_enslave_reply_t * mp)
1985 {
1986   vat_main_t *vam = &vat_main;
1987   vat_json_node_t node;
1988
1989   vat_json_init_object (&node);
1990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1991
1992   vat_json_print (vam->ofp, &node);
1993   vat_json_free (&node);
1994
1995   vam->retval = ntohl (mp->retval);
1996   vam->result_ready = 1;
1997 }
1998
1999 static void
2000 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2001                                           mp)
2002 {
2003   vat_main_t *vam = &vat_main;
2004   i32 retval = ntohl (mp->retval);
2005
2006   if (vam->async_mode)
2007     {
2008       vam->async_errors += (retval < 0);
2009     }
2010   else
2011     {
2012       vam->retval = retval;
2013       vam->result_ready = 1;
2014     }
2015 }
2016
2017 static void vl_api_bond_detach_slave_reply_t_handler_json
2018   (vl_api_bond_detach_slave_reply_t * mp)
2019 {
2020   vat_main_t *vam = &vat_main;
2021   vat_json_node_t node;
2022
2023   vat_json_init_object (&node);
2024   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2025
2026   vat_json_print (vam->ofp, &node);
2027   vat_json_free (&node);
2028
2029   vam->retval = ntohl (mp->retval);
2030   vam->result_ready = 1;
2031 }
2032
2033 static void vl_api_sw_interface_bond_details_t_handler
2034   (vl_api_sw_interface_bond_details_t * mp)
2035 {
2036   vat_main_t *vam = &vat_main;
2037
2038   print (vam->ofp,
2039          "%-16s %-12d %-12U %-13U %-14u %-14u",
2040          mp->interface_name, ntohl (mp->sw_if_index),
2041          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2042          ntohl (mp->active_slaves), ntohl (mp->slaves));
2043 }
2044
2045 static void vl_api_sw_interface_bond_details_t_handler_json
2046   (vl_api_sw_interface_bond_details_t * mp)
2047 {
2048   vat_main_t *vam = &vat_main;
2049   vat_json_node_t *node = NULL;
2050
2051   if (VAT_JSON_ARRAY != vam->json_tree.type)
2052     {
2053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2054       vat_json_init_array (&vam->json_tree);
2055     }
2056   node = vat_json_array_add (&vam->json_tree);
2057
2058   vat_json_init_object (node);
2059   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2060   vat_json_object_add_string_copy (node, "interface_name",
2061                                    mp->interface_name);
2062   vat_json_object_add_uint (node, "mode", mp->mode);
2063   vat_json_object_add_uint (node, "load_balance", mp->lb);
2064   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2065   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2066 }
2067
2068 static int
2069 api_sw_interface_bond_dump (vat_main_t * vam)
2070 {
2071   vl_api_sw_interface_bond_dump_t *mp;
2072   vl_api_control_ping_t *mp_ping;
2073   int ret;
2074
2075   print (vam->ofp,
2076          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2077          "interface name", "sw_if_index", "mode", "load balance",
2078          "active slaves", "slaves");
2079
2080   /* Get list of bond interfaces */
2081   M (SW_INTERFACE_BOND_DUMP, mp);
2082   S (mp);
2083
2084   /* Use a control ping for synchronization */
2085   MPING (CONTROL_PING, mp_ping);
2086   S (mp_ping);
2087
2088   W (ret);
2089   return ret;
2090 }
2091
2092 static void vl_api_sw_interface_slave_details_t_handler
2093   (vl_api_sw_interface_slave_details_t * mp)
2094 {
2095   vat_main_t *vam = &vat_main;
2096
2097   print (vam->ofp,
2098          "%-25s %-12d %-12d %d", mp->interface_name,
2099          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler_json
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106   vat_json_node_t *node = NULL;
2107
2108   if (VAT_JSON_ARRAY != vam->json_tree.type)
2109     {
2110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2111       vat_json_init_array (&vam->json_tree);
2112     }
2113   node = vat_json_array_add (&vam->json_tree);
2114
2115   vat_json_init_object (node);
2116   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2117   vat_json_object_add_string_copy (node, "interface_name",
2118                                    mp->interface_name);
2119   vat_json_object_add_uint (node, "passive", mp->is_passive);
2120   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2121 }
2122
2123 static int
2124 api_sw_interface_slave_dump (vat_main_t * vam)
2125 {
2126   unformat_input_t *i = vam->input;
2127   vl_api_sw_interface_slave_dump_t *mp;
2128   vl_api_control_ping_t *mp_ping;
2129   u32 sw_if_index = ~0;
2130   u8 sw_if_index_set = 0;
2131   int ret;
2132
2133   /* Parse args required to build the message */
2134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2135     {
2136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2137         sw_if_index_set = 1;
2138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2139         sw_if_index_set = 1;
2140       else
2141         break;
2142     }
2143
2144   if (sw_if_index_set == 0)
2145     {
2146       errmsg ("missing vpp interface name. ");
2147       return -99;
2148     }
2149
2150   print (vam->ofp,
2151          "\n%-25s %-12s %-12s %s",
2152          "slave interface name", "sw_if_index", "passive", "long_timeout");
2153
2154   /* Get list of bond interfaces */
2155   M (SW_INTERFACE_SLAVE_DUMP, mp);
2156   mp->sw_if_index = ntohl (sw_if_index);
2157   S (mp);
2158
2159   /* Use a control ping for synchronization */
2160   MPING (CONTROL_PING, mp_ping);
2161   S (mp_ping);
2162
2163   W (ret);
2164   return ret;
2165 }
2166
2167 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2168   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2169 {
2170   vat_main_t *vam = &vat_main;
2171   i32 retval = ntohl (mp->retval);
2172   if (vam->async_mode)
2173     {
2174       vam->async_errors += (retval < 0);
2175     }
2176   else
2177     {
2178       vam->retval = retval;
2179       vam->sw_if_index = ntohl (mp->sw_if_index);
2180       vam->result_ready = 1;
2181     }
2182   vam->regenerate_interface_table = 1;
2183 }
2184
2185 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2186   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2187 {
2188   vat_main_t *vam = &vat_main;
2189   vat_json_node_t node;
2190
2191   vat_json_init_object (&node);
2192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2193   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2194                             ntohl (mp->sw_if_index));
2195
2196   vat_json_print (vam->ofp, &node);
2197   vat_json_free (&node);
2198
2199   vam->retval = ntohl (mp->retval);
2200   vam->result_ready = 1;
2201 }
2202
2203 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2204   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2205 {
2206   vat_main_t *vam = &vat_main;
2207   i32 retval = ntohl (mp->retval);
2208   if (vam->async_mode)
2209     {
2210       vam->async_errors += (retval < 0);
2211     }
2212   else
2213     {
2214       vam->retval = retval;
2215       vam->sw_if_index = ntohl (mp->sw_if_index);
2216       vam->result_ready = 1;
2217     }
2218 }
2219
2220 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2221   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   vat_json_node_t node;
2225
2226   vat_json_init_object (&node);
2227   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2228   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2229
2230   vat_json_print (vam->ofp, &node);
2231   vat_json_free (&node);
2232
2233   vam->retval = ntohl (mp->retval);
2234   vam->result_ready = 1;
2235 }
2236
2237 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2238   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   i32 retval = ntohl (mp->retval);
2242   if (vam->async_mode)
2243     {
2244       vam->async_errors += (retval < 0);
2245     }
2246   else
2247     {
2248       vam->retval = retval;
2249       vam->result_ready = 1;
2250     }
2251 }
2252
2253 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2254   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   vat_json_node_t node;
2258
2259   vat_json_init_object (&node);
2260   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2261   vat_json_object_add_uint (&node, "fwd_entry_index",
2262                             clib_net_to_host_u32 (mp->fwd_entry_index));
2263
2264   vat_json_print (vam->ofp, &node);
2265   vat_json_free (&node);
2266
2267   vam->retval = ntohl (mp->retval);
2268   vam->result_ready = 1;
2269 }
2270
2271 u8 *
2272 format_lisp_transport_protocol (u8 * s, va_list * args)
2273 {
2274   u32 proto = va_arg (*args, u32);
2275
2276   switch (proto)
2277     {
2278     case 1:
2279       return format (s, "udp");
2280     case 2:
2281       return format (s, "api");
2282     default:
2283       return 0;
2284     }
2285   return 0;
2286 }
2287
2288 static void vl_api_one_get_transport_protocol_reply_t_handler
2289   (vl_api_one_get_transport_protocol_reply_t * mp)
2290 {
2291   vat_main_t *vam = &vat_main;
2292   i32 retval = ntohl (mp->retval);
2293   if (vam->async_mode)
2294     {
2295       vam->async_errors += (retval < 0);
2296     }
2297   else
2298     {
2299       u32 proto = mp->protocol;
2300       print (vam->ofp, "Transport protocol: %U",
2301              format_lisp_transport_protocol, proto);
2302       vam->retval = retval;
2303       vam->result_ready = 1;
2304     }
2305 }
2306
2307 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2308   (vl_api_one_get_transport_protocol_reply_t * mp)
2309 {
2310   vat_main_t *vam = &vat_main;
2311   vat_json_node_t node;
2312   u8 *s;
2313
2314   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2315   vec_add1 (s, 0);
2316
2317   vat_json_init_object (&node);
2318   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2319   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2320
2321   vec_free (s);
2322   vat_json_print (vam->ofp, &node);
2323   vat_json_free (&node);
2324
2325   vam->retval = ntohl (mp->retval);
2326   vam->result_ready = 1;
2327 }
2328
2329 static void vl_api_one_add_del_locator_set_reply_t_handler
2330   (vl_api_one_add_del_locator_set_reply_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   i32 retval = ntohl (mp->retval);
2334   if (vam->async_mode)
2335     {
2336       vam->async_errors += (retval < 0);
2337     }
2338   else
2339     {
2340       vam->retval = retval;
2341       vam->result_ready = 1;
2342     }
2343 }
2344
2345 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2346   (vl_api_one_add_del_locator_set_reply_t * mp)
2347 {
2348   vat_main_t *vam = &vat_main;
2349   vat_json_node_t node;
2350
2351   vat_json_init_object (&node);
2352   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2353   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2354
2355   vat_json_print (vam->ofp, &node);
2356   vat_json_free (&node);
2357
2358   vam->retval = ntohl (mp->retval);
2359   vam->result_ready = 1;
2360 }
2361
2362 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2363   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   i32 retval = ntohl (mp->retval);
2367   if (vam->async_mode)
2368     {
2369       vam->async_errors += (retval < 0);
2370     }
2371   else
2372     {
2373       vam->retval = retval;
2374       vam->sw_if_index = ntohl (mp->sw_if_index);
2375       vam->result_ready = 1;
2376     }
2377   vam->regenerate_interface_table = 1;
2378 }
2379
2380 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2381   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vat_json_node_t node;
2385
2386   vat_json_init_object (&node);
2387   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2388   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2389
2390   vat_json_print (vam->ofp, &node);
2391   vat_json_free (&node);
2392
2393   vam->retval = ntohl (mp->retval);
2394   vam->result_ready = 1;
2395 }
2396
2397 static void vl_api_vxlan_offload_rx_reply_t_handler
2398   (vl_api_vxlan_offload_rx_reply_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   i32 retval = ntohl (mp->retval);
2402   if (vam->async_mode)
2403     {
2404       vam->async_errors += (retval < 0);
2405     }
2406   else
2407     {
2408       vam->retval = retval;
2409       vam->result_ready = 1;
2410     }
2411 }
2412
2413 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2414   (vl_api_vxlan_offload_rx_reply_t * mp)
2415 {
2416   vat_main_t *vam = &vat_main;
2417   vat_json_node_t node;
2418
2419   vat_json_init_object (&node);
2420   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2421
2422   vat_json_print (vam->ofp, &node);
2423   vat_json_free (&node);
2424
2425   vam->retval = ntohl (mp->retval);
2426   vam->result_ready = 1;
2427 }
2428
2429 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2430   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   i32 retval = ntohl (mp->retval);
2434   if (vam->async_mode)
2435     {
2436       vam->async_errors += (retval < 0);
2437     }
2438   else
2439     {
2440       vam->retval = retval;
2441       vam->sw_if_index = ntohl (mp->sw_if_index);
2442       vam->result_ready = 1;
2443     }
2444 }
2445
2446 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2447   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2448 {
2449   vat_main_t *vam = &vat_main;
2450   vat_json_node_t node;
2451
2452   vat_json_init_object (&node);
2453   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2454   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2455
2456   vat_json_print (vam->ofp, &node);
2457   vat_json_free (&node);
2458
2459   vam->retval = ntohl (mp->retval);
2460   vam->result_ready = 1;
2461 }
2462
2463 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2464   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2465 {
2466   vat_main_t *vam = &vat_main;
2467   i32 retval = ntohl (mp->retval);
2468   if (vam->async_mode)
2469     {
2470       vam->async_errors += (retval < 0);
2471     }
2472   else
2473     {
2474       vam->retval = retval;
2475       vam->sw_if_index = ntohl (mp->sw_if_index);
2476       vam->result_ready = 1;
2477     }
2478   vam->regenerate_interface_table = 1;
2479 }
2480
2481 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2482   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2483 {
2484   vat_main_t *vam = &vat_main;
2485   vat_json_node_t node;
2486
2487   vat_json_init_object (&node);
2488   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2489   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2490
2491   vat_json_print (vam->ofp, &node);
2492   vat_json_free (&node);
2493
2494   vam->retval = ntohl (mp->retval);
2495   vam->result_ready = 1;
2496 }
2497
2498 static void vl_api_gre_add_del_tunnel_reply_t_handler
2499   (vl_api_gre_add_del_tunnel_reply_t * mp)
2500 {
2501   vat_main_t *vam = &vat_main;
2502   i32 retval = ntohl (mp->retval);
2503   if (vam->async_mode)
2504     {
2505       vam->async_errors += (retval < 0);
2506     }
2507   else
2508     {
2509       vam->retval = retval;
2510       vam->sw_if_index = ntohl (mp->sw_if_index);
2511       vam->result_ready = 1;
2512     }
2513 }
2514
2515 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2516   (vl_api_gre_add_del_tunnel_reply_t * mp)
2517 {
2518   vat_main_t *vam = &vat_main;
2519   vat_json_node_t node;
2520
2521   vat_json_init_object (&node);
2522   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2523   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2524
2525   vat_json_print (vam->ofp, &node);
2526   vat_json_free (&node);
2527
2528   vam->retval = ntohl (mp->retval);
2529   vam->result_ready = 1;
2530 }
2531
2532 static void vl_api_create_vhost_user_if_reply_t_handler
2533   (vl_api_create_vhost_user_if_reply_t * mp)
2534 {
2535   vat_main_t *vam = &vat_main;
2536   i32 retval = ntohl (mp->retval);
2537   if (vam->async_mode)
2538     {
2539       vam->async_errors += (retval < 0);
2540     }
2541   else
2542     {
2543       vam->retval = retval;
2544       vam->sw_if_index = ntohl (mp->sw_if_index);
2545       vam->result_ready = 1;
2546     }
2547   vam->regenerate_interface_table = 1;
2548 }
2549
2550 static void vl_api_create_vhost_user_if_reply_t_handler_json
2551   (vl_api_create_vhost_user_if_reply_t * mp)
2552 {
2553   vat_main_t *vam = &vat_main;
2554   vat_json_node_t node;
2555
2556   vat_json_init_object (&node);
2557   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2558   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2559
2560   vat_json_print (vam->ofp, &node);
2561   vat_json_free (&node);
2562
2563   vam->retval = ntohl (mp->retval);
2564   vam->result_ready = 1;
2565 }
2566
2567 static void vl_api_dns_resolve_name_reply_t_handler
2568   (vl_api_dns_resolve_name_reply_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   i32 retval = ntohl (mp->retval);
2572   if (vam->async_mode)
2573     {
2574       vam->async_errors += (retval < 0);
2575     }
2576   else
2577     {
2578       vam->retval = retval;
2579       vam->result_ready = 1;
2580
2581       if (retval == 0)
2582         {
2583           if (mp->ip4_set)
2584             clib_warning ("ip4 address %U", format_ip4_address,
2585                           (ip4_address_t *) mp->ip4_address);
2586           if (mp->ip6_set)
2587             clib_warning ("ip6 address %U", format_ip6_address,
2588                           (ip6_address_t *) mp->ip6_address);
2589         }
2590       else
2591         clib_warning ("retval %d", retval);
2592     }
2593 }
2594
2595 static void vl_api_dns_resolve_name_reply_t_handler_json
2596   (vl_api_dns_resolve_name_reply_t * mp)
2597 {
2598   clib_warning ("not implemented");
2599 }
2600
2601 static void vl_api_dns_resolve_ip_reply_t_handler
2602   (vl_api_dns_resolve_ip_reply_t * mp)
2603 {
2604   vat_main_t *vam = &vat_main;
2605   i32 retval = ntohl (mp->retval);
2606   if (vam->async_mode)
2607     {
2608       vam->async_errors += (retval < 0);
2609     }
2610   else
2611     {
2612       vam->retval = retval;
2613       vam->result_ready = 1;
2614
2615       if (retval == 0)
2616         {
2617           clib_warning ("canonical name %s", mp->name);
2618         }
2619       else
2620         clib_warning ("retval %d", retval);
2621     }
2622 }
2623
2624 static void vl_api_dns_resolve_ip_reply_t_handler_json
2625   (vl_api_dns_resolve_ip_reply_t * mp)
2626 {
2627   clib_warning ("not implemented");
2628 }
2629
2630
2631 static void vl_api_ip_address_details_t_handler
2632   (vl_api_ip_address_details_t * mp)
2633 {
2634   vat_main_t *vam = &vat_main;
2635   static ip_address_details_t empty_ip_address_details = { {0} };
2636   ip_address_details_t *address = NULL;
2637   ip_details_t *current_ip_details = NULL;
2638   ip_details_t *details = NULL;
2639
2640   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2641
2642   if (!details || vam->current_sw_if_index >= vec_len (details)
2643       || !details[vam->current_sw_if_index].present)
2644     {
2645       errmsg ("ip address details arrived but not stored");
2646       errmsg ("ip_dump should be called first");
2647       return;
2648     }
2649
2650   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2651
2652 #define addresses (current_ip_details->addr)
2653
2654   vec_validate_init_empty (addresses, vec_len (addresses),
2655                            empty_ip_address_details);
2656
2657   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2658
2659   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2660   address->prefix_length = mp->prefix_length;
2661 #undef addresses
2662 }
2663
2664 static void vl_api_ip_address_details_t_handler_json
2665   (vl_api_ip_address_details_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   vat_json_node_t *node = NULL;
2669   struct in6_addr ip6;
2670   struct in_addr ip4;
2671
2672   if (VAT_JSON_ARRAY != vam->json_tree.type)
2673     {
2674       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2675       vat_json_init_array (&vam->json_tree);
2676     }
2677   node = vat_json_array_add (&vam->json_tree);
2678
2679   vat_json_init_object (node);
2680   if (vam->is_ipv6)
2681     {
2682       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2683       vat_json_object_add_ip6 (node, "ip", ip6);
2684     }
2685   else
2686     {
2687       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2688       vat_json_object_add_ip4 (node, "ip", ip4);
2689     }
2690   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2691 }
2692
2693 static void
2694 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2695 {
2696   vat_main_t *vam = &vat_main;
2697   static ip_details_t empty_ip_details = { 0 };
2698   ip_details_t *ip = NULL;
2699   u32 sw_if_index = ~0;
2700
2701   sw_if_index = ntohl (mp->sw_if_index);
2702
2703   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2704                            sw_if_index, empty_ip_details);
2705
2706   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2707                          sw_if_index);
2708
2709   ip->present = 1;
2710 }
2711
2712 static void
2713 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2714 {
2715   vat_main_t *vam = &vat_main;
2716
2717   if (VAT_JSON_ARRAY != vam->json_tree.type)
2718     {
2719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2720       vat_json_init_array (&vam->json_tree);
2721     }
2722   vat_json_array_add_uint (&vam->json_tree,
2723                            clib_net_to_host_u32 (mp->sw_if_index));
2724 }
2725
2726 static void
2727 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2728 {
2729   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2730           "router_addr %U host_mac %U",
2731           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2732           mp->lease.hostname,
2733           format_ip4_address, &mp->lease.host_address,
2734           format_ip4_address, &mp->lease.router_address,
2735           format_ethernet_address, mp->lease.host_mac);
2736 }
2737
2738 static void vl_api_dhcp_compl_event_t_handler_json
2739   (vl_api_dhcp_compl_event_t * mp)
2740 {
2741   /* JSON output not supported */
2742 }
2743
2744 static void
2745 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2746                               u32 counter)
2747 {
2748   vat_main_t *vam = &vat_main;
2749   static u64 default_counter = 0;
2750
2751   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2752                            NULL);
2753   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2754                            sw_if_index, default_counter);
2755   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2756 }
2757
2758 static void
2759 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2760                                 interface_counter_t counter)
2761 {
2762   vat_main_t *vam = &vat_main;
2763   static interface_counter_t default_counter = { 0, };
2764
2765   vec_validate_init_empty (vam->combined_interface_counters,
2766                            vnet_counter_type, NULL);
2767   vec_validate_init_empty (vam->combined_interface_counters
2768                            [vnet_counter_type], sw_if_index, default_counter);
2769   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2770 }
2771
2772 static void vl_api_vnet_interface_simple_counters_t_handler
2773   (vl_api_vnet_interface_simple_counters_t * mp)
2774 {
2775   /* not supported */
2776 }
2777
2778 static void vl_api_vnet_interface_combined_counters_t_handler
2779   (vl_api_vnet_interface_combined_counters_t * mp)
2780 {
2781   /* not supported */
2782 }
2783
2784 static void vl_api_vnet_interface_simple_counters_t_handler_json
2785   (vl_api_vnet_interface_simple_counters_t * mp)
2786 {
2787   u64 *v_packets;
2788   u64 packets;
2789   u32 count;
2790   u32 first_sw_if_index;
2791   int i;
2792
2793   count = ntohl (mp->count);
2794   first_sw_if_index = ntohl (mp->first_sw_if_index);
2795
2796   v_packets = (u64 *) & mp->data;
2797   for (i = 0; i < count; i++)
2798     {
2799       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2800       set_simple_interface_counter (mp->vnet_counter_type,
2801                                     first_sw_if_index + i, packets);
2802       v_packets++;
2803     }
2804 }
2805
2806 static void vl_api_vnet_interface_combined_counters_t_handler_json
2807   (vl_api_vnet_interface_combined_counters_t * mp)
2808 {
2809   interface_counter_t counter;
2810   vlib_counter_t *v;
2811   u32 first_sw_if_index;
2812   int i;
2813   u32 count;
2814
2815   count = ntohl (mp->count);
2816   first_sw_if_index = ntohl (mp->first_sw_if_index);
2817
2818   v = (vlib_counter_t *) & mp->data;
2819   for (i = 0; i < count; i++)
2820     {
2821       counter.packets =
2822         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2823       counter.bytes =
2824         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2825       set_combined_interface_counter (mp->vnet_counter_type,
2826                                       first_sw_if_index + i, counter);
2827       v++;
2828     }
2829 }
2830
2831 static u32
2832 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2833 {
2834   vat_main_t *vam = &vat_main;
2835   u32 i;
2836
2837   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2838     {
2839       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2840         {
2841           return i;
2842         }
2843     }
2844   return ~0;
2845 }
2846
2847 static u32
2848 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2849 {
2850   vat_main_t *vam = &vat_main;
2851   u32 i;
2852
2853   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2854     {
2855       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2856         {
2857           return i;
2858         }
2859     }
2860   return ~0;
2861 }
2862
2863 static void vl_api_vnet_ip4_fib_counters_t_handler
2864   (vl_api_vnet_ip4_fib_counters_t * mp)
2865 {
2866   /* not supported */
2867 }
2868
2869 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2870   (vl_api_vnet_ip4_fib_counters_t * mp)
2871 {
2872   vat_main_t *vam = &vat_main;
2873   vl_api_ip4_fib_counter_t *v;
2874   ip4_fib_counter_t *counter;
2875   struct in_addr ip4;
2876   u32 vrf_id;
2877   u32 vrf_index;
2878   u32 count;
2879   int i;
2880
2881   vrf_id = ntohl (mp->vrf_id);
2882   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2883   if (~0 == vrf_index)
2884     {
2885       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2886       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2887       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2888       vec_validate (vam->ip4_fib_counters, vrf_index);
2889       vam->ip4_fib_counters[vrf_index] = NULL;
2890     }
2891
2892   vec_free (vam->ip4_fib_counters[vrf_index]);
2893   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2894   count = ntohl (mp->count);
2895   for (i = 0; i < count; i++)
2896     {
2897       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2898       counter = &vam->ip4_fib_counters[vrf_index][i];
2899       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2900       counter->address = ip4;
2901       counter->address_length = v->address_length;
2902       counter->packets = clib_net_to_host_u64 (v->packets);
2903       counter->bytes = clib_net_to_host_u64 (v->bytes);
2904       v++;
2905     }
2906 }
2907
2908 static void vl_api_vnet_ip4_nbr_counters_t_handler
2909   (vl_api_vnet_ip4_nbr_counters_t * mp)
2910 {
2911   /* not supported */
2912 }
2913
2914 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2915   (vl_api_vnet_ip4_nbr_counters_t * mp)
2916 {
2917   vat_main_t *vam = &vat_main;
2918   vl_api_ip4_nbr_counter_t *v;
2919   ip4_nbr_counter_t *counter;
2920   u32 sw_if_index;
2921   u32 count;
2922   int i;
2923
2924   sw_if_index = ntohl (mp->sw_if_index);
2925   count = ntohl (mp->count);
2926   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2927
2928   if (mp->begin)
2929     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2930
2931   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2932   for (i = 0; i < count; i++)
2933     {
2934       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2935       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2936       counter->address.s_addr = v->address;
2937       counter->packets = clib_net_to_host_u64 (v->packets);
2938       counter->bytes = clib_net_to_host_u64 (v->bytes);
2939       counter->linkt = v->link_type;
2940       v++;
2941     }
2942 }
2943
2944 static void vl_api_vnet_ip6_fib_counters_t_handler
2945   (vl_api_vnet_ip6_fib_counters_t * mp)
2946 {
2947   /* not supported */
2948 }
2949
2950 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2951   (vl_api_vnet_ip6_fib_counters_t * mp)
2952 {
2953   vat_main_t *vam = &vat_main;
2954   vl_api_ip6_fib_counter_t *v;
2955   ip6_fib_counter_t *counter;
2956   struct in6_addr ip6;
2957   u32 vrf_id;
2958   u32 vrf_index;
2959   u32 count;
2960   int i;
2961
2962   vrf_id = ntohl (mp->vrf_id);
2963   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2964   if (~0 == vrf_index)
2965     {
2966       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2967       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2968       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2969       vec_validate (vam->ip6_fib_counters, vrf_index);
2970       vam->ip6_fib_counters[vrf_index] = NULL;
2971     }
2972
2973   vec_free (vam->ip6_fib_counters[vrf_index]);
2974   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2975   count = ntohl (mp->count);
2976   for (i = 0; i < count; i++)
2977     {
2978       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2979       counter = &vam->ip6_fib_counters[vrf_index][i];
2980       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2981       counter->address = ip6;
2982       counter->address_length = v->address_length;
2983       counter->packets = clib_net_to_host_u64 (v->packets);
2984       counter->bytes = clib_net_to_host_u64 (v->bytes);
2985       v++;
2986     }
2987 }
2988
2989 static void vl_api_vnet_ip6_nbr_counters_t_handler
2990   (vl_api_vnet_ip6_nbr_counters_t * mp)
2991 {
2992   /* not supported */
2993 }
2994
2995 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2996   (vl_api_vnet_ip6_nbr_counters_t * mp)
2997 {
2998   vat_main_t *vam = &vat_main;
2999   vl_api_ip6_nbr_counter_t *v;
3000   ip6_nbr_counter_t *counter;
3001   struct in6_addr ip6;
3002   u32 sw_if_index;
3003   u32 count;
3004   int i;
3005
3006   sw_if_index = ntohl (mp->sw_if_index);
3007   count = ntohl (mp->count);
3008   vec_validate (vam->ip6_nbr_counters, sw_if_index);
3009
3010   if (mp->begin)
3011     vec_free (vam->ip6_nbr_counters[sw_if_index]);
3012
3013   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
3014   for (i = 0; i < count; i++)
3015     {
3016       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
3017       counter = &vam->ip6_nbr_counters[sw_if_index][i];
3018       clib_memcpy (&ip6, &v->address, sizeof (ip6));
3019       counter->address = ip6;
3020       counter->packets = clib_net_to_host_u64 (v->packets);
3021       counter->bytes = clib_net_to_host_u64 (v->bytes);
3022       v++;
3023     }
3024 }
3025
3026 static void vl_api_get_first_msg_id_reply_t_handler
3027   (vl_api_get_first_msg_id_reply_t * mp)
3028 {
3029   vat_main_t *vam = &vat_main;
3030   i32 retval = ntohl (mp->retval);
3031
3032   if (vam->async_mode)
3033     {
3034       vam->async_errors += (retval < 0);
3035     }
3036   else
3037     {
3038       vam->retval = retval;
3039       vam->result_ready = 1;
3040     }
3041   if (retval >= 0)
3042     {
3043       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3044     }
3045 }
3046
3047 static void vl_api_get_first_msg_id_reply_t_handler_json
3048   (vl_api_get_first_msg_id_reply_t * mp)
3049 {
3050   vat_main_t *vam = &vat_main;
3051   vat_json_node_t node;
3052
3053   vat_json_init_object (&node);
3054   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3055   vat_json_object_add_uint (&node, "first_msg_id",
3056                             (uint) ntohs (mp->first_msg_id));
3057
3058   vat_json_print (vam->ofp, &node);
3059   vat_json_free (&node);
3060
3061   vam->retval = ntohl (mp->retval);
3062   vam->result_ready = 1;
3063 }
3064
3065 static void vl_api_get_node_graph_reply_t_handler
3066   (vl_api_get_node_graph_reply_t * mp)
3067 {
3068   vat_main_t *vam = &vat_main;
3069   api_main_t *am = &api_main;
3070   i32 retval = ntohl (mp->retval);
3071   u8 *pvt_copy, *reply;
3072   void *oldheap;
3073   vlib_node_t *node;
3074   int i;
3075
3076   if (vam->async_mode)
3077     {
3078       vam->async_errors += (retval < 0);
3079     }
3080   else
3081     {
3082       vam->retval = retval;
3083       vam->result_ready = 1;
3084     }
3085
3086   /* "Should never happen..." */
3087   if (retval != 0)
3088     return;
3089
3090   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3091   pvt_copy = vec_dup (reply);
3092
3093   /* Toss the shared-memory original... */
3094   pthread_mutex_lock (&am->vlib_rp->mutex);
3095   oldheap = svm_push_data_heap (am->vlib_rp);
3096
3097   vec_free (reply);
3098
3099   svm_pop_heap (oldheap);
3100   pthread_mutex_unlock (&am->vlib_rp->mutex);
3101
3102   if (vam->graph_nodes)
3103     {
3104       hash_free (vam->graph_node_index_by_name);
3105
3106       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3107         {
3108           node = vam->graph_nodes[0][i];
3109           vec_free (node->name);
3110           vec_free (node->next_nodes);
3111           vec_free (node);
3112         }
3113       vec_free (vam->graph_nodes[0]);
3114       vec_free (vam->graph_nodes);
3115     }
3116
3117   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3118   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3119   vec_free (pvt_copy);
3120
3121   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3122     {
3123       node = vam->graph_nodes[0][i];
3124       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3125     }
3126 }
3127
3128 static void vl_api_get_node_graph_reply_t_handler_json
3129   (vl_api_get_node_graph_reply_t * mp)
3130 {
3131   vat_main_t *vam = &vat_main;
3132   api_main_t *am = &api_main;
3133   void *oldheap;
3134   vat_json_node_t node;
3135   u8 *reply;
3136
3137   /* $$$$ make this real? */
3138   vat_json_init_object (&node);
3139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3140   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3141
3142   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3143
3144   /* Toss the shared-memory original... */
3145   pthread_mutex_lock (&am->vlib_rp->mutex);
3146   oldheap = svm_push_data_heap (am->vlib_rp);
3147
3148   vec_free (reply);
3149
3150   svm_pop_heap (oldheap);
3151   pthread_mutex_unlock (&am->vlib_rp->mutex);
3152
3153   vat_json_print (vam->ofp, &node);
3154   vat_json_free (&node);
3155
3156   vam->retval = ntohl (mp->retval);
3157   vam->result_ready = 1;
3158 }
3159
3160 static void
3161 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164   u8 *s = 0;
3165
3166   if (mp->local)
3167     {
3168       s = format (s, "%=16d%=16d%=16d",
3169                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3170     }
3171   else
3172     {
3173       s = format (s, "%=16U%=16d%=16d",
3174                   mp->is_ipv6 ? format_ip6_address :
3175                   format_ip4_address,
3176                   mp->ip_address, mp->priority, mp->weight);
3177     }
3178
3179   print (vam->ofp, "%v", s);
3180   vec_free (s);
3181 }
3182
3183 static void
3184 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3185 {
3186   vat_main_t *vam = &vat_main;
3187   vat_json_node_t *node = NULL;
3188   struct in6_addr ip6;
3189   struct in_addr ip4;
3190
3191   if (VAT_JSON_ARRAY != vam->json_tree.type)
3192     {
3193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3194       vat_json_init_array (&vam->json_tree);
3195     }
3196   node = vat_json_array_add (&vam->json_tree);
3197   vat_json_init_object (node);
3198
3199   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3200   vat_json_object_add_uint (node, "priority", mp->priority);
3201   vat_json_object_add_uint (node, "weight", mp->weight);
3202
3203   if (mp->local)
3204     vat_json_object_add_uint (node, "sw_if_index",
3205                               clib_net_to_host_u32 (mp->sw_if_index));
3206   else
3207     {
3208       if (mp->is_ipv6)
3209         {
3210           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3211           vat_json_object_add_ip6 (node, "address", ip6);
3212         }
3213       else
3214         {
3215           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3216           vat_json_object_add_ip4 (node, "address", ip4);
3217         }
3218     }
3219 }
3220
3221 static void
3222 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3223                                           mp)
3224 {
3225   vat_main_t *vam = &vat_main;
3226   u8 *ls_name = 0;
3227
3228   ls_name = format (0, "%s", mp->ls_name);
3229
3230   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3231          ls_name);
3232   vec_free (ls_name);
3233 }
3234
3235 static void
3236   vl_api_one_locator_set_details_t_handler_json
3237   (vl_api_one_locator_set_details_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t *node = 0;
3241   u8 *ls_name = 0;
3242
3243   ls_name = format (0, "%s", mp->ls_name);
3244   vec_add1 (ls_name, 0);
3245
3246   if (VAT_JSON_ARRAY != vam->json_tree.type)
3247     {
3248       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3249       vat_json_init_array (&vam->json_tree);
3250     }
3251   node = vat_json_array_add (&vam->json_tree);
3252
3253   vat_json_init_object (node);
3254   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3255   vat_json_object_add_uint (node, "ls_index",
3256                             clib_net_to_host_u32 (mp->ls_index));
3257   vec_free (ls_name);
3258 }
3259
3260 typedef struct
3261 {
3262   u32 spi;
3263   u8 si;
3264 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3265
3266 uword
3267 unformat_nsh_address (unformat_input_t * input, va_list * args)
3268 {
3269   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3270   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3271 }
3272
3273 u8 *
3274 format_nsh_address_vat (u8 * s, va_list * args)
3275 {
3276   nsh_t *a = va_arg (*args, nsh_t *);
3277   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3278 }
3279
3280 static u8 *
3281 format_lisp_flat_eid (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
3287   switch (type)
3288     {
3289     case 0:
3290       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3291     case 1:
3292       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3293     case 2:
3294       return format (s, "%U", format_ethernet_address, eid);
3295     case 3:
3296       return format (s, "%U", format_nsh_address_vat, eid);
3297     }
3298   return 0;
3299 }
3300
3301 static u8 *
3302 format_lisp_eid_vat (u8 * s, va_list * args)
3303 {
3304   u32 type = va_arg (*args, u32);
3305   u8 *eid = va_arg (*args, u8 *);
3306   u32 eid_len = va_arg (*args, u32);
3307   u8 *seid = va_arg (*args, u8 *);
3308   u32 seid_len = va_arg (*args, u32);
3309   u32 is_src_dst = va_arg (*args, u32);
3310
3311   if (is_src_dst)
3312     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3313
3314   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3315
3316   return s;
3317 }
3318
3319 static void
3320 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   u8 *s = 0, *eid = 0;
3324
3325   if (~0 == mp->locator_set_index)
3326     s = format (0, "action: %d", mp->action);
3327   else
3328     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3329
3330   eid = format (0, "%U", format_lisp_eid_vat,
3331                 mp->eid_type,
3332                 mp->eid,
3333                 mp->eid_prefix_len,
3334                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3335   vec_add1 (eid, 0);
3336
3337   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3338          clib_net_to_host_u32 (mp->vni),
3339          eid,
3340          mp->is_local ? "local" : "remote",
3341          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3342          clib_net_to_host_u16 (mp->key_id), mp->key);
3343
3344   vec_free (s);
3345   vec_free (eid);
3346 }
3347
3348 static void
3349 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3350                                              * mp)
3351 {
3352   vat_main_t *vam = &vat_main;
3353   vat_json_node_t *node = 0;
3354   u8 *eid = 0;
3355
3356   if (VAT_JSON_ARRAY != vam->json_tree.type)
3357     {
3358       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3359       vat_json_init_array (&vam->json_tree);
3360     }
3361   node = vat_json_array_add (&vam->json_tree);
3362
3363   vat_json_init_object (node);
3364   if (~0 == mp->locator_set_index)
3365     vat_json_object_add_uint (node, "action", mp->action);
3366   else
3367     vat_json_object_add_uint (node, "locator_set_index",
3368                               clib_net_to_host_u32 (mp->locator_set_index));
3369
3370   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3371   if (mp->eid_type == 3)
3372     {
3373       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3374       vat_json_init_object (nsh_json);
3375       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3376       vat_json_object_add_uint (nsh_json, "spi",
3377                                 clib_net_to_host_u32 (nsh->spi));
3378       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3379     }
3380   else
3381     {
3382       eid = format (0, "%U", format_lisp_eid_vat,
3383                     mp->eid_type,
3384                     mp->eid,
3385                     mp->eid_prefix_len,
3386                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3387       vec_add1 (eid, 0);
3388       vat_json_object_add_string_copy (node, "eid", eid);
3389       vec_free (eid);
3390     }
3391   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3392   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3393   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3394
3395   if (mp->key_id)
3396     {
3397       vat_json_object_add_uint (node, "key_id",
3398                                 clib_net_to_host_u16 (mp->key_id));
3399       vat_json_object_add_string_copy (node, "key", mp->key);
3400     }
3401 }
3402
3403 static void
3404 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3405 {
3406   vat_main_t *vam = &vat_main;
3407   u8 *seid = 0, *deid = 0;
3408   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3409
3410   deid = format (0, "%U", format_lisp_eid_vat,
3411                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3412
3413   seid = format (0, "%U", format_lisp_eid_vat,
3414                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3415
3416   vec_add1 (deid, 0);
3417   vec_add1 (seid, 0);
3418
3419   if (mp->is_ip4)
3420     format_ip_address_fcn = format_ip4_address;
3421   else
3422     format_ip_address_fcn = format_ip6_address;
3423
3424
3425   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3426          clib_net_to_host_u32 (mp->vni),
3427          seid, deid,
3428          format_ip_address_fcn, mp->lloc,
3429          format_ip_address_fcn, mp->rloc,
3430          clib_net_to_host_u32 (mp->pkt_count),
3431          clib_net_to_host_u32 (mp->bytes));
3432
3433   vec_free (deid);
3434   vec_free (seid);
3435 }
3436
3437 static void
3438 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3439 {
3440   struct in6_addr ip6;
3441   struct in_addr ip4;
3442   vat_main_t *vam = &vat_main;
3443   vat_json_node_t *node = 0;
3444   u8 *deid = 0, *seid = 0;
3445
3446   if (VAT_JSON_ARRAY != vam->json_tree.type)
3447     {
3448       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3449       vat_json_init_array (&vam->json_tree);
3450     }
3451   node = vat_json_array_add (&vam->json_tree);
3452
3453   vat_json_init_object (node);
3454   deid = format (0, "%U", format_lisp_eid_vat,
3455                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3456
3457   seid = format (0, "%U", format_lisp_eid_vat,
3458                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3459
3460   vec_add1 (deid, 0);
3461   vec_add1 (seid, 0);
3462
3463   vat_json_object_add_string_copy (node, "seid", seid);
3464   vat_json_object_add_string_copy (node, "deid", deid);
3465   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3466
3467   if (mp->is_ip4)
3468     {
3469       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3470       vat_json_object_add_ip4 (node, "lloc", ip4);
3471       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3472       vat_json_object_add_ip4 (node, "rloc", ip4);
3473     }
3474   else
3475     {
3476       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3477       vat_json_object_add_ip6 (node, "lloc", ip6);
3478       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3479       vat_json_object_add_ip6 (node, "rloc", ip6);
3480     }
3481   vat_json_object_add_uint (node, "pkt_count",
3482                             clib_net_to_host_u32 (mp->pkt_count));
3483   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3484
3485   vec_free (deid);
3486   vec_free (seid);
3487 }
3488
3489 static void
3490   vl_api_one_eid_table_map_details_t_handler
3491   (vl_api_one_eid_table_map_details_t * mp)
3492 {
3493   vat_main_t *vam = &vat_main;
3494
3495   u8 *line = format (0, "%=10d%=10d",
3496                      clib_net_to_host_u32 (mp->vni),
3497                      clib_net_to_host_u32 (mp->dp_table));
3498   print (vam->ofp, "%v", line);
3499   vec_free (line);
3500 }
3501
3502 static void
3503   vl_api_one_eid_table_map_details_t_handler_json
3504   (vl_api_one_eid_table_map_details_t * mp)
3505 {
3506   vat_main_t *vam = &vat_main;
3507   vat_json_node_t *node = NULL;
3508
3509   if (VAT_JSON_ARRAY != vam->json_tree.type)
3510     {
3511       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3512       vat_json_init_array (&vam->json_tree);
3513     }
3514   node = vat_json_array_add (&vam->json_tree);
3515   vat_json_init_object (node);
3516   vat_json_object_add_uint (node, "dp_table",
3517                             clib_net_to_host_u32 (mp->dp_table));
3518   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3519 }
3520
3521 static void
3522   vl_api_one_eid_table_vni_details_t_handler
3523   (vl_api_one_eid_table_vni_details_t * mp)
3524 {
3525   vat_main_t *vam = &vat_main;
3526
3527   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3528   print (vam->ofp, "%v", line);
3529   vec_free (line);
3530 }
3531
3532 static void
3533   vl_api_one_eid_table_vni_details_t_handler_json
3534   (vl_api_one_eid_table_vni_details_t * mp)
3535 {
3536   vat_main_t *vam = &vat_main;
3537   vat_json_node_t *node = NULL;
3538
3539   if (VAT_JSON_ARRAY != vam->json_tree.type)
3540     {
3541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3542       vat_json_init_array (&vam->json_tree);
3543     }
3544   node = vat_json_array_add (&vam->json_tree);
3545   vat_json_init_object (node);
3546   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3547 }
3548
3549 static void
3550   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3551   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3552 {
3553   vat_main_t *vam = &vat_main;
3554   int retval = clib_net_to_host_u32 (mp->retval);
3555
3556   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3557   print (vam->ofp, "fallback threshold value: %d", mp->value);
3558
3559   vam->retval = retval;
3560   vam->result_ready = 1;
3561 }
3562
3563 static void
3564   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3565   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3566 {
3567   vat_main_t *vam = &vat_main;
3568   vat_json_node_t _node, *node = &_node;
3569   int retval = clib_net_to_host_u32 (mp->retval);
3570
3571   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3572   vat_json_init_object (node);
3573   vat_json_object_add_uint (node, "value", mp->value);
3574
3575   vat_json_print (vam->ofp, node);
3576   vat_json_free (node);
3577
3578   vam->retval = retval;
3579   vam->result_ready = 1;
3580 }
3581
3582 static void
3583   vl_api_show_one_map_register_state_reply_t_handler
3584   (vl_api_show_one_map_register_state_reply_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587   int retval = clib_net_to_host_u32 (mp->retval);
3588
3589   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3590
3591   vam->retval = retval;
3592   vam->result_ready = 1;
3593 }
3594
3595 static void
3596   vl_api_show_one_map_register_state_reply_t_handler_json
3597   (vl_api_show_one_map_register_state_reply_t * mp)
3598 {
3599   vat_main_t *vam = &vat_main;
3600   vat_json_node_t _node, *node = &_node;
3601   int retval = clib_net_to_host_u32 (mp->retval);
3602
3603   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3604
3605   vat_json_init_object (node);
3606   vat_json_object_add_string_copy (node, "state", s);
3607
3608   vat_json_print (vam->ofp, node);
3609   vat_json_free (node);
3610
3611   vam->retval = retval;
3612   vam->result_ready = 1;
3613   vec_free (s);
3614 }
3615
3616 static void
3617   vl_api_show_one_rloc_probe_state_reply_t_handler
3618   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3619 {
3620   vat_main_t *vam = &vat_main;
3621   int retval = clib_net_to_host_u32 (mp->retval);
3622
3623   if (retval)
3624     goto end;
3625
3626   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3627 end:
3628   vam->retval = retval;
3629   vam->result_ready = 1;
3630 }
3631
3632 static void
3633   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3634   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3635 {
3636   vat_main_t *vam = &vat_main;
3637   vat_json_node_t _node, *node = &_node;
3638   int retval = clib_net_to_host_u32 (mp->retval);
3639
3640   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3641   vat_json_init_object (node);
3642   vat_json_object_add_string_copy (node, "state", s);
3643
3644   vat_json_print (vam->ofp, node);
3645   vat_json_free (node);
3646
3647   vam->retval = retval;
3648   vam->result_ready = 1;
3649   vec_free (s);
3650 }
3651
3652 static void
3653   vl_api_show_one_stats_enable_disable_reply_t_handler
3654   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3655 {
3656   vat_main_t *vam = &vat_main;
3657   int retval = clib_net_to_host_u32 (mp->retval);
3658
3659   if (retval)
3660     goto end;
3661
3662   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3663 end:
3664   vam->retval = retval;
3665   vam->result_ready = 1;
3666 }
3667
3668 static void
3669   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3670   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3671 {
3672   vat_main_t *vam = &vat_main;
3673   vat_json_node_t _node, *node = &_node;
3674   int retval = clib_net_to_host_u32 (mp->retval);
3675
3676   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3677   vat_json_init_object (node);
3678   vat_json_object_add_string_copy (node, "state", s);
3679
3680   vat_json_print (vam->ofp, node);
3681   vat_json_free (node);
3682
3683   vam->retval = retval;
3684   vam->result_ready = 1;
3685   vec_free (s);
3686 }
3687
3688 static void
3689 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3690 {
3691   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3692   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3693   e->vni = clib_net_to_host_u32 (e->vni);
3694 }
3695
3696 static void
3697   gpe_fwd_entries_get_reply_t_net_to_host
3698   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3699 {
3700   u32 i;
3701
3702   mp->count = clib_net_to_host_u32 (mp->count);
3703   for (i = 0; i < mp->count; i++)
3704     {
3705       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3706     }
3707 }
3708
3709 static u8 *
3710 format_gpe_encap_mode (u8 * s, va_list * args)
3711 {
3712   u32 mode = va_arg (*args, u32);
3713
3714   switch (mode)
3715     {
3716     case 0:
3717       return format (s, "lisp");
3718     case 1:
3719       return format (s, "vxlan");
3720     }
3721   return 0;
3722 }
3723
3724 static void
3725   vl_api_gpe_get_encap_mode_reply_t_handler
3726   (vl_api_gpe_get_encap_mode_reply_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729
3730   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3731   vam->retval = ntohl (mp->retval);
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_get_encap_mode_reply_t_handler_json
3737   (vl_api_gpe_get_encap_mode_reply_t * mp)
3738 {
3739   vat_main_t *vam = &vat_main;
3740   vat_json_node_t node;
3741
3742   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3743   vec_add1 (encap_mode, 0);
3744
3745   vat_json_init_object (&node);
3746   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3747
3748   vec_free (encap_mode);
3749   vat_json_print (vam->ofp, &node);
3750   vat_json_free (&node);
3751
3752   vam->retval = ntohl (mp->retval);
3753   vam->result_ready = 1;
3754 }
3755
3756 static void
3757   vl_api_gpe_fwd_entry_path_details_t_handler
3758   (vl_api_gpe_fwd_entry_path_details_t * mp)
3759 {
3760   vat_main_t *vam = &vat_main;
3761   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3762
3763   if (mp->lcl_loc.is_ip4)
3764     format_ip_address_fcn = format_ip4_address;
3765   else
3766     format_ip_address_fcn = format_ip6_address;
3767
3768   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3769          format_ip_address_fcn, &mp->lcl_loc,
3770          format_ip_address_fcn, &mp->rmt_loc);
3771 }
3772
3773 static void
3774 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3775 {
3776   struct in6_addr ip6;
3777   struct in_addr ip4;
3778
3779   if (loc->is_ip4)
3780     {
3781       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3782       vat_json_object_add_ip4 (n, "address", ip4);
3783     }
3784   else
3785     {
3786       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3787       vat_json_object_add_ip6 (n, "address", ip6);
3788     }
3789   vat_json_object_add_uint (n, "weight", loc->weight);
3790 }
3791
3792 static void
3793   vl_api_gpe_fwd_entry_path_details_t_handler_json
3794   (vl_api_gpe_fwd_entry_path_details_t * mp)
3795 {
3796   vat_main_t *vam = &vat_main;
3797   vat_json_node_t *node = NULL;
3798   vat_json_node_t *loc_node;
3799
3800   if (VAT_JSON_ARRAY != vam->json_tree.type)
3801     {
3802       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3803       vat_json_init_array (&vam->json_tree);
3804     }
3805   node = vat_json_array_add (&vam->json_tree);
3806   vat_json_init_object (node);
3807
3808   loc_node = vat_json_object_add (node, "local_locator");
3809   vat_json_init_object (loc_node);
3810   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3811
3812   loc_node = vat_json_object_add (node, "remote_locator");
3813   vat_json_init_object (loc_node);
3814   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3815 }
3816
3817 static void
3818   vl_api_gpe_fwd_entries_get_reply_t_handler
3819   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3820 {
3821   vat_main_t *vam = &vat_main;
3822   u32 i;
3823   int retval = clib_net_to_host_u32 (mp->retval);
3824   vl_api_gpe_fwd_entry_t *e;
3825
3826   if (retval)
3827     goto end;
3828
3829   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3830
3831   for (i = 0; i < mp->count; i++)
3832     {
3833       e = &mp->entries[i];
3834       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3835              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3836              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3837     }
3838
3839 end:
3840   vam->retval = retval;
3841   vam->result_ready = 1;
3842 }
3843
3844 static void
3845   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3846   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3847 {
3848   u8 *s = 0;
3849   vat_main_t *vam = &vat_main;
3850   vat_json_node_t *e = 0, root;
3851   u32 i;
3852   int retval = clib_net_to_host_u32 (mp->retval);
3853   vl_api_gpe_fwd_entry_t *fwd;
3854
3855   if (retval)
3856     goto end;
3857
3858   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3859   vat_json_init_array (&root);
3860
3861   for (i = 0; i < mp->count; i++)
3862     {
3863       e = vat_json_array_add (&root);
3864       fwd = &mp->entries[i];
3865
3866       vat_json_init_object (e);
3867       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3868       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3869       vat_json_object_add_int (e, "vni", fwd->vni);
3870       vat_json_object_add_int (e, "action", fwd->action);
3871
3872       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3873                   fwd->leid_prefix_len);
3874       vec_add1 (s, 0);
3875       vat_json_object_add_string_copy (e, "leid", s);
3876       vec_free (s);
3877
3878       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3879                   fwd->reid_prefix_len);
3880       vec_add1 (s, 0);
3881       vat_json_object_add_string_copy (e, "reid", s);
3882       vec_free (s);
3883     }
3884
3885   vat_json_print (vam->ofp, &root);
3886   vat_json_free (&root);
3887
3888 end:
3889   vam->retval = retval;
3890   vam->result_ready = 1;
3891 }
3892
3893 static void
3894   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3895   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3896 {
3897   vat_main_t *vam = &vat_main;
3898   u32 i, n;
3899   int retval = clib_net_to_host_u32 (mp->retval);
3900   vl_api_gpe_native_fwd_rpath_t *r;
3901
3902   if (retval)
3903     goto end;
3904
3905   n = clib_net_to_host_u32 (mp->count);
3906
3907   for (i = 0; i < n; i++)
3908     {
3909       r = &mp->entries[i];
3910       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3911              clib_net_to_host_u32 (r->fib_index),
3912              clib_net_to_host_u32 (r->nh_sw_if_index),
3913              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3914     }
3915
3916 end:
3917   vam->retval = retval;
3918   vam->result_ready = 1;
3919 }
3920
3921 static void
3922   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3923   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3924 {
3925   vat_main_t *vam = &vat_main;
3926   vat_json_node_t root, *e;
3927   u32 i, n;
3928   int retval = clib_net_to_host_u32 (mp->retval);
3929   vl_api_gpe_native_fwd_rpath_t *r;
3930   u8 *s;
3931
3932   if (retval)
3933     goto end;
3934
3935   n = clib_net_to_host_u32 (mp->count);
3936   vat_json_init_array (&root);
3937
3938   for (i = 0; i < n; i++)
3939     {
3940       e = vat_json_array_add (&root);
3941       vat_json_init_object (e);
3942       r = &mp->entries[i];
3943       s =
3944         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3945                 r->nh_addr);
3946       vec_add1 (s, 0);
3947       vat_json_object_add_string_copy (e, "ip4", s);
3948       vec_free (s);
3949
3950       vat_json_object_add_uint (e, "fib_index",
3951                                 clib_net_to_host_u32 (r->fib_index));
3952       vat_json_object_add_uint (e, "nh_sw_if_index",
3953                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3954     }
3955
3956   vat_json_print (vam->ofp, &root);
3957   vat_json_free (&root);
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
3966   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3967 {
3968   vat_main_t *vam = &vat_main;
3969   u32 i, n;
3970   int retval = clib_net_to_host_u32 (mp->retval);
3971
3972   if (retval)
3973     goto end;
3974
3975   n = clib_net_to_host_u32 (mp->count);
3976
3977   for (i = 0; i < n; i++)
3978     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3979
3980 end:
3981   vam->retval = retval;
3982   vam->result_ready = 1;
3983 }
3984
3985 static void
3986   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3987   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3988 {
3989   vat_main_t *vam = &vat_main;
3990   vat_json_node_t root;
3991   u32 i, n;
3992   int retval = clib_net_to_host_u32 (mp->retval);
3993
3994   if (retval)
3995     goto end;
3996
3997   n = clib_net_to_host_u32 (mp->count);
3998   vat_json_init_array (&root);
3999
4000   for (i = 0; i < n; i++)
4001     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
4002
4003   vat_json_print (vam->ofp, &root);
4004   vat_json_free (&root);
4005
4006 end:
4007   vam->retval = retval;
4008   vam->result_ready = 1;
4009 }
4010
4011 static void
4012   vl_api_one_ndp_entries_get_reply_t_handler
4013   (vl_api_one_ndp_entries_get_reply_t * mp)
4014 {
4015   vat_main_t *vam = &vat_main;
4016   u32 i, n;
4017   int retval = clib_net_to_host_u32 (mp->retval);
4018
4019   if (retval)
4020     goto end;
4021
4022   n = clib_net_to_host_u32 (mp->count);
4023
4024   for (i = 0; i < n; i++)
4025     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
4026            format_ethernet_address, mp->entries[i].mac);
4027
4028 end:
4029   vam->retval = retval;
4030   vam->result_ready = 1;
4031 }
4032
4033 static void
4034   vl_api_one_ndp_entries_get_reply_t_handler_json
4035   (vl_api_one_ndp_entries_get_reply_t * mp)
4036 {
4037   u8 *s = 0;
4038   vat_main_t *vam = &vat_main;
4039   vat_json_node_t *e = 0, root;
4040   u32 i, n;
4041   int retval = clib_net_to_host_u32 (mp->retval);
4042   vl_api_one_ndp_entry_t *arp_entry;
4043
4044   if (retval)
4045     goto end;
4046
4047   n = clib_net_to_host_u32 (mp->count);
4048   vat_json_init_array (&root);
4049
4050   for (i = 0; i < n; i++)
4051     {
4052       e = vat_json_array_add (&root);
4053       arp_entry = &mp->entries[i];
4054
4055       vat_json_init_object (e);
4056       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4057       vec_add1 (s, 0);
4058
4059       vat_json_object_add_string_copy (e, "mac", s);
4060       vec_free (s);
4061
4062       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4063       vec_add1 (s, 0);
4064       vat_json_object_add_string_copy (e, "ip6", s);
4065       vec_free (s);
4066     }
4067
4068   vat_json_print (vam->ofp, &root);
4069   vat_json_free (&root);
4070
4071 end:
4072   vam->retval = retval;
4073   vam->result_ready = 1;
4074 }
4075
4076 static void
4077   vl_api_one_l2_arp_entries_get_reply_t_handler
4078   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081   u32 i, n;
4082   int retval = clib_net_to_host_u32 (mp->retval);
4083
4084   if (retval)
4085     goto end;
4086
4087   n = clib_net_to_host_u32 (mp->count);
4088
4089   for (i = 0; i < n; i++)
4090     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4091            format_ethernet_address, mp->entries[i].mac);
4092
4093 end:
4094   vam->retval = retval;
4095   vam->result_ready = 1;
4096 }
4097
4098 static void
4099   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4100   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4101 {
4102   u8 *s = 0;
4103   vat_main_t *vam = &vat_main;
4104   vat_json_node_t *e = 0, root;
4105   u32 i, n;
4106   int retval = clib_net_to_host_u32 (mp->retval);
4107   vl_api_one_l2_arp_entry_t *arp_entry;
4108
4109   if (retval)
4110     goto end;
4111
4112   n = clib_net_to_host_u32 (mp->count);
4113   vat_json_init_array (&root);
4114
4115   for (i = 0; i < n; i++)
4116     {
4117       e = vat_json_array_add (&root);
4118       arp_entry = &mp->entries[i];
4119
4120       vat_json_init_object (e);
4121       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4122       vec_add1 (s, 0);
4123
4124       vat_json_object_add_string_copy (e, "mac", s);
4125       vec_free (s);
4126
4127       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4128       vec_add1 (s, 0);
4129       vat_json_object_add_string_copy (e, "ip4", s);
4130       vec_free (s);
4131     }
4132
4133   vat_json_print (vam->ofp, &root);
4134   vat_json_free (&root);
4135
4136 end:
4137   vam->retval = retval;
4138   vam->result_ready = 1;
4139 }
4140
4141 static void
4142 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4143 {
4144   vat_main_t *vam = &vat_main;
4145   u32 i, n;
4146   int retval = clib_net_to_host_u32 (mp->retval);
4147
4148   if (retval)
4149     goto end;
4150
4151   n = clib_net_to_host_u32 (mp->count);
4152
4153   for (i = 0; i < n; i++)
4154     {
4155       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4156     }
4157
4158 end:
4159   vam->retval = retval;
4160   vam->result_ready = 1;
4161 }
4162
4163 static void
4164   vl_api_one_ndp_bd_get_reply_t_handler_json
4165   (vl_api_one_ndp_bd_get_reply_t * mp)
4166 {
4167   vat_main_t *vam = &vat_main;
4168   vat_json_node_t root;
4169   u32 i, n;
4170   int retval = clib_net_to_host_u32 (mp->retval);
4171
4172   if (retval)
4173     goto end;
4174
4175   n = clib_net_to_host_u32 (mp->count);
4176   vat_json_init_array (&root);
4177
4178   for (i = 0; i < n; i++)
4179     {
4180       vat_json_array_add_uint (&root,
4181                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4182     }
4183
4184   vat_json_print (vam->ofp, &root);
4185   vat_json_free (&root);
4186
4187 end:
4188   vam->retval = retval;
4189   vam->result_ready = 1;
4190 }
4191
4192 static void
4193   vl_api_one_l2_arp_bd_get_reply_t_handler
4194   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4195 {
4196   vat_main_t *vam = &vat_main;
4197   u32 i, n;
4198   int retval = clib_net_to_host_u32 (mp->retval);
4199
4200   if (retval)
4201     goto end;
4202
4203   n = clib_net_to_host_u32 (mp->count);
4204
4205   for (i = 0; i < n; i++)
4206     {
4207       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4208     }
4209
4210 end:
4211   vam->retval = retval;
4212   vam->result_ready = 1;
4213 }
4214
4215 static void
4216   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4217   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4218 {
4219   vat_main_t *vam = &vat_main;
4220   vat_json_node_t root;
4221   u32 i, n;
4222   int retval = clib_net_to_host_u32 (mp->retval);
4223
4224   if (retval)
4225     goto end;
4226
4227   n = clib_net_to_host_u32 (mp->count);
4228   vat_json_init_array (&root);
4229
4230   for (i = 0; i < n; i++)
4231     {
4232       vat_json_array_add_uint (&root,
4233                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4234     }
4235
4236   vat_json_print (vam->ofp, &root);
4237   vat_json_free (&root);
4238
4239 end:
4240   vam->retval = retval;
4241   vam->result_ready = 1;
4242 }
4243
4244 static void
4245   vl_api_one_adjacencies_get_reply_t_handler
4246   (vl_api_one_adjacencies_get_reply_t * mp)
4247 {
4248   vat_main_t *vam = &vat_main;
4249   u32 i, n;
4250   int retval = clib_net_to_host_u32 (mp->retval);
4251   vl_api_one_adjacency_t *a;
4252
4253   if (retval)
4254     goto end;
4255
4256   n = clib_net_to_host_u32 (mp->count);
4257
4258   for (i = 0; i < n; i++)
4259     {
4260       a = &mp->adjacencies[i];
4261       print (vam->ofp, "%U %40U",
4262              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4263              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4264     }
4265
4266 end:
4267   vam->retval = retval;
4268   vam->result_ready = 1;
4269 }
4270
4271 static void
4272   vl_api_one_adjacencies_get_reply_t_handler_json
4273   (vl_api_one_adjacencies_get_reply_t * mp)
4274 {
4275   u8 *s = 0;
4276   vat_main_t *vam = &vat_main;
4277   vat_json_node_t *e = 0, root;
4278   u32 i, n;
4279   int retval = clib_net_to_host_u32 (mp->retval);
4280   vl_api_one_adjacency_t *a;
4281
4282   if (retval)
4283     goto end;
4284
4285   n = clib_net_to_host_u32 (mp->count);
4286   vat_json_init_array (&root);
4287
4288   for (i = 0; i < n; i++)
4289     {
4290       e = vat_json_array_add (&root);
4291       a = &mp->adjacencies[i];
4292
4293       vat_json_init_object (e);
4294       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4295                   a->leid_prefix_len);
4296       vec_add1 (s, 0);
4297       vat_json_object_add_string_copy (e, "leid", s);
4298       vec_free (s);
4299
4300       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4301                   a->reid_prefix_len);
4302       vec_add1 (s, 0);
4303       vat_json_object_add_string_copy (e, "reid", s);
4304       vec_free (s);
4305     }
4306
4307   vat_json_print (vam->ofp, &root);
4308   vat_json_free (&root);
4309
4310 end:
4311   vam->retval = retval;
4312   vam->result_ready = 1;
4313 }
4314
4315 static void
4316 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4317 {
4318   vat_main_t *vam = &vat_main;
4319
4320   print (vam->ofp, "%=20U",
4321          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4322          mp->ip_address);
4323 }
4324
4325 static void
4326   vl_api_one_map_server_details_t_handler_json
4327   (vl_api_one_map_server_details_t * mp)
4328 {
4329   vat_main_t *vam = &vat_main;
4330   vat_json_node_t *node = NULL;
4331   struct in6_addr ip6;
4332   struct in_addr ip4;
4333
4334   if (VAT_JSON_ARRAY != vam->json_tree.type)
4335     {
4336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4337       vat_json_init_array (&vam->json_tree);
4338     }
4339   node = vat_json_array_add (&vam->json_tree);
4340
4341   vat_json_init_object (node);
4342   if (mp->is_ipv6)
4343     {
4344       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4345       vat_json_object_add_ip6 (node, "map-server", ip6);
4346     }
4347   else
4348     {
4349       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4350       vat_json_object_add_ip4 (node, "map-server", ip4);
4351     }
4352 }
4353
4354 static void
4355 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4356                                            * mp)
4357 {
4358   vat_main_t *vam = &vat_main;
4359
4360   print (vam->ofp, "%=20U",
4361          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4362          mp->ip_address);
4363 }
4364
4365 static void
4366   vl_api_one_map_resolver_details_t_handler_json
4367   (vl_api_one_map_resolver_details_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t *node = NULL;
4371   struct in6_addr ip6;
4372   struct in_addr ip4;
4373
4374   if (VAT_JSON_ARRAY != vam->json_tree.type)
4375     {
4376       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4377       vat_json_init_array (&vam->json_tree);
4378     }
4379   node = vat_json_array_add (&vam->json_tree);
4380
4381   vat_json_init_object (node);
4382   if (mp->is_ipv6)
4383     {
4384       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4385       vat_json_object_add_ip6 (node, "map resolver", ip6);
4386     }
4387   else
4388     {
4389       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4390       vat_json_object_add_ip4 (node, "map resolver", ip4);
4391     }
4392 }
4393
4394 static void
4395 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4396 {
4397   vat_main_t *vam = &vat_main;
4398   i32 retval = ntohl (mp->retval);
4399
4400   if (0 <= retval)
4401     {
4402       print (vam->ofp, "feature: %s\ngpe: %s",
4403              mp->feature_status ? "enabled" : "disabled",
4404              mp->gpe_status ? "enabled" : "disabled");
4405     }
4406
4407   vam->retval = retval;
4408   vam->result_ready = 1;
4409 }
4410
4411 static void
4412   vl_api_show_one_status_reply_t_handler_json
4413   (vl_api_show_one_status_reply_t * mp)
4414 {
4415   vat_main_t *vam = &vat_main;
4416   vat_json_node_t node;
4417   u8 *gpe_status = NULL;
4418   u8 *feature_status = NULL;
4419
4420   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4421   feature_status = format (0, "%s",
4422                            mp->feature_status ? "enabled" : "disabled");
4423   vec_add1 (gpe_status, 0);
4424   vec_add1 (feature_status, 0);
4425
4426   vat_json_init_object (&node);
4427   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4428   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4429
4430   vec_free (gpe_status);
4431   vec_free (feature_status);
4432
4433   vat_json_print (vam->ofp, &node);
4434   vat_json_free (&node);
4435
4436   vam->retval = ntohl (mp->retval);
4437   vam->result_ready = 1;
4438 }
4439
4440 static void
4441   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4442   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4443 {
4444   vat_main_t *vam = &vat_main;
4445   i32 retval = ntohl (mp->retval);
4446
4447   if (retval >= 0)
4448     {
4449       print (vam->ofp, "%=20s", mp->locator_set_name);
4450     }
4451
4452   vam->retval = retval;
4453   vam->result_ready = 1;
4454 }
4455
4456 static void
4457   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4458   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4459 {
4460   vat_main_t *vam = &vat_main;
4461   vat_json_node_t *node = NULL;
4462
4463   if (VAT_JSON_ARRAY != vam->json_tree.type)
4464     {
4465       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4466       vat_json_init_array (&vam->json_tree);
4467     }
4468   node = vat_json_array_add (&vam->json_tree);
4469
4470   vat_json_init_object (node);
4471   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4472
4473   vat_json_print (vam->ofp, node);
4474   vat_json_free (node);
4475
4476   vam->retval = ntohl (mp->retval);
4477   vam->result_ready = 1;
4478 }
4479
4480 static u8 *
4481 format_lisp_map_request_mode (u8 * s, va_list * args)
4482 {
4483   u32 mode = va_arg (*args, u32);
4484
4485   switch (mode)
4486     {
4487     case 0:
4488       return format (0, "dst-only");
4489     case 1:
4490       return format (0, "src-dst");
4491     }
4492   return 0;
4493 }
4494
4495 static void
4496   vl_api_show_one_map_request_mode_reply_t_handler
4497   (vl_api_show_one_map_request_mode_reply_t * mp)
4498 {
4499   vat_main_t *vam = &vat_main;
4500   i32 retval = ntohl (mp->retval);
4501
4502   if (0 <= retval)
4503     {
4504       u32 mode = mp->mode;
4505       print (vam->ofp, "map_request_mode: %U",
4506              format_lisp_map_request_mode, mode);
4507     }
4508
4509   vam->retval = retval;
4510   vam->result_ready = 1;
4511 }
4512
4513 static void
4514   vl_api_show_one_map_request_mode_reply_t_handler_json
4515   (vl_api_show_one_map_request_mode_reply_t * mp)
4516 {
4517   vat_main_t *vam = &vat_main;
4518   vat_json_node_t node;
4519   u8 *s = 0;
4520   u32 mode;
4521
4522   mode = mp->mode;
4523   s = format (0, "%U", format_lisp_map_request_mode, mode);
4524   vec_add1 (s, 0);
4525
4526   vat_json_init_object (&node);
4527   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4528   vat_json_print (vam->ofp, &node);
4529   vat_json_free (&node);
4530
4531   vec_free (s);
4532   vam->retval = ntohl (mp->retval);
4533   vam->result_ready = 1;
4534 }
4535
4536 static void
4537   vl_api_one_show_xtr_mode_reply_t_handler
4538   (vl_api_one_show_xtr_mode_reply_t * mp)
4539 {
4540   vat_main_t *vam = &vat_main;
4541   i32 retval = ntohl (mp->retval);
4542
4543   if (0 <= retval)
4544     {
4545       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4546     }
4547
4548   vam->retval = retval;
4549   vam->result_ready = 1;
4550 }
4551
4552 static void
4553   vl_api_one_show_xtr_mode_reply_t_handler_json
4554   (vl_api_one_show_xtr_mode_reply_t * mp)
4555 {
4556   vat_main_t *vam = &vat_main;
4557   vat_json_node_t node;
4558   u8 *status = 0;
4559
4560   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4561   vec_add1 (status, 0);
4562
4563   vat_json_init_object (&node);
4564   vat_json_object_add_string_copy (&node, "status", status);
4565
4566   vec_free (status);
4567
4568   vat_json_print (vam->ofp, &node);
4569   vat_json_free (&node);
4570
4571   vam->retval = ntohl (mp->retval);
4572   vam->result_ready = 1;
4573 }
4574
4575 static void
4576   vl_api_one_show_pitr_mode_reply_t_handler
4577   (vl_api_one_show_pitr_mode_reply_t * mp)
4578 {
4579   vat_main_t *vam = &vat_main;
4580   i32 retval = ntohl (mp->retval);
4581
4582   if (0 <= retval)
4583     {
4584       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4585     }
4586
4587   vam->retval = retval;
4588   vam->result_ready = 1;
4589 }
4590
4591 static void
4592   vl_api_one_show_pitr_mode_reply_t_handler_json
4593   (vl_api_one_show_pitr_mode_reply_t * mp)
4594 {
4595   vat_main_t *vam = &vat_main;
4596   vat_json_node_t node;
4597   u8 *status = 0;
4598
4599   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4600   vec_add1 (status, 0);
4601
4602   vat_json_init_object (&node);
4603   vat_json_object_add_string_copy (&node, "status", status);
4604
4605   vec_free (status);
4606
4607   vat_json_print (vam->ofp, &node);
4608   vat_json_free (&node);
4609
4610   vam->retval = ntohl (mp->retval);
4611   vam->result_ready = 1;
4612 }
4613
4614 static void
4615   vl_api_one_show_petr_mode_reply_t_handler
4616   (vl_api_one_show_petr_mode_reply_t * mp)
4617 {
4618   vat_main_t *vam = &vat_main;
4619   i32 retval = ntohl (mp->retval);
4620
4621   if (0 <= retval)
4622     {
4623       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4624     }
4625
4626   vam->retval = retval;
4627   vam->result_ready = 1;
4628 }
4629
4630 static void
4631   vl_api_one_show_petr_mode_reply_t_handler_json
4632   (vl_api_one_show_petr_mode_reply_t * mp)
4633 {
4634   vat_main_t *vam = &vat_main;
4635   vat_json_node_t node;
4636   u8 *status = 0;
4637
4638   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4639   vec_add1 (status, 0);
4640
4641   vat_json_init_object (&node);
4642   vat_json_object_add_string_copy (&node, "status", status);
4643
4644   vec_free (status);
4645
4646   vat_json_print (vam->ofp, &node);
4647   vat_json_free (&node);
4648
4649   vam->retval = ntohl (mp->retval);
4650   vam->result_ready = 1;
4651 }
4652
4653 static void
4654   vl_api_show_one_use_petr_reply_t_handler
4655   (vl_api_show_one_use_petr_reply_t * mp)
4656 {
4657   vat_main_t *vam = &vat_main;
4658   i32 retval = ntohl (mp->retval);
4659
4660   if (0 <= retval)
4661     {
4662       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4663       if (mp->status)
4664         {
4665           print (vam->ofp, "Proxy-ETR address; %U",
4666                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4667                  mp->address);
4668         }
4669     }
4670
4671   vam->retval = retval;
4672   vam->result_ready = 1;
4673 }
4674
4675 static void
4676   vl_api_show_one_use_petr_reply_t_handler_json
4677   (vl_api_show_one_use_petr_reply_t * mp)
4678 {
4679   vat_main_t *vam = &vat_main;
4680   vat_json_node_t node;
4681   u8 *status = 0;
4682   struct in_addr ip4;
4683   struct in6_addr ip6;
4684
4685   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4686   vec_add1 (status, 0);
4687
4688   vat_json_init_object (&node);
4689   vat_json_object_add_string_copy (&node, "status", status);
4690   if (mp->status)
4691     {
4692       if (mp->is_ip4)
4693         {
4694           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4695           vat_json_object_add_ip6 (&node, "address", ip6);
4696         }
4697       else
4698         {
4699           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4700           vat_json_object_add_ip4 (&node, "address", ip4);
4701         }
4702     }
4703
4704   vec_free (status);
4705
4706   vat_json_print (vam->ofp, &node);
4707   vat_json_free (&node);
4708
4709   vam->retval = ntohl (mp->retval);
4710   vam->result_ready = 1;
4711 }
4712
4713 static void
4714   vl_api_show_one_nsh_mapping_reply_t_handler
4715   (vl_api_show_one_nsh_mapping_reply_t * mp)
4716 {
4717   vat_main_t *vam = &vat_main;
4718   i32 retval = ntohl (mp->retval);
4719
4720   if (0 <= retval)
4721     {
4722       print (vam->ofp, "%-20s%-16s",
4723              mp->is_set ? "set" : "not-set",
4724              mp->is_set ? (char *) mp->locator_set_name : "");
4725     }
4726
4727   vam->retval = retval;
4728   vam->result_ready = 1;
4729 }
4730
4731 static void
4732   vl_api_show_one_nsh_mapping_reply_t_handler_json
4733   (vl_api_show_one_nsh_mapping_reply_t * mp)
4734 {
4735   vat_main_t *vam = &vat_main;
4736   vat_json_node_t node;
4737   u8 *status = 0;
4738
4739   status = format (0, "%s", mp->is_set ? "yes" : "no");
4740   vec_add1 (status, 0);
4741
4742   vat_json_init_object (&node);
4743   vat_json_object_add_string_copy (&node, "is_set", status);
4744   if (mp->is_set)
4745     {
4746       vat_json_object_add_string_copy (&node, "locator_set",
4747                                        mp->locator_set_name);
4748     }
4749
4750   vec_free (status);
4751
4752   vat_json_print (vam->ofp, &node);
4753   vat_json_free (&node);
4754
4755   vam->retval = ntohl (mp->retval);
4756   vam->result_ready = 1;
4757 }
4758
4759 static void
4760   vl_api_show_one_map_register_ttl_reply_t_handler
4761   (vl_api_show_one_map_register_ttl_reply_t * mp)
4762 {
4763   vat_main_t *vam = &vat_main;
4764   i32 retval = ntohl (mp->retval);
4765
4766   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4767
4768   if (0 <= retval)
4769     {
4770       print (vam->ofp, "ttl: %u", mp->ttl);
4771     }
4772
4773   vam->retval = retval;
4774   vam->result_ready = 1;
4775 }
4776
4777 static void
4778   vl_api_show_one_map_register_ttl_reply_t_handler_json
4779   (vl_api_show_one_map_register_ttl_reply_t * mp)
4780 {
4781   vat_main_t *vam = &vat_main;
4782   vat_json_node_t node;
4783
4784   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4785   vat_json_init_object (&node);
4786   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4787
4788   vat_json_print (vam->ofp, &node);
4789   vat_json_free (&node);
4790
4791   vam->retval = ntohl (mp->retval);
4792   vam->result_ready = 1;
4793 }
4794
4795 static void
4796 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4797 {
4798   vat_main_t *vam = &vat_main;
4799   i32 retval = ntohl (mp->retval);
4800
4801   if (0 <= retval)
4802     {
4803       print (vam->ofp, "%-20s%-16s",
4804              mp->status ? "enabled" : "disabled",
4805              mp->status ? (char *) mp->locator_set_name : "");
4806     }
4807
4808   vam->retval = retval;
4809   vam->result_ready = 1;
4810 }
4811
4812 static void
4813 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4814 {
4815   vat_main_t *vam = &vat_main;
4816   vat_json_node_t node;
4817   u8 *status = 0;
4818
4819   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4820   vec_add1 (status, 0);
4821
4822   vat_json_init_object (&node);
4823   vat_json_object_add_string_copy (&node, "status", status);
4824   if (mp->status)
4825     {
4826       vat_json_object_add_string_copy (&node, "locator_set",
4827                                        mp->locator_set_name);
4828     }
4829
4830   vec_free (status);
4831
4832   vat_json_print (vam->ofp, &node);
4833   vat_json_free (&node);
4834
4835   vam->retval = ntohl (mp->retval);
4836   vam->result_ready = 1;
4837 }
4838
4839 static u8 *
4840 format_policer_type (u8 * s, va_list * va)
4841 {
4842   u32 i = va_arg (*va, u32);
4843
4844   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4845     s = format (s, "1r2c");
4846   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4847     s = format (s, "1r3c");
4848   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4849     s = format (s, "2r3c-2698");
4850   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4851     s = format (s, "2r3c-4115");
4852   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4853     s = format (s, "2r3c-mef5cf1");
4854   else
4855     s = format (s, "ILLEGAL");
4856   return s;
4857 }
4858
4859 static u8 *
4860 format_policer_rate_type (u8 * s, va_list * va)
4861 {
4862   u32 i = va_arg (*va, u32);
4863
4864   if (i == SSE2_QOS_RATE_KBPS)
4865     s = format (s, "kbps");
4866   else if (i == SSE2_QOS_RATE_PPS)
4867     s = format (s, "pps");
4868   else
4869     s = format (s, "ILLEGAL");
4870   return s;
4871 }
4872
4873 static u8 *
4874 format_policer_round_type (u8 * s, va_list * va)
4875 {
4876   u32 i = va_arg (*va, u32);
4877
4878   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4879     s = format (s, "closest");
4880   else if (i == SSE2_QOS_ROUND_TO_UP)
4881     s = format (s, "up");
4882   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4883     s = format (s, "down");
4884   else
4885     s = format (s, "ILLEGAL");
4886   return s;
4887 }
4888
4889 static u8 *
4890 format_policer_action_type (u8 * s, va_list * va)
4891 {
4892   u32 i = va_arg (*va, u32);
4893
4894   if (i == SSE2_QOS_ACTION_DROP)
4895     s = format (s, "drop");
4896   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4897     s = format (s, "transmit");
4898   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4899     s = format (s, "mark-and-transmit");
4900   else
4901     s = format (s, "ILLEGAL");
4902   return s;
4903 }
4904
4905 static u8 *
4906 format_dscp (u8 * s, va_list * va)
4907 {
4908   u32 i = va_arg (*va, u32);
4909   char *t = 0;
4910
4911   switch (i)
4912     {
4913 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4914       foreach_vnet_dscp
4915 #undef _
4916     default:
4917       return format (s, "ILLEGAL");
4918     }
4919   s = format (s, "%s", t);
4920   return s;
4921 }
4922
4923 static void
4924 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4928
4929   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4930     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4931   else
4932     conform_dscp_str = format (0, "");
4933
4934   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4935     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4936   else
4937     exceed_dscp_str = format (0, "");
4938
4939   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4940     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4941   else
4942     violate_dscp_str = format (0, "");
4943
4944   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4945          "rate type %U, round type %U, %s rate, %s color-aware, "
4946          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4947          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4948          "conform action %U%s, exceed action %U%s, violate action %U%s",
4949          mp->name,
4950          format_policer_type, mp->type,
4951          ntohl (mp->cir),
4952          ntohl (mp->eir),
4953          clib_net_to_host_u64 (mp->cb),
4954          clib_net_to_host_u64 (mp->eb),
4955          format_policer_rate_type, mp->rate_type,
4956          format_policer_round_type, mp->round_type,
4957          mp->single_rate ? "single" : "dual",
4958          mp->color_aware ? "is" : "not",
4959          ntohl (mp->cir_tokens_per_period),
4960          ntohl (mp->pir_tokens_per_period),
4961          ntohl (mp->scale),
4962          ntohl (mp->current_limit),
4963          ntohl (mp->current_bucket),
4964          ntohl (mp->extended_limit),
4965          ntohl (mp->extended_bucket),
4966          clib_net_to_host_u64 (mp->last_update_time),
4967          format_policer_action_type, mp->conform_action_type,
4968          conform_dscp_str,
4969          format_policer_action_type, mp->exceed_action_type,
4970          exceed_dscp_str,
4971          format_policer_action_type, mp->violate_action_type,
4972          violate_dscp_str);
4973
4974   vec_free (conform_dscp_str);
4975   vec_free (exceed_dscp_str);
4976   vec_free (violate_dscp_str);
4977 }
4978
4979 static void vl_api_policer_details_t_handler_json
4980   (vl_api_policer_details_t * mp)
4981 {
4982   vat_main_t *vam = &vat_main;
4983   vat_json_node_t *node;
4984   u8 *rate_type_str, *round_type_str, *type_str;
4985   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4986
4987   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4988   round_type_str =
4989     format (0, "%U", format_policer_round_type, mp->round_type);
4990   type_str = format (0, "%U", format_policer_type, mp->type);
4991   conform_action_str = format (0, "%U", format_policer_action_type,
4992                                mp->conform_action_type);
4993   exceed_action_str = format (0, "%U", format_policer_action_type,
4994                               mp->exceed_action_type);
4995   violate_action_str = format (0, "%U", format_policer_action_type,
4996                                mp->violate_action_type);
4997
4998   if (VAT_JSON_ARRAY != vam->json_tree.type)
4999     {
5000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5001       vat_json_init_array (&vam->json_tree);
5002     }
5003   node = vat_json_array_add (&vam->json_tree);
5004
5005   vat_json_init_object (node);
5006   vat_json_object_add_string_copy (node, "name", mp->name);
5007   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
5008   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
5009   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
5010   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
5011   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
5012   vat_json_object_add_string_copy (node, "round_type", round_type_str);
5013   vat_json_object_add_string_copy (node, "type", type_str);
5014   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
5015   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
5016   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
5017   vat_json_object_add_uint (node, "cir_tokens_per_period",
5018                             ntohl (mp->cir_tokens_per_period));
5019   vat_json_object_add_uint (node, "eir_tokens_per_period",
5020                             ntohl (mp->pir_tokens_per_period));
5021   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
5022   vat_json_object_add_uint (node, "current_bucket",
5023                             ntohl (mp->current_bucket));
5024   vat_json_object_add_uint (node, "extended_limit",
5025                             ntohl (mp->extended_limit));
5026   vat_json_object_add_uint (node, "extended_bucket",
5027                             ntohl (mp->extended_bucket));
5028   vat_json_object_add_uint (node, "last_update_time",
5029                             ntohl (mp->last_update_time));
5030   vat_json_object_add_string_copy (node, "conform_action",
5031                                    conform_action_str);
5032   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5033     {
5034       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5035       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5036       vec_free (dscp_str);
5037     }
5038   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5039   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5040     {
5041       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5042       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5043       vec_free (dscp_str);
5044     }
5045   vat_json_object_add_string_copy (node, "violate_action",
5046                                    violate_action_str);
5047   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5048     {
5049       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5050       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5051       vec_free (dscp_str);
5052     }
5053
5054   vec_free (rate_type_str);
5055   vec_free (round_type_str);
5056   vec_free (type_str);
5057   vec_free (conform_action_str);
5058   vec_free (exceed_action_str);
5059   vec_free (violate_action_str);
5060 }
5061
5062 static void
5063 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5064                                            mp)
5065 {
5066   vat_main_t *vam = &vat_main;
5067   int i, count = ntohl (mp->count);
5068
5069   if (count > 0)
5070     print (vam->ofp, "classify table ids (%d) : ", count);
5071   for (i = 0; i < count; i++)
5072     {
5073       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5074       print (vam->ofp, (i < count - 1) ? "," : "");
5075     }
5076   vam->retval = ntohl (mp->retval);
5077   vam->result_ready = 1;
5078 }
5079
5080 static void
5081   vl_api_classify_table_ids_reply_t_handler_json
5082   (vl_api_classify_table_ids_reply_t * mp)
5083 {
5084   vat_main_t *vam = &vat_main;
5085   int i, count = ntohl (mp->count);
5086
5087   if (count > 0)
5088     {
5089       vat_json_node_t node;
5090
5091       vat_json_init_object (&node);
5092       for (i = 0; i < count; i++)
5093         {
5094           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5095         }
5096       vat_json_print (vam->ofp, &node);
5097       vat_json_free (&node);
5098     }
5099   vam->retval = ntohl (mp->retval);
5100   vam->result_ready = 1;
5101 }
5102
5103 static void
5104   vl_api_classify_table_by_interface_reply_t_handler
5105   (vl_api_classify_table_by_interface_reply_t * mp)
5106 {
5107   vat_main_t *vam = &vat_main;
5108   u32 table_id;
5109
5110   table_id = ntohl (mp->l2_table_id);
5111   if (table_id != ~0)
5112     print (vam->ofp, "l2 table id : %d", table_id);
5113   else
5114     print (vam->ofp, "l2 table id : No input ACL tables configured");
5115   table_id = ntohl (mp->ip4_table_id);
5116   if (table_id != ~0)
5117     print (vam->ofp, "ip4 table id : %d", table_id);
5118   else
5119     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5120   table_id = ntohl (mp->ip6_table_id);
5121   if (table_id != ~0)
5122     print (vam->ofp, "ip6 table id : %d", table_id);
5123   else
5124     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5125   vam->retval = ntohl (mp->retval);
5126   vam->result_ready = 1;
5127 }
5128
5129 static void
5130   vl_api_classify_table_by_interface_reply_t_handler_json
5131   (vl_api_classify_table_by_interface_reply_t * mp)
5132 {
5133   vat_main_t *vam = &vat_main;
5134   vat_json_node_t node;
5135
5136   vat_json_init_object (&node);
5137
5138   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5139   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5140   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5141
5142   vat_json_print (vam->ofp, &node);
5143   vat_json_free (&node);
5144
5145   vam->retval = ntohl (mp->retval);
5146   vam->result_ready = 1;
5147 }
5148
5149 static void vl_api_policer_add_del_reply_t_handler
5150   (vl_api_policer_add_del_reply_t * mp)
5151 {
5152   vat_main_t *vam = &vat_main;
5153   i32 retval = ntohl (mp->retval);
5154   if (vam->async_mode)
5155     {
5156       vam->async_errors += (retval < 0);
5157     }
5158   else
5159     {
5160       vam->retval = retval;
5161       vam->result_ready = 1;
5162       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5163         /*
5164          * Note: this is just barely thread-safe, depends on
5165          * the main thread spinning waiting for an answer...
5166          */
5167         errmsg ("policer index %d", ntohl (mp->policer_index));
5168     }
5169 }
5170
5171 static void vl_api_policer_add_del_reply_t_handler_json
5172   (vl_api_policer_add_del_reply_t * mp)
5173 {
5174   vat_main_t *vam = &vat_main;
5175   vat_json_node_t node;
5176
5177   vat_json_init_object (&node);
5178   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5179   vat_json_object_add_uint (&node, "policer_index",
5180                             ntohl (mp->policer_index));
5181
5182   vat_json_print (vam->ofp, &node);
5183   vat_json_free (&node);
5184
5185   vam->retval = ntohl (mp->retval);
5186   vam->result_ready = 1;
5187 }
5188
5189 /* Format hex dump. */
5190 u8 *
5191 format_hex_bytes (u8 * s, va_list * va)
5192 {
5193   u8 *bytes = va_arg (*va, u8 *);
5194   int n_bytes = va_arg (*va, int);
5195   uword i;
5196
5197   /* Print short or long form depending on byte count. */
5198   uword short_form = n_bytes <= 32;
5199   u32 indent = format_get_indent (s);
5200
5201   if (n_bytes == 0)
5202     return s;
5203
5204   for (i = 0; i < n_bytes; i++)
5205     {
5206       if (!short_form && (i % 32) == 0)
5207         s = format (s, "%08x: ", i);
5208       s = format (s, "%02x", bytes[i]);
5209       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5210         s = format (s, "\n%U", format_white_space, indent);
5211     }
5212
5213   return s;
5214 }
5215
5216 static void
5217 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5218                                             * mp)
5219 {
5220   vat_main_t *vam = &vat_main;
5221   i32 retval = ntohl (mp->retval);
5222   if (retval == 0)
5223     {
5224       print (vam->ofp, "classify table info :");
5225       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5226              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5227              ntohl (mp->miss_next_index));
5228       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5229              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5230              ntohl (mp->match_n_vectors));
5231       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5232              ntohl (mp->mask_length));
5233     }
5234   vam->retval = retval;
5235   vam->result_ready = 1;
5236 }
5237
5238 static void
5239   vl_api_classify_table_info_reply_t_handler_json
5240   (vl_api_classify_table_info_reply_t * mp)
5241 {
5242   vat_main_t *vam = &vat_main;
5243   vat_json_node_t node;
5244
5245   i32 retval = ntohl (mp->retval);
5246   if (retval == 0)
5247     {
5248       vat_json_init_object (&node);
5249
5250       vat_json_object_add_int (&node, "sessions",
5251                                ntohl (mp->active_sessions));
5252       vat_json_object_add_int (&node, "nexttbl",
5253                                ntohl (mp->next_table_index));
5254       vat_json_object_add_int (&node, "nextnode",
5255                                ntohl (mp->miss_next_index));
5256       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5257       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5258       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5259       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5260                       ntohl (mp->mask_length), 0);
5261       vat_json_object_add_string_copy (&node, "mask", s);
5262
5263       vat_json_print (vam->ofp, &node);
5264       vat_json_free (&node);
5265     }
5266   vam->retval = ntohl (mp->retval);
5267   vam->result_ready = 1;
5268 }
5269
5270 static void
5271 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5272                                            mp)
5273 {
5274   vat_main_t *vam = &vat_main;
5275
5276   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5277          ntohl (mp->hit_next_index), ntohl (mp->advance),
5278          ntohl (mp->opaque_index));
5279   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5280          ntohl (mp->match_length));
5281 }
5282
5283 static void
5284   vl_api_classify_session_details_t_handler_json
5285   (vl_api_classify_session_details_t * mp)
5286 {
5287   vat_main_t *vam = &vat_main;
5288   vat_json_node_t *node = NULL;
5289
5290   if (VAT_JSON_ARRAY != vam->json_tree.type)
5291     {
5292       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5293       vat_json_init_array (&vam->json_tree);
5294     }
5295   node = vat_json_array_add (&vam->json_tree);
5296
5297   vat_json_init_object (node);
5298   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5299   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5300   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5301   u8 *s =
5302     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5303             0);
5304   vat_json_object_add_string_copy (node, "match", s);
5305 }
5306
5307 static void vl_api_pg_create_interface_reply_t_handler
5308   (vl_api_pg_create_interface_reply_t * mp)
5309 {
5310   vat_main_t *vam = &vat_main;
5311
5312   vam->retval = ntohl (mp->retval);
5313   vam->result_ready = 1;
5314 }
5315
5316 static void vl_api_pg_create_interface_reply_t_handler_json
5317   (vl_api_pg_create_interface_reply_t * mp)
5318 {
5319   vat_main_t *vam = &vat_main;
5320   vat_json_node_t node;
5321
5322   i32 retval = ntohl (mp->retval);
5323   if (retval == 0)
5324     {
5325       vat_json_init_object (&node);
5326
5327       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5328
5329       vat_json_print (vam->ofp, &node);
5330       vat_json_free (&node);
5331     }
5332   vam->retval = ntohl (mp->retval);
5333   vam->result_ready = 1;
5334 }
5335
5336 static void vl_api_policer_classify_details_t_handler
5337   (vl_api_policer_classify_details_t * mp)
5338 {
5339   vat_main_t *vam = &vat_main;
5340
5341   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5342          ntohl (mp->table_index));
5343 }
5344
5345 static void vl_api_policer_classify_details_t_handler_json
5346   (vl_api_policer_classify_details_t * mp)
5347 {
5348   vat_main_t *vam = &vat_main;
5349   vat_json_node_t *node;
5350
5351   if (VAT_JSON_ARRAY != vam->json_tree.type)
5352     {
5353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5354       vat_json_init_array (&vam->json_tree);
5355     }
5356   node = vat_json_array_add (&vam->json_tree);
5357
5358   vat_json_init_object (node);
5359   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5360   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5361 }
5362
5363 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5364   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5365 {
5366   vat_main_t *vam = &vat_main;
5367   i32 retval = ntohl (mp->retval);
5368   if (vam->async_mode)
5369     {
5370       vam->async_errors += (retval < 0);
5371     }
5372   else
5373     {
5374       vam->retval = retval;
5375       vam->sw_if_index = ntohl (mp->sw_if_index);
5376       vam->result_ready = 1;
5377     }
5378   vam->regenerate_interface_table = 1;
5379 }
5380
5381 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5382   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5383 {
5384   vat_main_t *vam = &vat_main;
5385   vat_json_node_t node;
5386
5387   vat_json_init_object (&node);
5388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5389   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5390
5391   vat_json_print (vam->ofp, &node);
5392   vat_json_free (&node);
5393
5394   vam->retval = ntohl (mp->retval);
5395   vam->result_ready = 1;
5396 }
5397
5398 static void vl_api_flow_classify_details_t_handler
5399   (vl_api_flow_classify_details_t * mp)
5400 {
5401   vat_main_t *vam = &vat_main;
5402
5403   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5404          ntohl (mp->table_index));
5405 }
5406
5407 static void vl_api_flow_classify_details_t_handler_json
5408   (vl_api_flow_classify_details_t * mp)
5409 {
5410   vat_main_t *vam = &vat_main;
5411   vat_json_node_t *node;
5412
5413   if (VAT_JSON_ARRAY != vam->json_tree.type)
5414     {
5415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5416       vat_json_init_array (&vam->json_tree);
5417     }
5418   node = vat_json_array_add (&vam->json_tree);
5419
5420   vat_json_init_object (node);
5421   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5422   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5423 }
5424
5425 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5426 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5427 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5428 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5429 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5430 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5431 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5432 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5433 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5434 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5435 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5436 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5437 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5438 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5439 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5440 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5441 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5442 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5443 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5444 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5445 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5446 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5447
5448 /*
5449  * Generate boilerplate reply handlers, which
5450  * dig the return value out of the xxx_reply_t API message,
5451  * stick it into vam->retval, and set vam->result_ready
5452  *
5453  * Could also do this by pointing N message decode slots at
5454  * a single function, but that could break in subtle ways.
5455  */
5456
5457 #define foreach_standard_reply_retval_handler           \
5458 _(sw_interface_set_flags_reply)                         \
5459 _(sw_interface_add_del_address_reply)                   \
5460 _(sw_interface_set_rx_mode_reply)                       \
5461 _(sw_interface_set_rx_placement_reply)                  \
5462 _(sw_interface_set_table_reply)                         \
5463 _(sw_interface_set_mpls_enable_reply)                   \
5464 _(sw_interface_set_vpath_reply)                         \
5465 _(sw_interface_set_vxlan_bypass_reply)                  \
5466 _(sw_interface_set_geneve_bypass_reply)                 \
5467 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5468 _(sw_interface_set_l2_bridge_reply)                     \
5469 _(bridge_domain_add_del_reply)                          \
5470 _(sw_interface_set_l2_xconnect_reply)                   \
5471 _(l2fib_add_del_reply)                                  \
5472 _(l2fib_flush_int_reply)                                \
5473 _(l2fib_flush_bd_reply)                                 \
5474 _(ip_add_del_route_reply)                               \
5475 _(ip_table_add_del_reply)                               \
5476 _(ip_mroute_add_del_reply)                              \
5477 _(mpls_route_add_del_reply)                             \
5478 _(mpls_table_add_del_reply)                             \
5479 _(mpls_ip_bind_unbind_reply)                            \
5480 _(bier_route_add_del_reply)                             \
5481 _(bier_table_add_del_reply)                             \
5482 _(proxy_arp_add_del_reply)                              \
5483 _(proxy_arp_intfc_enable_disable_reply)                 \
5484 _(sw_interface_set_unnumbered_reply)                    \
5485 _(ip_neighbor_add_del_reply)                            \
5486 _(oam_add_del_reply)                                    \
5487 _(reset_fib_reply)                                      \
5488 _(dhcp_proxy_config_reply)                              \
5489 _(dhcp_proxy_set_vss_reply)                             \
5490 _(dhcp_client_config_reply)                             \
5491 _(set_ip_flow_hash_reply)                               \
5492 _(sw_interface_ip6_enable_disable_reply)                \
5493 _(ip6nd_proxy_add_del_reply)                            \
5494 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5495 _(sw_interface_ip6nd_ra_config_reply)                   \
5496 _(set_arp_neighbor_limit_reply)                         \
5497 _(l2_patch_add_del_reply)                               \
5498 _(sr_mpls_policy_add_reply)                             \
5499 _(sr_mpls_policy_mod_reply)                             \
5500 _(sr_mpls_policy_del_reply)                             \
5501 _(sr_policy_add_reply)                                  \
5502 _(sr_policy_mod_reply)                                  \
5503 _(sr_policy_del_reply)                                  \
5504 _(sr_localsid_add_del_reply)                            \
5505 _(sr_steering_add_del_reply)                            \
5506 _(classify_add_del_session_reply)                       \
5507 _(classify_set_interface_ip_table_reply)                \
5508 _(classify_set_interface_l2_tables_reply)               \
5509 _(l2tpv3_set_tunnel_cookies_reply)                      \
5510 _(l2tpv3_interface_enable_disable_reply)                \
5511 _(l2tpv3_set_lookup_key_reply)                          \
5512 _(l2_fib_clear_table_reply)                             \
5513 _(l2_interface_efp_filter_reply)                        \
5514 _(l2_interface_vlan_tag_rewrite_reply)                  \
5515 _(modify_vhost_user_if_reply)                           \
5516 _(delete_vhost_user_if_reply)                           \
5517 _(ip_probe_neighbor_reply)                              \
5518 _(ip_scan_neighbor_enable_disable_reply)                \
5519 _(want_ip4_arp_events_reply)                            \
5520 _(want_ip6_nd_events_reply)                             \
5521 _(want_l2_macs_events_reply)                            \
5522 _(input_acl_set_interface_reply)                        \
5523 _(ipsec_spd_add_del_reply)                              \
5524 _(ipsec_interface_add_del_spd_reply)                    \
5525 _(ipsec_spd_add_del_entry_reply)                        \
5526 _(ipsec_sad_add_del_entry_reply)                        \
5527 _(ipsec_sa_set_key_reply)                               \
5528 _(ipsec_tunnel_if_add_del_reply)                        \
5529 _(ipsec_tunnel_if_set_key_reply)                        \
5530 _(ipsec_tunnel_if_set_sa_reply)                         \
5531 _(ikev2_profile_add_del_reply)                          \
5532 _(ikev2_profile_set_auth_reply)                         \
5533 _(ikev2_profile_set_id_reply)                           \
5534 _(ikev2_profile_set_ts_reply)                           \
5535 _(ikev2_set_local_key_reply)                            \
5536 _(ikev2_set_responder_reply)                            \
5537 _(ikev2_set_ike_transforms_reply)                       \
5538 _(ikev2_set_esp_transforms_reply)                       \
5539 _(ikev2_set_sa_lifetime_reply)                          \
5540 _(ikev2_initiate_sa_init_reply)                         \
5541 _(ikev2_initiate_del_ike_sa_reply)                      \
5542 _(ikev2_initiate_del_child_sa_reply)                    \
5543 _(ikev2_initiate_rekey_child_sa_reply)                  \
5544 _(delete_loopback_reply)                                \
5545 _(bd_ip_mac_add_del_reply)                              \
5546 _(want_interface_events_reply)                          \
5547 _(want_stats_reply)                                     \
5548 _(cop_interface_enable_disable_reply)                   \
5549 _(cop_whitelist_enable_disable_reply)                   \
5550 _(sw_interface_clear_stats_reply)                       \
5551 _(ioam_enable_reply)                                    \
5552 _(ioam_disable_reply)                                   \
5553 _(one_add_del_locator_reply)                            \
5554 _(one_add_del_local_eid_reply)                          \
5555 _(one_add_del_remote_mapping_reply)                     \
5556 _(one_add_del_adjacency_reply)                          \
5557 _(one_add_del_map_resolver_reply)                       \
5558 _(one_add_del_map_server_reply)                         \
5559 _(one_enable_disable_reply)                             \
5560 _(one_rloc_probe_enable_disable_reply)                  \
5561 _(one_map_register_enable_disable_reply)                \
5562 _(one_map_register_set_ttl_reply)                       \
5563 _(one_set_transport_protocol_reply)                     \
5564 _(one_map_register_fallback_threshold_reply)            \
5565 _(one_pitr_set_locator_set_reply)                       \
5566 _(one_map_request_mode_reply)                           \
5567 _(one_add_del_map_request_itr_rlocs_reply)              \
5568 _(one_eid_table_add_del_map_reply)                      \
5569 _(one_use_petr_reply)                                   \
5570 _(one_stats_enable_disable_reply)                       \
5571 _(one_add_del_l2_arp_entry_reply)                       \
5572 _(one_add_del_ndp_entry_reply)                          \
5573 _(one_stats_flush_reply)                                \
5574 _(one_enable_disable_xtr_mode_reply)                    \
5575 _(one_enable_disable_pitr_mode_reply)                   \
5576 _(one_enable_disable_petr_mode_reply)                   \
5577 _(gpe_enable_disable_reply)                             \
5578 _(gpe_set_encap_mode_reply)                             \
5579 _(gpe_add_del_iface_reply)                              \
5580 _(gpe_add_del_native_fwd_rpath_reply)                   \
5581 _(af_packet_delete_reply)                               \
5582 _(policer_classify_set_interface_reply)                 \
5583 _(netmap_create_reply)                                  \
5584 _(netmap_delete_reply)                                  \
5585 _(set_ipfix_exporter_reply)                             \
5586 _(set_ipfix_classify_stream_reply)                      \
5587 _(ipfix_classify_table_add_del_reply)                   \
5588 _(flow_classify_set_interface_reply)                    \
5589 _(sw_interface_span_enable_disable_reply)               \
5590 _(pg_capture_reply)                                     \
5591 _(pg_enable_disable_reply)                              \
5592 _(ip_source_and_port_range_check_add_del_reply)         \
5593 _(ip_source_and_port_range_check_interface_add_del_reply)\
5594 _(delete_subif_reply)                                   \
5595 _(l2_interface_pbb_tag_rewrite_reply)                   \
5596 _(set_punt_reply)                                       \
5597 _(feature_enable_disable_reply)                         \
5598 _(sw_interface_tag_add_del_reply)                       \
5599 _(hw_interface_set_mtu_reply)                           \
5600 _(p2p_ethernet_add_reply)                               \
5601 _(p2p_ethernet_del_reply)                               \
5602 _(lldp_config_reply)                                    \
5603 _(sw_interface_set_lldp_reply)                          \
5604 _(tcp_configure_src_addresses_reply)                    \
5605 _(dns_enable_disable_reply)                             \
5606 _(dns_name_server_add_del_reply)                        \
5607 _(session_rule_add_del_reply)                           \
5608 _(ip_container_proxy_add_del_reply)                     \
5609 _(output_acl_set_interface_reply)                       \
5610 _(qos_record_enable_disable_reply)
5611
5612 #define _(n)                                    \
5613     static void vl_api_##n##_t_handler          \
5614     (vl_api_##n##_t * mp)                       \
5615     {                                           \
5616         vat_main_t * vam = &vat_main;           \
5617         i32 retval = ntohl(mp->retval);         \
5618         if (vam->async_mode) {                  \
5619             vam->async_errors += (retval < 0);  \
5620         } else {                                \
5621             vam->retval = retval;               \
5622             vam->result_ready = 1;              \
5623         }                                       \
5624     }
5625 foreach_standard_reply_retval_handler;
5626 #undef _
5627
5628 #define _(n)                                    \
5629     static void vl_api_##n##_t_handler_json     \
5630     (vl_api_##n##_t * mp)                       \
5631     {                                           \
5632         vat_main_t * vam = &vat_main;           \
5633         vat_json_node_t node;                   \
5634         vat_json_init_object(&node);            \
5635         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5636         vat_json_print(vam->ofp, &node);        \
5637         vam->retval = ntohl(mp->retval);        \
5638         vam->result_ready = 1;                  \
5639     }
5640 foreach_standard_reply_retval_handler;
5641 #undef _
5642
5643 /*
5644  * Table of message reply handlers, must include boilerplate handlers
5645  * we just generated
5646  */
5647
5648 #define foreach_vpe_api_reply_msg                                       \
5649 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5650 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5651 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5652 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5653 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5654 _(CLI_REPLY, cli_reply)                                                 \
5655 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5656 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5657   sw_interface_add_del_address_reply)                                   \
5658 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5659 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5660 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5661 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5662 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5663 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5664 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5665 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5666 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5667 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5668   sw_interface_set_l2_xconnect_reply)                                   \
5669 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5670   sw_interface_set_l2_bridge_reply)                                     \
5671 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5672 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5673 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5674 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5675 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5676 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5677 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5678 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5679 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5680 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5681 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5682 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5683 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5684 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5685 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5686 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5687 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5688 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5689 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5690 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5691 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5692 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5693 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5694 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5695 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5696 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5697 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5698 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5699 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5700 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5701 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5702   proxy_arp_intfc_enable_disable_reply)                                 \
5703 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5704 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5705   sw_interface_set_unnumbered_reply)                                    \
5706 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5707 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5708 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5709 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5710 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5711 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5712 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5713 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5714 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5715 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5716 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5717   sw_interface_ip6_enable_disable_reply)                                \
5718 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5719 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5720 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5721   sw_interface_ip6nd_ra_prefix_reply)                                   \
5722 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5723   sw_interface_ip6nd_ra_config_reply)                                   \
5724 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5725 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5726 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5727 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5728 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5729 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5730 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5731 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5732 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5733 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5734 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5735 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5736 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5737 classify_set_interface_ip_table_reply)                                  \
5738 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5739   classify_set_interface_l2_tables_reply)                               \
5740 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5741 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5742 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5743 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5744 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5745   l2tpv3_interface_enable_disable_reply)                                \
5746 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5747 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5748 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5749 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5750 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5751 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5752 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5753 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5754 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5755 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5756 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5757 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5758 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5759 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5760 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5761 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5762 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5763 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5764 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5765 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5766 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5767 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5768 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5769 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5770 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5771 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5772 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5773 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5774 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5775 _(L2_MACS_EVENT, l2_macs_event)                                         \
5776 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5777 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5778 _(IP_DETAILS, ip_details)                                               \
5779 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5780 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5781 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5782 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5783 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5784 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5785 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5786 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5787 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5788 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5789 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5790 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5791 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5792 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5793 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5794 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5795 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5796 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5797 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5798 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5799 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5800 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5801 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5802 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5803 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5804 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5805 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5806 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5807 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5808 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5809 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5810 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5811 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5812 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5813 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5814 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5815 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5816 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5817 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5818 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5819 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5820 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5821 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5822 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5823   one_map_register_enable_disable_reply)                                \
5824 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5825 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5826 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5827 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5828   one_map_register_fallback_threshold_reply)                            \
5829 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5830   one_rloc_probe_enable_disable_reply)                                  \
5831 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5832 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5833 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5834 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5835 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5836 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5837 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5838 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5839 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5840 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5841 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5842 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5843 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5844 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5845 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5846 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5847   show_one_stats_enable_disable_reply)                                  \
5848 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5849 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5850 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5851 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5852 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5853 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5854 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5855 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5856   one_enable_disable_pitr_mode_reply)                                   \
5857 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5858   one_enable_disable_petr_mode_reply)                                   \
5859 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5860 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5861 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5862 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5863 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5864 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5865 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5866 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5867 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5868 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5869 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5870 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5871   gpe_add_del_native_fwd_rpath_reply)                                   \
5872 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5873   gpe_fwd_entry_path_details)                                           \
5874 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5875 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5876   one_add_del_map_request_itr_rlocs_reply)                              \
5877 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5878   one_get_map_request_itr_rlocs_reply)                                  \
5879 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5880 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5881 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5882 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5883 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5884 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5885   show_one_map_register_state_reply)                                    \
5886 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5887 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5888   show_one_map_register_fallback_threshold_reply)                       \
5889 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5890 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5891 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5892 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5893 _(POLICER_DETAILS, policer_details)                                     \
5894 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5895 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5896 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5897 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5898 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5899 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5900 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5901 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5902 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5903 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5904 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5905 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5906 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5907 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5908 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5909 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5910 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5911 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5912 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5913 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5914 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5915 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5916 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5917 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5918 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5919  ip_source_and_port_range_check_add_del_reply)                          \
5920 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5921  ip_source_and_port_range_check_interface_add_del_reply)                \
5922 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5923 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5924 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5925 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5926 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5927 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5928 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5929 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5930 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5931 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5932 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5933 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5934 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5935 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5936 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5937 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5938 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5939 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5940 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5941 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5942 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5943 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5944 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5945 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5946 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5947 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5948 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5949 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5950
5951 #define foreach_standalone_reply_msg                                    \
5952 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5953 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5954 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5955 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5956 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5957 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5958 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5959
5960 typedef struct
5961 {
5962   u8 *name;
5963   u32 value;
5964 } name_sort_t;
5965
5966 #define STR_VTR_OP_CASE(op)     \
5967     case L2_VTR_ ## op:         \
5968         return "" # op;
5969
5970 static const char *
5971 str_vtr_op (u32 vtr_op)
5972 {
5973   switch (vtr_op)
5974     {
5975       STR_VTR_OP_CASE (DISABLED);
5976       STR_VTR_OP_CASE (PUSH_1);
5977       STR_VTR_OP_CASE (PUSH_2);
5978       STR_VTR_OP_CASE (POP_1);
5979       STR_VTR_OP_CASE (POP_2);
5980       STR_VTR_OP_CASE (TRANSLATE_1_1);
5981       STR_VTR_OP_CASE (TRANSLATE_1_2);
5982       STR_VTR_OP_CASE (TRANSLATE_2_1);
5983       STR_VTR_OP_CASE (TRANSLATE_2_2);
5984     }
5985
5986   return "UNKNOWN";
5987 }
5988
5989 static int
5990 dump_sub_interface_table (vat_main_t * vam)
5991 {
5992   const sw_interface_subif_t *sub = NULL;
5993
5994   if (vam->json_output)
5995     {
5996       clib_warning
5997         ("JSON output supported only for VPE API calls and dump_stats_table");
5998       return -99;
5999     }
6000
6001   print (vam->ofp,
6002          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
6003          "Interface", "sw_if_index",
6004          "sub id", "dot1ad", "tags", "outer id",
6005          "inner id", "exact", "default", "outer any", "inner any");
6006
6007   vec_foreach (sub, vam->sw_if_subif_table)
6008   {
6009     print (vam->ofp,
6010            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
6011            sub->interface_name,
6012            sub->sw_if_index,
6013            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
6014            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
6015            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
6016            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
6017     if (sub->vtr_op != L2_VTR_DISABLED)
6018       {
6019         print (vam->ofp,
6020                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6021                "tag1: %d tag2: %d ]",
6022                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6023                sub->vtr_tag1, sub->vtr_tag2);
6024       }
6025   }
6026
6027   return 0;
6028 }
6029
6030 static int
6031 name_sort_cmp (void *a1, void *a2)
6032 {
6033   name_sort_t *n1 = a1;
6034   name_sort_t *n2 = a2;
6035
6036   return strcmp ((char *) n1->name, (char *) n2->name);
6037 }
6038
6039 static int
6040 dump_interface_table (vat_main_t * vam)
6041 {
6042   hash_pair_t *p;
6043   name_sort_t *nses = 0, *ns;
6044
6045   if (vam->json_output)
6046     {
6047       clib_warning
6048         ("JSON output supported only for VPE API calls and dump_stats_table");
6049       return -99;
6050     }
6051
6052   /* *INDENT-OFF* */
6053   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6054   ({
6055     vec_add2 (nses, ns, 1);
6056     ns->name = (u8 *)(p->key);
6057     ns->value = (u32) p->value[0];
6058   }));
6059   /* *INDENT-ON* */
6060
6061   vec_sort_with_function (nses, name_sort_cmp);
6062
6063   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6064   vec_foreach (ns, nses)
6065   {
6066     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6067   }
6068   vec_free (nses);
6069   return 0;
6070 }
6071
6072 static int
6073 dump_ip_table (vat_main_t * vam, int is_ipv6)
6074 {
6075   const ip_details_t *det = NULL;
6076   const ip_address_details_t *address = NULL;
6077   u32 i = ~0;
6078
6079   print (vam->ofp, "%-12s", "sw_if_index");
6080
6081   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6082   {
6083     i++;
6084     if (!det->present)
6085       {
6086         continue;
6087       }
6088     print (vam->ofp, "%-12d", i);
6089     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6090     if (!det->addr)
6091       {
6092         continue;
6093       }
6094     vec_foreach (address, det->addr)
6095     {
6096       print (vam->ofp,
6097              "            %-30U%-13d",
6098              is_ipv6 ? format_ip6_address : format_ip4_address,
6099              address->ip, address->prefix_length);
6100     }
6101   }
6102
6103   return 0;
6104 }
6105
6106 static int
6107 dump_ipv4_table (vat_main_t * vam)
6108 {
6109   if (vam->json_output)
6110     {
6111       clib_warning
6112         ("JSON output supported only for VPE API calls and dump_stats_table");
6113       return -99;
6114     }
6115
6116   return dump_ip_table (vam, 0);
6117 }
6118
6119 static int
6120 dump_ipv6_table (vat_main_t * vam)
6121 {
6122   if (vam->json_output)
6123     {
6124       clib_warning
6125         ("JSON output supported only for VPE API calls and dump_stats_table");
6126       return -99;
6127     }
6128
6129   return dump_ip_table (vam, 1);
6130 }
6131
6132 static char *
6133 counter_type_to_str (u8 counter_type, u8 is_combined)
6134 {
6135   if (!is_combined)
6136     {
6137       switch (counter_type)
6138         {
6139         case VNET_INTERFACE_COUNTER_DROP:
6140           return "drop";
6141         case VNET_INTERFACE_COUNTER_PUNT:
6142           return "punt";
6143         case VNET_INTERFACE_COUNTER_IP4:
6144           return "ip4";
6145         case VNET_INTERFACE_COUNTER_IP6:
6146           return "ip6";
6147         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6148           return "rx-no-buf";
6149         case VNET_INTERFACE_COUNTER_RX_MISS:
6150           return "rx-miss";
6151         case VNET_INTERFACE_COUNTER_RX_ERROR:
6152           return "rx-error";
6153         case VNET_INTERFACE_COUNTER_TX_ERROR:
6154           return "tx-error";
6155         default:
6156           return "INVALID-COUNTER-TYPE";
6157         }
6158     }
6159   else
6160     {
6161       switch (counter_type)
6162         {
6163         case VNET_INTERFACE_COUNTER_RX:
6164           return "rx";
6165         case VNET_INTERFACE_COUNTER_TX:
6166           return "tx";
6167         default:
6168           return "INVALID-COUNTER-TYPE";
6169         }
6170     }
6171 }
6172
6173 static int
6174 dump_stats_table (vat_main_t * vam)
6175 {
6176   vat_json_node_t node;
6177   vat_json_node_t *msg_array;
6178   vat_json_node_t *msg;
6179   vat_json_node_t *counter_array;
6180   vat_json_node_t *counter;
6181   interface_counter_t c;
6182   u64 packets;
6183   ip4_fib_counter_t *c4;
6184   ip6_fib_counter_t *c6;
6185   ip4_nbr_counter_t *n4;
6186   ip6_nbr_counter_t *n6;
6187   int i, j;
6188
6189   if (!vam->json_output)
6190     {
6191       clib_warning ("dump_stats_table supported only in JSON format");
6192       return -99;
6193     }
6194
6195   vat_json_init_object (&node);
6196
6197   /* interface counters */
6198   msg_array = vat_json_object_add (&node, "interface_counters");
6199   vat_json_init_array (msg_array);
6200   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6201     {
6202       msg = vat_json_array_add (msg_array);
6203       vat_json_init_object (msg);
6204       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6205                                        (u8 *) counter_type_to_str (i, 0));
6206       vat_json_object_add_int (msg, "is_combined", 0);
6207       counter_array = vat_json_object_add (msg, "data");
6208       vat_json_init_array (counter_array);
6209       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6210         {
6211           packets = vam->simple_interface_counters[i][j];
6212           vat_json_array_add_uint (counter_array, packets);
6213         }
6214     }
6215   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6216     {
6217       msg = vat_json_array_add (msg_array);
6218       vat_json_init_object (msg);
6219       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6220                                        (u8 *) counter_type_to_str (i, 1));
6221       vat_json_object_add_int (msg, "is_combined", 1);
6222       counter_array = vat_json_object_add (msg, "data");
6223       vat_json_init_array (counter_array);
6224       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6225         {
6226           c = vam->combined_interface_counters[i][j];
6227           counter = vat_json_array_add (counter_array);
6228           vat_json_init_object (counter);
6229           vat_json_object_add_uint (counter, "packets", c.packets);
6230           vat_json_object_add_uint (counter, "bytes", c.bytes);
6231         }
6232     }
6233
6234   /* ip4 fib counters */
6235   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6236   vat_json_init_array (msg_array);
6237   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6238     {
6239       msg = vat_json_array_add (msg_array);
6240       vat_json_init_object (msg);
6241       vat_json_object_add_uint (msg, "vrf_id",
6242                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6243       counter_array = vat_json_object_add (msg, "c");
6244       vat_json_init_array (counter_array);
6245       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6246         {
6247           counter = vat_json_array_add (counter_array);
6248           vat_json_init_object (counter);
6249           c4 = &vam->ip4_fib_counters[i][j];
6250           vat_json_object_add_ip4 (counter, "address", c4->address);
6251           vat_json_object_add_uint (counter, "address_length",
6252                                     c4->address_length);
6253           vat_json_object_add_uint (counter, "packets", c4->packets);
6254           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6255         }
6256     }
6257
6258   /* ip6 fib counters */
6259   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6260   vat_json_init_array (msg_array);
6261   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6262     {
6263       msg = vat_json_array_add (msg_array);
6264       vat_json_init_object (msg);
6265       vat_json_object_add_uint (msg, "vrf_id",
6266                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6267       counter_array = vat_json_object_add (msg, "c");
6268       vat_json_init_array (counter_array);
6269       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6270         {
6271           counter = vat_json_array_add (counter_array);
6272           vat_json_init_object (counter);
6273           c6 = &vam->ip6_fib_counters[i][j];
6274           vat_json_object_add_ip6 (counter, "address", c6->address);
6275           vat_json_object_add_uint (counter, "address_length",
6276                                     c6->address_length);
6277           vat_json_object_add_uint (counter, "packets", c6->packets);
6278           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6279         }
6280     }
6281
6282   /* ip4 nbr counters */
6283   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6284   vat_json_init_array (msg_array);
6285   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6286     {
6287       msg = vat_json_array_add (msg_array);
6288       vat_json_init_object (msg);
6289       vat_json_object_add_uint (msg, "sw_if_index", i);
6290       counter_array = vat_json_object_add (msg, "c");
6291       vat_json_init_array (counter_array);
6292       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6293         {
6294           counter = vat_json_array_add (counter_array);
6295           vat_json_init_object (counter);
6296           n4 = &vam->ip4_nbr_counters[i][j];
6297           vat_json_object_add_ip4 (counter, "address", n4->address);
6298           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6299           vat_json_object_add_uint (counter, "packets", n4->packets);
6300           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6301         }
6302     }
6303
6304   /* ip6 nbr counters */
6305   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6306   vat_json_init_array (msg_array);
6307   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6308     {
6309       msg = vat_json_array_add (msg_array);
6310       vat_json_init_object (msg);
6311       vat_json_object_add_uint (msg, "sw_if_index", i);
6312       counter_array = vat_json_object_add (msg, "c");
6313       vat_json_init_array (counter_array);
6314       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6315         {
6316           counter = vat_json_array_add (counter_array);
6317           vat_json_init_object (counter);
6318           n6 = &vam->ip6_nbr_counters[i][j];
6319           vat_json_object_add_ip6 (counter, "address", n6->address);
6320           vat_json_object_add_uint (counter, "packets", n6->packets);
6321           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6322         }
6323     }
6324
6325   vat_json_print (vam->ofp, &node);
6326   vat_json_free (&node);
6327
6328   return 0;
6329 }
6330
6331 /*
6332  * Pass CLI buffers directly in the CLI_INBAND API message,
6333  * instead of an additional shared memory area.
6334  */
6335 static int
6336 exec_inband (vat_main_t * vam)
6337 {
6338   vl_api_cli_inband_t *mp;
6339   unformat_input_t *i = vam->input;
6340   int ret;
6341
6342   if (vec_len (i->buffer) == 0)
6343     return -1;
6344
6345   if (vam->exec_mode == 0 && unformat (i, "mode"))
6346     {
6347       vam->exec_mode = 1;
6348       return 0;
6349     }
6350   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6351     {
6352       vam->exec_mode = 0;
6353       return 0;
6354     }
6355
6356   /*
6357    * In order for the CLI command to work, it
6358    * must be a vector ending in \n, not a C-string ending
6359    * in \n\0.
6360    */
6361   u32 len = vec_len (vam->input->buffer);
6362   M2 (CLI_INBAND, mp, len);
6363   vl_api_to_api_string (len, (const char *) vam->input->buffer, &mp->cmd);
6364
6365   S (mp);
6366   W (ret);
6367   /* json responses may or may not include a useful reply... */
6368   if (vec_len (vam->cmd_reply))
6369     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6370   return ret;
6371 }
6372
6373 int
6374 exec (vat_main_t * vam)
6375 {
6376   return exec_inband (vam);
6377 }
6378
6379 static int
6380 api_create_loopback (vat_main_t * vam)
6381 {
6382   unformat_input_t *i = vam->input;
6383   vl_api_create_loopback_t *mp;
6384   vl_api_create_loopback_instance_t *mp_lbi;
6385   u8 mac_address[6];
6386   u8 mac_set = 0;
6387   u8 is_specified = 0;
6388   u32 user_instance = 0;
6389   int ret;
6390
6391   clib_memset (mac_address, 0, sizeof (mac_address));
6392
6393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6394     {
6395       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6396         mac_set = 1;
6397       if (unformat (i, "instance %d", &user_instance))
6398         is_specified = 1;
6399       else
6400         break;
6401     }
6402
6403   if (is_specified)
6404     {
6405       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6406       mp_lbi->is_specified = is_specified;
6407       if (is_specified)
6408         mp_lbi->user_instance = htonl (user_instance);
6409       if (mac_set)
6410         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6411       S (mp_lbi);
6412     }
6413   else
6414     {
6415       /* Construct the API message */
6416       M (CREATE_LOOPBACK, mp);
6417       if (mac_set)
6418         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6419       S (mp);
6420     }
6421
6422   W (ret);
6423   return ret;
6424 }
6425
6426 static int
6427 api_delete_loopback (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_delete_loopback_t *mp;
6431   u32 sw_if_index = ~0;
6432   int ret;
6433
6434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6435     {
6436       if (unformat (i, "sw_if_index %d", &sw_if_index))
6437         ;
6438       else
6439         break;
6440     }
6441
6442   if (sw_if_index == ~0)
6443     {
6444       errmsg ("missing sw_if_index");
6445       return -99;
6446     }
6447
6448   /* Construct the API message */
6449   M (DELETE_LOOPBACK, mp);
6450   mp->sw_if_index = ntohl (sw_if_index);
6451
6452   S (mp);
6453   W (ret);
6454   return ret;
6455 }
6456
6457 static int
6458 api_want_stats (vat_main_t * vam)
6459 {
6460   unformat_input_t *i = vam->input;
6461   vl_api_want_stats_t *mp;
6462   int enable = -1;
6463   int ret;
6464
6465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6466     {
6467       if (unformat (i, "enable"))
6468         enable = 1;
6469       else if (unformat (i, "disable"))
6470         enable = 0;
6471       else
6472         break;
6473     }
6474
6475   if (enable == -1)
6476     {
6477       errmsg ("missing enable|disable");
6478       return -99;
6479     }
6480
6481   M (WANT_STATS, mp);
6482   mp->enable_disable = enable;
6483
6484   S (mp);
6485   W (ret);
6486   return ret;
6487 }
6488
6489 static int
6490 api_want_interface_events (vat_main_t * vam)
6491 {
6492   unformat_input_t *i = vam->input;
6493   vl_api_want_interface_events_t *mp;
6494   int enable = -1;
6495   int ret;
6496
6497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6498     {
6499       if (unformat (i, "enable"))
6500         enable = 1;
6501       else if (unformat (i, "disable"))
6502         enable = 0;
6503       else
6504         break;
6505     }
6506
6507   if (enable == -1)
6508     {
6509       errmsg ("missing enable|disable");
6510       return -99;
6511     }
6512
6513   M (WANT_INTERFACE_EVENTS, mp);
6514   mp->enable_disable = enable;
6515
6516   vam->interface_event_display = enable;
6517
6518   S (mp);
6519   W (ret);
6520   return ret;
6521 }
6522
6523
6524 /* Note: non-static, called once to set up the initial intfc table */
6525 int
6526 api_sw_interface_dump (vat_main_t * vam)
6527 {
6528   vl_api_sw_interface_dump_t *mp;
6529   vl_api_control_ping_t *mp_ping;
6530   hash_pair_t *p;
6531   name_sort_t *nses = 0, *ns;
6532   sw_interface_subif_t *sub = NULL;
6533   int ret;
6534
6535   /* Toss the old name table */
6536   /* *INDENT-OFF* */
6537   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6538   ({
6539     vec_add2 (nses, ns, 1);
6540     ns->name = (u8 *)(p->key);
6541     ns->value = (u32) p->value[0];
6542   }));
6543   /* *INDENT-ON* */
6544
6545   hash_free (vam->sw_if_index_by_interface_name);
6546
6547   vec_foreach (ns, nses) vec_free (ns->name);
6548
6549   vec_free (nses);
6550
6551   vec_foreach (sub, vam->sw_if_subif_table)
6552   {
6553     vec_free (sub->interface_name);
6554   }
6555   vec_free (vam->sw_if_subif_table);
6556
6557   /* recreate the interface name hash table */
6558   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6559
6560   /*
6561    * Ask for all interface names. Otherwise, the epic catalog of
6562    * name filters becomes ridiculously long, and vat ends up needing
6563    * to be taught about new interface types.
6564    */
6565   M (SW_INTERFACE_DUMP, mp);
6566   S (mp);
6567
6568   /* Use a control ping for synchronization */
6569   MPING (CONTROL_PING, mp_ping);
6570   S (mp_ping);
6571
6572   W (ret);
6573   return ret;
6574 }
6575
6576 static int
6577 api_sw_interface_set_flags (vat_main_t * vam)
6578 {
6579   unformat_input_t *i = vam->input;
6580   vl_api_sw_interface_set_flags_t *mp;
6581   u32 sw_if_index;
6582   u8 sw_if_index_set = 0;
6583   u8 admin_up = 0;
6584   int ret;
6585
6586   /* Parse args required to build the message */
6587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588     {
6589       if (unformat (i, "admin-up"))
6590         admin_up = 1;
6591       else if (unformat (i, "admin-down"))
6592         admin_up = 0;
6593       else
6594         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6595         sw_if_index_set = 1;
6596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6597         sw_if_index_set = 1;
6598       else
6599         break;
6600     }
6601
6602   if (sw_if_index_set == 0)
6603     {
6604       errmsg ("missing interface name or sw_if_index");
6605       return -99;
6606     }
6607
6608   /* Construct the API message */
6609   M (SW_INTERFACE_SET_FLAGS, mp);
6610   mp->sw_if_index = ntohl (sw_if_index);
6611   mp->admin_up_down = admin_up;
6612
6613   /* send it... */
6614   S (mp);
6615
6616   /* Wait for a reply, return the good/bad news... */
6617   W (ret);
6618   return ret;
6619 }
6620
6621 static int
6622 api_sw_interface_set_rx_mode (vat_main_t * vam)
6623 {
6624   unformat_input_t *i = vam->input;
6625   vl_api_sw_interface_set_rx_mode_t *mp;
6626   u32 sw_if_index;
6627   u8 sw_if_index_set = 0;
6628   int ret;
6629   u8 queue_id_valid = 0;
6630   u32 queue_id;
6631   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6632
6633   /* Parse args required to build the message */
6634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6635     {
6636       if (unformat (i, "queue %d", &queue_id))
6637         queue_id_valid = 1;
6638       else if (unformat (i, "polling"))
6639         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6640       else if (unformat (i, "interrupt"))
6641         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6642       else if (unformat (i, "adaptive"))
6643         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6644       else
6645         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6646         sw_if_index_set = 1;
6647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6648         sw_if_index_set = 1;
6649       else
6650         break;
6651     }
6652
6653   if (sw_if_index_set == 0)
6654     {
6655       errmsg ("missing interface name or sw_if_index");
6656       return -99;
6657     }
6658   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6659     {
6660       errmsg ("missing rx-mode");
6661       return -99;
6662     }
6663
6664   /* Construct the API message */
6665   M (SW_INTERFACE_SET_RX_MODE, mp);
6666   mp->sw_if_index = ntohl (sw_if_index);
6667   mp->mode = mode;
6668   mp->queue_id_valid = queue_id_valid;
6669   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6670
6671   /* send it... */
6672   S (mp);
6673
6674   /* Wait for a reply, return the good/bad news... */
6675   W (ret);
6676   return ret;
6677 }
6678
6679 static int
6680 api_sw_interface_set_rx_placement (vat_main_t * vam)
6681 {
6682   unformat_input_t *i = vam->input;
6683   vl_api_sw_interface_set_rx_placement_t *mp;
6684   u32 sw_if_index;
6685   u8 sw_if_index_set = 0;
6686   int ret;
6687   u8 is_main = 0;
6688   u32 queue_id, thread_index;
6689
6690   /* Parse args required to build the message */
6691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6692     {
6693       if (unformat (i, "queue %d", &queue_id))
6694         ;
6695       else if (unformat (i, "main"))
6696         is_main = 1;
6697       else if (unformat (i, "worker %d", &thread_index))
6698         ;
6699       else
6700         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6701         sw_if_index_set = 1;
6702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6703         sw_if_index_set = 1;
6704       else
6705         break;
6706     }
6707
6708   if (sw_if_index_set == 0)
6709     {
6710       errmsg ("missing interface name or sw_if_index");
6711       return -99;
6712     }
6713
6714   if (is_main)
6715     thread_index = 0;
6716   /* Construct the API message */
6717   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6718   mp->sw_if_index = ntohl (sw_if_index);
6719   mp->worker_id = ntohl (thread_index);
6720   mp->queue_id = ntohl (queue_id);
6721   mp->is_main = is_main;
6722
6723   /* send it... */
6724   S (mp);
6725   /* Wait for a reply, return the good/bad news... */
6726   W (ret);
6727   return ret;
6728 }
6729
6730 static void vl_api_sw_interface_rx_placement_details_t_handler
6731   (vl_api_sw_interface_rx_placement_details_t * mp)
6732 {
6733   vat_main_t *vam = &vat_main;
6734   u32 worker_id = ntohl (mp->worker_id);
6735
6736   print (vam->ofp,
6737          "\n%-11d %-11s %-6d %-5d %-9s",
6738          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6739          worker_id, ntohl (mp->queue_id),
6740          (mp->mode ==
6741           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6742 }
6743
6744 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6745   (vl_api_sw_interface_rx_placement_details_t * mp)
6746 {
6747   vat_main_t *vam = &vat_main;
6748   vat_json_node_t *node = NULL;
6749
6750   if (VAT_JSON_ARRAY != vam->json_tree.type)
6751     {
6752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6753       vat_json_init_array (&vam->json_tree);
6754     }
6755   node = vat_json_array_add (&vam->json_tree);
6756
6757   vat_json_init_object (node);
6758   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6759   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6760   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6761   vat_json_object_add_uint (node, "mode", mp->mode);
6762 }
6763
6764 static int
6765 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6766 {
6767   unformat_input_t *i = vam->input;
6768   vl_api_sw_interface_rx_placement_dump_t *mp;
6769   vl_api_control_ping_t *mp_ping;
6770   int ret;
6771   u32 sw_if_index;
6772   u8 sw_if_index_set = 0;
6773
6774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6775     {
6776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6777         sw_if_index_set++;
6778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6779         sw_if_index_set++;
6780       else
6781         break;
6782     }
6783
6784   print (vam->ofp,
6785          "\n%-11s %-11s %-6s %-5s %-4s",
6786          "sw_if_index", "main/worker", "thread", "queue", "mode");
6787
6788   /* Dump Interface rx placement */
6789   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6790
6791   if (sw_if_index_set)
6792     mp->sw_if_index = htonl (sw_if_index);
6793   else
6794     mp->sw_if_index = ~0;
6795
6796   S (mp);
6797
6798   /* Use a control ping for synchronization */
6799   MPING (CONTROL_PING, mp_ping);
6800   S (mp_ping);
6801
6802   W (ret);
6803   return ret;
6804 }
6805
6806 static int
6807 api_sw_interface_clear_stats (vat_main_t * vam)
6808 {
6809   unformat_input_t *i = vam->input;
6810   vl_api_sw_interface_clear_stats_t *mp;
6811   u32 sw_if_index;
6812   u8 sw_if_index_set = 0;
6813   int ret;
6814
6815   /* Parse args required to build the message */
6816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6817     {
6818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6819         sw_if_index_set = 1;
6820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else
6823         break;
6824     }
6825
6826   /* Construct the API message */
6827   M (SW_INTERFACE_CLEAR_STATS, mp);
6828
6829   if (sw_if_index_set == 1)
6830     mp->sw_if_index = ntohl (sw_if_index);
6831   else
6832     mp->sw_if_index = ~0;
6833
6834   /* send it... */
6835   S (mp);
6836
6837   /* Wait for a reply, return the good/bad news... */
6838   W (ret);
6839   return ret;
6840 }
6841
6842 static int
6843 api_sw_interface_add_del_address (vat_main_t * vam)
6844 {
6845   unformat_input_t *i = vam->input;
6846   vl_api_sw_interface_add_del_address_t *mp;
6847   u32 sw_if_index;
6848   u8 sw_if_index_set = 0;
6849   u8 is_add = 1, del_all = 0;
6850   u32 address_length = 0;
6851   u8 v4_address_set = 0;
6852   u8 v6_address_set = 0;
6853   ip4_address_t v4address;
6854   ip6_address_t v6address;
6855   int ret;
6856
6857   /* Parse args required to build the message */
6858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6859     {
6860       if (unformat (i, "del-all"))
6861         del_all = 1;
6862       else if (unformat (i, "del"))
6863         is_add = 0;
6864       else
6865         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6866         sw_if_index_set = 1;
6867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6868         sw_if_index_set = 1;
6869       else if (unformat (i, "%U/%d",
6870                          unformat_ip4_address, &v4address, &address_length))
6871         v4_address_set = 1;
6872       else if (unformat (i, "%U/%d",
6873                          unformat_ip6_address, &v6address, &address_length))
6874         v6_address_set = 1;
6875       else
6876         break;
6877     }
6878
6879   if (sw_if_index_set == 0)
6880     {
6881       errmsg ("missing interface name or sw_if_index");
6882       return -99;
6883     }
6884   if (v4_address_set && v6_address_set)
6885     {
6886       errmsg ("both v4 and v6 addresses set");
6887       return -99;
6888     }
6889   if (!v4_address_set && !v6_address_set && !del_all)
6890     {
6891       errmsg ("no addresses set");
6892       return -99;
6893     }
6894
6895   /* Construct the API message */
6896   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6897
6898   mp->sw_if_index = ntohl (sw_if_index);
6899   mp->is_add = is_add;
6900   mp->del_all = del_all;
6901   if (v6_address_set)
6902     {
6903       mp->is_ipv6 = 1;
6904       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6905     }
6906   else
6907     {
6908       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6909     }
6910   mp->address_length = address_length;
6911
6912   /* send it... */
6913   S (mp);
6914
6915   /* Wait for a reply, return good/bad news  */
6916   W (ret);
6917   return ret;
6918 }
6919
6920 static int
6921 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6922 {
6923   unformat_input_t *i = vam->input;
6924   vl_api_sw_interface_set_mpls_enable_t *mp;
6925   u32 sw_if_index;
6926   u8 sw_if_index_set = 0;
6927   u8 enable = 1;
6928   int ret;
6929
6930   /* Parse args required to build the message */
6931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6932     {
6933       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6934         sw_if_index_set = 1;
6935       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6936         sw_if_index_set = 1;
6937       else if (unformat (i, "disable"))
6938         enable = 0;
6939       else if (unformat (i, "dis"))
6940         enable = 0;
6941       else
6942         break;
6943     }
6944
6945   if (sw_if_index_set == 0)
6946     {
6947       errmsg ("missing interface name or sw_if_index");
6948       return -99;
6949     }
6950
6951   /* Construct the API message */
6952   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6953
6954   mp->sw_if_index = ntohl (sw_if_index);
6955   mp->enable = enable;
6956
6957   /* send it... */
6958   S (mp);
6959
6960   /* Wait for a reply... */
6961   W (ret);
6962   return ret;
6963 }
6964
6965 static int
6966 api_sw_interface_set_table (vat_main_t * vam)
6967 {
6968   unformat_input_t *i = vam->input;
6969   vl_api_sw_interface_set_table_t *mp;
6970   u32 sw_if_index, vrf_id = 0;
6971   u8 sw_if_index_set = 0;
6972   u8 is_ipv6 = 0;
6973   int ret;
6974
6975   /* Parse args required to build the message */
6976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6977     {
6978       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6979         sw_if_index_set = 1;
6980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6981         sw_if_index_set = 1;
6982       else if (unformat (i, "vrf %d", &vrf_id))
6983         ;
6984       else if (unformat (i, "ipv6"))
6985         is_ipv6 = 1;
6986       else
6987         break;
6988     }
6989
6990   if (sw_if_index_set == 0)
6991     {
6992       errmsg ("missing interface name or sw_if_index");
6993       return -99;
6994     }
6995
6996   /* Construct the API message */
6997   M (SW_INTERFACE_SET_TABLE, mp);
6998
6999   mp->sw_if_index = ntohl (sw_if_index);
7000   mp->is_ipv6 = is_ipv6;
7001   mp->vrf_id = ntohl (vrf_id);
7002
7003   /* send it... */
7004   S (mp);
7005
7006   /* Wait for a reply... */
7007   W (ret);
7008   return ret;
7009 }
7010
7011 static void vl_api_sw_interface_get_table_reply_t_handler
7012   (vl_api_sw_interface_get_table_reply_t * mp)
7013 {
7014   vat_main_t *vam = &vat_main;
7015
7016   print (vam->ofp, "%d", ntohl (mp->vrf_id));
7017
7018   vam->retval = ntohl (mp->retval);
7019   vam->result_ready = 1;
7020
7021 }
7022
7023 static void vl_api_sw_interface_get_table_reply_t_handler_json
7024   (vl_api_sw_interface_get_table_reply_t * mp)
7025 {
7026   vat_main_t *vam = &vat_main;
7027   vat_json_node_t node;
7028
7029   vat_json_init_object (&node);
7030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
7031   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
7032
7033   vat_json_print (vam->ofp, &node);
7034   vat_json_free (&node);
7035
7036   vam->retval = ntohl (mp->retval);
7037   vam->result_ready = 1;
7038 }
7039
7040 static int
7041 api_sw_interface_get_table (vat_main_t * vam)
7042 {
7043   unformat_input_t *i = vam->input;
7044   vl_api_sw_interface_get_table_t *mp;
7045   u32 sw_if_index;
7046   u8 sw_if_index_set = 0;
7047   u8 is_ipv6 = 0;
7048   int ret;
7049
7050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7051     {
7052       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7053         sw_if_index_set = 1;
7054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7055         sw_if_index_set = 1;
7056       else if (unformat (i, "ipv6"))
7057         is_ipv6 = 1;
7058       else
7059         break;
7060     }
7061
7062   if (sw_if_index_set == 0)
7063     {
7064       errmsg ("missing interface name or sw_if_index");
7065       return -99;
7066     }
7067
7068   M (SW_INTERFACE_GET_TABLE, mp);
7069   mp->sw_if_index = htonl (sw_if_index);
7070   mp->is_ipv6 = is_ipv6;
7071
7072   S (mp);
7073   W (ret);
7074   return ret;
7075 }
7076
7077 static int
7078 api_sw_interface_set_vpath (vat_main_t * vam)
7079 {
7080   unformat_input_t *i = vam->input;
7081   vl_api_sw_interface_set_vpath_t *mp;
7082   u32 sw_if_index = 0;
7083   u8 sw_if_index_set = 0;
7084   u8 is_enable = 0;
7085   int ret;
7086
7087   /* Parse args required to build the message */
7088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7089     {
7090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7091         sw_if_index_set = 1;
7092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7093         sw_if_index_set = 1;
7094       else if (unformat (i, "enable"))
7095         is_enable = 1;
7096       else if (unformat (i, "disable"))
7097         is_enable = 0;
7098       else
7099         break;
7100     }
7101
7102   if (sw_if_index_set == 0)
7103     {
7104       errmsg ("missing interface name or sw_if_index");
7105       return -99;
7106     }
7107
7108   /* Construct the API message */
7109   M (SW_INTERFACE_SET_VPATH, mp);
7110
7111   mp->sw_if_index = ntohl (sw_if_index);
7112   mp->enable = is_enable;
7113
7114   /* send it... */
7115   S (mp);
7116
7117   /* Wait for a reply... */
7118   W (ret);
7119   return ret;
7120 }
7121
7122 static int
7123 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7124 {
7125   unformat_input_t *i = vam->input;
7126   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7127   u32 sw_if_index = 0;
7128   u8 sw_if_index_set = 0;
7129   u8 is_enable = 1;
7130   u8 is_ipv6 = 0;
7131   int ret;
7132
7133   /* Parse args required to build the message */
7134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7135     {
7136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7137         sw_if_index_set = 1;
7138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7139         sw_if_index_set = 1;
7140       else if (unformat (i, "enable"))
7141         is_enable = 1;
7142       else if (unformat (i, "disable"))
7143         is_enable = 0;
7144       else if (unformat (i, "ip4"))
7145         is_ipv6 = 0;
7146       else if (unformat (i, "ip6"))
7147         is_ipv6 = 1;
7148       else
7149         break;
7150     }
7151
7152   if (sw_if_index_set == 0)
7153     {
7154       errmsg ("missing interface name or sw_if_index");
7155       return -99;
7156     }
7157
7158   /* Construct the API message */
7159   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7160
7161   mp->sw_if_index = ntohl (sw_if_index);
7162   mp->enable = is_enable;
7163   mp->is_ipv6 = is_ipv6;
7164
7165   /* send it... */
7166   S (mp);
7167
7168   /* Wait for a reply... */
7169   W (ret);
7170   return ret;
7171 }
7172
7173 static int
7174 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7175 {
7176   unformat_input_t *i = vam->input;
7177   vl_api_sw_interface_set_geneve_bypass_t *mp;
7178   u32 sw_if_index = 0;
7179   u8 sw_if_index_set = 0;
7180   u8 is_enable = 1;
7181   u8 is_ipv6 = 0;
7182   int ret;
7183
7184   /* Parse args required to build the message */
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7188         sw_if_index_set = 1;
7189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7190         sw_if_index_set = 1;
7191       else if (unformat (i, "enable"))
7192         is_enable = 1;
7193       else if (unformat (i, "disable"))
7194         is_enable = 0;
7195       else if (unformat (i, "ip4"))
7196         is_ipv6 = 0;
7197       else if (unformat (i, "ip6"))
7198         is_ipv6 = 1;
7199       else
7200         break;
7201     }
7202
7203   if (sw_if_index_set == 0)
7204     {
7205       errmsg ("missing interface name or sw_if_index");
7206       return -99;
7207     }
7208
7209   /* Construct the API message */
7210   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7211
7212   mp->sw_if_index = ntohl (sw_if_index);
7213   mp->enable = is_enable;
7214   mp->is_ipv6 = is_ipv6;
7215
7216   /* send it... */
7217   S (mp);
7218
7219   /* Wait for a reply... */
7220   W (ret);
7221   return ret;
7222 }
7223
7224 static int
7225 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7226 {
7227   unformat_input_t *i = vam->input;
7228   vl_api_sw_interface_set_l2_xconnect_t *mp;
7229   u32 rx_sw_if_index;
7230   u8 rx_sw_if_index_set = 0;
7231   u32 tx_sw_if_index;
7232   u8 tx_sw_if_index_set = 0;
7233   u8 enable = 1;
7234   int ret;
7235
7236   /* Parse args required to build the message */
7237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7238     {
7239       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7240         rx_sw_if_index_set = 1;
7241       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7242         tx_sw_if_index_set = 1;
7243       else if (unformat (i, "rx"))
7244         {
7245           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7246             {
7247               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7248                             &rx_sw_if_index))
7249                 rx_sw_if_index_set = 1;
7250             }
7251           else
7252             break;
7253         }
7254       else if (unformat (i, "tx"))
7255         {
7256           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7257             {
7258               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7259                             &tx_sw_if_index))
7260                 tx_sw_if_index_set = 1;
7261             }
7262           else
7263             break;
7264         }
7265       else if (unformat (i, "enable"))
7266         enable = 1;
7267       else if (unformat (i, "disable"))
7268         enable = 0;
7269       else
7270         break;
7271     }
7272
7273   if (rx_sw_if_index_set == 0)
7274     {
7275       errmsg ("missing rx interface name or rx_sw_if_index");
7276       return -99;
7277     }
7278
7279   if (enable && (tx_sw_if_index_set == 0))
7280     {
7281       errmsg ("missing tx interface name or tx_sw_if_index");
7282       return -99;
7283     }
7284
7285   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7286
7287   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7288   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7289   mp->enable = enable;
7290
7291   S (mp);
7292   W (ret);
7293   return ret;
7294 }
7295
7296 static int
7297 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7298 {
7299   unformat_input_t *i = vam->input;
7300   vl_api_sw_interface_set_l2_bridge_t *mp;
7301   vl_api_l2_port_type_t port_type;
7302   u32 rx_sw_if_index;
7303   u8 rx_sw_if_index_set = 0;
7304   u32 bd_id;
7305   u8 bd_id_set = 0;
7306   u32 shg = 0;
7307   u8 enable = 1;
7308   int ret;
7309
7310   port_type = L2_API_PORT_TYPE_NORMAL;
7311
7312   /* Parse args required to build the message */
7313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7314     {
7315       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7316         rx_sw_if_index_set = 1;
7317       else if (unformat (i, "bd_id %d", &bd_id))
7318         bd_id_set = 1;
7319       else
7320         if (unformat
7321             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7322         rx_sw_if_index_set = 1;
7323       else if (unformat (i, "shg %d", &shg))
7324         ;
7325       else if (unformat (i, "bvi"))
7326         port_type = L2_API_PORT_TYPE_BVI;
7327       else if (unformat (i, "uu-fwd"))
7328         port_type = L2_API_PORT_TYPE_UU_FWD;
7329       else if (unformat (i, "enable"))
7330         enable = 1;
7331       else if (unformat (i, "disable"))
7332         enable = 0;
7333       else
7334         break;
7335     }
7336
7337   if (rx_sw_if_index_set == 0)
7338     {
7339       errmsg ("missing rx interface name or sw_if_index");
7340       return -99;
7341     }
7342
7343   if (enable && (bd_id_set == 0))
7344     {
7345       errmsg ("missing bridge domain");
7346       return -99;
7347     }
7348
7349   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7350
7351   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7352   mp->bd_id = ntohl (bd_id);
7353   mp->shg = (u8) shg;
7354   mp->port_type = ntohl (port_type);
7355   mp->enable = enable;
7356
7357   S (mp);
7358   W (ret);
7359   return ret;
7360 }
7361
7362 static int
7363 api_bridge_domain_dump (vat_main_t * vam)
7364 {
7365   unformat_input_t *i = vam->input;
7366   vl_api_bridge_domain_dump_t *mp;
7367   vl_api_control_ping_t *mp_ping;
7368   u32 bd_id = ~0;
7369   int ret;
7370
7371   /* Parse args required to build the message */
7372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7373     {
7374       if (unformat (i, "bd_id %d", &bd_id))
7375         ;
7376       else
7377         break;
7378     }
7379
7380   M (BRIDGE_DOMAIN_DUMP, mp);
7381   mp->bd_id = ntohl (bd_id);
7382   S (mp);
7383
7384   /* Use a control ping for synchronization */
7385   MPING (CONTROL_PING, mp_ping);
7386   S (mp_ping);
7387
7388   W (ret);
7389   return ret;
7390 }
7391
7392 static int
7393 api_bridge_domain_add_del (vat_main_t * vam)
7394 {
7395   unformat_input_t *i = vam->input;
7396   vl_api_bridge_domain_add_del_t *mp;
7397   u32 bd_id = ~0;
7398   u8 is_add = 1;
7399   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7400   u8 *bd_tag = NULL;
7401   u32 mac_age = 0;
7402   int ret;
7403
7404   /* Parse args required to build the message */
7405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7406     {
7407       if (unformat (i, "bd_id %d", &bd_id))
7408         ;
7409       else if (unformat (i, "flood %d", &flood))
7410         ;
7411       else if (unformat (i, "uu-flood %d", &uu_flood))
7412         ;
7413       else if (unformat (i, "forward %d", &forward))
7414         ;
7415       else if (unformat (i, "learn %d", &learn))
7416         ;
7417       else if (unformat (i, "arp-term %d", &arp_term))
7418         ;
7419       else if (unformat (i, "mac-age %d", &mac_age))
7420         ;
7421       else if (unformat (i, "bd-tag %s", &bd_tag))
7422         ;
7423       else if (unformat (i, "del"))
7424         {
7425           is_add = 0;
7426           flood = uu_flood = forward = learn = 0;
7427         }
7428       else
7429         break;
7430     }
7431
7432   if (bd_id == ~0)
7433     {
7434       errmsg ("missing bridge domain");
7435       ret = -99;
7436       goto done;
7437     }
7438
7439   if (mac_age > 255)
7440     {
7441       errmsg ("mac age must be less than 256 ");
7442       ret = -99;
7443       goto done;
7444     }
7445
7446   if ((bd_tag) && (vec_len (bd_tag) > 63))
7447     {
7448       errmsg ("bd-tag cannot be longer than 63");
7449       ret = -99;
7450       goto done;
7451     }
7452
7453   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7454
7455   mp->bd_id = ntohl (bd_id);
7456   mp->flood = flood;
7457   mp->uu_flood = uu_flood;
7458   mp->forward = forward;
7459   mp->learn = learn;
7460   mp->arp_term = arp_term;
7461   mp->is_add = is_add;
7462   mp->mac_age = (u8) mac_age;
7463   if (bd_tag)
7464     {
7465       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7466       mp->bd_tag[vec_len (bd_tag)] = 0;
7467     }
7468   S (mp);
7469   W (ret);
7470
7471 done:
7472   vec_free (bd_tag);
7473   return ret;
7474 }
7475
7476 static int
7477 api_l2fib_flush_bd (vat_main_t * vam)
7478 {
7479   unformat_input_t *i = vam->input;
7480   vl_api_l2fib_flush_bd_t *mp;
7481   u32 bd_id = ~0;
7482   int ret;
7483
7484   /* Parse args required to build the message */
7485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7486     {
7487       if (unformat (i, "bd_id %d", &bd_id));
7488       else
7489         break;
7490     }
7491
7492   if (bd_id == ~0)
7493     {
7494       errmsg ("missing bridge domain");
7495       return -99;
7496     }
7497
7498   M (L2FIB_FLUSH_BD, mp);
7499
7500   mp->bd_id = htonl (bd_id);
7501
7502   S (mp);
7503   W (ret);
7504   return ret;
7505 }
7506
7507 static int
7508 api_l2fib_flush_int (vat_main_t * vam)
7509 {
7510   unformat_input_t *i = vam->input;
7511   vl_api_l2fib_flush_int_t *mp;
7512   u32 sw_if_index = ~0;
7513   int ret;
7514
7515   /* Parse args required to build the message */
7516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7517     {
7518       if (unformat (i, "sw_if_index %d", &sw_if_index));
7519       else
7520         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7521       else
7522         break;
7523     }
7524
7525   if (sw_if_index == ~0)
7526     {
7527       errmsg ("missing interface name or sw_if_index");
7528       return -99;
7529     }
7530
7531   M (L2FIB_FLUSH_INT, mp);
7532
7533   mp->sw_if_index = ntohl (sw_if_index);
7534
7535   S (mp);
7536   W (ret);
7537   return ret;
7538 }
7539
7540 static int
7541 api_l2fib_add_del (vat_main_t * vam)
7542 {
7543   unformat_input_t *i = vam->input;
7544   vl_api_l2fib_add_del_t *mp;
7545   f64 timeout;
7546   u8 mac[6] = { 0 };
7547   u8 mac_set = 0;
7548   u32 bd_id;
7549   u8 bd_id_set = 0;
7550   u32 sw_if_index = 0;
7551   u8 sw_if_index_set = 0;
7552   u8 is_add = 1;
7553   u8 static_mac = 0;
7554   u8 filter_mac = 0;
7555   u8 bvi_mac = 0;
7556   int count = 1;
7557   f64 before = 0;
7558   int j;
7559
7560   /* Parse args required to build the message */
7561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7562     {
7563       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7564         mac_set = 1;
7565       else if (unformat (i, "bd_id %d", &bd_id))
7566         bd_id_set = 1;
7567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7568         sw_if_index_set = 1;
7569       else if (unformat (i, "sw_if"))
7570         {
7571           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7572             {
7573               if (unformat
7574                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7575                 sw_if_index_set = 1;
7576             }
7577           else
7578             break;
7579         }
7580       else if (unformat (i, "static"))
7581         static_mac = 1;
7582       else if (unformat (i, "filter"))
7583         {
7584           filter_mac = 1;
7585           static_mac = 1;
7586         }
7587       else if (unformat (i, "bvi"))
7588         {
7589           bvi_mac = 1;
7590           static_mac = 1;
7591         }
7592       else if (unformat (i, "del"))
7593         is_add = 0;
7594       else if (unformat (i, "count %d", &count))
7595         ;
7596       else
7597         break;
7598     }
7599
7600   if (mac_set == 0)
7601     {
7602       errmsg ("missing mac address");
7603       return -99;
7604     }
7605
7606   if (bd_id_set == 0)
7607     {
7608       errmsg ("missing bridge domain");
7609       return -99;
7610     }
7611
7612   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7613     {
7614       errmsg ("missing interface name or sw_if_index");
7615       return -99;
7616     }
7617
7618   if (count > 1)
7619     {
7620       /* Turn on async mode */
7621       vam->async_mode = 1;
7622       vam->async_errors = 0;
7623       before = vat_time_now (vam);
7624     }
7625
7626   for (j = 0; j < count; j++)
7627     {
7628       M (L2FIB_ADD_DEL, mp);
7629
7630       clib_memcpy (mp->mac, mac, 6);
7631       mp->bd_id = ntohl (bd_id);
7632       mp->is_add = is_add;
7633       mp->sw_if_index = ntohl (sw_if_index);
7634
7635       if (is_add)
7636         {
7637           mp->static_mac = static_mac;
7638           mp->filter_mac = filter_mac;
7639           mp->bvi_mac = bvi_mac;
7640         }
7641       increment_mac_address (mac);
7642       /* send it... */
7643       S (mp);
7644     }
7645
7646   if (count > 1)
7647     {
7648       vl_api_control_ping_t *mp_ping;
7649       f64 after;
7650
7651       /* Shut off async mode */
7652       vam->async_mode = 0;
7653
7654       MPING (CONTROL_PING, mp_ping);
7655       S (mp_ping);
7656
7657       timeout = vat_time_now (vam) + 1.0;
7658       while (vat_time_now (vam) < timeout)
7659         if (vam->result_ready == 1)
7660           goto out;
7661       vam->retval = -99;
7662
7663     out:
7664       if (vam->retval == -99)
7665         errmsg ("timeout");
7666
7667       if (vam->async_errors > 0)
7668         {
7669           errmsg ("%d asynchronous errors", vam->async_errors);
7670           vam->retval = -98;
7671         }
7672       vam->async_errors = 0;
7673       after = vat_time_now (vam);
7674
7675       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7676              count, after - before, count / (after - before));
7677     }
7678   else
7679     {
7680       int ret;
7681
7682       /* Wait for a reply... */
7683       W (ret);
7684       return ret;
7685     }
7686   /* Return the good/bad news */
7687   return (vam->retval);
7688 }
7689
7690 static int
7691 api_bridge_domain_set_mac_age (vat_main_t * vam)
7692 {
7693   unformat_input_t *i = vam->input;
7694   vl_api_bridge_domain_set_mac_age_t *mp;
7695   u32 bd_id = ~0;
7696   u32 mac_age = 0;
7697   int ret;
7698
7699   /* Parse args required to build the message */
7700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7701     {
7702       if (unformat (i, "bd_id %d", &bd_id));
7703       else if (unformat (i, "mac-age %d", &mac_age));
7704       else
7705         break;
7706     }
7707
7708   if (bd_id == ~0)
7709     {
7710       errmsg ("missing bridge domain");
7711       return -99;
7712     }
7713
7714   if (mac_age > 255)
7715     {
7716       errmsg ("mac age must be less than 256 ");
7717       return -99;
7718     }
7719
7720   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7721
7722   mp->bd_id = htonl (bd_id);
7723   mp->mac_age = (u8) mac_age;
7724
7725   S (mp);
7726   W (ret);
7727   return ret;
7728 }
7729
7730 static int
7731 api_l2_flags (vat_main_t * vam)
7732 {
7733   unformat_input_t *i = vam->input;
7734   vl_api_l2_flags_t *mp;
7735   u32 sw_if_index;
7736   u32 flags = 0;
7737   u8 sw_if_index_set = 0;
7738   u8 is_set = 0;
7739   int ret;
7740
7741   /* Parse args required to build the message */
7742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7743     {
7744       if (unformat (i, "sw_if_index %d", &sw_if_index))
7745         sw_if_index_set = 1;
7746       else if (unformat (i, "sw_if"))
7747         {
7748           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7749             {
7750               if (unformat
7751                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7752                 sw_if_index_set = 1;
7753             }
7754           else
7755             break;
7756         }
7757       else if (unformat (i, "learn"))
7758         flags |= L2_LEARN;
7759       else if (unformat (i, "forward"))
7760         flags |= L2_FWD;
7761       else if (unformat (i, "flood"))
7762         flags |= L2_FLOOD;
7763       else if (unformat (i, "uu-flood"))
7764         flags |= L2_UU_FLOOD;
7765       else if (unformat (i, "arp-term"))
7766         flags |= L2_ARP_TERM;
7767       else if (unformat (i, "off"))
7768         is_set = 0;
7769       else if (unformat (i, "disable"))
7770         is_set = 0;
7771       else
7772         break;
7773     }
7774
7775   if (sw_if_index_set == 0)
7776     {
7777       errmsg ("missing interface name or sw_if_index");
7778       return -99;
7779     }
7780
7781   M (L2_FLAGS, mp);
7782
7783   mp->sw_if_index = ntohl (sw_if_index);
7784   mp->feature_bitmap = ntohl (flags);
7785   mp->is_set = is_set;
7786
7787   S (mp);
7788   W (ret);
7789   return ret;
7790 }
7791
7792 static int
7793 api_bridge_flags (vat_main_t * vam)
7794 {
7795   unformat_input_t *i = vam->input;
7796   vl_api_bridge_flags_t *mp;
7797   u32 bd_id;
7798   u8 bd_id_set = 0;
7799   u8 is_set = 1;
7800   bd_flags_t flags = 0;
7801   int ret;
7802
7803   /* Parse args required to build the message */
7804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7805     {
7806       if (unformat (i, "bd_id %d", &bd_id))
7807         bd_id_set = 1;
7808       else if (unformat (i, "learn"))
7809         flags |= BRIDGE_API_FLAG_LEARN;
7810       else if (unformat (i, "forward"))
7811         flags |= BRIDGE_API_FLAG_FWD;
7812       else if (unformat (i, "flood"))
7813         flags |= BRIDGE_API_FLAG_FLOOD;
7814       else if (unformat (i, "uu-flood"))
7815         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7816       else if (unformat (i, "arp-term"))
7817         flags |= BRIDGE_API_FLAG_ARP_TERM;
7818       else if (unformat (i, "off"))
7819         is_set = 0;
7820       else if (unformat (i, "disable"))
7821         is_set = 0;
7822       else
7823         break;
7824     }
7825
7826   if (bd_id_set == 0)
7827     {
7828       errmsg ("missing bridge domain");
7829       return -99;
7830     }
7831
7832   M (BRIDGE_FLAGS, mp);
7833
7834   mp->bd_id = ntohl (bd_id);
7835   mp->flags = ntohl (flags);
7836   mp->is_set = is_set;
7837
7838   S (mp);
7839   W (ret);
7840   return ret;
7841 }
7842
7843 static int
7844 api_bd_ip_mac_add_del (vat_main_t * vam)
7845 {
7846   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7847   vl_api_mac_address_t mac = VL_API_ZERO_MAC_ADDRESS;
7848   unformat_input_t *i = vam->input;
7849   vl_api_bd_ip_mac_add_del_t *mp;
7850   ip46_type_t type;
7851   u32 bd_id;
7852   u8 is_ipv6 = 0;
7853   u8 is_add = 1;
7854   u8 bd_id_set = 0;
7855   u8 ip_set = 0;
7856   u8 mac_set = 0;
7857   u8 macaddr[6];
7858   int ret;
7859
7860
7861   /* Parse args required to build the message */
7862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7863     {
7864       if (unformat (i, "bd_id %d", &bd_id))
7865         {
7866           bd_id_set++;
7867         }
7868       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7869         {
7870           ip_set++;
7871         }
7872       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7873         {
7874           mac_set++;
7875         }
7876       else if (unformat (i, "del"))
7877         is_add = 0;
7878       else
7879         break;
7880     }
7881
7882   if (bd_id_set == 0)
7883     {
7884       errmsg ("missing bridge domain");
7885       return -99;
7886     }
7887   else if (ip_set == 0)
7888     {
7889       errmsg ("missing IP address");
7890       return -99;
7891     }
7892   else if (mac_set == 0)
7893     {
7894       errmsg ("missing MAC address");
7895       return -99;
7896     }
7897
7898   M (BD_IP_MAC_ADD_DEL, mp);
7899
7900   mp->bd_id = ntohl (bd_id);
7901   mp->is_add = is_add;
7902
7903   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7904   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7905
7906   S (mp);
7907   W (ret);
7908   return ret;
7909 }
7910
7911 static void vl_api_bd_ip_mac_details_t_handler
7912   (vl_api_bd_ip_mac_details_t * mp)
7913 {
7914   vat_main_t *vam = &vat_main;
7915   u8 *ip = 0;
7916
7917   if (!mp->is_ipv6)
7918     ip =
7919       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7920   else
7921     ip =
7922       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7923
7924   print (vam->ofp,
7925          "\n%-5d %-7s %-20U %-30s",
7926          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7927          format_ethernet_address, mp->mac_address, ip);
7928
7929   vec_free (ip);
7930 }
7931
7932 static void vl_api_bd_ip_mac_details_t_handler_json
7933   (vl_api_bd_ip_mac_details_t * mp)
7934 {
7935   vat_main_t *vam = &vat_main;
7936   vat_json_node_t *node = NULL;
7937
7938   if (VAT_JSON_ARRAY != vam->json_tree.type)
7939     {
7940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7941       vat_json_init_array (&vam->json_tree);
7942     }
7943   node = vat_json_array_add (&vam->json_tree);
7944
7945   vat_json_init_object (node);
7946   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7947   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7948   vat_json_object_add_string_copy (node, "mac_address",
7949                                    format (0, "%U", format_ethernet_address,
7950                                            &mp->mac_address));
7951   u8 *ip = 0;
7952
7953   if (!mp->is_ipv6)
7954     ip =
7955       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7956   else
7957     ip =
7958       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7959   vat_json_object_add_string_copy (node, "ip_address", ip);
7960   vec_free (ip);
7961 }
7962
7963 static int
7964 api_bd_ip_mac_dump (vat_main_t * vam)
7965 {
7966   unformat_input_t *i = vam->input;
7967   vl_api_bd_ip_mac_dump_t *mp;
7968   vl_api_control_ping_t *mp_ping;
7969   int ret;
7970   u32 bd_id;
7971   u8 bd_id_set = 0;
7972
7973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7974     {
7975       if (unformat (i, "bd_id %d", &bd_id))
7976         {
7977           bd_id_set++;
7978         }
7979       else
7980         break;
7981     }
7982
7983   print (vam->ofp,
7984          "\n%-5s %-7s %-20s %-30s",
7985          "bd_id", "is_ipv6", "mac_address", "ip_address");
7986
7987   /* Dump Bridge Domain Ip to Mac entries */
7988   M (BD_IP_MAC_DUMP, mp);
7989
7990   if (bd_id_set)
7991     mp->bd_id = htonl (bd_id);
7992   else
7993     mp->bd_id = ~0;
7994
7995   S (mp);
7996
7997   /* Use a control ping for synchronization */
7998   MPING (CONTROL_PING, mp_ping);
7999   S (mp_ping);
8000
8001   W (ret);
8002   return ret;
8003 }
8004
8005 static int
8006 api_tap_connect (vat_main_t * vam)
8007 {
8008   unformat_input_t *i = vam->input;
8009   vl_api_tap_connect_t *mp;
8010   u8 mac_address[6];
8011   u8 random_mac = 1;
8012   u8 name_set = 0;
8013   u8 *tap_name;
8014   u8 *tag = 0;
8015   ip4_address_t ip4_address;
8016   u32 ip4_mask_width;
8017   int ip4_address_set = 0;
8018   ip6_address_t ip6_address;
8019   u32 ip6_mask_width;
8020   int ip6_address_set = 0;
8021   int ret;
8022
8023   clib_memset (mac_address, 0, sizeof (mac_address));
8024
8025   /* Parse args required to build the message */
8026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8027     {
8028       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8029         {
8030           random_mac = 0;
8031         }
8032       else if (unformat (i, "random-mac"))
8033         random_mac = 1;
8034       else if (unformat (i, "tapname %s", &tap_name))
8035         name_set = 1;
8036       else if (unformat (i, "tag %s", &tag))
8037         ;
8038       else if (unformat (i, "address %U/%d",
8039                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
8040         ip4_address_set = 1;
8041       else if (unformat (i, "address %U/%d",
8042                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
8043         ip6_address_set = 1;
8044       else
8045         break;
8046     }
8047
8048   if (name_set == 0)
8049     {
8050       errmsg ("missing tap name");
8051       return -99;
8052     }
8053   if (vec_len (tap_name) > 63)
8054     {
8055       errmsg ("tap name too long");
8056       return -99;
8057     }
8058   vec_add1 (tap_name, 0);
8059
8060   if (vec_len (tag) > 63)
8061     {
8062       errmsg ("tag too long");
8063       return -99;
8064     }
8065
8066   /* Construct the API message */
8067   M (TAP_CONNECT, mp);
8068
8069   mp->use_random_mac = random_mac;
8070   clib_memcpy (mp->mac_address, mac_address, 6);
8071   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8072   if (tag)
8073     clib_memcpy (mp->tag, tag, vec_len (tag));
8074
8075   if (ip4_address_set)
8076     {
8077       mp->ip4_address_set = 1;
8078       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
8079       mp->ip4_mask_width = ip4_mask_width;
8080     }
8081   if (ip6_address_set)
8082     {
8083       mp->ip6_address_set = 1;
8084       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
8085       mp->ip6_mask_width = ip6_mask_width;
8086     }
8087
8088   vec_free (tap_name);
8089   vec_free (tag);
8090
8091   /* send it... */
8092   S (mp);
8093
8094   /* Wait for a reply... */
8095   W (ret);
8096   return ret;
8097 }
8098
8099 static int
8100 api_tap_modify (vat_main_t * vam)
8101 {
8102   unformat_input_t *i = vam->input;
8103   vl_api_tap_modify_t *mp;
8104   u8 mac_address[6];
8105   u8 random_mac = 1;
8106   u8 name_set = 0;
8107   u8 *tap_name;
8108   u32 sw_if_index = ~0;
8109   u8 sw_if_index_set = 0;
8110   int ret;
8111
8112   clib_memset (mac_address, 0, sizeof (mac_address));
8113
8114   /* Parse args required to build the message */
8115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8116     {
8117       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8118         sw_if_index_set = 1;
8119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8120         sw_if_index_set = 1;
8121       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8122         {
8123           random_mac = 0;
8124         }
8125       else if (unformat (i, "random-mac"))
8126         random_mac = 1;
8127       else if (unformat (i, "tapname %s", &tap_name))
8128         name_set = 1;
8129       else
8130         break;
8131     }
8132
8133   if (sw_if_index_set == 0)
8134     {
8135       errmsg ("missing vpp interface name");
8136       return -99;
8137     }
8138   if (name_set == 0)
8139     {
8140       errmsg ("missing tap name");
8141       return -99;
8142     }
8143   if (vec_len (tap_name) > 63)
8144     {
8145       errmsg ("tap name too long");
8146     }
8147   vec_add1 (tap_name, 0);
8148
8149   /* Construct the API message */
8150   M (TAP_MODIFY, mp);
8151
8152   mp->use_random_mac = random_mac;
8153   mp->sw_if_index = ntohl (sw_if_index);
8154   clib_memcpy (mp->mac_address, mac_address, 6);
8155   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8156   vec_free (tap_name);
8157
8158   /* send it... */
8159   S (mp);
8160
8161   /* Wait for a reply... */
8162   W (ret);
8163   return ret;
8164 }
8165
8166 static int
8167 api_tap_delete (vat_main_t * vam)
8168 {
8169   unformat_input_t *i = vam->input;
8170   vl_api_tap_delete_t *mp;
8171   u32 sw_if_index = ~0;
8172   u8 sw_if_index_set = 0;
8173   int ret;
8174
8175   /* Parse args required to build the message */
8176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8177     {
8178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8179         sw_if_index_set = 1;
8180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8181         sw_if_index_set = 1;
8182       else
8183         break;
8184     }
8185
8186   if (sw_if_index_set == 0)
8187     {
8188       errmsg ("missing vpp interface name");
8189       return -99;
8190     }
8191
8192   /* Construct the API message */
8193   M (TAP_DELETE, mp);
8194
8195   mp->sw_if_index = ntohl (sw_if_index);
8196
8197   /* send it... */
8198   S (mp);
8199
8200   /* Wait for a reply... */
8201   W (ret);
8202   return ret;
8203 }
8204
8205 static int
8206 api_tap_create_v2 (vat_main_t * vam)
8207 {
8208   unformat_input_t *i = vam->input;
8209   vl_api_tap_create_v2_t *mp;
8210   u8 mac_address[6];
8211   u8 random_mac = 1;
8212   u32 id = ~0;
8213   u8 *host_if_name = 0;
8214   u8 *host_ns = 0;
8215   u8 host_mac_addr[6];
8216   u8 host_mac_addr_set = 0;
8217   u8 *host_bridge = 0;
8218   ip4_address_t host_ip4_addr;
8219   ip4_address_t host_ip4_gw;
8220   u8 host_ip4_gw_set = 0;
8221   u32 host_ip4_prefix_len = 0;
8222   ip6_address_t host_ip6_addr;
8223   ip6_address_t host_ip6_gw;
8224   u8 host_ip6_gw_set = 0;
8225   u32 host_ip6_prefix_len = 0;
8226   int ret;
8227   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8228
8229   clib_memset (mac_address, 0, sizeof (mac_address));
8230
8231   /* Parse args required to build the message */
8232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8233     {
8234       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8235         {
8236           random_mac = 0;
8237         }
8238       else if (unformat (i, "id %u", &id))
8239         ;
8240       else if (unformat (i, "host-if-name %s", &host_if_name))
8241         ;
8242       else if (unformat (i, "host-ns %s", &host_ns))
8243         ;
8244       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8245                          host_mac_addr))
8246         host_mac_addr_set = 1;
8247       else if (unformat (i, "host-bridge %s", &host_bridge))
8248         ;
8249       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8250                          &host_ip4_addr, &host_ip4_prefix_len))
8251         ;
8252       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8253                          &host_ip6_addr, &host_ip6_prefix_len))
8254         ;
8255       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8256                          &host_ip4_gw))
8257         host_ip4_gw_set = 1;
8258       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8259                          &host_ip6_gw))
8260         host_ip6_gw_set = 1;
8261       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8262         ;
8263       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8264         ;
8265       else
8266         break;
8267     }
8268
8269   if (vec_len (host_if_name) > 63)
8270     {
8271       errmsg ("tap name too long. ");
8272       return -99;
8273     }
8274   if (vec_len (host_ns) > 63)
8275     {
8276       errmsg ("host name space too long. ");
8277       return -99;
8278     }
8279   if (vec_len (host_bridge) > 63)
8280     {
8281       errmsg ("host bridge name too long. ");
8282       return -99;
8283     }
8284   if (host_ip4_prefix_len > 32)
8285     {
8286       errmsg ("host ip4 prefix length not valid. ");
8287       return -99;
8288     }
8289   if (host_ip6_prefix_len > 128)
8290     {
8291       errmsg ("host ip6 prefix length not valid. ");
8292       return -99;
8293     }
8294   if (!is_pow2 (rx_ring_sz))
8295     {
8296       errmsg ("rx ring size must be power of 2. ");
8297       return -99;
8298     }
8299   if (rx_ring_sz > 32768)
8300     {
8301       errmsg ("rx ring size must be 32768 or lower. ");
8302       return -99;
8303     }
8304   if (!is_pow2 (tx_ring_sz))
8305     {
8306       errmsg ("tx ring size must be power of 2. ");
8307       return -99;
8308     }
8309   if (tx_ring_sz > 32768)
8310     {
8311       errmsg ("tx ring size must be 32768 or lower. ");
8312       return -99;
8313     }
8314
8315   /* Construct the API message */
8316   M (TAP_CREATE_V2, mp);
8317
8318   mp->use_random_mac = random_mac;
8319
8320   mp->id = ntohl (id);
8321   mp->host_namespace_set = host_ns != 0;
8322   mp->host_bridge_set = host_bridge != 0;
8323   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8324   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8325   mp->rx_ring_sz = ntohs (rx_ring_sz);
8326   mp->tx_ring_sz = ntohs (tx_ring_sz);
8327
8328   if (random_mac == 0)
8329     clib_memcpy (mp->mac_address, mac_address, 6);
8330   if (host_mac_addr_set)
8331     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8332   if (host_if_name)
8333     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8334   if (host_ns)
8335     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8336   if (host_bridge)
8337     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8338   if (host_ip4_prefix_len)
8339     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8340   if (host_ip6_prefix_len)
8341     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8342   if (host_ip4_gw_set)
8343     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8344   if (host_ip6_gw_set)
8345     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8346
8347   vec_free (host_ns);
8348   vec_free (host_if_name);
8349   vec_free (host_bridge);
8350
8351   /* send it... */
8352   S (mp);
8353
8354   /* Wait for a reply... */
8355   W (ret);
8356   return ret;
8357 }
8358
8359 static int
8360 api_tap_delete_v2 (vat_main_t * vam)
8361 {
8362   unformat_input_t *i = vam->input;
8363   vl_api_tap_delete_v2_t *mp;
8364   u32 sw_if_index = ~0;
8365   u8 sw_if_index_set = 0;
8366   int ret;
8367
8368   /* Parse args required to build the message */
8369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8370     {
8371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8372         sw_if_index_set = 1;
8373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8374         sw_if_index_set = 1;
8375       else
8376         break;
8377     }
8378
8379   if (sw_if_index_set == 0)
8380     {
8381       errmsg ("missing vpp interface name. ");
8382       return -99;
8383     }
8384
8385   /* Construct the API message */
8386   M (TAP_DELETE_V2, mp);
8387
8388   mp->sw_if_index = ntohl (sw_if_index);
8389
8390   /* send it... */
8391   S (mp);
8392
8393   /* Wait for a reply... */
8394   W (ret);
8395   return ret;
8396 }
8397
8398 static int
8399 api_bond_create (vat_main_t * vam)
8400 {
8401   unformat_input_t *i = vam->input;
8402   vl_api_bond_create_t *mp;
8403   u8 mac_address[6];
8404   u8 custom_mac = 0;
8405   int ret;
8406   u8 mode;
8407   u8 lb;
8408   u8 mode_is_set = 0;
8409
8410   clib_memset (mac_address, 0, sizeof (mac_address));
8411   lb = BOND_LB_L2;
8412
8413   /* Parse args required to build the message */
8414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8415     {
8416       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8417         mode_is_set = 1;
8418       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8419                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8420         ;
8421       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8422                          mac_address))
8423         custom_mac = 1;
8424       else
8425         break;
8426     }
8427
8428   if (mode_is_set == 0)
8429     {
8430       errmsg ("Missing bond mode. ");
8431       return -99;
8432     }
8433
8434   /* Construct the API message */
8435   M (BOND_CREATE, mp);
8436
8437   mp->use_custom_mac = custom_mac;
8438
8439   mp->mode = mode;
8440   mp->lb = lb;
8441
8442   if (custom_mac)
8443     clib_memcpy (mp->mac_address, mac_address, 6);
8444
8445   /* send it... */
8446   S (mp);
8447
8448   /* Wait for a reply... */
8449   W (ret);
8450   return ret;
8451 }
8452
8453 static int
8454 api_bond_delete (vat_main_t * vam)
8455 {
8456   unformat_input_t *i = vam->input;
8457   vl_api_bond_delete_t *mp;
8458   u32 sw_if_index = ~0;
8459   u8 sw_if_index_set = 0;
8460   int ret;
8461
8462   /* Parse args required to build the message */
8463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8464     {
8465       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8466         sw_if_index_set = 1;
8467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8468         sw_if_index_set = 1;
8469       else
8470         break;
8471     }
8472
8473   if (sw_if_index_set == 0)
8474     {
8475       errmsg ("missing vpp interface name. ");
8476       return -99;
8477     }
8478
8479   /* Construct the API message */
8480   M (BOND_DELETE, mp);
8481
8482   mp->sw_if_index = ntohl (sw_if_index);
8483
8484   /* send it... */
8485   S (mp);
8486
8487   /* Wait for a reply... */
8488   W (ret);
8489   return ret;
8490 }
8491
8492 static int
8493 api_bond_enslave (vat_main_t * vam)
8494 {
8495   unformat_input_t *i = vam->input;
8496   vl_api_bond_enslave_t *mp;
8497   u32 bond_sw_if_index;
8498   int ret;
8499   u8 is_passive;
8500   u8 is_long_timeout;
8501   u32 bond_sw_if_index_is_set = 0;
8502   u32 sw_if_index;
8503   u8 sw_if_index_is_set = 0;
8504
8505   /* Parse args required to build the message */
8506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8507     {
8508       if (unformat (i, "sw_if_index %d", &sw_if_index))
8509         sw_if_index_is_set = 1;
8510       else if (unformat (i, "bond %u", &bond_sw_if_index))
8511         bond_sw_if_index_is_set = 1;
8512       else if (unformat (i, "passive %d", &is_passive))
8513         ;
8514       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8515         ;
8516       else
8517         break;
8518     }
8519
8520   if (bond_sw_if_index_is_set == 0)
8521     {
8522       errmsg ("Missing bond sw_if_index. ");
8523       return -99;
8524     }
8525   if (sw_if_index_is_set == 0)
8526     {
8527       errmsg ("Missing slave sw_if_index. ");
8528       return -99;
8529     }
8530
8531   /* Construct the API message */
8532   M (BOND_ENSLAVE, mp);
8533
8534   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8535   mp->sw_if_index = ntohl (sw_if_index);
8536   mp->is_long_timeout = is_long_timeout;
8537   mp->is_passive = is_passive;
8538
8539   /* send it... */
8540   S (mp);
8541
8542   /* Wait for a reply... */
8543   W (ret);
8544   return ret;
8545 }
8546
8547 static int
8548 api_bond_detach_slave (vat_main_t * vam)
8549 {
8550   unformat_input_t *i = vam->input;
8551   vl_api_bond_detach_slave_t *mp;
8552   u32 sw_if_index = ~0;
8553   u8 sw_if_index_set = 0;
8554   int ret;
8555
8556   /* Parse args required to build the message */
8557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8558     {
8559       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8560         sw_if_index_set = 1;
8561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8562         sw_if_index_set = 1;
8563       else
8564         break;
8565     }
8566
8567   if (sw_if_index_set == 0)
8568     {
8569       errmsg ("missing vpp interface name. ");
8570       return -99;
8571     }
8572
8573   /* Construct the API message */
8574   M (BOND_DETACH_SLAVE, mp);
8575
8576   mp->sw_if_index = ntohl (sw_if_index);
8577
8578   /* send it... */
8579   S (mp);
8580
8581   /* Wait for a reply... */
8582   W (ret);
8583   return ret;
8584 }
8585
8586 static int
8587 api_ip_table_add_del (vat_main_t * vam)
8588 {
8589   unformat_input_t *i = vam->input;
8590   vl_api_ip_table_add_del_t *mp;
8591   u32 table_id = ~0;
8592   u8 is_ipv6 = 0;
8593   u8 is_add = 1;
8594   int ret = 0;
8595
8596   /* Parse args required to build the message */
8597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8598     {
8599       if (unformat (i, "ipv6"))
8600         is_ipv6 = 1;
8601       else if (unformat (i, "del"))
8602         is_add = 0;
8603       else if (unformat (i, "add"))
8604         is_add = 1;
8605       else if (unformat (i, "table %d", &table_id))
8606         ;
8607       else
8608         {
8609           clib_warning ("parse error '%U'", format_unformat_error, i);
8610           return -99;
8611         }
8612     }
8613
8614   if (~0 == table_id)
8615     {
8616       errmsg ("missing table-ID");
8617       return -99;
8618     }
8619
8620   /* Construct the API message */
8621   M (IP_TABLE_ADD_DEL, mp);
8622
8623   mp->table_id = ntohl (table_id);
8624   mp->is_ipv6 = is_ipv6;
8625   mp->is_add = is_add;
8626
8627   /* send it... */
8628   S (mp);
8629
8630   /* Wait for a reply... */
8631   W (ret);
8632
8633   return ret;
8634 }
8635
8636 static int
8637 api_ip_add_del_route (vat_main_t * vam)
8638 {
8639   unformat_input_t *i = vam->input;
8640   vl_api_ip_add_del_route_t *mp;
8641   u32 sw_if_index = ~0, vrf_id = 0;
8642   u8 is_ipv6 = 0;
8643   u8 is_local = 0, is_drop = 0;
8644   u8 is_unreach = 0, is_prohibit = 0;
8645   u8 is_add = 1;
8646   u32 next_hop_weight = 1;
8647   u8 is_multipath = 0;
8648   u8 address_set = 0;
8649   u8 address_length_set = 0;
8650   u32 next_hop_table_id = 0;
8651   u32 resolve_attempts = 0;
8652   u32 dst_address_length = 0;
8653   u8 next_hop_set = 0;
8654   ip4_address_t v4_dst_address, v4_next_hop_address;
8655   ip6_address_t v6_dst_address, v6_next_hop_address;
8656   int count = 1;
8657   int j;
8658   f64 before = 0;
8659   u32 random_add_del = 0;
8660   u32 *random_vector = 0;
8661   uword *random_hash;
8662   u32 random_seed = 0xdeaddabe;
8663   u32 classify_table_index = ~0;
8664   u8 is_classify = 0;
8665   u8 resolve_host = 0, resolve_attached = 0;
8666   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8667   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8668   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8669
8670   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8671   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8672   /* Parse args required to build the message */
8673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8674     {
8675       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8676         ;
8677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8678         ;
8679       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8680         {
8681           address_set = 1;
8682           is_ipv6 = 0;
8683         }
8684       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8685         {
8686           address_set = 1;
8687           is_ipv6 = 1;
8688         }
8689       else if (unformat (i, "/%d", &dst_address_length))
8690         {
8691           address_length_set = 1;
8692         }
8693
8694       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8695                                          &v4_next_hop_address))
8696         {
8697           next_hop_set = 1;
8698         }
8699       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8700                                          &v6_next_hop_address))
8701         {
8702           next_hop_set = 1;
8703         }
8704       else
8705         if (unformat
8706             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8707         {
8708           next_hop_set = 1;
8709         }
8710       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8711         {
8712           next_hop_set = 1;
8713         }
8714       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8715         ;
8716       else if (unformat (i, "weight %d", &next_hop_weight))
8717         ;
8718       else if (unformat (i, "drop"))
8719         {
8720           is_drop = 1;
8721         }
8722       else if (unformat (i, "null-send-unreach"))
8723         {
8724           is_unreach = 1;
8725         }
8726       else if (unformat (i, "null-send-prohibit"))
8727         {
8728           is_prohibit = 1;
8729         }
8730       else if (unformat (i, "local"))
8731         {
8732           is_local = 1;
8733         }
8734       else if (unformat (i, "classify %d", &classify_table_index))
8735         {
8736           is_classify = 1;
8737         }
8738       else if (unformat (i, "del"))
8739         is_add = 0;
8740       else if (unformat (i, "add"))
8741         is_add = 1;
8742       else if (unformat (i, "resolve-via-host"))
8743         resolve_host = 1;
8744       else if (unformat (i, "resolve-via-attached"))
8745         resolve_attached = 1;
8746       else if (unformat (i, "multipath"))
8747         is_multipath = 1;
8748       else if (unformat (i, "vrf %d", &vrf_id))
8749         ;
8750       else if (unformat (i, "count %d", &count))
8751         ;
8752       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8753         ;
8754       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8755         ;
8756       else if (unformat (i, "out-label %d", &next_hop_out_label))
8757         {
8758           vl_api_fib_mpls_label_t fib_label = {
8759             .label = ntohl (next_hop_out_label),
8760             .ttl = 64,
8761             .exp = 0,
8762           };
8763           vec_add1 (next_hop_out_label_stack, fib_label);
8764         }
8765       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8766         ;
8767       else if (unformat (i, "random"))
8768         random_add_del = 1;
8769       else if (unformat (i, "seed %d", &random_seed))
8770         ;
8771       else
8772         {
8773           clib_warning ("parse error '%U'", format_unformat_error, i);
8774           return -99;
8775         }
8776     }
8777
8778   if (!next_hop_set && !is_drop && !is_local &&
8779       !is_classify && !is_unreach && !is_prohibit &&
8780       MPLS_LABEL_INVALID == next_hop_via_label)
8781     {
8782       errmsg
8783         ("next hop / local / drop / unreach / prohibit / classify not set");
8784       return -99;
8785     }
8786
8787   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8788     {
8789       errmsg ("next hop and next-hop via label set");
8790       return -99;
8791     }
8792   if (address_set == 0)
8793     {
8794       errmsg ("missing addresses");
8795       return -99;
8796     }
8797
8798   if (address_length_set == 0)
8799     {
8800       errmsg ("missing address length");
8801       return -99;
8802     }
8803
8804   /* Generate a pile of unique, random routes */
8805   if (random_add_del)
8806     {
8807       u32 this_random_address;
8808       random_hash = hash_create (count, sizeof (uword));
8809
8810       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8811       for (j = 0; j <= count; j++)
8812         {
8813           do
8814             {
8815               this_random_address = random_u32 (&random_seed);
8816               this_random_address =
8817                 clib_host_to_net_u32 (this_random_address);
8818             }
8819           while (hash_get (random_hash, this_random_address));
8820           vec_add1 (random_vector, this_random_address);
8821           hash_set (random_hash, this_random_address, 1);
8822         }
8823       hash_free (random_hash);
8824       v4_dst_address.as_u32 = random_vector[0];
8825     }
8826
8827   if (count > 1)
8828     {
8829       /* Turn on async mode */
8830       vam->async_mode = 1;
8831       vam->async_errors = 0;
8832       before = vat_time_now (vam);
8833     }
8834
8835   for (j = 0; j < count; j++)
8836     {
8837       /* Construct the API message */
8838       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8839           vec_len (next_hop_out_label_stack));
8840
8841       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8842       mp->table_id = ntohl (vrf_id);
8843
8844       mp->is_add = is_add;
8845       mp->is_drop = is_drop;
8846       mp->is_unreach = is_unreach;
8847       mp->is_prohibit = is_prohibit;
8848       mp->is_ipv6 = is_ipv6;
8849       mp->is_local = is_local;
8850       mp->is_classify = is_classify;
8851       mp->is_multipath = is_multipath;
8852       mp->is_resolve_host = resolve_host;
8853       mp->is_resolve_attached = resolve_attached;
8854       mp->next_hop_weight = next_hop_weight;
8855       mp->next_hop_preference = 0;
8856       mp->dst_address_length = dst_address_length;
8857       mp->next_hop_table_id = ntohl (next_hop_table_id);
8858       mp->classify_table_index = ntohl (classify_table_index);
8859       mp->next_hop_via_label = ntohl (next_hop_via_label);
8860       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8861       if (0 != mp->next_hop_n_out_labels)
8862         {
8863           memcpy (mp->next_hop_out_label_stack,
8864                   next_hop_out_label_stack,
8865                   (vec_len (next_hop_out_label_stack) *
8866                    sizeof (vl_api_fib_mpls_label_t)));
8867           vec_free (next_hop_out_label_stack);
8868         }
8869
8870       if (is_ipv6)
8871         {
8872           clib_memcpy (mp->dst_address, &v6_dst_address,
8873                        sizeof (v6_dst_address));
8874           if (next_hop_set)
8875             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8876                          sizeof (v6_next_hop_address));
8877           increment_v6_address (&v6_dst_address);
8878         }
8879       else
8880         {
8881           clib_memcpy (mp->dst_address, &v4_dst_address,
8882                        sizeof (v4_dst_address));
8883           if (next_hop_set)
8884             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8885                          sizeof (v4_next_hop_address));
8886           if (random_add_del)
8887             v4_dst_address.as_u32 = random_vector[j + 1];
8888           else
8889             increment_v4_address (&v4_dst_address);
8890         }
8891       /* send it... */
8892       S (mp);
8893       /* If we receive SIGTERM, stop now... */
8894       if (vam->do_exit)
8895         break;
8896     }
8897
8898   /* When testing multiple add/del ops, use a control-ping to sync */
8899   if (count > 1)
8900     {
8901       vl_api_control_ping_t *mp_ping;
8902       f64 after;
8903       f64 timeout;
8904
8905       /* Shut off async mode */
8906       vam->async_mode = 0;
8907
8908       MPING (CONTROL_PING, mp_ping);
8909       S (mp_ping);
8910
8911       timeout = vat_time_now (vam) + 1.0;
8912       while (vat_time_now (vam) < timeout)
8913         if (vam->result_ready == 1)
8914           goto out;
8915       vam->retval = -99;
8916
8917     out:
8918       if (vam->retval == -99)
8919         errmsg ("timeout");
8920
8921       if (vam->async_errors > 0)
8922         {
8923           errmsg ("%d asynchronous errors", vam->async_errors);
8924           vam->retval = -98;
8925         }
8926       vam->async_errors = 0;
8927       after = vat_time_now (vam);
8928
8929       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8930       if (j > 0)
8931         count = j;
8932
8933       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8934              count, after - before, count / (after - before));
8935     }
8936   else
8937     {
8938       int ret;
8939
8940       /* Wait for a reply... */
8941       W (ret);
8942       return ret;
8943     }
8944
8945   /* Return the good/bad news */
8946   return (vam->retval);
8947 }
8948
8949 static int
8950 api_ip_mroute_add_del (vat_main_t * vam)
8951 {
8952   unformat_input_t *i = vam->input;
8953   vl_api_ip_mroute_add_del_t *mp;
8954   u32 sw_if_index = ~0, vrf_id = 0;
8955   u8 is_ipv6 = 0;
8956   u8 is_local = 0;
8957   u8 is_add = 1;
8958   u8 address_set = 0;
8959   u32 grp_address_length = 0;
8960   ip4_address_t v4_grp_address, v4_src_address;
8961   ip6_address_t v6_grp_address, v6_src_address;
8962   mfib_itf_flags_t iflags = 0;
8963   mfib_entry_flags_t eflags = 0;
8964   int ret;
8965
8966   /* Parse args required to build the message */
8967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8968     {
8969       if (unformat (i, "sw_if_index %d", &sw_if_index))
8970         ;
8971       else if (unformat (i, "%U %U",
8972                          unformat_ip4_address, &v4_src_address,
8973                          unformat_ip4_address, &v4_grp_address))
8974         {
8975           grp_address_length = 64;
8976           address_set = 1;
8977           is_ipv6 = 0;
8978         }
8979       else if (unformat (i, "%U %U",
8980                          unformat_ip6_address, &v6_src_address,
8981                          unformat_ip6_address, &v6_grp_address))
8982         {
8983           grp_address_length = 256;
8984           address_set = 1;
8985           is_ipv6 = 1;
8986         }
8987       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8988         {
8989           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8990           grp_address_length = 32;
8991           address_set = 1;
8992           is_ipv6 = 0;
8993         }
8994       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8995         {
8996           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8997           grp_address_length = 128;
8998           address_set = 1;
8999           is_ipv6 = 1;
9000         }
9001       else if (unformat (i, "/%d", &grp_address_length))
9002         ;
9003       else if (unformat (i, "local"))
9004         {
9005           is_local = 1;
9006         }
9007       else if (unformat (i, "del"))
9008         is_add = 0;
9009       else if (unformat (i, "add"))
9010         is_add = 1;
9011       else if (unformat (i, "vrf %d", &vrf_id))
9012         ;
9013       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
9014         ;
9015       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
9016         ;
9017       else
9018         {
9019           clib_warning ("parse error '%U'", format_unformat_error, i);
9020           return -99;
9021         }
9022     }
9023
9024   if (address_set == 0)
9025     {
9026       errmsg ("missing addresses\n");
9027       return -99;
9028     }
9029
9030   /* Construct the API message */
9031   M (IP_MROUTE_ADD_DEL, mp);
9032
9033   mp->next_hop_sw_if_index = ntohl (sw_if_index);
9034   mp->table_id = ntohl (vrf_id);
9035
9036   mp->is_add = is_add;
9037   mp->is_ipv6 = is_ipv6;
9038   mp->is_local = is_local;
9039   mp->itf_flags = ntohl (iflags);
9040   mp->entry_flags = ntohl (eflags);
9041   mp->grp_address_length = grp_address_length;
9042   mp->grp_address_length = ntohs (mp->grp_address_length);
9043
9044   if (is_ipv6)
9045     {
9046       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
9047       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
9048     }
9049   else
9050     {
9051       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
9052       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
9053
9054     }
9055
9056   /* send it... */
9057   S (mp);
9058   /* Wait for a reply... */
9059   W (ret);
9060   return ret;
9061 }
9062
9063 static int
9064 api_mpls_table_add_del (vat_main_t * vam)
9065 {
9066   unformat_input_t *i = vam->input;
9067   vl_api_mpls_table_add_del_t *mp;
9068   u32 table_id = ~0;
9069   u8 is_add = 1;
9070   int ret = 0;
9071
9072   /* Parse args required to build the message */
9073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9074     {
9075       if (unformat (i, "table %d", &table_id))
9076         ;
9077       else if (unformat (i, "del"))
9078         is_add = 0;
9079       else if (unformat (i, "add"))
9080         is_add = 1;
9081       else
9082         {
9083           clib_warning ("parse error '%U'", format_unformat_error, i);
9084           return -99;
9085         }
9086     }
9087
9088   if (~0 == table_id)
9089     {
9090       errmsg ("missing table-ID");
9091       return -99;
9092     }
9093
9094   /* Construct the API message */
9095   M (MPLS_TABLE_ADD_DEL, mp);
9096
9097   mp->mt_table_id = ntohl (table_id);
9098   mp->mt_is_add = is_add;
9099
9100   /* send it... */
9101   S (mp);
9102
9103   /* Wait for a reply... */
9104   W (ret);
9105
9106   return ret;
9107 }
9108
9109 static int
9110 api_mpls_route_add_del (vat_main_t * vam)
9111 {
9112   unformat_input_t *i = vam->input;
9113   vl_api_mpls_route_add_del_t *mp;
9114   u32 sw_if_index = ~0, table_id = 0;
9115   u8 is_add = 1;
9116   u32 next_hop_weight = 1;
9117   u8 is_multipath = 0;
9118   u32 next_hop_table_id = 0;
9119   u8 next_hop_set = 0;
9120   ip4_address_t v4_next_hop_address = {
9121     .as_u32 = 0,
9122   };
9123   ip6_address_t v6_next_hop_address = { {0} };
9124   int count = 1;
9125   int j;
9126   f64 before = 0;
9127   u32 classify_table_index = ~0;
9128   u8 is_classify = 0;
9129   u8 resolve_host = 0, resolve_attached = 0;
9130   u8 is_interface_rx = 0;
9131   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9132   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9133   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9134   mpls_label_t local_label = MPLS_LABEL_INVALID;
9135   u8 is_eos = 0;
9136   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9137
9138   /* Parse args required to build the message */
9139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9140     {
9141       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9142         ;
9143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9144         ;
9145       else if (unformat (i, "%d", &local_label))
9146         ;
9147       else if (unformat (i, "eos"))
9148         is_eos = 1;
9149       else if (unformat (i, "non-eos"))
9150         is_eos = 0;
9151       else if (unformat (i, "via %U", unformat_ip4_address,
9152                          &v4_next_hop_address))
9153         {
9154           next_hop_set = 1;
9155           next_hop_proto = DPO_PROTO_IP4;
9156         }
9157       else if (unformat (i, "via %U", unformat_ip6_address,
9158                          &v6_next_hop_address))
9159         {
9160           next_hop_set = 1;
9161           next_hop_proto = DPO_PROTO_IP6;
9162         }
9163       else if (unformat (i, "weight %d", &next_hop_weight))
9164         ;
9165       else if (unformat (i, "classify %d", &classify_table_index))
9166         {
9167           is_classify = 1;
9168         }
9169       else if (unformat (i, "del"))
9170         is_add = 0;
9171       else if (unformat (i, "add"))
9172         is_add = 1;
9173       else if (unformat (i, "resolve-via-host"))
9174         resolve_host = 1;
9175       else if (unformat (i, "resolve-via-attached"))
9176         resolve_attached = 1;
9177       else if (unformat (i, "multipath"))
9178         is_multipath = 1;
9179       else if (unformat (i, "count %d", &count))
9180         ;
9181       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9182         {
9183           next_hop_set = 1;
9184           next_hop_proto = DPO_PROTO_IP4;
9185         }
9186       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9187         {
9188           next_hop_set = 1;
9189           next_hop_proto = DPO_PROTO_IP6;
9190         }
9191       else
9192         if (unformat
9193             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9194              &sw_if_index))
9195         {
9196           next_hop_set = 1;
9197           next_hop_proto = DPO_PROTO_ETHERNET;
9198           is_interface_rx = 1;
9199         }
9200       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9201         {
9202           next_hop_set = 1;
9203           next_hop_proto = DPO_PROTO_ETHERNET;
9204           is_interface_rx = 1;
9205         }
9206       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9207         next_hop_set = 1;
9208       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9209         next_hop_set = 1;
9210       else if (unformat (i, "out-label %d", &next_hop_out_label))
9211         {
9212           vl_api_fib_mpls_label_t fib_label = {
9213             .label = ntohl (next_hop_out_label),
9214             .ttl = 64,
9215             .exp = 0,
9216           };
9217           vec_add1 (next_hop_out_label_stack, fib_label);
9218         }
9219       else
9220         {
9221           clib_warning ("parse error '%U'", format_unformat_error, i);
9222           return -99;
9223         }
9224     }
9225
9226   if (!next_hop_set && !is_classify)
9227     {
9228       errmsg ("next hop / classify not set");
9229       return -99;
9230     }
9231
9232   if (MPLS_LABEL_INVALID == local_label)
9233     {
9234       errmsg ("missing label");
9235       return -99;
9236     }
9237
9238   if (count > 1)
9239     {
9240       /* Turn on async mode */
9241       vam->async_mode = 1;
9242       vam->async_errors = 0;
9243       before = vat_time_now (vam);
9244     }
9245
9246   for (j = 0; j < count; j++)
9247     {
9248       /* Construct the API message */
9249       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9250           vec_len (next_hop_out_label_stack));
9251
9252       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9253       mp->mr_table_id = ntohl (table_id);
9254
9255       mp->mr_is_add = is_add;
9256       mp->mr_next_hop_proto = next_hop_proto;
9257       mp->mr_is_classify = is_classify;
9258       mp->mr_is_multipath = is_multipath;
9259       mp->mr_is_resolve_host = resolve_host;
9260       mp->mr_is_resolve_attached = resolve_attached;
9261       mp->mr_is_interface_rx = is_interface_rx;
9262       mp->mr_next_hop_weight = next_hop_weight;
9263       mp->mr_next_hop_preference = 0;
9264       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9265       mp->mr_classify_table_index = ntohl (classify_table_index);
9266       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9267       mp->mr_label = ntohl (local_label);
9268       mp->mr_eos = is_eos;
9269
9270       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9271       if (0 != mp->mr_next_hop_n_out_labels)
9272         {
9273           memcpy (mp->mr_next_hop_out_label_stack,
9274                   next_hop_out_label_stack,
9275                   vec_len (next_hop_out_label_stack) *
9276                   sizeof (vl_api_fib_mpls_label_t));
9277           vec_free (next_hop_out_label_stack);
9278         }
9279
9280       if (next_hop_set)
9281         {
9282           if (DPO_PROTO_IP4 == next_hop_proto)
9283             {
9284               clib_memcpy (mp->mr_next_hop,
9285                            &v4_next_hop_address,
9286                            sizeof (v4_next_hop_address));
9287             }
9288           else if (DPO_PROTO_IP6 == next_hop_proto)
9289
9290             {
9291               clib_memcpy (mp->mr_next_hop,
9292                            &v6_next_hop_address,
9293                            sizeof (v6_next_hop_address));
9294             }
9295         }
9296       local_label++;
9297
9298       /* send it... */
9299       S (mp);
9300       /* If we receive SIGTERM, stop now... */
9301       if (vam->do_exit)
9302         break;
9303     }
9304
9305   /* When testing multiple add/del ops, use a control-ping to sync */
9306   if (count > 1)
9307     {
9308       vl_api_control_ping_t *mp_ping;
9309       f64 after;
9310       f64 timeout;
9311
9312       /* Shut off async mode */
9313       vam->async_mode = 0;
9314
9315       MPING (CONTROL_PING, mp_ping);
9316       S (mp_ping);
9317
9318       timeout = vat_time_now (vam) + 1.0;
9319       while (vat_time_now (vam) < timeout)
9320         if (vam->result_ready == 1)
9321           goto out;
9322       vam->retval = -99;
9323
9324     out:
9325       if (vam->retval == -99)
9326         errmsg ("timeout");
9327
9328       if (vam->async_errors > 0)
9329         {
9330           errmsg ("%d asynchronous errors", vam->async_errors);
9331           vam->retval = -98;
9332         }
9333       vam->async_errors = 0;
9334       after = vat_time_now (vam);
9335
9336       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9337       if (j > 0)
9338         count = j;
9339
9340       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9341              count, after - before, count / (after - before));
9342     }
9343   else
9344     {
9345       int ret;
9346
9347       /* Wait for a reply... */
9348       W (ret);
9349       return ret;
9350     }
9351
9352   /* Return the good/bad news */
9353   return (vam->retval);
9354 }
9355
9356 static int
9357 api_mpls_ip_bind_unbind (vat_main_t * vam)
9358 {
9359   unformat_input_t *i = vam->input;
9360   vl_api_mpls_ip_bind_unbind_t *mp;
9361   u32 ip_table_id = 0;
9362   u8 is_bind = 1;
9363   u8 is_ip4 = 1;
9364   ip4_address_t v4_address;
9365   ip6_address_t v6_address;
9366   u32 address_length;
9367   u8 address_set = 0;
9368   mpls_label_t local_label = MPLS_LABEL_INVALID;
9369   int ret;
9370
9371   /* Parse args required to build the message */
9372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9373     {
9374       if (unformat (i, "%U/%d", unformat_ip4_address,
9375                     &v4_address, &address_length))
9376         {
9377           is_ip4 = 1;
9378           address_set = 1;
9379         }
9380       else if (unformat (i, "%U/%d", unformat_ip6_address,
9381                          &v6_address, &address_length))
9382         {
9383           is_ip4 = 0;
9384           address_set = 1;
9385         }
9386       else if (unformat (i, "%d", &local_label))
9387         ;
9388       else if (unformat (i, "table-id %d", &ip_table_id))
9389         ;
9390       else if (unformat (i, "unbind"))
9391         is_bind = 0;
9392       else if (unformat (i, "bind"))
9393         is_bind = 1;
9394       else
9395         {
9396           clib_warning ("parse error '%U'", format_unformat_error, i);
9397           return -99;
9398         }
9399     }
9400
9401   if (!address_set)
9402     {
9403       errmsg ("IP address not set");
9404       return -99;
9405     }
9406
9407   if (MPLS_LABEL_INVALID == local_label)
9408     {
9409       errmsg ("missing label");
9410       return -99;
9411     }
9412
9413   /* Construct the API message */
9414   M (MPLS_IP_BIND_UNBIND, mp);
9415
9416   mp->mb_is_bind = is_bind;
9417   mp->mb_is_ip4 = is_ip4;
9418   mp->mb_ip_table_id = ntohl (ip_table_id);
9419   mp->mb_mpls_table_id = 0;
9420   mp->mb_label = ntohl (local_label);
9421   mp->mb_address_length = address_length;
9422
9423   if (is_ip4)
9424     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9425   else
9426     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9427
9428   /* send it... */
9429   S (mp);
9430
9431   /* Wait for a reply... */
9432   W (ret);
9433   return ret;
9434 }
9435
9436 static int
9437 api_sr_mpls_policy_add (vat_main_t * vam)
9438 {
9439   unformat_input_t *i = vam->input;
9440   vl_api_sr_mpls_policy_add_t *mp;
9441   u32 bsid = 0;
9442   u32 weight = 1;
9443   u8 type = 0;
9444   u8 n_segments = 0;
9445   u32 sid;
9446   u32 *segments = NULL;
9447   int ret;
9448
9449   /* Parse args required to build the message */
9450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9451     {
9452       if (unformat (i, "bsid %d", &bsid))
9453         ;
9454       else if (unformat (i, "weight %d", &weight))
9455         ;
9456       else if (unformat (i, "spray"))
9457         type = 1;
9458       else if (unformat (i, "next %d", &sid))
9459         {
9460           n_segments += 1;
9461           vec_add1 (segments, htonl (sid));
9462         }
9463       else
9464         {
9465           clib_warning ("parse error '%U'", format_unformat_error, i);
9466           return -99;
9467         }
9468     }
9469
9470   if (bsid == 0)
9471     {
9472       errmsg ("bsid not set");
9473       return -99;
9474     }
9475
9476   if (n_segments == 0)
9477     {
9478       errmsg ("no sid in segment stack");
9479       return -99;
9480     }
9481
9482   /* Construct the API message */
9483   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9484
9485   mp->bsid = htonl (bsid);
9486   mp->weight = htonl (weight);
9487   mp->type = type;
9488   mp->n_segments = n_segments;
9489   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9490   vec_free (segments);
9491
9492   /* send it... */
9493   S (mp);
9494
9495   /* Wait for a reply... */
9496   W (ret);
9497   return ret;
9498 }
9499
9500 static int
9501 api_sr_mpls_policy_del (vat_main_t * vam)
9502 {
9503   unformat_input_t *i = vam->input;
9504   vl_api_sr_mpls_policy_del_t *mp;
9505   u32 bsid = 0;
9506   int ret;
9507
9508   /* Parse args required to build the message */
9509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9510     {
9511       if (unformat (i, "bsid %d", &bsid))
9512         ;
9513       else
9514         {
9515           clib_warning ("parse error '%U'", format_unformat_error, i);
9516           return -99;
9517         }
9518     }
9519
9520   if (bsid == 0)
9521     {
9522       errmsg ("bsid not set");
9523       return -99;
9524     }
9525
9526   /* Construct the API message */
9527   M (SR_MPLS_POLICY_DEL, mp);
9528
9529   mp->bsid = htonl (bsid);
9530
9531   /* send it... */
9532   S (mp);
9533
9534   /* Wait for a reply... */
9535   W (ret);
9536   return ret;
9537 }
9538
9539 static int
9540 api_bier_table_add_del (vat_main_t * vam)
9541 {
9542   unformat_input_t *i = vam->input;
9543   vl_api_bier_table_add_del_t *mp;
9544   u8 is_add = 1;
9545   u32 set = 0, sub_domain = 0, hdr_len = 3;
9546   mpls_label_t local_label = MPLS_LABEL_INVALID;
9547   int ret;
9548
9549   /* Parse args required to build the message */
9550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9551     {
9552       if (unformat (i, "sub-domain %d", &sub_domain))
9553         ;
9554       else if (unformat (i, "set %d", &set))
9555         ;
9556       else if (unformat (i, "label %d", &local_label))
9557         ;
9558       else if (unformat (i, "hdr-len %d", &hdr_len))
9559         ;
9560       else if (unformat (i, "add"))
9561         is_add = 1;
9562       else if (unformat (i, "del"))
9563         is_add = 0;
9564       else
9565         {
9566           clib_warning ("parse error '%U'", format_unformat_error, i);
9567           return -99;
9568         }
9569     }
9570
9571   if (MPLS_LABEL_INVALID == local_label)
9572     {
9573       errmsg ("missing label\n");
9574       return -99;
9575     }
9576
9577   /* Construct the API message */
9578   M (BIER_TABLE_ADD_DEL, mp);
9579
9580   mp->bt_is_add = is_add;
9581   mp->bt_label = ntohl (local_label);
9582   mp->bt_tbl_id.bt_set = set;
9583   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9584   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9585
9586   /* send it... */
9587   S (mp);
9588
9589   /* Wait for a reply... */
9590   W (ret);
9591
9592   return (ret);
9593 }
9594
9595 static int
9596 api_bier_route_add_del (vat_main_t * vam)
9597 {
9598   unformat_input_t *i = vam->input;
9599   vl_api_bier_route_add_del_t *mp;
9600   u8 is_add = 1;
9601   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9602   ip4_address_t v4_next_hop_address;
9603   ip6_address_t v6_next_hop_address;
9604   u8 next_hop_set = 0;
9605   u8 next_hop_proto_is_ip4 = 1;
9606   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9607   int ret;
9608
9609   /* Parse args required to build the message */
9610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9611     {
9612       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9613         {
9614           next_hop_proto_is_ip4 = 1;
9615           next_hop_set = 1;
9616         }
9617       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9618         {
9619           next_hop_proto_is_ip4 = 0;
9620           next_hop_set = 1;
9621         }
9622       if (unformat (i, "sub-domain %d", &sub_domain))
9623         ;
9624       else if (unformat (i, "set %d", &set))
9625         ;
9626       else if (unformat (i, "hdr-len %d", &hdr_len))
9627         ;
9628       else if (unformat (i, "bp %d", &bp))
9629         ;
9630       else if (unformat (i, "add"))
9631         is_add = 1;
9632       else if (unformat (i, "del"))
9633         is_add = 0;
9634       else if (unformat (i, "out-label %d", &next_hop_out_label))
9635         ;
9636       else
9637         {
9638           clib_warning ("parse error '%U'", format_unformat_error, i);
9639           return -99;
9640         }
9641     }
9642
9643   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9644     {
9645       errmsg ("next hop / label set\n");
9646       return -99;
9647     }
9648   if (0 == bp)
9649     {
9650       errmsg ("bit=position not set\n");
9651       return -99;
9652     }
9653
9654   /* Construct the API message */
9655   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9656
9657   mp->br_is_add = is_add;
9658   mp->br_tbl_id.bt_set = set;
9659   mp->br_tbl_id.bt_sub_domain = sub_domain;
9660   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9661   mp->br_bp = ntohs (bp);
9662   mp->br_n_paths = 1;
9663   mp->br_paths[0].n_labels = 1;
9664   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9665   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9666
9667   if (next_hop_proto_is_ip4)
9668     {
9669       clib_memcpy (mp->br_paths[0].next_hop,
9670                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9671     }
9672   else
9673     {
9674       clib_memcpy (mp->br_paths[0].next_hop,
9675                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9676     }
9677
9678   /* send it... */
9679   S (mp);
9680
9681   /* Wait for a reply... */
9682   W (ret);
9683
9684   return (ret);
9685 }
9686
9687 static int
9688 api_proxy_arp_add_del (vat_main_t * vam)
9689 {
9690   unformat_input_t *i = vam->input;
9691   vl_api_proxy_arp_add_del_t *mp;
9692   u32 vrf_id = 0;
9693   u8 is_add = 1;
9694   ip4_address_t lo, hi;
9695   u8 range_set = 0;
9696   int ret;
9697
9698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9699     {
9700       if (unformat (i, "vrf %d", &vrf_id))
9701         ;
9702       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9703                          unformat_ip4_address, &hi))
9704         range_set = 1;
9705       else if (unformat (i, "del"))
9706         is_add = 0;
9707       else
9708         {
9709           clib_warning ("parse error '%U'", format_unformat_error, i);
9710           return -99;
9711         }
9712     }
9713
9714   if (range_set == 0)
9715     {
9716       errmsg ("address range not set");
9717       return -99;
9718     }
9719
9720   M (PROXY_ARP_ADD_DEL, mp);
9721
9722   mp->proxy.vrf_id = ntohl (vrf_id);
9723   mp->is_add = is_add;
9724   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9725   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9726
9727   S (mp);
9728   W (ret);
9729   return ret;
9730 }
9731
9732 static int
9733 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9734 {
9735   unformat_input_t *i = vam->input;
9736   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9737   u32 sw_if_index;
9738   u8 enable = 1;
9739   u8 sw_if_index_set = 0;
9740   int ret;
9741
9742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9743     {
9744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9745         sw_if_index_set = 1;
9746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9747         sw_if_index_set = 1;
9748       else if (unformat (i, "enable"))
9749         enable = 1;
9750       else if (unformat (i, "disable"))
9751         enable = 0;
9752       else
9753         {
9754           clib_warning ("parse error '%U'", format_unformat_error, i);
9755           return -99;
9756         }
9757     }
9758
9759   if (sw_if_index_set == 0)
9760     {
9761       errmsg ("missing interface name or sw_if_index");
9762       return -99;
9763     }
9764
9765   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9766
9767   mp->sw_if_index = ntohl (sw_if_index);
9768   mp->enable_disable = enable;
9769
9770   S (mp);
9771   W (ret);
9772   return ret;
9773 }
9774
9775 static int
9776 api_mpls_tunnel_add_del (vat_main_t * vam)
9777 {
9778   unformat_input_t *i = vam->input;
9779   vl_api_mpls_tunnel_add_del_t *mp;
9780
9781   u8 is_add = 1;
9782   u8 l2_only = 0;
9783   u32 sw_if_index = ~0;
9784   u32 next_hop_sw_if_index = ~0;
9785   u32 next_hop_proto_is_ip4 = 1;
9786
9787   u32 next_hop_table_id = 0;
9788   ip4_address_t v4_next_hop_address = {
9789     .as_u32 = 0,
9790   };
9791   ip6_address_t v6_next_hop_address = { {0} };
9792   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9793   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9794   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9795   int ret;
9796
9797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9798     {
9799       if (unformat (i, "add"))
9800         is_add = 1;
9801       else
9802         if (unformat
9803             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9804         is_add = 0;
9805       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9806         is_add = 0;
9807       else if (unformat (i, "via %U",
9808                          unformat_ip4_address, &v4_next_hop_address))
9809         {
9810           next_hop_proto_is_ip4 = 1;
9811         }
9812       else if (unformat (i, "via %U",
9813                          unformat_ip6_address, &v6_next_hop_address))
9814         {
9815           next_hop_proto_is_ip4 = 0;
9816         }
9817       else if (unformat (i, "via-label %d", &next_hop_via_label))
9818         ;
9819       else
9820         if (unformat
9821             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9822         ;
9823       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9824         ;
9825       else if (unformat (i, "l2-only"))
9826         l2_only = 1;
9827       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9828         ;
9829       else if (unformat (i, "out-label %d", &next_hop_out_label))
9830         {
9831           vl_api_fib_mpls_label_t fib_label = {
9832             .label = ntohl (next_hop_out_label),
9833             .ttl = 64,
9834             .exp = 0,
9835           };
9836           vec_add1 (next_hop_out_label_stack, fib_label);
9837         }
9838       else
9839         {
9840           clib_warning ("parse error '%U'", format_unformat_error, i);
9841           return -99;
9842         }
9843     }
9844
9845   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9846       vec_len (next_hop_out_label_stack));
9847
9848   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9849   mp->mt_sw_if_index = ntohl (sw_if_index);
9850   mp->mt_is_add = is_add;
9851   mp->mt_l2_only = l2_only;
9852   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9853   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9854   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9855   mp->mt_next_hop_weight = 1;
9856   mp->mt_next_hop_preference = 0;
9857
9858   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9859
9860   if (0 != mp->mt_next_hop_n_out_labels)
9861     {
9862       clib_memcpy (mp->mt_next_hop_out_label_stack,
9863                    next_hop_out_label_stack,
9864                    (vec_len (next_hop_out_label_stack) *
9865                     sizeof (vl_api_fib_mpls_label_t)));
9866       vec_free (next_hop_out_label_stack);
9867     }
9868
9869   if (next_hop_proto_is_ip4)
9870     {
9871       clib_memcpy (mp->mt_next_hop,
9872                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9873     }
9874   else
9875     {
9876       clib_memcpy (mp->mt_next_hop,
9877                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9878     }
9879
9880   S (mp);
9881   W (ret);
9882   return ret;
9883 }
9884
9885 static int
9886 api_sw_interface_set_unnumbered (vat_main_t * vam)
9887 {
9888   unformat_input_t *i = vam->input;
9889   vl_api_sw_interface_set_unnumbered_t *mp;
9890   u32 sw_if_index;
9891   u32 unnum_sw_index = ~0;
9892   u8 is_add = 1;
9893   u8 sw_if_index_set = 0;
9894   int ret;
9895
9896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9897     {
9898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9899         sw_if_index_set = 1;
9900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9901         sw_if_index_set = 1;
9902       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9903         ;
9904       else if (unformat (i, "del"))
9905         is_add = 0;
9906       else
9907         {
9908           clib_warning ("parse error '%U'", format_unformat_error, i);
9909           return -99;
9910         }
9911     }
9912
9913   if (sw_if_index_set == 0)
9914     {
9915       errmsg ("missing interface name or sw_if_index");
9916       return -99;
9917     }
9918
9919   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9920
9921   mp->sw_if_index = ntohl (sw_if_index);
9922   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9923   mp->is_add = is_add;
9924
9925   S (mp);
9926   W (ret);
9927   return ret;
9928 }
9929
9930 static int
9931 api_ip_neighbor_add_del (vat_main_t * vam)
9932 {
9933   unformat_input_t *i = vam->input;
9934   vl_api_ip_neighbor_add_del_t *mp;
9935   u32 sw_if_index;
9936   u8 sw_if_index_set = 0;
9937   u8 is_add = 1;
9938   u8 is_static = 0;
9939   u8 is_no_fib_entry = 0;
9940   u8 mac_address[6];
9941   u8 mac_set = 0;
9942   u8 v4_address_set = 0;
9943   u8 v6_address_set = 0;
9944   ip4_address_t v4address;
9945   ip6_address_t v6address;
9946   int ret;
9947
9948   clib_memset (mac_address, 0, sizeof (mac_address));
9949
9950   /* Parse args required to build the message */
9951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9952     {
9953       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9954         {
9955           mac_set = 1;
9956         }
9957       else if (unformat (i, "del"))
9958         is_add = 0;
9959       else
9960         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9961         sw_if_index_set = 1;
9962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9963         sw_if_index_set = 1;
9964       else if (unformat (i, "is_static"))
9965         is_static = 1;
9966       else if (unformat (i, "no-fib-entry"))
9967         is_no_fib_entry = 1;
9968       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9969         v4_address_set = 1;
9970       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9971         v6_address_set = 1;
9972       else
9973         {
9974           clib_warning ("parse error '%U'", format_unformat_error, i);
9975           return -99;
9976         }
9977     }
9978
9979   if (sw_if_index_set == 0)
9980     {
9981       errmsg ("missing interface name or sw_if_index");
9982       return -99;
9983     }
9984   if (v4_address_set && v6_address_set)
9985     {
9986       errmsg ("both v4 and v6 addresses set");
9987       return -99;
9988     }
9989   if (!v4_address_set && !v6_address_set)
9990     {
9991       errmsg ("no address set");
9992       return -99;
9993     }
9994
9995   /* Construct the API message */
9996   M (IP_NEIGHBOR_ADD_DEL, mp);
9997
9998   mp->sw_if_index = ntohl (sw_if_index);
9999   mp->is_add = is_add;
10000   mp->is_static = is_static;
10001   mp->is_no_adj_fib = is_no_fib_entry;
10002   if (mac_set)
10003     clib_memcpy (mp->mac_address, mac_address, 6);
10004   if (v6_address_set)
10005     {
10006       mp->is_ipv6 = 1;
10007       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
10008     }
10009   else
10010     {
10011       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
10012       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
10013     }
10014
10015   /* send it... */
10016   S (mp);
10017
10018   /* Wait for a reply, return good/bad news  */
10019   W (ret);
10020   return ret;
10021 }
10022
10023 static int
10024 api_create_vlan_subif (vat_main_t * vam)
10025 {
10026   unformat_input_t *i = vam->input;
10027   vl_api_create_vlan_subif_t *mp;
10028   u32 sw_if_index;
10029   u8 sw_if_index_set = 0;
10030   u32 vlan_id;
10031   u8 vlan_id_set = 0;
10032   int ret;
10033
10034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10035     {
10036       if (unformat (i, "sw_if_index %d", &sw_if_index))
10037         sw_if_index_set = 1;
10038       else
10039         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10040         sw_if_index_set = 1;
10041       else if (unformat (i, "vlan %d", &vlan_id))
10042         vlan_id_set = 1;
10043       else
10044         {
10045           clib_warning ("parse error '%U'", format_unformat_error, i);
10046           return -99;
10047         }
10048     }
10049
10050   if (sw_if_index_set == 0)
10051     {
10052       errmsg ("missing interface name or sw_if_index");
10053       return -99;
10054     }
10055
10056   if (vlan_id_set == 0)
10057     {
10058       errmsg ("missing vlan_id");
10059       return -99;
10060     }
10061   M (CREATE_VLAN_SUBIF, mp);
10062
10063   mp->sw_if_index = ntohl (sw_if_index);
10064   mp->vlan_id = ntohl (vlan_id);
10065
10066   S (mp);
10067   W (ret);
10068   return ret;
10069 }
10070
10071 #define foreach_create_subif_bit                \
10072 _(no_tags)                                      \
10073 _(one_tag)                                      \
10074 _(two_tags)                                     \
10075 _(dot1ad)                                       \
10076 _(exact_match)                                  \
10077 _(default_sub)                                  \
10078 _(outer_vlan_id_any)                            \
10079 _(inner_vlan_id_any)
10080
10081 static int
10082 api_create_subif (vat_main_t * vam)
10083 {
10084   unformat_input_t *i = vam->input;
10085   vl_api_create_subif_t *mp;
10086   u32 sw_if_index;
10087   u8 sw_if_index_set = 0;
10088   u32 sub_id;
10089   u8 sub_id_set = 0;
10090   u32 no_tags = 0;
10091   u32 one_tag = 0;
10092   u32 two_tags = 0;
10093   u32 dot1ad = 0;
10094   u32 exact_match = 0;
10095   u32 default_sub = 0;
10096   u32 outer_vlan_id_any = 0;
10097   u32 inner_vlan_id_any = 0;
10098   u32 tmp;
10099   u16 outer_vlan_id = 0;
10100   u16 inner_vlan_id = 0;
10101   int ret;
10102
10103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (i, "sw_if_index %d", &sw_if_index))
10106         sw_if_index_set = 1;
10107       else
10108         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10109         sw_if_index_set = 1;
10110       else if (unformat (i, "sub_id %d", &sub_id))
10111         sub_id_set = 1;
10112       else if (unformat (i, "outer_vlan_id %d", &tmp))
10113         outer_vlan_id = tmp;
10114       else if (unformat (i, "inner_vlan_id %d", &tmp))
10115         inner_vlan_id = tmp;
10116
10117 #define _(a) else if (unformat (i, #a)) a = 1 ;
10118       foreach_create_subif_bit
10119 #undef _
10120         else
10121         {
10122           clib_warning ("parse error '%U'", format_unformat_error, i);
10123           return -99;
10124         }
10125     }
10126
10127   if (sw_if_index_set == 0)
10128     {
10129       errmsg ("missing interface name or sw_if_index");
10130       return -99;
10131     }
10132
10133   if (sub_id_set == 0)
10134     {
10135       errmsg ("missing sub_id");
10136       return -99;
10137     }
10138   M (CREATE_SUBIF, mp);
10139
10140   mp->sw_if_index = ntohl (sw_if_index);
10141   mp->sub_id = ntohl (sub_id);
10142
10143 #define _(a) mp->a = a;
10144   foreach_create_subif_bit;
10145 #undef _
10146
10147   mp->outer_vlan_id = ntohs (outer_vlan_id);
10148   mp->inner_vlan_id = ntohs (inner_vlan_id);
10149
10150   S (mp);
10151   W (ret);
10152   return ret;
10153 }
10154
10155 static int
10156 api_oam_add_del (vat_main_t * vam)
10157 {
10158   unformat_input_t *i = vam->input;
10159   vl_api_oam_add_del_t *mp;
10160   u32 vrf_id = 0;
10161   u8 is_add = 1;
10162   ip4_address_t src, dst;
10163   u8 src_set = 0;
10164   u8 dst_set = 0;
10165   int ret;
10166
10167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10168     {
10169       if (unformat (i, "vrf %d", &vrf_id))
10170         ;
10171       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10172         src_set = 1;
10173       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10174         dst_set = 1;
10175       else if (unformat (i, "del"))
10176         is_add = 0;
10177       else
10178         {
10179           clib_warning ("parse error '%U'", format_unformat_error, i);
10180           return -99;
10181         }
10182     }
10183
10184   if (src_set == 0)
10185     {
10186       errmsg ("missing src addr");
10187       return -99;
10188     }
10189
10190   if (dst_set == 0)
10191     {
10192       errmsg ("missing dst addr");
10193       return -99;
10194     }
10195
10196   M (OAM_ADD_DEL, mp);
10197
10198   mp->vrf_id = ntohl (vrf_id);
10199   mp->is_add = is_add;
10200   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10201   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10202
10203   S (mp);
10204   W (ret);
10205   return ret;
10206 }
10207
10208 static int
10209 api_reset_fib (vat_main_t * vam)
10210 {
10211   unformat_input_t *i = vam->input;
10212   vl_api_reset_fib_t *mp;
10213   u32 vrf_id = 0;
10214   u8 is_ipv6 = 0;
10215   u8 vrf_id_set = 0;
10216
10217   int ret;
10218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10219     {
10220       if (unformat (i, "vrf %d", &vrf_id))
10221         vrf_id_set = 1;
10222       else if (unformat (i, "ipv6"))
10223         is_ipv6 = 1;
10224       else
10225         {
10226           clib_warning ("parse error '%U'", format_unformat_error, i);
10227           return -99;
10228         }
10229     }
10230
10231   if (vrf_id_set == 0)
10232     {
10233       errmsg ("missing vrf id");
10234       return -99;
10235     }
10236
10237   M (RESET_FIB, mp);
10238
10239   mp->vrf_id = ntohl (vrf_id);
10240   mp->is_ipv6 = is_ipv6;
10241
10242   S (mp);
10243   W (ret);
10244   return ret;
10245 }
10246
10247 static int
10248 api_dhcp_proxy_config (vat_main_t * vam)
10249 {
10250   unformat_input_t *i = vam->input;
10251   vl_api_dhcp_proxy_config_t *mp;
10252   u32 rx_vrf_id = 0;
10253   u32 server_vrf_id = 0;
10254   u8 is_add = 1;
10255   u8 v4_address_set = 0;
10256   u8 v6_address_set = 0;
10257   ip4_address_t v4address;
10258   ip6_address_t v6address;
10259   u8 v4_src_address_set = 0;
10260   u8 v6_src_address_set = 0;
10261   ip4_address_t v4srcaddress;
10262   ip6_address_t v6srcaddress;
10263   int ret;
10264
10265   /* Parse args required to build the message */
10266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10267     {
10268       if (unformat (i, "del"))
10269         is_add = 0;
10270       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10271         ;
10272       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10273         ;
10274       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10275         v4_address_set = 1;
10276       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10277         v6_address_set = 1;
10278       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10279         v4_src_address_set = 1;
10280       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10281         v6_src_address_set = 1;
10282       else
10283         break;
10284     }
10285
10286   if (v4_address_set && v6_address_set)
10287     {
10288       errmsg ("both v4 and v6 server addresses set");
10289       return -99;
10290     }
10291   if (!v4_address_set && !v6_address_set)
10292     {
10293       errmsg ("no server addresses set");
10294       return -99;
10295     }
10296
10297   if (v4_src_address_set && v6_src_address_set)
10298     {
10299       errmsg ("both v4 and v6  src addresses set");
10300       return -99;
10301     }
10302   if (!v4_src_address_set && !v6_src_address_set)
10303     {
10304       errmsg ("no src addresses set");
10305       return -99;
10306     }
10307
10308   if (!(v4_src_address_set && v4_address_set) &&
10309       !(v6_src_address_set && v6_address_set))
10310     {
10311       errmsg ("no matching server and src addresses set");
10312       return -99;
10313     }
10314
10315   /* Construct the API message */
10316   M (DHCP_PROXY_CONFIG, mp);
10317
10318   mp->is_add = is_add;
10319   mp->rx_vrf_id = ntohl (rx_vrf_id);
10320   mp->server_vrf_id = ntohl (server_vrf_id);
10321   if (v6_address_set)
10322     {
10323       mp->is_ipv6 = 1;
10324       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10325       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10326     }
10327   else
10328     {
10329       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10330       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10331     }
10332
10333   /* send it... */
10334   S (mp);
10335
10336   /* Wait for a reply, return good/bad news  */
10337   W (ret);
10338   return ret;
10339 }
10340
10341 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10342 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10343
10344 static void
10345 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10346 {
10347   vat_main_t *vam = &vat_main;
10348   u32 i, count = mp->count;
10349   vl_api_dhcp_server_t *s;
10350
10351   if (mp->is_ipv6)
10352     print (vam->ofp,
10353            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10354            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10355            ntohl (mp->rx_vrf_id),
10356            format_ip6_address, mp->dhcp_src_address,
10357            mp->vss_type, mp->vss_vpn_ascii_id,
10358            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10359   else
10360     print (vam->ofp,
10361            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10362            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10363            ntohl (mp->rx_vrf_id),
10364            format_ip4_address, mp->dhcp_src_address,
10365            mp->vss_type, mp->vss_vpn_ascii_id,
10366            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10367
10368   for (i = 0; i < count; i++)
10369     {
10370       s = &mp->servers[i];
10371
10372       if (mp->is_ipv6)
10373         print (vam->ofp,
10374                " Server Table-ID %d, Server Address %U",
10375                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10376       else
10377         print (vam->ofp,
10378                " Server Table-ID %d, Server Address %U",
10379                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10380     }
10381 }
10382
10383 static void vl_api_dhcp_proxy_details_t_handler_json
10384   (vl_api_dhcp_proxy_details_t * mp)
10385 {
10386   vat_main_t *vam = &vat_main;
10387   vat_json_node_t *node = NULL;
10388   u32 i, count = mp->count;
10389   struct in_addr ip4;
10390   struct in6_addr ip6;
10391   vl_api_dhcp_server_t *s;
10392
10393   if (VAT_JSON_ARRAY != vam->json_tree.type)
10394     {
10395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10396       vat_json_init_array (&vam->json_tree);
10397     }
10398   node = vat_json_array_add (&vam->json_tree);
10399
10400   vat_json_init_object (node);
10401   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10402   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10403                              sizeof (mp->vss_type));
10404   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10405                                    mp->vss_vpn_ascii_id);
10406   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10407   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10408
10409   if (mp->is_ipv6)
10410     {
10411       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10412       vat_json_object_add_ip6 (node, "src_address", ip6);
10413     }
10414   else
10415     {
10416       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10417       vat_json_object_add_ip4 (node, "src_address", ip4);
10418     }
10419
10420   for (i = 0; i < count; i++)
10421     {
10422       s = &mp->servers[i];
10423
10424       vat_json_object_add_uint (node, "server-table-id",
10425                                 ntohl (s->server_vrf_id));
10426
10427       if (mp->is_ipv6)
10428         {
10429           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10430           vat_json_object_add_ip4 (node, "src_address", ip4);
10431         }
10432       else
10433         {
10434           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10435           vat_json_object_add_ip6 (node, "server_address", ip6);
10436         }
10437     }
10438 }
10439
10440 static int
10441 api_dhcp_proxy_dump (vat_main_t * vam)
10442 {
10443   unformat_input_t *i = vam->input;
10444   vl_api_control_ping_t *mp_ping;
10445   vl_api_dhcp_proxy_dump_t *mp;
10446   u8 is_ipv6 = 0;
10447   int ret;
10448
10449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10450     {
10451       if (unformat (i, "ipv6"))
10452         is_ipv6 = 1;
10453       else
10454         {
10455           clib_warning ("parse error '%U'", format_unformat_error, i);
10456           return -99;
10457         }
10458     }
10459
10460   M (DHCP_PROXY_DUMP, mp);
10461
10462   mp->is_ip6 = is_ipv6;
10463   S (mp);
10464
10465   /* Use a control ping for synchronization */
10466   MPING (CONTROL_PING, mp_ping);
10467   S (mp_ping);
10468
10469   W (ret);
10470   return ret;
10471 }
10472
10473 static int
10474 api_dhcp_proxy_set_vss (vat_main_t * vam)
10475 {
10476   unformat_input_t *i = vam->input;
10477   vl_api_dhcp_proxy_set_vss_t *mp;
10478   u8 is_ipv6 = 0;
10479   u8 is_add = 1;
10480   u32 tbl_id = ~0;
10481   u8 vss_type = VSS_TYPE_DEFAULT;
10482   u8 *vpn_ascii_id = 0;
10483   u32 oui = 0;
10484   u32 fib_id = 0;
10485   int ret;
10486
10487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10488     {
10489       if (unformat (i, "tbl_id %d", &tbl_id))
10490         ;
10491       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10492         vss_type = VSS_TYPE_ASCII;
10493       else if (unformat (i, "fib_id %d", &fib_id))
10494         vss_type = VSS_TYPE_VPN_ID;
10495       else if (unformat (i, "oui %d", &oui))
10496         vss_type = VSS_TYPE_VPN_ID;
10497       else if (unformat (i, "ipv6"))
10498         is_ipv6 = 1;
10499       else if (unformat (i, "del"))
10500         is_add = 0;
10501       else
10502         break;
10503     }
10504
10505   if (tbl_id == ~0)
10506     {
10507       errmsg ("missing tbl_id ");
10508       vec_free (vpn_ascii_id);
10509       return -99;
10510     }
10511
10512   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10513     {
10514       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10515       vec_free (vpn_ascii_id);
10516       return -99;
10517     }
10518
10519   M (DHCP_PROXY_SET_VSS, mp);
10520   mp->tbl_id = ntohl (tbl_id);
10521   mp->vss_type = vss_type;
10522   if (vpn_ascii_id)
10523     {
10524       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10525       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10526     }
10527   mp->vpn_index = ntohl (fib_id);
10528   mp->oui = ntohl (oui);
10529   mp->is_ipv6 = is_ipv6;
10530   mp->is_add = is_add;
10531
10532   S (mp);
10533   W (ret);
10534
10535   vec_free (vpn_ascii_id);
10536   return ret;
10537 }
10538
10539 static int
10540 api_dhcp_client_config (vat_main_t * vam)
10541 {
10542   unformat_input_t *i = vam->input;
10543   vl_api_dhcp_client_config_t *mp;
10544   u32 sw_if_index;
10545   u8 sw_if_index_set = 0;
10546   u8 is_add = 1;
10547   u8 *hostname = 0;
10548   u8 disable_event = 0;
10549   int ret;
10550
10551   /* Parse args required to build the message */
10552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10553     {
10554       if (unformat (i, "del"))
10555         is_add = 0;
10556       else
10557         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10558         sw_if_index_set = 1;
10559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10560         sw_if_index_set = 1;
10561       else if (unformat (i, "hostname %s", &hostname))
10562         ;
10563       else if (unformat (i, "disable_event"))
10564         disable_event = 1;
10565       else
10566         break;
10567     }
10568
10569   if (sw_if_index_set == 0)
10570     {
10571       errmsg ("missing interface name or sw_if_index");
10572       return -99;
10573     }
10574
10575   if (vec_len (hostname) > 63)
10576     {
10577       errmsg ("hostname too long");
10578     }
10579   vec_add1 (hostname, 0);
10580
10581   /* Construct the API message */
10582   M (DHCP_CLIENT_CONFIG, mp);
10583
10584   mp->is_add = is_add;
10585   mp->client.sw_if_index = htonl (sw_if_index);
10586   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10587   vec_free (hostname);
10588   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10589   mp->client.pid = htonl (getpid ());
10590
10591   /* send it... */
10592   S (mp);
10593
10594   /* Wait for a reply, return good/bad news  */
10595   W (ret);
10596   return ret;
10597 }
10598
10599 static int
10600 api_set_ip_flow_hash (vat_main_t * vam)
10601 {
10602   unformat_input_t *i = vam->input;
10603   vl_api_set_ip_flow_hash_t *mp;
10604   u32 vrf_id = 0;
10605   u8 is_ipv6 = 0;
10606   u8 vrf_id_set = 0;
10607   u8 src = 0;
10608   u8 dst = 0;
10609   u8 sport = 0;
10610   u8 dport = 0;
10611   u8 proto = 0;
10612   u8 reverse = 0;
10613   int ret;
10614
10615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10616     {
10617       if (unformat (i, "vrf %d", &vrf_id))
10618         vrf_id_set = 1;
10619       else if (unformat (i, "ipv6"))
10620         is_ipv6 = 1;
10621       else if (unformat (i, "src"))
10622         src = 1;
10623       else if (unformat (i, "dst"))
10624         dst = 1;
10625       else if (unformat (i, "sport"))
10626         sport = 1;
10627       else if (unformat (i, "dport"))
10628         dport = 1;
10629       else if (unformat (i, "proto"))
10630         proto = 1;
10631       else if (unformat (i, "reverse"))
10632         reverse = 1;
10633
10634       else
10635         {
10636           clib_warning ("parse error '%U'", format_unformat_error, i);
10637           return -99;
10638         }
10639     }
10640
10641   if (vrf_id_set == 0)
10642     {
10643       errmsg ("missing vrf id");
10644       return -99;
10645     }
10646
10647   M (SET_IP_FLOW_HASH, mp);
10648   mp->src = src;
10649   mp->dst = dst;
10650   mp->sport = sport;
10651   mp->dport = dport;
10652   mp->proto = proto;
10653   mp->reverse = reverse;
10654   mp->vrf_id = ntohl (vrf_id);
10655   mp->is_ipv6 = is_ipv6;
10656
10657   S (mp);
10658   W (ret);
10659   return ret;
10660 }
10661
10662 static int
10663 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10664 {
10665   unformat_input_t *i = vam->input;
10666   vl_api_sw_interface_ip6_enable_disable_t *mp;
10667   u32 sw_if_index;
10668   u8 sw_if_index_set = 0;
10669   u8 enable = 0;
10670   int ret;
10671
10672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10673     {
10674       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10675         sw_if_index_set = 1;
10676       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10677         sw_if_index_set = 1;
10678       else if (unformat (i, "enable"))
10679         enable = 1;
10680       else if (unformat (i, "disable"))
10681         enable = 0;
10682       else
10683         {
10684           clib_warning ("parse error '%U'", format_unformat_error, i);
10685           return -99;
10686         }
10687     }
10688
10689   if (sw_if_index_set == 0)
10690     {
10691       errmsg ("missing interface name or sw_if_index");
10692       return -99;
10693     }
10694
10695   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10696
10697   mp->sw_if_index = ntohl (sw_if_index);
10698   mp->enable = enable;
10699
10700   S (mp);
10701   W (ret);
10702   return ret;
10703 }
10704
10705 static int
10706 api_ip6nd_proxy_add_del (vat_main_t * vam)
10707 {
10708   unformat_input_t *i = vam->input;
10709   vl_api_ip6nd_proxy_add_del_t *mp;
10710   u32 sw_if_index = ~0;
10711   u8 v6_address_set = 0;
10712   ip6_address_t v6address;
10713   u8 is_del = 0;
10714   int ret;
10715
10716   /* Parse args required to build the message */
10717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10718     {
10719       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10720         ;
10721       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10722         ;
10723       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10724         v6_address_set = 1;
10725       if (unformat (i, "del"))
10726         is_del = 1;
10727       else
10728         {
10729           clib_warning ("parse error '%U'", format_unformat_error, i);
10730           return -99;
10731         }
10732     }
10733
10734   if (sw_if_index == ~0)
10735     {
10736       errmsg ("missing interface name or sw_if_index");
10737       return -99;
10738     }
10739   if (!v6_address_set)
10740     {
10741       errmsg ("no address set");
10742       return -99;
10743     }
10744
10745   /* Construct the API message */
10746   M (IP6ND_PROXY_ADD_DEL, mp);
10747
10748   mp->is_del = is_del;
10749   mp->sw_if_index = ntohl (sw_if_index);
10750   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10751
10752   /* send it... */
10753   S (mp);
10754
10755   /* Wait for a reply, return good/bad news  */
10756   W (ret);
10757   return ret;
10758 }
10759
10760 static int
10761 api_ip6nd_proxy_dump (vat_main_t * vam)
10762 {
10763   vl_api_ip6nd_proxy_dump_t *mp;
10764   vl_api_control_ping_t *mp_ping;
10765   int ret;
10766
10767   M (IP6ND_PROXY_DUMP, mp);
10768
10769   S (mp);
10770
10771   /* Use a control ping for synchronization */
10772   MPING (CONTROL_PING, mp_ping);
10773   S (mp_ping);
10774
10775   W (ret);
10776   return ret;
10777 }
10778
10779 static void vl_api_ip6nd_proxy_details_t_handler
10780   (vl_api_ip6nd_proxy_details_t * mp)
10781 {
10782   vat_main_t *vam = &vat_main;
10783
10784   print (vam->ofp, "host %U sw_if_index %d",
10785          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10786 }
10787
10788 static void vl_api_ip6nd_proxy_details_t_handler_json
10789   (vl_api_ip6nd_proxy_details_t * mp)
10790 {
10791   vat_main_t *vam = &vat_main;
10792   struct in6_addr ip6;
10793   vat_json_node_t *node = NULL;
10794
10795   if (VAT_JSON_ARRAY != vam->json_tree.type)
10796     {
10797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10798       vat_json_init_array (&vam->json_tree);
10799     }
10800   node = vat_json_array_add (&vam->json_tree);
10801
10802   vat_json_init_object (node);
10803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10804
10805   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10806   vat_json_object_add_ip6 (node, "host", ip6);
10807 }
10808
10809 static int
10810 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10811 {
10812   unformat_input_t *i = vam->input;
10813   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10814   u32 sw_if_index;
10815   u8 sw_if_index_set = 0;
10816   u32 address_length = 0;
10817   u8 v6_address_set = 0;
10818   ip6_address_t v6address;
10819   u8 use_default = 0;
10820   u8 no_advertise = 0;
10821   u8 off_link = 0;
10822   u8 no_autoconfig = 0;
10823   u8 no_onlink = 0;
10824   u8 is_no = 0;
10825   u32 val_lifetime = 0;
10826   u32 pref_lifetime = 0;
10827   int ret;
10828
10829   /* Parse args required to build the message */
10830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10831     {
10832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10833         sw_if_index_set = 1;
10834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10835         sw_if_index_set = 1;
10836       else if (unformat (i, "%U/%d",
10837                          unformat_ip6_address, &v6address, &address_length))
10838         v6_address_set = 1;
10839       else if (unformat (i, "val_life %d", &val_lifetime))
10840         ;
10841       else if (unformat (i, "pref_life %d", &pref_lifetime))
10842         ;
10843       else if (unformat (i, "def"))
10844         use_default = 1;
10845       else if (unformat (i, "noadv"))
10846         no_advertise = 1;
10847       else if (unformat (i, "offl"))
10848         off_link = 1;
10849       else if (unformat (i, "noauto"))
10850         no_autoconfig = 1;
10851       else if (unformat (i, "nolink"))
10852         no_onlink = 1;
10853       else if (unformat (i, "isno"))
10854         is_no = 1;
10855       else
10856         {
10857           clib_warning ("parse error '%U'", format_unformat_error, i);
10858           return -99;
10859         }
10860     }
10861
10862   if (sw_if_index_set == 0)
10863     {
10864       errmsg ("missing interface name or sw_if_index");
10865       return -99;
10866     }
10867   if (!v6_address_set)
10868     {
10869       errmsg ("no address set");
10870       return -99;
10871     }
10872
10873   /* Construct the API message */
10874   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10875
10876   mp->sw_if_index = ntohl (sw_if_index);
10877   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10878   mp->address_length = address_length;
10879   mp->use_default = use_default;
10880   mp->no_advertise = no_advertise;
10881   mp->off_link = off_link;
10882   mp->no_autoconfig = no_autoconfig;
10883   mp->no_onlink = no_onlink;
10884   mp->is_no = is_no;
10885   mp->val_lifetime = ntohl (val_lifetime);
10886   mp->pref_lifetime = ntohl (pref_lifetime);
10887
10888   /* send it... */
10889   S (mp);
10890
10891   /* Wait for a reply, return good/bad news  */
10892   W (ret);
10893   return ret;
10894 }
10895
10896 static int
10897 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10898 {
10899   unformat_input_t *i = vam->input;
10900   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10901   u32 sw_if_index;
10902   u8 sw_if_index_set = 0;
10903   u8 suppress = 0;
10904   u8 managed = 0;
10905   u8 other = 0;
10906   u8 ll_option = 0;
10907   u8 send_unicast = 0;
10908   u8 cease = 0;
10909   u8 is_no = 0;
10910   u8 default_router = 0;
10911   u32 max_interval = 0;
10912   u32 min_interval = 0;
10913   u32 lifetime = 0;
10914   u32 initial_count = 0;
10915   u32 initial_interval = 0;
10916   int ret;
10917
10918
10919   /* Parse args required to build the message */
10920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10921     {
10922       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10923         sw_if_index_set = 1;
10924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10925         sw_if_index_set = 1;
10926       else if (unformat (i, "maxint %d", &max_interval))
10927         ;
10928       else if (unformat (i, "minint %d", &min_interval))
10929         ;
10930       else if (unformat (i, "life %d", &lifetime))
10931         ;
10932       else if (unformat (i, "count %d", &initial_count))
10933         ;
10934       else if (unformat (i, "interval %d", &initial_interval))
10935         ;
10936       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10937         suppress = 1;
10938       else if (unformat (i, "managed"))
10939         managed = 1;
10940       else if (unformat (i, "other"))
10941         other = 1;
10942       else if (unformat (i, "ll"))
10943         ll_option = 1;
10944       else if (unformat (i, "send"))
10945         send_unicast = 1;
10946       else if (unformat (i, "cease"))
10947         cease = 1;
10948       else if (unformat (i, "isno"))
10949         is_no = 1;
10950       else if (unformat (i, "def"))
10951         default_router = 1;
10952       else
10953         {
10954           clib_warning ("parse error '%U'", format_unformat_error, i);
10955           return -99;
10956         }
10957     }
10958
10959   if (sw_if_index_set == 0)
10960     {
10961       errmsg ("missing interface name or sw_if_index");
10962       return -99;
10963     }
10964
10965   /* Construct the API message */
10966   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10967
10968   mp->sw_if_index = ntohl (sw_if_index);
10969   mp->max_interval = ntohl (max_interval);
10970   mp->min_interval = ntohl (min_interval);
10971   mp->lifetime = ntohl (lifetime);
10972   mp->initial_count = ntohl (initial_count);
10973   mp->initial_interval = ntohl (initial_interval);
10974   mp->suppress = suppress;
10975   mp->managed = managed;
10976   mp->other = other;
10977   mp->ll_option = ll_option;
10978   mp->send_unicast = send_unicast;
10979   mp->cease = cease;
10980   mp->is_no = is_no;
10981   mp->default_router = default_router;
10982
10983   /* send it... */
10984   S (mp);
10985
10986   /* Wait for a reply, return good/bad news  */
10987   W (ret);
10988   return ret;
10989 }
10990
10991 static int
10992 api_set_arp_neighbor_limit (vat_main_t * vam)
10993 {
10994   unformat_input_t *i = vam->input;
10995   vl_api_set_arp_neighbor_limit_t *mp;
10996   u32 arp_nbr_limit;
10997   u8 limit_set = 0;
10998   u8 is_ipv6 = 0;
10999   int ret;
11000
11001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002     {
11003       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
11004         limit_set = 1;
11005       else if (unformat (i, "ipv6"))
11006         is_ipv6 = 1;
11007       else
11008         {
11009           clib_warning ("parse error '%U'", format_unformat_error, i);
11010           return -99;
11011         }
11012     }
11013
11014   if (limit_set == 0)
11015     {
11016       errmsg ("missing limit value");
11017       return -99;
11018     }
11019
11020   M (SET_ARP_NEIGHBOR_LIMIT, mp);
11021
11022   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
11023   mp->is_ipv6 = is_ipv6;
11024
11025   S (mp);
11026   W (ret);
11027   return ret;
11028 }
11029
11030 static int
11031 api_l2_patch_add_del (vat_main_t * vam)
11032 {
11033   unformat_input_t *i = vam->input;
11034   vl_api_l2_patch_add_del_t *mp;
11035   u32 rx_sw_if_index;
11036   u8 rx_sw_if_index_set = 0;
11037   u32 tx_sw_if_index;
11038   u8 tx_sw_if_index_set = 0;
11039   u8 is_add = 1;
11040   int ret;
11041
11042   /* Parse args required to build the message */
11043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11044     {
11045       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
11046         rx_sw_if_index_set = 1;
11047       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
11048         tx_sw_if_index_set = 1;
11049       else if (unformat (i, "rx"))
11050         {
11051           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11052             {
11053               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11054                             &rx_sw_if_index))
11055                 rx_sw_if_index_set = 1;
11056             }
11057           else
11058             break;
11059         }
11060       else if (unformat (i, "tx"))
11061         {
11062           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11063             {
11064               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11065                             &tx_sw_if_index))
11066                 tx_sw_if_index_set = 1;
11067             }
11068           else
11069             break;
11070         }
11071       else if (unformat (i, "del"))
11072         is_add = 0;
11073       else
11074         break;
11075     }
11076
11077   if (rx_sw_if_index_set == 0)
11078     {
11079       errmsg ("missing rx interface name or rx_sw_if_index");
11080       return -99;
11081     }
11082
11083   if (tx_sw_if_index_set == 0)
11084     {
11085       errmsg ("missing tx interface name or tx_sw_if_index");
11086       return -99;
11087     }
11088
11089   M (L2_PATCH_ADD_DEL, mp);
11090
11091   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11092   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11093   mp->is_add = is_add;
11094
11095   S (mp);
11096   W (ret);
11097   return ret;
11098 }
11099
11100 u8 is_del;
11101 u8 localsid_addr[16];
11102 u8 end_psp;
11103 u8 behavior;
11104 u32 sw_if_index;
11105 u32 vlan_index;
11106 u32 fib_table;
11107 u8 nh_addr[16];
11108
11109 static int
11110 api_sr_localsid_add_del (vat_main_t * vam)
11111 {
11112   unformat_input_t *i = vam->input;
11113   vl_api_sr_localsid_add_del_t *mp;
11114
11115   u8 is_del;
11116   ip6_address_t localsid;
11117   u8 end_psp = 0;
11118   u8 behavior = ~0;
11119   u32 sw_if_index;
11120   u32 fib_table = ~(u32) 0;
11121   ip6_address_t nh_addr6;
11122   ip4_address_t nh_addr4;
11123   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
11124   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
11125
11126   bool nexthop_set = 0;
11127
11128   int ret;
11129
11130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11131     {
11132       if (unformat (i, "del"))
11133         is_del = 1;
11134       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11135       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11136         nexthop_set = 1;
11137       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11138         nexthop_set = 1;
11139       else if (unformat (i, "behavior %u", &behavior));
11140       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11141       else if (unformat (i, "fib-table %u", &fib_table));
11142       else if (unformat (i, "end.psp %u", &behavior));
11143       else
11144         break;
11145     }
11146
11147   M (SR_LOCALSID_ADD_DEL, mp);
11148
11149   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11150   if (nexthop_set)
11151     {
11152       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11153       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11154     }
11155   mp->behavior = behavior;
11156   mp->sw_if_index = ntohl (sw_if_index);
11157   mp->fib_table = ntohl (fib_table);
11158   mp->end_psp = end_psp;
11159   mp->is_del = is_del;
11160
11161   S (mp);
11162   W (ret);
11163   return ret;
11164 }
11165
11166 static int
11167 api_ioam_enable (vat_main_t * vam)
11168 {
11169   unformat_input_t *input = vam->input;
11170   vl_api_ioam_enable_t *mp;
11171   u32 id = 0;
11172   int has_trace_option = 0;
11173   int has_pot_option = 0;
11174   int has_seqno_option = 0;
11175   int has_analyse_option = 0;
11176   int ret;
11177
11178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11179     {
11180       if (unformat (input, "trace"))
11181         has_trace_option = 1;
11182       else if (unformat (input, "pot"))
11183         has_pot_option = 1;
11184       else if (unformat (input, "seqno"))
11185         has_seqno_option = 1;
11186       else if (unformat (input, "analyse"))
11187         has_analyse_option = 1;
11188       else
11189         break;
11190     }
11191   M (IOAM_ENABLE, mp);
11192   mp->id = htons (id);
11193   mp->seqno = has_seqno_option;
11194   mp->analyse = has_analyse_option;
11195   mp->pot_enable = has_pot_option;
11196   mp->trace_enable = has_trace_option;
11197
11198   S (mp);
11199   W (ret);
11200   return ret;
11201 }
11202
11203
11204 static int
11205 api_ioam_disable (vat_main_t * vam)
11206 {
11207   vl_api_ioam_disable_t *mp;
11208   int ret;
11209
11210   M (IOAM_DISABLE, mp);
11211   S (mp);
11212   W (ret);
11213   return ret;
11214 }
11215
11216 #define foreach_tcp_proto_field                 \
11217 _(src_port)                                     \
11218 _(dst_port)
11219
11220 #define foreach_udp_proto_field                 \
11221 _(src_port)                                     \
11222 _(dst_port)
11223
11224 #define foreach_ip4_proto_field                 \
11225 _(src_address)                                  \
11226 _(dst_address)                                  \
11227 _(tos)                                          \
11228 _(length)                                       \
11229 _(fragment_id)                                  \
11230 _(ttl)                                          \
11231 _(protocol)                                     \
11232 _(checksum)
11233
11234 typedef struct
11235 {
11236   u16 src_port, dst_port;
11237 } tcpudp_header_t;
11238
11239 #if VPP_API_TEST_BUILTIN == 0
11240 uword
11241 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11242 {
11243   u8 **maskp = va_arg (*args, u8 **);
11244   u8 *mask = 0;
11245   u8 found_something = 0;
11246   tcp_header_t *tcp;
11247
11248 #define _(a) u8 a=0;
11249   foreach_tcp_proto_field;
11250 #undef _
11251
11252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11253     {
11254       if (0);
11255 #define _(a) else if (unformat (input, #a)) a=1;
11256       foreach_tcp_proto_field
11257 #undef _
11258         else
11259         break;
11260     }
11261
11262 #define _(a) found_something += a;
11263   foreach_tcp_proto_field;
11264 #undef _
11265
11266   if (found_something == 0)
11267     return 0;
11268
11269   vec_validate (mask, sizeof (*tcp) - 1);
11270
11271   tcp = (tcp_header_t *) mask;
11272
11273 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
11274   foreach_tcp_proto_field;
11275 #undef _
11276
11277   *maskp = mask;
11278   return 1;
11279 }
11280
11281 uword
11282 unformat_udp_mask (unformat_input_t * input, va_list * args)
11283 {
11284   u8 **maskp = va_arg (*args, u8 **);
11285   u8 *mask = 0;
11286   u8 found_something = 0;
11287   udp_header_t *udp;
11288
11289 #define _(a) u8 a=0;
11290   foreach_udp_proto_field;
11291 #undef _
11292
11293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11294     {
11295       if (0);
11296 #define _(a) else if (unformat (input, #a)) a=1;
11297       foreach_udp_proto_field
11298 #undef _
11299         else
11300         break;
11301     }
11302
11303 #define _(a) found_something += a;
11304   foreach_udp_proto_field;
11305 #undef _
11306
11307   if (found_something == 0)
11308     return 0;
11309
11310   vec_validate (mask, sizeof (*udp) - 1);
11311
11312   udp = (udp_header_t *) mask;
11313
11314 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
11315   foreach_udp_proto_field;
11316 #undef _
11317
11318   *maskp = mask;
11319   return 1;
11320 }
11321
11322 uword
11323 unformat_l4_mask (unformat_input_t * input, va_list * args)
11324 {
11325   u8 **maskp = va_arg (*args, u8 **);
11326   u16 src_port = 0, dst_port = 0;
11327   tcpudp_header_t *tcpudp;
11328
11329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11330     {
11331       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11332         return 1;
11333       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11334         return 1;
11335       else if (unformat (input, "src_port"))
11336         src_port = 0xFFFF;
11337       else if (unformat (input, "dst_port"))
11338         dst_port = 0xFFFF;
11339       else
11340         return 0;
11341     }
11342
11343   if (!src_port && !dst_port)
11344     return 0;
11345
11346   u8 *mask = 0;
11347   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11348
11349   tcpudp = (tcpudp_header_t *) mask;
11350   tcpudp->src_port = src_port;
11351   tcpudp->dst_port = dst_port;
11352
11353   *maskp = mask;
11354
11355   return 1;
11356 }
11357
11358 uword
11359 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11360 {
11361   u8 **maskp = va_arg (*args, u8 **);
11362   u8 *mask = 0;
11363   u8 found_something = 0;
11364   ip4_header_t *ip;
11365
11366 #define _(a) u8 a=0;
11367   foreach_ip4_proto_field;
11368 #undef _
11369   u8 version = 0;
11370   u8 hdr_length = 0;
11371
11372
11373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11374     {
11375       if (unformat (input, "version"))
11376         version = 1;
11377       else if (unformat (input, "hdr_length"))
11378         hdr_length = 1;
11379       else if (unformat (input, "src"))
11380         src_address = 1;
11381       else if (unformat (input, "dst"))
11382         dst_address = 1;
11383       else if (unformat (input, "proto"))
11384         protocol = 1;
11385
11386 #define _(a) else if (unformat (input, #a)) a=1;
11387       foreach_ip4_proto_field
11388 #undef _
11389         else
11390         break;
11391     }
11392
11393 #define _(a) found_something += a;
11394   foreach_ip4_proto_field;
11395 #undef _
11396
11397   if (found_something == 0)
11398     return 0;
11399
11400   vec_validate (mask, sizeof (*ip) - 1);
11401
11402   ip = (ip4_header_t *) mask;
11403
11404 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11405   foreach_ip4_proto_field;
11406 #undef _
11407
11408   ip->ip_version_and_header_length = 0;
11409
11410   if (version)
11411     ip->ip_version_and_header_length |= 0xF0;
11412
11413   if (hdr_length)
11414     ip->ip_version_and_header_length |= 0x0F;
11415
11416   *maskp = mask;
11417   return 1;
11418 }
11419
11420 #define foreach_ip6_proto_field                 \
11421 _(src_address)                                  \
11422 _(dst_address)                                  \
11423 _(payload_length)                               \
11424 _(hop_limit)                                    \
11425 _(protocol)
11426
11427 uword
11428 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11429 {
11430   u8 **maskp = va_arg (*args, u8 **);
11431   u8 *mask = 0;
11432   u8 found_something = 0;
11433   ip6_header_t *ip;
11434   u32 ip_version_traffic_class_and_flow_label;
11435
11436 #define _(a) u8 a=0;
11437   foreach_ip6_proto_field;
11438 #undef _
11439   u8 version = 0;
11440   u8 traffic_class = 0;
11441   u8 flow_label = 0;
11442
11443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11444     {
11445       if (unformat (input, "version"))
11446         version = 1;
11447       else if (unformat (input, "traffic-class"))
11448         traffic_class = 1;
11449       else if (unformat (input, "flow-label"))
11450         flow_label = 1;
11451       else if (unformat (input, "src"))
11452         src_address = 1;
11453       else if (unformat (input, "dst"))
11454         dst_address = 1;
11455       else if (unformat (input, "proto"))
11456         protocol = 1;
11457
11458 #define _(a) else if (unformat (input, #a)) a=1;
11459       foreach_ip6_proto_field
11460 #undef _
11461         else
11462         break;
11463     }
11464
11465 #define _(a) found_something += a;
11466   foreach_ip6_proto_field;
11467 #undef _
11468
11469   if (found_something == 0)
11470     return 0;
11471
11472   vec_validate (mask, sizeof (*ip) - 1);
11473
11474   ip = (ip6_header_t *) mask;
11475
11476 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11477   foreach_ip6_proto_field;
11478 #undef _
11479
11480   ip_version_traffic_class_and_flow_label = 0;
11481
11482   if (version)
11483     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11484
11485   if (traffic_class)
11486     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11487
11488   if (flow_label)
11489     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11490
11491   ip->ip_version_traffic_class_and_flow_label =
11492     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11493
11494   *maskp = mask;
11495   return 1;
11496 }
11497
11498 uword
11499 unformat_l3_mask (unformat_input_t * input, va_list * args)
11500 {
11501   u8 **maskp = va_arg (*args, u8 **);
11502
11503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11504     {
11505       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11506         return 1;
11507       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11508         return 1;
11509       else
11510         break;
11511     }
11512   return 0;
11513 }
11514
11515 uword
11516 unformat_l2_mask (unformat_input_t * input, va_list * args)
11517 {
11518   u8 **maskp = va_arg (*args, u8 **);
11519   u8 *mask = 0;
11520   u8 src = 0;
11521   u8 dst = 0;
11522   u8 proto = 0;
11523   u8 tag1 = 0;
11524   u8 tag2 = 0;
11525   u8 ignore_tag1 = 0;
11526   u8 ignore_tag2 = 0;
11527   u8 cos1 = 0;
11528   u8 cos2 = 0;
11529   u8 dot1q = 0;
11530   u8 dot1ad = 0;
11531   int len = 14;
11532
11533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11534     {
11535       if (unformat (input, "src"))
11536         src = 1;
11537       else if (unformat (input, "dst"))
11538         dst = 1;
11539       else if (unformat (input, "proto"))
11540         proto = 1;
11541       else if (unformat (input, "tag1"))
11542         tag1 = 1;
11543       else if (unformat (input, "tag2"))
11544         tag2 = 1;
11545       else if (unformat (input, "ignore-tag1"))
11546         ignore_tag1 = 1;
11547       else if (unformat (input, "ignore-tag2"))
11548         ignore_tag2 = 1;
11549       else if (unformat (input, "cos1"))
11550         cos1 = 1;
11551       else if (unformat (input, "cos2"))
11552         cos2 = 1;
11553       else if (unformat (input, "dot1q"))
11554         dot1q = 1;
11555       else if (unformat (input, "dot1ad"))
11556         dot1ad = 1;
11557       else
11558         break;
11559     }
11560   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11561        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11562     return 0;
11563
11564   if (tag1 || ignore_tag1 || cos1 || dot1q)
11565     len = 18;
11566   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11567     len = 22;
11568
11569   vec_validate (mask, len - 1);
11570
11571   if (dst)
11572     clib_memset (mask, 0xff, 6);
11573
11574   if (src)
11575     clib_memset (mask + 6, 0xff, 6);
11576
11577   if (tag2 || dot1ad)
11578     {
11579       /* inner vlan tag */
11580       if (tag2)
11581         {
11582           mask[19] = 0xff;
11583           mask[18] = 0x0f;
11584         }
11585       if (cos2)
11586         mask[18] |= 0xe0;
11587       if (proto)
11588         mask[21] = mask[20] = 0xff;
11589       if (tag1)
11590         {
11591           mask[15] = 0xff;
11592           mask[14] = 0x0f;
11593         }
11594       if (cos1)
11595         mask[14] |= 0xe0;
11596       *maskp = mask;
11597       return 1;
11598     }
11599   if (tag1 | dot1q)
11600     {
11601       if (tag1)
11602         {
11603           mask[15] = 0xff;
11604           mask[14] = 0x0f;
11605         }
11606       if (cos1)
11607         mask[14] |= 0xe0;
11608       if (proto)
11609         mask[16] = mask[17] = 0xff;
11610
11611       *maskp = mask;
11612       return 1;
11613     }
11614   if (cos2)
11615     mask[18] |= 0xe0;
11616   if (cos1)
11617     mask[14] |= 0xe0;
11618   if (proto)
11619     mask[12] = mask[13] = 0xff;
11620
11621   *maskp = mask;
11622   return 1;
11623 }
11624
11625 uword
11626 unformat_classify_mask (unformat_input_t * input, va_list * args)
11627 {
11628   u8 **maskp = va_arg (*args, u8 **);
11629   u32 *skipp = va_arg (*args, u32 *);
11630   u32 *matchp = va_arg (*args, u32 *);
11631   u32 match;
11632   u8 *mask = 0;
11633   u8 *l2 = 0;
11634   u8 *l3 = 0;
11635   u8 *l4 = 0;
11636   int i;
11637
11638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11639     {
11640       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11641         ;
11642       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11643         ;
11644       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11645         ;
11646       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11647         ;
11648       else
11649         break;
11650     }
11651
11652   if (l4 && !l3)
11653     {
11654       vec_free (mask);
11655       vec_free (l2);
11656       vec_free (l4);
11657       return 0;
11658     }
11659
11660   if (mask || l2 || l3 || l4)
11661     {
11662       if (l2 || l3 || l4)
11663         {
11664           /* "With a free Ethernet header in every package" */
11665           if (l2 == 0)
11666             vec_validate (l2, 13);
11667           mask = l2;
11668           if (vec_len (l3))
11669             {
11670               vec_append (mask, l3);
11671               vec_free (l3);
11672             }
11673           if (vec_len (l4))
11674             {
11675               vec_append (mask, l4);
11676               vec_free (l4);
11677             }
11678         }
11679
11680       /* Scan forward looking for the first significant mask octet */
11681       for (i = 0; i < vec_len (mask); i++)
11682         if (mask[i])
11683           break;
11684
11685       /* compute (skip, match) params */
11686       *skipp = i / sizeof (u32x4);
11687       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11688
11689       /* Pad mask to an even multiple of the vector size */
11690       while (vec_len (mask) % sizeof (u32x4))
11691         vec_add1 (mask, 0);
11692
11693       match = vec_len (mask) / sizeof (u32x4);
11694
11695       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11696         {
11697           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11698           if (*tmp || *(tmp + 1))
11699             break;
11700           match--;
11701         }
11702       if (match == 0)
11703         clib_warning ("BUG: match 0");
11704
11705       _vec_len (mask) = match * sizeof (u32x4);
11706
11707       *matchp = match;
11708       *maskp = mask;
11709
11710       return 1;
11711     }
11712
11713   return 0;
11714 }
11715 #endif /* VPP_API_TEST_BUILTIN */
11716
11717 #define foreach_l2_next                         \
11718 _(drop, DROP)                                   \
11719 _(ethernet, ETHERNET_INPUT)                     \
11720 _(ip4, IP4_INPUT)                               \
11721 _(ip6, IP6_INPUT)
11722
11723 uword
11724 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11725 {
11726   u32 *miss_next_indexp = va_arg (*args, u32 *);
11727   u32 next_index = 0;
11728   u32 tmp;
11729
11730 #define _(n,N) \
11731   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11732   foreach_l2_next;
11733 #undef _
11734
11735   if (unformat (input, "%d", &tmp))
11736     {
11737       next_index = tmp;
11738       goto out;
11739     }
11740
11741   return 0;
11742
11743 out:
11744   *miss_next_indexp = next_index;
11745   return 1;
11746 }
11747
11748 #define foreach_ip_next                         \
11749 _(drop, DROP)                                   \
11750 _(local, LOCAL)                                 \
11751 _(rewrite, REWRITE)
11752
11753 uword
11754 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11755 {
11756   u32 *miss_next_indexp = va_arg (*args, u32 *);
11757   u32 next_index = 0;
11758   u32 tmp;
11759
11760 #define _(n,N) \
11761   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11762   foreach_ip_next;
11763 #undef _
11764
11765   if (unformat (input, "%d", &tmp))
11766     {
11767       next_index = tmp;
11768       goto out;
11769     }
11770
11771   return 0;
11772
11773 out:
11774   *miss_next_indexp = next_index;
11775   return 1;
11776 }
11777
11778 #define foreach_acl_next                        \
11779 _(deny, DENY)
11780
11781 uword
11782 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11783 {
11784   u32 *miss_next_indexp = va_arg (*args, u32 *);
11785   u32 next_index = 0;
11786   u32 tmp;
11787
11788 #define _(n,N) \
11789   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11790   foreach_acl_next;
11791 #undef _
11792
11793   if (unformat (input, "permit"))
11794     {
11795       next_index = ~0;
11796       goto out;
11797     }
11798   else if (unformat (input, "%d", &tmp))
11799     {
11800       next_index = tmp;
11801       goto out;
11802     }
11803
11804   return 0;
11805
11806 out:
11807   *miss_next_indexp = next_index;
11808   return 1;
11809 }
11810
11811 uword
11812 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11813 {
11814   u32 *r = va_arg (*args, u32 *);
11815
11816   if (unformat (input, "conform-color"))
11817     *r = POLICE_CONFORM;
11818   else if (unformat (input, "exceed-color"))
11819     *r = POLICE_EXCEED;
11820   else
11821     return 0;
11822
11823   return 1;
11824 }
11825
11826 static int
11827 api_classify_add_del_table (vat_main_t * vam)
11828 {
11829   unformat_input_t *i = vam->input;
11830   vl_api_classify_add_del_table_t *mp;
11831
11832   u32 nbuckets = 2;
11833   u32 skip = ~0;
11834   u32 match = ~0;
11835   int is_add = 1;
11836   int del_chain = 0;
11837   u32 table_index = ~0;
11838   u32 next_table_index = ~0;
11839   u32 miss_next_index = ~0;
11840   u32 memory_size = 32 << 20;
11841   u8 *mask = 0;
11842   u32 current_data_flag = 0;
11843   int current_data_offset = 0;
11844   int ret;
11845
11846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11847     {
11848       if (unformat (i, "del"))
11849         is_add = 0;
11850       else if (unformat (i, "del-chain"))
11851         {
11852           is_add = 0;
11853           del_chain = 1;
11854         }
11855       else if (unformat (i, "buckets %d", &nbuckets))
11856         ;
11857       else if (unformat (i, "memory_size %d", &memory_size))
11858         ;
11859       else if (unformat (i, "skip %d", &skip))
11860         ;
11861       else if (unformat (i, "match %d", &match))
11862         ;
11863       else if (unformat (i, "table %d", &table_index))
11864         ;
11865       else if (unformat (i, "mask %U", unformat_classify_mask,
11866                          &mask, &skip, &match))
11867         ;
11868       else if (unformat (i, "next-table %d", &next_table_index))
11869         ;
11870       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11871                          &miss_next_index))
11872         ;
11873       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11874                          &miss_next_index))
11875         ;
11876       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11877                          &miss_next_index))
11878         ;
11879       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11880         ;
11881       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11882         ;
11883       else
11884         break;
11885     }
11886
11887   if (is_add && mask == 0)
11888     {
11889       errmsg ("Mask required");
11890       return -99;
11891     }
11892
11893   if (is_add && skip == ~0)
11894     {
11895       errmsg ("skip count required");
11896       return -99;
11897     }
11898
11899   if (is_add && match == ~0)
11900     {
11901       errmsg ("match count required");
11902       return -99;
11903     }
11904
11905   if (!is_add && table_index == ~0)
11906     {
11907       errmsg ("table index required for delete");
11908       return -99;
11909     }
11910
11911   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11912
11913   mp->is_add = is_add;
11914   mp->del_chain = del_chain;
11915   mp->table_index = ntohl (table_index);
11916   mp->nbuckets = ntohl (nbuckets);
11917   mp->memory_size = ntohl (memory_size);
11918   mp->skip_n_vectors = ntohl (skip);
11919   mp->match_n_vectors = ntohl (match);
11920   mp->next_table_index = ntohl (next_table_index);
11921   mp->miss_next_index = ntohl (miss_next_index);
11922   mp->current_data_flag = ntohl (current_data_flag);
11923   mp->current_data_offset = ntohl (current_data_offset);
11924   mp->mask_len = ntohl (vec_len (mask));
11925   clib_memcpy (mp->mask, mask, vec_len (mask));
11926
11927   vec_free (mask);
11928
11929   S (mp);
11930   W (ret);
11931   return ret;
11932 }
11933
11934 #if VPP_API_TEST_BUILTIN == 0
11935 uword
11936 unformat_l4_match (unformat_input_t * input, va_list * args)
11937 {
11938   u8 **matchp = va_arg (*args, u8 **);
11939
11940   u8 *proto_header = 0;
11941   int src_port = 0;
11942   int dst_port = 0;
11943
11944   tcpudp_header_t h;
11945
11946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11947     {
11948       if (unformat (input, "src_port %d", &src_port))
11949         ;
11950       else if (unformat (input, "dst_port %d", &dst_port))
11951         ;
11952       else
11953         return 0;
11954     }
11955
11956   h.src_port = clib_host_to_net_u16 (src_port);
11957   h.dst_port = clib_host_to_net_u16 (dst_port);
11958   vec_validate (proto_header, sizeof (h) - 1);
11959   memcpy (proto_header, &h, sizeof (h));
11960
11961   *matchp = proto_header;
11962
11963   return 1;
11964 }
11965
11966 uword
11967 unformat_ip4_match (unformat_input_t * input, va_list * args)
11968 {
11969   u8 **matchp = va_arg (*args, u8 **);
11970   u8 *match = 0;
11971   ip4_header_t *ip;
11972   int version = 0;
11973   u32 version_val;
11974   int hdr_length = 0;
11975   u32 hdr_length_val;
11976   int src = 0, dst = 0;
11977   ip4_address_t src_val, dst_val;
11978   int proto = 0;
11979   u32 proto_val;
11980   int tos = 0;
11981   u32 tos_val;
11982   int length = 0;
11983   u32 length_val;
11984   int fragment_id = 0;
11985   u32 fragment_id_val;
11986   int ttl = 0;
11987   int ttl_val;
11988   int checksum = 0;
11989   u32 checksum_val;
11990
11991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11992     {
11993       if (unformat (input, "version %d", &version_val))
11994         version = 1;
11995       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11996         hdr_length = 1;
11997       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11998         src = 1;
11999       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
12000         dst = 1;
12001       else if (unformat (input, "proto %d", &proto_val))
12002         proto = 1;
12003       else if (unformat (input, "tos %d", &tos_val))
12004         tos = 1;
12005       else if (unformat (input, "length %d", &length_val))
12006         length = 1;
12007       else if (unformat (input, "fragment_id %d", &fragment_id_val))
12008         fragment_id = 1;
12009       else if (unformat (input, "ttl %d", &ttl_val))
12010         ttl = 1;
12011       else if (unformat (input, "checksum %d", &checksum_val))
12012         checksum = 1;
12013       else
12014         break;
12015     }
12016
12017   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
12018       + ttl + checksum == 0)
12019     return 0;
12020
12021   /*
12022    * Aligned because we use the real comparison functions
12023    */
12024   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12025
12026   ip = (ip4_header_t *) match;
12027
12028   /* These are realistically matched in practice */
12029   if (src)
12030     ip->src_address.as_u32 = src_val.as_u32;
12031
12032   if (dst)
12033     ip->dst_address.as_u32 = dst_val.as_u32;
12034
12035   if (proto)
12036     ip->protocol = proto_val;
12037
12038
12039   /* These are not, but they're included for completeness */
12040   if (version)
12041     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
12042
12043   if (hdr_length)
12044     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
12045
12046   if (tos)
12047     ip->tos = tos_val;
12048
12049   if (length)
12050     ip->length = clib_host_to_net_u16 (length_val);
12051
12052   if (ttl)
12053     ip->ttl = ttl_val;
12054
12055   if (checksum)
12056     ip->checksum = clib_host_to_net_u16 (checksum_val);
12057
12058   *matchp = match;
12059   return 1;
12060 }
12061
12062 uword
12063 unformat_ip6_match (unformat_input_t * input, va_list * args)
12064 {
12065   u8 **matchp = va_arg (*args, u8 **);
12066   u8 *match = 0;
12067   ip6_header_t *ip;
12068   int version = 0;
12069   u32 version_val;
12070   u8 traffic_class = 0;
12071   u32 traffic_class_val = 0;
12072   u8 flow_label = 0;
12073   u8 flow_label_val;
12074   int src = 0, dst = 0;
12075   ip6_address_t src_val, dst_val;
12076   int proto = 0;
12077   u32 proto_val;
12078   int payload_length = 0;
12079   u32 payload_length_val;
12080   int hop_limit = 0;
12081   int hop_limit_val;
12082   u32 ip_version_traffic_class_and_flow_label;
12083
12084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12085     {
12086       if (unformat (input, "version %d", &version_val))
12087         version = 1;
12088       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12089         traffic_class = 1;
12090       else if (unformat (input, "flow_label %d", &flow_label_val))
12091         flow_label = 1;
12092       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12093         src = 1;
12094       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12095         dst = 1;
12096       else if (unformat (input, "proto %d", &proto_val))
12097         proto = 1;
12098       else if (unformat (input, "payload_length %d", &payload_length_val))
12099         payload_length = 1;
12100       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12101         hop_limit = 1;
12102       else
12103         break;
12104     }
12105
12106   if (version + traffic_class + flow_label + src + dst + proto +
12107       payload_length + hop_limit == 0)
12108     return 0;
12109
12110   /*
12111    * Aligned because we use the real comparison functions
12112    */
12113   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12114
12115   ip = (ip6_header_t *) match;
12116
12117   if (src)
12118     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12119
12120   if (dst)
12121     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12122
12123   if (proto)
12124     ip->protocol = proto_val;
12125
12126   ip_version_traffic_class_and_flow_label = 0;
12127
12128   if (version)
12129     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12130
12131   if (traffic_class)
12132     ip_version_traffic_class_and_flow_label |=
12133       (traffic_class_val & 0xFF) << 20;
12134
12135   if (flow_label)
12136     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12137
12138   ip->ip_version_traffic_class_and_flow_label =
12139     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12140
12141   if (payload_length)
12142     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12143
12144   if (hop_limit)
12145     ip->hop_limit = hop_limit_val;
12146
12147   *matchp = match;
12148   return 1;
12149 }
12150
12151 uword
12152 unformat_l3_match (unformat_input_t * input, va_list * args)
12153 {
12154   u8 **matchp = va_arg (*args, u8 **);
12155
12156   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12157     {
12158       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12159         return 1;
12160       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12161         return 1;
12162       else
12163         break;
12164     }
12165   return 0;
12166 }
12167
12168 uword
12169 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12170 {
12171   u8 *tagp = va_arg (*args, u8 *);
12172   u32 tag;
12173
12174   if (unformat (input, "%d", &tag))
12175     {
12176       tagp[0] = (tag >> 8) & 0x0F;
12177       tagp[1] = tag & 0xFF;
12178       return 1;
12179     }
12180
12181   return 0;
12182 }
12183
12184 uword
12185 unformat_l2_match (unformat_input_t * input, va_list * args)
12186 {
12187   u8 **matchp = va_arg (*args, u8 **);
12188   u8 *match = 0;
12189   u8 src = 0;
12190   u8 src_val[6];
12191   u8 dst = 0;
12192   u8 dst_val[6];
12193   u8 proto = 0;
12194   u16 proto_val;
12195   u8 tag1 = 0;
12196   u8 tag1_val[2];
12197   u8 tag2 = 0;
12198   u8 tag2_val[2];
12199   int len = 14;
12200   u8 ignore_tag1 = 0;
12201   u8 ignore_tag2 = 0;
12202   u8 cos1 = 0;
12203   u8 cos2 = 0;
12204   u32 cos1_val = 0;
12205   u32 cos2_val = 0;
12206
12207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12208     {
12209       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12210         src = 1;
12211       else
12212         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12213         dst = 1;
12214       else if (unformat (input, "proto %U",
12215                          unformat_ethernet_type_host_byte_order, &proto_val))
12216         proto = 1;
12217       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12218         tag1 = 1;
12219       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12220         tag2 = 1;
12221       else if (unformat (input, "ignore-tag1"))
12222         ignore_tag1 = 1;
12223       else if (unformat (input, "ignore-tag2"))
12224         ignore_tag2 = 1;
12225       else if (unformat (input, "cos1 %d", &cos1_val))
12226         cos1 = 1;
12227       else if (unformat (input, "cos2 %d", &cos2_val))
12228         cos2 = 1;
12229       else
12230         break;
12231     }
12232   if ((src + dst + proto + tag1 + tag2 +
12233        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12234     return 0;
12235
12236   if (tag1 || ignore_tag1 || cos1)
12237     len = 18;
12238   if (tag2 || ignore_tag2 || cos2)
12239     len = 22;
12240
12241   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12242
12243   if (dst)
12244     clib_memcpy (match, dst_val, 6);
12245
12246   if (src)
12247     clib_memcpy (match + 6, src_val, 6);
12248
12249   if (tag2)
12250     {
12251       /* inner vlan tag */
12252       match[19] = tag2_val[1];
12253       match[18] = tag2_val[0];
12254       if (cos2)
12255         match[18] |= (cos2_val & 0x7) << 5;
12256       if (proto)
12257         {
12258           match[21] = proto_val & 0xff;
12259           match[20] = proto_val >> 8;
12260         }
12261       if (tag1)
12262         {
12263           match[15] = tag1_val[1];
12264           match[14] = tag1_val[0];
12265         }
12266       if (cos1)
12267         match[14] |= (cos1_val & 0x7) << 5;
12268       *matchp = match;
12269       return 1;
12270     }
12271   if (tag1)
12272     {
12273       match[15] = tag1_val[1];
12274       match[14] = tag1_val[0];
12275       if (proto)
12276         {
12277           match[17] = proto_val & 0xff;
12278           match[16] = proto_val >> 8;
12279         }
12280       if (cos1)
12281         match[14] |= (cos1_val & 0x7) << 5;
12282
12283       *matchp = match;
12284       return 1;
12285     }
12286   if (cos2)
12287     match[18] |= (cos2_val & 0x7) << 5;
12288   if (cos1)
12289     match[14] |= (cos1_val & 0x7) << 5;
12290   if (proto)
12291     {
12292       match[13] = proto_val & 0xff;
12293       match[12] = proto_val >> 8;
12294     }
12295
12296   *matchp = match;
12297   return 1;
12298 }
12299
12300 uword
12301 unformat_qos_source (unformat_input_t * input, va_list * args)
12302 {
12303   int *qs = va_arg (*args, int *);
12304
12305   if (unformat (input, "ip"))
12306     *qs = QOS_SOURCE_IP;
12307   else if (unformat (input, "mpls"))
12308     *qs = QOS_SOURCE_MPLS;
12309   else if (unformat (input, "ext"))
12310     *qs = QOS_SOURCE_EXT;
12311   else if (unformat (input, "vlan"))
12312     *qs = QOS_SOURCE_VLAN;
12313   else
12314     return 0;
12315
12316   return 1;
12317 }
12318 #endif
12319
12320 uword
12321 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12322 {
12323   u8 **matchp = va_arg (*args, u8 **);
12324   u32 skip_n_vectors = va_arg (*args, u32);
12325   u32 match_n_vectors = va_arg (*args, u32);
12326
12327   u8 *match = 0;
12328   u8 *l2 = 0;
12329   u8 *l3 = 0;
12330   u8 *l4 = 0;
12331
12332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12333     {
12334       if (unformat (input, "hex %U", unformat_hex_string, &match))
12335         ;
12336       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12337         ;
12338       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12339         ;
12340       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12341         ;
12342       else
12343         break;
12344     }
12345
12346   if (l4 && !l3)
12347     {
12348       vec_free (match);
12349       vec_free (l2);
12350       vec_free (l4);
12351       return 0;
12352     }
12353
12354   if (match || l2 || l3 || l4)
12355     {
12356       if (l2 || l3 || l4)
12357         {
12358           /* "Win a free Ethernet header in every packet" */
12359           if (l2 == 0)
12360             vec_validate_aligned (l2, 13, sizeof (u32x4));
12361           match = l2;
12362           if (vec_len (l3))
12363             {
12364               vec_append_aligned (match, l3, sizeof (u32x4));
12365               vec_free (l3);
12366             }
12367           if (vec_len (l4))
12368             {
12369               vec_append_aligned (match, l4, sizeof (u32x4));
12370               vec_free (l4);
12371             }
12372         }
12373
12374       /* Make sure the vector is big enough even if key is all 0's */
12375       vec_validate_aligned
12376         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12377          sizeof (u32x4));
12378
12379       /* Set size, include skipped vectors */
12380       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12381
12382       *matchp = match;
12383
12384       return 1;
12385     }
12386
12387   return 0;
12388 }
12389
12390 static int
12391 api_classify_add_del_session (vat_main_t * vam)
12392 {
12393   unformat_input_t *i = vam->input;
12394   vl_api_classify_add_del_session_t *mp;
12395   int is_add = 1;
12396   u32 table_index = ~0;
12397   u32 hit_next_index = ~0;
12398   u32 opaque_index = ~0;
12399   u8 *match = 0;
12400   i32 advance = 0;
12401   u32 skip_n_vectors = 0;
12402   u32 match_n_vectors = 0;
12403   u32 action = 0;
12404   u32 metadata = 0;
12405   int ret;
12406
12407   /*
12408    * Warning: you have to supply skip_n and match_n
12409    * because the API client cant simply look at the classify
12410    * table object.
12411    */
12412
12413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12414     {
12415       if (unformat (i, "del"))
12416         is_add = 0;
12417       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12418                          &hit_next_index))
12419         ;
12420       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12421                          &hit_next_index))
12422         ;
12423       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12424                          &hit_next_index))
12425         ;
12426       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12427         ;
12428       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12429         ;
12430       else if (unformat (i, "opaque-index %d", &opaque_index))
12431         ;
12432       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12433         ;
12434       else if (unformat (i, "match_n %d", &match_n_vectors))
12435         ;
12436       else if (unformat (i, "match %U", api_unformat_classify_match,
12437                          &match, skip_n_vectors, match_n_vectors))
12438         ;
12439       else if (unformat (i, "advance %d", &advance))
12440         ;
12441       else if (unformat (i, "table-index %d", &table_index))
12442         ;
12443       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12444         action = 1;
12445       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12446         action = 2;
12447       else if (unformat (i, "action %d", &action))
12448         ;
12449       else if (unformat (i, "metadata %d", &metadata))
12450         ;
12451       else
12452         break;
12453     }
12454
12455   if (table_index == ~0)
12456     {
12457       errmsg ("Table index required");
12458       return -99;
12459     }
12460
12461   if (is_add && match == 0)
12462     {
12463       errmsg ("Match value required");
12464       return -99;
12465     }
12466
12467   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12468
12469   mp->is_add = is_add;
12470   mp->table_index = ntohl (table_index);
12471   mp->hit_next_index = ntohl (hit_next_index);
12472   mp->opaque_index = ntohl (opaque_index);
12473   mp->advance = ntohl (advance);
12474   mp->action = action;
12475   mp->metadata = ntohl (metadata);
12476   mp->match_len = ntohl (vec_len (match));
12477   clib_memcpy (mp->match, match, vec_len (match));
12478   vec_free (match);
12479
12480   S (mp);
12481   W (ret);
12482   return ret;
12483 }
12484
12485 static int
12486 api_classify_set_interface_ip_table (vat_main_t * vam)
12487 {
12488   unformat_input_t *i = vam->input;
12489   vl_api_classify_set_interface_ip_table_t *mp;
12490   u32 sw_if_index;
12491   int sw_if_index_set;
12492   u32 table_index = ~0;
12493   u8 is_ipv6 = 0;
12494   int ret;
12495
12496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12497     {
12498       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12499         sw_if_index_set = 1;
12500       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12501         sw_if_index_set = 1;
12502       else if (unformat (i, "table %d", &table_index))
12503         ;
12504       else
12505         {
12506           clib_warning ("parse error '%U'", format_unformat_error, i);
12507           return -99;
12508         }
12509     }
12510
12511   if (sw_if_index_set == 0)
12512     {
12513       errmsg ("missing interface name or sw_if_index");
12514       return -99;
12515     }
12516
12517
12518   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12519
12520   mp->sw_if_index = ntohl (sw_if_index);
12521   mp->table_index = ntohl (table_index);
12522   mp->is_ipv6 = is_ipv6;
12523
12524   S (mp);
12525   W (ret);
12526   return ret;
12527 }
12528
12529 static int
12530 api_classify_set_interface_l2_tables (vat_main_t * vam)
12531 {
12532   unformat_input_t *i = vam->input;
12533   vl_api_classify_set_interface_l2_tables_t *mp;
12534   u32 sw_if_index;
12535   int sw_if_index_set;
12536   u32 ip4_table_index = ~0;
12537   u32 ip6_table_index = ~0;
12538   u32 other_table_index = ~0;
12539   u32 is_input = 1;
12540   int ret;
12541
12542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12543     {
12544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12545         sw_if_index_set = 1;
12546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12547         sw_if_index_set = 1;
12548       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12549         ;
12550       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12551         ;
12552       else if (unformat (i, "other-table %d", &other_table_index))
12553         ;
12554       else if (unformat (i, "is-input %d", &is_input))
12555         ;
12556       else
12557         {
12558           clib_warning ("parse error '%U'", format_unformat_error, i);
12559           return -99;
12560         }
12561     }
12562
12563   if (sw_if_index_set == 0)
12564     {
12565       errmsg ("missing interface name or sw_if_index");
12566       return -99;
12567     }
12568
12569
12570   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12571
12572   mp->sw_if_index = ntohl (sw_if_index);
12573   mp->ip4_table_index = ntohl (ip4_table_index);
12574   mp->ip6_table_index = ntohl (ip6_table_index);
12575   mp->other_table_index = ntohl (other_table_index);
12576   mp->is_input = (u8) is_input;
12577
12578   S (mp);
12579   W (ret);
12580   return ret;
12581 }
12582
12583 static int
12584 api_set_ipfix_exporter (vat_main_t * vam)
12585 {
12586   unformat_input_t *i = vam->input;
12587   vl_api_set_ipfix_exporter_t *mp;
12588   ip4_address_t collector_address;
12589   u8 collector_address_set = 0;
12590   u32 collector_port = ~0;
12591   ip4_address_t src_address;
12592   u8 src_address_set = 0;
12593   u32 vrf_id = ~0;
12594   u32 path_mtu = ~0;
12595   u32 template_interval = ~0;
12596   u8 udp_checksum = 0;
12597   int ret;
12598
12599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12600     {
12601       if (unformat (i, "collector_address %U", unformat_ip4_address,
12602                     &collector_address))
12603         collector_address_set = 1;
12604       else if (unformat (i, "collector_port %d", &collector_port))
12605         ;
12606       else if (unformat (i, "src_address %U", unformat_ip4_address,
12607                          &src_address))
12608         src_address_set = 1;
12609       else if (unformat (i, "vrf_id %d", &vrf_id))
12610         ;
12611       else if (unformat (i, "path_mtu %d", &path_mtu))
12612         ;
12613       else if (unformat (i, "template_interval %d", &template_interval))
12614         ;
12615       else if (unformat (i, "udp_checksum"))
12616         udp_checksum = 1;
12617       else
12618         break;
12619     }
12620
12621   if (collector_address_set == 0)
12622     {
12623       errmsg ("collector_address required");
12624       return -99;
12625     }
12626
12627   if (src_address_set == 0)
12628     {
12629       errmsg ("src_address required");
12630       return -99;
12631     }
12632
12633   M (SET_IPFIX_EXPORTER, mp);
12634
12635   memcpy (mp->collector_address, collector_address.data,
12636           sizeof (collector_address.data));
12637   mp->collector_port = htons ((u16) collector_port);
12638   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12639   mp->vrf_id = htonl (vrf_id);
12640   mp->path_mtu = htonl (path_mtu);
12641   mp->template_interval = htonl (template_interval);
12642   mp->udp_checksum = udp_checksum;
12643
12644   S (mp);
12645   W (ret);
12646   return ret;
12647 }
12648
12649 static int
12650 api_set_ipfix_classify_stream (vat_main_t * vam)
12651 {
12652   unformat_input_t *i = vam->input;
12653   vl_api_set_ipfix_classify_stream_t *mp;
12654   u32 domain_id = 0;
12655   u32 src_port = UDP_DST_PORT_ipfix;
12656   int ret;
12657
12658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12659     {
12660       if (unformat (i, "domain %d", &domain_id))
12661         ;
12662       else if (unformat (i, "src_port %d", &src_port))
12663         ;
12664       else
12665         {
12666           errmsg ("unknown input `%U'", format_unformat_error, i);
12667           return -99;
12668         }
12669     }
12670
12671   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12672
12673   mp->domain_id = htonl (domain_id);
12674   mp->src_port = htons ((u16) src_port);
12675
12676   S (mp);
12677   W (ret);
12678   return ret;
12679 }
12680
12681 static int
12682 api_ipfix_classify_table_add_del (vat_main_t * vam)
12683 {
12684   unformat_input_t *i = vam->input;
12685   vl_api_ipfix_classify_table_add_del_t *mp;
12686   int is_add = -1;
12687   u32 classify_table_index = ~0;
12688   u8 ip_version = 0;
12689   u8 transport_protocol = 255;
12690   int ret;
12691
12692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12693     {
12694       if (unformat (i, "add"))
12695         is_add = 1;
12696       else if (unformat (i, "del"))
12697         is_add = 0;
12698       else if (unformat (i, "table %d", &classify_table_index))
12699         ;
12700       else if (unformat (i, "ip4"))
12701         ip_version = 4;
12702       else if (unformat (i, "ip6"))
12703         ip_version = 6;
12704       else if (unformat (i, "tcp"))
12705         transport_protocol = 6;
12706       else if (unformat (i, "udp"))
12707         transport_protocol = 17;
12708       else
12709         {
12710           errmsg ("unknown input `%U'", format_unformat_error, i);
12711           return -99;
12712         }
12713     }
12714
12715   if (is_add == -1)
12716     {
12717       errmsg ("expecting: add|del");
12718       return -99;
12719     }
12720   if (classify_table_index == ~0)
12721     {
12722       errmsg ("classifier table not specified");
12723       return -99;
12724     }
12725   if (ip_version == 0)
12726     {
12727       errmsg ("IP version not specified");
12728       return -99;
12729     }
12730
12731   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12732
12733   mp->is_add = is_add;
12734   mp->table_id = htonl (classify_table_index);
12735   mp->ip_version = ip_version;
12736   mp->transport_protocol = transport_protocol;
12737
12738   S (mp);
12739   W (ret);
12740   return ret;
12741 }
12742
12743 static int
12744 api_get_node_index (vat_main_t * vam)
12745 {
12746   unformat_input_t *i = vam->input;
12747   vl_api_get_node_index_t *mp;
12748   u8 *name = 0;
12749   int ret;
12750
12751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12752     {
12753       if (unformat (i, "node %s", &name))
12754         ;
12755       else
12756         break;
12757     }
12758   if (name == 0)
12759     {
12760       errmsg ("node name required");
12761       return -99;
12762     }
12763   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12764     {
12765       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12766       return -99;
12767     }
12768
12769   M (GET_NODE_INDEX, mp);
12770   clib_memcpy (mp->node_name, name, vec_len (name));
12771   vec_free (name);
12772
12773   S (mp);
12774   W (ret);
12775   return ret;
12776 }
12777
12778 static int
12779 api_get_next_index (vat_main_t * vam)
12780 {
12781   unformat_input_t *i = vam->input;
12782   vl_api_get_next_index_t *mp;
12783   u8 *node_name = 0, *next_node_name = 0;
12784   int ret;
12785
12786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12787     {
12788       if (unformat (i, "node-name %s", &node_name))
12789         ;
12790       else if (unformat (i, "next-node-name %s", &next_node_name))
12791         break;
12792     }
12793
12794   if (node_name == 0)
12795     {
12796       errmsg ("node name required");
12797       return -99;
12798     }
12799   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12800     {
12801       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12802       return -99;
12803     }
12804
12805   if (next_node_name == 0)
12806     {
12807       errmsg ("next node name required");
12808       return -99;
12809     }
12810   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12811     {
12812       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12813       return -99;
12814     }
12815
12816   M (GET_NEXT_INDEX, mp);
12817   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12818   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12819   vec_free (node_name);
12820   vec_free (next_node_name);
12821
12822   S (mp);
12823   W (ret);
12824   return ret;
12825 }
12826
12827 static int
12828 api_add_node_next (vat_main_t * vam)
12829 {
12830   unformat_input_t *i = vam->input;
12831   vl_api_add_node_next_t *mp;
12832   u8 *name = 0;
12833   u8 *next = 0;
12834   int ret;
12835
12836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12837     {
12838       if (unformat (i, "node %s", &name))
12839         ;
12840       else if (unformat (i, "next %s", &next))
12841         ;
12842       else
12843         break;
12844     }
12845   if (name == 0)
12846     {
12847       errmsg ("node name required");
12848       return -99;
12849     }
12850   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12851     {
12852       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12853       return -99;
12854     }
12855   if (next == 0)
12856     {
12857       errmsg ("next node required");
12858       return -99;
12859     }
12860   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12861     {
12862       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12863       return -99;
12864     }
12865
12866   M (ADD_NODE_NEXT, mp);
12867   clib_memcpy (mp->node_name, name, vec_len (name));
12868   clib_memcpy (mp->next_name, next, vec_len (next));
12869   vec_free (name);
12870   vec_free (next);
12871
12872   S (mp);
12873   W (ret);
12874   return ret;
12875 }
12876
12877 static int
12878 api_l2tpv3_create_tunnel (vat_main_t * vam)
12879 {
12880   unformat_input_t *i = vam->input;
12881   ip6_address_t client_address, our_address;
12882   int client_address_set = 0;
12883   int our_address_set = 0;
12884   u32 local_session_id = 0;
12885   u32 remote_session_id = 0;
12886   u64 local_cookie = 0;
12887   u64 remote_cookie = 0;
12888   u8 l2_sublayer_present = 0;
12889   vl_api_l2tpv3_create_tunnel_t *mp;
12890   int ret;
12891
12892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12893     {
12894       if (unformat (i, "client_address %U", unformat_ip6_address,
12895                     &client_address))
12896         client_address_set = 1;
12897       else if (unformat (i, "our_address %U", unformat_ip6_address,
12898                          &our_address))
12899         our_address_set = 1;
12900       else if (unformat (i, "local_session_id %d", &local_session_id))
12901         ;
12902       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12903         ;
12904       else if (unformat (i, "local_cookie %lld", &local_cookie))
12905         ;
12906       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12907         ;
12908       else if (unformat (i, "l2-sublayer-present"))
12909         l2_sublayer_present = 1;
12910       else
12911         break;
12912     }
12913
12914   if (client_address_set == 0)
12915     {
12916       errmsg ("client_address required");
12917       return -99;
12918     }
12919
12920   if (our_address_set == 0)
12921     {
12922       errmsg ("our_address required");
12923       return -99;
12924     }
12925
12926   M (L2TPV3_CREATE_TUNNEL, mp);
12927
12928   clib_memcpy (mp->client_address, client_address.as_u8,
12929                sizeof (mp->client_address));
12930
12931   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12932
12933   mp->local_session_id = ntohl (local_session_id);
12934   mp->remote_session_id = ntohl (remote_session_id);
12935   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12936   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12937   mp->l2_sublayer_present = l2_sublayer_present;
12938   mp->is_ipv6 = 1;
12939
12940   S (mp);
12941   W (ret);
12942   return ret;
12943 }
12944
12945 static int
12946 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12947 {
12948   unformat_input_t *i = vam->input;
12949   u32 sw_if_index;
12950   u8 sw_if_index_set = 0;
12951   u64 new_local_cookie = 0;
12952   u64 new_remote_cookie = 0;
12953   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12954   int ret;
12955
12956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12957     {
12958       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12959         sw_if_index_set = 1;
12960       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12961         sw_if_index_set = 1;
12962       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12963         ;
12964       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12965         ;
12966       else
12967         break;
12968     }
12969
12970   if (sw_if_index_set == 0)
12971     {
12972       errmsg ("missing interface name or sw_if_index");
12973       return -99;
12974     }
12975
12976   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12977
12978   mp->sw_if_index = ntohl (sw_if_index);
12979   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12980   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12981
12982   S (mp);
12983   W (ret);
12984   return ret;
12985 }
12986
12987 static int
12988 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12989 {
12990   unformat_input_t *i = vam->input;
12991   vl_api_l2tpv3_interface_enable_disable_t *mp;
12992   u32 sw_if_index;
12993   u8 sw_if_index_set = 0;
12994   u8 enable_disable = 1;
12995   int ret;
12996
12997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12998     {
12999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13000         sw_if_index_set = 1;
13001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13002         sw_if_index_set = 1;
13003       else if (unformat (i, "enable"))
13004         enable_disable = 1;
13005       else if (unformat (i, "disable"))
13006         enable_disable = 0;
13007       else
13008         break;
13009     }
13010
13011   if (sw_if_index_set == 0)
13012     {
13013       errmsg ("missing interface name or sw_if_index");
13014       return -99;
13015     }
13016
13017   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
13018
13019   mp->sw_if_index = ntohl (sw_if_index);
13020   mp->enable_disable = enable_disable;
13021
13022   S (mp);
13023   W (ret);
13024   return ret;
13025 }
13026
13027 static int
13028 api_l2tpv3_set_lookup_key (vat_main_t * vam)
13029 {
13030   unformat_input_t *i = vam->input;
13031   vl_api_l2tpv3_set_lookup_key_t *mp;
13032   u8 key = ~0;
13033   int ret;
13034
13035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13036     {
13037       if (unformat (i, "lookup_v6_src"))
13038         key = L2T_LOOKUP_SRC_ADDRESS;
13039       else if (unformat (i, "lookup_v6_dst"))
13040         key = L2T_LOOKUP_DST_ADDRESS;
13041       else if (unformat (i, "lookup_session_id"))
13042         key = L2T_LOOKUP_SESSION_ID;
13043       else
13044         break;
13045     }
13046
13047   if (key == (u8) ~ 0)
13048     {
13049       errmsg ("l2tp session lookup key unset");
13050       return -99;
13051     }
13052
13053   M (L2TPV3_SET_LOOKUP_KEY, mp);
13054
13055   mp->key = key;
13056
13057   S (mp);
13058   W (ret);
13059   return ret;
13060 }
13061
13062 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
13063   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13064 {
13065   vat_main_t *vam = &vat_main;
13066
13067   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
13068          format_ip6_address, mp->our_address,
13069          format_ip6_address, mp->client_address,
13070          clib_net_to_host_u32 (mp->sw_if_index));
13071
13072   print (vam->ofp,
13073          "   local cookies %016llx %016llx remote cookie %016llx",
13074          clib_net_to_host_u64 (mp->local_cookie[0]),
13075          clib_net_to_host_u64 (mp->local_cookie[1]),
13076          clib_net_to_host_u64 (mp->remote_cookie));
13077
13078   print (vam->ofp, "   local session-id %d remote session-id %d",
13079          clib_net_to_host_u32 (mp->local_session_id),
13080          clib_net_to_host_u32 (mp->remote_session_id));
13081
13082   print (vam->ofp, "   l2 specific sublayer %s\n",
13083          mp->l2_sublayer_present ? "preset" : "absent");
13084
13085 }
13086
13087 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13088   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13089 {
13090   vat_main_t *vam = &vat_main;
13091   vat_json_node_t *node = NULL;
13092   struct in6_addr addr;
13093
13094   if (VAT_JSON_ARRAY != vam->json_tree.type)
13095     {
13096       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13097       vat_json_init_array (&vam->json_tree);
13098     }
13099   node = vat_json_array_add (&vam->json_tree);
13100
13101   vat_json_init_object (node);
13102
13103   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13104   vat_json_object_add_ip6 (node, "our_address", addr);
13105   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13106   vat_json_object_add_ip6 (node, "client_address", addr);
13107
13108   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13109   vat_json_init_array (lc);
13110   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13111   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13112   vat_json_object_add_uint (node, "remote_cookie",
13113                             clib_net_to_host_u64 (mp->remote_cookie));
13114
13115   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13116   vat_json_object_add_uint (node, "local_session_id",
13117                             clib_net_to_host_u32 (mp->local_session_id));
13118   vat_json_object_add_uint (node, "remote_session_id",
13119                             clib_net_to_host_u32 (mp->remote_session_id));
13120   vat_json_object_add_string_copy (node, "l2_sublayer",
13121                                    mp->l2_sublayer_present ? (u8 *) "present"
13122                                    : (u8 *) "absent");
13123 }
13124
13125 static int
13126 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13127 {
13128   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13129   vl_api_control_ping_t *mp_ping;
13130   int ret;
13131
13132   /* Get list of l2tpv3-tunnel interfaces */
13133   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13134   S (mp);
13135
13136   /* Use a control ping for synchronization */
13137   MPING (CONTROL_PING, mp_ping);
13138   S (mp_ping);
13139
13140   W (ret);
13141   return ret;
13142 }
13143
13144
13145 static void vl_api_sw_interface_tap_details_t_handler
13146   (vl_api_sw_interface_tap_details_t * mp)
13147 {
13148   vat_main_t *vam = &vat_main;
13149
13150   print (vam->ofp, "%-16s %d",
13151          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13152 }
13153
13154 static void vl_api_sw_interface_tap_details_t_handler_json
13155   (vl_api_sw_interface_tap_details_t * mp)
13156 {
13157   vat_main_t *vam = &vat_main;
13158   vat_json_node_t *node = NULL;
13159
13160   if (VAT_JSON_ARRAY != vam->json_tree.type)
13161     {
13162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13163       vat_json_init_array (&vam->json_tree);
13164     }
13165   node = vat_json_array_add (&vam->json_tree);
13166
13167   vat_json_init_object (node);
13168   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13169   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13170 }
13171
13172 static int
13173 api_sw_interface_tap_dump (vat_main_t * vam)
13174 {
13175   vl_api_sw_interface_tap_dump_t *mp;
13176   vl_api_control_ping_t *mp_ping;
13177   int ret;
13178
13179   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13180   /* Get list of tap interfaces */
13181   M (SW_INTERFACE_TAP_DUMP, mp);
13182   S (mp);
13183
13184   /* Use a control ping for synchronization */
13185   MPING (CONTROL_PING, mp_ping);
13186   S (mp_ping);
13187
13188   W (ret);
13189   return ret;
13190 }
13191
13192 static void vl_api_sw_interface_tap_v2_details_t_handler
13193   (vl_api_sw_interface_tap_v2_details_t * mp)
13194 {
13195   vat_main_t *vam = &vat_main;
13196
13197   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13198                     mp->host_ip4_prefix_len);
13199   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13200                     mp->host_ip6_prefix_len);
13201
13202   print (vam->ofp,
13203          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13204          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13205          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13206          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13207          mp->host_bridge, ip4, ip6);
13208
13209   vec_free (ip4);
13210   vec_free (ip6);
13211 }
13212
13213 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13214   (vl_api_sw_interface_tap_v2_details_t * mp)
13215 {
13216   vat_main_t *vam = &vat_main;
13217   vat_json_node_t *node = NULL;
13218
13219   if (VAT_JSON_ARRAY != vam->json_tree.type)
13220     {
13221       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13222       vat_json_init_array (&vam->json_tree);
13223     }
13224   node = vat_json_array_add (&vam->json_tree);
13225
13226   vat_json_init_object (node);
13227   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13228   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13229   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13230   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13231   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13232   vat_json_object_add_string_copy (node, "host_mac_addr",
13233                                    format (0, "%U", format_ethernet_address,
13234                                            &mp->host_mac_addr));
13235   vat_json_object_add_string_copy (node, "host_namespace",
13236                                    mp->host_namespace);
13237   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13238   vat_json_object_add_string_copy (node, "host_ip4_addr",
13239                                    format (0, "%U/%d", format_ip4_address,
13240                                            mp->host_ip4_addr,
13241                                            mp->host_ip4_prefix_len));
13242   vat_json_object_add_string_copy (node, "host_ip6_addr",
13243                                    format (0, "%U/%d", format_ip6_address,
13244                                            mp->host_ip6_addr,
13245                                            mp->host_ip6_prefix_len));
13246
13247 }
13248
13249 static int
13250 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13251 {
13252   vl_api_sw_interface_tap_v2_dump_t *mp;
13253   vl_api_control_ping_t *mp_ping;
13254   int ret;
13255
13256   print (vam->ofp,
13257          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13258          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13259          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13260          "host_ip6_addr");
13261
13262   /* Get list of tap interfaces */
13263   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13264   S (mp);
13265
13266   /* Use a control ping for synchronization */
13267   MPING (CONTROL_PING, mp_ping);
13268   S (mp_ping);
13269
13270   W (ret);
13271   return ret;
13272 }
13273
13274 static int
13275 api_vxlan_offload_rx (vat_main_t * vam)
13276 {
13277   unformat_input_t *line_input = vam->input;
13278   vl_api_vxlan_offload_rx_t *mp;
13279   u32 hw_if_index = ~0, rx_if_index = ~0;
13280   u8 is_add = 1;
13281   int ret;
13282
13283   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13284     {
13285       if (unformat (line_input, "del"))
13286         is_add = 0;
13287       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13288                          &hw_if_index))
13289         ;
13290       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13291         ;
13292       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13293                          &rx_if_index))
13294         ;
13295       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13296         ;
13297       else
13298         {
13299           errmsg ("parse error '%U'", format_unformat_error, line_input);
13300           return -99;
13301         }
13302     }
13303
13304   if (hw_if_index == ~0)
13305     {
13306       errmsg ("no hw interface");
13307       return -99;
13308     }
13309
13310   if (rx_if_index == ~0)
13311     {
13312       errmsg ("no rx tunnel");
13313       return -99;
13314     }
13315
13316   M (VXLAN_OFFLOAD_RX, mp);
13317
13318   mp->hw_if_index = ntohl (hw_if_index);
13319   mp->sw_if_index = ntohl (rx_if_index);
13320   mp->enable = is_add;
13321
13322   S (mp);
13323   W (ret);
13324   return ret;
13325 }
13326
13327 static uword unformat_vxlan_decap_next
13328   (unformat_input_t * input, va_list * args)
13329 {
13330   u32 *result = va_arg (*args, u32 *);
13331   u32 tmp;
13332
13333   if (unformat (input, "l2"))
13334     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13335   else if (unformat (input, "%d", &tmp))
13336     *result = tmp;
13337   else
13338     return 0;
13339   return 1;
13340 }
13341
13342 static int
13343 api_vxlan_add_del_tunnel (vat_main_t * vam)
13344 {
13345   unformat_input_t *line_input = vam->input;
13346   vl_api_vxlan_add_del_tunnel_t *mp;
13347   ip46_address_t src, dst;
13348   u8 is_add = 1;
13349   u8 ipv4_set = 0, ipv6_set = 0;
13350   u8 src_set = 0;
13351   u8 dst_set = 0;
13352   u8 grp_set = 0;
13353   u32 instance = ~0;
13354   u32 mcast_sw_if_index = ~0;
13355   u32 encap_vrf_id = 0;
13356   u32 decap_next_index = ~0;
13357   u32 vni = 0;
13358   int ret;
13359
13360   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13361   clib_memset (&src, 0, sizeof src);
13362   clib_memset (&dst, 0, sizeof dst);
13363
13364   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13365     {
13366       if (unformat (line_input, "del"))
13367         is_add = 0;
13368       else if (unformat (line_input, "instance %d", &instance))
13369         ;
13370       else
13371         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13372         {
13373           ipv4_set = 1;
13374           src_set = 1;
13375         }
13376       else
13377         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13378         {
13379           ipv4_set = 1;
13380           dst_set = 1;
13381         }
13382       else
13383         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13384         {
13385           ipv6_set = 1;
13386           src_set = 1;
13387         }
13388       else
13389         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13390         {
13391           ipv6_set = 1;
13392           dst_set = 1;
13393         }
13394       else if (unformat (line_input, "group %U %U",
13395                          unformat_ip4_address, &dst.ip4,
13396                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13397         {
13398           grp_set = dst_set = 1;
13399           ipv4_set = 1;
13400         }
13401       else if (unformat (line_input, "group %U",
13402                          unformat_ip4_address, &dst.ip4))
13403         {
13404           grp_set = dst_set = 1;
13405           ipv4_set = 1;
13406         }
13407       else if (unformat (line_input, "group %U %U",
13408                          unformat_ip6_address, &dst.ip6,
13409                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13410         {
13411           grp_set = dst_set = 1;
13412           ipv6_set = 1;
13413         }
13414       else if (unformat (line_input, "group %U",
13415                          unformat_ip6_address, &dst.ip6))
13416         {
13417           grp_set = dst_set = 1;
13418           ipv6_set = 1;
13419         }
13420       else
13421         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13422         ;
13423       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13424         ;
13425       else if (unformat (line_input, "decap-next %U",
13426                          unformat_vxlan_decap_next, &decap_next_index))
13427         ;
13428       else if (unformat (line_input, "vni %d", &vni))
13429         ;
13430       else
13431         {
13432           errmsg ("parse error '%U'", format_unformat_error, line_input);
13433           return -99;
13434         }
13435     }
13436
13437   if (src_set == 0)
13438     {
13439       errmsg ("tunnel src address not specified");
13440       return -99;
13441     }
13442   if (dst_set == 0)
13443     {
13444       errmsg ("tunnel dst address not specified");
13445       return -99;
13446     }
13447
13448   if (grp_set && !ip46_address_is_multicast (&dst))
13449     {
13450       errmsg ("tunnel group address not multicast");
13451       return -99;
13452     }
13453   if (grp_set && mcast_sw_if_index == ~0)
13454     {
13455       errmsg ("tunnel nonexistent multicast device");
13456       return -99;
13457     }
13458   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13459     {
13460       errmsg ("tunnel dst address must be unicast");
13461       return -99;
13462     }
13463
13464
13465   if (ipv4_set && ipv6_set)
13466     {
13467       errmsg ("both IPv4 and IPv6 addresses specified");
13468       return -99;
13469     }
13470
13471   if ((vni == 0) || (vni >> 24))
13472     {
13473       errmsg ("vni not specified or out of range");
13474       return -99;
13475     }
13476
13477   M (VXLAN_ADD_DEL_TUNNEL, mp);
13478
13479   if (ipv6_set)
13480     {
13481       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13482       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13483     }
13484   else
13485     {
13486       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13487       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13488     }
13489
13490   mp->instance = htonl (instance);
13491   mp->encap_vrf_id = ntohl (encap_vrf_id);
13492   mp->decap_next_index = ntohl (decap_next_index);
13493   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13494   mp->vni = ntohl (vni);
13495   mp->is_add = is_add;
13496   mp->is_ipv6 = ipv6_set;
13497
13498   S (mp);
13499   W (ret);
13500   return ret;
13501 }
13502
13503 static void vl_api_vxlan_tunnel_details_t_handler
13504   (vl_api_vxlan_tunnel_details_t * mp)
13505 {
13506   vat_main_t *vam = &vat_main;
13507   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13508   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13509
13510   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13511          ntohl (mp->sw_if_index),
13512          ntohl (mp->instance),
13513          format_ip46_address, &src, IP46_TYPE_ANY,
13514          format_ip46_address, &dst, IP46_TYPE_ANY,
13515          ntohl (mp->encap_vrf_id),
13516          ntohl (mp->decap_next_index), ntohl (mp->vni),
13517          ntohl (mp->mcast_sw_if_index));
13518 }
13519
13520 static void vl_api_vxlan_tunnel_details_t_handler_json
13521   (vl_api_vxlan_tunnel_details_t * mp)
13522 {
13523   vat_main_t *vam = &vat_main;
13524   vat_json_node_t *node = NULL;
13525
13526   if (VAT_JSON_ARRAY != vam->json_tree.type)
13527     {
13528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13529       vat_json_init_array (&vam->json_tree);
13530     }
13531   node = vat_json_array_add (&vam->json_tree);
13532
13533   vat_json_init_object (node);
13534   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13535
13536   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13537
13538   if (mp->is_ipv6)
13539     {
13540       struct in6_addr ip6;
13541
13542       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13543       vat_json_object_add_ip6 (node, "src_address", ip6);
13544       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13545       vat_json_object_add_ip6 (node, "dst_address", ip6);
13546     }
13547   else
13548     {
13549       struct in_addr ip4;
13550
13551       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13552       vat_json_object_add_ip4 (node, "src_address", ip4);
13553       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13554       vat_json_object_add_ip4 (node, "dst_address", ip4);
13555     }
13556   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13557   vat_json_object_add_uint (node, "decap_next_index",
13558                             ntohl (mp->decap_next_index));
13559   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13560   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13561   vat_json_object_add_uint (node, "mcast_sw_if_index",
13562                             ntohl (mp->mcast_sw_if_index));
13563 }
13564
13565 static int
13566 api_vxlan_tunnel_dump (vat_main_t * vam)
13567 {
13568   unformat_input_t *i = vam->input;
13569   vl_api_vxlan_tunnel_dump_t *mp;
13570   vl_api_control_ping_t *mp_ping;
13571   u32 sw_if_index;
13572   u8 sw_if_index_set = 0;
13573   int ret;
13574
13575   /* Parse args required to build the message */
13576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13577     {
13578       if (unformat (i, "sw_if_index %d", &sw_if_index))
13579         sw_if_index_set = 1;
13580       else
13581         break;
13582     }
13583
13584   if (sw_if_index_set == 0)
13585     {
13586       sw_if_index = ~0;
13587     }
13588
13589   if (!vam->json_output)
13590     {
13591       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13592              "sw_if_index", "instance", "src_address", "dst_address",
13593              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13594     }
13595
13596   /* Get list of vxlan-tunnel interfaces */
13597   M (VXLAN_TUNNEL_DUMP, mp);
13598
13599   mp->sw_if_index = htonl (sw_if_index);
13600
13601   S (mp);
13602
13603   /* Use a control ping for synchronization */
13604   MPING (CONTROL_PING, mp_ping);
13605   S (mp_ping);
13606
13607   W (ret);
13608   return ret;
13609 }
13610
13611 static uword unformat_geneve_decap_next
13612   (unformat_input_t * input, va_list * args)
13613 {
13614   u32 *result = va_arg (*args, u32 *);
13615   u32 tmp;
13616
13617   if (unformat (input, "l2"))
13618     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13619   else if (unformat (input, "%d", &tmp))
13620     *result = tmp;
13621   else
13622     return 0;
13623   return 1;
13624 }
13625
13626 static int
13627 api_geneve_add_del_tunnel (vat_main_t * vam)
13628 {
13629   unformat_input_t *line_input = vam->input;
13630   vl_api_geneve_add_del_tunnel_t *mp;
13631   ip46_address_t src, dst;
13632   u8 is_add = 1;
13633   u8 ipv4_set = 0, ipv6_set = 0;
13634   u8 src_set = 0;
13635   u8 dst_set = 0;
13636   u8 grp_set = 0;
13637   u32 mcast_sw_if_index = ~0;
13638   u32 encap_vrf_id = 0;
13639   u32 decap_next_index = ~0;
13640   u32 vni = 0;
13641   int ret;
13642
13643   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13644   clib_memset (&src, 0, sizeof src);
13645   clib_memset (&dst, 0, sizeof dst);
13646
13647   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13648     {
13649       if (unformat (line_input, "del"))
13650         is_add = 0;
13651       else
13652         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13653         {
13654           ipv4_set = 1;
13655           src_set = 1;
13656         }
13657       else
13658         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13659         {
13660           ipv4_set = 1;
13661           dst_set = 1;
13662         }
13663       else
13664         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13665         {
13666           ipv6_set = 1;
13667           src_set = 1;
13668         }
13669       else
13670         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13671         {
13672           ipv6_set = 1;
13673           dst_set = 1;
13674         }
13675       else if (unformat (line_input, "group %U %U",
13676                          unformat_ip4_address, &dst.ip4,
13677                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13678         {
13679           grp_set = dst_set = 1;
13680           ipv4_set = 1;
13681         }
13682       else if (unformat (line_input, "group %U",
13683                          unformat_ip4_address, &dst.ip4))
13684         {
13685           grp_set = dst_set = 1;
13686           ipv4_set = 1;
13687         }
13688       else if (unformat (line_input, "group %U %U",
13689                          unformat_ip6_address, &dst.ip6,
13690                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13691         {
13692           grp_set = dst_set = 1;
13693           ipv6_set = 1;
13694         }
13695       else if (unformat (line_input, "group %U",
13696                          unformat_ip6_address, &dst.ip6))
13697         {
13698           grp_set = dst_set = 1;
13699           ipv6_set = 1;
13700         }
13701       else
13702         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13703         ;
13704       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13705         ;
13706       else if (unformat (line_input, "decap-next %U",
13707                          unformat_geneve_decap_next, &decap_next_index))
13708         ;
13709       else if (unformat (line_input, "vni %d", &vni))
13710         ;
13711       else
13712         {
13713           errmsg ("parse error '%U'", format_unformat_error, line_input);
13714           return -99;
13715         }
13716     }
13717
13718   if (src_set == 0)
13719     {
13720       errmsg ("tunnel src address not specified");
13721       return -99;
13722     }
13723   if (dst_set == 0)
13724     {
13725       errmsg ("tunnel dst address not specified");
13726       return -99;
13727     }
13728
13729   if (grp_set && !ip46_address_is_multicast (&dst))
13730     {
13731       errmsg ("tunnel group address not multicast");
13732       return -99;
13733     }
13734   if (grp_set && mcast_sw_if_index == ~0)
13735     {
13736       errmsg ("tunnel nonexistent multicast device");
13737       return -99;
13738     }
13739   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13740     {
13741       errmsg ("tunnel dst address must be unicast");
13742       return -99;
13743     }
13744
13745
13746   if (ipv4_set && ipv6_set)
13747     {
13748       errmsg ("both IPv4 and IPv6 addresses specified");
13749       return -99;
13750     }
13751
13752   if ((vni == 0) || (vni >> 24))
13753     {
13754       errmsg ("vni not specified or out of range");
13755       return -99;
13756     }
13757
13758   M (GENEVE_ADD_DEL_TUNNEL, mp);
13759
13760   if (ipv6_set)
13761     {
13762       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13763       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13764     }
13765   else
13766     {
13767       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13768       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13769     }
13770   mp->encap_vrf_id = ntohl (encap_vrf_id);
13771   mp->decap_next_index = ntohl (decap_next_index);
13772   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13773   mp->vni = ntohl (vni);
13774   mp->is_add = is_add;
13775   mp->is_ipv6 = ipv6_set;
13776
13777   S (mp);
13778   W (ret);
13779   return ret;
13780 }
13781
13782 static void vl_api_geneve_tunnel_details_t_handler
13783   (vl_api_geneve_tunnel_details_t * mp)
13784 {
13785   vat_main_t *vam = &vat_main;
13786   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13787   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13788
13789   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13790          ntohl (mp->sw_if_index),
13791          format_ip46_address, &src, IP46_TYPE_ANY,
13792          format_ip46_address, &dst, IP46_TYPE_ANY,
13793          ntohl (mp->encap_vrf_id),
13794          ntohl (mp->decap_next_index), ntohl (mp->vni),
13795          ntohl (mp->mcast_sw_if_index));
13796 }
13797
13798 static void vl_api_geneve_tunnel_details_t_handler_json
13799   (vl_api_geneve_tunnel_details_t * mp)
13800 {
13801   vat_main_t *vam = &vat_main;
13802   vat_json_node_t *node = NULL;
13803
13804   if (VAT_JSON_ARRAY != vam->json_tree.type)
13805     {
13806       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13807       vat_json_init_array (&vam->json_tree);
13808     }
13809   node = vat_json_array_add (&vam->json_tree);
13810
13811   vat_json_init_object (node);
13812   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13813   if (mp->is_ipv6)
13814     {
13815       struct in6_addr ip6;
13816
13817       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13818       vat_json_object_add_ip6 (node, "src_address", ip6);
13819       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13820       vat_json_object_add_ip6 (node, "dst_address", ip6);
13821     }
13822   else
13823     {
13824       struct in_addr ip4;
13825
13826       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13827       vat_json_object_add_ip4 (node, "src_address", ip4);
13828       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13829       vat_json_object_add_ip4 (node, "dst_address", ip4);
13830     }
13831   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13832   vat_json_object_add_uint (node, "decap_next_index",
13833                             ntohl (mp->decap_next_index));
13834   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13835   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13836   vat_json_object_add_uint (node, "mcast_sw_if_index",
13837                             ntohl (mp->mcast_sw_if_index));
13838 }
13839
13840 static int
13841 api_geneve_tunnel_dump (vat_main_t * vam)
13842 {
13843   unformat_input_t *i = vam->input;
13844   vl_api_geneve_tunnel_dump_t *mp;
13845   vl_api_control_ping_t *mp_ping;
13846   u32 sw_if_index;
13847   u8 sw_if_index_set = 0;
13848   int ret;
13849
13850   /* Parse args required to build the message */
13851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13852     {
13853       if (unformat (i, "sw_if_index %d", &sw_if_index))
13854         sw_if_index_set = 1;
13855       else
13856         break;
13857     }
13858
13859   if (sw_if_index_set == 0)
13860     {
13861       sw_if_index = ~0;
13862     }
13863
13864   if (!vam->json_output)
13865     {
13866       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13867              "sw_if_index", "local_address", "remote_address",
13868              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13869     }
13870
13871   /* Get list of geneve-tunnel interfaces */
13872   M (GENEVE_TUNNEL_DUMP, mp);
13873
13874   mp->sw_if_index = htonl (sw_if_index);
13875
13876   S (mp);
13877
13878   /* Use a control ping for synchronization */
13879   M (CONTROL_PING, mp_ping);
13880   S (mp_ping);
13881
13882   W (ret);
13883   return ret;
13884 }
13885
13886 static int
13887 api_gre_add_del_tunnel (vat_main_t * vam)
13888 {
13889   unformat_input_t *line_input = vam->input;
13890   vl_api_gre_add_del_tunnel_t *mp;
13891   ip4_address_t src4, dst4;
13892   ip6_address_t src6, dst6;
13893   u8 is_add = 1;
13894   u8 ipv4_set = 0;
13895   u8 ipv6_set = 0;
13896   u8 t_type = GRE_TUNNEL_TYPE_L3;
13897   u8 src_set = 0;
13898   u8 dst_set = 0;
13899   u32 outer_fib_id = 0;
13900   u32 session_id = 0;
13901   u32 instance = ~0;
13902   int ret;
13903
13904   clib_memset (&src4, 0, sizeof src4);
13905   clib_memset (&dst4, 0, sizeof dst4);
13906   clib_memset (&src6, 0, sizeof src6);
13907   clib_memset (&dst6, 0, sizeof dst6);
13908
13909   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13910     {
13911       if (unformat (line_input, "del"))
13912         is_add = 0;
13913       else if (unformat (line_input, "instance %d", &instance))
13914         ;
13915       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13916         {
13917           src_set = 1;
13918           ipv4_set = 1;
13919         }
13920       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13921         {
13922           dst_set = 1;
13923           ipv4_set = 1;
13924         }
13925       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13926         {
13927           src_set = 1;
13928           ipv6_set = 1;
13929         }
13930       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13931         {
13932           dst_set = 1;
13933           ipv6_set = 1;
13934         }
13935       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13936         ;
13937       else if (unformat (line_input, "teb"))
13938         t_type = GRE_TUNNEL_TYPE_TEB;
13939       else if (unformat (line_input, "erspan %d", &session_id))
13940         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13941       else
13942         {
13943           errmsg ("parse error '%U'", format_unformat_error, line_input);
13944           return -99;
13945         }
13946     }
13947
13948   if (src_set == 0)
13949     {
13950       errmsg ("tunnel src address not specified");
13951       return -99;
13952     }
13953   if (dst_set == 0)
13954     {
13955       errmsg ("tunnel dst address not specified");
13956       return -99;
13957     }
13958   if (ipv4_set && ipv6_set)
13959     {
13960       errmsg ("both IPv4 and IPv6 addresses specified");
13961       return -99;
13962     }
13963
13964
13965   M (GRE_ADD_DEL_TUNNEL, mp);
13966
13967   if (ipv4_set)
13968     {
13969       clib_memcpy (&mp->src_address, &src4, 4);
13970       clib_memcpy (&mp->dst_address, &dst4, 4);
13971     }
13972   else
13973     {
13974       clib_memcpy (&mp->src_address, &src6, 16);
13975       clib_memcpy (&mp->dst_address, &dst6, 16);
13976     }
13977   mp->instance = htonl (instance);
13978   mp->outer_fib_id = htonl (outer_fib_id);
13979   mp->is_add = is_add;
13980   mp->session_id = htons ((u16) session_id);
13981   mp->tunnel_type = t_type;
13982   mp->is_ipv6 = ipv6_set;
13983
13984   S (mp);
13985   W (ret);
13986   return ret;
13987 }
13988
13989 static void vl_api_gre_tunnel_details_t_handler
13990   (vl_api_gre_tunnel_details_t * mp)
13991 {
13992   vat_main_t *vam = &vat_main;
13993   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13994   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13995
13996   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13997          ntohl (mp->sw_if_index),
13998          ntohl (mp->instance),
13999          format_ip46_address, &src, IP46_TYPE_ANY,
14000          format_ip46_address, &dst, IP46_TYPE_ANY,
14001          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
14002 }
14003
14004 static void vl_api_gre_tunnel_details_t_handler_json
14005   (vl_api_gre_tunnel_details_t * mp)
14006 {
14007   vat_main_t *vam = &vat_main;
14008   vat_json_node_t *node = NULL;
14009   struct in_addr ip4;
14010   struct in6_addr ip6;
14011
14012   if (VAT_JSON_ARRAY != vam->json_tree.type)
14013     {
14014       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14015       vat_json_init_array (&vam->json_tree);
14016     }
14017   node = vat_json_array_add (&vam->json_tree);
14018
14019   vat_json_init_object (node);
14020   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14021   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
14022   if (!mp->is_ipv6)
14023     {
14024       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14025       vat_json_object_add_ip4 (node, "src_address", ip4);
14026       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14027       vat_json_object_add_ip4 (node, "dst_address", ip4);
14028     }
14029   else
14030     {
14031       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
14032       vat_json_object_add_ip6 (node, "src_address", ip6);
14033       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
14034       vat_json_object_add_ip6 (node, "dst_address", ip6);
14035     }
14036   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
14037   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
14038   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
14039   vat_json_object_add_uint (node, "session_id", mp->session_id);
14040 }
14041
14042 static int
14043 api_gre_tunnel_dump (vat_main_t * vam)
14044 {
14045   unformat_input_t *i = vam->input;
14046   vl_api_gre_tunnel_dump_t *mp;
14047   vl_api_control_ping_t *mp_ping;
14048   u32 sw_if_index;
14049   u8 sw_if_index_set = 0;
14050   int ret;
14051
14052   /* Parse args required to build the message */
14053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14054     {
14055       if (unformat (i, "sw_if_index %d", &sw_if_index))
14056         sw_if_index_set = 1;
14057       else
14058         break;
14059     }
14060
14061   if (sw_if_index_set == 0)
14062     {
14063       sw_if_index = ~0;
14064     }
14065
14066   if (!vam->json_output)
14067     {
14068       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
14069              "sw_if_index", "instance", "src_address", "dst_address",
14070              "tunnel_type", "outer_fib_id", "session_id");
14071     }
14072
14073   /* Get list of gre-tunnel interfaces */
14074   M (GRE_TUNNEL_DUMP, mp);
14075
14076   mp->sw_if_index = htonl (sw_if_index);
14077
14078   S (mp);
14079
14080   /* Use a control ping for synchronization */
14081   MPING (CONTROL_PING, mp_ping);
14082   S (mp_ping);
14083
14084   W (ret);
14085   return ret;
14086 }
14087
14088 static int
14089 api_l2_fib_clear_table (vat_main_t * vam)
14090 {
14091 //  unformat_input_t * i = vam->input;
14092   vl_api_l2_fib_clear_table_t *mp;
14093   int ret;
14094
14095   M (L2_FIB_CLEAR_TABLE, mp);
14096
14097   S (mp);
14098   W (ret);
14099   return ret;
14100 }
14101
14102 static int
14103 api_l2_interface_efp_filter (vat_main_t * vam)
14104 {
14105   unformat_input_t *i = vam->input;
14106   vl_api_l2_interface_efp_filter_t *mp;
14107   u32 sw_if_index;
14108   u8 enable = 1;
14109   u8 sw_if_index_set = 0;
14110   int ret;
14111
14112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14113     {
14114       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14115         sw_if_index_set = 1;
14116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14117         sw_if_index_set = 1;
14118       else if (unformat (i, "enable"))
14119         enable = 1;
14120       else if (unformat (i, "disable"))
14121         enable = 0;
14122       else
14123         {
14124           clib_warning ("parse error '%U'", format_unformat_error, i);
14125           return -99;
14126         }
14127     }
14128
14129   if (sw_if_index_set == 0)
14130     {
14131       errmsg ("missing sw_if_index");
14132       return -99;
14133     }
14134
14135   M (L2_INTERFACE_EFP_FILTER, mp);
14136
14137   mp->sw_if_index = ntohl (sw_if_index);
14138   mp->enable_disable = enable;
14139
14140   S (mp);
14141   W (ret);
14142   return ret;
14143 }
14144
14145 #define foreach_vtr_op                          \
14146 _("disable",  L2_VTR_DISABLED)                  \
14147 _("push-1",  L2_VTR_PUSH_1)                     \
14148 _("push-2",  L2_VTR_PUSH_2)                     \
14149 _("pop-1",  L2_VTR_POP_1)                       \
14150 _("pop-2",  L2_VTR_POP_2)                       \
14151 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14152 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14153 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14154 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14155
14156 static int
14157 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14158 {
14159   unformat_input_t *i = vam->input;
14160   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14161   u32 sw_if_index;
14162   u8 sw_if_index_set = 0;
14163   u8 vtr_op_set = 0;
14164   u32 vtr_op = 0;
14165   u32 push_dot1q = 1;
14166   u32 tag1 = ~0;
14167   u32 tag2 = ~0;
14168   int ret;
14169
14170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14171     {
14172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14173         sw_if_index_set = 1;
14174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14175         sw_if_index_set = 1;
14176       else if (unformat (i, "vtr_op %d", &vtr_op))
14177         vtr_op_set = 1;
14178 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14179       foreach_vtr_op
14180 #undef _
14181         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14182         ;
14183       else if (unformat (i, "tag1 %d", &tag1))
14184         ;
14185       else if (unformat (i, "tag2 %d", &tag2))
14186         ;
14187       else
14188         {
14189           clib_warning ("parse error '%U'", format_unformat_error, i);
14190           return -99;
14191         }
14192     }
14193
14194   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14195     {
14196       errmsg ("missing vtr operation or sw_if_index");
14197       return -99;
14198     }
14199
14200   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14201   mp->sw_if_index = ntohl (sw_if_index);
14202   mp->vtr_op = ntohl (vtr_op);
14203   mp->push_dot1q = ntohl (push_dot1q);
14204   mp->tag1 = ntohl (tag1);
14205   mp->tag2 = ntohl (tag2);
14206
14207   S (mp);
14208   W (ret);
14209   return ret;
14210 }
14211
14212 static int
14213 api_create_vhost_user_if (vat_main_t * vam)
14214 {
14215   unformat_input_t *i = vam->input;
14216   vl_api_create_vhost_user_if_t *mp;
14217   u8 *file_name;
14218   u8 is_server = 0;
14219   u8 file_name_set = 0;
14220   u32 custom_dev_instance = ~0;
14221   u8 hwaddr[6];
14222   u8 use_custom_mac = 0;
14223   u8 disable_mrg_rxbuf = 0;
14224   u8 disable_indirect_desc = 0;
14225   u8 *tag = 0;
14226   int ret;
14227
14228   /* Shut up coverity */
14229   clib_memset (hwaddr, 0, sizeof (hwaddr));
14230
14231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14232     {
14233       if (unformat (i, "socket %s", &file_name))
14234         {
14235           file_name_set = 1;
14236         }
14237       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14238         ;
14239       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14240         use_custom_mac = 1;
14241       else if (unformat (i, "server"))
14242         is_server = 1;
14243       else if (unformat (i, "disable_mrg_rxbuf"))
14244         disable_mrg_rxbuf = 1;
14245       else if (unformat (i, "disable_indirect_desc"))
14246         disable_indirect_desc = 1;
14247       else if (unformat (i, "tag %s", &tag))
14248         ;
14249       else
14250         break;
14251     }
14252
14253   if (file_name_set == 0)
14254     {
14255       errmsg ("missing socket file name");
14256       return -99;
14257     }
14258
14259   if (vec_len (file_name) > 255)
14260     {
14261       errmsg ("socket file name too long");
14262       return -99;
14263     }
14264   vec_add1 (file_name, 0);
14265
14266   M (CREATE_VHOST_USER_IF, mp);
14267
14268   mp->is_server = is_server;
14269   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14270   mp->disable_indirect_desc = disable_indirect_desc;
14271   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14272   vec_free (file_name);
14273   if (custom_dev_instance != ~0)
14274     {
14275       mp->renumber = 1;
14276       mp->custom_dev_instance = ntohl (custom_dev_instance);
14277     }
14278
14279   mp->use_custom_mac = use_custom_mac;
14280   clib_memcpy (mp->mac_address, hwaddr, 6);
14281   if (tag)
14282     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14283   vec_free (tag);
14284
14285   S (mp);
14286   W (ret);
14287   return ret;
14288 }
14289
14290 static int
14291 api_modify_vhost_user_if (vat_main_t * vam)
14292 {
14293   unformat_input_t *i = vam->input;
14294   vl_api_modify_vhost_user_if_t *mp;
14295   u8 *file_name;
14296   u8 is_server = 0;
14297   u8 file_name_set = 0;
14298   u32 custom_dev_instance = ~0;
14299   u8 sw_if_index_set = 0;
14300   u32 sw_if_index = (u32) ~ 0;
14301   int ret;
14302
14303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14304     {
14305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14306         sw_if_index_set = 1;
14307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14308         sw_if_index_set = 1;
14309       else if (unformat (i, "socket %s", &file_name))
14310         {
14311           file_name_set = 1;
14312         }
14313       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14314         ;
14315       else if (unformat (i, "server"))
14316         is_server = 1;
14317       else
14318         break;
14319     }
14320
14321   if (sw_if_index_set == 0)
14322     {
14323       errmsg ("missing sw_if_index or interface name");
14324       return -99;
14325     }
14326
14327   if (file_name_set == 0)
14328     {
14329       errmsg ("missing socket file name");
14330       return -99;
14331     }
14332
14333   if (vec_len (file_name) > 255)
14334     {
14335       errmsg ("socket file name too long");
14336       return -99;
14337     }
14338   vec_add1 (file_name, 0);
14339
14340   M (MODIFY_VHOST_USER_IF, mp);
14341
14342   mp->sw_if_index = ntohl (sw_if_index);
14343   mp->is_server = is_server;
14344   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14345   vec_free (file_name);
14346   if (custom_dev_instance != ~0)
14347     {
14348       mp->renumber = 1;
14349       mp->custom_dev_instance = ntohl (custom_dev_instance);
14350     }
14351
14352   S (mp);
14353   W (ret);
14354   return ret;
14355 }
14356
14357 static int
14358 api_delete_vhost_user_if (vat_main_t * vam)
14359 {
14360   unformat_input_t *i = vam->input;
14361   vl_api_delete_vhost_user_if_t *mp;
14362   u32 sw_if_index = ~0;
14363   u8 sw_if_index_set = 0;
14364   int ret;
14365
14366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14367     {
14368       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14369         sw_if_index_set = 1;
14370       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14371         sw_if_index_set = 1;
14372       else
14373         break;
14374     }
14375
14376   if (sw_if_index_set == 0)
14377     {
14378       errmsg ("missing sw_if_index or interface name");
14379       return -99;
14380     }
14381
14382
14383   M (DELETE_VHOST_USER_IF, mp);
14384
14385   mp->sw_if_index = ntohl (sw_if_index);
14386
14387   S (mp);
14388   W (ret);
14389   return ret;
14390 }
14391
14392 static void vl_api_sw_interface_vhost_user_details_t_handler
14393   (vl_api_sw_interface_vhost_user_details_t * mp)
14394 {
14395   vat_main_t *vam = &vat_main;
14396
14397   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14398          (char *) mp->interface_name,
14399          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14400          clib_net_to_host_u64 (mp->features), mp->is_server,
14401          ntohl (mp->num_regions), (char *) mp->sock_filename);
14402   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14403 }
14404
14405 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14406   (vl_api_sw_interface_vhost_user_details_t * mp)
14407 {
14408   vat_main_t *vam = &vat_main;
14409   vat_json_node_t *node = NULL;
14410
14411   if (VAT_JSON_ARRAY != vam->json_tree.type)
14412     {
14413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14414       vat_json_init_array (&vam->json_tree);
14415     }
14416   node = vat_json_array_add (&vam->json_tree);
14417
14418   vat_json_init_object (node);
14419   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14420   vat_json_object_add_string_copy (node, "interface_name",
14421                                    mp->interface_name);
14422   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14423                             ntohl (mp->virtio_net_hdr_sz));
14424   vat_json_object_add_uint (node, "features",
14425                             clib_net_to_host_u64 (mp->features));
14426   vat_json_object_add_uint (node, "is_server", mp->is_server);
14427   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14428   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14429   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14430 }
14431
14432 static int
14433 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14434 {
14435   vl_api_sw_interface_vhost_user_dump_t *mp;
14436   vl_api_control_ping_t *mp_ping;
14437   int ret;
14438   print (vam->ofp,
14439          "Interface name            idx hdr_sz features server regions filename");
14440
14441   /* Get list of vhost-user interfaces */
14442   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14443   S (mp);
14444
14445   /* Use a control ping for synchronization */
14446   MPING (CONTROL_PING, mp_ping);
14447   S (mp_ping);
14448
14449   W (ret);
14450   return ret;
14451 }
14452
14453 static int
14454 api_show_version (vat_main_t * vam)
14455 {
14456   vl_api_show_version_t *mp;
14457   int ret;
14458
14459   M (SHOW_VERSION, mp);
14460
14461   S (mp);
14462   W (ret);
14463   return ret;
14464 }
14465
14466
14467 static int
14468 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14469 {
14470   unformat_input_t *line_input = vam->input;
14471   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14472   ip4_address_t local4, remote4;
14473   ip6_address_t local6, remote6;
14474   u8 is_add = 1;
14475   u8 ipv4_set = 0, ipv6_set = 0;
14476   u8 local_set = 0;
14477   u8 remote_set = 0;
14478   u8 grp_set = 0;
14479   u32 mcast_sw_if_index = ~0;
14480   u32 encap_vrf_id = 0;
14481   u32 decap_vrf_id = 0;
14482   u8 protocol = ~0;
14483   u32 vni;
14484   u8 vni_set = 0;
14485   int ret;
14486
14487   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14488   clib_memset (&local4, 0, sizeof local4);
14489   clib_memset (&remote4, 0, sizeof remote4);
14490   clib_memset (&local6, 0, sizeof local6);
14491   clib_memset (&remote6, 0, sizeof remote6);
14492
14493   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14494     {
14495       if (unformat (line_input, "del"))
14496         is_add = 0;
14497       else if (unformat (line_input, "local %U",
14498                          unformat_ip4_address, &local4))
14499         {
14500           local_set = 1;
14501           ipv4_set = 1;
14502         }
14503       else if (unformat (line_input, "remote %U",
14504                          unformat_ip4_address, &remote4))
14505         {
14506           remote_set = 1;
14507           ipv4_set = 1;
14508         }
14509       else if (unformat (line_input, "local %U",
14510                          unformat_ip6_address, &local6))
14511         {
14512           local_set = 1;
14513           ipv6_set = 1;
14514         }
14515       else if (unformat (line_input, "remote %U",
14516                          unformat_ip6_address, &remote6))
14517         {
14518           remote_set = 1;
14519           ipv6_set = 1;
14520         }
14521       else if (unformat (line_input, "group %U %U",
14522                          unformat_ip4_address, &remote4,
14523                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14524         {
14525           grp_set = remote_set = 1;
14526           ipv4_set = 1;
14527         }
14528       else if (unformat (line_input, "group %U",
14529                          unformat_ip4_address, &remote4))
14530         {
14531           grp_set = remote_set = 1;
14532           ipv4_set = 1;
14533         }
14534       else if (unformat (line_input, "group %U %U",
14535                          unformat_ip6_address, &remote6,
14536                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14537         {
14538           grp_set = remote_set = 1;
14539           ipv6_set = 1;
14540         }
14541       else if (unformat (line_input, "group %U",
14542                          unformat_ip6_address, &remote6))
14543         {
14544           grp_set = remote_set = 1;
14545           ipv6_set = 1;
14546         }
14547       else
14548         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14549         ;
14550       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14551         ;
14552       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14553         ;
14554       else if (unformat (line_input, "vni %d", &vni))
14555         vni_set = 1;
14556       else if (unformat (line_input, "next-ip4"))
14557         protocol = 1;
14558       else if (unformat (line_input, "next-ip6"))
14559         protocol = 2;
14560       else if (unformat (line_input, "next-ethernet"))
14561         protocol = 3;
14562       else if (unformat (line_input, "next-nsh"))
14563         protocol = 4;
14564       else
14565         {
14566           errmsg ("parse error '%U'", format_unformat_error, line_input);
14567           return -99;
14568         }
14569     }
14570
14571   if (local_set == 0)
14572     {
14573       errmsg ("tunnel local address not specified");
14574       return -99;
14575     }
14576   if (remote_set == 0)
14577     {
14578       errmsg ("tunnel remote address not specified");
14579       return -99;
14580     }
14581   if (grp_set && mcast_sw_if_index == ~0)
14582     {
14583       errmsg ("tunnel nonexistent multicast device");
14584       return -99;
14585     }
14586   if (ipv4_set && ipv6_set)
14587     {
14588       errmsg ("both IPv4 and IPv6 addresses specified");
14589       return -99;
14590     }
14591
14592   if (vni_set == 0)
14593     {
14594       errmsg ("vni not specified");
14595       return -99;
14596     }
14597
14598   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14599
14600
14601   if (ipv6_set)
14602     {
14603       clib_memcpy (&mp->local, &local6, sizeof (local6));
14604       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14605     }
14606   else
14607     {
14608       clib_memcpy (&mp->local, &local4, sizeof (local4));
14609       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14610     }
14611
14612   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14613   mp->encap_vrf_id = ntohl (encap_vrf_id);
14614   mp->decap_vrf_id = ntohl (decap_vrf_id);
14615   mp->protocol = protocol;
14616   mp->vni = ntohl (vni);
14617   mp->is_add = is_add;
14618   mp->is_ipv6 = ipv6_set;
14619
14620   S (mp);
14621   W (ret);
14622   return ret;
14623 }
14624
14625 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14626   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14627 {
14628   vat_main_t *vam = &vat_main;
14629   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14630   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14631
14632   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14633          ntohl (mp->sw_if_index),
14634          format_ip46_address, &local, IP46_TYPE_ANY,
14635          format_ip46_address, &remote, IP46_TYPE_ANY,
14636          ntohl (mp->vni), mp->protocol,
14637          ntohl (mp->mcast_sw_if_index),
14638          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14639 }
14640
14641
14642 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14643   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14644 {
14645   vat_main_t *vam = &vat_main;
14646   vat_json_node_t *node = NULL;
14647   struct in_addr ip4;
14648   struct in6_addr ip6;
14649
14650   if (VAT_JSON_ARRAY != vam->json_tree.type)
14651     {
14652       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14653       vat_json_init_array (&vam->json_tree);
14654     }
14655   node = vat_json_array_add (&vam->json_tree);
14656
14657   vat_json_init_object (node);
14658   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14659   if (mp->is_ipv6)
14660     {
14661       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14662       vat_json_object_add_ip6 (node, "local", ip6);
14663       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14664       vat_json_object_add_ip6 (node, "remote", ip6);
14665     }
14666   else
14667     {
14668       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14669       vat_json_object_add_ip4 (node, "local", ip4);
14670       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14671       vat_json_object_add_ip4 (node, "remote", ip4);
14672     }
14673   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14674   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14675   vat_json_object_add_uint (node, "mcast_sw_if_index",
14676                             ntohl (mp->mcast_sw_if_index));
14677   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14678   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14679   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14680 }
14681
14682 static int
14683 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14684 {
14685   unformat_input_t *i = vam->input;
14686   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14687   vl_api_control_ping_t *mp_ping;
14688   u32 sw_if_index;
14689   u8 sw_if_index_set = 0;
14690   int ret;
14691
14692   /* Parse args required to build the message */
14693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14694     {
14695       if (unformat (i, "sw_if_index %d", &sw_if_index))
14696         sw_if_index_set = 1;
14697       else
14698         break;
14699     }
14700
14701   if (sw_if_index_set == 0)
14702     {
14703       sw_if_index = ~0;
14704     }
14705
14706   if (!vam->json_output)
14707     {
14708       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14709              "sw_if_index", "local", "remote", "vni",
14710              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14711     }
14712
14713   /* Get list of vxlan-tunnel interfaces */
14714   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14715
14716   mp->sw_if_index = htonl (sw_if_index);
14717
14718   S (mp);
14719
14720   /* Use a control ping for synchronization */
14721   MPING (CONTROL_PING, mp_ping);
14722   S (mp_ping);
14723
14724   W (ret);
14725   return ret;
14726 }
14727
14728 static void vl_api_l2_fib_table_details_t_handler
14729   (vl_api_l2_fib_table_details_t * mp)
14730 {
14731   vat_main_t *vam = &vat_main;
14732
14733   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14734          "       %d       %d     %d",
14735          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14736          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14737          mp->bvi_mac);
14738 }
14739
14740 static void vl_api_l2_fib_table_details_t_handler_json
14741   (vl_api_l2_fib_table_details_t * mp)
14742 {
14743   vat_main_t *vam = &vat_main;
14744   vat_json_node_t *node = NULL;
14745
14746   if (VAT_JSON_ARRAY != vam->json_tree.type)
14747     {
14748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14749       vat_json_init_array (&vam->json_tree);
14750     }
14751   node = vat_json_array_add (&vam->json_tree);
14752
14753   vat_json_init_object (node);
14754   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14755   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14756   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14757   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14758   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14759   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14760 }
14761
14762 static int
14763 api_l2_fib_table_dump (vat_main_t * vam)
14764 {
14765   unformat_input_t *i = vam->input;
14766   vl_api_l2_fib_table_dump_t *mp;
14767   vl_api_control_ping_t *mp_ping;
14768   u32 bd_id;
14769   u8 bd_id_set = 0;
14770   int ret;
14771
14772   /* Parse args required to build the message */
14773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14774     {
14775       if (unformat (i, "bd_id %d", &bd_id))
14776         bd_id_set = 1;
14777       else
14778         break;
14779     }
14780
14781   if (bd_id_set == 0)
14782     {
14783       errmsg ("missing bridge domain");
14784       return -99;
14785     }
14786
14787   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14788
14789   /* Get list of l2 fib entries */
14790   M (L2_FIB_TABLE_DUMP, mp);
14791
14792   mp->bd_id = ntohl (bd_id);
14793   S (mp);
14794
14795   /* Use a control ping for synchronization */
14796   MPING (CONTROL_PING, mp_ping);
14797   S (mp_ping);
14798
14799   W (ret);
14800   return ret;
14801 }
14802
14803
14804 static int
14805 api_interface_name_renumber (vat_main_t * vam)
14806 {
14807   unformat_input_t *line_input = vam->input;
14808   vl_api_interface_name_renumber_t *mp;
14809   u32 sw_if_index = ~0;
14810   u32 new_show_dev_instance = ~0;
14811   int ret;
14812
14813   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14814     {
14815       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14816                     &sw_if_index))
14817         ;
14818       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14819         ;
14820       else if (unformat (line_input, "new_show_dev_instance %d",
14821                          &new_show_dev_instance))
14822         ;
14823       else
14824         break;
14825     }
14826
14827   if (sw_if_index == ~0)
14828     {
14829       errmsg ("missing interface name or sw_if_index");
14830       return -99;
14831     }
14832
14833   if (new_show_dev_instance == ~0)
14834     {
14835       errmsg ("missing new_show_dev_instance");
14836       return -99;
14837     }
14838
14839   M (INTERFACE_NAME_RENUMBER, mp);
14840
14841   mp->sw_if_index = ntohl (sw_if_index);
14842   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14843
14844   S (mp);
14845   W (ret);
14846   return ret;
14847 }
14848
14849 static int
14850 api_ip_probe_neighbor (vat_main_t * vam)
14851 {
14852   unformat_input_t *i = vam->input;
14853   vl_api_ip_probe_neighbor_t *mp;
14854   u8 int_set = 0;
14855   u8 adr_set = 0;
14856   u8 is_ipv6 = 0;
14857   u8 dst_adr[16];
14858   u32 sw_if_index;
14859   int ret;
14860
14861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14862     {
14863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14864         int_set = 1;
14865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14866         int_set = 1;
14867       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14868         adr_set = 1;
14869       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14870         {
14871           adr_set = 1;
14872           is_ipv6 = 1;
14873         }
14874       else
14875         break;
14876     }
14877
14878   if (int_set == 0)
14879     {
14880       errmsg ("missing interface");
14881       return -99;
14882     }
14883
14884   if (adr_set == 0)
14885     {
14886       errmsg ("missing addresses");
14887       return -99;
14888     }
14889
14890   M (IP_PROBE_NEIGHBOR, mp);
14891
14892   mp->sw_if_index = ntohl (sw_if_index);
14893   mp->is_ipv6 = is_ipv6;
14894   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14895
14896   S (mp);
14897   W (ret);
14898   return ret;
14899 }
14900
14901 static int
14902 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14903 {
14904   unformat_input_t *i = vam->input;
14905   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14906   u8 mode = IP_SCAN_V46_NEIGHBORS;
14907   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14908   int ret;
14909
14910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14911     {
14912       if (unformat (i, "ip4"))
14913         mode = IP_SCAN_V4_NEIGHBORS;
14914       else if (unformat (i, "ip6"))
14915         mode = IP_SCAN_V6_NEIGHBORS;
14916       if (unformat (i, "both"))
14917         mode = IP_SCAN_V46_NEIGHBORS;
14918       else if (unformat (i, "disable"))
14919         mode = IP_SCAN_DISABLED;
14920       else if (unformat (i, "interval %d", &interval))
14921         ;
14922       else if (unformat (i, "max-time %d", &time))
14923         ;
14924       else if (unformat (i, "max-update %d", &update))
14925         ;
14926       else if (unformat (i, "delay %d", &delay))
14927         ;
14928       else if (unformat (i, "stale %d", &stale))
14929         ;
14930       else
14931         break;
14932     }
14933
14934   if (interval > 255)
14935     {
14936       errmsg ("interval cannot exceed 255 minutes.");
14937       return -99;
14938     }
14939   if (time > 255)
14940     {
14941       errmsg ("max-time cannot exceed 255 usec.");
14942       return -99;
14943     }
14944   if (update > 255)
14945     {
14946       errmsg ("max-update cannot exceed 255.");
14947       return -99;
14948     }
14949   if (delay > 255)
14950     {
14951       errmsg ("delay cannot exceed 255 msec.");
14952       return -99;
14953     }
14954   if (stale > 255)
14955     {
14956       errmsg ("stale cannot exceed 255 minutes.");
14957       return -99;
14958     }
14959
14960   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14961   mp->mode = mode;
14962   mp->scan_interval = interval;
14963   mp->max_proc_time = time;
14964   mp->max_update = update;
14965   mp->scan_int_delay = delay;
14966   mp->stale_threshold = stale;
14967
14968   S (mp);
14969   W (ret);
14970   return ret;
14971 }
14972
14973 static int
14974 api_want_ip4_arp_events (vat_main_t * vam)
14975 {
14976   unformat_input_t *line_input = vam->input;
14977   vl_api_want_ip4_arp_events_t *mp;
14978   ip4_address_t address;
14979   int address_set = 0;
14980   u32 enable_disable = 1;
14981   int ret;
14982
14983   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14984     {
14985       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14986         address_set = 1;
14987       else if (unformat (line_input, "del"))
14988         enable_disable = 0;
14989       else
14990         break;
14991     }
14992
14993   if (address_set == 0)
14994     {
14995       errmsg ("missing addresses");
14996       return -99;
14997     }
14998
14999   M (WANT_IP4_ARP_EVENTS, mp);
15000   mp->enable_disable = enable_disable;
15001   mp->pid = htonl (getpid ());
15002   mp->address = address.as_u32;
15003
15004   S (mp);
15005   W (ret);
15006   return ret;
15007 }
15008
15009 static int
15010 api_want_ip6_nd_events (vat_main_t * vam)
15011 {
15012   unformat_input_t *line_input = vam->input;
15013   vl_api_want_ip6_nd_events_t *mp;
15014   ip6_address_t address;
15015   int address_set = 0;
15016   u32 enable_disable = 1;
15017   int ret;
15018
15019   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15020     {
15021       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
15022         address_set = 1;
15023       else if (unformat (line_input, "del"))
15024         enable_disable = 0;
15025       else
15026         break;
15027     }
15028
15029   if (address_set == 0)
15030     {
15031       errmsg ("missing addresses");
15032       return -99;
15033     }
15034
15035   M (WANT_IP6_ND_EVENTS, mp);
15036   mp->enable_disable = enable_disable;
15037   mp->pid = htonl (getpid ());
15038   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
15039
15040   S (mp);
15041   W (ret);
15042   return ret;
15043 }
15044
15045 static int
15046 api_want_l2_macs_events (vat_main_t * vam)
15047 {
15048   unformat_input_t *line_input = vam->input;
15049   vl_api_want_l2_macs_events_t *mp;
15050   u8 enable_disable = 1;
15051   u32 scan_delay = 0;
15052   u32 max_macs_in_event = 0;
15053   u32 learn_limit = 0;
15054   int ret;
15055
15056   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15057     {
15058       if (unformat (line_input, "learn-limit %d", &learn_limit))
15059         ;
15060       else if (unformat (line_input, "scan-delay %d", &scan_delay))
15061         ;
15062       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
15063         ;
15064       else if (unformat (line_input, "disable"))
15065         enable_disable = 0;
15066       else
15067         break;
15068     }
15069
15070   M (WANT_L2_MACS_EVENTS, mp);
15071   mp->enable_disable = enable_disable;
15072   mp->pid = htonl (getpid ());
15073   mp->learn_limit = htonl (learn_limit);
15074   mp->scan_delay = (u8) scan_delay;
15075   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15076   S (mp);
15077   W (ret);
15078   return ret;
15079 }
15080
15081 static int
15082 api_input_acl_set_interface (vat_main_t * vam)
15083 {
15084   unformat_input_t *i = vam->input;
15085   vl_api_input_acl_set_interface_t *mp;
15086   u32 sw_if_index;
15087   int sw_if_index_set;
15088   u32 ip4_table_index = ~0;
15089   u32 ip6_table_index = ~0;
15090   u32 l2_table_index = ~0;
15091   u8 is_add = 1;
15092   int ret;
15093
15094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15095     {
15096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15097         sw_if_index_set = 1;
15098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15099         sw_if_index_set = 1;
15100       else if (unformat (i, "del"))
15101         is_add = 0;
15102       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15103         ;
15104       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15105         ;
15106       else if (unformat (i, "l2-table %d", &l2_table_index))
15107         ;
15108       else
15109         {
15110           clib_warning ("parse error '%U'", format_unformat_error, i);
15111           return -99;
15112         }
15113     }
15114
15115   if (sw_if_index_set == 0)
15116     {
15117       errmsg ("missing interface name or sw_if_index");
15118       return -99;
15119     }
15120
15121   M (INPUT_ACL_SET_INTERFACE, mp);
15122
15123   mp->sw_if_index = ntohl (sw_if_index);
15124   mp->ip4_table_index = ntohl (ip4_table_index);
15125   mp->ip6_table_index = ntohl (ip6_table_index);
15126   mp->l2_table_index = ntohl (l2_table_index);
15127   mp->is_add = is_add;
15128
15129   S (mp);
15130   W (ret);
15131   return ret;
15132 }
15133
15134 static int
15135 api_output_acl_set_interface (vat_main_t * vam)
15136 {
15137   unformat_input_t *i = vam->input;
15138   vl_api_output_acl_set_interface_t *mp;
15139   u32 sw_if_index;
15140   int sw_if_index_set;
15141   u32 ip4_table_index = ~0;
15142   u32 ip6_table_index = ~0;
15143   u32 l2_table_index = ~0;
15144   u8 is_add = 1;
15145   int ret;
15146
15147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15148     {
15149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15150         sw_if_index_set = 1;
15151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15152         sw_if_index_set = 1;
15153       else if (unformat (i, "del"))
15154         is_add = 0;
15155       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15156         ;
15157       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15158         ;
15159       else if (unformat (i, "l2-table %d", &l2_table_index))
15160         ;
15161       else
15162         {
15163           clib_warning ("parse error '%U'", format_unformat_error, i);
15164           return -99;
15165         }
15166     }
15167
15168   if (sw_if_index_set == 0)
15169     {
15170       errmsg ("missing interface name or sw_if_index");
15171       return -99;
15172     }
15173
15174   M (OUTPUT_ACL_SET_INTERFACE, mp);
15175
15176   mp->sw_if_index = ntohl (sw_if_index);
15177   mp->ip4_table_index = ntohl (ip4_table_index);
15178   mp->ip6_table_index = ntohl (ip6_table_index);
15179   mp->l2_table_index = ntohl (l2_table_index);
15180   mp->is_add = is_add;
15181
15182   S (mp);
15183   W (ret);
15184   return ret;
15185 }
15186
15187 static int
15188 api_ip_address_dump (vat_main_t * vam)
15189 {
15190   unformat_input_t *i = vam->input;
15191   vl_api_ip_address_dump_t *mp;
15192   vl_api_control_ping_t *mp_ping;
15193   u32 sw_if_index = ~0;
15194   u8 sw_if_index_set = 0;
15195   u8 ipv4_set = 0;
15196   u8 ipv6_set = 0;
15197   int ret;
15198
15199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15200     {
15201       if (unformat (i, "sw_if_index %d", &sw_if_index))
15202         sw_if_index_set = 1;
15203       else
15204         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15205         sw_if_index_set = 1;
15206       else if (unformat (i, "ipv4"))
15207         ipv4_set = 1;
15208       else if (unformat (i, "ipv6"))
15209         ipv6_set = 1;
15210       else
15211         break;
15212     }
15213
15214   if (ipv4_set && ipv6_set)
15215     {
15216       errmsg ("ipv4 and ipv6 flags cannot be both set");
15217       return -99;
15218     }
15219
15220   if ((!ipv4_set) && (!ipv6_set))
15221     {
15222       errmsg ("no ipv4 nor ipv6 flag set");
15223       return -99;
15224     }
15225
15226   if (sw_if_index_set == 0)
15227     {
15228       errmsg ("missing interface name or sw_if_index");
15229       return -99;
15230     }
15231
15232   vam->current_sw_if_index = sw_if_index;
15233   vam->is_ipv6 = ipv6_set;
15234
15235   M (IP_ADDRESS_DUMP, mp);
15236   mp->sw_if_index = ntohl (sw_if_index);
15237   mp->is_ipv6 = ipv6_set;
15238   S (mp);
15239
15240   /* Use a control ping for synchronization */
15241   MPING (CONTROL_PING, mp_ping);
15242   S (mp_ping);
15243
15244   W (ret);
15245   return ret;
15246 }
15247
15248 static int
15249 api_ip_dump (vat_main_t * vam)
15250 {
15251   vl_api_ip_dump_t *mp;
15252   vl_api_control_ping_t *mp_ping;
15253   unformat_input_t *in = vam->input;
15254   int ipv4_set = 0;
15255   int ipv6_set = 0;
15256   int is_ipv6;
15257   int i;
15258   int ret;
15259
15260   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15261     {
15262       if (unformat (in, "ipv4"))
15263         ipv4_set = 1;
15264       else if (unformat (in, "ipv6"))
15265         ipv6_set = 1;
15266       else
15267         break;
15268     }
15269
15270   if (ipv4_set && ipv6_set)
15271     {
15272       errmsg ("ipv4 and ipv6 flags cannot be both set");
15273       return -99;
15274     }
15275
15276   if ((!ipv4_set) && (!ipv6_set))
15277     {
15278       errmsg ("no ipv4 nor ipv6 flag set");
15279       return -99;
15280     }
15281
15282   is_ipv6 = ipv6_set;
15283   vam->is_ipv6 = is_ipv6;
15284
15285   /* free old data */
15286   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15287     {
15288       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15289     }
15290   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15291
15292   M (IP_DUMP, mp);
15293   mp->is_ipv6 = ipv6_set;
15294   S (mp);
15295
15296   /* Use a control ping for synchronization */
15297   MPING (CONTROL_PING, mp_ping);
15298   S (mp_ping);
15299
15300   W (ret);
15301   return ret;
15302 }
15303
15304 static int
15305 api_ipsec_spd_add_del (vat_main_t * vam)
15306 {
15307   unformat_input_t *i = vam->input;
15308   vl_api_ipsec_spd_add_del_t *mp;
15309   u32 spd_id = ~0;
15310   u8 is_add = 1;
15311   int ret;
15312
15313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15314     {
15315       if (unformat (i, "spd_id %d", &spd_id))
15316         ;
15317       else if (unformat (i, "del"))
15318         is_add = 0;
15319       else
15320         {
15321           clib_warning ("parse error '%U'", format_unformat_error, i);
15322           return -99;
15323         }
15324     }
15325   if (spd_id == ~0)
15326     {
15327       errmsg ("spd_id must be set");
15328       return -99;
15329     }
15330
15331   M (IPSEC_SPD_ADD_DEL, mp);
15332
15333   mp->spd_id = ntohl (spd_id);
15334   mp->is_add = is_add;
15335
15336   S (mp);
15337   W (ret);
15338   return ret;
15339 }
15340
15341 static int
15342 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15343 {
15344   unformat_input_t *i = vam->input;
15345   vl_api_ipsec_interface_add_del_spd_t *mp;
15346   u32 sw_if_index;
15347   u8 sw_if_index_set = 0;
15348   u32 spd_id = (u32) ~ 0;
15349   u8 is_add = 1;
15350   int ret;
15351
15352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15353     {
15354       if (unformat (i, "del"))
15355         is_add = 0;
15356       else if (unformat (i, "spd_id %d", &spd_id))
15357         ;
15358       else
15359         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15360         sw_if_index_set = 1;
15361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15362         sw_if_index_set = 1;
15363       else
15364         {
15365           clib_warning ("parse error '%U'", format_unformat_error, i);
15366           return -99;
15367         }
15368
15369     }
15370
15371   if (spd_id == (u32) ~ 0)
15372     {
15373       errmsg ("spd_id must be set");
15374       return -99;
15375     }
15376
15377   if (sw_if_index_set == 0)
15378     {
15379       errmsg ("missing interface name or sw_if_index");
15380       return -99;
15381     }
15382
15383   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15384
15385   mp->spd_id = ntohl (spd_id);
15386   mp->sw_if_index = ntohl (sw_if_index);
15387   mp->is_add = is_add;
15388
15389   S (mp);
15390   W (ret);
15391   return ret;
15392 }
15393
15394 static int
15395 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15396 {
15397   unformat_input_t *i = vam->input;
15398   vl_api_ipsec_spd_add_del_entry_t *mp;
15399   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15400   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15401   i32 priority = 0;
15402   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15403   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15404   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15405   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15406   int ret;
15407
15408   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15409   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15410   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15411   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15412   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15413   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15414
15415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15416     {
15417       if (unformat (i, "del"))
15418         is_add = 0;
15419       if (unformat (i, "outbound"))
15420         is_outbound = 1;
15421       if (unformat (i, "inbound"))
15422         is_outbound = 0;
15423       else if (unformat (i, "spd_id %d", &spd_id))
15424         ;
15425       else if (unformat (i, "sa_id %d", &sa_id))
15426         ;
15427       else if (unformat (i, "priority %d", &priority))
15428         ;
15429       else if (unformat (i, "protocol %d", &protocol))
15430         ;
15431       else if (unformat (i, "lport_start %d", &lport_start))
15432         ;
15433       else if (unformat (i, "lport_stop %d", &lport_stop))
15434         ;
15435       else if (unformat (i, "rport_start %d", &rport_start))
15436         ;
15437       else if (unformat (i, "rport_stop %d", &rport_stop))
15438         ;
15439       else
15440         if (unformat
15441             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15442         {
15443           is_ipv6 = 0;
15444           is_ip_any = 0;
15445         }
15446       else
15447         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15448         {
15449           is_ipv6 = 0;
15450           is_ip_any = 0;
15451         }
15452       else
15453         if (unformat
15454             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15455         {
15456           is_ipv6 = 0;
15457           is_ip_any = 0;
15458         }
15459       else
15460         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15461         {
15462           is_ipv6 = 0;
15463           is_ip_any = 0;
15464         }
15465       else
15466         if (unformat
15467             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15468         {
15469           is_ipv6 = 1;
15470           is_ip_any = 0;
15471         }
15472       else
15473         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15474         {
15475           is_ipv6 = 1;
15476           is_ip_any = 0;
15477         }
15478       else
15479         if (unformat
15480             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15481         {
15482           is_ipv6 = 1;
15483           is_ip_any = 0;
15484         }
15485       else
15486         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15487         {
15488           is_ipv6 = 1;
15489           is_ip_any = 0;
15490         }
15491       else
15492         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15493         {
15494           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15495             {
15496               clib_warning ("unsupported action: 'resolve'");
15497               return -99;
15498             }
15499         }
15500       else
15501         {
15502           clib_warning ("parse error '%U'", format_unformat_error, i);
15503           return -99;
15504         }
15505
15506     }
15507
15508   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15509
15510   mp->spd_id = ntohl (spd_id);
15511   mp->priority = ntohl (priority);
15512   mp->is_outbound = is_outbound;
15513
15514   mp->is_ipv6 = is_ipv6;
15515   if (is_ipv6 || is_ip_any)
15516     {
15517       clib_memcpy (mp->remote_address_start, &raddr6_start,
15518                    sizeof (ip6_address_t));
15519       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15520                    sizeof (ip6_address_t));
15521       clib_memcpy (mp->local_address_start, &laddr6_start,
15522                    sizeof (ip6_address_t));
15523       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15524                    sizeof (ip6_address_t));
15525     }
15526   else
15527     {
15528       clib_memcpy (mp->remote_address_start, &raddr4_start,
15529                    sizeof (ip4_address_t));
15530       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15531                    sizeof (ip4_address_t));
15532       clib_memcpy (mp->local_address_start, &laddr4_start,
15533                    sizeof (ip4_address_t));
15534       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15535                    sizeof (ip4_address_t));
15536     }
15537   mp->protocol = (u8) protocol;
15538   mp->local_port_start = ntohs ((u16) lport_start);
15539   mp->local_port_stop = ntohs ((u16) lport_stop);
15540   mp->remote_port_start = ntohs ((u16) rport_start);
15541   mp->remote_port_stop = ntohs ((u16) rport_stop);
15542   mp->policy = (u8) policy;
15543   mp->sa_id = ntohl (sa_id);
15544   mp->is_add = is_add;
15545   mp->is_ip_any = is_ip_any;
15546   S (mp);
15547   W (ret);
15548   return ret;
15549 }
15550
15551 static int
15552 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15553 {
15554   unformat_input_t *i = vam->input;
15555   vl_api_ipsec_sad_add_del_entry_t *mp;
15556   u32 sad_id = 0, spi = 0;
15557   u8 *ck = 0, *ik = 0;
15558   u8 is_add = 1;
15559
15560   u8 protocol = IPSEC_PROTOCOL_AH;
15561   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15562   u32 crypto_alg = 0, integ_alg = 0;
15563   ip4_address_t tun_src4;
15564   ip4_address_t tun_dst4;
15565   ip6_address_t tun_src6;
15566   ip6_address_t tun_dst6;
15567   int ret;
15568
15569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15570     {
15571       if (unformat (i, "del"))
15572         is_add = 0;
15573       else if (unformat (i, "sad_id %d", &sad_id))
15574         ;
15575       else if (unformat (i, "spi %d", &spi))
15576         ;
15577       else if (unformat (i, "esp"))
15578         protocol = IPSEC_PROTOCOL_ESP;
15579       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15580         {
15581           is_tunnel = 1;
15582           is_tunnel_ipv6 = 0;
15583         }
15584       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15585         {
15586           is_tunnel = 1;
15587           is_tunnel_ipv6 = 0;
15588         }
15589       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15590         {
15591           is_tunnel = 1;
15592           is_tunnel_ipv6 = 1;
15593         }
15594       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15595         {
15596           is_tunnel = 1;
15597           is_tunnel_ipv6 = 1;
15598         }
15599       else
15600         if (unformat
15601             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15602         {
15603           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15604             {
15605               clib_warning ("unsupported crypto-alg: '%U'",
15606                             format_ipsec_crypto_alg, crypto_alg);
15607               return -99;
15608             }
15609         }
15610       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15611         ;
15612       else
15613         if (unformat
15614             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15615         {
15616           if (integ_alg >= IPSEC_INTEG_N_ALG)
15617             {
15618               clib_warning ("unsupported integ-alg: '%U'",
15619                             format_ipsec_integ_alg, integ_alg);
15620               return -99;
15621             }
15622         }
15623       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15624         ;
15625       else
15626         {
15627           clib_warning ("parse error '%U'", format_unformat_error, i);
15628           return -99;
15629         }
15630
15631     }
15632
15633   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15634
15635   mp->sad_id = ntohl (sad_id);
15636   mp->is_add = is_add;
15637   mp->protocol = protocol;
15638   mp->spi = ntohl (spi);
15639   mp->is_tunnel = is_tunnel;
15640   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15641   mp->crypto_algorithm = crypto_alg;
15642   mp->integrity_algorithm = integ_alg;
15643   mp->crypto_key_length = vec_len (ck);
15644   mp->integrity_key_length = vec_len (ik);
15645
15646   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15647     mp->crypto_key_length = sizeof (mp->crypto_key);
15648
15649   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15650     mp->integrity_key_length = sizeof (mp->integrity_key);
15651
15652   if (ck)
15653     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15654   if (ik)
15655     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15656
15657   if (is_tunnel)
15658     {
15659       if (is_tunnel_ipv6)
15660         {
15661           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15662                        sizeof (ip6_address_t));
15663           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15664                        sizeof (ip6_address_t));
15665         }
15666       else
15667         {
15668           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15669                        sizeof (ip4_address_t));
15670           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15671                        sizeof (ip4_address_t));
15672         }
15673     }
15674
15675   S (mp);
15676   W (ret);
15677   return ret;
15678 }
15679
15680 static int
15681 api_ipsec_sa_set_key (vat_main_t * vam)
15682 {
15683   unformat_input_t *i = vam->input;
15684   vl_api_ipsec_sa_set_key_t *mp;
15685   u32 sa_id;
15686   u8 *ck = 0, *ik = 0;
15687   int ret;
15688
15689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15690     {
15691       if (unformat (i, "sa_id %d", &sa_id))
15692         ;
15693       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15694         ;
15695       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15696         ;
15697       else
15698         {
15699           clib_warning ("parse error '%U'", format_unformat_error, i);
15700           return -99;
15701         }
15702     }
15703
15704   M (IPSEC_SA_SET_KEY, mp);
15705
15706   mp->sa_id = ntohl (sa_id);
15707   mp->crypto_key_length = vec_len (ck);
15708   mp->integrity_key_length = vec_len (ik);
15709
15710   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15711     mp->crypto_key_length = sizeof (mp->crypto_key);
15712
15713   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15714     mp->integrity_key_length = sizeof (mp->integrity_key);
15715
15716   if (ck)
15717     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15718   if (ik)
15719     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15720
15721   S (mp);
15722   W (ret);
15723   return ret;
15724 }
15725
15726 static int
15727 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15728 {
15729   unformat_input_t *i = vam->input;
15730   vl_api_ipsec_tunnel_if_add_del_t *mp;
15731   u32 local_spi = 0, remote_spi = 0;
15732   u32 crypto_alg = 0, integ_alg = 0;
15733   u8 *lck = NULL, *rck = NULL;
15734   u8 *lik = NULL, *rik = NULL;
15735   ip4_address_t local_ip = { {0} };
15736   ip4_address_t remote_ip = { {0} };
15737   u8 is_add = 1;
15738   u8 esn = 0;
15739   u8 anti_replay = 0;
15740   u8 renumber = 0;
15741   u32 instance = ~0;
15742   int ret;
15743
15744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15745     {
15746       if (unformat (i, "del"))
15747         is_add = 0;
15748       else if (unformat (i, "esn"))
15749         esn = 1;
15750       else if (unformat (i, "anti_replay"))
15751         anti_replay = 1;
15752       else if (unformat (i, "local_spi %d", &local_spi))
15753         ;
15754       else if (unformat (i, "remote_spi %d", &remote_spi))
15755         ;
15756       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15757         ;
15758       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15759         ;
15760       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15761         ;
15762       else
15763         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15764         ;
15765       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15766         ;
15767       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15768         ;
15769       else
15770         if (unformat
15771             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15772         {
15773           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15774             {
15775               errmsg ("unsupported crypto-alg: '%U'\n",
15776                       format_ipsec_crypto_alg, crypto_alg);
15777               return -99;
15778             }
15779         }
15780       else
15781         if (unformat
15782             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15783         {
15784           if (integ_alg >= IPSEC_INTEG_N_ALG)
15785             {
15786               errmsg ("unsupported integ-alg: '%U'\n",
15787                       format_ipsec_integ_alg, integ_alg);
15788               return -99;
15789             }
15790         }
15791       else if (unformat (i, "instance %u", &instance))
15792         renumber = 1;
15793       else
15794         {
15795           errmsg ("parse error '%U'\n", format_unformat_error, i);
15796           return -99;
15797         }
15798     }
15799
15800   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15801
15802   mp->is_add = is_add;
15803   mp->esn = esn;
15804   mp->anti_replay = anti_replay;
15805
15806   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15807   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15808
15809   mp->local_spi = htonl (local_spi);
15810   mp->remote_spi = htonl (remote_spi);
15811   mp->crypto_alg = (u8) crypto_alg;
15812
15813   mp->local_crypto_key_len = 0;
15814   if (lck)
15815     {
15816       mp->local_crypto_key_len = vec_len (lck);
15817       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15818         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15819       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15820     }
15821
15822   mp->remote_crypto_key_len = 0;
15823   if (rck)
15824     {
15825       mp->remote_crypto_key_len = vec_len (rck);
15826       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15827         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15828       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15829     }
15830
15831   mp->integ_alg = (u8) integ_alg;
15832
15833   mp->local_integ_key_len = 0;
15834   if (lik)
15835     {
15836       mp->local_integ_key_len = vec_len (lik);
15837       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15838         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15839       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15840     }
15841
15842   mp->remote_integ_key_len = 0;
15843   if (rik)
15844     {
15845       mp->remote_integ_key_len = vec_len (rik);
15846       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15847         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15848       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15849     }
15850
15851   if (renumber)
15852     {
15853       mp->renumber = renumber;
15854       mp->show_instance = ntohl (instance);
15855     }
15856
15857   S (mp);
15858   W (ret);
15859   return ret;
15860 }
15861
15862 static void
15863 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15864 {
15865   vat_main_t *vam = &vat_main;
15866
15867   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15868          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15869          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15870          "tunnel_src_addr %U tunnel_dst_addr %U "
15871          "salt %u seq_outbound %lu last_seq_inbound %lu "
15872          "replay_window %lu total_data_size %lu\n",
15873          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15874          mp->protocol,
15875          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15876          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15877          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15878          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15879          mp->tunnel_src_addr,
15880          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15881          mp->tunnel_dst_addr,
15882          ntohl (mp->salt),
15883          clib_net_to_host_u64 (mp->seq_outbound),
15884          clib_net_to_host_u64 (mp->last_seq_inbound),
15885          clib_net_to_host_u64 (mp->replay_window),
15886          clib_net_to_host_u64 (mp->total_data_size));
15887 }
15888
15889 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15890 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15891
15892 static void vl_api_ipsec_sa_details_t_handler_json
15893   (vl_api_ipsec_sa_details_t * mp)
15894 {
15895   vat_main_t *vam = &vat_main;
15896   vat_json_node_t *node = NULL;
15897   struct in_addr src_ip4, dst_ip4;
15898   struct in6_addr src_ip6, dst_ip6;
15899
15900   if (VAT_JSON_ARRAY != vam->json_tree.type)
15901     {
15902       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15903       vat_json_init_array (&vam->json_tree);
15904     }
15905   node = vat_json_array_add (&vam->json_tree);
15906
15907   vat_json_init_object (node);
15908   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15909   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15910   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15911   vat_json_object_add_uint (node, "proto", mp->protocol);
15912   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15913   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15914   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15915   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15916   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15917   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15918   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15919                              mp->crypto_key_len);
15920   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15921                              mp->integ_key_len);
15922   if (mp->is_tunnel_ip6)
15923     {
15924       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15925       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15926       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15927       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15928     }
15929   else
15930     {
15931       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15932       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15933       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15934       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15935     }
15936   vat_json_object_add_uint (node, "replay_window",
15937                             clib_net_to_host_u64 (mp->replay_window));
15938   vat_json_object_add_uint (node, "total_data_size",
15939                             clib_net_to_host_u64 (mp->total_data_size));
15940
15941 }
15942
15943 static int
15944 api_ipsec_sa_dump (vat_main_t * vam)
15945 {
15946   unformat_input_t *i = vam->input;
15947   vl_api_ipsec_sa_dump_t *mp;
15948   vl_api_control_ping_t *mp_ping;
15949   u32 sa_id = ~0;
15950   int ret;
15951
15952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15953     {
15954       if (unformat (i, "sa_id %d", &sa_id))
15955         ;
15956       else
15957         {
15958           clib_warning ("parse error '%U'", format_unformat_error, i);
15959           return -99;
15960         }
15961     }
15962
15963   M (IPSEC_SA_DUMP, mp);
15964
15965   mp->sa_id = ntohl (sa_id);
15966
15967   S (mp);
15968
15969   /* Use a control ping for synchronization */
15970   M (CONTROL_PING, mp_ping);
15971   S (mp_ping);
15972
15973   W (ret);
15974   return ret;
15975 }
15976
15977 static int
15978 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15979 {
15980   unformat_input_t *i = vam->input;
15981   vl_api_ipsec_tunnel_if_set_key_t *mp;
15982   u32 sw_if_index = ~0;
15983   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15984   u8 *key = 0;
15985   u32 alg = ~0;
15986   int ret;
15987
15988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15989     {
15990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15991         ;
15992       else
15993         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15994         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15995       else
15996         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15997         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15998       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15999         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
16000       else
16001         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
16002         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
16003       else if (unformat (i, "%U", unformat_hex_string, &key))
16004         ;
16005       else
16006         {
16007           clib_warning ("parse error '%U'", format_unformat_error, i);
16008           return -99;
16009         }
16010     }
16011
16012   if (sw_if_index == ~0)
16013     {
16014       errmsg ("interface must be specified");
16015       return -99;
16016     }
16017
16018   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
16019     {
16020       errmsg ("key type must be specified");
16021       return -99;
16022     }
16023
16024   if (alg == ~0)
16025     {
16026       errmsg ("algorithm must be specified");
16027       return -99;
16028     }
16029
16030   if (vec_len (key) == 0)
16031     {
16032       errmsg ("key must be specified");
16033       return -99;
16034     }
16035
16036   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
16037
16038   mp->sw_if_index = htonl (sw_if_index);
16039   mp->alg = alg;
16040   mp->key_type = key_type;
16041   mp->key_len = vec_len (key);
16042   clib_memcpy (mp->key, key, vec_len (key));
16043
16044   S (mp);
16045   W (ret);
16046
16047   return ret;
16048 }
16049
16050 static int
16051 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
16052 {
16053   unformat_input_t *i = vam->input;
16054   vl_api_ipsec_tunnel_if_set_sa_t *mp;
16055   u32 sw_if_index = ~0;
16056   u32 sa_id = ~0;
16057   u8 is_outbound = (u8) ~ 0;
16058   int ret;
16059
16060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16061     {
16062       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16063         ;
16064       else if (unformat (i, "sa_id %d", &sa_id))
16065         ;
16066       else if (unformat (i, "outbound"))
16067         is_outbound = 1;
16068       else if (unformat (i, "inbound"))
16069         is_outbound = 0;
16070       else
16071         {
16072           clib_warning ("parse error '%U'", format_unformat_error, i);
16073           return -99;
16074         }
16075     }
16076
16077   if (sw_if_index == ~0)
16078     {
16079       errmsg ("interface must be specified");
16080       return -99;
16081     }
16082
16083   if (sa_id == ~0)
16084     {
16085       errmsg ("SA ID must be specified");
16086       return -99;
16087     }
16088
16089   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16090
16091   mp->sw_if_index = htonl (sw_if_index);
16092   mp->sa_id = htonl (sa_id);
16093   mp->is_outbound = is_outbound;
16094
16095   S (mp);
16096   W (ret);
16097
16098   return ret;
16099 }
16100
16101 static int
16102 api_ikev2_profile_add_del (vat_main_t * vam)
16103 {
16104   unformat_input_t *i = vam->input;
16105   vl_api_ikev2_profile_add_del_t *mp;
16106   u8 is_add = 1;
16107   u8 *name = 0;
16108   int ret;
16109
16110   const char *valid_chars = "a-zA-Z0-9_";
16111
16112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16113     {
16114       if (unformat (i, "del"))
16115         is_add = 0;
16116       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16117         vec_add1 (name, 0);
16118       else
16119         {
16120           errmsg ("parse error '%U'", format_unformat_error, i);
16121           return -99;
16122         }
16123     }
16124
16125   if (!vec_len (name))
16126     {
16127       errmsg ("profile name must be specified");
16128       return -99;
16129     }
16130
16131   if (vec_len (name) > 64)
16132     {
16133       errmsg ("profile name too long");
16134       return -99;
16135     }
16136
16137   M (IKEV2_PROFILE_ADD_DEL, mp);
16138
16139   clib_memcpy (mp->name, name, vec_len (name));
16140   mp->is_add = is_add;
16141   vec_free (name);
16142
16143   S (mp);
16144   W (ret);
16145   return ret;
16146 }
16147
16148 static int
16149 api_ikev2_profile_set_auth (vat_main_t * vam)
16150 {
16151   unformat_input_t *i = vam->input;
16152   vl_api_ikev2_profile_set_auth_t *mp;
16153   u8 *name = 0;
16154   u8 *data = 0;
16155   u32 auth_method = 0;
16156   u8 is_hex = 0;
16157   int ret;
16158
16159   const char *valid_chars = "a-zA-Z0-9_";
16160
16161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16162     {
16163       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16164         vec_add1 (name, 0);
16165       else if (unformat (i, "auth_method %U",
16166                          unformat_ikev2_auth_method, &auth_method))
16167         ;
16168       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16169         is_hex = 1;
16170       else if (unformat (i, "auth_data %v", &data))
16171         ;
16172       else
16173         {
16174           errmsg ("parse error '%U'", format_unformat_error, i);
16175           return -99;
16176         }
16177     }
16178
16179   if (!vec_len (name))
16180     {
16181       errmsg ("profile name must be specified");
16182       return -99;
16183     }
16184
16185   if (vec_len (name) > 64)
16186     {
16187       errmsg ("profile name too long");
16188       return -99;
16189     }
16190
16191   if (!vec_len (data))
16192     {
16193       errmsg ("auth_data must be specified");
16194       return -99;
16195     }
16196
16197   if (!auth_method)
16198     {
16199       errmsg ("auth_method must be specified");
16200       return -99;
16201     }
16202
16203   M (IKEV2_PROFILE_SET_AUTH, mp);
16204
16205   mp->is_hex = is_hex;
16206   mp->auth_method = (u8) auth_method;
16207   mp->data_len = vec_len (data);
16208   clib_memcpy (mp->name, name, vec_len (name));
16209   clib_memcpy (mp->data, data, vec_len (data));
16210   vec_free (name);
16211   vec_free (data);
16212
16213   S (mp);
16214   W (ret);
16215   return ret;
16216 }
16217
16218 static int
16219 api_ikev2_profile_set_id (vat_main_t * vam)
16220 {
16221   unformat_input_t *i = vam->input;
16222   vl_api_ikev2_profile_set_id_t *mp;
16223   u8 *name = 0;
16224   u8 *data = 0;
16225   u8 is_local = 0;
16226   u32 id_type = 0;
16227   ip4_address_t ip4;
16228   int ret;
16229
16230   const char *valid_chars = "a-zA-Z0-9_";
16231
16232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16233     {
16234       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16235         vec_add1 (name, 0);
16236       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16237         ;
16238       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16239         {
16240           data = vec_new (u8, 4);
16241           clib_memcpy (data, ip4.as_u8, 4);
16242         }
16243       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16244         ;
16245       else if (unformat (i, "id_data %v", &data))
16246         ;
16247       else if (unformat (i, "local"))
16248         is_local = 1;
16249       else if (unformat (i, "remote"))
16250         is_local = 0;
16251       else
16252         {
16253           errmsg ("parse error '%U'", format_unformat_error, i);
16254           return -99;
16255         }
16256     }
16257
16258   if (!vec_len (name))
16259     {
16260       errmsg ("profile name must be specified");
16261       return -99;
16262     }
16263
16264   if (vec_len (name) > 64)
16265     {
16266       errmsg ("profile name too long");
16267       return -99;
16268     }
16269
16270   if (!vec_len (data))
16271     {
16272       errmsg ("id_data must be specified");
16273       return -99;
16274     }
16275
16276   if (!id_type)
16277     {
16278       errmsg ("id_type must be specified");
16279       return -99;
16280     }
16281
16282   M (IKEV2_PROFILE_SET_ID, mp);
16283
16284   mp->is_local = is_local;
16285   mp->id_type = (u8) id_type;
16286   mp->data_len = vec_len (data);
16287   clib_memcpy (mp->name, name, vec_len (name));
16288   clib_memcpy (mp->data, data, vec_len (data));
16289   vec_free (name);
16290   vec_free (data);
16291
16292   S (mp);
16293   W (ret);
16294   return ret;
16295 }
16296
16297 static int
16298 api_ikev2_profile_set_ts (vat_main_t * vam)
16299 {
16300   unformat_input_t *i = vam->input;
16301   vl_api_ikev2_profile_set_ts_t *mp;
16302   u8 *name = 0;
16303   u8 is_local = 0;
16304   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16305   ip4_address_t start_addr, end_addr;
16306
16307   const char *valid_chars = "a-zA-Z0-9_";
16308   int ret;
16309
16310   start_addr.as_u32 = 0;
16311   end_addr.as_u32 = (u32) ~ 0;
16312
16313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16314     {
16315       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16316         vec_add1 (name, 0);
16317       else if (unformat (i, "protocol %d", &proto))
16318         ;
16319       else if (unformat (i, "start_port %d", &start_port))
16320         ;
16321       else if (unformat (i, "end_port %d", &end_port))
16322         ;
16323       else
16324         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16325         ;
16326       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16327         ;
16328       else if (unformat (i, "local"))
16329         is_local = 1;
16330       else if (unformat (i, "remote"))
16331         is_local = 0;
16332       else
16333         {
16334           errmsg ("parse error '%U'", format_unformat_error, i);
16335           return -99;
16336         }
16337     }
16338
16339   if (!vec_len (name))
16340     {
16341       errmsg ("profile name must be specified");
16342       return -99;
16343     }
16344
16345   if (vec_len (name) > 64)
16346     {
16347       errmsg ("profile name too long");
16348       return -99;
16349     }
16350
16351   M (IKEV2_PROFILE_SET_TS, mp);
16352
16353   mp->is_local = is_local;
16354   mp->proto = (u8) proto;
16355   mp->start_port = (u16) start_port;
16356   mp->end_port = (u16) end_port;
16357   mp->start_addr = start_addr.as_u32;
16358   mp->end_addr = end_addr.as_u32;
16359   clib_memcpy (mp->name, name, vec_len (name));
16360   vec_free (name);
16361
16362   S (mp);
16363   W (ret);
16364   return ret;
16365 }
16366
16367 static int
16368 api_ikev2_set_local_key (vat_main_t * vam)
16369 {
16370   unformat_input_t *i = vam->input;
16371   vl_api_ikev2_set_local_key_t *mp;
16372   u8 *file = 0;
16373   int ret;
16374
16375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16376     {
16377       if (unformat (i, "file %v", &file))
16378         vec_add1 (file, 0);
16379       else
16380         {
16381           errmsg ("parse error '%U'", format_unformat_error, i);
16382           return -99;
16383         }
16384     }
16385
16386   if (!vec_len (file))
16387     {
16388       errmsg ("RSA key file must be specified");
16389       return -99;
16390     }
16391
16392   if (vec_len (file) > 256)
16393     {
16394       errmsg ("file name too long");
16395       return -99;
16396     }
16397
16398   M (IKEV2_SET_LOCAL_KEY, mp);
16399
16400   clib_memcpy (mp->key_file, file, vec_len (file));
16401   vec_free (file);
16402
16403   S (mp);
16404   W (ret);
16405   return ret;
16406 }
16407
16408 static int
16409 api_ikev2_set_responder (vat_main_t * vam)
16410 {
16411   unformat_input_t *i = vam->input;
16412   vl_api_ikev2_set_responder_t *mp;
16413   int ret;
16414   u8 *name = 0;
16415   u32 sw_if_index = ~0;
16416   ip4_address_t address;
16417
16418   const char *valid_chars = "a-zA-Z0-9_";
16419
16420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16421     {
16422       if (unformat
16423           (i, "%U interface %d address %U", unformat_token, valid_chars,
16424            &name, &sw_if_index, unformat_ip4_address, &address))
16425         vec_add1 (name, 0);
16426       else
16427         {
16428           errmsg ("parse error '%U'", format_unformat_error, i);
16429           return -99;
16430         }
16431     }
16432
16433   if (!vec_len (name))
16434     {
16435       errmsg ("profile name must be specified");
16436       return -99;
16437     }
16438
16439   if (vec_len (name) > 64)
16440     {
16441       errmsg ("profile name too long");
16442       return -99;
16443     }
16444
16445   M (IKEV2_SET_RESPONDER, mp);
16446
16447   clib_memcpy (mp->name, name, vec_len (name));
16448   vec_free (name);
16449
16450   mp->sw_if_index = sw_if_index;
16451   clib_memcpy (mp->address, &address, sizeof (address));
16452
16453   S (mp);
16454   W (ret);
16455   return ret;
16456 }
16457
16458 static int
16459 api_ikev2_set_ike_transforms (vat_main_t * vam)
16460 {
16461   unformat_input_t *i = vam->input;
16462   vl_api_ikev2_set_ike_transforms_t *mp;
16463   int ret;
16464   u8 *name = 0;
16465   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16466
16467   const char *valid_chars = "a-zA-Z0-9_";
16468
16469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16470     {
16471       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16472                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16473         vec_add1 (name, 0);
16474       else
16475         {
16476           errmsg ("parse error '%U'", format_unformat_error, i);
16477           return -99;
16478         }
16479     }
16480
16481   if (!vec_len (name))
16482     {
16483       errmsg ("profile name must be specified");
16484       return -99;
16485     }
16486
16487   if (vec_len (name) > 64)
16488     {
16489       errmsg ("profile name too long");
16490       return -99;
16491     }
16492
16493   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16494
16495   clib_memcpy (mp->name, name, vec_len (name));
16496   vec_free (name);
16497   mp->crypto_alg = crypto_alg;
16498   mp->crypto_key_size = crypto_key_size;
16499   mp->integ_alg = integ_alg;
16500   mp->dh_group = dh_group;
16501
16502   S (mp);
16503   W (ret);
16504   return ret;
16505 }
16506
16507
16508 static int
16509 api_ikev2_set_esp_transforms (vat_main_t * vam)
16510 {
16511   unformat_input_t *i = vam->input;
16512   vl_api_ikev2_set_esp_transforms_t *mp;
16513   int ret;
16514   u8 *name = 0;
16515   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16516
16517   const char *valid_chars = "a-zA-Z0-9_";
16518
16519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16520     {
16521       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16522                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16523         vec_add1 (name, 0);
16524       else
16525         {
16526           errmsg ("parse error '%U'", format_unformat_error, i);
16527           return -99;
16528         }
16529     }
16530
16531   if (!vec_len (name))
16532     {
16533       errmsg ("profile name must be specified");
16534       return -99;
16535     }
16536
16537   if (vec_len (name) > 64)
16538     {
16539       errmsg ("profile name too long");
16540       return -99;
16541     }
16542
16543   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16544
16545   clib_memcpy (mp->name, name, vec_len (name));
16546   vec_free (name);
16547   mp->crypto_alg = crypto_alg;
16548   mp->crypto_key_size = crypto_key_size;
16549   mp->integ_alg = integ_alg;
16550   mp->dh_group = dh_group;
16551
16552   S (mp);
16553   W (ret);
16554   return ret;
16555 }
16556
16557 static int
16558 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16559 {
16560   unformat_input_t *i = vam->input;
16561   vl_api_ikev2_set_sa_lifetime_t *mp;
16562   int ret;
16563   u8 *name = 0;
16564   u64 lifetime, lifetime_maxdata;
16565   u32 lifetime_jitter, handover;
16566
16567   const char *valid_chars = "a-zA-Z0-9_";
16568
16569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16570     {
16571       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16572                     &lifetime, &lifetime_jitter, &handover,
16573                     &lifetime_maxdata))
16574         vec_add1 (name, 0);
16575       else
16576         {
16577           errmsg ("parse error '%U'", format_unformat_error, i);
16578           return -99;
16579         }
16580     }
16581
16582   if (!vec_len (name))
16583     {
16584       errmsg ("profile name must be specified");
16585       return -99;
16586     }
16587
16588   if (vec_len (name) > 64)
16589     {
16590       errmsg ("profile name too long");
16591       return -99;
16592     }
16593
16594   M (IKEV2_SET_SA_LIFETIME, mp);
16595
16596   clib_memcpy (mp->name, name, vec_len (name));
16597   vec_free (name);
16598   mp->lifetime = lifetime;
16599   mp->lifetime_jitter = lifetime_jitter;
16600   mp->handover = handover;
16601   mp->lifetime_maxdata = lifetime_maxdata;
16602
16603   S (mp);
16604   W (ret);
16605   return ret;
16606 }
16607
16608 static int
16609 api_ikev2_initiate_sa_init (vat_main_t * vam)
16610 {
16611   unformat_input_t *i = vam->input;
16612   vl_api_ikev2_initiate_sa_init_t *mp;
16613   int ret;
16614   u8 *name = 0;
16615
16616   const char *valid_chars = "a-zA-Z0-9_";
16617
16618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16619     {
16620       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16621         vec_add1 (name, 0);
16622       else
16623         {
16624           errmsg ("parse error '%U'", format_unformat_error, i);
16625           return -99;
16626         }
16627     }
16628
16629   if (!vec_len (name))
16630     {
16631       errmsg ("profile name must be specified");
16632       return -99;
16633     }
16634
16635   if (vec_len (name) > 64)
16636     {
16637       errmsg ("profile name too long");
16638       return -99;
16639     }
16640
16641   M (IKEV2_INITIATE_SA_INIT, mp);
16642
16643   clib_memcpy (mp->name, name, vec_len (name));
16644   vec_free (name);
16645
16646   S (mp);
16647   W (ret);
16648   return ret;
16649 }
16650
16651 static int
16652 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16653 {
16654   unformat_input_t *i = vam->input;
16655   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16656   int ret;
16657   u64 ispi;
16658
16659
16660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat (i, "%lx", &ispi))
16663         ;
16664       else
16665         {
16666           errmsg ("parse error '%U'", format_unformat_error, i);
16667           return -99;
16668         }
16669     }
16670
16671   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16672
16673   mp->ispi = ispi;
16674
16675   S (mp);
16676   W (ret);
16677   return ret;
16678 }
16679
16680 static int
16681 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16682 {
16683   unformat_input_t *i = vam->input;
16684   vl_api_ikev2_initiate_del_child_sa_t *mp;
16685   int ret;
16686   u32 ispi;
16687
16688
16689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16690     {
16691       if (unformat (i, "%x", &ispi))
16692         ;
16693       else
16694         {
16695           errmsg ("parse error '%U'", format_unformat_error, i);
16696           return -99;
16697         }
16698     }
16699
16700   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16701
16702   mp->ispi = ispi;
16703
16704   S (mp);
16705   W (ret);
16706   return ret;
16707 }
16708
16709 static int
16710 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16711 {
16712   unformat_input_t *i = vam->input;
16713   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16714   int ret;
16715   u32 ispi;
16716
16717
16718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16719     {
16720       if (unformat (i, "%x", &ispi))
16721         ;
16722       else
16723         {
16724           errmsg ("parse error '%U'", format_unformat_error, i);
16725           return -99;
16726         }
16727     }
16728
16729   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16730
16731   mp->ispi = ispi;
16732
16733   S (mp);
16734   W (ret);
16735   return ret;
16736 }
16737
16738 static int
16739 api_get_first_msg_id (vat_main_t * vam)
16740 {
16741   vl_api_get_first_msg_id_t *mp;
16742   unformat_input_t *i = vam->input;
16743   u8 *name;
16744   u8 name_set = 0;
16745   int ret;
16746
16747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16748     {
16749       if (unformat (i, "client %s", &name))
16750         name_set = 1;
16751       else
16752         break;
16753     }
16754
16755   if (name_set == 0)
16756     {
16757       errmsg ("missing client name");
16758       return -99;
16759     }
16760   vec_add1 (name, 0);
16761
16762   if (vec_len (name) > 63)
16763     {
16764       errmsg ("client name too long");
16765       return -99;
16766     }
16767
16768   M (GET_FIRST_MSG_ID, mp);
16769   clib_memcpy (mp->name, name, vec_len (name));
16770   S (mp);
16771   W (ret);
16772   return ret;
16773 }
16774
16775 static int
16776 api_cop_interface_enable_disable (vat_main_t * vam)
16777 {
16778   unformat_input_t *line_input = vam->input;
16779   vl_api_cop_interface_enable_disable_t *mp;
16780   u32 sw_if_index = ~0;
16781   u8 enable_disable = 1;
16782   int ret;
16783
16784   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16785     {
16786       if (unformat (line_input, "disable"))
16787         enable_disable = 0;
16788       if (unformat (line_input, "enable"))
16789         enable_disable = 1;
16790       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16791                          vam, &sw_if_index))
16792         ;
16793       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16794         ;
16795       else
16796         break;
16797     }
16798
16799   if (sw_if_index == ~0)
16800     {
16801       errmsg ("missing interface name or sw_if_index");
16802       return -99;
16803     }
16804
16805   /* Construct the API message */
16806   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16807   mp->sw_if_index = ntohl (sw_if_index);
16808   mp->enable_disable = enable_disable;
16809
16810   /* send it... */
16811   S (mp);
16812   /* Wait for the reply */
16813   W (ret);
16814   return ret;
16815 }
16816
16817 static int
16818 api_cop_whitelist_enable_disable (vat_main_t * vam)
16819 {
16820   unformat_input_t *line_input = vam->input;
16821   vl_api_cop_whitelist_enable_disable_t *mp;
16822   u32 sw_if_index = ~0;
16823   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16824   u32 fib_id = 0;
16825   int ret;
16826
16827   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16828     {
16829       if (unformat (line_input, "ip4"))
16830         ip4 = 1;
16831       else if (unformat (line_input, "ip6"))
16832         ip6 = 1;
16833       else if (unformat (line_input, "default"))
16834         default_cop = 1;
16835       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16836                          vam, &sw_if_index))
16837         ;
16838       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16839         ;
16840       else if (unformat (line_input, "fib-id %d", &fib_id))
16841         ;
16842       else
16843         break;
16844     }
16845
16846   if (sw_if_index == ~0)
16847     {
16848       errmsg ("missing interface name or sw_if_index");
16849       return -99;
16850     }
16851
16852   /* Construct the API message */
16853   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16854   mp->sw_if_index = ntohl (sw_if_index);
16855   mp->fib_id = ntohl (fib_id);
16856   mp->ip4 = ip4;
16857   mp->ip6 = ip6;
16858   mp->default_cop = default_cop;
16859
16860   /* send it... */
16861   S (mp);
16862   /* Wait for the reply */
16863   W (ret);
16864   return ret;
16865 }
16866
16867 static int
16868 api_get_node_graph (vat_main_t * vam)
16869 {
16870   vl_api_get_node_graph_t *mp;
16871   int ret;
16872
16873   M (GET_NODE_GRAPH, mp);
16874
16875   /* send it... */
16876   S (mp);
16877   /* Wait for the reply */
16878   W (ret);
16879   return ret;
16880 }
16881
16882 /* *INDENT-OFF* */
16883 /** Used for parsing LISP eids */
16884 typedef CLIB_PACKED(struct{
16885   u8 addr[16];   /**< eid address */
16886   u32 len;       /**< prefix length if IP */
16887   u8 type;      /**< type of eid */
16888 }) lisp_eid_vat_t;
16889 /* *INDENT-ON* */
16890
16891 static uword
16892 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16893 {
16894   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16895
16896   clib_memset (a, 0, sizeof (a[0]));
16897
16898   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16899     {
16900       a->type = 0;              /* ipv4 type */
16901     }
16902   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16903     {
16904       a->type = 1;              /* ipv6 type */
16905     }
16906   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16907     {
16908       a->type = 2;              /* mac type */
16909     }
16910   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16911     {
16912       a->type = 3;              /* NSH type */
16913       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16914       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16915     }
16916   else
16917     {
16918       return 0;
16919     }
16920
16921   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16922     {
16923       return 0;
16924     }
16925
16926   return 1;
16927 }
16928
16929 static int
16930 lisp_eid_size_vat (u8 type)
16931 {
16932   switch (type)
16933     {
16934     case 0:
16935       return 4;
16936     case 1:
16937       return 16;
16938     case 2:
16939       return 6;
16940     case 3:
16941       return 5;
16942     }
16943   return 0;
16944 }
16945
16946 static void
16947 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16948 {
16949   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16950 }
16951
16952 static int
16953 api_one_add_del_locator_set (vat_main_t * vam)
16954 {
16955   unformat_input_t *input = vam->input;
16956   vl_api_one_add_del_locator_set_t *mp;
16957   u8 is_add = 1;
16958   u8 *locator_set_name = NULL;
16959   u8 locator_set_name_set = 0;
16960   vl_api_local_locator_t locator, *locators = 0;
16961   u32 sw_if_index, priority, weight;
16962   u32 data_len = 0;
16963
16964   int ret;
16965   /* Parse args required to build the message */
16966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16967     {
16968       if (unformat (input, "del"))
16969         {
16970           is_add = 0;
16971         }
16972       else if (unformat (input, "locator-set %s", &locator_set_name))
16973         {
16974           locator_set_name_set = 1;
16975         }
16976       else if (unformat (input, "sw_if_index %u p %u w %u",
16977                          &sw_if_index, &priority, &weight))
16978         {
16979           locator.sw_if_index = htonl (sw_if_index);
16980           locator.priority = priority;
16981           locator.weight = weight;
16982           vec_add1 (locators, locator);
16983         }
16984       else
16985         if (unformat
16986             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16987              &sw_if_index, &priority, &weight))
16988         {
16989           locator.sw_if_index = htonl (sw_if_index);
16990           locator.priority = priority;
16991           locator.weight = weight;
16992           vec_add1 (locators, locator);
16993         }
16994       else
16995         break;
16996     }
16997
16998   if (locator_set_name_set == 0)
16999     {
17000       errmsg ("missing locator-set name");
17001       vec_free (locators);
17002       return -99;
17003     }
17004
17005   if (vec_len (locator_set_name) > 64)
17006     {
17007       errmsg ("locator-set name too long");
17008       vec_free (locator_set_name);
17009       vec_free (locators);
17010       return -99;
17011     }
17012   vec_add1 (locator_set_name, 0);
17013
17014   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
17015
17016   /* Construct the API message */
17017   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
17018
17019   mp->is_add = is_add;
17020   clib_memcpy (mp->locator_set_name, locator_set_name,
17021                vec_len (locator_set_name));
17022   vec_free (locator_set_name);
17023
17024   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
17025   if (locators)
17026     clib_memcpy (mp->locators, locators, data_len);
17027   vec_free (locators);
17028
17029   /* send it... */
17030   S (mp);
17031
17032   /* Wait for a reply... */
17033   W (ret);
17034   return ret;
17035 }
17036
17037 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
17038
17039 static int
17040 api_one_add_del_locator (vat_main_t * vam)
17041 {
17042   unformat_input_t *input = vam->input;
17043   vl_api_one_add_del_locator_t *mp;
17044   u32 tmp_if_index = ~0;
17045   u32 sw_if_index = ~0;
17046   u8 sw_if_index_set = 0;
17047   u8 sw_if_index_if_name_set = 0;
17048   u32 priority = ~0;
17049   u8 priority_set = 0;
17050   u32 weight = ~0;
17051   u8 weight_set = 0;
17052   u8 is_add = 1;
17053   u8 *locator_set_name = NULL;
17054   u8 locator_set_name_set = 0;
17055   int ret;
17056
17057   /* Parse args required to build the message */
17058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17059     {
17060       if (unformat (input, "del"))
17061         {
17062           is_add = 0;
17063         }
17064       else if (unformat (input, "locator-set %s", &locator_set_name))
17065         {
17066           locator_set_name_set = 1;
17067         }
17068       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
17069                          &tmp_if_index))
17070         {
17071           sw_if_index_if_name_set = 1;
17072           sw_if_index = tmp_if_index;
17073         }
17074       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17075         {
17076           sw_if_index_set = 1;
17077           sw_if_index = tmp_if_index;
17078         }
17079       else if (unformat (input, "p %d", &priority))
17080         {
17081           priority_set = 1;
17082         }
17083       else if (unformat (input, "w %d", &weight))
17084         {
17085           weight_set = 1;
17086         }
17087       else
17088         break;
17089     }
17090
17091   if (locator_set_name_set == 0)
17092     {
17093       errmsg ("missing locator-set name");
17094       return -99;
17095     }
17096
17097   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17098     {
17099       errmsg ("missing sw_if_index");
17100       vec_free (locator_set_name);
17101       return -99;
17102     }
17103
17104   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17105     {
17106       errmsg ("cannot use both params interface name and sw_if_index");
17107       vec_free (locator_set_name);
17108       return -99;
17109     }
17110
17111   if (priority_set == 0)
17112     {
17113       errmsg ("missing locator-set priority");
17114       vec_free (locator_set_name);
17115       return -99;
17116     }
17117
17118   if (weight_set == 0)
17119     {
17120       errmsg ("missing locator-set weight");
17121       vec_free (locator_set_name);
17122       return -99;
17123     }
17124
17125   if (vec_len (locator_set_name) > 64)
17126     {
17127       errmsg ("locator-set name too long");
17128       vec_free (locator_set_name);
17129       return -99;
17130     }
17131   vec_add1 (locator_set_name, 0);
17132
17133   /* Construct the API message */
17134   M (ONE_ADD_DEL_LOCATOR, mp);
17135
17136   mp->is_add = is_add;
17137   mp->sw_if_index = ntohl (sw_if_index);
17138   mp->priority = priority;
17139   mp->weight = weight;
17140   clib_memcpy (mp->locator_set_name, locator_set_name,
17141                vec_len (locator_set_name));
17142   vec_free (locator_set_name);
17143
17144   /* send it... */
17145   S (mp);
17146
17147   /* Wait for a reply... */
17148   W (ret);
17149   return ret;
17150 }
17151
17152 #define api_lisp_add_del_locator api_one_add_del_locator
17153
17154 uword
17155 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17156 {
17157   u32 *key_id = va_arg (*args, u32 *);
17158   u8 *s = 0;
17159
17160   if (unformat (input, "%s", &s))
17161     {
17162       if (!strcmp ((char *) s, "sha1"))
17163         key_id[0] = HMAC_SHA_1_96;
17164       else if (!strcmp ((char *) s, "sha256"))
17165         key_id[0] = HMAC_SHA_256_128;
17166       else
17167         {
17168           clib_warning ("invalid key_id: '%s'", s);
17169           key_id[0] = HMAC_NO_KEY;
17170         }
17171     }
17172   else
17173     return 0;
17174
17175   vec_free (s);
17176   return 1;
17177 }
17178
17179 static int
17180 api_one_add_del_local_eid (vat_main_t * vam)
17181 {
17182   unformat_input_t *input = vam->input;
17183   vl_api_one_add_del_local_eid_t *mp;
17184   u8 is_add = 1;
17185   u8 eid_set = 0;
17186   lisp_eid_vat_t _eid, *eid = &_eid;
17187   u8 *locator_set_name = 0;
17188   u8 locator_set_name_set = 0;
17189   u32 vni = 0;
17190   u16 key_id = 0;
17191   u8 *key = 0;
17192   int ret;
17193
17194   /* Parse args required to build the message */
17195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17196     {
17197       if (unformat (input, "del"))
17198         {
17199           is_add = 0;
17200         }
17201       else if (unformat (input, "vni %d", &vni))
17202         {
17203           ;
17204         }
17205       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17206         {
17207           eid_set = 1;
17208         }
17209       else if (unformat (input, "locator-set %s", &locator_set_name))
17210         {
17211           locator_set_name_set = 1;
17212         }
17213       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17214         ;
17215       else if (unformat (input, "secret-key %_%v%_", &key))
17216         ;
17217       else
17218         break;
17219     }
17220
17221   if (locator_set_name_set == 0)
17222     {
17223       errmsg ("missing locator-set name");
17224       return -99;
17225     }
17226
17227   if (0 == eid_set)
17228     {
17229       errmsg ("EID address not set!");
17230       vec_free (locator_set_name);
17231       return -99;
17232     }
17233
17234   if (key && (0 == key_id))
17235     {
17236       errmsg ("invalid key_id!");
17237       return -99;
17238     }
17239
17240   if (vec_len (key) > 64)
17241     {
17242       errmsg ("key too long");
17243       vec_free (key);
17244       return -99;
17245     }
17246
17247   if (vec_len (locator_set_name) > 64)
17248     {
17249       errmsg ("locator-set name too long");
17250       vec_free (locator_set_name);
17251       return -99;
17252     }
17253   vec_add1 (locator_set_name, 0);
17254
17255   /* Construct the API message */
17256   M (ONE_ADD_DEL_LOCAL_EID, mp);
17257
17258   mp->is_add = is_add;
17259   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17260   mp->eid_type = eid->type;
17261   mp->prefix_len = eid->len;
17262   mp->vni = clib_host_to_net_u32 (vni);
17263   mp->key_id = clib_host_to_net_u16 (key_id);
17264   clib_memcpy (mp->locator_set_name, locator_set_name,
17265                vec_len (locator_set_name));
17266   clib_memcpy (mp->key, key, vec_len (key));
17267
17268   vec_free (locator_set_name);
17269   vec_free (key);
17270
17271   /* send it... */
17272   S (mp);
17273
17274   /* Wait for a reply... */
17275   W (ret);
17276   return ret;
17277 }
17278
17279 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17280
17281 static int
17282 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17283 {
17284   u32 dp_table = 0, vni = 0;;
17285   unformat_input_t *input = vam->input;
17286   vl_api_gpe_add_del_fwd_entry_t *mp;
17287   u8 is_add = 1;
17288   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17289   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17290   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17291   u32 action = ~0, w;
17292   ip4_address_t rmt_rloc4, lcl_rloc4;
17293   ip6_address_t rmt_rloc6, lcl_rloc6;
17294   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17295   int ret;
17296
17297   clib_memset (&rloc, 0, sizeof (rloc));
17298
17299   /* Parse args required to build the message */
17300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17301     {
17302       if (unformat (input, "del"))
17303         is_add = 0;
17304       else if (unformat (input, "add"))
17305         is_add = 1;
17306       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17307         {
17308           rmt_eid_set = 1;
17309         }
17310       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17311         {
17312           lcl_eid_set = 1;
17313         }
17314       else if (unformat (input, "vrf %d", &dp_table))
17315         ;
17316       else if (unformat (input, "bd %d", &dp_table))
17317         ;
17318       else if (unformat (input, "vni %d", &vni))
17319         ;
17320       else if (unformat (input, "w %d", &w))
17321         {
17322           if (!curr_rloc)
17323             {
17324               errmsg ("No RLOC configured for setting priority/weight!");
17325               return -99;
17326             }
17327           curr_rloc->weight = w;
17328         }
17329       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17330                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17331         {
17332           rloc.is_ip4 = 1;
17333
17334           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17335           rloc.weight = 0;
17336           vec_add1 (lcl_locs, rloc);
17337
17338           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17339           vec_add1 (rmt_locs, rloc);
17340           /* weight saved in rmt loc */
17341           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17342         }
17343       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17344                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17345         {
17346           rloc.is_ip4 = 0;
17347           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17348           rloc.weight = 0;
17349           vec_add1 (lcl_locs, rloc);
17350
17351           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17352           vec_add1 (rmt_locs, rloc);
17353           /* weight saved in rmt loc */
17354           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17355         }
17356       else if (unformat (input, "action %d", &action))
17357         {
17358           ;
17359         }
17360       else
17361         {
17362           clib_warning ("parse error '%U'", format_unformat_error, input);
17363           return -99;
17364         }
17365     }
17366
17367   if (!rmt_eid_set)
17368     {
17369       errmsg ("remote eid addresses not set");
17370       return -99;
17371     }
17372
17373   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17374     {
17375       errmsg ("eid types don't match");
17376       return -99;
17377     }
17378
17379   if (0 == rmt_locs && (u32) ~ 0 == action)
17380     {
17381       errmsg ("action not set for negative mapping");
17382       return -99;
17383     }
17384
17385   /* Construct the API message */
17386   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17387       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17388
17389   mp->is_add = is_add;
17390   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17391   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17392   mp->eid_type = rmt_eid->type;
17393   mp->dp_table = clib_host_to_net_u32 (dp_table);
17394   mp->vni = clib_host_to_net_u32 (vni);
17395   mp->rmt_len = rmt_eid->len;
17396   mp->lcl_len = lcl_eid->len;
17397   mp->action = action;
17398
17399   if (0 != rmt_locs && 0 != lcl_locs)
17400     {
17401       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17402       clib_memcpy (mp->locs, lcl_locs,
17403                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17404
17405       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17406       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17407                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17408     }
17409   vec_free (lcl_locs);
17410   vec_free (rmt_locs);
17411
17412   /* send it... */
17413   S (mp);
17414
17415   /* Wait for a reply... */
17416   W (ret);
17417   return ret;
17418 }
17419
17420 static int
17421 api_one_add_del_map_server (vat_main_t * vam)
17422 {
17423   unformat_input_t *input = vam->input;
17424   vl_api_one_add_del_map_server_t *mp;
17425   u8 is_add = 1;
17426   u8 ipv4_set = 0;
17427   u8 ipv6_set = 0;
17428   ip4_address_t ipv4;
17429   ip6_address_t ipv6;
17430   int ret;
17431
17432   /* Parse args required to build the message */
17433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17434     {
17435       if (unformat (input, "del"))
17436         {
17437           is_add = 0;
17438         }
17439       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17440         {
17441           ipv4_set = 1;
17442         }
17443       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17444         {
17445           ipv6_set = 1;
17446         }
17447       else
17448         break;
17449     }
17450
17451   if (ipv4_set && ipv6_set)
17452     {
17453       errmsg ("both eid v4 and v6 addresses set");
17454       return -99;
17455     }
17456
17457   if (!ipv4_set && !ipv6_set)
17458     {
17459       errmsg ("eid addresses not set");
17460       return -99;
17461     }
17462
17463   /* Construct the API message */
17464   M (ONE_ADD_DEL_MAP_SERVER, mp);
17465
17466   mp->is_add = is_add;
17467   if (ipv6_set)
17468     {
17469       mp->is_ipv6 = 1;
17470       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17471     }
17472   else
17473     {
17474       mp->is_ipv6 = 0;
17475       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17476     }
17477
17478   /* send it... */
17479   S (mp);
17480
17481   /* Wait for a reply... */
17482   W (ret);
17483   return ret;
17484 }
17485
17486 #define api_lisp_add_del_map_server api_one_add_del_map_server
17487
17488 static int
17489 api_one_add_del_map_resolver (vat_main_t * vam)
17490 {
17491   unformat_input_t *input = vam->input;
17492   vl_api_one_add_del_map_resolver_t *mp;
17493   u8 is_add = 1;
17494   u8 ipv4_set = 0;
17495   u8 ipv6_set = 0;
17496   ip4_address_t ipv4;
17497   ip6_address_t ipv6;
17498   int ret;
17499
17500   /* Parse args required to build the message */
17501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17502     {
17503       if (unformat (input, "del"))
17504         {
17505           is_add = 0;
17506         }
17507       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17508         {
17509           ipv4_set = 1;
17510         }
17511       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17512         {
17513           ipv6_set = 1;
17514         }
17515       else
17516         break;
17517     }
17518
17519   if (ipv4_set && ipv6_set)
17520     {
17521       errmsg ("both eid v4 and v6 addresses set");
17522       return -99;
17523     }
17524
17525   if (!ipv4_set && !ipv6_set)
17526     {
17527       errmsg ("eid addresses not set");
17528       return -99;
17529     }
17530
17531   /* Construct the API message */
17532   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17533
17534   mp->is_add = is_add;
17535   if (ipv6_set)
17536     {
17537       mp->is_ipv6 = 1;
17538       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17539     }
17540   else
17541     {
17542       mp->is_ipv6 = 0;
17543       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17544     }
17545
17546   /* send it... */
17547   S (mp);
17548
17549   /* Wait for a reply... */
17550   W (ret);
17551   return ret;
17552 }
17553
17554 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17555
17556 static int
17557 api_lisp_gpe_enable_disable (vat_main_t * vam)
17558 {
17559   unformat_input_t *input = vam->input;
17560   vl_api_gpe_enable_disable_t *mp;
17561   u8 is_set = 0;
17562   u8 is_en = 1;
17563   int ret;
17564
17565   /* Parse args required to build the message */
17566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17567     {
17568       if (unformat (input, "enable"))
17569         {
17570           is_set = 1;
17571           is_en = 1;
17572         }
17573       else if (unformat (input, "disable"))
17574         {
17575           is_set = 1;
17576           is_en = 0;
17577         }
17578       else
17579         break;
17580     }
17581
17582   if (is_set == 0)
17583     {
17584       errmsg ("Value not set");
17585       return -99;
17586     }
17587
17588   /* Construct the API message */
17589   M (GPE_ENABLE_DISABLE, mp);
17590
17591   mp->is_en = is_en;
17592
17593   /* send it... */
17594   S (mp);
17595
17596   /* Wait for a reply... */
17597   W (ret);
17598   return ret;
17599 }
17600
17601 static int
17602 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17603 {
17604   unformat_input_t *input = vam->input;
17605   vl_api_one_rloc_probe_enable_disable_t *mp;
17606   u8 is_set = 0;
17607   u8 is_en = 0;
17608   int ret;
17609
17610   /* Parse args required to build the message */
17611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17612     {
17613       if (unformat (input, "enable"))
17614         {
17615           is_set = 1;
17616           is_en = 1;
17617         }
17618       else if (unformat (input, "disable"))
17619         is_set = 1;
17620       else
17621         break;
17622     }
17623
17624   if (!is_set)
17625     {
17626       errmsg ("Value not set");
17627       return -99;
17628     }
17629
17630   /* Construct the API message */
17631   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17632
17633   mp->is_enabled = is_en;
17634
17635   /* send it... */
17636   S (mp);
17637
17638   /* Wait for a reply... */
17639   W (ret);
17640   return ret;
17641 }
17642
17643 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17644
17645 static int
17646 api_one_map_register_enable_disable (vat_main_t * vam)
17647 {
17648   unformat_input_t *input = vam->input;
17649   vl_api_one_map_register_enable_disable_t *mp;
17650   u8 is_set = 0;
17651   u8 is_en = 0;
17652   int ret;
17653
17654   /* Parse args required to build the message */
17655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17656     {
17657       if (unformat (input, "enable"))
17658         {
17659           is_set = 1;
17660           is_en = 1;
17661         }
17662       else if (unformat (input, "disable"))
17663         is_set = 1;
17664       else
17665         break;
17666     }
17667
17668   if (!is_set)
17669     {
17670       errmsg ("Value not set");
17671       return -99;
17672     }
17673
17674   /* Construct the API message */
17675   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17676
17677   mp->is_enabled = is_en;
17678
17679   /* send it... */
17680   S (mp);
17681
17682   /* Wait for a reply... */
17683   W (ret);
17684   return ret;
17685 }
17686
17687 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17688
17689 static int
17690 api_one_enable_disable (vat_main_t * vam)
17691 {
17692   unformat_input_t *input = vam->input;
17693   vl_api_one_enable_disable_t *mp;
17694   u8 is_set = 0;
17695   u8 is_en = 0;
17696   int ret;
17697
17698   /* Parse args required to build the message */
17699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17700     {
17701       if (unformat (input, "enable"))
17702         {
17703           is_set = 1;
17704           is_en = 1;
17705         }
17706       else if (unformat (input, "disable"))
17707         {
17708           is_set = 1;
17709         }
17710       else
17711         break;
17712     }
17713
17714   if (!is_set)
17715     {
17716       errmsg ("Value not set");
17717       return -99;
17718     }
17719
17720   /* Construct the API message */
17721   M (ONE_ENABLE_DISABLE, mp);
17722
17723   mp->is_en = is_en;
17724
17725   /* send it... */
17726   S (mp);
17727
17728   /* Wait for a reply... */
17729   W (ret);
17730   return ret;
17731 }
17732
17733 #define api_lisp_enable_disable api_one_enable_disable
17734
17735 static int
17736 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17737 {
17738   unformat_input_t *input = vam->input;
17739   vl_api_one_enable_disable_xtr_mode_t *mp;
17740   u8 is_set = 0;
17741   u8 is_en = 0;
17742   int ret;
17743
17744   /* Parse args required to build the message */
17745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17746     {
17747       if (unformat (input, "enable"))
17748         {
17749           is_set = 1;
17750           is_en = 1;
17751         }
17752       else if (unformat (input, "disable"))
17753         {
17754           is_set = 1;
17755         }
17756       else
17757         break;
17758     }
17759
17760   if (!is_set)
17761     {
17762       errmsg ("Value not set");
17763       return -99;
17764     }
17765
17766   /* Construct the API message */
17767   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17768
17769   mp->is_en = is_en;
17770
17771   /* send it... */
17772   S (mp);
17773
17774   /* Wait for a reply... */
17775   W (ret);
17776   return ret;
17777 }
17778
17779 static int
17780 api_one_show_xtr_mode (vat_main_t * vam)
17781 {
17782   vl_api_one_show_xtr_mode_t *mp;
17783   int ret;
17784
17785   /* Construct the API message */
17786   M (ONE_SHOW_XTR_MODE, mp);
17787
17788   /* send it... */
17789   S (mp);
17790
17791   /* Wait for a reply... */
17792   W (ret);
17793   return ret;
17794 }
17795
17796 static int
17797 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17798 {
17799   unformat_input_t *input = vam->input;
17800   vl_api_one_enable_disable_pitr_mode_t *mp;
17801   u8 is_set = 0;
17802   u8 is_en = 0;
17803   int ret;
17804
17805   /* Parse args required to build the message */
17806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17807     {
17808       if (unformat (input, "enable"))
17809         {
17810           is_set = 1;
17811           is_en = 1;
17812         }
17813       else if (unformat (input, "disable"))
17814         {
17815           is_set = 1;
17816         }
17817       else
17818         break;
17819     }
17820
17821   if (!is_set)
17822     {
17823       errmsg ("Value not set");
17824       return -99;
17825     }
17826
17827   /* Construct the API message */
17828   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17829
17830   mp->is_en = is_en;
17831
17832   /* send it... */
17833   S (mp);
17834
17835   /* Wait for a reply... */
17836   W (ret);
17837   return ret;
17838 }
17839
17840 static int
17841 api_one_show_pitr_mode (vat_main_t * vam)
17842 {
17843   vl_api_one_show_pitr_mode_t *mp;
17844   int ret;
17845
17846   /* Construct the API message */
17847   M (ONE_SHOW_PITR_MODE, mp);
17848
17849   /* send it... */
17850   S (mp);
17851
17852   /* Wait for a reply... */
17853   W (ret);
17854   return ret;
17855 }
17856
17857 static int
17858 api_one_enable_disable_petr_mode (vat_main_t * vam)
17859 {
17860   unformat_input_t *input = vam->input;
17861   vl_api_one_enable_disable_petr_mode_t *mp;
17862   u8 is_set = 0;
17863   u8 is_en = 0;
17864   int ret;
17865
17866   /* Parse args required to build the message */
17867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17868     {
17869       if (unformat (input, "enable"))
17870         {
17871           is_set = 1;
17872           is_en = 1;
17873         }
17874       else if (unformat (input, "disable"))
17875         {
17876           is_set = 1;
17877         }
17878       else
17879         break;
17880     }
17881
17882   if (!is_set)
17883     {
17884       errmsg ("Value not set");
17885       return -99;
17886     }
17887
17888   /* Construct the API message */
17889   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17890
17891   mp->is_en = is_en;
17892
17893   /* send it... */
17894   S (mp);
17895
17896   /* Wait for a reply... */
17897   W (ret);
17898   return ret;
17899 }
17900
17901 static int
17902 api_one_show_petr_mode (vat_main_t * vam)
17903 {
17904   vl_api_one_show_petr_mode_t *mp;
17905   int ret;
17906
17907   /* Construct the API message */
17908   M (ONE_SHOW_PETR_MODE, mp);
17909
17910   /* send it... */
17911   S (mp);
17912
17913   /* Wait for a reply... */
17914   W (ret);
17915   return ret;
17916 }
17917
17918 static int
17919 api_show_one_map_register_state (vat_main_t * vam)
17920 {
17921   vl_api_show_one_map_register_state_t *mp;
17922   int ret;
17923
17924   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17925
17926   /* send */
17927   S (mp);
17928
17929   /* wait for reply */
17930   W (ret);
17931   return ret;
17932 }
17933
17934 #define api_show_lisp_map_register_state api_show_one_map_register_state
17935
17936 static int
17937 api_show_one_rloc_probe_state (vat_main_t * vam)
17938 {
17939   vl_api_show_one_rloc_probe_state_t *mp;
17940   int ret;
17941
17942   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17943
17944   /* send */
17945   S (mp);
17946
17947   /* wait for reply */
17948   W (ret);
17949   return ret;
17950 }
17951
17952 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17953
17954 static int
17955 api_one_add_del_ndp_entry (vat_main_t * vam)
17956 {
17957   vl_api_one_add_del_ndp_entry_t *mp;
17958   unformat_input_t *input = vam->input;
17959   u8 is_add = 1;
17960   u8 mac_set = 0;
17961   u8 bd_set = 0;
17962   u8 ip_set = 0;
17963   u8 mac[6] = { 0, };
17964   u8 ip6[16] = { 0, };
17965   u32 bd = ~0;
17966   int ret;
17967
17968   /* Parse args required to build the message */
17969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17970     {
17971       if (unformat (input, "del"))
17972         is_add = 0;
17973       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17974         mac_set = 1;
17975       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17976         ip_set = 1;
17977       else if (unformat (input, "bd %d", &bd))
17978         bd_set = 1;
17979       else
17980         {
17981           errmsg ("parse error '%U'", format_unformat_error, input);
17982           return -99;
17983         }
17984     }
17985
17986   if (!bd_set || !ip_set || (!mac_set && is_add))
17987     {
17988       errmsg ("Missing BD, IP or MAC!");
17989       return -99;
17990     }
17991
17992   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17993   mp->is_add = is_add;
17994   clib_memcpy (mp->mac, mac, 6);
17995   mp->bd = clib_host_to_net_u32 (bd);
17996   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17997
17998   /* send */
17999   S (mp);
18000
18001   /* wait for reply */
18002   W (ret);
18003   return ret;
18004 }
18005
18006 static int
18007 api_one_add_del_l2_arp_entry (vat_main_t * vam)
18008 {
18009   vl_api_one_add_del_l2_arp_entry_t *mp;
18010   unformat_input_t *input = vam->input;
18011   u8 is_add = 1;
18012   u8 mac_set = 0;
18013   u8 bd_set = 0;
18014   u8 ip_set = 0;
18015   u8 mac[6] = { 0, };
18016   u32 ip4 = 0, bd = ~0;
18017   int ret;
18018
18019   /* Parse args required to build the message */
18020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18021     {
18022       if (unformat (input, "del"))
18023         is_add = 0;
18024       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18025         mac_set = 1;
18026       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
18027         ip_set = 1;
18028       else if (unformat (input, "bd %d", &bd))
18029         bd_set = 1;
18030       else
18031         {
18032           errmsg ("parse error '%U'", format_unformat_error, input);
18033           return -99;
18034         }
18035     }
18036
18037   if (!bd_set || !ip_set || (!mac_set && is_add))
18038     {
18039       errmsg ("Missing BD, IP or MAC!");
18040       return -99;
18041     }
18042
18043   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
18044   mp->is_add = is_add;
18045   clib_memcpy (mp->mac, mac, 6);
18046   mp->bd = clib_host_to_net_u32 (bd);
18047   mp->ip4 = ip4;
18048
18049   /* send */
18050   S (mp);
18051
18052   /* wait for reply */
18053   W (ret);
18054   return ret;
18055 }
18056
18057 static int
18058 api_one_ndp_bd_get (vat_main_t * vam)
18059 {
18060   vl_api_one_ndp_bd_get_t *mp;
18061   int ret;
18062
18063   M (ONE_NDP_BD_GET, mp);
18064
18065   /* send */
18066   S (mp);
18067
18068   /* wait for reply */
18069   W (ret);
18070   return ret;
18071 }
18072
18073 static int
18074 api_one_ndp_entries_get (vat_main_t * vam)
18075 {
18076   vl_api_one_ndp_entries_get_t *mp;
18077   unformat_input_t *input = vam->input;
18078   u8 bd_set = 0;
18079   u32 bd = ~0;
18080   int ret;
18081
18082   /* Parse args required to build the message */
18083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18084     {
18085       if (unformat (input, "bd %d", &bd))
18086         bd_set = 1;
18087       else
18088         {
18089           errmsg ("parse error '%U'", format_unformat_error, input);
18090           return -99;
18091         }
18092     }
18093
18094   if (!bd_set)
18095     {
18096       errmsg ("Expected bridge domain!");
18097       return -99;
18098     }
18099
18100   M (ONE_NDP_ENTRIES_GET, mp);
18101   mp->bd = clib_host_to_net_u32 (bd);
18102
18103   /* send */
18104   S (mp);
18105
18106   /* wait for reply */
18107   W (ret);
18108   return ret;
18109 }
18110
18111 static int
18112 api_one_l2_arp_bd_get (vat_main_t * vam)
18113 {
18114   vl_api_one_l2_arp_bd_get_t *mp;
18115   int ret;
18116
18117   M (ONE_L2_ARP_BD_GET, mp);
18118
18119   /* send */
18120   S (mp);
18121
18122   /* wait for reply */
18123   W (ret);
18124   return ret;
18125 }
18126
18127 static int
18128 api_one_l2_arp_entries_get (vat_main_t * vam)
18129 {
18130   vl_api_one_l2_arp_entries_get_t *mp;
18131   unformat_input_t *input = vam->input;
18132   u8 bd_set = 0;
18133   u32 bd = ~0;
18134   int ret;
18135
18136   /* Parse args required to build the message */
18137   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18138     {
18139       if (unformat (input, "bd %d", &bd))
18140         bd_set = 1;
18141       else
18142         {
18143           errmsg ("parse error '%U'", format_unformat_error, input);
18144           return -99;
18145         }
18146     }
18147
18148   if (!bd_set)
18149     {
18150       errmsg ("Expected bridge domain!");
18151       return -99;
18152     }
18153
18154   M (ONE_L2_ARP_ENTRIES_GET, mp);
18155   mp->bd = clib_host_to_net_u32 (bd);
18156
18157   /* send */
18158   S (mp);
18159
18160   /* wait for reply */
18161   W (ret);
18162   return ret;
18163 }
18164
18165 static int
18166 api_one_stats_enable_disable (vat_main_t * vam)
18167 {
18168   vl_api_one_stats_enable_disable_t *mp;
18169   unformat_input_t *input = vam->input;
18170   u8 is_set = 0;
18171   u8 is_en = 0;
18172   int ret;
18173
18174   /* Parse args required to build the message */
18175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18176     {
18177       if (unformat (input, "enable"))
18178         {
18179           is_set = 1;
18180           is_en = 1;
18181         }
18182       else if (unformat (input, "disable"))
18183         {
18184           is_set = 1;
18185         }
18186       else
18187         break;
18188     }
18189
18190   if (!is_set)
18191     {
18192       errmsg ("Value not set");
18193       return -99;
18194     }
18195
18196   M (ONE_STATS_ENABLE_DISABLE, mp);
18197   mp->is_en = is_en;
18198
18199   /* send */
18200   S (mp);
18201
18202   /* wait for reply */
18203   W (ret);
18204   return ret;
18205 }
18206
18207 static int
18208 api_show_one_stats_enable_disable (vat_main_t * vam)
18209 {
18210   vl_api_show_one_stats_enable_disable_t *mp;
18211   int ret;
18212
18213   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18214
18215   /* send */
18216   S (mp);
18217
18218   /* wait for reply */
18219   W (ret);
18220   return ret;
18221 }
18222
18223 static int
18224 api_show_one_map_request_mode (vat_main_t * vam)
18225 {
18226   vl_api_show_one_map_request_mode_t *mp;
18227   int ret;
18228
18229   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18230
18231   /* send */
18232   S (mp);
18233
18234   /* wait for reply */
18235   W (ret);
18236   return ret;
18237 }
18238
18239 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18240
18241 static int
18242 api_one_map_request_mode (vat_main_t * vam)
18243 {
18244   unformat_input_t *input = vam->input;
18245   vl_api_one_map_request_mode_t *mp;
18246   u8 mode = 0;
18247   int ret;
18248
18249   /* Parse args required to build the message */
18250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18251     {
18252       if (unformat (input, "dst-only"))
18253         mode = 0;
18254       else if (unformat (input, "src-dst"))
18255         mode = 1;
18256       else
18257         {
18258           errmsg ("parse error '%U'", format_unformat_error, input);
18259           return -99;
18260         }
18261     }
18262
18263   M (ONE_MAP_REQUEST_MODE, mp);
18264
18265   mp->mode = mode;
18266
18267   /* send */
18268   S (mp);
18269
18270   /* wait for reply */
18271   W (ret);
18272   return ret;
18273 }
18274
18275 #define api_lisp_map_request_mode api_one_map_request_mode
18276
18277 /**
18278  * Enable/disable ONE proxy ITR.
18279  *
18280  * @param vam vpp API test context
18281  * @return return code
18282  */
18283 static int
18284 api_one_pitr_set_locator_set (vat_main_t * vam)
18285 {
18286   u8 ls_name_set = 0;
18287   unformat_input_t *input = vam->input;
18288   vl_api_one_pitr_set_locator_set_t *mp;
18289   u8 is_add = 1;
18290   u8 *ls_name = 0;
18291   int ret;
18292
18293   /* Parse args required to build the message */
18294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18295     {
18296       if (unformat (input, "del"))
18297         is_add = 0;
18298       else if (unformat (input, "locator-set %s", &ls_name))
18299         ls_name_set = 1;
18300       else
18301         {
18302           errmsg ("parse error '%U'", format_unformat_error, input);
18303           return -99;
18304         }
18305     }
18306
18307   if (!ls_name_set)
18308     {
18309       errmsg ("locator-set name not set!");
18310       return -99;
18311     }
18312
18313   M (ONE_PITR_SET_LOCATOR_SET, mp);
18314
18315   mp->is_add = is_add;
18316   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18317   vec_free (ls_name);
18318
18319   /* send */
18320   S (mp);
18321
18322   /* wait for reply */
18323   W (ret);
18324   return ret;
18325 }
18326
18327 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18328
18329 static int
18330 api_one_nsh_set_locator_set (vat_main_t * vam)
18331 {
18332   u8 ls_name_set = 0;
18333   unformat_input_t *input = vam->input;
18334   vl_api_one_nsh_set_locator_set_t *mp;
18335   u8 is_add = 1;
18336   u8 *ls_name = 0;
18337   int ret;
18338
18339   /* Parse args required to build the message */
18340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18341     {
18342       if (unformat (input, "del"))
18343         is_add = 0;
18344       else if (unformat (input, "ls %s", &ls_name))
18345         ls_name_set = 1;
18346       else
18347         {
18348           errmsg ("parse error '%U'", format_unformat_error, input);
18349           return -99;
18350         }
18351     }
18352
18353   if (!ls_name_set && is_add)
18354     {
18355       errmsg ("locator-set name not set!");
18356       return -99;
18357     }
18358
18359   M (ONE_NSH_SET_LOCATOR_SET, mp);
18360
18361   mp->is_add = is_add;
18362   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18363   vec_free (ls_name);
18364
18365   /* send */
18366   S (mp);
18367
18368   /* wait for reply */
18369   W (ret);
18370   return ret;
18371 }
18372
18373 static int
18374 api_show_one_pitr (vat_main_t * vam)
18375 {
18376   vl_api_show_one_pitr_t *mp;
18377   int ret;
18378
18379   if (!vam->json_output)
18380     {
18381       print (vam->ofp, "%=20s", "lisp status:");
18382     }
18383
18384   M (SHOW_ONE_PITR, mp);
18385   /* send it... */
18386   S (mp);
18387
18388   /* Wait for a reply... */
18389   W (ret);
18390   return ret;
18391 }
18392
18393 #define api_show_lisp_pitr api_show_one_pitr
18394
18395 static int
18396 api_one_use_petr (vat_main_t * vam)
18397 {
18398   unformat_input_t *input = vam->input;
18399   vl_api_one_use_petr_t *mp;
18400   u8 is_add = 0;
18401   ip_address_t ip;
18402   int ret;
18403
18404   clib_memset (&ip, 0, sizeof (ip));
18405
18406   /* Parse args required to build the message */
18407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18408     {
18409       if (unformat (input, "disable"))
18410         is_add = 0;
18411       else
18412         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18413         {
18414           is_add = 1;
18415           ip_addr_version (&ip) = IP4;
18416         }
18417       else
18418         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18419         {
18420           is_add = 1;
18421           ip_addr_version (&ip) = IP6;
18422         }
18423       else
18424         {
18425           errmsg ("parse error '%U'", format_unformat_error, input);
18426           return -99;
18427         }
18428     }
18429
18430   M (ONE_USE_PETR, mp);
18431
18432   mp->is_add = is_add;
18433   if (is_add)
18434     {
18435       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18436       if (mp->is_ip4)
18437         clib_memcpy (mp->address, &ip, 4);
18438       else
18439         clib_memcpy (mp->address, &ip, 16);
18440     }
18441
18442   /* send */
18443   S (mp);
18444
18445   /* wait for reply */
18446   W (ret);
18447   return ret;
18448 }
18449
18450 #define api_lisp_use_petr api_one_use_petr
18451
18452 static int
18453 api_show_one_nsh_mapping (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", "local ONE NSH mapping:");
18461     }
18462
18463   M (SHOW_ONE_NSH_MAPPING, mp);
18464   /* send it... */
18465   S (mp);
18466
18467   /* Wait for a reply... */
18468   W (ret);
18469   return ret;
18470 }
18471
18472 static int
18473 api_show_one_use_petr (vat_main_t * vam)
18474 {
18475   vl_api_show_one_use_petr_t *mp;
18476   int ret;
18477
18478   if (!vam->json_output)
18479     {
18480       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18481     }
18482
18483   M (SHOW_ONE_USE_PETR, mp);
18484   /* send it... */
18485   S (mp);
18486
18487   /* Wait for a reply... */
18488   W (ret);
18489   return ret;
18490 }
18491
18492 #define api_show_lisp_use_petr api_show_one_use_petr
18493
18494 /**
18495  * Add/delete mapping between vni and vrf
18496  */
18497 static int
18498 api_one_eid_table_add_del_map (vat_main_t * vam)
18499 {
18500   unformat_input_t *input = vam->input;
18501   vl_api_one_eid_table_add_del_map_t *mp;
18502   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18503   u32 vni, vrf, bd_index;
18504   int ret;
18505
18506   /* Parse args required to build the message */
18507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18508     {
18509       if (unformat (input, "del"))
18510         is_add = 0;
18511       else if (unformat (input, "vrf %d", &vrf))
18512         vrf_set = 1;
18513       else if (unformat (input, "bd_index %d", &bd_index))
18514         bd_index_set = 1;
18515       else if (unformat (input, "vni %d", &vni))
18516         vni_set = 1;
18517       else
18518         break;
18519     }
18520
18521   if (!vni_set || (!vrf_set && !bd_index_set))
18522     {
18523       errmsg ("missing arguments!");
18524       return -99;
18525     }
18526
18527   if (vrf_set && bd_index_set)
18528     {
18529       errmsg ("error: both vrf and bd entered!");
18530       return -99;
18531     }
18532
18533   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18534
18535   mp->is_add = is_add;
18536   mp->vni = htonl (vni);
18537   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18538   mp->is_l2 = bd_index_set;
18539
18540   /* send */
18541   S (mp);
18542
18543   /* wait for reply */
18544   W (ret);
18545   return ret;
18546 }
18547
18548 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18549
18550 uword
18551 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18552 {
18553   u32 *action = va_arg (*args, u32 *);
18554   u8 *s = 0;
18555
18556   if (unformat (input, "%s", &s))
18557     {
18558       if (!strcmp ((char *) s, "no-action"))
18559         action[0] = 0;
18560       else if (!strcmp ((char *) s, "natively-forward"))
18561         action[0] = 1;
18562       else if (!strcmp ((char *) s, "send-map-request"))
18563         action[0] = 2;
18564       else if (!strcmp ((char *) s, "drop"))
18565         action[0] = 3;
18566       else
18567         {
18568           clib_warning ("invalid action: '%s'", s);
18569           action[0] = 3;
18570         }
18571     }
18572   else
18573     return 0;
18574
18575   vec_free (s);
18576   return 1;
18577 }
18578
18579 /**
18580  * Add/del remote mapping to/from ONE control plane
18581  *
18582  * @param vam vpp API test context
18583  * @return return code
18584  */
18585 static int
18586 api_one_add_del_remote_mapping (vat_main_t * vam)
18587 {
18588   unformat_input_t *input = vam->input;
18589   vl_api_one_add_del_remote_mapping_t *mp;
18590   u32 vni = 0;
18591   lisp_eid_vat_t _eid, *eid = &_eid;
18592   lisp_eid_vat_t _seid, *seid = &_seid;
18593   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18594   u32 action = ~0, p, w, data_len;
18595   ip4_address_t rloc4;
18596   ip6_address_t rloc6;
18597   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18598   int ret;
18599
18600   clib_memset (&rloc, 0, sizeof (rloc));
18601
18602   /* Parse args required to build the message */
18603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18604     {
18605       if (unformat (input, "del-all"))
18606         {
18607           del_all = 1;
18608         }
18609       else if (unformat (input, "del"))
18610         {
18611           is_add = 0;
18612         }
18613       else if (unformat (input, "add"))
18614         {
18615           is_add = 1;
18616         }
18617       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18618         {
18619           eid_set = 1;
18620         }
18621       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18622         {
18623           seid_set = 1;
18624         }
18625       else if (unformat (input, "vni %d", &vni))
18626         {
18627           ;
18628         }
18629       else if (unformat (input, "p %d w %d", &p, &w))
18630         {
18631           if (!curr_rloc)
18632             {
18633               errmsg ("No RLOC configured for setting priority/weight!");
18634               return -99;
18635             }
18636           curr_rloc->priority = p;
18637           curr_rloc->weight = w;
18638         }
18639       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18640         {
18641           rloc.is_ip4 = 1;
18642           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18643           vec_add1 (rlocs, rloc);
18644           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18645         }
18646       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18647         {
18648           rloc.is_ip4 = 0;
18649           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18650           vec_add1 (rlocs, rloc);
18651           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18652         }
18653       else if (unformat (input, "action %U",
18654                          unformat_negative_mapping_action, &action))
18655         {
18656           ;
18657         }
18658       else
18659         {
18660           clib_warning ("parse error '%U'", format_unformat_error, input);
18661           return -99;
18662         }
18663     }
18664
18665   if (0 == eid_set)
18666     {
18667       errmsg ("missing params!");
18668       return -99;
18669     }
18670
18671   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18672     {
18673       errmsg ("no action set for negative map-reply!");
18674       return -99;
18675     }
18676
18677   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18678
18679   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18680   mp->is_add = is_add;
18681   mp->vni = htonl (vni);
18682   mp->action = (u8) action;
18683   mp->is_src_dst = seid_set;
18684   mp->eid_len = eid->len;
18685   mp->seid_len = seid->len;
18686   mp->del_all = del_all;
18687   mp->eid_type = eid->type;
18688   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18689   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18690
18691   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18692   clib_memcpy (mp->rlocs, rlocs, data_len);
18693   vec_free (rlocs);
18694
18695   /* send it... */
18696   S (mp);
18697
18698   /* Wait for a reply... */
18699   W (ret);
18700   return ret;
18701 }
18702
18703 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18704
18705 /**
18706  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18707  * forwarding entries in data-plane accordingly.
18708  *
18709  * @param vam vpp API test context
18710  * @return return code
18711  */
18712 static int
18713 api_one_add_del_adjacency (vat_main_t * vam)
18714 {
18715   unformat_input_t *input = vam->input;
18716   vl_api_one_add_del_adjacency_t *mp;
18717   u32 vni = 0;
18718   ip4_address_t leid4, reid4;
18719   ip6_address_t leid6, reid6;
18720   u8 reid_mac[6] = { 0 };
18721   u8 leid_mac[6] = { 0 };
18722   u8 reid_type, leid_type;
18723   u32 leid_len = 0, reid_len = 0, len;
18724   u8 is_add = 1;
18725   int ret;
18726
18727   leid_type = reid_type = (u8) ~ 0;
18728
18729   /* Parse args required to build the message */
18730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18731     {
18732       if (unformat (input, "del"))
18733         {
18734           is_add = 0;
18735         }
18736       else if (unformat (input, "add"))
18737         {
18738           is_add = 1;
18739         }
18740       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18741                          &reid4, &len))
18742         {
18743           reid_type = 0;        /* ipv4 */
18744           reid_len = len;
18745         }
18746       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18747                          &reid6, &len))
18748         {
18749           reid_type = 1;        /* ipv6 */
18750           reid_len = len;
18751         }
18752       else if (unformat (input, "reid %U", unformat_ethernet_address,
18753                          reid_mac))
18754         {
18755           reid_type = 2;        /* mac */
18756         }
18757       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18758                          &leid4, &len))
18759         {
18760           leid_type = 0;        /* ipv4 */
18761           leid_len = len;
18762         }
18763       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18764                          &leid6, &len))
18765         {
18766           leid_type = 1;        /* ipv6 */
18767           leid_len = len;
18768         }
18769       else if (unformat (input, "leid %U", unformat_ethernet_address,
18770                          leid_mac))
18771         {
18772           leid_type = 2;        /* mac */
18773         }
18774       else if (unformat (input, "vni %d", &vni))
18775         {
18776           ;
18777         }
18778       else
18779         {
18780           errmsg ("parse error '%U'", format_unformat_error, input);
18781           return -99;
18782         }
18783     }
18784
18785   if ((u8) ~ 0 == reid_type)
18786     {
18787       errmsg ("missing params!");
18788       return -99;
18789     }
18790
18791   if (leid_type != reid_type)
18792     {
18793       errmsg ("remote and local EIDs are of different types!");
18794       return -99;
18795     }
18796
18797   M (ONE_ADD_DEL_ADJACENCY, mp);
18798   mp->is_add = is_add;
18799   mp->vni = htonl (vni);
18800   mp->leid_len = leid_len;
18801   mp->reid_len = reid_len;
18802   mp->eid_type = reid_type;
18803
18804   switch (mp->eid_type)
18805     {
18806     case 0:
18807       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18808       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18809       break;
18810     case 1:
18811       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18812       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18813       break;
18814     case 2:
18815       clib_memcpy (mp->leid, leid_mac, 6);
18816       clib_memcpy (mp->reid, reid_mac, 6);
18817       break;
18818     default:
18819       errmsg ("unknown EID type %d!", mp->eid_type);
18820       return 0;
18821     }
18822
18823   /* send it... */
18824   S (mp);
18825
18826   /* Wait for a reply... */
18827   W (ret);
18828   return ret;
18829 }
18830
18831 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18832
18833 uword
18834 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18835 {
18836   u32 *mode = va_arg (*args, u32 *);
18837
18838   if (unformat (input, "lisp"))
18839     *mode = 0;
18840   else if (unformat (input, "vxlan"))
18841     *mode = 1;
18842   else
18843     return 0;
18844
18845   return 1;
18846 }
18847
18848 static int
18849 api_gpe_get_encap_mode (vat_main_t * vam)
18850 {
18851   vl_api_gpe_get_encap_mode_t *mp;
18852   int ret;
18853
18854   /* Construct the API message */
18855   M (GPE_GET_ENCAP_MODE, mp);
18856
18857   /* send it... */
18858   S (mp);
18859
18860   /* Wait for a reply... */
18861   W (ret);
18862   return ret;
18863 }
18864
18865 static int
18866 api_gpe_set_encap_mode (vat_main_t * vam)
18867 {
18868   unformat_input_t *input = vam->input;
18869   vl_api_gpe_set_encap_mode_t *mp;
18870   int ret;
18871   u32 mode = 0;
18872
18873   /* Parse args required to build the message */
18874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18875     {
18876       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18877         ;
18878       else
18879         break;
18880     }
18881
18882   /* Construct the API message */
18883   M (GPE_SET_ENCAP_MODE, mp);
18884
18885   mp->mode = mode;
18886
18887   /* send it... */
18888   S (mp);
18889
18890   /* Wait for a reply... */
18891   W (ret);
18892   return ret;
18893 }
18894
18895 static int
18896 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18897 {
18898   unformat_input_t *input = vam->input;
18899   vl_api_gpe_add_del_iface_t *mp;
18900   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18901   u32 dp_table = 0, vni = 0;
18902   int ret;
18903
18904   /* Parse args required to build the message */
18905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18906     {
18907       if (unformat (input, "up"))
18908         {
18909           action_set = 1;
18910           is_add = 1;
18911         }
18912       else if (unformat (input, "down"))
18913         {
18914           action_set = 1;
18915           is_add = 0;
18916         }
18917       else if (unformat (input, "table_id %d", &dp_table))
18918         {
18919           dp_table_set = 1;
18920         }
18921       else if (unformat (input, "bd_id %d", &dp_table))
18922         {
18923           dp_table_set = 1;
18924           is_l2 = 1;
18925         }
18926       else if (unformat (input, "vni %d", &vni))
18927         {
18928           vni_set = 1;
18929         }
18930       else
18931         break;
18932     }
18933
18934   if (action_set == 0)
18935     {
18936       errmsg ("Action not set");
18937       return -99;
18938     }
18939   if (dp_table_set == 0 || vni_set == 0)
18940     {
18941       errmsg ("vni and dp_table must be set");
18942       return -99;
18943     }
18944
18945   /* Construct the API message */
18946   M (GPE_ADD_DEL_IFACE, mp);
18947
18948   mp->is_add = is_add;
18949   mp->dp_table = clib_host_to_net_u32 (dp_table);
18950   mp->is_l2 = is_l2;
18951   mp->vni = clib_host_to_net_u32 (vni);
18952
18953   /* send it... */
18954   S (mp);
18955
18956   /* Wait for a reply... */
18957   W (ret);
18958   return ret;
18959 }
18960
18961 static int
18962 api_one_map_register_fallback_threshold (vat_main_t * vam)
18963 {
18964   unformat_input_t *input = vam->input;
18965   vl_api_one_map_register_fallback_threshold_t *mp;
18966   u32 value = 0;
18967   u8 is_set = 0;
18968   int ret;
18969
18970   /* Parse args required to build the message */
18971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18972     {
18973       if (unformat (input, "%u", &value))
18974         is_set = 1;
18975       else
18976         {
18977           clib_warning ("parse error '%U'", format_unformat_error, input);
18978           return -99;
18979         }
18980     }
18981
18982   if (!is_set)
18983     {
18984       errmsg ("fallback threshold value is missing!");
18985       return -99;
18986     }
18987
18988   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18989   mp->value = clib_host_to_net_u32 (value);
18990
18991   /* send it... */
18992   S (mp);
18993
18994   /* Wait for a reply... */
18995   W (ret);
18996   return ret;
18997 }
18998
18999 static int
19000 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
19001 {
19002   vl_api_show_one_map_register_fallback_threshold_t *mp;
19003   int ret;
19004
19005   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19006
19007   /* send it... */
19008   S (mp);
19009
19010   /* Wait for a reply... */
19011   W (ret);
19012   return ret;
19013 }
19014
19015 uword
19016 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
19017 {
19018   u32 *proto = va_arg (*args, u32 *);
19019
19020   if (unformat (input, "udp"))
19021     *proto = 1;
19022   else if (unformat (input, "api"))
19023     *proto = 2;
19024   else
19025     return 0;
19026
19027   return 1;
19028 }
19029
19030 static int
19031 api_one_set_transport_protocol (vat_main_t * vam)
19032 {
19033   unformat_input_t *input = vam->input;
19034   vl_api_one_set_transport_protocol_t *mp;
19035   u8 is_set = 0;
19036   u32 protocol = 0;
19037   int ret;
19038
19039   /* Parse args required to build the message */
19040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19041     {
19042       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
19043         is_set = 1;
19044       else
19045         {
19046           clib_warning ("parse error '%U'", format_unformat_error, input);
19047           return -99;
19048         }
19049     }
19050
19051   if (!is_set)
19052     {
19053       errmsg ("Transport protocol missing!");
19054       return -99;
19055     }
19056
19057   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
19058   mp->protocol = (u8) protocol;
19059
19060   /* send it... */
19061   S (mp);
19062
19063   /* Wait for a reply... */
19064   W (ret);
19065   return ret;
19066 }
19067
19068 static int
19069 api_one_get_transport_protocol (vat_main_t * vam)
19070 {
19071   vl_api_one_get_transport_protocol_t *mp;
19072   int ret;
19073
19074   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19075
19076   /* send it... */
19077   S (mp);
19078
19079   /* Wait for a reply... */
19080   W (ret);
19081   return ret;
19082 }
19083
19084 static int
19085 api_one_map_register_set_ttl (vat_main_t * vam)
19086 {
19087   unformat_input_t *input = vam->input;
19088   vl_api_one_map_register_set_ttl_t *mp;
19089   u32 ttl = 0;
19090   u8 is_set = 0;
19091   int ret;
19092
19093   /* Parse args required to build the message */
19094   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19095     {
19096       if (unformat (input, "%u", &ttl))
19097         is_set = 1;
19098       else
19099         {
19100           clib_warning ("parse error '%U'", format_unformat_error, input);
19101           return -99;
19102         }
19103     }
19104
19105   if (!is_set)
19106     {
19107       errmsg ("TTL value missing!");
19108       return -99;
19109     }
19110
19111   M (ONE_MAP_REGISTER_SET_TTL, mp);
19112   mp->ttl = clib_host_to_net_u32 (ttl);
19113
19114   /* send it... */
19115   S (mp);
19116
19117   /* Wait for a reply... */
19118   W (ret);
19119   return ret;
19120 }
19121
19122 static int
19123 api_show_one_map_register_ttl (vat_main_t * vam)
19124 {
19125   vl_api_show_one_map_register_ttl_t *mp;
19126   int ret;
19127
19128   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19129
19130   /* send it... */
19131   S (mp);
19132
19133   /* Wait for a reply... */
19134   W (ret);
19135   return ret;
19136 }
19137
19138 /**
19139  * Add/del map request itr rlocs from ONE control plane and updates
19140  *
19141  * @param vam vpp API test context
19142  * @return return code
19143  */
19144 static int
19145 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19146 {
19147   unformat_input_t *input = vam->input;
19148   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19149   u8 *locator_set_name = 0;
19150   u8 locator_set_name_set = 0;
19151   u8 is_add = 1;
19152   int ret;
19153
19154   /* Parse args required to build the message */
19155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19156     {
19157       if (unformat (input, "del"))
19158         {
19159           is_add = 0;
19160         }
19161       else if (unformat (input, "%_%v%_", &locator_set_name))
19162         {
19163           locator_set_name_set = 1;
19164         }
19165       else
19166         {
19167           clib_warning ("parse error '%U'", format_unformat_error, input);
19168           return -99;
19169         }
19170     }
19171
19172   if (is_add && !locator_set_name_set)
19173     {
19174       errmsg ("itr-rloc is not set!");
19175       return -99;
19176     }
19177
19178   if (is_add && vec_len (locator_set_name) > 64)
19179     {
19180       errmsg ("itr-rloc locator-set name too long");
19181       vec_free (locator_set_name);
19182       return -99;
19183     }
19184
19185   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19186   mp->is_add = is_add;
19187   if (is_add)
19188     {
19189       clib_memcpy (mp->locator_set_name, locator_set_name,
19190                    vec_len (locator_set_name));
19191     }
19192   else
19193     {
19194       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19195     }
19196   vec_free (locator_set_name);
19197
19198   /* send it... */
19199   S (mp);
19200
19201   /* Wait for a reply... */
19202   W (ret);
19203   return ret;
19204 }
19205
19206 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19207
19208 static int
19209 api_one_locator_dump (vat_main_t * vam)
19210 {
19211   unformat_input_t *input = vam->input;
19212   vl_api_one_locator_dump_t *mp;
19213   vl_api_control_ping_t *mp_ping;
19214   u8 is_index_set = 0, is_name_set = 0;
19215   u8 *ls_name = 0;
19216   u32 ls_index = ~0;
19217   int ret;
19218
19219   /* Parse args required to build the message */
19220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19221     {
19222       if (unformat (input, "ls_name %_%v%_", &ls_name))
19223         {
19224           is_name_set = 1;
19225         }
19226       else if (unformat (input, "ls_index %d", &ls_index))
19227         {
19228           is_index_set = 1;
19229         }
19230       else
19231         {
19232           errmsg ("parse error '%U'", format_unformat_error, input);
19233           return -99;
19234         }
19235     }
19236
19237   if (!is_index_set && !is_name_set)
19238     {
19239       errmsg ("error: expected one of index or name!");
19240       return -99;
19241     }
19242
19243   if (is_index_set && is_name_set)
19244     {
19245       errmsg ("error: only one param expected!");
19246       return -99;
19247     }
19248
19249   if (vec_len (ls_name) > 62)
19250     {
19251       errmsg ("error: locator set name too long!");
19252       return -99;
19253     }
19254
19255   if (!vam->json_output)
19256     {
19257       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19258     }
19259
19260   M (ONE_LOCATOR_DUMP, mp);
19261   mp->is_index_set = is_index_set;
19262
19263   if (is_index_set)
19264     mp->ls_index = clib_host_to_net_u32 (ls_index);
19265   else
19266     {
19267       vec_add1 (ls_name, 0);
19268       strncpy ((char *) mp->ls_name, (char *) ls_name,
19269                sizeof (mp->ls_name) - 1);
19270     }
19271
19272   /* send it... */
19273   S (mp);
19274
19275   /* Use a control ping for synchronization */
19276   MPING (CONTROL_PING, mp_ping);
19277   S (mp_ping);
19278
19279   /* Wait for a reply... */
19280   W (ret);
19281   return ret;
19282 }
19283
19284 #define api_lisp_locator_dump api_one_locator_dump
19285
19286 static int
19287 api_one_locator_set_dump (vat_main_t * vam)
19288 {
19289   vl_api_one_locator_set_dump_t *mp;
19290   vl_api_control_ping_t *mp_ping;
19291   unformat_input_t *input = vam->input;
19292   u8 filter = 0;
19293   int ret;
19294
19295   /* Parse args required to build the message */
19296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19297     {
19298       if (unformat (input, "local"))
19299         {
19300           filter = 1;
19301         }
19302       else if (unformat (input, "remote"))
19303         {
19304           filter = 2;
19305         }
19306       else
19307         {
19308           errmsg ("parse error '%U'", format_unformat_error, input);
19309           return -99;
19310         }
19311     }
19312
19313   if (!vam->json_output)
19314     {
19315       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19316     }
19317
19318   M (ONE_LOCATOR_SET_DUMP, mp);
19319
19320   mp->filter = filter;
19321
19322   /* send it... */
19323   S (mp);
19324
19325   /* Use a control ping for synchronization */
19326   MPING (CONTROL_PING, mp_ping);
19327   S (mp_ping);
19328
19329   /* Wait for a reply... */
19330   W (ret);
19331   return ret;
19332 }
19333
19334 #define api_lisp_locator_set_dump api_one_locator_set_dump
19335
19336 static int
19337 api_one_eid_table_map_dump (vat_main_t * vam)
19338 {
19339   u8 is_l2 = 0;
19340   u8 mode_set = 0;
19341   unformat_input_t *input = vam->input;
19342   vl_api_one_eid_table_map_dump_t *mp;
19343   vl_api_control_ping_t *mp_ping;
19344   int ret;
19345
19346   /* Parse args required to build the message */
19347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19348     {
19349       if (unformat (input, "l2"))
19350         {
19351           is_l2 = 1;
19352           mode_set = 1;
19353         }
19354       else if (unformat (input, "l3"))
19355         {
19356           is_l2 = 0;
19357           mode_set = 1;
19358         }
19359       else
19360         {
19361           errmsg ("parse error '%U'", format_unformat_error, input);
19362           return -99;
19363         }
19364     }
19365
19366   if (!mode_set)
19367     {
19368       errmsg ("expected one of 'l2' or 'l3' parameter!");
19369       return -99;
19370     }
19371
19372   if (!vam->json_output)
19373     {
19374       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19375     }
19376
19377   M (ONE_EID_TABLE_MAP_DUMP, mp);
19378   mp->is_l2 = is_l2;
19379
19380   /* send it... */
19381   S (mp);
19382
19383   /* Use a control ping for synchronization */
19384   MPING (CONTROL_PING, mp_ping);
19385   S (mp_ping);
19386
19387   /* Wait for a reply... */
19388   W (ret);
19389   return ret;
19390 }
19391
19392 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19393
19394 static int
19395 api_one_eid_table_vni_dump (vat_main_t * vam)
19396 {
19397   vl_api_one_eid_table_vni_dump_t *mp;
19398   vl_api_control_ping_t *mp_ping;
19399   int ret;
19400
19401   if (!vam->json_output)
19402     {
19403       print (vam->ofp, "VNI");
19404     }
19405
19406   M (ONE_EID_TABLE_VNI_DUMP, mp);
19407
19408   /* send it... */
19409   S (mp);
19410
19411   /* Use a control ping for synchronization */
19412   MPING (CONTROL_PING, mp_ping);
19413   S (mp_ping);
19414
19415   /* Wait for a reply... */
19416   W (ret);
19417   return ret;
19418 }
19419
19420 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19421
19422 static int
19423 api_one_eid_table_dump (vat_main_t * vam)
19424 {
19425   unformat_input_t *i = vam->input;
19426   vl_api_one_eid_table_dump_t *mp;
19427   vl_api_control_ping_t *mp_ping;
19428   struct in_addr ip4;
19429   struct in6_addr ip6;
19430   u8 mac[6];
19431   u8 eid_type = ~0, eid_set = 0;
19432   u32 prefix_length = ~0, t, vni = 0;
19433   u8 filter = 0;
19434   int ret;
19435   lisp_nsh_api_t nsh;
19436
19437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19438     {
19439       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19440         {
19441           eid_set = 1;
19442           eid_type = 0;
19443           prefix_length = t;
19444         }
19445       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19446         {
19447           eid_set = 1;
19448           eid_type = 1;
19449           prefix_length = t;
19450         }
19451       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19452         {
19453           eid_set = 1;
19454           eid_type = 2;
19455         }
19456       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19457         {
19458           eid_set = 1;
19459           eid_type = 3;
19460         }
19461       else if (unformat (i, "vni %d", &t))
19462         {
19463           vni = t;
19464         }
19465       else if (unformat (i, "local"))
19466         {
19467           filter = 1;
19468         }
19469       else if (unformat (i, "remote"))
19470         {
19471           filter = 2;
19472         }
19473       else
19474         {
19475           errmsg ("parse error '%U'", format_unformat_error, i);
19476           return -99;
19477         }
19478     }
19479
19480   if (!vam->json_output)
19481     {
19482       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19483              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19484     }
19485
19486   M (ONE_EID_TABLE_DUMP, mp);
19487
19488   mp->filter = filter;
19489   if (eid_set)
19490     {
19491       mp->eid_set = 1;
19492       mp->vni = htonl (vni);
19493       mp->eid_type = eid_type;
19494       switch (eid_type)
19495         {
19496         case 0:
19497           mp->prefix_length = prefix_length;
19498           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19499           break;
19500         case 1:
19501           mp->prefix_length = prefix_length;
19502           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19503           break;
19504         case 2:
19505           clib_memcpy (mp->eid, mac, sizeof (mac));
19506           break;
19507         case 3:
19508           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19509           break;
19510         default:
19511           errmsg ("unknown EID type %d!", eid_type);
19512           return -99;
19513         }
19514     }
19515
19516   /* send it... */
19517   S (mp);
19518
19519   /* Use a control ping for synchronization */
19520   MPING (CONTROL_PING, mp_ping);
19521   S (mp_ping);
19522
19523   /* Wait for a reply... */
19524   W (ret);
19525   return ret;
19526 }
19527
19528 #define api_lisp_eid_table_dump api_one_eid_table_dump
19529
19530 static int
19531 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19532 {
19533   unformat_input_t *i = vam->input;
19534   vl_api_gpe_fwd_entries_get_t *mp;
19535   u8 vni_set = 0;
19536   u32 vni = ~0;
19537   int ret;
19538
19539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19540     {
19541       if (unformat (i, "vni %d", &vni))
19542         {
19543           vni_set = 1;
19544         }
19545       else
19546         {
19547           errmsg ("parse error '%U'", format_unformat_error, i);
19548           return -99;
19549         }
19550     }
19551
19552   if (!vni_set)
19553     {
19554       errmsg ("vni not set!");
19555       return -99;
19556     }
19557
19558   if (!vam->json_output)
19559     {
19560       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19561              "leid", "reid");
19562     }
19563
19564   M (GPE_FWD_ENTRIES_GET, mp);
19565   mp->vni = clib_host_to_net_u32 (vni);
19566
19567   /* send it... */
19568   S (mp);
19569
19570   /* Wait for a reply... */
19571   W (ret);
19572   return ret;
19573 }
19574
19575 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19576 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19577 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19578 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19579 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19580 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19581 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19582 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19583
19584 static int
19585 api_one_adjacencies_get (vat_main_t * vam)
19586 {
19587   unformat_input_t *i = vam->input;
19588   vl_api_one_adjacencies_get_t *mp;
19589   u8 vni_set = 0;
19590   u32 vni = ~0;
19591   int ret;
19592
19593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19594     {
19595       if (unformat (i, "vni %d", &vni))
19596         {
19597           vni_set = 1;
19598         }
19599       else
19600         {
19601           errmsg ("parse error '%U'", format_unformat_error, i);
19602           return -99;
19603         }
19604     }
19605
19606   if (!vni_set)
19607     {
19608       errmsg ("vni not set!");
19609       return -99;
19610     }
19611
19612   if (!vam->json_output)
19613     {
19614       print (vam->ofp, "%s %40s", "leid", "reid");
19615     }
19616
19617   M (ONE_ADJACENCIES_GET, mp);
19618   mp->vni = clib_host_to_net_u32 (vni);
19619
19620   /* send it... */
19621   S (mp);
19622
19623   /* Wait for a reply... */
19624   W (ret);
19625   return ret;
19626 }
19627
19628 #define api_lisp_adjacencies_get api_one_adjacencies_get
19629
19630 static int
19631 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19632 {
19633   unformat_input_t *i = vam->input;
19634   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19635   int ret;
19636   u8 ip_family_set = 0, is_ip4 = 1;
19637
19638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19639     {
19640       if (unformat (i, "ip4"))
19641         {
19642           ip_family_set = 1;
19643           is_ip4 = 1;
19644         }
19645       else if (unformat (i, "ip6"))
19646         {
19647           ip_family_set = 1;
19648           is_ip4 = 0;
19649         }
19650       else
19651         {
19652           errmsg ("parse error '%U'", format_unformat_error, i);
19653           return -99;
19654         }
19655     }
19656
19657   if (!ip_family_set)
19658     {
19659       errmsg ("ip family not set!");
19660       return -99;
19661     }
19662
19663   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19664   mp->is_ip4 = is_ip4;
19665
19666   /* send it... */
19667   S (mp);
19668
19669   /* Wait for a reply... */
19670   W (ret);
19671   return ret;
19672 }
19673
19674 static int
19675 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19676 {
19677   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19678   int ret;
19679
19680   if (!vam->json_output)
19681     {
19682       print (vam->ofp, "VNIs");
19683     }
19684
19685   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19686
19687   /* send it... */
19688   S (mp);
19689
19690   /* Wait for a reply... */
19691   W (ret);
19692   return ret;
19693 }
19694
19695 static int
19696 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19697 {
19698   unformat_input_t *i = vam->input;
19699   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19700   int ret = 0;
19701   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19702   struct in_addr ip4;
19703   struct in6_addr ip6;
19704   u32 table_id = 0, nh_sw_if_index = ~0;
19705
19706   clib_memset (&ip4, 0, sizeof (ip4));
19707   clib_memset (&ip6, 0, sizeof (ip6));
19708
19709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19710     {
19711       if (unformat (i, "del"))
19712         is_add = 0;
19713       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19714                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19715         {
19716           ip_set = 1;
19717           is_ip4 = 1;
19718         }
19719       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19720                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19721         {
19722           ip_set = 1;
19723           is_ip4 = 0;
19724         }
19725       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19726         {
19727           ip_set = 1;
19728           is_ip4 = 1;
19729           nh_sw_if_index = ~0;
19730         }
19731       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19732         {
19733           ip_set = 1;
19734           is_ip4 = 0;
19735           nh_sw_if_index = ~0;
19736         }
19737       else if (unformat (i, "table %d", &table_id))
19738         ;
19739       else
19740         {
19741           errmsg ("parse error '%U'", format_unformat_error, i);
19742           return -99;
19743         }
19744     }
19745
19746   if (!ip_set)
19747     {
19748       errmsg ("nh addr not set!");
19749       return -99;
19750     }
19751
19752   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19753   mp->is_add = is_add;
19754   mp->table_id = clib_host_to_net_u32 (table_id);
19755   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19756   mp->is_ip4 = is_ip4;
19757   if (is_ip4)
19758     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19759   else
19760     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19761
19762   /* send it... */
19763   S (mp);
19764
19765   /* Wait for a reply... */
19766   W (ret);
19767   return ret;
19768 }
19769
19770 static int
19771 api_one_map_server_dump (vat_main_t * vam)
19772 {
19773   vl_api_one_map_server_dump_t *mp;
19774   vl_api_control_ping_t *mp_ping;
19775   int ret;
19776
19777   if (!vam->json_output)
19778     {
19779       print (vam->ofp, "%=20s", "Map server");
19780     }
19781
19782   M (ONE_MAP_SERVER_DUMP, mp);
19783   /* send it... */
19784   S (mp);
19785
19786   /* Use a control ping for synchronization */
19787   MPING (CONTROL_PING, mp_ping);
19788   S (mp_ping);
19789
19790   /* Wait for a reply... */
19791   W (ret);
19792   return ret;
19793 }
19794
19795 #define api_lisp_map_server_dump api_one_map_server_dump
19796
19797 static int
19798 api_one_map_resolver_dump (vat_main_t * vam)
19799 {
19800   vl_api_one_map_resolver_dump_t *mp;
19801   vl_api_control_ping_t *mp_ping;
19802   int ret;
19803
19804   if (!vam->json_output)
19805     {
19806       print (vam->ofp, "%=20s", "Map resolver");
19807     }
19808
19809   M (ONE_MAP_RESOLVER_DUMP, mp);
19810   /* send it... */
19811   S (mp);
19812
19813   /* Use a control ping for synchronization */
19814   MPING (CONTROL_PING, mp_ping);
19815   S (mp_ping);
19816
19817   /* Wait for a reply... */
19818   W (ret);
19819   return ret;
19820 }
19821
19822 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19823
19824 static int
19825 api_one_stats_flush (vat_main_t * vam)
19826 {
19827   vl_api_one_stats_flush_t *mp;
19828   int ret = 0;
19829
19830   M (ONE_STATS_FLUSH, mp);
19831   S (mp);
19832   W (ret);
19833   return ret;
19834 }
19835
19836 static int
19837 api_one_stats_dump (vat_main_t * vam)
19838 {
19839   vl_api_one_stats_dump_t *mp;
19840   vl_api_control_ping_t *mp_ping;
19841   int ret;
19842
19843   M (ONE_STATS_DUMP, mp);
19844   /* send it... */
19845   S (mp);
19846
19847   /* Use a control ping for synchronization */
19848   MPING (CONTROL_PING, mp_ping);
19849   S (mp_ping);
19850
19851   /* Wait for a reply... */
19852   W (ret);
19853   return ret;
19854 }
19855
19856 static int
19857 api_show_one_status (vat_main_t * vam)
19858 {
19859   vl_api_show_one_status_t *mp;
19860   int ret;
19861
19862   if (!vam->json_output)
19863     {
19864       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19865     }
19866
19867   M (SHOW_ONE_STATUS, mp);
19868   /* send it... */
19869   S (mp);
19870   /* Wait for a reply... */
19871   W (ret);
19872   return ret;
19873 }
19874
19875 #define api_show_lisp_status api_show_one_status
19876
19877 static int
19878 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19879 {
19880   vl_api_gpe_fwd_entry_path_dump_t *mp;
19881   vl_api_control_ping_t *mp_ping;
19882   unformat_input_t *i = vam->input;
19883   u32 fwd_entry_index = ~0;
19884   int ret;
19885
19886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19887     {
19888       if (unformat (i, "index %d", &fwd_entry_index))
19889         ;
19890       else
19891         break;
19892     }
19893
19894   if (~0 == fwd_entry_index)
19895     {
19896       errmsg ("no index specified!");
19897       return -99;
19898     }
19899
19900   if (!vam->json_output)
19901     {
19902       print (vam->ofp, "first line");
19903     }
19904
19905   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19906
19907   /* send it... */
19908   S (mp);
19909   /* Use a control ping for synchronization */
19910   MPING (CONTROL_PING, mp_ping);
19911   S (mp_ping);
19912
19913   /* Wait for a reply... */
19914   W (ret);
19915   return ret;
19916 }
19917
19918 static int
19919 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19920 {
19921   vl_api_one_get_map_request_itr_rlocs_t *mp;
19922   int ret;
19923
19924   if (!vam->json_output)
19925     {
19926       print (vam->ofp, "%=20s", "itr-rlocs:");
19927     }
19928
19929   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19930   /* send it... */
19931   S (mp);
19932   /* Wait for a reply... */
19933   W (ret);
19934   return ret;
19935 }
19936
19937 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19938
19939 static int
19940 api_af_packet_create (vat_main_t * vam)
19941 {
19942   unformat_input_t *i = vam->input;
19943   vl_api_af_packet_create_t *mp;
19944   u8 *host_if_name = 0;
19945   u8 hw_addr[6];
19946   u8 random_hw_addr = 1;
19947   int ret;
19948
19949   clib_memset (hw_addr, 0, sizeof (hw_addr));
19950
19951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19952     {
19953       if (unformat (i, "name %s", &host_if_name))
19954         vec_add1 (host_if_name, 0);
19955       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19956         random_hw_addr = 0;
19957       else
19958         break;
19959     }
19960
19961   if (!vec_len (host_if_name))
19962     {
19963       errmsg ("host-interface name must be specified");
19964       return -99;
19965     }
19966
19967   if (vec_len (host_if_name) > 64)
19968     {
19969       errmsg ("host-interface name too long");
19970       return -99;
19971     }
19972
19973   M (AF_PACKET_CREATE, mp);
19974
19975   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19976   clib_memcpy (mp->hw_addr, hw_addr, 6);
19977   mp->use_random_hw_addr = random_hw_addr;
19978   vec_free (host_if_name);
19979
19980   S (mp);
19981
19982   /* *INDENT-OFF* */
19983   W2 (ret,
19984       ({
19985         if (ret == 0)
19986           fprintf (vam->ofp ? vam->ofp : stderr,
19987                    " new sw_if_index = %d\n", vam->sw_if_index);
19988       }));
19989   /* *INDENT-ON* */
19990   return ret;
19991 }
19992
19993 static int
19994 api_af_packet_delete (vat_main_t * vam)
19995 {
19996   unformat_input_t *i = vam->input;
19997   vl_api_af_packet_delete_t *mp;
19998   u8 *host_if_name = 0;
19999   int ret;
20000
20001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20002     {
20003       if (unformat (i, "name %s", &host_if_name))
20004         vec_add1 (host_if_name, 0);
20005       else
20006         break;
20007     }
20008
20009   if (!vec_len (host_if_name))
20010     {
20011       errmsg ("host-interface name must be specified");
20012       return -99;
20013     }
20014
20015   if (vec_len (host_if_name) > 64)
20016     {
20017       errmsg ("host-interface name too long");
20018       return -99;
20019     }
20020
20021   M (AF_PACKET_DELETE, mp);
20022
20023   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20024   vec_free (host_if_name);
20025
20026   S (mp);
20027   W (ret);
20028   return ret;
20029 }
20030
20031 static void vl_api_af_packet_details_t_handler
20032   (vl_api_af_packet_details_t * mp)
20033 {
20034   vat_main_t *vam = &vat_main;
20035
20036   print (vam->ofp, "%-16s %d",
20037          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
20038 }
20039
20040 static void vl_api_af_packet_details_t_handler_json
20041   (vl_api_af_packet_details_t * mp)
20042 {
20043   vat_main_t *vam = &vat_main;
20044   vat_json_node_t *node = NULL;
20045
20046   if (VAT_JSON_ARRAY != vam->json_tree.type)
20047     {
20048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20049       vat_json_init_array (&vam->json_tree);
20050     }
20051   node = vat_json_array_add (&vam->json_tree);
20052
20053   vat_json_init_object (node);
20054   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20055   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
20056 }
20057
20058 static int
20059 api_af_packet_dump (vat_main_t * vam)
20060 {
20061   vl_api_af_packet_dump_t *mp;
20062   vl_api_control_ping_t *mp_ping;
20063   int ret;
20064
20065   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
20066   /* Get list of tap interfaces */
20067   M (AF_PACKET_DUMP, mp);
20068   S (mp);
20069
20070   /* Use a control ping for synchronization */
20071   MPING (CONTROL_PING, mp_ping);
20072   S (mp_ping);
20073
20074   W (ret);
20075   return ret;
20076 }
20077
20078 static int
20079 api_policer_add_del (vat_main_t * vam)
20080 {
20081   unformat_input_t *i = vam->input;
20082   vl_api_policer_add_del_t *mp;
20083   u8 is_add = 1;
20084   u8 *name = 0;
20085   u32 cir = 0;
20086   u32 eir = 0;
20087   u64 cb = 0;
20088   u64 eb = 0;
20089   u8 rate_type = 0;
20090   u8 round_type = 0;
20091   u8 type = 0;
20092   u8 color_aware = 0;
20093   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20094   int ret;
20095
20096   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20097   conform_action.dscp = 0;
20098   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20099   exceed_action.dscp = 0;
20100   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20101   violate_action.dscp = 0;
20102
20103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20104     {
20105       if (unformat (i, "del"))
20106         is_add = 0;
20107       else if (unformat (i, "name %s", &name))
20108         vec_add1 (name, 0);
20109       else if (unformat (i, "cir %u", &cir))
20110         ;
20111       else if (unformat (i, "eir %u", &eir))
20112         ;
20113       else if (unformat (i, "cb %u", &cb))
20114         ;
20115       else if (unformat (i, "eb %u", &eb))
20116         ;
20117       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20118                          &rate_type))
20119         ;
20120       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20121                          &round_type))
20122         ;
20123       else if (unformat (i, "type %U", unformat_policer_type, &type))
20124         ;
20125       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20126                          &conform_action))
20127         ;
20128       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20129                          &exceed_action))
20130         ;
20131       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20132                          &violate_action))
20133         ;
20134       else if (unformat (i, "color-aware"))
20135         color_aware = 1;
20136       else
20137         break;
20138     }
20139
20140   if (!vec_len (name))
20141     {
20142       errmsg ("policer name must be specified");
20143       return -99;
20144     }
20145
20146   if (vec_len (name) > 64)
20147     {
20148       errmsg ("policer name too long");
20149       return -99;
20150     }
20151
20152   M (POLICER_ADD_DEL, mp);
20153
20154   clib_memcpy (mp->name, name, vec_len (name));
20155   vec_free (name);
20156   mp->is_add = is_add;
20157   mp->cir = ntohl (cir);
20158   mp->eir = ntohl (eir);
20159   mp->cb = clib_net_to_host_u64 (cb);
20160   mp->eb = clib_net_to_host_u64 (eb);
20161   mp->rate_type = rate_type;
20162   mp->round_type = round_type;
20163   mp->type = type;
20164   mp->conform_action_type = conform_action.action_type;
20165   mp->conform_dscp = conform_action.dscp;
20166   mp->exceed_action_type = exceed_action.action_type;
20167   mp->exceed_dscp = exceed_action.dscp;
20168   mp->violate_action_type = violate_action.action_type;
20169   mp->violate_dscp = violate_action.dscp;
20170   mp->color_aware = color_aware;
20171
20172   S (mp);
20173   W (ret);
20174   return ret;
20175 }
20176
20177 static int
20178 api_policer_dump (vat_main_t * vam)
20179 {
20180   unformat_input_t *i = vam->input;
20181   vl_api_policer_dump_t *mp;
20182   vl_api_control_ping_t *mp_ping;
20183   u8 *match_name = 0;
20184   u8 match_name_valid = 0;
20185   int ret;
20186
20187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20188     {
20189       if (unformat (i, "name %s", &match_name))
20190         {
20191           vec_add1 (match_name, 0);
20192           match_name_valid = 1;
20193         }
20194       else
20195         break;
20196     }
20197
20198   M (POLICER_DUMP, mp);
20199   mp->match_name_valid = match_name_valid;
20200   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20201   vec_free (match_name);
20202   /* send it... */
20203   S (mp);
20204
20205   /* Use a control ping for synchronization */
20206   MPING (CONTROL_PING, mp_ping);
20207   S (mp_ping);
20208
20209   /* Wait for a reply... */
20210   W (ret);
20211   return ret;
20212 }
20213
20214 static int
20215 api_policer_classify_set_interface (vat_main_t * vam)
20216 {
20217   unformat_input_t *i = vam->input;
20218   vl_api_policer_classify_set_interface_t *mp;
20219   u32 sw_if_index;
20220   int sw_if_index_set;
20221   u32 ip4_table_index = ~0;
20222   u32 ip6_table_index = ~0;
20223   u32 l2_table_index = ~0;
20224   u8 is_add = 1;
20225   int ret;
20226
20227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20228     {
20229       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20230         sw_if_index_set = 1;
20231       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20232         sw_if_index_set = 1;
20233       else if (unformat (i, "del"))
20234         is_add = 0;
20235       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20236         ;
20237       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20238         ;
20239       else if (unformat (i, "l2-table %d", &l2_table_index))
20240         ;
20241       else
20242         {
20243           clib_warning ("parse error '%U'", format_unformat_error, i);
20244           return -99;
20245         }
20246     }
20247
20248   if (sw_if_index_set == 0)
20249     {
20250       errmsg ("missing interface name or sw_if_index");
20251       return -99;
20252     }
20253
20254   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20255
20256   mp->sw_if_index = ntohl (sw_if_index);
20257   mp->ip4_table_index = ntohl (ip4_table_index);
20258   mp->ip6_table_index = ntohl (ip6_table_index);
20259   mp->l2_table_index = ntohl (l2_table_index);
20260   mp->is_add = is_add;
20261
20262   S (mp);
20263   W (ret);
20264   return ret;
20265 }
20266
20267 static int
20268 api_policer_classify_dump (vat_main_t * vam)
20269 {
20270   unformat_input_t *i = vam->input;
20271   vl_api_policer_classify_dump_t *mp;
20272   vl_api_control_ping_t *mp_ping;
20273   u8 type = POLICER_CLASSIFY_N_TABLES;
20274   int ret;
20275
20276   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20277     ;
20278   else
20279     {
20280       errmsg ("classify table type must be specified");
20281       return -99;
20282     }
20283
20284   if (!vam->json_output)
20285     {
20286       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20287     }
20288
20289   M (POLICER_CLASSIFY_DUMP, mp);
20290   mp->type = type;
20291   /* send it... */
20292   S (mp);
20293
20294   /* Use a control ping for synchronization */
20295   MPING (CONTROL_PING, mp_ping);
20296   S (mp_ping);
20297
20298   /* Wait for a reply... */
20299   W (ret);
20300   return ret;
20301 }
20302
20303 static int
20304 api_netmap_create (vat_main_t * vam)
20305 {
20306   unformat_input_t *i = vam->input;
20307   vl_api_netmap_create_t *mp;
20308   u8 *if_name = 0;
20309   u8 hw_addr[6];
20310   u8 random_hw_addr = 1;
20311   u8 is_pipe = 0;
20312   u8 is_master = 0;
20313   int ret;
20314
20315   clib_memset (hw_addr, 0, sizeof (hw_addr));
20316
20317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20318     {
20319       if (unformat (i, "name %s", &if_name))
20320         vec_add1 (if_name, 0);
20321       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20322         random_hw_addr = 0;
20323       else if (unformat (i, "pipe"))
20324         is_pipe = 1;
20325       else if (unformat (i, "master"))
20326         is_master = 1;
20327       else if (unformat (i, "slave"))
20328         is_master = 0;
20329       else
20330         break;
20331     }
20332
20333   if (!vec_len (if_name))
20334     {
20335       errmsg ("interface name must be specified");
20336       return -99;
20337     }
20338
20339   if (vec_len (if_name) > 64)
20340     {
20341       errmsg ("interface name too long");
20342       return -99;
20343     }
20344
20345   M (NETMAP_CREATE, mp);
20346
20347   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20348   clib_memcpy (mp->hw_addr, hw_addr, 6);
20349   mp->use_random_hw_addr = random_hw_addr;
20350   mp->is_pipe = is_pipe;
20351   mp->is_master = is_master;
20352   vec_free (if_name);
20353
20354   S (mp);
20355   W (ret);
20356   return ret;
20357 }
20358
20359 static int
20360 api_netmap_delete (vat_main_t * vam)
20361 {
20362   unformat_input_t *i = vam->input;
20363   vl_api_netmap_delete_t *mp;
20364   u8 *if_name = 0;
20365   int ret;
20366
20367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20368     {
20369       if (unformat (i, "name %s", &if_name))
20370         vec_add1 (if_name, 0);
20371       else
20372         break;
20373     }
20374
20375   if (!vec_len (if_name))
20376     {
20377       errmsg ("interface name must be specified");
20378       return -99;
20379     }
20380
20381   if (vec_len (if_name) > 64)
20382     {
20383       errmsg ("interface name too long");
20384       return -99;
20385     }
20386
20387   M (NETMAP_DELETE, mp);
20388
20389   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20390   vec_free (if_name);
20391
20392   S (mp);
20393   W (ret);
20394   return ret;
20395 }
20396
20397 static void
20398 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20399 {
20400   if (fp->afi == IP46_TYPE_IP6)
20401     print (vam->ofp,
20402            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20403            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20404            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
20405            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20406            format_ip6_address, fp->next_hop);
20407   else if (fp->afi == IP46_TYPE_IP4)
20408     print (vam->ofp,
20409            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20410            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20411            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
20412            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20413            format_ip4_address, fp->next_hop);
20414 }
20415
20416 static void
20417 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20418                                  vl_api_fib_path_t * fp)
20419 {
20420   struct in_addr ip4;
20421   struct in6_addr ip6;
20422
20423   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20424   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20425   vat_json_object_add_uint (node, "is_local", fp->is_local);
20426   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20427   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20428   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20429   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20430   if (fp->afi == IP46_TYPE_IP4)
20431     {
20432       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20433       vat_json_object_add_ip4 (node, "next_hop", ip4);
20434     }
20435   else if (fp->afi == IP46_TYPE_IP6)
20436     {
20437       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20438       vat_json_object_add_ip6 (node, "next_hop", ip6);
20439     }
20440 }
20441
20442 static void
20443 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20444 {
20445   vat_main_t *vam = &vat_main;
20446   int count = ntohl (mp->mt_count);
20447   vl_api_fib_path_t *fp;
20448   i32 i;
20449
20450   print (vam->ofp, "[%d]: sw_if_index %d via:",
20451          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20452   fp = mp->mt_paths;
20453   for (i = 0; i < count; i++)
20454     {
20455       vl_api_mpls_fib_path_print (vam, fp);
20456       fp++;
20457     }
20458
20459   print (vam->ofp, "");
20460 }
20461
20462 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20463 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20464
20465 static void
20466 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20467 {
20468   vat_main_t *vam = &vat_main;
20469   vat_json_node_t *node = NULL;
20470   int count = ntohl (mp->mt_count);
20471   vl_api_fib_path_t *fp;
20472   i32 i;
20473
20474   if (VAT_JSON_ARRAY != vam->json_tree.type)
20475     {
20476       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20477       vat_json_init_array (&vam->json_tree);
20478     }
20479   node = vat_json_array_add (&vam->json_tree);
20480
20481   vat_json_init_object (node);
20482   vat_json_object_add_uint (node, "tunnel_index",
20483                             ntohl (mp->mt_tunnel_index));
20484   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20485
20486   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20487
20488   fp = mp->mt_paths;
20489   for (i = 0; i < count; i++)
20490     {
20491       vl_api_mpls_fib_path_json_print (node, fp);
20492       fp++;
20493     }
20494 }
20495
20496 static int
20497 api_mpls_tunnel_dump (vat_main_t * vam)
20498 {
20499   vl_api_mpls_tunnel_dump_t *mp;
20500   vl_api_control_ping_t *mp_ping;
20501   u32 sw_if_index = ~0;
20502   int ret;
20503
20504   /* Parse args required to build the message */
20505   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20506     {
20507       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20508         ;
20509     }
20510
20511   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20512
20513   M (MPLS_TUNNEL_DUMP, mp);
20514   mp->sw_if_index = htonl (sw_if_index);
20515   S (mp);
20516
20517   /* Use a control ping for synchronization */
20518   MPING (CONTROL_PING, mp_ping);
20519   S (mp_ping);
20520
20521   W (ret);
20522   return ret;
20523 }
20524
20525 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20526 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20527
20528
20529 static void
20530 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20531 {
20532   vat_main_t *vam = &vat_main;
20533   int count = ntohl (mp->count);
20534   vl_api_fib_path_t *fp;
20535   int i;
20536
20537   print (vam->ofp,
20538          "table-id %d, label %u, ess_bit %u",
20539          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20540   fp = mp->path;
20541   for (i = 0; i < count; i++)
20542     {
20543       vl_api_mpls_fib_path_print (vam, fp);
20544       fp++;
20545     }
20546 }
20547
20548 static void vl_api_mpls_fib_details_t_handler_json
20549   (vl_api_mpls_fib_details_t * mp)
20550 {
20551   vat_main_t *vam = &vat_main;
20552   int count = ntohl (mp->count);
20553   vat_json_node_t *node = NULL;
20554   vl_api_fib_path_t *fp;
20555   int i;
20556
20557   if (VAT_JSON_ARRAY != vam->json_tree.type)
20558     {
20559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20560       vat_json_init_array (&vam->json_tree);
20561     }
20562   node = vat_json_array_add (&vam->json_tree);
20563
20564   vat_json_init_object (node);
20565   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20566   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20567   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20568   vat_json_object_add_uint (node, "path_count", count);
20569   fp = mp->path;
20570   for (i = 0; i < count; i++)
20571     {
20572       vl_api_mpls_fib_path_json_print (node, fp);
20573       fp++;
20574     }
20575 }
20576
20577 static int
20578 api_mpls_fib_dump (vat_main_t * vam)
20579 {
20580   vl_api_mpls_fib_dump_t *mp;
20581   vl_api_control_ping_t *mp_ping;
20582   int ret;
20583
20584   M (MPLS_FIB_DUMP, mp);
20585   S (mp);
20586
20587   /* Use a control ping for synchronization */
20588   MPING (CONTROL_PING, mp_ping);
20589   S (mp_ping);
20590
20591   W (ret);
20592   return ret;
20593 }
20594
20595 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20596 #define vl_api_ip_fib_details_t_print vl_noop_handler
20597
20598 static void
20599 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20600 {
20601   vat_main_t *vam = &vat_main;
20602   int count = ntohl (mp->count);
20603   vl_api_fib_path_t *fp;
20604   int i;
20605
20606   print (vam->ofp,
20607          "table-id %d, prefix %U/%d stats-index %d",
20608          ntohl (mp->table_id), format_ip4_address, mp->address,
20609          mp->address_length, ntohl (mp->stats_index));
20610   fp = mp->path;
20611   for (i = 0; i < count; i++)
20612     {
20613       if (fp->afi == IP46_TYPE_IP6)
20614         print (vam->ofp,
20615                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20616                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20617                "next_hop_table %d",
20618                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20619                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20620                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20621       else if (fp->afi == IP46_TYPE_IP4)
20622         print (vam->ofp,
20623                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20624                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20625                "next_hop_table %d",
20626                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20627                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20628                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20629       fp++;
20630     }
20631 }
20632
20633 static void vl_api_ip_fib_details_t_handler_json
20634   (vl_api_ip_fib_details_t * mp)
20635 {
20636   vat_main_t *vam = &vat_main;
20637   int count = ntohl (mp->count);
20638   vat_json_node_t *node = NULL;
20639   struct in_addr ip4;
20640   struct in6_addr ip6;
20641   vl_api_fib_path_t *fp;
20642   int i;
20643
20644   if (VAT_JSON_ARRAY != vam->json_tree.type)
20645     {
20646       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20647       vat_json_init_array (&vam->json_tree);
20648     }
20649   node = vat_json_array_add (&vam->json_tree);
20650
20651   vat_json_init_object (node);
20652   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20653   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20654   vat_json_object_add_ip4 (node, "prefix", ip4);
20655   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20656   vat_json_object_add_uint (node, "path_count", count);
20657   fp = mp->path;
20658   for (i = 0; i < count; i++)
20659     {
20660       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20661       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20662       vat_json_object_add_uint (node, "is_local", fp->is_local);
20663       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20664       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20665       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20666       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20667       if (fp->afi == IP46_TYPE_IP4)
20668         {
20669           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20670           vat_json_object_add_ip4 (node, "next_hop", ip4);
20671         }
20672       else if (fp->afi == IP46_TYPE_IP6)
20673         {
20674           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20675           vat_json_object_add_ip6 (node, "next_hop", ip6);
20676         }
20677     }
20678 }
20679
20680 static int
20681 api_ip_fib_dump (vat_main_t * vam)
20682 {
20683   vl_api_ip_fib_dump_t *mp;
20684   vl_api_control_ping_t *mp_ping;
20685   int ret;
20686
20687   M (IP_FIB_DUMP, mp);
20688   S (mp);
20689
20690   /* Use a control ping for synchronization */
20691   MPING (CONTROL_PING, mp_ping);
20692   S (mp_ping);
20693
20694   W (ret);
20695   return ret;
20696 }
20697
20698 static int
20699 api_ip_mfib_dump (vat_main_t * vam)
20700 {
20701   vl_api_ip_mfib_dump_t *mp;
20702   vl_api_control_ping_t *mp_ping;
20703   int ret;
20704
20705   M (IP_MFIB_DUMP, mp);
20706   S (mp);
20707
20708   /* Use a control ping for synchronization */
20709   MPING (CONTROL_PING, mp_ping);
20710   S (mp_ping);
20711
20712   W (ret);
20713   return ret;
20714 }
20715
20716 static void vl_api_ip_neighbor_details_t_handler
20717   (vl_api_ip_neighbor_details_t * mp)
20718 {
20719   vat_main_t *vam = &vat_main;
20720
20721   print (vam->ofp, "%c %U %U",
20722          (mp->is_static) ? 'S' : 'D',
20723          format_ethernet_address, &mp->mac_address,
20724          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20725          &mp->ip_address);
20726 }
20727
20728 static void vl_api_ip_neighbor_details_t_handler_json
20729   (vl_api_ip_neighbor_details_t * mp)
20730 {
20731
20732   vat_main_t *vam = &vat_main;
20733   vat_json_node_t *node;
20734   struct in_addr ip4;
20735   struct in6_addr ip6;
20736
20737   if (VAT_JSON_ARRAY != vam->json_tree.type)
20738     {
20739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20740       vat_json_init_array (&vam->json_tree);
20741     }
20742   node = vat_json_array_add (&vam->json_tree);
20743
20744   vat_json_init_object (node);
20745   vat_json_object_add_string_copy (node, "flag",
20746                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20747                                    "dynamic");
20748
20749   vat_json_object_add_string_copy (node, "link_layer",
20750                                    format (0, "%U", format_ethernet_address,
20751                                            &mp->mac_address));
20752
20753   if (mp->is_ipv6)
20754     {
20755       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20756       vat_json_object_add_ip6 (node, "ip_address", ip6);
20757     }
20758   else
20759     {
20760       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20761       vat_json_object_add_ip4 (node, "ip_address", ip4);
20762     }
20763 }
20764
20765 static int
20766 api_ip_neighbor_dump (vat_main_t * vam)
20767 {
20768   unformat_input_t *i = vam->input;
20769   vl_api_ip_neighbor_dump_t *mp;
20770   vl_api_control_ping_t *mp_ping;
20771   u8 is_ipv6 = 0;
20772   u32 sw_if_index = ~0;
20773   int ret;
20774
20775   /* Parse args required to build the message */
20776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20777     {
20778       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20779         ;
20780       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20781         ;
20782       else if (unformat (i, "ip6"))
20783         is_ipv6 = 1;
20784       else
20785         break;
20786     }
20787
20788   if (sw_if_index == ~0)
20789     {
20790       errmsg ("missing interface name or sw_if_index");
20791       return -99;
20792     }
20793
20794   M (IP_NEIGHBOR_DUMP, mp);
20795   mp->is_ipv6 = (u8) is_ipv6;
20796   mp->sw_if_index = ntohl (sw_if_index);
20797   S (mp);
20798
20799   /* Use a control ping for synchronization */
20800   MPING (CONTROL_PING, mp_ping);
20801   S (mp_ping);
20802
20803   W (ret);
20804   return ret;
20805 }
20806
20807 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20808 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20809
20810 static void
20811 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20812 {
20813   vat_main_t *vam = &vat_main;
20814   int count = ntohl (mp->count);
20815   vl_api_fib_path_t *fp;
20816   int i;
20817
20818   print (vam->ofp,
20819          "table-id %d, prefix %U/%d stats-index %d",
20820          ntohl (mp->table_id), format_ip6_address, mp->address,
20821          mp->address_length, ntohl (mp->stats_index));
20822   fp = mp->path;
20823   for (i = 0; i < count; i++)
20824     {
20825       if (fp->afi == IP46_TYPE_IP6)
20826         print (vam->ofp,
20827                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20828                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20829                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20830                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20831                format_ip6_address, fp->next_hop);
20832       else if (fp->afi == IP46_TYPE_IP4)
20833         print (vam->ofp,
20834                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20835                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20836                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20837                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20838                format_ip4_address, fp->next_hop);
20839       fp++;
20840     }
20841 }
20842
20843 static void vl_api_ip6_fib_details_t_handler_json
20844   (vl_api_ip6_fib_details_t * mp)
20845 {
20846   vat_main_t *vam = &vat_main;
20847   int count = ntohl (mp->count);
20848   vat_json_node_t *node = NULL;
20849   struct in_addr ip4;
20850   struct in6_addr ip6;
20851   vl_api_fib_path_t *fp;
20852   int i;
20853
20854   if (VAT_JSON_ARRAY != vam->json_tree.type)
20855     {
20856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20857       vat_json_init_array (&vam->json_tree);
20858     }
20859   node = vat_json_array_add (&vam->json_tree);
20860
20861   vat_json_init_object (node);
20862   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20863   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20864   vat_json_object_add_ip6 (node, "prefix", ip6);
20865   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20866   vat_json_object_add_uint (node, "path_count", count);
20867   fp = mp->path;
20868   for (i = 0; i < count; i++)
20869     {
20870       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20871       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20872       vat_json_object_add_uint (node, "is_local", fp->is_local);
20873       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20874       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20875       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20876       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20877       if (fp->afi == IP46_TYPE_IP4)
20878         {
20879           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20880           vat_json_object_add_ip4 (node, "next_hop", ip4);
20881         }
20882       else if (fp->afi == IP46_TYPE_IP6)
20883         {
20884           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20885           vat_json_object_add_ip6 (node, "next_hop", ip6);
20886         }
20887     }
20888 }
20889
20890 static int
20891 api_ip6_fib_dump (vat_main_t * vam)
20892 {
20893   vl_api_ip6_fib_dump_t *mp;
20894   vl_api_control_ping_t *mp_ping;
20895   int ret;
20896
20897   M (IP6_FIB_DUMP, mp);
20898   S (mp);
20899
20900   /* Use a control ping for synchronization */
20901   MPING (CONTROL_PING, mp_ping);
20902   S (mp_ping);
20903
20904   W (ret);
20905   return ret;
20906 }
20907
20908 static int
20909 api_ip6_mfib_dump (vat_main_t * vam)
20910 {
20911   vl_api_ip6_mfib_dump_t *mp;
20912   vl_api_control_ping_t *mp_ping;
20913   int ret;
20914
20915   M (IP6_MFIB_DUMP, mp);
20916   S (mp);
20917
20918   /* Use a control ping for synchronization */
20919   MPING (CONTROL_PING, mp_ping);
20920   S (mp_ping);
20921
20922   W (ret);
20923   return ret;
20924 }
20925
20926 int
20927 api_classify_table_ids (vat_main_t * vam)
20928 {
20929   vl_api_classify_table_ids_t *mp;
20930   int ret;
20931
20932   /* Construct the API message */
20933   M (CLASSIFY_TABLE_IDS, mp);
20934   mp->context = 0;
20935
20936   S (mp);
20937   W (ret);
20938   return ret;
20939 }
20940
20941 int
20942 api_classify_table_by_interface (vat_main_t * vam)
20943 {
20944   unformat_input_t *input = vam->input;
20945   vl_api_classify_table_by_interface_t *mp;
20946
20947   u32 sw_if_index = ~0;
20948   int ret;
20949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20950     {
20951       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20952         ;
20953       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20954         ;
20955       else
20956         break;
20957     }
20958   if (sw_if_index == ~0)
20959     {
20960       errmsg ("missing interface name or sw_if_index");
20961       return -99;
20962     }
20963
20964   /* Construct the API message */
20965   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20966   mp->context = 0;
20967   mp->sw_if_index = ntohl (sw_if_index);
20968
20969   S (mp);
20970   W (ret);
20971   return ret;
20972 }
20973
20974 int
20975 api_classify_table_info (vat_main_t * vam)
20976 {
20977   unformat_input_t *input = vam->input;
20978   vl_api_classify_table_info_t *mp;
20979
20980   u32 table_id = ~0;
20981   int ret;
20982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20983     {
20984       if (unformat (input, "table_id %d", &table_id))
20985         ;
20986       else
20987         break;
20988     }
20989   if (table_id == ~0)
20990     {
20991       errmsg ("missing table id");
20992       return -99;
20993     }
20994
20995   /* Construct the API message */
20996   M (CLASSIFY_TABLE_INFO, mp);
20997   mp->context = 0;
20998   mp->table_id = ntohl (table_id);
20999
21000   S (mp);
21001   W (ret);
21002   return ret;
21003 }
21004
21005 int
21006 api_classify_session_dump (vat_main_t * vam)
21007 {
21008   unformat_input_t *input = vam->input;
21009   vl_api_classify_session_dump_t *mp;
21010   vl_api_control_ping_t *mp_ping;
21011
21012   u32 table_id = ~0;
21013   int ret;
21014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21015     {
21016       if (unformat (input, "table_id %d", &table_id))
21017         ;
21018       else
21019         break;
21020     }
21021   if (table_id == ~0)
21022     {
21023       errmsg ("missing table id");
21024       return -99;
21025     }
21026
21027   /* Construct the API message */
21028   M (CLASSIFY_SESSION_DUMP, mp);
21029   mp->context = 0;
21030   mp->table_id = ntohl (table_id);
21031   S (mp);
21032
21033   /* Use a control ping for synchronization */
21034   MPING (CONTROL_PING, mp_ping);
21035   S (mp_ping);
21036
21037   W (ret);
21038   return ret;
21039 }
21040
21041 static void
21042 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
21043 {
21044   vat_main_t *vam = &vat_main;
21045
21046   print (vam->ofp, "collector_address %U, collector_port %d, "
21047          "src_address %U, vrf_id %d, path_mtu %u, "
21048          "template_interval %u, udp_checksum %d",
21049          format_ip4_address, mp->collector_address,
21050          ntohs (mp->collector_port),
21051          format_ip4_address, mp->src_address,
21052          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
21053          ntohl (mp->template_interval), mp->udp_checksum);
21054
21055   vam->retval = 0;
21056   vam->result_ready = 1;
21057 }
21058
21059 static void
21060   vl_api_ipfix_exporter_details_t_handler_json
21061   (vl_api_ipfix_exporter_details_t * mp)
21062 {
21063   vat_main_t *vam = &vat_main;
21064   vat_json_node_t node;
21065   struct in_addr collector_address;
21066   struct in_addr src_address;
21067
21068   vat_json_init_object (&node);
21069   clib_memcpy (&collector_address, &mp->collector_address,
21070                sizeof (collector_address));
21071   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
21072   vat_json_object_add_uint (&node, "collector_port",
21073                             ntohs (mp->collector_port));
21074   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21075   vat_json_object_add_ip4 (&node, "src_address", src_address);
21076   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21077   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21078   vat_json_object_add_uint (&node, "template_interval",
21079                             ntohl (mp->template_interval));
21080   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21081
21082   vat_json_print (vam->ofp, &node);
21083   vat_json_free (&node);
21084   vam->retval = 0;
21085   vam->result_ready = 1;
21086 }
21087
21088 int
21089 api_ipfix_exporter_dump (vat_main_t * vam)
21090 {
21091   vl_api_ipfix_exporter_dump_t *mp;
21092   int ret;
21093
21094   /* Construct the API message */
21095   M (IPFIX_EXPORTER_DUMP, mp);
21096   mp->context = 0;
21097
21098   S (mp);
21099   W (ret);
21100   return ret;
21101 }
21102
21103 static int
21104 api_ipfix_classify_stream_dump (vat_main_t * vam)
21105 {
21106   vl_api_ipfix_classify_stream_dump_t *mp;
21107   int ret;
21108
21109   /* Construct the API message */
21110   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21111   mp->context = 0;
21112
21113   S (mp);
21114   W (ret);
21115   return ret;
21116   /* NOTREACHED */
21117   return 0;
21118 }
21119
21120 static void
21121   vl_api_ipfix_classify_stream_details_t_handler
21122   (vl_api_ipfix_classify_stream_details_t * mp)
21123 {
21124   vat_main_t *vam = &vat_main;
21125   print (vam->ofp, "domain_id %d, src_port %d",
21126          ntohl (mp->domain_id), ntohs (mp->src_port));
21127   vam->retval = 0;
21128   vam->result_ready = 1;
21129 }
21130
21131 static void
21132   vl_api_ipfix_classify_stream_details_t_handler_json
21133   (vl_api_ipfix_classify_stream_details_t * mp)
21134 {
21135   vat_main_t *vam = &vat_main;
21136   vat_json_node_t node;
21137
21138   vat_json_init_object (&node);
21139   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21140   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21141
21142   vat_json_print (vam->ofp, &node);
21143   vat_json_free (&node);
21144   vam->retval = 0;
21145   vam->result_ready = 1;
21146 }
21147
21148 static int
21149 api_ipfix_classify_table_dump (vat_main_t * vam)
21150 {
21151   vl_api_ipfix_classify_table_dump_t *mp;
21152   vl_api_control_ping_t *mp_ping;
21153   int ret;
21154
21155   if (!vam->json_output)
21156     {
21157       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21158              "transport_protocol");
21159     }
21160
21161   /* Construct the API message */
21162   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21163
21164   /* send it... */
21165   S (mp);
21166
21167   /* Use a control ping for synchronization */
21168   MPING (CONTROL_PING, mp_ping);
21169   S (mp_ping);
21170
21171   W (ret);
21172   return ret;
21173 }
21174
21175 static void
21176   vl_api_ipfix_classify_table_details_t_handler
21177   (vl_api_ipfix_classify_table_details_t * mp)
21178 {
21179   vat_main_t *vam = &vat_main;
21180   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21181          mp->transport_protocol);
21182 }
21183
21184 static void
21185   vl_api_ipfix_classify_table_details_t_handler_json
21186   (vl_api_ipfix_classify_table_details_t * mp)
21187 {
21188   vat_json_node_t *node = NULL;
21189   vat_main_t *vam = &vat_main;
21190
21191   if (VAT_JSON_ARRAY != vam->json_tree.type)
21192     {
21193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21194       vat_json_init_array (&vam->json_tree);
21195     }
21196
21197   node = vat_json_array_add (&vam->json_tree);
21198   vat_json_init_object (node);
21199
21200   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21201   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21202   vat_json_object_add_uint (node, "transport_protocol",
21203                             mp->transport_protocol);
21204 }
21205
21206 static int
21207 api_sw_interface_span_enable_disable (vat_main_t * vam)
21208 {
21209   unformat_input_t *i = vam->input;
21210   vl_api_sw_interface_span_enable_disable_t *mp;
21211   u32 src_sw_if_index = ~0;
21212   u32 dst_sw_if_index = ~0;
21213   u8 state = 3;
21214   int ret;
21215   u8 is_l2 = 0;
21216
21217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21218     {
21219       if (unformat
21220           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21221         ;
21222       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21223         ;
21224       else
21225         if (unformat
21226             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21227         ;
21228       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21229         ;
21230       else if (unformat (i, "disable"))
21231         state = 0;
21232       else if (unformat (i, "rx"))
21233         state = 1;
21234       else if (unformat (i, "tx"))
21235         state = 2;
21236       else if (unformat (i, "both"))
21237         state = 3;
21238       else if (unformat (i, "l2"))
21239         is_l2 = 1;
21240       else
21241         break;
21242     }
21243
21244   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21245
21246   mp->sw_if_index_from = htonl (src_sw_if_index);
21247   mp->sw_if_index_to = htonl (dst_sw_if_index);
21248   mp->state = state;
21249   mp->is_l2 = is_l2;
21250
21251   S (mp);
21252   W (ret);
21253   return ret;
21254 }
21255
21256 static void
21257 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21258                                             * mp)
21259 {
21260   vat_main_t *vam = &vat_main;
21261   u8 *sw_if_from_name = 0;
21262   u8 *sw_if_to_name = 0;
21263   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21264   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21265   char *states[] = { "none", "rx", "tx", "both" };
21266   hash_pair_t *p;
21267
21268   /* *INDENT-OFF* */
21269   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21270   ({
21271     if ((u32) p->value[0] == sw_if_index_from)
21272       {
21273         sw_if_from_name = (u8 *)(p->key);
21274         if (sw_if_to_name)
21275           break;
21276       }
21277     if ((u32) p->value[0] == sw_if_index_to)
21278       {
21279         sw_if_to_name = (u8 *)(p->key);
21280         if (sw_if_from_name)
21281           break;
21282       }
21283   }));
21284   /* *INDENT-ON* */
21285   print (vam->ofp, "%20s => %20s (%s) %s",
21286          sw_if_from_name, sw_if_to_name, states[mp->state],
21287          mp->is_l2 ? "l2" : "device");
21288 }
21289
21290 static void
21291   vl_api_sw_interface_span_details_t_handler_json
21292   (vl_api_sw_interface_span_details_t * mp)
21293 {
21294   vat_main_t *vam = &vat_main;
21295   vat_json_node_t *node = NULL;
21296   u8 *sw_if_from_name = 0;
21297   u8 *sw_if_to_name = 0;
21298   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21299   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21300   hash_pair_t *p;
21301
21302   /* *INDENT-OFF* */
21303   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21304   ({
21305     if ((u32) p->value[0] == sw_if_index_from)
21306       {
21307         sw_if_from_name = (u8 *)(p->key);
21308         if (sw_if_to_name)
21309           break;
21310       }
21311     if ((u32) p->value[0] == sw_if_index_to)
21312       {
21313         sw_if_to_name = (u8 *)(p->key);
21314         if (sw_if_from_name)
21315           break;
21316       }
21317   }));
21318   /* *INDENT-ON* */
21319
21320   if (VAT_JSON_ARRAY != vam->json_tree.type)
21321     {
21322       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21323       vat_json_init_array (&vam->json_tree);
21324     }
21325   node = vat_json_array_add (&vam->json_tree);
21326
21327   vat_json_init_object (node);
21328   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21329   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21330   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21331   if (0 != sw_if_to_name)
21332     {
21333       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21334     }
21335   vat_json_object_add_uint (node, "state", mp->state);
21336   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21337 }
21338
21339 static int
21340 api_sw_interface_span_dump (vat_main_t * vam)
21341 {
21342   unformat_input_t *input = vam->input;
21343   vl_api_sw_interface_span_dump_t *mp;
21344   vl_api_control_ping_t *mp_ping;
21345   u8 is_l2 = 0;
21346   int ret;
21347
21348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21349     {
21350       if (unformat (input, "l2"))
21351         is_l2 = 1;
21352       else
21353         break;
21354     }
21355
21356   M (SW_INTERFACE_SPAN_DUMP, mp);
21357   mp->is_l2 = is_l2;
21358   S (mp);
21359
21360   /* Use a control ping for synchronization */
21361   MPING (CONTROL_PING, mp_ping);
21362   S (mp_ping);
21363
21364   W (ret);
21365   return ret;
21366 }
21367
21368 int
21369 api_pg_create_interface (vat_main_t * vam)
21370 {
21371   unformat_input_t *input = vam->input;
21372   vl_api_pg_create_interface_t *mp;
21373
21374   u32 if_id = ~0;
21375   int ret;
21376   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21377     {
21378       if (unformat (input, "if_id %d", &if_id))
21379         ;
21380       else
21381         break;
21382     }
21383   if (if_id == ~0)
21384     {
21385       errmsg ("missing pg interface index");
21386       return -99;
21387     }
21388
21389   /* Construct the API message */
21390   M (PG_CREATE_INTERFACE, mp);
21391   mp->context = 0;
21392   mp->interface_id = ntohl (if_id);
21393
21394   S (mp);
21395   W (ret);
21396   return ret;
21397 }
21398
21399 int
21400 api_pg_capture (vat_main_t * vam)
21401 {
21402   unformat_input_t *input = vam->input;
21403   vl_api_pg_capture_t *mp;
21404
21405   u32 if_id = ~0;
21406   u8 enable = 1;
21407   u32 count = 1;
21408   u8 pcap_file_set = 0;
21409   u8 *pcap_file = 0;
21410   int ret;
21411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21412     {
21413       if (unformat (input, "if_id %d", &if_id))
21414         ;
21415       else if (unformat (input, "pcap %s", &pcap_file))
21416         pcap_file_set = 1;
21417       else if (unformat (input, "count %d", &count))
21418         ;
21419       else if (unformat (input, "disable"))
21420         enable = 0;
21421       else
21422         break;
21423     }
21424   if (if_id == ~0)
21425     {
21426       errmsg ("missing pg interface index");
21427       return -99;
21428     }
21429   if (pcap_file_set > 0)
21430     {
21431       if (vec_len (pcap_file) > 255)
21432         {
21433           errmsg ("pcap file name is too long");
21434           return -99;
21435         }
21436     }
21437
21438   u32 name_len = vec_len (pcap_file);
21439   /* Construct the API message */
21440   M (PG_CAPTURE, mp);
21441   mp->context = 0;
21442   mp->interface_id = ntohl (if_id);
21443   mp->is_enabled = enable;
21444   mp->count = ntohl (count);
21445   mp->pcap_name_length = ntohl (name_len);
21446   if (pcap_file_set != 0)
21447     {
21448       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21449     }
21450   vec_free (pcap_file);
21451
21452   S (mp);
21453   W (ret);
21454   return ret;
21455 }
21456
21457 int
21458 api_pg_enable_disable (vat_main_t * vam)
21459 {
21460   unformat_input_t *input = vam->input;
21461   vl_api_pg_enable_disable_t *mp;
21462
21463   u8 enable = 1;
21464   u8 stream_name_set = 0;
21465   u8 *stream_name = 0;
21466   int ret;
21467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21468     {
21469       if (unformat (input, "stream %s", &stream_name))
21470         stream_name_set = 1;
21471       else if (unformat (input, "disable"))
21472         enable = 0;
21473       else
21474         break;
21475     }
21476
21477   if (stream_name_set > 0)
21478     {
21479       if (vec_len (stream_name) > 255)
21480         {
21481           errmsg ("stream name too long");
21482           return -99;
21483         }
21484     }
21485
21486   u32 name_len = vec_len (stream_name);
21487   /* Construct the API message */
21488   M (PG_ENABLE_DISABLE, mp);
21489   mp->context = 0;
21490   mp->is_enabled = enable;
21491   if (stream_name_set != 0)
21492     {
21493       mp->stream_name_length = ntohl (name_len);
21494       clib_memcpy (mp->stream_name, stream_name, name_len);
21495     }
21496   vec_free (stream_name);
21497
21498   S (mp);
21499   W (ret);
21500   return ret;
21501 }
21502
21503 int
21504 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21505 {
21506   unformat_input_t *input = vam->input;
21507   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21508
21509   u16 *low_ports = 0;
21510   u16 *high_ports = 0;
21511   u16 this_low;
21512   u16 this_hi;
21513   ip4_address_t ip4_addr;
21514   ip6_address_t ip6_addr;
21515   u32 length;
21516   u32 tmp, tmp2;
21517   u8 prefix_set = 0;
21518   u32 vrf_id = ~0;
21519   u8 is_add = 1;
21520   u8 is_ipv6 = 0;
21521   int ret;
21522
21523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21524     {
21525       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21526         {
21527           prefix_set = 1;
21528         }
21529       else
21530         if (unformat
21531             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21532         {
21533           prefix_set = 1;
21534           is_ipv6 = 1;
21535         }
21536       else if (unformat (input, "vrf %d", &vrf_id))
21537         ;
21538       else if (unformat (input, "del"))
21539         is_add = 0;
21540       else if (unformat (input, "port %d", &tmp))
21541         {
21542           if (tmp == 0 || tmp > 65535)
21543             {
21544               errmsg ("port %d out of range", tmp);
21545               return -99;
21546             }
21547           this_low = tmp;
21548           this_hi = this_low + 1;
21549           vec_add1 (low_ports, this_low);
21550           vec_add1 (high_ports, this_hi);
21551         }
21552       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21553         {
21554           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21555             {
21556               errmsg ("incorrect range parameters");
21557               return -99;
21558             }
21559           this_low = tmp;
21560           /* Note: in debug CLI +1 is added to high before
21561              passing to real fn that does "the work"
21562              (ip_source_and_port_range_check_add_del).
21563              This fn is a wrapper around the binary API fn a
21564              control plane will call, which expects this increment
21565              to have occurred. Hence letting the binary API control
21566              plane fn do the increment for consistency between VAT
21567              and other control planes.
21568            */
21569           this_hi = tmp2;
21570           vec_add1 (low_ports, this_low);
21571           vec_add1 (high_ports, this_hi);
21572         }
21573       else
21574         break;
21575     }
21576
21577   if (prefix_set == 0)
21578     {
21579       errmsg ("<address>/<mask> not specified");
21580       return -99;
21581     }
21582
21583   if (vrf_id == ~0)
21584     {
21585       errmsg ("VRF ID required, not specified");
21586       return -99;
21587     }
21588
21589   if (vrf_id == 0)
21590     {
21591       errmsg
21592         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21593       return -99;
21594     }
21595
21596   if (vec_len (low_ports) == 0)
21597     {
21598       errmsg ("At least one port or port range required");
21599       return -99;
21600     }
21601
21602   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21603
21604   mp->is_add = is_add;
21605
21606   if (is_ipv6)
21607     {
21608       mp->is_ipv6 = 1;
21609       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21610     }
21611   else
21612     {
21613       mp->is_ipv6 = 0;
21614       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21615     }
21616
21617   mp->mask_length = length;
21618   mp->number_of_ranges = vec_len (low_ports);
21619
21620   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21621   vec_free (low_ports);
21622
21623   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21624   vec_free (high_ports);
21625
21626   mp->vrf_id = ntohl (vrf_id);
21627
21628   S (mp);
21629   W (ret);
21630   return ret;
21631 }
21632
21633 int
21634 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21635 {
21636   unformat_input_t *input = vam->input;
21637   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21638   u32 sw_if_index = ~0;
21639   int vrf_set = 0;
21640   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21641   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21642   u8 is_add = 1;
21643   int ret;
21644
21645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21646     {
21647       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21648         ;
21649       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21650         ;
21651       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21652         vrf_set = 1;
21653       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21654         vrf_set = 1;
21655       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21656         vrf_set = 1;
21657       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21658         vrf_set = 1;
21659       else if (unformat (input, "del"))
21660         is_add = 0;
21661       else
21662         break;
21663     }
21664
21665   if (sw_if_index == ~0)
21666     {
21667       errmsg ("Interface required but not specified");
21668       return -99;
21669     }
21670
21671   if (vrf_set == 0)
21672     {
21673       errmsg ("VRF ID required but not specified");
21674       return -99;
21675     }
21676
21677   if (tcp_out_vrf_id == 0
21678       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21679     {
21680       errmsg
21681         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21682       return -99;
21683     }
21684
21685   /* Construct the API message */
21686   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21687
21688   mp->sw_if_index = ntohl (sw_if_index);
21689   mp->is_add = is_add;
21690   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21691   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21692   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21693   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21694
21695   /* send it... */
21696   S (mp);
21697
21698   /* Wait for a reply... */
21699   W (ret);
21700   return ret;
21701 }
21702
21703 static int
21704 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21705 {
21706   unformat_input_t *i = vam->input;
21707   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21708   u32 local_sa_id = 0;
21709   u32 remote_sa_id = 0;
21710   ip4_address_t src_address;
21711   ip4_address_t dst_address;
21712   u8 is_add = 1;
21713   int ret;
21714
21715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21716     {
21717       if (unformat (i, "local_sa %d", &local_sa_id))
21718         ;
21719       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21720         ;
21721       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21722         ;
21723       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21724         ;
21725       else if (unformat (i, "del"))
21726         is_add = 0;
21727       else
21728         {
21729           clib_warning ("parse error '%U'", format_unformat_error, i);
21730           return -99;
21731         }
21732     }
21733
21734   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21735
21736   mp->local_sa_id = ntohl (local_sa_id);
21737   mp->remote_sa_id = ntohl (remote_sa_id);
21738   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21739   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21740   mp->is_add = is_add;
21741
21742   S (mp);
21743   W (ret);
21744   return ret;
21745 }
21746
21747 static int
21748 api_set_punt (vat_main_t * vam)
21749 {
21750   unformat_input_t *i = vam->input;
21751   vl_api_set_punt_t *mp;
21752   u32 ipv = ~0;
21753   u32 protocol = ~0;
21754   u32 port = ~0;
21755   int is_add = 1;
21756   int ret;
21757
21758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21759     {
21760       if (unformat (i, "ip %d", &ipv))
21761         ;
21762       else if (unformat (i, "protocol %d", &protocol))
21763         ;
21764       else if (unformat (i, "port %d", &port))
21765         ;
21766       else if (unformat (i, "del"))
21767         is_add = 0;
21768       else
21769         {
21770           clib_warning ("parse error '%U'", format_unformat_error, i);
21771           return -99;
21772         }
21773     }
21774
21775   M (SET_PUNT, mp);
21776
21777   mp->is_add = (u8) is_add;
21778   mp->punt.ipv = (u8) ipv;
21779   mp->punt.l4_protocol = (u8) protocol;
21780   mp->punt.l4_port = htons ((u16) port);
21781
21782   S (mp);
21783   W (ret);
21784   return ret;
21785 }
21786
21787 static void vl_api_ipsec_gre_tunnel_details_t_handler
21788   (vl_api_ipsec_gre_tunnel_details_t * mp)
21789 {
21790   vat_main_t *vam = &vat_main;
21791
21792   print (vam->ofp, "%11d%15U%15U%14d%14d",
21793          ntohl (mp->sw_if_index),
21794          format_ip4_address, &mp->src_address,
21795          format_ip4_address, &mp->dst_address,
21796          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21797 }
21798
21799 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21800   (vl_api_ipsec_gre_tunnel_details_t * mp)
21801 {
21802   vat_main_t *vam = &vat_main;
21803   vat_json_node_t *node = NULL;
21804   struct in_addr ip4;
21805
21806   if (VAT_JSON_ARRAY != vam->json_tree.type)
21807     {
21808       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21809       vat_json_init_array (&vam->json_tree);
21810     }
21811   node = vat_json_array_add (&vam->json_tree);
21812
21813   vat_json_init_object (node);
21814   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21815   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21816   vat_json_object_add_ip4 (node, "src_address", ip4);
21817   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21818   vat_json_object_add_ip4 (node, "dst_address", ip4);
21819   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21820   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21821 }
21822
21823 static int
21824 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21825 {
21826   unformat_input_t *i = vam->input;
21827   vl_api_ipsec_gre_tunnel_dump_t *mp;
21828   vl_api_control_ping_t *mp_ping;
21829   u32 sw_if_index;
21830   u8 sw_if_index_set = 0;
21831   int ret;
21832
21833   /* Parse args required to build the message */
21834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21835     {
21836       if (unformat (i, "sw_if_index %d", &sw_if_index))
21837         sw_if_index_set = 1;
21838       else
21839         break;
21840     }
21841
21842   if (sw_if_index_set == 0)
21843     {
21844       sw_if_index = ~0;
21845     }
21846
21847   if (!vam->json_output)
21848     {
21849       print (vam->ofp, "%11s%15s%15s%14s%14s",
21850              "sw_if_index", "src_address", "dst_address",
21851              "local_sa_id", "remote_sa_id");
21852     }
21853
21854   /* Get list of gre-tunnel interfaces */
21855   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21856
21857   mp->sw_if_index = htonl (sw_if_index);
21858
21859   S (mp);
21860
21861   /* Use a control ping for synchronization */
21862   MPING (CONTROL_PING, mp_ping);
21863   S (mp_ping);
21864
21865   W (ret);
21866   return ret;
21867 }
21868
21869 static int
21870 api_delete_subif (vat_main_t * vam)
21871 {
21872   unformat_input_t *i = vam->input;
21873   vl_api_delete_subif_t *mp;
21874   u32 sw_if_index = ~0;
21875   int ret;
21876
21877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21878     {
21879       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21880         ;
21881       if (unformat (i, "sw_if_index %d", &sw_if_index))
21882         ;
21883       else
21884         break;
21885     }
21886
21887   if (sw_if_index == ~0)
21888     {
21889       errmsg ("missing sw_if_index");
21890       return -99;
21891     }
21892
21893   /* Construct the API message */
21894   M (DELETE_SUBIF, mp);
21895   mp->sw_if_index = ntohl (sw_if_index);
21896
21897   S (mp);
21898   W (ret);
21899   return ret;
21900 }
21901
21902 #define foreach_pbb_vtr_op      \
21903 _("disable",  L2_VTR_DISABLED)  \
21904 _("pop",  L2_VTR_POP_2)         \
21905 _("push",  L2_VTR_PUSH_2)
21906
21907 static int
21908 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21909 {
21910   unformat_input_t *i = vam->input;
21911   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21912   u32 sw_if_index = ~0, vtr_op = ~0;
21913   u16 outer_tag = ~0;
21914   u8 dmac[6], smac[6];
21915   u8 dmac_set = 0, smac_set = 0;
21916   u16 vlanid = 0;
21917   u32 sid = ~0;
21918   u32 tmp;
21919   int ret;
21920
21921   /* Shut up coverity */
21922   clib_memset (dmac, 0, sizeof (dmac));
21923   clib_memset (smac, 0, sizeof (smac));
21924
21925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21926     {
21927       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21928         ;
21929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21930         ;
21931       else if (unformat (i, "vtr_op %d", &vtr_op))
21932         ;
21933 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21934       foreach_pbb_vtr_op
21935 #undef _
21936         else if (unformat (i, "translate_pbb_stag"))
21937         {
21938           if (unformat (i, "%d", &tmp))
21939             {
21940               vtr_op = L2_VTR_TRANSLATE_2_1;
21941               outer_tag = tmp;
21942             }
21943           else
21944             {
21945               errmsg
21946                 ("translate_pbb_stag operation requires outer tag definition");
21947               return -99;
21948             }
21949         }
21950       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21951         dmac_set++;
21952       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21953         smac_set++;
21954       else if (unformat (i, "sid %d", &sid))
21955         ;
21956       else if (unformat (i, "vlanid %d", &tmp))
21957         vlanid = tmp;
21958       else
21959         {
21960           clib_warning ("parse error '%U'", format_unformat_error, i);
21961           return -99;
21962         }
21963     }
21964
21965   if ((sw_if_index == ~0) || (vtr_op == ~0))
21966     {
21967       errmsg ("missing sw_if_index or vtr operation");
21968       return -99;
21969     }
21970   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21971       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21972     {
21973       errmsg
21974         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21975       return -99;
21976     }
21977
21978   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21979   mp->sw_if_index = ntohl (sw_if_index);
21980   mp->vtr_op = ntohl (vtr_op);
21981   mp->outer_tag = ntohs (outer_tag);
21982   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21983   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21984   mp->b_vlanid = ntohs (vlanid);
21985   mp->i_sid = ntohl (sid);
21986
21987   S (mp);
21988   W (ret);
21989   return ret;
21990 }
21991
21992 static int
21993 api_flow_classify_set_interface (vat_main_t * vam)
21994 {
21995   unformat_input_t *i = vam->input;
21996   vl_api_flow_classify_set_interface_t *mp;
21997   u32 sw_if_index;
21998   int sw_if_index_set;
21999   u32 ip4_table_index = ~0;
22000   u32 ip6_table_index = ~0;
22001   u8 is_add = 1;
22002   int ret;
22003
22004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22005     {
22006       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22007         sw_if_index_set = 1;
22008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22009         sw_if_index_set = 1;
22010       else if (unformat (i, "del"))
22011         is_add = 0;
22012       else if (unformat (i, "ip4-table %d", &ip4_table_index))
22013         ;
22014       else if (unformat (i, "ip6-table %d", &ip6_table_index))
22015         ;
22016       else
22017         {
22018           clib_warning ("parse error '%U'", format_unformat_error, i);
22019           return -99;
22020         }
22021     }
22022
22023   if (sw_if_index_set == 0)
22024     {
22025       errmsg ("missing interface name or sw_if_index");
22026       return -99;
22027     }
22028
22029   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
22030
22031   mp->sw_if_index = ntohl (sw_if_index);
22032   mp->ip4_table_index = ntohl (ip4_table_index);
22033   mp->ip6_table_index = ntohl (ip6_table_index);
22034   mp->is_add = is_add;
22035
22036   S (mp);
22037   W (ret);
22038   return ret;
22039 }
22040
22041 static int
22042 api_flow_classify_dump (vat_main_t * vam)
22043 {
22044   unformat_input_t *i = vam->input;
22045   vl_api_flow_classify_dump_t *mp;
22046   vl_api_control_ping_t *mp_ping;
22047   u8 type = FLOW_CLASSIFY_N_TABLES;
22048   int ret;
22049
22050   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
22051     ;
22052   else
22053     {
22054       errmsg ("classify table type must be specified");
22055       return -99;
22056     }
22057
22058   if (!vam->json_output)
22059     {
22060       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
22061     }
22062
22063   M (FLOW_CLASSIFY_DUMP, mp);
22064   mp->type = type;
22065   /* send it... */
22066   S (mp);
22067
22068   /* Use a control ping for synchronization */
22069   MPING (CONTROL_PING, mp_ping);
22070   S (mp_ping);
22071
22072   /* Wait for a reply... */
22073   W (ret);
22074   return ret;
22075 }
22076
22077 static int
22078 api_feature_enable_disable (vat_main_t * vam)
22079 {
22080   unformat_input_t *i = vam->input;
22081   vl_api_feature_enable_disable_t *mp;
22082   u8 *arc_name = 0;
22083   u8 *feature_name = 0;
22084   u32 sw_if_index = ~0;
22085   u8 enable = 1;
22086   int ret;
22087
22088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22089     {
22090       if (unformat (i, "arc_name %s", &arc_name))
22091         ;
22092       else if (unformat (i, "feature_name %s", &feature_name))
22093         ;
22094       else
22095         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22096         ;
22097       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22098         ;
22099       else if (unformat (i, "disable"))
22100         enable = 0;
22101       else
22102         break;
22103     }
22104
22105   if (arc_name == 0)
22106     {
22107       errmsg ("missing arc name");
22108       return -99;
22109     }
22110   if (vec_len (arc_name) > 63)
22111     {
22112       errmsg ("arc name too long");
22113     }
22114
22115   if (feature_name == 0)
22116     {
22117       errmsg ("missing feature name");
22118       return -99;
22119     }
22120   if (vec_len (feature_name) > 63)
22121     {
22122       errmsg ("feature name too long");
22123     }
22124
22125   if (sw_if_index == ~0)
22126     {
22127       errmsg ("missing interface name or sw_if_index");
22128       return -99;
22129     }
22130
22131   /* Construct the API message */
22132   M (FEATURE_ENABLE_DISABLE, mp);
22133   mp->sw_if_index = ntohl (sw_if_index);
22134   mp->enable = enable;
22135   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22136   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22137   vec_free (arc_name);
22138   vec_free (feature_name);
22139
22140   S (mp);
22141   W (ret);
22142   return ret;
22143 }
22144
22145 static int
22146 api_sw_interface_tag_add_del (vat_main_t * vam)
22147 {
22148   unformat_input_t *i = vam->input;
22149   vl_api_sw_interface_tag_add_del_t *mp;
22150   u32 sw_if_index = ~0;
22151   u8 *tag = 0;
22152   u8 enable = 1;
22153   int ret;
22154
22155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22156     {
22157       if (unformat (i, "tag %s", &tag))
22158         ;
22159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22160         ;
22161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22162         ;
22163       else if (unformat (i, "del"))
22164         enable = 0;
22165       else
22166         break;
22167     }
22168
22169   if (sw_if_index == ~0)
22170     {
22171       errmsg ("missing interface name or sw_if_index");
22172       return -99;
22173     }
22174
22175   if (enable && (tag == 0))
22176     {
22177       errmsg ("no tag specified");
22178       return -99;
22179     }
22180
22181   /* Construct the API message */
22182   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22183   mp->sw_if_index = ntohl (sw_if_index);
22184   mp->is_add = enable;
22185   if (enable)
22186     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22187   vec_free (tag);
22188
22189   S (mp);
22190   W (ret);
22191   return ret;
22192 }
22193
22194 static void vl_api_l2_xconnect_details_t_handler
22195   (vl_api_l2_xconnect_details_t * mp)
22196 {
22197   vat_main_t *vam = &vat_main;
22198
22199   print (vam->ofp, "%15d%15d",
22200          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22201 }
22202
22203 static void vl_api_l2_xconnect_details_t_handler_json
22204   (vl_api_l2_xconnect_details_t * mp)
22205 {
22206   vat_main_t *vam = &vat_main;
22207   vat_json_node_t *node = NULL;
22208
22209   if (VAT_JSON_ARRAY != vam->json_tree.type)
22210     {
22211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22212       vat_json_init_array (&vam->json_tree);
22213     }
22214   node = vat_json_array_add (&vam->json_tree);
22215
22216   vat_json_init_object (node);
22217   vat_json_object_add_uint (node, "rx_sw_if_index",
22218                             ntohl (mp->rx_sw_if_index));
22219   vat_json_object_add_uint (node, "tx_sw_if_index",
22220                             ntohl (mp->tx_sw_if_index));
22221 }
22222
22223 static int
22224 api_l2_xconnect_dump (vat_main_t * vam)
22225 {
22226   vl_api_l2_xconnect_dump_t *mp;
22227   vl_api_control_ping_t *mp_ping;
22228   int ret;
22229
22230   if (!vam->json_output)
22231     {
22232       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22233     }
22234
22235   M (L2_XCONNECT_DUMP, mp);
22236
22237   S (mp);
22238
22239   /* Use a control ping for synchronization */
22240   MPING (CONTROL_PING, mp_ping);
22241   S (mp_ping);
22242
22243   W (ret);
22244   return ret;
22245 }
22246
22247 static int
22248 api_hw_interface_set_mtu (vat_main_t * vam)
22249 {
22250   unformat_input_t *i = vam->input;
22251   vl_api_hw_interface_set_mtu_t *mp;
22252   u32 sw_if_index = ~0;
22253   u32 mtu = 0;
22254   int ret;
22255
22256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22257     {
22258       if (unformat (i, "mtu %d", &mtu))
22259         ;
22260       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22261         ;
22262       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22263         ;
22264       else
22265         break;
22266     }
22267
22268   if (sw_if_index == ~0)
22269     {
22270       errmsg ("missing interface name or sw_if_index");
22271       return -99;
22272     }
22273
22274   if (mtu == 0)
22275     {
22276       errmsg ("no mtu specified");
22277       return -99;
22278     }
22279
22280   /* Construct the API message */
22281   M (HW_INTERFACE_SET_MTU, mp);
22282   mp->sw_if_index = ntohl (sw_if_index);
22283   mp->mtu = ntohs ((u16) mtu);
22284
22285   S (mp);
22286   W (ret);
22287   return ret;
22288 }
22289
22290 static int
22291 api_p2p_ethernet_add (vat_main_t * vam)
22292 {
22293   unformat_input_t *i = vam->input;
22294   vl_api_p2p_ethernet_add_t *mp;
22295   u32 parent_if_index = ~0;
22296   u32 sub_id = ~0;
22297   u8 remote_mac[6];
22298   u8 mac_set = 0;
22299   int ret;
22300
22301   clib_memset (remote_mac, 0, sizeof (remote_mac));
22302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22303     {
22304       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22305         ;
22306       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22307         ;
22308       else
22309         if (unformat
22310             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22311         mac_set++;
22312       else if (unformat (i, "sub_id %d", &sub_id))
22313         ;
22314       else
22315         {
22316           clib_warning ("parse error '%U'", format_unformat_error, i);
22317           return -99;
22318         }
22319     }
22320
22321   if (parent_if_index == ~0)
22322     {
22323       errmsg ("missing interface name or sw_if_index");
22324       return -99;
22325     }
22326   if (mac_set == 0)
22327     {
22328       errmsg ("missing remote mac address");
22329       return -99;
22330     }
22331   if (sub_id == ~0)
22332     {
22333       errmsg ("missing sub-interface id");
22334       return -99;
22335     }
22336
22337   M (P2P_ETHERNET_ADD, mp);
22338   mp->parent_if_index = ntohl (parent_if_index);
22339   mp->subif_id = ntohl (sub_id);
22340   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22341
22342   S (mp);
22343   W (ret);
22344   return ret;
22345 }
22346
22347 static int
22348 api_p2p_ethernet_del (vat_main_t * vam)
22349 {
22350   unformat_input_t *i = vam->input;
22351   vl_api_p2p_ethernet_del_t *mp;
22352   u32 parent_if_index = ~0;
22353   u8 remote_mac[6];
22354   u8 mac_set = 0;
22355   int ret;
22356
22357   clib_memset (remote_mac, 0, sizeof (remote_mac));
22358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22359     {
22360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22361         ;
22362       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22363         ;
22364       else
22365         if (unformat
22366             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22367         mac_set++;
22368       else
22369         {
22370           clib_warning ("parse error '%U'", format_unformat_error, i);
22371           return -99;
22372         }
22373     }
22374
22375   if (parent_if_index == ~0)
22376     {
22377       errmsg ("missing interface name or sw_if_index");
22378       return -99;
22379     }
22380   if (mac_set == 0)
22381     {
22382       errmsg ("missing remote mac address");
22383       return -99;
22384     }
22385
22386   M (P2P_ETHERNET_DEL, mp);
22387   mp->parent_if_index = ntohl (parent_if_index);
22388   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22389
22390   S (mp);
22391   W (ret);
22392   return ret;
22393 }
22394
22395 static int
22396 api_lldp_config (vat_main_t * vam)
22397 {
22398   unformat_input_t *i = vam->input;
22399   vl_api_lldp_config_t *mp;
22400   int tx_hold = 0;
22401   int tx_interval = 0;
22402   u8 *sys_name = NULL;
22403   int ret;
22404
22405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22406     {
22407       if (unformat (i, "system-name %s", &sys_name))
22408         ;
22409       else if (unformat (i, "tx-hold %d", &tx_hold))
22410         ;
22411       else if (unformat (i, "tx-interval %d", &tx_interval))
22412         ;
22413       else
22414         {
22415           clib_warning ("parse error '%U'", format_unformat_error, i);
22416           return -99;
22417         }
22418     }
22419
22420   vec_add1 (sys_name, 0);
22421
22422   M (LLDP_CONFIG, mp);
22423   mp->tx_hold = htonl (tx_hold);
22424   mp->tx_interval = htonl (tx_interval);
22425   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22426   vec_free (sys_name);
22427
22428   S (mp);
22429   W (ret);
22430   return ret;
22431 }
22432
22433 static int
22434 api_sw_interface_set_lldp (vat_main_t * vam)
22435 {
22436   unformat_input_t *i = vam->input;
22437   vl_api_sw_interface_set_lldp_t *mp;
22438   u32 sw_if_index = ~0;
22439   u32 enable = 1;
22440   u8 *port_desc = NULL, *mgmt_oid = NULL;
22441   ip4_address_t ip4_addr;
22442   ip6_address_t ip6_addr;
22443   int ret;
22444
22445   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
22446   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
22447
22448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22449     {
22450       if (unformat (i, "disable"))
22451         enable = 0;
22452       else
22453         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22454         ;
22455       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22456         ;
22457       else if (unformat (i, "port-desc %s", &port_desc))
22458         ;
22459       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22460         ;
22461       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22462         ;
22463       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22464         ;
22465       else
22466         break;
22467     }
22468
22469   if (sw_if_index == ~0)
22470     {
22471       errmsg ("missing interface name or sw_if_index");
22472       return -99;
22473     }
22474
22475   /* Construct the API message */
22476   vec_add1 (port_desc, 0);
22477   vec_add1 (mgmt_oid, 0);
22478   M (SW_INTERFACE_SET_LLDP, mp);
22479   mp->sw_if_index = ntohl (sw_if_index);
22480   mp->enable = enable;
22481   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22482   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22483   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22484   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22485   vec_free (port_desc);
22486   vec_free (mgmt_oid);
22487
22488   S (mp);
22489   W (ret);
22490   return ret;
22491 }
22492
22493 static int
22494 api_tcp_configure_src_addresses (vat_main_t * vam)
22495 {
22496   vl_api_tcp_configure_src_addresses_t *mp;
22497   unformat_input_t *i = vam->input;
22498   ip4_address_t v4first, v4last;
22499   ip6_address_t v6first, v6last;
22500   u8 range_set = 0;
22501   u32 vrf_id = 0;
22502   int ret;
22503
22504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22505     {
22506       if (unformat (i, "%U - %U",
22507                     unformat_ip4_address, &v4first,
22508                     unformat_ip4_address, &v4last))
22509         {
22510           if (range_set)
22511             {
22512               errmsg ("one range per message (range already set)");
22513               return -99;
22514             }
22515           range_set = 1;
22516         }
22517       else if (unformat (i, "%U - %U",
22518                          unformat_ip6_address, &v6first,
22519                          unformat_ip6_address, &v6last))
22520         {
22521           if (range_set)
22522             {
22523               errmsg ("one range per message (range already set)");
22524               return -99;
22525             }
22526           range_set = 2;
22527         }
22528       else if (unformat (i, "vrf %d", &vrf_id))
22529         ;
22530       else
22531         break;
22532     }
22533
22534   if (range_set == 0)
22535     {
22536       errmsg ("address range not set");
22537       return -99;
22538     }
22539
22540   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22541   mp->vrf_id = ntohl (vrf_id);
22542   /* ipv6? */
22543   if (range_set == 2)
22544     {
22545       mp->is_ipv6 = 1;
22546       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22547       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22548     }
22549   else
22550     {
22551       mp->is_ipv6 = 0;
22552       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22553       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22554     }
22555   S (mp);
22556   W (ret);
22557   return ret;
22558 }
22559
22560 static void vl_api_app_namespace_add_del_reply_t_handler
22561   (vl_api_app_namespace_add_del_reply_t * mp)
22562 {
22563   vat_main_t *vam = &vat_main;
22564   i32 retval = ntohl (mp->retval);
22565   if (vam->async_mode)
22566     {
22567       vam->async_errors += (retval < 0);
22568     }
22569   else
22570     {
22571       vam->retval = retval;
22572       if (retval == 0)
22573         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22574       vam->result_ready = 1;
22575     }
22576 }
22577
22578 static void vl_api_app_namespace_add_del_reply_t_handler_json
22579   (vl_api_app_namespace_add_del_reply_t * mp)
22580 {
22581   vat_main_t *vam = &vat_main;
22582   vat_json_node_t node;
22583
22584   vat_json_init_object (&node);
22585   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22586   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22587
22588   vat_json_print (vam->ofp, &node);
22589   vat_json_free (&node);
22590
22591   vam->retval = ntohl (mp->retval);
22592   vam->result_ready = 1;
22593 }
22594
22595 static int
22596 api_app_namespace_add_del (vat_main_t * vam)
22597 {
22598   vl_api_app_namespace_add_del_t *mp;
22599   unformat_input_t *i = vam->input;
22600   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22601   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22602   u64 secret;
22603   int ret;
22604
22605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22606     {
22607       if (unformat (i, "id %_%v%_", &ns_id))
22608         ;
22609       else if (unformat (i, "secret %lu", &secret))
22610         secret_set = 1;
22611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22612         sw_if_index_set = 1;
22613       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22614         ;
22615       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22616         ;
22617       else
22618         break;
22619     }
22620   if (!ns_id || !secret_set || !sw_if_index_set)
22621     {
22622       errmsg ("namespace id, secret and sw_if_index must be set");
22623       return -99;
22624     }
22625   if (vec_len (ns_id) > 64)
22626     {
22627       errmsg ("namespace id too long");
22628       return -99;
22629     }
22630   M (APP_NAMESPACE_ADD_DEL, mp);
22631
22632   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22633   mp->namespace_id_len = vec_len (ns_id);
22634   mp->secret = clib_host_to_net_u64 (secret);
22635   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22636   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22637   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22638   vec_free (ns_id);
22639   S (mp);
22640   W (ret);
22641   return ret;
22642 }
22643
22644 static int
22645 api_sock_init_shm (vat_main_t * vam)
22646 {
22647 #if VPP_API_TEST_BUILTIN == 0
22648   unformat_input_t *i = vam->input;
22649   vl_api_shm_elem_config_t *config = 0;
22650   u64 size = 64 << 20;
22651   int rv;
22652
22653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22654     {
22655       if (unformat (i, "size %U", unformat_memory_size, &size))
22656         ;
22657       else
22658         break;
22659     }
22660
22661   /*
22662    * Canned custom ring allocator config.
22663    * Should probably parse all of this
22664    */
22665   vec_validate (config, 6);
22666   config[0].type = VL_API_VLIB_RING;
22667   config[0].size = 256;
22668   config[0].count = 32;
22669
22670   config[1].type = VL_API_VLIB_RING;
22671   config[1].size = 1024;
22672   config[1].count = 16;
22673
22674   config[2].type = VL_API_VLIB_RING;
22675   config[2].size = 4096;
22676   config[2].count = 2;
22677
22678   config[3].type = VL_API_CLIENT_RING;
22679   config[3].size = 256;
22680   config[3].count = 32;
22681
22682   config[4].type = VL_API_CLIENT_RING;
22683   config[4].size = 1024;
22684   config[4].count = 16;
22685
22686   config[5].type = VL_API_CLIENT_RING;
22687   config[5].size = 4096;
22688   config[5].count = 2;
22689
22690   config[6].type = VL_API_QUEUE;
22691   config[6].count = 128;
22692   config[6].size = sizeof (uword);
22693
22694   rv = vl_socket_client_init_shm (config);
22695   if (!rv)
22696     vam->client_index_invalid = 1;
22697   return rv;
22698 #else
22699   return -99;
22700 #endif
22701 }
22702
22703 static int
22704 api_dns_enable_disable (vat_main_t * vam)
22705 {
22706   unformat_input_t *line_input = vam->input;
22707   vl_api_dns_enable_disable_t *mp;
22708   u8 enable_disable = 1;
22709   int ret;
22710
22711   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22712     {
22713       if (unformat (line_input, "disable"))
22714         enable_disable = 0;
22715       if (unformat (line_input, "enable"))
22716         enable_disable = 1;
22717       else
22718         break;
22719     }
22720
22721   /* Construct the API message */
22722   M (DNS_ENABLE_DISABLE, mp);
22723   mp->enable = enable_disable;
22724
22725   /* send it... */
22726   S (mp);
22727   /* Wait for the reply */
22728   W (ret);
22729   return ret;
22730 }
22731
22732 static int
22733 api_dns_resolve_name (vat_main_t * vam)
22734 {
22735   unformat_input_t *line_input = vam->input;
22736   vl_api_dns_resolve_name_t *mp;
22737   u8 *name = 0;
22738   int ret;
22739
22740   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22741     {
22742       if (unformat (line_input, "%s", &name))
22743         ;
22744       else
22745         break;
22746     }
22747
22748   if (vec_len (name) > 127)
22749     {
22750       errmsg ("name too long");
22751       return -99;
22752     }
22753
22754   /* Construct the API message */
22755   M (DNS_RESOLVE_NAME, mp);
22756   memcpy (mp->name, name, vec_len (name));
22757   vec_free (name);
22758
22759   /* send it... */
22760   S (mp);
22761   /* Wait for the reply */
22762   W (ret);
22763   return ret;
22764 }
22765
22766 static int
22767 api_dns_resolve_ip (vat_main_t * vam)
22768 {
22769   unformat_input_t *line_input = vam->input;
22770   vl_api_dns_resolve_ip_t *mp;
22771   int is_ip6 = -1;
22772   ip4_address_t addr4;
22773   ip6_address_t addr6;
22774   int ret;
22775
22776   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22777     {
22778       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22779         is_ip6 = 1;
22780       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22781         is_ip6 = 0;
22782       else
22783         break;
22784     }
22785
22786   if (is_ip6 == -1)
22787     {
22788       errmsg ("missing address");
22789       return -99;
22790     }
22791
22792   /* Construct the API message */
22793   M (DNS_RESOLVE_IP, mp);
22794   mp->is_ip6 = is_ip6;
22795   if (is_ip6)
22796     memcpy (mp->address, &addr6, sizeof (addr6));
22797   else
22798     memcpy (mp->address, &addr4, sizeof (addr4));
22799
22800   /* send it... */
22801   S (mp);
22802   /* Wait for the reply */
22803   W (ret);
22804   return ret;
22805 }
22806
22807 static int
22808 api_dns_name_server_add_del (vat_main_t * vam)
22809 {
22810   unformat_input_t *i = vam->input;
22811   vl_api_dns_name_server_add_del_t *mp;
22812   u8 is_add = 1;
22813   ip6_address_t ip6_server;
22814   ip4_address_t ip4_server;
22815   int ip6_set = 0;
22816   int ip4_set = 0;
22817   int ret = 0;
22818
22819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22820     {
22821       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22822         ip6_set = 1;
22823       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22824         ip4_set = 1;
22825       else if (unformat (i, "del"))
22826         is_add = 0;
22827       else
22828         {
22829           clib_warning ("parse error '%U'", format_unformat_error, i);
22830           return -99;
22831         }
22832     }
22833
22834   if (ip4_set && ip6_set)
22835     {
22836       errmsg ("Only one server address allowed per message");
22837       return -99;
22838     }
22839   if ((ip4_set + ip6_set) == 0)
22840     {
22841       errmsg ("Server address required");
22842       return -99;
22843     }
22844
22845   /* Construct the API message */
22846   M (DNS_NAME_SERVER_ADD_DEL, mp);
22847
22848   if (ip6_set)
22849     {
22850       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22851       mp->is_ip6 = 1;
22852     }
22853   else
22854     {
22855       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22856       mp->is_ip6 = 0;
22857     }
22858
22859   mp->is_add = is_add;
22860
22861   /* send it... */
22862   S (mp);
22863
22864   /* Wait for a reply, return good/bad news  */
22865   W (ret);
22866   return ret;
22867 }
22868
22869 static void
22870 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22871 {
22872   vat_main_t *vam = &vat_main;
22873
22874   if (mp->is_ip4)
22875     {
22876       print (vam->ofp,
22877              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22878              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22879              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22880              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22881              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22882              clib_net_to_host_u32 (mp->action_index), mp->tag);
22883     }
22884   else
22885     {
22886       print (vam->ofp,
22887              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22888              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22889              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22890              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22891              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22892              clib_net_to_host_u32 (mp->action_index), mp->tag);
22893     }
22894 }
22895
22896 static void
22897 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22898                                              mp)
22899 {
22900   vat_main_t *vam = &vat_main;
22901   vat_json_node_t *node = NULL;
22902   struct in6_addr ip6;
22903   struct in_addr ip4;
22904
22905   if (VAT_JSON_ARRAY != vam->json_tree.type)
22906     {
22907       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22908       vat_json_init_array (&vam->json_tree);
22909     }
22910   node = vat_json_array_add (&vam->json_tree);
22911   vat_json_init_object (node);
22912
22913   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22914   vat_json_object_add_uint (node, "appns_index",
22915                             clib_net_to_host_u32 (mp->appns_index));
22916   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22917   vat_json_object_add_uint (node, "scope", mp->scope);
22918   vat_json_object_add_uint (node, "action_index",
22919                             clib_net_to_host_u32 (mp->action_index));
22920   vat_json_object_add_uint (node, "lcl_port",
22921                             clib_net_to_host_u16 (mp->lcl_port));
22922   vat_json_object_add_uint (node, "rmt_port",
22923                             clib_net_to_host_u16 (mp->rmt_port));
22924   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22925   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22926   vat_json_object_add_string_copy (node, "tag", mp->tag);
22927   if (mp->is_ip4)
22928     {
22929       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22930       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22931       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22932       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22933     }
22934   else
22935     {
22936       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22937       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22938       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22939       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22940     }
22941 }
22942
22943 static int
22944 api_session_rule_add_del (vat_main_t * vam)
22945 {
22946   vl_api_session_rule_add_del_t *mp;
22947   unformat_input_t *i = vam->input;
22948   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22949   u32 appns_index = 0, scope = 0;
22950   ip4_address_t lcl_ip4, rmt_ip4;
22951   ip6_address_t lcl_ip6, rmt_ip6;
22952   u8 is_ip4 = 1, conn_set = 0;
22953   u8 is_add = 1, *tag = 0;
22954   int ret;
22955
22956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22957     {
22958       if (unformat (i, "del"))
22959         is_add = 0;
22960       else if (unformat (i, "add"))
22961         ;
22962       else if (unformat (i, "proto tcp"))
22963         proto = 0;
22964       else if (unformat (i, "proto udp"))
22965         proto = 1;
22966       else if (unformat (i, "appns %d", &appns_index))
22967         ;
22968       else if (unformat (i, "scope %d", &scope))
22969         ;
22970       else if (unformat (i, "tag %_%v%_", &tag))
22971         ;
22972       else
22973         if (unformat
22974             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22975              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22976              &rmt_port))
22977         {
22978           is_ip4 = 1;
22979           conn_set = 1;
22980         }
22981       else
22982         if (unformat
22983             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22984              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22985              &rmt_port))
22986         {
22987           is_ip4 = 0;
22988           conn_set = 1;
22989         }
22990       else if (unformat (i, "action %d", &action))
22991         ;
22992       else
22993         break;
22994     }
22995   if (proto == ~0 || !conn_set || action == ~0)
22996     {
22997       errmsg ("transport proto, connection and action must be set");
22998       return -99;
22999     }
23000
23001   if (scope > 3)
23002     {
23003       errmsg ("scope should be 0-3");
23004       return -99;
23005     }
23006
23007   M (SESSION_RULE_ADD_DEL, mp);
23008
23009   mp->is_ip4 = is_ip4;
23010   mp->transport_proto = proto;
23011   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
23012   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
23013   mp->lcl_plen = lcl_plen;
23014   mp->rmt_plen = rmt_plen;
23015   mp->action_index = clib_host_to_net_u32 (action);
23016   mp->appns_index = clib_host_to_net_u32 (appns_index);
23017   mp->scope = scope;
23018   mp->is_add = is_add;
23019   if (is_ip4)
23020     {
23021       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
23022       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
23023     }
23024   else
23025     {
23026       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23027       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23028     }
23029   if (tag)
23030     {
23031       clib_memcpy (mp->tag, tag, vec_len (tag));
23032       vec_free (tag);
23033     }
23034
23035   S (mp);
23036   W (ret);
23037   return ret;
23038 }
23039
23040 static int
23041 api_session_rules_dump (vat_main_t * vam)
23042 {
23043   vl_api_session_rules_dump_t *mp;
23044   vl_api_control_ping_t *mp_ping;
23045   int ret;
23046
23047   if (!vam->json_output)
23048     {
23049       print (vam->ofp, "%=20s", "Session Rules");
23050     }
23051
23052   M (SESSION_RULES_DUMP, mp);
23053   /* send it... */
23054   S (mp);
23055
23056   /* Use a control ping for synchronization */
23057   MPING (CONTROL_PING, mp_ping);
23058   S (mp_ping);
23059
23060   /* Wait for a reply... */
23061   W (ret);
23062   return ret;
23063 }
23064
23065 static int
23066 api_ip_container_proxy_add_del (vat_main_t * vam)
23067 {
23068   vl_api_ip_container_proxy_add_del_t *mp;
23069   unformat_input_t *i = vam->input;
23070   u32 plen = ~0, sw_if_index = ~0;
23071   ip4_address_t ip4;
23072   ip6_address_t ip6;
23073   u8 is_ip4 = 1;
23074   u8 is_add = 1;
23075   int ret;
23076
23077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23078     {
23079       if (unformat (i, "del"))
23080         is_add = 0;
23081       else if (unformat (i, "add"))
23082         ;
23083       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23084         {
23085           is_ip4 = 1;
23086           plen = 32;
23087         }
23088       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23089         {
23090           is_ip4 = 0;
23091           plen = 128;
23092         }
23093       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23094         ;
23095       else
23096         break;
23097     }
23098   if (sw_if_index == ~0 || plen == ~0)
23099     {
23100       errmsg ("address and sw_if_index must be set");
23101       return -99;
23102     }
23103
23104   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23105
23106   mp->is_ip4 = is_ip4;
23107   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23108   mp->plen = plen;
23109   mp->is_add = is_add;
23110   if (is_ip4)
23111     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23112   else
23113     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23114
23115   S (mp);
23116   W (ret);
23117   return ret;
23118 }
23119
23120 static int
23121 api_qos_record_enable_disable (vat_main_t * vam)
23122 {
23123   unformat_input_t *i = vam->input;
23124   vl_api_qos_record_enable_disable_t *mp;
23125   u32 sw_if_index, qs = 0xff;
23126   u8 sw_if_index_set = 0;
23127   u8 enable = 1;
23128   int ret;
23129
23130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23131     {
23132       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23133         sw_if_index_set = 1;
23134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23135         sw_if_index_set = 1;
23136       else if (unformat (i, "%U", unformat_qos_source, &qs))
23137         ;
23138       else if (unformat (i, "disable"))
23139         enable = 0;
23140       else
23141         {
23142           clib_warning ("parse error '%U'", format_unformat_error, i);
23143           return -99;
23144         }
23145     }
23146
23147   if (sw_if_index_set == 0)
23148     {
23149       errmsg ("missing interface name or sw_if_index");
23150       return -99;
23151     }
23152   if (qs == 0xff)
23153     {
23154       errmsg ("input location must be specified");
23155       return -99;
23156     }
23157
23158   M (QOS_RECORD_ENABLE_DISABLE, mp);
23159
23160   mp->sw_if_index = ntohl (sw_if_index);
23161   mp->input_source = qs;
23162   mp->enable = enable;
23163
23164   S (mp);
23165   W (ret);
23166   return ret;
23167 }
23168
23169
23170 static int
23171 q_or_quit (vat_main_t * vam)
23172 {
23173 #if VPP_API_TEST_BUILTIN == 0
23174   longjmp (vam->jump_buf, 1);
23175 #endif
23176   return 0;                     /* not so much */
23177 }
23178
23179 static int
23180 q (vat_main_t * vam)
23181 {
23182   return q_or_quit (vam);
23183 }
23184
23185 static int
23186 quit (vat_main_t * vam)
23187 {
23188   return q_or_quit (vam);
23189 }
23190
23191 static int
23192 comment (vat_main_t * vam)
23193 {
23194   return 0;
23195 }
23196
23197 static int
23198 statseg (vat_main_t * vam)
23199 {
23200   ssvm_private_t *ssvmp = &vam->stat_segment;
23201   ssvm_shared_header_t *shared_header = ssvmp->sh;
23202   vlib_counter_t **counters;
23203   u64 thread0_index1_packets;
23204   u64 thread0_index1_bytes;
23205   f64 vector_rate, input_rate;
23206   uword *p;
23207
23208   uword *counter_vector_by_name;
23209   if (vam->stat_segment_lockp == 0)
23210     {
23211       errmsg ("Stat segment not mapped...");
23212       return -99;
23213     }
23214
23215   /* look up "/if/rx for sw_if_index 1 as a test */
23216
23217   clib_spinlock_lock (vam->stat_segment_lockp);
23218
23219   counter_vector_by_name = (uword *) shared_header->opaque[1];
23220
23221   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23222   if (p == 0)
23223     {
23224       clib_spinlock_unlock (vam->stat_segment_lockp);
23225       errmsg ("/if/tx not found?");
23226       return -99;
23227     }
23228
23229   /* Fish per-thread vector of combined counters from shared memory */
23230   counters = (vlib_counter_t **) p[0];
23231
23232   if (vec_len (counters[0]) < 2)
23233     {
23234       clib_spinlock_unlock (vam->stat_segment_lockp);
23235       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23236       return -99;
23237     }
23238
23239   /* Read thread 0 sw_if_index 1 counter */
23240   thread0_index1_packets = counters[0][1].packets;
23241   thread0_index1_bytes = counters[0][1].bytes;
23242
23243   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23244   if (p == 0)
23245     {
23246       clib_spinlock_unlock (vam->stat_segment_lockp);
23247       errmsg ("vector_rate not found?");
23248       return -99;
23249     }
23250
23251   vector_rate = *(f64 *) (p[0]);
23252   p = hash_get_mem (counter_vector_by_name, "input_rate");
23253   if (p == 0)
23254     {
23255       clib_spinlock_unlock (vam->stat_segment_lockp);
23256       errmsg ("input_rate not found?");
23257       return -99;
23258     }
23259   input_rate = *(f64 *) (p[0]);
23260
23261   clib_spinlock_unlock (vam->stat_segment_lockp);
23262
23263   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23264          vector_rate, input_rate);
23265   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23266          thread0_index1_packets, thread0_index1_bytes);
23267
23268   return 0;
23269 }
23270
23271 static int
23272 cmd_cmp (void *a1, void *a2)
23273 {
23274   u8 **c1 = a1;
23275   u8 **c2 = a2;
23276
23277   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23278 }
23279
23280 static int
23281 help (vat_main_t * vam)
23282 {
23283   u8 **cmds = 0;
23284   u8 *name = 0;
23285   hash_pair_t *p;
23286   unformat_input_t *i = vam->input;
23287   int j;
23288
23289   if (unformat (i, "%s", &name))
23290     {
23291       uword *hs;
23292
23293       vec_add1 (name, 0);
23294
23295       hs = hash_get_mem (vam->help_by_name, name);
23296       if (hs)
23297         print (vam->ofp, "usage: %s %s", name, hs[0]);
23298       else
23299         print (vam->ofp, "No such msg / command '%s'", name);
23300       vec_free (name);
23301       return 0;
23302     }
23303
23304   print (vam->ofp, "Help is available for the following:");
23305
23306     /* *INDENT-OFF* */
23307     hash_foreach_pair (p, vam->function_by_name,
23308     ({
23309       vec_add1 (cmds, (u8 *)(p->key));
23310     }));
23311     /* *INDENT-ON* */
23312
23313   vec_sort_with_function (cmds, cmd_cmp);
23314
23315   for (j = 0; j < vec_len (cmds); j++)
23316     print (vam->ofp, "%s", cmds[j]);
23317
23318   vec_free (cmds);
23319   return 0;
23320 }
23321
23322 static int
23323 set (vat_main_t * vam)
23324 {
23325   u8 *name = 0, *value = 0;
23326   unformat_input_t *i = vam->input;
23327
23328   if (unformat (i, "%s", &name))
23329     {
23330       /* The input buffer is a vector, not a string. */
23331       value = vec_dup (i->buffer);
23332       vec_delete (value, i->index, 0);
23333       /* Almost certainly has a trailing newline */
23334       if (value[vec_len (value) - 1] == '\n')
23335         value[vec_len (value) - 1] = 0;
23336       /* Make sure it's a proper string, one way or the other */
23337       vec_add1 (value, 0);
23338       (void) clib_macro_set_value (&vam->macro_main,
23339                                    (char *) name, (char *) value);
23340     }
23341   else
23342     errmsg ("usage: set <name> <value>");
23343
23344   vec_free (name);
23345   vec_free (value);
23346   return 0;
23347 }
23348
23349 static int
23350 unset (vat_main_t * vam)
23351 {
23352   u8 *name = 0;
23353
23354   if (unformat (vam->input, "%s", &name))
23355     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23356       errmsg ("unset: %s wasn't set", name);
23357   vec_free (name);
23358   return 0;
23359 }
23360
23361 typedef struct
23362 {
23363   u8 *name;
23364   u8 *value;
23365 } macro_sort_t;
23366
23367
23368 static int
23369 macro_sort_cmp (void *a1, void *a2)
23370 {
23371   macro_sort_t *s1 = a1;
23372   macro_sort_t *s2 = a2;
23373
23374   return strcmp ((char *) (s1->name), (char *) (s2->name));
23375 }
23376
23377 static int
23378 dump_macro_table (vat_main_t * vam)
23379 {
23380   macro_sort_t *sort_me = 0, *sm;
23381   int i;
23382   hash_pair_t *p;
23383
23384     /* *INDENT-OFF* */
23385     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23386     ({
23387       vec_add2 (sort_me, sm, 1);
23388       sm->name = (u8 *)(p->key);
23389       sm->value = (u8 *) (p->value[0]);
23390     }));
23391     /* *INDENT-ON* */
23392
23393   vec_sort_with_function (sort_me, macro_sort_cmp);
23394
23395   if (vec_len (sort_me))
23396     print (vam->ofp, "%-15s%s", "Name", "Value");
23397   else
23398     print (vam->ofp, "The macro table is empty...");
23399
23400   for (i = 0; i < vec_len (sort_me); i++)
23401     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23402   return 0;
23403 }
23404
23405 static int
23406 dump_node_table (vat_main_t * vam)
23407 {
23408   int i, j;
23409   vlib_node_t *node, *next_node;
23410
23411   if (vec_len (vam->graph_nodes) == 0)
23412     {
23413       print (vam->ofp, "Node table empty, issue get_node_graph...");
23414       return 0;
23415     }
23416
23417   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23418     {
23419       node = vam->graph_nodes[0][i];
23420       print (vam->ofp, "[%d] %s", i, node->name);
23421       for (j = 0; j < vec_len (node->next_nodes); j++)
23422         {
23423           if (node->next_nodes[j] != ~0)
23424             {
23425               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23426               print (vam->ofp, "  [%d] %s", j, next_node->name);
23427             }
23428         }
23429     }
23430   return 0;
23431 }
23432
23433 static int
23434 value_sort_cmp (void *a1, void *a2)
23435 {
23436   name_sort_t *n1 = a1;
23437   name_sort_t *n2 = a2;
23438
23439   if (n1->value < n2->value)
23440     return -1;
23441   if (n1->value > n2->value)
23442     return 1;
23443   return 0;
23444 }
23445
23446
23447 static int
23448 dump_msg_api_table (vat_main_t * vam)
23449 {
23450   api_main_t *am = &api_main;
23451   name_sort_t *nses = 0, *ns;
23452   hash_pair_t *hp;
23453   int i;
23454
23455   /* *INDENT-OFF* */
23456   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23457   ({
23458     vec_add2 (nses, ns, 1);
23459     ns->name = (u8 *)(hp->key);
23460     ns->value = (u32) hp->value[0];
23461   }));
23462   /* *INDENT-ON* */
23463
23464   vec_sort_with_function (nses, value_sort_cmp);
23465
23466   for (i = 0; i < vec_len (nses); i++)
23467     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23468   vec_free (nses);
23469   return 0;
23470 }
23471
23472 static int
23473 get_msg_id (vat_main_t * vam)
23474 {
23475   u8 *name_and_crc;
23476   u32 message_index;
23477
23478   if (unformat (vam->input, "%s", &name_and_crc))
23479     {
23480       message_index = vl_msg_api_get_msg_index (name_and_crc);
23481       if (message_index == ~0)
23482         {
23483           print (vam->ofp, " '%s' not found", name_and_crc);
23484           return 0;
23485         }
23486       print (vam->ofp, " '%s' has message index %d",
23487              name_and_crc, message_index);
23488       return 0;
23489     }
23490   errmsg ("name_and_crc required...");
23491   return 0;
23492 }
23493
23494 static int
23495 search_node_table (vat_main_t * vam)
23496 {
23497   unformat_input_t *line_input = vam->input;
23498   u8 *node_to_find;
23499   int j;
23500   vlib_node_t *node, *next_node;
23501   uword *p;
23502
23503   if (vam->graph_node_index_by_name == 0)
23504     {
23505       print (vam->ofp, "Node table empty, issue get_node_graph...");
23506       return 0;
23507     }
23508
23509   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23510     {
23511       if (unformat (line_input, "%s", &node_to_find))
23512         {
23513           vec_add1 (node_to_find, 0);
23514           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23515           if (p == 0)
23516             {
23517               print (vam->ofp, "%s not found...", node_to_find);
23518               goto out;
23519             }
23520           node = vam->graph_nodes[0][p[0]];
23521           print (vam->ofp, "[%d] %s", p[0], node->name);
23522           for (j = 0; j < vec_len (node->next_nodes); j++)
23523             {
23524               if (node->next_nodes[j] != ~0)
23525                 {
23526                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23527                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23528                 }
23529             }
23530         }
23531
23532       else
23533         {
23534           clib_warning ("parse error '%U'", format_unformat_error,
23535                         line_input);
23536           return -99;
23537         }
23538
23539     out:
23540       vec_free (node_to_find);
23541
23542     }
23543
23544   return 0;
23545 }
23546
23547
23548 static int
23549 script (vat_main_t * vam)
23550 {
23551 #if (VPP_API_TEST_BUILTIN==0)
23552   u8 *s = 0;
23553   char *save_current_file;
23554   unformat_input_t save_input;
23555   jmp_buf save_jump_buf;
23556   u32 save_line_number;
23557
23558   FILE *new_fp, *save_ifp;
23559
23560   if (unformat (vam->input, "%s", &s))
23561     {
23562       new_fp = fopen ((char *) s, "r");
23563       if (new_fp == 0)
23564         {
23565           errmsg ("Couldn't open script file %s", s);
23566           vec_free (s);
23567           return -99;
23568         }
23569     }
23570   else
23571     {
23572       errmsg ("Missing script name");
23573       return -99;
23574     }
23575
23576   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23577   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23578   save_ifp = vam->ifp;
23579   save_line_number = vam->input_line_number;
23580   save_current_file = (char *) vam->current_file;
23581
23582   vam->input_line_number = 0;
23583   vam->ifp = new_fp;
23584   vam->current_file = s;
23585   do_one_file (vam);
23586
23587   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23588   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23589   vam->ifp = save_ifp;
23590   vam->input_line_number = save_line_number;
23591   vam->current_file = (u8 *) save_current_file;
23592   vec_free (s);
23593
23594   return 0;
23595 #else
23596   clib_warning ("use the exec command...");
23597   return -99;
23598 #endif
23599 }
23600
23601 static int
23602 echo (vat_main_t * vam)
23603 {
23604   print (vam->ofp, "%v", vam->input->buffer);
23605   return 0;
23606 }
23607
23608 /* List of API message constructors, CLI names map to api_xxx */
23609 #define foreach_vpe_api_msg                                             \
23610 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23611 _(sw_interface_dump,"")                                                 \
23612 _(sw_interface_set_flags,                                               \
23613   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23614 _(sw_interface_add_del_address,                                         \
23615   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23616 _(sw_interface_set_rx_mode,                                             \
23617   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23618 _(sw_interface_set_rx_placement,                                        \
23619   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23620 _(sw_interface_rx_placement_dump,                                       \
23621   "[<intfc> | sw_if_index <id>]")                                         \
23622 _(sw_interface_set_table,                                               \
23623   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23624 _(sw_interface_set_mpls_enable,                                         \
23625   "<intfc> | sw_if_index [disable | dis]")                              \
23626 _(sw_interface_set_vpath,                                               \
23627   "<intfc> | sw_if_index <id> enable | disable")                        \
23628 _(sw_interface_set_vxlan_bypass,                                        \
23629   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23630 _(sw_interface_set_geneve_bypass,                                       \
23631   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23632 _(sw_interface_set_l2_xconnect,                                         \
23633   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23634   "enable | disable")                                                   \
23635 _(sw_interface_set_l2_bridge,                                           \
23636   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23637   "[shg <split-horizon-group>] [bvi]\n"                                 \
23638   "enable | disable")                                                   \
23639 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23640 _(bridge_domain_add_del,                                                \
23641   "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") \
23642 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23643 _(l2fib_add_del,                                                        \
23644   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23645 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23646 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23647 _(l2_flags,                                                             \
23648   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23649 _(bridge_flags,                                                         \
23650   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23651 _(tap_connect,                                                          \
23652   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23653 _(tap_modify,                                                           \
23654   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23655 _(tap_delete,                                                           \
23656   "<vpp-if-name> | sw_if_index <id>")                                   \
23657 _(sw_interface_tap_dump, "")                                            \
23658 _(tap_create_v2,                                                        \
23659   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23660 _(tap_delete_v2,                                                        \
23661   "<vpp-if-name> | sw_if_index <id>")                                   \
23662 _(sw_interface_tap_v2_dump, "")                                         \
23663 _(bond_create,                                                          \
23664   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23665   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23666 _(bond_delete,                                                          \
23667   "<vpp-if-name> | sw_if_index <id>")                                   \
23668 _(bond_enslave,                                                         \
23669   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23670 _(bond_detach_slave,                                                    \
23671   "sw_if_index <n>")                                                    \
23672 _(sw_interface_bond_dump, "")                                           \
23673 _(sw_interface_slave_dump,                                              \
23674   "<vpp-if-name> | sw_if_index <id>")                                   \
23675 _(ip_table_add_del,                                                     \
23676   "table <n> [ipv6] [add | del]\n")                                     \
23677 _(ip_add_del_route,                                                     \
23678   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23679   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23680   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23681   "[multipath] [count <n>] [del]")                                      \
23682 _(ip_mroute_add_del,                                                    \
23683   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23684   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23685 _(mpls_table_add_del,                                                   \
23686   "table <n> [add | del]\n")                                            \
23687 _(mpls_route_add_del,                                                   \
23688   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23689   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23690   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23691   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23692   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23693   "[count <n>] [del]")                                                  \
23694 _(mpls_ip_bind_unbind,                                                  \
23695   "<label> <addr/len>")                                                 \
23696 _(mpls_tunnel_add_del,                                                  \
23697   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23698   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23699   "[l2-only]  [out-label <n>]")                                         \
23700 _(sr_mpls_policy_add,                                                   \
23701   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23702 _(sr_mpls_policy_del,                                                   \
23703   "bsid <id>")                                                          \
23704 _(bier_table_add_del,                                                   \
23705   "<label> <sub-domain> <set> <bsl> [del]")                             \
23706 _(bier_route_add_del,                                                   \
23707   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23708   "[<intfc> | sw_if_index <id>]"                                        \
23709   "[weight <n>] [del] [multipath]")                                     \
23710 _(proxy_arp_add_del,                                                    \
23711   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23712 _(proxy_arp_intfc_enable_disable,                                       \
23713   "<intfc> | sw_if_index <id> enable | disable")                        \
23714 _(sw_interface_set_unnumbered,                                          \
23715   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23716 _(ip_neighbor_add_del,                                                  \
23717   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23718   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23719 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23720 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23721   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23722   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23723   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23724 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23725 _(reset_fib, "vrf <n> [ipv6]")                                          \
23726 _(dhcp_proxy_config,                                                    \
23727   "svr <v46-address> src <v46-address>\n"                               \
23728    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23729 _(dhcp_proxy_set_vss,                                                   \
23730   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23731 _(dhcp_proxy_dump, "ip6")                                               \
23732 _(dhcp_client_config,                                                   \
23733   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23734 _(set_ip_flow_hash,                                                     \
23735   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23736 _(sw_interface_ip6_enable_disable,                                      \
23737   "<intfc> | sw_if_index <id> enable | disable")                        \
23738 _(ip6nd_proxy_add_del,                                                  \
23739   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23740 _(ip6nd_proxy_dump, "")                                                 \
23741 _(sw_interface_ip6nd_ra_prefix,                                         \
23742   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23743   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23744   "[nolink] [isno]")                                                    \
23745 _(sw_interface_ip6nd_ra_config,                                         \
23746   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23747   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23748   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23749 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23750 _(l2_patch_add_del,                                                     \
23751   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23752   "enable | disable")                                                   \
23753 _(sr_localsid_add_del,                                                  \
23754   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23755   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23756 _(classify_add_del_table,                                               \
23757   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23758   " [del] [del-chain] mask <mask-value>\n"                              \
23759   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23760   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23761 _(classify_add_del_session,                                             \
23762   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23763   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23764   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23765   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23766 _(classify_set_interface_ip_table,                                      \
23767   "<intfc> | sw_if_index <nn> table <nn>")                              \
23768 _(classify_set_interface_l2_tables,                                     \
23769   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23770   "  [other-table <nn>]")                                               \
23771 _(get_node_index, "node <node-name")                                    \
23772 _(add_node_next, "node <node-name> next <next-node-name>")              \
23773 _(l2tpv3_create_tunnel,                                                 \
23774   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23775   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23776   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23777 _(l2tpv3_set_tunnel_cookies,                                            \
23778   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23779   "[new_remote_cookie <nn>]\n")                                         \
23780 _(l2tpv3_interface_enable_disable,                                      \
23781   "<intfc> | sw_if_index <nn> enable | disable")                        \
23782 _(l2tpv3_set_lookup_key,                                                \
23783   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23784 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23785 _(vxlan_offload_rx,                                                     \
23786   "hw { <interface name> | hw_if_index <nn>} "                          \
23787   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23788 _(vxlan_add_del_tunnel,                                                 \
23789   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23790   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23791   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23792 _(geneve_add_del_tunnel,                                                \
23793   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23794   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23795   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23796 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23797 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23798 _(gre_add_del_tunnel,                                                   \
23799   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23800   "[teb | erspan <session-id>] [del]")                                  \
23801 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23802 _(l2_fib_clear_table, "")                                               \
23803 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23804 _(l2_interface_vlan_tag_rewrite,                                        \
23805   "<intfc> | sw_if_index <nn> \n"                                       \
23806   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23807   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23808 _(create_vhost_user_if,                                                 \
23809         "socket <filename> [server] [renumber <dev_instance>] "         \
23810         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23811         "[mac <mac_address>]")                                          \
23812 _(modify_vhost_user_if,                                                 \
23813         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23814         "[server] [renumber <dev_instance>]")                           \
23815 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23816 _(sw_interface_vhost_user_dump, "")                                     \
23817 _(show_version, "")                                                     \
23818 _(show_threads, "")                                                     \
23819 _(vxlan_gpe_add_del_tunnel,                                             \
23820   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23821   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23822   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23823   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23824 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23825 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23826 _(interface_name_renumber,                                              \
23827   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23828 _(input_acl_set_interface,                                              \
23829   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23830   "  [l2-table <nn>] [del]")                                            \
23831 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23832 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23833   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23834 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23835 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23836 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23837 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23838 _(ip_dump, "ipv4 | ipv6")                                               \
23839 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23840 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23841   "  spid_id <n> ")                                                     \
23842 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23843   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23844   "  integ_alg <alg> integ_key <hex>")                                  \
23845 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23846   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23847   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23848   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23849 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23850 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23851   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23852   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23853   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23854   "  [instance <n>]")     \
23855 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23856 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23857   "  <alg> <hex>\n")                                                    \
23858 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23859 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23860 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23861   "(auth_data 0x<data> | auth_data <data>)")                            \
23862 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23863   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23864 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23865   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23866   "(local|remote)")                                                     \
23867 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23868 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23869 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23870 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23871 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23872 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23873 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23874 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23875 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23876 _(delete_loopback,"sw_if_index <nn>")                                   \
23877 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23878 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23879 _(want_interface_events,  "enable|disable")                             \
23880 _(want_stats,"enable|disable")                                          \
23881 _(get_first_msg_id, "client <name>")                                    \
23882 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23883 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23884   "fib-id <nn> [ip4][ip6][default]")                                    \
23885 _(get_node_graph, " ")                                                  \
23886 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23887 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23888 _(ioam_disable, "")                                                     \
23889 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23890                             " sw_if_index <sw_if_index> p <priority> "  \
23891                             "w <weight>] [del]")                        \
23892 _(one_add_del_locator, "locator-set <locator_name> "                    \
23893                         "iface <intf> | sw_if_index <sw_if_index> "     \
23894                         "p <priority> w <weight> [del]")                \
23895 _(one_add_del_local_eid,"vni <vni> eid "                                \
23896                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23897                          "locator-set <locator_name> [del]"             \
23898                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23899 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23900 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23901 _(one_enable_disable, "enable|disable")                                 \
23902 _(one_map_register_enable_disable, "enable|disable")                    \
23903 _(one_map_register_fallback_threshold, "<value>")                       \
23904 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23905 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23906                                "[seid <seid>] "                         \
23907                                "rloc <locator> p <prio> "               \
23908                                "w <weight> [rloc <loc> ... ] "          \
23909                                "action <action> [del-all]")             \
23910 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23911                           "<local-eid>")                                \
23912 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23913 _(one_use_petr, "ip-address> | disable")                                \
23914 _(one_map_request_mode, "src-dst|dst-only")                             \
23915 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23916 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23917 _(one_locator_set_dump, "[local | remote]")                             \
23918 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23919 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23920                        "[local] | [remote]")                            \
23921 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23922 _(one_ndp_bd_get, "")                                                   \
23923 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23924 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23925 _(one_l2_arp_bd_get, "")                                                \
23926 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23927 _(one_stats_enable_disable, "enable|disable")                           \
23928 _(show_one_stats_enable_disable, "")                                    \
23929 _(one_eid_table_vni_dump, "")                                           \
23930 _(one_eid_table_map_dump, "l2|l3")                                      \
23931 _(one_map_resolver_dump, "")                                            \
23932 _(one_map_server_dump, "")                                              \
23933 _(one_adjacencies_get, "vni <vni>")                                     \
23934 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23935 _(show_one_rloc_probe_state, "")                                        \
23936 _(show_one_map_register_state, "")                                      \
23937 _(show_one_status, "")                                                  \
23938 _(one_stats_dump, "")                                                   \
23939 _(one_stats_flush, "")                                                  \
23940 _(one_get_map_request_itr_rlocs, "")                                    \
23941 _(one_map_register_set_ttl, "<ttl>")                                    \
23942 _(one_set_transport_protocol, "udp|api")                                \
23943 _(one_get_transport_protocol, "")                                       \
23944 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23945 _(one_show_xtr_mode, "")                                                \
23946 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23947 _(one_show_pitr_mode, "")                                               \
23948 _(one_enable_disable_petr_mode, "enable|disable")                       \
23949 _(one_show_petr_mode, "")                                               \
23950 _(show_one_nsh_mapping, "")                                             \
23951 _(show_one_pitr, "")                                                    \
23952 _(show_one_use_petr, "")                                                \
23953 _(show_one_map_request_mode, "")                                        \
23954 _(show_one_map_register_ttl, "")                                        \
23955 _(show_one_map_register_fallback_threshold, "")                         \
23956 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23957                             " sw_if_index <sw_if_index> p <priority> "  \
23958                             "w <weight>] [del]")                        \
23959 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23960                         "iface <intf> | sw_if_index <sw_if_index> "     \
23961                         "p <priority> w <weight> [del]")                \
23962 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23963                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23964                          "locator-set <locator_name> [del]"             \
23965                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23966 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23967 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23968 _(lisp_enable_disable, "enable|disable")                                \
23969 _(lisp_map_register_enable_disable, "enable|disable")                   \
23970 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23971 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23972                                "[seid <seid>] "                         \
23973                                "rloc <locator> p <prio> "               \
23974                                "w <weight> [rloc <loc> ... ] "          \
23975                                "action <action> [del-all]")             \
23976 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23977                           "<local-eid>")                                \
23978 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23979 _(lisp_use_petr, "<ip-address> | disable")                              \
23980 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23981 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23982 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23983 _(lisp_locator_set_dump, "[local | remote]")                            \
23984 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23985 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23986                        "[local] | [remote]")                            \
23987 _(lisp_eid_table_vni_dump, "")                                          \
23988 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23989 _(lisp_map_resolver_dump, "")                                           \
23990 _(lisp_map_server_dump, "")                                             \
23991 _(lisp_adjacencies_get, "vni <vni>")                                    \
23992 _(gpe_fwd_entry_vnis_get, "")                                           \
23993 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23994 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23995                                 "[table <table-id>]")                   \
23996 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23997 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23998 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23999 _(gpe_get_encap_mode, "")                                               \
24000 _(lisp_gpe_add_del_iface, "up|down")                                    \
24001 _(lisp_gpe_enable_disable, "enable|disable")                            \
24002 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
24003   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
24004 _(show_lisp_rloc_probe_state, "")                                       \
24005 _(show_lisp_map_register_state, "")                                     \
24006 _(show_lisp_status, "")                                                 \
24007 _(lisp_get_map_request_itr_rlocs, "")                                   \
24008 _(show_lisp_pitr, "")                                                   \
24009 _(show_lisp_use_petr, "")                                               \
24010 _(show_lisp_map_request_mode, "")                                       \
24011 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
24012 _(af_packet_delete, "name <host interface name>")                       \
24013 _(af_packet_dump, "")                                                   \
24014 _(policer_add_del, "name <policer name> <params> [del]")                \
24015 _(policer_dump, "[name <policer name>]")                                \
24016 _(policer_classify_set_interface,                                       \
24017   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24018   "  [l2-table <nn>] [del]")                                            \
24019 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
24020 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
24021     "[master|slave]")                                                   \
24022 _(netmap_delete, "name <interface name>")                               \
24023 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
24024 _(mpls_fib_dump, "")                                                    \
24025 _(classify_table_ids, "")                                               \
24026 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24027 _(classify_table_info, "table_id <nn>")                                 \
24028 _(classify_session_dump, "table_id <nn>")                               \
24029 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24030     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24031     "[template_interval <nn>] [udp_checksum]")                          \
24032 _(ipfix_exporter_dump, "")                                              \
24033 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24034 _(ipfix_classify_stream_dump, "")                                       \
24035 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24036 _(ipfix_classify_table_dump, "")                                        \
24037 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24038 _(sw_interface_span_dump, "[l2]")                                           \
24039 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24040 _(pg_create_interface, "if_id <nn>")                                    \
24041 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24042 _(pg_enable_disable, "[stream <id>] disable")                           \
24043 _(ip_source_and_port_range_check_add_del,                               \
24044   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24045 _(ip_source_and_port_range_check_interface_add_del,                     \
24046   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24047   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24048 _(ipsec_gre_add_del_tunnel,                                             \
24049   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24050 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24051 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24052 _(l2_interface_pbb_tag_rewrite,                                         \
24053   "<intfc> | sw_if_index <nn> \n"                                       \
24054   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24055   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24056 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24057 _(flow_classify_set_interface,                                          \
24058   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24059 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24060 _(ip_fib_dump, "")                                                      \
24061 _(ip_mfib_dump, "")                                                     \
24062 _(ip6_fib_dump, "")                                                     \
24063 _(ip6_mfib_dump, "")                                                    \
24064 _(feature_enable_disable, "arc_name <arc_name> "                        \
24065   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24066 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24067 "[disable]")                                                            \
24068 _(l2_xconnect_dump, "")                                                 \
24069 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24070 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24071 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24072 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24073 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24074 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24075 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24076   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24077 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24078 _(sock_init_shm, "size <nnn>")                                          \
24079 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24080 _(dns_enable_disable, "[enable][disable]")                              \
24081 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24082 _(dns_resolve_name, "<hostname>")                                       \
24083 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24084 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24085 _(dns_resolve_name, "<hostname>")                                       \
24086 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24087   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24088 _(session_rules_dump, "")                                               \
24089 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24090 _(output_acl_set_interface,                                             \
24091   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24092   "  [l2-table <nn>] [del]")                                            \
24093 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24094
24095 /* List of command functions, CLI names map directly to functions */
24096 #define foreach_cli_function                                    \
24097 _(comment, "usage: comment <ignore-rest-of-line>")              \
24098 _(dump_interface_table, "usage: dump_interface_table")          \
24099 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24100 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24101 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24102 _(dump_stats_table, "usage: dump_stats_table")                  \
24103 _(dump_macro_table, "usage: dump_macro_table ")                 \
24104 _(dump_node_table, "usage: dump_node_table")                    \
24105 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24106 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24107 _(echo, "usage: echo <message>")                                \
24108 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24109 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24110 _(help, "usage: help")                                          \
24111 _(q, "usage: quit")                                             \
24112 _(quit, "usage: quit")                                          \
24113 _(search_node_table, "usage: search_node_table <name>...")      \
24114 _(set, "usage: set <variable-name> <value>")                    \
24115 _(script, "usage: script <file-name>")                          \
24116 _(statseg, "usage: statseg");                                   \
24117 _(unset, "usage: unset <variable-name>")
24118
24119 #define _(N,n)                                  \
24120     static void vl_api_##n##_t_handler_uni      \
24121     (vl_api_##n##_t * mp)                       \
24122     {                                           \
24123         vat_main_t * vam = &vat_main;           \
24124         if (vam->json_output) {                 \
24125             vl_api_##n##_t_handler_json(mp);    \
24126         } else {                                \
24127             vl_api_##n##_t_handler(mp);         \
24128         }                                       \
24129     }
24130 foreach_vpe_api_reply_msg;
24131 #if VPP_API_TEST_BUILTIN == 0
24132 foreach_standalone_reply_msg;
24133 #endif
24134 #undef _
24135
24136 void
24137 vat_api_hookup (vat_main_t * vam)
24138 {
24139 #define _(N,n)                                                  \
24140     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24141                            vl_api_##n##_t_handler_uni,          \
24142                            vl_noop_handler,                     \
24143                            vl_api_##n##_t_endian,               \
24144                            vl_api_##n##_t_print,                \
24145                            sizeof(vl_api_##n##_t), 1);
24146   foreach_vpe_api_reply_msg;
24147 #if VPP_API_TEST_BUILTIN == 0
24148   foreach_standalone_reply_msg;
24149 #endif
24150 #undef _
24151
24152 #if (VPP_API_TEST_BUILTIN==0)
24153   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24154
24155   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24156
24157   vam->function_by_name = hash_create_string (0, sizeof (uword));
24158
24159   vam->help_by_name = hash_create_string (0, sizeof (uword));
24160 #endif
24161
24162   /* API messages we can send */
24163 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24164   foreach_vpe_api_msg;
24165 #undef _
24166
24167   /* Help strings */
24168 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24169   foreach_vpe_api_msg;
24170 #undef _
24171
24172   /* CLI functions */
24173 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24174   foreach_cli_function;
24175 #undef _
24176
24177   /* Help strings */
24178 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24179   foreach_cli_function;
24180 #undef _
24181 }
24182
24183 #if VPP_API_TEST_BUILTIN
24184 static clib_error_t *
24185 vat_api_hookup_shim (vlib_main_t * vm)
24186 {
24187   vat_api_hookup (&vat_main);
24188   return 0;
24189 }
24190
24191 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24192 #endif
24193
24194 /*
24195  * fd.io coding-style-patch-verification: ON
24196  *
24197  * Local Variables:
24198  * eval: (c-set-style "gnu")
24199  * End:
24200  */