String type: Not include \0 in show_version
[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 *s;
1306       char *p = (char *) &mp->program;
1307
1308       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1309       errmsg ("        program: %s\n", s);
1310       free (s);
1311
1312       p +=
1313         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1314       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1315       errmsg ("        version: %s\n", s);
1316       free (s);
1317
1318       p +=
1319         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1320       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1321       errmsg ("     build date: %s\n", s);
1322       free (s);
1323
1324       p +=
1325         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1326       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1327       errmsg ("build directory: %s\n", s);
1328       free (s);
1329     }
1330   vam->retval = retval;
1331   vam->result_ready = 1;
1332 }
1333
1334 static void vl_api_show_version_reply_t_handler_json
1335   (vl_api_show_version_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   vat_json_node_t node;
1339
1340   vat_json_init_object (&node);
1341   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1342   char *p = (char *) &mp->program;
1343   vat_json_object_add_string_copy (&node, "program",
1344                                    vl_api_from_api_string ((vl_api_string_t *)
1345                                                            p));
1346   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1347   vat_json_object_add_string_copy (&node, "version",
1348                                    vl_api_from_api_string ((vl_api_string_t *)
1349                                                            p));
1350   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1351   vat_json_object_add_string_copy (&node, "build_date",
1352                                    vl_api_from_api_string ((vl_api_string_t *)
1353                                                            p));
1354   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1355   vat_json_object_add_string_copy (&node, "build_directory",
1356                                    vl_api_from_api_string ((vl_api_string_t *)
1357                                                            p));
1358
1359   vat_json_print (vam->ofp, &node);
1360   vat_json_free (&node);
1361
1362   vam->retval = ntohl (mp->retval);
1363   vam->result_ready = 1;
1364 }
1365
1366 static void vl_api_show_threads_reply_t_handler
1367   (vl_api_show_threads_reply_t * mp)
1368 {
1369   vat_main_t *vam = &vat_main;
1370   i32 retval = ntohl (mp->retval);
1371   int i, count = 0;
1372
1373   if (retval >= 0)
1374     count = ntohl (mp->count);
1375
1376   for (i = 0; i < count; i++)
1377     print (vam->ofp,
1378            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1379            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1380            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1381            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1382            ntohl (mp->thread_data[i].cpu_socket));
1383
1384   vam->retval = retval;
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_show_threads_reply_t_handler_json
1389   (vl_api_show_threads_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   vat_json_node_t node;
1393   vl_api_thread_data_t *td;
1394   i32 retval = ntohl (mp->retval);
1395   int i, count = 0;
1396
1397   if (retval >= 0)
1398     count = ntohl (mp->count);
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", retval);
1402   vat_json_object_add_uint (&node, "count", count);
1403
1404   for (i = 0; i < count; i++)
1405     {
1406       td = &mp->thread_data[i];
1407       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1408       vat_json_object_add_string_copy (&node, "name", td->name);
1409       vat_json_object_add_string_copy (&node, "type", td->type);
1410       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1411       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1412       vat_json_object_add_int (&node, "core", ntohl (td->id));
1413       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1414     }
1415
1416   vat_json_print (vam->ofp, &node);
1417   vat_json_free (&node);
1418
1419   vam->retval = retval;
1420   vam->result_ready = 1;
1421 }
1422
1423 static int
1424 api_show_threads (vat_main_t * vam)
1425 {
1426   vl_api_show_threads_t *mp;
1427   int ret;
1428
1429   print (vam->ofp,
1430          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1431          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1432
1433   M (SHOW_THREADS, mp);
1434
1435   S (mp);
1436   W (ret);
1437   return ret;
1438 }
1439
1440 static void
1441 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1442 {
1443   u32 sw_if_index = ntohl (mp->sw_if_index);
1444   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1445           mp->mac_ip ? "mac/ip binding" : "address resolution",
1446           ntohl (mp->pid), format_ip4_address, &mp->address,
1447           format_ethernet_address, mp->new_mac, sw_if_index);
1448 }
1449
1450 static void
1451 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1452 {
1453   /* JSON output not supported */
1454 }
1455
1456 static void
1457 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1458 {
1459   u32 sw_if_index = ntohl (mp->sw_if_index);
1460   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1461           mp->mac_ip ? "mac/ip binding" : "address resolution",
1462           ntohl (mp->pid), format_ip6_address, mp->address,
1463           format_ethernet_address, mp->new_mac, sw_if_index);
1464 }
1465
1466 static void
1467 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1468 {
1469   /* JSON output not supported */
1470 }
1471
1472 static void
1473 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1474 {
1475   u32 n_macs = ntohl (mp->n_macs);
1476   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1477           ntohl (mp->pid), mp->client_index, n_macs);
1478   int i;
1479   for (i = 0; i < n_macs; i++)
1480     {
1481       vl_api_mac_entry_t *mac = &mp->mac[i];
1482       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1483               i + 1, ntohl (mac->sw_if_index),
1484               format_ethernet_address, mac->mac_addr, mac->action);
1485       if (i == 1000)
1486         break;
1487     }
1488 }
1489
1490 static void
1491 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1492 {
1493   /* JSON output not supported */
1494 }
1495
1496 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1497 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1498
1499 /*
1500  * Special-case: build the bridge domain table, maintain
1501  * the next bd id vbl.
1502  */
1503 static void vl_api_bridge_domain_details_t_handler
1504   (vl_api_bridge_domain_details_t * mp)
1505 {
1506   vat_main_t *vam = &vat_main;
1507   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1508   int i;
1509
1510   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1511          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1512
1513   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1514          ntohl (mp->bd_id), mp->learn, mp->forward,
1515          mp->flood, ntohl (mp->bvi_sw_if_index),
1516          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1517
1518   if (n_sw_ifs)
1519     {
1520       vl_api_bridge_domain_sw_if_t *sw_ifs;
1521       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1522              "Interface Name");
1523
1524       sw_ifs = mp->sw_if_details;
1525       for (i = 0; i < n_sw_ifs; i++)
1526         {
1527           u8 *sw_if_name = 0;
1528           u32 sw_if_index;
1529           hash_pair_t *p;
1530
1531           sw_if_index = ntohl (sw_ifs->sw_if_index);
1532
1533           /* *INDENT-OFF* */
1534           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1535                              ({
1536                                if ((u32) p->value[0] == sw_if_index)
1537                                  {
1538                                    sw_if_name = (u8 *)(p->key);
1539                                    break;
1540                                  }
1541                              }));
1542           /* *INDENT-ON* */
1543           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1544                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1545                  "sw_if_index not found!");
1546
1547           sw_ifs++;
1548         }
1549     }
1550 }
1551
1552 static void vl_api_bridge_domain_details_t_handler_json
1553   (vl_api_bridge_domain_details_t * mp)
1554 {
1555   vat_main_t *vam = &vat_main;
1556   vat_json_node_t *node, *array = NULL;
1557   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1558
1559   if (VAT_JSON_ARRAY != vam->json_tree.type)
1560     {
1561       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1562       vat_json_init_array (&vam->json_tree);
1563     }
1564   node = vat_json_array_add (&vam->json_tree);
1565
1566   vat_json_init_object (node);
1567   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1568   vat_json_object_add_uint (node, "flood", mp->flood);
1569   vat_json_object_add_uint (node, "forward", mp->forward);
1570   vat_json_object_add_uint (node, "learn", mp->learn);
1571   vat_json_object_add_uint (node, "bvi_sw_if_index",
1572                             ntohl (mp->bvi_sw_if_index));
1573   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1574   array = vat_json_object_add (node, "sw_if");
1575   vat_json_init_array (array);
1576
1577
1578
1579   if (n_sw_ifs)
1580     {
1581       vl_api_bridge_domain_sw_if_t *sw_ifs;
1582       int i;
1583
1584       sw_ifs = mp->sw_if_details;
1585       for (i = 0; i < n_sw_ifs; i++)
1586         {
1587           node = vat_json_array_add (array);
1588           vat_json_init_object (node);
1589           vat_json_object_add_uint (node, "sw_if_index",
1590                                     ntohl (sw_ifs->sw_if_index));
1591           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1592           sw_ifs++;
1593         }
1594     }
1595 }
1596
1597 static void vl_api_control_ping_reply_t_handler
1598   (vl_api_control_ping_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611   if (vam->socket_client_main)
1612     vam->socket_client_main->control_pings_outstanding--;
1613 }
1614
1615 static void vl_api_control_ping_reply_t_handler_json
1616   (vl_api_control_ping_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   i32 retval = ntohl (mp->retval);
1620
1621   if (VAT_JSON_NONE != vam->json_tree.type)
1622     {
1623       vat_json_print (vam->ofp, &vam->json_tree);
1624       vat_json_free (&vam->json_tree);
1625       vam->json_tree.type = VAT_JSON_NONE;
1626     }
1627   else
1628     {
1629       /* just print [] */
1630       vat_json_init_array (&vam->json_tree);
1631       vat_json_print (vam->ofp, &vam->json_tree);
1632       vam->json_tree.type = VAT_JSON_NONE;
1633     }
1634
1635   vam->retval = retval;
1636   vam->result_ready = 1;
1637 }
1638
1639 static void
1640   vl_api_bridge_domain_set_mac_age_reply_t_handler
1641   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1642 {
1643   vat_main_t *vam = &vat_main;
1644   i32 retval = ntohl (mp->retval);
1645   if (vam->async_mode)
1646     {
1647       vam->async_errors += (retval < 0);
1648     }
1649   else
1650     {
1651       vam->retval = retval;
1652       vam->result_ready = 1;
1653     }
1654 }
1655
1656 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1657   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1658 {
1659   vat_main_t *vam = &vat_main;
1660   vat_json_node_t node;
1661
1662   vat_json_init_object (&node);
1663   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1664
1665   vat_json_print (vam->ofp, &node);
1666   vat_json_free (&node);
1667
1668   vam->retval = ntohl (mp->retval);
1669   vam->result_ready = 1;
1670 }
1671
1672 static void
1673 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1674 {
1675   vat_main_t *vam = &vat_main;
1676   i32 retval = ntohl (mp->retval);
1677   if (vam->async_mode)
1678     {
1679       vam->async_errors += (retval < 0);
1680     }
1681   else
1682     {
1683       vam->retval = retval;
1684       vam->result_ready = 1;
1685     }
1686 }
1687
1688 static void vl_api_l2_flags_reply_t_handler_json
1689   (vl_api_l2_flags_reply_t * mp)
1690 {
1691   vat_main_t *vam = &vat_main;
1692   vat_json_node_t node;
1693
1694   vat_json_init_object (&node);
1695   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1696   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1697                             ntohl (mp->resulting_feature_bitmap));
1698
1699   vat_json_print (vam->ofp, &node);
1700   vat_json_free (&node);
1701
1702   vam->retval = ntohl (mp->retval);
1703   vam->result_ready = 1;
1704 }
1705
1706 static void vl_api_bridge_flags_reply_t_handler
1707   (vl_api_bridge_flags_reply_t * mp)
1708 {
1709   vat_main_t *vam = &vat_main;
1710   i32 retval = ntohl (mp->retval);
1711   if (vam->async_mode)
1712     {
1713       vam->async_errors += (retval < 0);
1714     }
1715   else
1716     {
1717       vam->retval = retval;
1718       vam->result_ready = 1;
1719     }
1720 }
1721
1722 static void vl_api_bridge_flags_reply_t_handler_json
1723   (vl_api_bridge_flags_reply_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   vat_json_node_t node;
1727
1728   vat_json_init_object (&node);
1729   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1730   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1731                             ntohl (mp->resulting_feature_bitmap));
1732
1733   vat_json_print (vam->ofp, &node);
1734   vat_json_free (&node);
1735
1736   vam->retval = ntohl (mp->retval);
1737   vam->result_ready = 1;
1738 }
1739
1740 static void vl_api_tap_connect_reply_t_handler
1741   (vl_api_tap_connect_reply_t * mp)
1742 {
1743   vat_main_t *vam = &vat_main;
1744   i32 retval = ntohl (mp->retval);
1745   if (vam->async_mode)
1746     {
1747       vam->async_errors += (retval < 0);
1748     }
1749   else
1750     {
1751       vam->retval = retval;
1752       vam->sw_if_index = ntohl (mp->sw_if_index);
1753       vam->result_ready = 1;
1754     }
1755
1756 }
1757
1758 static void vl_api_tap_connect_reply_t_handler_json
1759   (vl_api_tap_connect_reply_t * mp)
1760 {
1761   vat_main_t *vam = &vat_main;
1762   vat_json_node_t node;
1763
1764   vat_json_init_object (&node);
1765   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1766   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1767
1768   vat_json_print (vam->ofp, &node);
1769   vat_json_free (&node);
1770
1771   vam->retval = ntohl (mp->retval);
1772   vam->result_ready = 1;
1773
1774 }
1775
1776 static void
1777 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1778 {
1779   vat_main_t *vam = &vat_main;
1780   i32 retval = ntohl (mp->retval);
1781   if (vam->async_mode)
1782     {
1783       vam->async_errors += (retval < 0);
1784     }
1785   else
1786     {
1787       vam->retval = retval;
1788       vam->sw_if_index = ntohl (mp->sw_if_index);
1789       vam->result_ready = 1;
1790     }
1791 }
1792
1793 static void vl_api_tap_modify_reply_t_handler_json
1794   (vl_api_tap_modify_reply_t * mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   vat_json_node_t node;
1798
1799   vat_json_init_object (&node);
1800   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1801   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1802
1803   vat_json_print (vam->ofp, &node);
1804   vat_json_free (&node);
1805
1806   vam->retval = ntohl (mp->retval);
1807   vam->result_ready = 1;
1808 }
1809
1810 static void
1811 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1812 {
1813   vat_main_t *vam = &vat_main;
1814   i32 retval = ntohl (mp->retval);
1815   if (vam->async_mode)
1816     {
1817       vam->async_errors += (retval < 0);
1818     }
1819   else
1820     {
1821       vam->retval = retval;
1822       vam->result_ready = 1;
1823     }
1824 }
1825
1826 static void vl_api_tap_delete_reply_t_handler_json
1827   (vl_api_tap_delete_reply_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   vat_json_node_t node;
1831
1832   vat_json_init_object (&node);
1833   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1834
1835   vat_json_print (vam->ofp, &node);
1836   vat_json_free (&node);
1837
1838   vam->retval = ntohl (mp->retval);
1839   vam->result_ready = 1;
1840 }
1841
1842 static void
1843 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1844 {
1845   vat_main_t *vam = &vat_main;
1846   i32 retval = ntohl (mp->retval);
1847   if (vam->async_mode)
1848     {
1849       vam->async_errors += (retval < 0);
1850     }
1851   else
1852     {
1853       vam->retval = retval;
1854       vam->sw_if_index = ntohl (mp->sw_if_index);
1855       vam->result_ready = 1;
1856     }
1857
1858 }
1859
1860 static void vl_api_tap_create_v2_reply_t_handler_json
1861   (vl_api_tap_create_v2_reply_t * mp)
1862 {
1863   vat_main_t *vam = &vat_main;
1864   vat_json_node_t node;
1865
1866   vat_json_init_object (&node);
1867   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1868   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1869
1870   vat_json_print (vam->ofp, &node);
1871   vat_json_free (&node);
1872
1873   vam->retval = ntohl (mp->retval);
1874   vam->result_ready = 1;
1875
1876 }
1877
1878 static void
1879 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1880 {
1881   vat_main_t *vam = &vat_main;
1882   i32 retval = ntohl (mp->retval);
1883   if (vam->async_mode)
1884     {
1885       vam->async_errors += (retval < 0);
1886     }
1887   else
1888     {
1889       vam->retval = retval;
1890       vam->result_ready = 1;
1891     }
1892 }
1893
1894 static void vl_api_tap_delete_v2_reply_t_handler_json
1895   (vl_api_tap_delete_v2_reply_t * mp)
1896 {
1897   vat_main_t *vam = &vat_main;
1898   vat_json_node_t node;
1899
1900   vat_json_init_object (&node);
1901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1902
1903   vat_json_print (vam->ofp, &node);
1904   vat_json_free (&node);
1905
1906   vam->retval = ntohl (mp->retval);
1907   vam->result_ready = 1;
1908 }
1909
1910 static void
1911 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   i32 retval = ntohl (mp->retval);
1915
1916   if (vam->async_mode)
1917     {
1918       vam->async_errors += (retval < 0);
1919     }
1920   else
1921     {
1922       vam->retval = retval;
1923       vam->sw_if_index = ntohl (mp->sw_if_index);
1924       vam->result_ready = 1;
1925     }
1926 }
1927
1928 static void vl_api_bond_create_reply_t_handler_json
1929   (vl_api_bond_create_reply_t * mp)
1930 {
1931   vat_main_t *vam = &vat_main;
1932   vat_json_node_t node;
1933
1934   vat_json_init_object (&node);
1935   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1936   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1937
1938   vat_json_print (vam->ofp, &node);
1939   vat_json_free (&node);
1940
1941   vam->retval = ntohl (mp->retval);
1942   vam->result_ready = 1;
1943 }
1944
1945 static void
1946 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   i32 retval = ntohl (mp->retval);
1950
1951   if (vam->async_mode)
1952     {
1953       vam->async_errors += (retval < 0);
1954     }
1955   else
1956     {
1957       vam->retval = retval;
1958       vam->result_ready = 1;
1959     }
1960 }
1961
1962 static void vl_api_bond_delete_reply_t_handler_json
1963   (vl_api_bond_delete_reply_t * mp)
1964 {
1965   vat_main_t *vam = &vat_main;
1966   vat_json_node_t node;
1967
1968   vat_json_init_object (&node);
1969   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1970
1971   vat_json_print (vam->ofp, &node);
1972   vat_json_free (&node);
1973
1974   vam->retval = ntohl (mp->retval);
1975   vam->result_ready = 1;
1976 }
1977
1978 static void
1979 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1980 {
1981   vat_main_t *vam = &vat_main;
1982   i32 retval = ntohl (mp->retval);
1983
1984   if (vam->async_mode)
1985     {
1986       vam->async_errors += (retval < 0);
1987     }
1988   else
1989     {
1990       vam->retval = retval;
1991       vam->result_ready = 1;
1992     }
1993 }
1994
1995 static void vl_api_bond_enslave_reply_t_handler_json
1996   (vl_api_bond_enslave_reply_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t node;
2000
2001   vat_json_init_object (&node);
2002   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2003
2004   vat_json_print (vam->ofp, &node);
2005   vat_json_free (&node);
2006
2007   vam->retval = ntohl (mp->retval);
2008   vam->result_ready = 1;
2009 }
2010
2011 static void
2012 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2013                                           mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   i32 retval = ntohl (mp->retval);
2017
2018   if (vam->async_mode)
2019     {
2020       vam->async_errors += (retval < 0);
2021     }
2022   else
2023     {
2024       vam->retval = retval;
2025       vam->result_ready = 1;
2026     }
2027 }
2028
2029 static void vl_api_bond_detach_slave_reply_t_handler_json
2030   (vl_api_bond_detach_slave_reply_t * mp)
2031 {
2032   vat_main_t *vam = &vat_main;
2033   vat_json_node_t node;
2034
2035   vat_json_init_object (&node);
2036   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2037
2038   vat_json_print (vam->ofp, &node);
2039   vat_json_free (&node);
2040
2041   vam->retval = ntohl (mp->retval);
2042   vam->result_ready = 1;
2043 }
2044
2045 static void vl_api_sw_interface_bond_details_t_handler
2046   (vl_api_sw_interface_bond_details_t * mp)
2047 {
2048   vat_main_t *vam = &vat_main;
2049
2050   print (vam->ofp,
2051          "%-16s %-12d %-12U %-13U %-14u %-14u",
2052          mp->interface_name, ntohl (mp->sw_if_index),
2053          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2054          ntohl (mp->active_slaves), ntohl (mp->slaves));
2055 }
2056
2057 static void vl_api_sw_interface_bond_details_t_handler_json
2058   (vl_api_sw_interface_bond_details_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vat_json_node_t *node = NULL;
2062
2063   if (VAT_JSON_ARRAY != vam->json_tree.type)
2064     {
2065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2066       vat_json_init_array (&vam->json_tree);
2067     }
2068   node = vat_json_array_add (&vam->json_tree);
2069
2070   vat_json_init_object (node);
2071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2072   vat_json_object_add_string_copy (node, "interface_name",
2073                                    mp->interface_name);
2074   vat_json_object_add_uint (node, "mode", mp->mode);
2075   vat_json_object_add_uint (node, "load_balance", mp->lb);
2076   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2077   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2078 }
2079
2080 static int
2081 api_sw_interface_bond_dump (vat_main_t * vam)
2082 {
2083   vl_api_sw_interface_bond_dump_t *mp;
2084   vl_api_control_ping_t *mp_ping;
2085   int ret;
2086
2087   print (vam->ofp,
2088          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2089          "interface name", "sw_if_index", "mode", "load balance",
2090          "active slaves", "slaves");
2091
2092   /* Get list of bond interfaces */
2093   M (SW_INTERFACE_BOND_DUMP, mp);
2094   S (mp);
2095
2096   /* Use a control ping for synchronization */
2097   MPING (CONTROL_PING, mp_ping);
2098   S (mp_ping);
2099
2100   W (ret);
2101   return ret;
2102 }
2103
2104 static void vl_api_sw_interface_slave_details_t_handler
2105   (vl_api_sw_interface_slave_details_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108
2109   print (vam->ofp,
2110          "%-25s %-12d %-12d %d", mp->interface_name,
2111          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2112 }
2113
2114 static void vl_api_sw_interface_slave_details_t_handler_json
2115   (vl_api_sw_interface_slave_details_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   vat_json_node_t *node = NULL;
2119
2120   if (VAT_JSON_ARRAY != vam->json_tree.type)
2121     {
2122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2123       vat_json_init_array (&vam->json_tree);
2124     }
2125   node = vat_json_array_add (&vam->json_tree);
2126
2127   vat_json_init_object (node);
2128   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2129   vat_json_object_add_string_copy (node, "interface_name",
2130                                    mp->interface_name);
2131   vat_json_object_add_uint (node, "passive", mp->is_passive);
2132   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2133 }
2134
2135 static int
2136 api_sw_interface_slave_dump (vat_main_t * vam)
2137 {
2138   unformat_input_t *i = vam->input;
2139   vl_api_sw_interface_slave_dump_t *mp;
2140   vl_api_control_ping_t *mp_ping;
2141   u32 sw_if_index = ~0;
2142   u8 sw_if_index_set = 0;
2143   int ret;
2144
2145   /* Parse args required to build the message */
2146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2147     {
2148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2149         sw_if_index_set = 1;
2150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2151         sw_if_index_set = 1;
2152       else
2153         break;
2154     }
2155
2156   if (sw_if_index_set == 0)
2157     {
2158       errmsg ("missing vpp interface name. ");
2159       return -99;
2160     }
2161
2162   print (vam->ofp,
2163          "\n%-25s %-12s %-12s %s",
2164          "slave interface name", "sw_if_index", "passive", "long_timeout");
2165
2166   /* Get list of bond interfaces */
2167   M (SW_INTERFACE_SLAVE_DUMP, mp);
2168   mp->sw_if_index = ntohl (sw_if_index);
2169   S (mp);
2170
2171   /* Use a control ping for synchronization */
2172   MPING (CONTROL_PING, mp_ping);
2173   S (mp_ping);
2174
2175   W (ret);
2176   return ret;
2177 }
2178
2179 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2180   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       vam->retval = retval;
2191       vam->sw_if_index = ntohl (mp->sw_if_index);
2192       vam->result_ready = 1;
2193     }
2194   vam->regenerate_interface_table = 1;
2195 }
2196
2197 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2198   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   vat_json_node_t node;
2202
2203   vat_json_init_object (&node);
2204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2205   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2206                             ntohl (mp->sw_if_index));
2207
2208   vat_json_print (vam->ofp, &node);
2209   vat_json_free (&node);
2210
2211   vam->retval = ntohl (mp->retval);
2212   vam->result_ready = 1;
2213 }
2214
2215 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2216   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   i32 retval = ntohl (mp->retval);
2220   if (vam->async_mode)
2221     {
2222       vam->async_errors += (retval < 0);
2223     }
2224   else
2225     {
2226       vam->retval = retval;
2227       vam->sw_if_index = ntohl (mp->sw_if_index);
2228       vam->result_ready = 1;
2229     }
2230 }
2231
2232 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2233   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   vat_json_node_t node;
2237
2238   vat_json_init_object (&node);
2239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2240   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2241
2242   vat_json_print (vam->ofp, &node);
2243   vat_json_free (&node);
2244
2245   vam->retval = ntohl (mp->retval);
2246   vam->result_ready = 1;
2247 }
2248
2249 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2250   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2251 {
2252   vat_main_t *vam = &vat_main;
2253   i32 retval = ntohl (mp->retval);
2254   if (vam->async_mode)
2255     {
2256       vam->async_errors += (retval < 0);
2257     }
2258   else
2259     {
2260       vam->retval = retval;
2261       vam->result_ready = 1;
2262     }
2263 }
2264
2265 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2266   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2267 {
2268   vat_main_t *vam = &vat_main;
2269   vat_json_node_t node;
2270
2271   vat_json_init_object (&node);
2272   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2273   vat_json_object_add_uint (&node, "fwd_entry_index",
2274                             clib_net_to_host_u32 (mp->fwd_entry_index));
2275
2276   vat_json_print (vam->ofp, &node);
2277   vat_json_free (&node);
2278
2279   vam->retval = ntohl (mp->retval);
2280   vam->result_ready = 1;
2281 }
2282
2283 u8 *
2284 format_lisp_transport_protocol (u8 * s, va_list * args)
2285 {
2286   u32 proto = va_arg (*args, u32);
2287
2288   switch (proto)
2289     {
2290     case 1:
2291       return format (s, "udp");
2292     case 2:
2293       return format (s, "api");
2294     default:
2295       return 0;
2296     }
2297   return 0;
2298 }
2299
2300 static void vl_api_one_get_transport_protocol_reply_t_handler
2301   (vl_api_one_get_transport_protocol_reply_t * mp)
2302 {
2303   vat_main_t *vam = &vat_main;
2304   i32 retval = ntohl (mp->retval);
2305   if (vam->async_mode)
2306     {
2307       vam->async_errors += (retval < 0);
2308     }
2309   else
2310     {
2311       u32 proto = mp->protocol;
2312       print (vam->ofp, "Transport protocol: %U",
2313              format_lisp_transport_protocol, proto);
2314       vam->retval = retval;
2315       vam->result_ready = 1;
2316     }
2317 }
2318
2319 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2320   (vl_api_one_get_transport_protocol_reply_t * mp)
2321 {
2322   vat_main_t *vam = &vat_main;
2323   vat_json_node_t node;
2324   u8 *s;
2325
2326   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2327   vec_add1 (s, 0);
2328
2329   vat_json_init_object (&node);
2330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2331   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2332
2333   vec_free (s);
2334   vat_json_print (vam->ofp, &node);
2335   vat_json_free (&node);
2336
2337   vam->retval = ntohl (mp->retval);
2338   vam->result_ready = 1;
2339 }
2340
2341 static void vl_api_one_add_del_locator_set_reply_t_handler
2342   (vl_api_one_add_del_locator_set_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   i32 retval = ntohl (mp->retval);
2346   if (vam->async_mode)
2347     {
2348       vam->async_errors += (retval < 0);
2349     }
2350   else
2351     {
2352       vam->retval = retval;
2353       vam->result_ready = 1;
2354     }
2355 }
2356
2357 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2358   (vl_api_one_add_del_locator_set_reply_t * mp)
2359 {
2360   vat_main_t *vam = &vat_main;
2361   vat_json_node_t node;
2362
2363   vat_json_init_object (&node);
2364   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2365   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2366
2367   vat_json_print (vam->ofp, &node);
2368   vat_json_free (&node);
2369
2370   vam->retval = ntohl (mp->retval);
2371   vam->result_ready = 1;
2372 }
2373
2374 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2375   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2376 {
2377   vat_main_t *vam = &vat_main;
2378   i32 retval = ntohl (mp->retval);
2379   if (vam->async_mode)
2380     {
2381       vam->async_errors += (retval < 0);
2382     }
2383   else
2384     {
2385       vam->retval = retval;
2386       vam->sw_if_index = ntohl (mp->sw_if_index);
2387       vam->result_ready = 1;
2388     }
2389   vam->regenerate_interface_table = 1;
2390 }
2391
2392 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2393   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2394 {
2395   vat_main_t *vam = &vat_main;
2396   vat_json_node_t node;
2397
2398   vat_json_init_object (&node);
2399   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2400   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2401
2402   vat_json_print (vam->ofp, &node);
2403   vat_json_free (&node);
2404
2405   vam->retval = ntohl (mp->retval);
2406   vam->result_ready = 1;
2407 }
2408
2409 static void vl_api_vxlan_offload_rx_reply_t_handler
2410   (vl_api_vxlan_offload_rx_reply_t * mp)
2411 {
2412   vat_main_t *vam = &vat_main;
2413   i32 retval = ntohl (mp->retval);
2414   if (vam->async_mode)
2415     {
2416       vam->async_errors += (retval < 0);
2417     }
2418   else
2419     {
2420       vam->retval = retval;
2421       vam->result_ready = 1;
2422     }
2423 }
2424
2425 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2426   (vl_api_vxlan_offload_rx_reply_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   vat_json_node_t node;
2430
2431   vat_json_init_object (&node);
2432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2433
2434   vat_json_print (vam->ofp, &node);
2435   vat_json_free (&node);
2436
2437   vam->retval = ntohl (mp->retval);
2438   vam->result_ready = 1;
2439 }
2440
2441 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2442   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   i32 retval = ntohl (mp->retval);
2446   if (vam->async_mode)
2447     {
2448       vam->async_errors += (retval < 0);
2449     }
2450   else
2451     {
2452       vam->retval = retval;
2453       vam->sw_if_index = ntohl (mp->sw_if_index);
2454       vam->result_ready = 1;
2455     }
2456 }
2457
2458 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2459   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   vat_json_node_t node;
2463
2464   vat_json_init_object (&node);
2465   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2466   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2467
2468   vat_json_print (vam->ofp, &node);
2469   vat_json_free (&node);
2470
2471   vam->retval = ntohl (mp->retval);
2472   vam->result_ready = 1;
2473 }
2474
2475 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2476   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479   i32 retval = ntohl (mp->retval);
2480   if (vam->async_mode)
2481     {
2482       vam->async_errors += (retval < 0);
2483     }
2484   else
2485     {
2486       vam->retval = retval;
2487       vam->sw_if_index = ntohl (mp->sw_if_index);
2488       vam->result_ready = 1;
2489     }
2490   vam->regenerate_interface_table = 1;
2491 }
2492
2493 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2494   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   vat_json_node_t node;
2498
2499   vat_json_init_object (&node);
2500   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2501   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2502
2503   vat_json_print (vam->ofp, &node);
2504   vat_json_free (&node);
2505
2506   vam->retval = ntohl (mp->retval);
2507   vam->result_ready = 1;
2508 }
2509
2510 static void vl_api_gre_add_del_tunnel_reply_t_handler
2511   (vl_api_gre_add_del_tunnel_reply_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   i32 retval = ntohl (mp->retval);
2515   if (vam->async_mode)
2516     {
2517       vam->async_errors += (retval < 0);
2518     }
2519   else
2520     {
2521       vam->retval = retval;
2522       vam->sw_if_index = ntohl (mp->sw_if_index);
2523       vam->result_ready = 1;
2524     }
2525 }
2526
2527 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2528   (vl_api_gre_add_del_tunnel_reply_t * mp)
2529 {
2530   vat_main_t *vam = &vat_main;
2531   vat_json_node_t node;
2532
2533   vat_json_init_object (&node);
2534   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2535   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2536
2537   vat_json_print (vam->ofp, &node);
2538   vat_json_free (&node);
2539
2540   vam->retval = ntohl (mp->retval);
2541   vam->result_ready = 1;
2542 }
2543
2544 static void vl_api_create_vhost_user_if_reply_t_handler
2545   (vl_api_create_vhost_user_if_reply_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   i32 retval = ntohl (mp->retval);
2549   if (vam->async_mode)
2550     {
2551       vam->async_errors += (retval < 0);
2552     }
2553   else
2554     {
2555       vam->retval = retval;
2556       vam->sw_if_index = ntohl (mp->sw_if_index);
2557       vam->result_ready = 1;
2558     }
2559   vam->regenerate_interface_table = 1;
2560 }
2561
2562 static void vl_api_create_vhost_user_if_reply_t_handler_json
2563   (vl_api_create_vhost_user_if_reply_t * mp)
2564 {
2565   vat_main_t *vam = &vat_main;
2566   vat_json_node_t node;
2567
2568   vat_json_init_object (&node);
2569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2571
2572   vat_json_print (vam->ofp, &node);
2573   vat_json_free (&node);
2574
2575   vam->retval = ntohl (mp->retval);
2576   vam->result_ready = 1;
2577 }
2578
2579 static void vl_api_dns_resolve_name_reply_t_handler
2580   (vl_api_dns_resolve_name_reply_t * mp)
2581 {
2582   vat_main_t *vam = &vat_main;
2583   i32 retval = ntohl (mp->retval);
2584   if (vam->async_mode)
2585     {
2586       vam->async_errors += (retval < 0);
2587     }
2588   else
2589     {
2590       vam->retval = retval;
2591       vam->result_ready = 1;
2592
2593       if (retval == 0)
2594         {
2595           if (mp->ip4_set)
2596             clib_warning ("ip4 address %U", format_ip4_address,
2597                           (ip4_address_t *) mp->ip4_address);
2598           if (mp->ip6_set)
2599             clib_warning ("ip6 address %U", format_ip6_address,
2600                           (ip6_address_t *) mp->ip6_address);
2601         }
2602       else
2603         clib_warning ("retval %d", retval);
2604     }
2605 }
2606
2607 static void vl_api_dns_resolve_name_reply_t_handler_json
2608   (vl_api_dns_resolve_name_reply_t * mp)
2609 {
2610   clib_warning ("not implemented");
2611 }
2612
2613 static void vl_api_dns_resolve_ip_reply_t_handler
2614   (vl_api_dns_resolve_ip_reply_t * mp)
2615 {
2616   vat_main_t *vam = &vat_main;
2617   i32 retval = ntohl (mp->retval);
2618   if (vam->async_mode)
2619     {
2620       vam->async_errors += (retval < 0);
2621     }
2622   else
2623     {
2624       vam->retval = retval;
2625       vam->result_ready = 1;
2626
2627       if (retval == 0)
2628         {
2629           clib_warning ("canonical name %s", mp->name);
2630         }
2631       else
2632         clib_warning ("retval %d", retval);
2633     }
2634 }
2635
2636 static void vl_api_dns_resolve_ip_reply_t_handler_json
2637   (vl_api_dns_resolve_ip_reply_t * mp)
2638 {
2639   clib_warning ("not implemented");
2640 }
2641
2642
2643 static void vl_api_ip_address_details_t_handler
2644   (vl_api_ip_address_details_t * mp)
2645 {
2646   vat_main_t *vam = &vat_main;
2647   static ip_address_details_t empty_ip_address_details = { {0} };
2648   ip_address_details_t *address = NULL;
2649   ip_details_t *current_ip_details = NULL;
2650   ip_details_t *details = NULL;
2651
2652   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2653
2654   if (!details || vam->current_sw_if_index >= vec_len (details)
2655       || !details[vam->current_sw_if_index].present)
2656     {
2657       errmsg ("ip address details arrived but not stored");
2658       errmsg ("ip_dump should be called first");
2659       return;
2660     }
2661
2662   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2663
2664 #define addresses (current_ip_details->addr)
2665
2666   vec_validate_init_empty (addresses, vec_len (addresses),
2667                            empty_ip_address_details);
2668
2669   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2670
2671   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2672   address->prefix_length = mp->prefix_length;
2673 #undef addresses
2674 }
2675
2676 static void vl_api_ip_address_details_t_handler_json
2677   (vl_api_ip_address_details_t * mp)
2678 {
2679   vat_main_t *vam = &vat_main;
2680   vat_json_node_t *node = NULL;
2681   struct in6_addr ip6;
2682   struct in_addr ip4;
2683
2684   if (VAT_JSON_ARRAY != vam->json_tree.type)
2685     {
2686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2687       vat_json_init_array (&vam->json_tree);
2688     }
2689   node = vat_json_array_add (&vam->json_tree);
2690
2691   vat_json_init_object (node);
2692   if (vam->is_ipv6)
2693     {
2694       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2695       vat_json_object_add_ip6 (node, "ip", ip6);
2696     }
2697   else
2698     {
2699       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2700       vat_json_object_add_ip4 (node, "ip", ip4);
2701     }
2702   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2703 }
2704
2705 static void
2706 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2707 {
2708   vat_main_t *vam = &vat_main;
2709   static ip_details_t empty_ip_details = { 0 };
2710   ip_details_t *ip = NULL;
2711   u32 sw_if_index = ~0;
2712
2713   sw_if_index = ntohl (mp->sw_if_index);
2714
2715   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2716                            sw_if_index, empty_ip_details);
2717
2718   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2719                          sw_if_index);
2720
2721   ip->present = 1;
2722 }
2723
2724 static void
2725 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728
2729   if (VAT_JSON_ARRAY != vam->json_tree.type)
2730     {
2731       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2732       vat_json_init_array (&vam->json_tree);
2733     }
2734   vat_json_array_add_uint (&vam->json_tree,
2735                            clib_net_to_host_u32 (mp->sw_if_index));
2736 }
2737
2738 static void
2739 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2740 {
2741   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2742           "router_addr %U host_mac %U",
2743           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2744           mp->lease.hostname,
2745           format_ip4_address, &mp->lease.host_address,
2746           format_ip4_address, &mp->lease.router_address,
2747           format_ethernet_address, mp->lease.host_mac);
2748 }
2749
2750 static void vl_api_dhcp_compl_event_t_handler_json
2751   (vl_api_dhcp_compl_event_t * mp)
2752 {
2753   /* JSON output not supported */
2754 }
2755
2756 static void
2757 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2758                               u32 counter)
2759 {
2760   vat_main_t *vam = &vat_main;
2761   static u64 default_counter = 0;
2762
2763   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2764                            NULL);
2765   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2766                            sw_if_index, default_counter);
2767   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2768 }
2769
2770 static void
2771 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2772                                 interface_counter_t counter)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   static interface_counter_t default_counter = { 0, };
2776
2777   vec_validate_init_empty (vam->combined_interface_counters,
2778                            vnet_counter_type, NULL);
2779   vec_validate_init_empty (vam->combined_interface_counters
2780                            [vnet_counter_type], sw_if_index, default_counter);
2781   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2782 }
2783
2784 static void vl_api_vnet_interface_simple_counters_t_handler
2785   (vl_api_vnet_interface_simple_counters_t * mp)
2786 {
2787   /* not supported */
2788 }
2789
2790 static void vl_api_vnet_interface_combined_counters_t_handler
2791   (vl_api_vnet_interface_combined_counters_t * mp)
2792 {
2793   /* not supported */
2794 }
2795
2796 static void vl_api_vnet_interface_simple_counters_t_handler_json
2797   (vl_api_vnet_interface_simple_counters_t * mp)
2798 {
2799   u64 *v_packets;
2800   u64 packets;
2801   u32 count;
2802   u32 first_sw_if_index;
2803   int i;
2804
2805   count = ntohl (mp->count);
2806   first_sw_if_index = ntohl (mp->first_sw_if_index);
2807
2808   v_packets = (u64 *) & mp->data;
2809   for (i = 0; i < count; i++)
2810     {
2811       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2812       set_simple_interface_counter (mp->vnet_counter_type,
2813                                     first_sw_if_index + i, packets);
2814       v_packets++;
2815     }
2816 }
2817
2818 static void vl_api_vnet_interface_combined_counters_t_handler_json
2819   (vl_api_vnet_interface_combined_counters_t * mp)
2820 {
2821   interface_counter_t counter;
2822   vlib_counter_t *v;
2823   u32 first_sw_if_index;
2824   int i;
2825   u32 count;
2826
2827   count = ntohl (mp->count);
2828   first_sw_if_index = ntohl (mp->first_sw_if_index);
2829
2830   v = (vlib_counter_t *) & mp->data;
2831   for (i = 0; i < count; i++)
2832     {
2833       counter.packets =
2834         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2835       counter.bytes =
2836         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2837       set_combined_interface_counter (mp->vnet_counter_type,
2838                                       first_sw_if_index + i, counter);
2839       v++;
2840     }
2841 }
2842
2843 static u32
2844 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2845 {
2846   vat_main_t *vam = &vat_main;
2847   u32 i;
2848
2849   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2850     {
2851       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2852         {
2853           return i;
2854         }
2855     }
2856   return ~0;
2857 }
2858
2859 static u32
2860 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   u32 i;
2864
2865   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2866     {
2867       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2868         {
2869           return i;
2870         }
2871     }
2872   return ~0;
2873 }
2874
2875 static void vl_api_vnet_ip4_fib_counters_t_handler
2876   (vl_api_vnet_ip4_fib_counters_t * mp)
2877 {
2878   /* not supported */
2879 }
2880
2881 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2882   (vl_api_vnet_ip4_fib_counters_t * mp)
2883 {
2884   vat_main_t *vam = &vat_main;
2885   vl_api_ip4_fib_counter_t *v;
2886   ip4_fib_counter_t *counter;
2887   struct in_addr ip4;
2888   u32 vrf_id;
2889   u32 vrf_index;
2890   u32 count;
2891   int i;
2892
2893   vrf_id = ntohl (mp->vrf_id);
2894   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2895   if (~0 == vrf_index)
2896     {
2897       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2898       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2899       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2900       vec_validate (vam->ip4_fib_counters, vrf_index);
2901       vam->ip4_fib_counters[vrf_index] = NULL;
2902     }
2903
2904   vec_free (vam->ip4_fib_counters[vrf_index]);
2905   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2906   count = ntohl (mp->count);
2907   for (i = 0; i < count; i++)
2908     {
2909       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2910       counter = &vam->ip4_fib_counters[vrf_index][i];
2911       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2912       counter->address = ip4;
2913       counter->address_length = v->address_length;
2914       counter->packets = clib_net_to_host_u64 (v->packets);
2915       counter->bytes = clib_net_to_host_u64 (v->bytes);
2916       v++;
2917     }
2918 }
2919
2920 static void vl_api_vnet_ip4_nbr_counters_t_handler
2921   (vl_api_vnet_ip4_nbr_counters_t * mp)
2922 {
2923   /* not supported */
2924 }
2925
2926 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2927   (vl_api_vnet_ip4_nbr_counters_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   vl_api_ip4_nbr_counter_t *v;
2931   ip4_nbr_counter_t *counter;
2932   u32 sw_if_index;
2933   u32 count;
2934   int i;
2935
2936   sw_if_index = ntohl (mp->sw_if_index);
2937   count = ntohl (mp->count);
2938   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2939
2940   if (mp->begin)
2941     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2942
2943   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2944   for (i = 0; i < count; i++)
2945     {
2946       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2947       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2948       counter->address.s_addr = v->address;
2949       counter->packets = clib_net_to_host_u64 (v->packets);
2950       counter->bytes = clib_net_to_host_u64 (v->bytes);
2951       counter->linkt = v->link_type;
2952       v++;
2953     }
2954 }
2955
2956 static void vl_api_vnet_ip6_fib_counters_t_handler
2957   (vl_api_vnet_ip6_fib_counters_t * mp)
2958 {
2959   /* not supported */
2960 }
2961
2962 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2963   (vl_api_vnet_ip6_fib_counters_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   vl_api_ip6_fib_counter_t *v;
2967   ip6_fib_counter_t *counter;
2968   struct in6_addr ip6;
2969   u32 vrf_id;
2970   u32 vrf_index;
2971   u32 count;
2972   int i;
2973
2974   vrf_id = ntohl (mp->vrf_id);
2975   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2976   if (~0 == vrf_index)
2977     {
2978       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2979       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2980       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2981       vec_validate (vam->ip6_fib_counters, vrf_index);
2982       vam->ip6_fib_counters[vrf_index] = NULL;
2983     }
2984
2985   vec_free (vam->ip6_fib_counters[vrf_index]);
2986   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2987   count = ntohl (mp->count);
2988   for (i = 0; i < count; i++)
2989     {
2990       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2991       counter = &vam->ip6_fib_counters[vrf_index][i];
2992       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2993       counter->address = ip6;
2994       counter->address_length = v->address_length;
2995       counter->packets = clib_net_to_host_u64 (v->packets);
2996       counter->bytes = clib_net_to_host_u64 (v->bytes);
2997       v++;
2998     }
2999 }
3000
3001 static void vl_api_vnet_ip6_nbr_counters_t_handler
3002   (vl_api_vnet_ip6_nbr_counters_t * mp)
3003 {
3004   /* not supported */
3005 }
3006
3007 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
3008   (vl_api_vnet_ip6_nbr_counters_t * mp)
3009 {
3010   vat_main_t *vam = &vat_main;
3011   vl_api_ip6_nbr_counter_t *v;
3012   ip6_nbr_counter_t *counter;
3013   struct in6_addr ip6;
3014   u32 sw_if_index;
3015   u32 count;
3016   int i;
3017
3018   sw_if_index = ntohl (mp->sw_if_index);
3019   count = ntohl (mp->count);
3020   vec_validate (vam->ip6_nbr_counters, sw_if_index);
3021
3022   if (mp->begin)
3023     vec_free (vam->ip6_nbr_counters[sw_if_index]);
3024
3025   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
3026   for (i = 0; i < count; i++)
3027     {
3028       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
3029       counter = &vam->ip6_nbr_counters[sw_if_index][i];
3030       clib_memcpy (&ip6, &v->address, sizeof (ip6));
3031       counter->address = ip6;
3032       counter->packets = clib_net_to_host_u64 (v->packets);
3033       counter->bytes = clib_net_to_host_u64 (v->bytes);
3034       v++;
3035     }
3036 }
3037
3038 static void vl_api_get_first_msg_id_reply_t_handler
3039   (vl_api_get_first_msg_id_reply_t * mp)
3040 {
3041   vat_main_t *vam = &vat_main;
3042   i32 retval = ntohl (mp->retval);
3043
3044   if (vam->async_mode)
3045     {
3046       vam->async_errors += (retval < 0);
3047     }
3048   else
3049     {
3050       vam->retval = retval;
3051       vam->result_ready = 1;
3052     }
3053   if (retval >= 0)
3054     {
3055       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3056     }
3057 }
3058
3059 static void vl_api_get_first_msg_id_reply_t_handler_json
3060   (vl_api_get_first_msg_id_reply_t * mp)
3061 {
3062   vat_main_t *vam = &vat_main;
3063   vat_json_node_t node;
3064
3065   vat_json_init_object (&node);
3066   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3067   vat_json_object_add_uint (&node, "first_msg_id",
3068                             (uint) ntohs (mp->first_msg_id));
3069
3070   vat_json_print (vam->ofp, &node);
3071   vat_json_free (&node);
3072
3073   vam->retval = ntohl (mp->retval);
3074   vam->result_ready = 1;
3075 }
3076
3077 static void vl_api_get_node_graph_reply_t_handler
3078   (vl_api_get_node_graph_reply_t * mp)
3079 {
3080   vat_main_t *vam = &vat_main;
3081   api_main_t *am = &api_main;
3082   i32 retval = ntohl (mp->retval);
3083   u8 *pvt_copy, *reply;
3084   void *oldheap;
3085   vlib_node_t *node;
3086   int i;
3087
3088   if (vam->async_mode)
3089     {
3090       vam->async_errors += (retval < 0);
3091     }
3092   else
3093     {
3094       vam->retval = retval;
3095       vam->result_ready = 1;
3096     }
3097
3098   /* "Should never happen..." */
3099   if (retval != 0)
3100     return;
3101
3102   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3103   pvt_copy = vec_dup (reply);
3104
3105   /* Toss the shared-memory original... */
3106   pthread_mutex_lock (&am->vlib_rp->mutex);
3107   oldheap = svm_push_data_heap (am->vlib_rp);
3108
3109   vec_free (reply);
3110
3111   svm_pop_heap (oldheap);
3112   pthread_mutex_unlock (&am->vlib_rp->mutex);
3113
3114   if (vam->graph_nodes)
3115     {
3116       hash_free (vam->graph_node_index_by_name);
3117
3118       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3119         {
3120           node = vam->graph_nodes[0][i];
3121           vec_free (node->name);
3122           vec_free (node->next_nodes);
3123           vec_free (node);
3124         }
3125       vec_free (vam->graph_nodes[0]);
3126       vec_free (vam->graph_nodes);
3127     }
3128
3129   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3130   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3131   vec_free (pvt_copy);
3132
3133   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3134     {
3135       node = vam->graph_nodes[0][i];
3136       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3137     }
3138 }
3139
3140 static void vl_api_get_node_graph_reply_t_handler_json
3141   (vl_api_get_node_graph_reply_t * mp)
3142 {
3143   vat_main_t *vam = &vat_main;
3144   api_main_t *am = &api_main;
3145   void *oldheap;
3146   vat_json_node_t node;
3147   u8 *reply;
3148
3149   /* $$$$ make this real? */
3150   vat_json_init_object (&node);
3151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3152   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3153
3154   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3155
3156   /* Toss the shared-memory original... */
3157   pthread_mutex_lock (&am->vlib_rp->mutex);
3158   oldheap = svm_push_data_heap (am->vlib_rp);
3159
3160   vec_free (reply);
3161
3162   svm_pop_heap (oldheap);
3163   pthread_mutex_unlock (&am->vlib_rp->mutex);
3164
3165   vat_json_print (vam->ofp, &node);
3166   vat_json_free (&node);
3167
3168   vam->retval = ntohl (mp->retval);
3169   vam->result_ready = 1;
3170 }
3171
3172 static void
3173 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3174 {
3175   vat_main_t *vam = &vat_main;
3176   u8 *s = 0;
3177
3178   if (mp->local)
3179     {
3180       s = format (s, "%=16d%=16d%=16d",
3181                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3182     }
3183   else
3184     {
3185       s = format (s, "%=16U%=16d%=16d",
3186                   mp->is_ipv6 ? format_ip6_address :
3187                   format_ip4_address,
3188                   mp->ip_address, mp->priority, mp->weight);
3189     }
3190
3191   print (vam->ofp, "%v", s);
3192   vec_free (s);
3193 }
3194
3195 static void
3196 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3197 {
3198   vat_main_t *vam = &vat_main;
3199   vat_json_node_t *node = NULL;
3200   struct in6_addr ip6;
3201   struct in_addr ip4;
3202
3203   if (VAT_JSON_ARRAY != vam->json_tree.type)
3204     {
3205       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3206       vat_json_init_array (&vam->json_tree);
3207     }
3208   node = vat_json_array_add (&vam->json_tree);
3209   vat_json_init_object (node);
3210
3211   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3212   vat_json_object_add_uint (node, "priority", mp->priority);
3213   vat_json_object_add_uint (node, "weight", mp->weight);
3214
3215   if (mp->local)
3216     vat_json_object_add_uint (node, "sw_if_index",
3217                               clib_net_to_host_u32 (mp->sw_if_index));
3218   else
3219     {
3220       if (mp->is_ipv6)
3221         {
3222           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3223           vat_json_object_add_ip6 (node, "address", ip6);
3224         }
3225       else
3226         {
3227           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3228           vat_json_object_add_ip4 (node, "address", ip4);
3229         }
3230     }
3231 }
3232
3233 static void
3234 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3235                                           mp)
3236 {
3237   vat_main_t *vam = &vat_main;
3238   u8 *ls_name = 0;
3239
3240   ls_name = format (0, "%s", mp->ls_name);
3241
3242   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3243          ls_name);
3244   vec_free (ls_name);
3245 }
3246
3247 static void
3248   vl_api_one_locator_set_details_t_handler_json
3249   (vl_api_one_locator_set_details_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   vat_json_node_t *node = 0;
3253   u8 *ls_name = 0;
3254
3255   ls_name = format (0, "%s", mp->ls_name);
3256   vec_add1 (ls_name, 0);
3257
3258   if (VAT_JSON_ARRAY != vam->json_tree.type)
3259     {
3260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3261       vat_json_init_array (&vam->json_tree);
3262     }
3263   node = vat_json_array_add (&vam->json_tree);
3264
3265   vat_json_init_object (node);
3266   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3267   vat_json_object_add_uint (node, "ls_index",
3268                             clib_net_to_host_u32 (mp->ls_index));
3269   vec_free (ls_name);
3270 }
3271
3272 typedef struct
3273 {
3274   u32 spi;
3275   u8 si;
3276 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3277
3278 uword
3279 unformat_nsh_address (unformat_input_t * input, va_list * args)
3280 {
3281   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3282   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3283 }
3284
3285 u8 *
3286 format_nsh_address_vat (u8 * s, va_list * args)
3287 {
3288   nsh_t *a = va_arg (*args, nsh_t *);
3289   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3290 }
3291
3292 static u8 *
3293 format_lisp_flat_eid (u8 * s, va_list * args)
3294 {
3295   u32 type = va_arg (*args, u32);
3296   u8 *eid = va_arg (*args, u8 *);
3297   u32 eid_len = va_arg (*args, u32);
3298
3299   switch (type)
3300     {
3301     case 0:
3302       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3303     case 1:
3304       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3305     case 2:
3306       return format (s, "%U", format_ethernet_address, eid);
3307     case 3:
3308       return format (s, "%U", format_nsh_address_vat, eid);
3309     }
3310   return 0;
3311 }
3312
3313 static u8 *
3314 format_lisp_eid_vat (u8 * s, va_list * args)
3315 {
3316   u32 type = va_arg (*args, u32);
3317   u8 *eid = va_arg (*args, u8 *);
3318   u32 eid_len = va_arg (*args, u32);
3319   u8 *seid = va_arg (*args, u8 *);
3320   u32 seid_len = va_arg (*args, u32);
3321   u32 is_src_dst = va_arg (*args, u32);
3322
3323   if (is_src_dst)
3324     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3325
3326   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3327
3328   return s;
3329 }
3330
3331 static void
3332 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3333 {
3334   vat_main_t *vam = &vat_main;
3335   u8 *s = 0, *eid = 0;
3336
3337   if (~0 == mp->locator_set_index)
3338     s = format (0, "action: %d", mp->action);
3339   else
3340     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3341
3342   eid = format (0, "%U", format_lisp_eid_vat,
3343                 mp->eid_type,
3344                 mp->eid,
3345                 mp->eid_prefix_len,
3346                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3347   vec_add1 (eid, 0);
3348
3349   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3350          clib_net_to_host_u32 (mp->vni),
3351          eid,
3352          mp->is_local ? "local" : "remote",
3353          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3354          clib_net_to_host_u16 (mp->key_id), mp->key);
3355
3356   vec_free (s);
3357   vec_free (eid);
3358 }
3359
3360 static void
3361 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3362                                              * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365   vat_json_node_t *node = 0;
3366   u8 *eid = 0;
3367
3368   if (VAT_JSON_ARRAY != vam->json_tree.type)
3369     {
3370       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3371       vat_json_init_array (&vam->json_tree);
3372     }
3373   node = vat_json_array_add (&vam->json_tree);
3374
3375   vat_json_init_object (node);
3376   if (~0 == mp->locator_set_index)
3377     vat_json_object_add_uint (node, "action", mp->action);
3378   else
3379     vat_json_object_add_uint (node, "locator_set_index",
3380                               clib_net_to_host_u32 (mp->locator_set_index));
3381
3382   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3383   if (mp->eid_type == 3)
3384     {
3385       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3386       vat_json_init_object (nsh_json);
3387       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3388       vat_json_object_add_uint (nsh_json, "spi",
3389                                 clib_net_to_host_u32 (nsh->spi));
3390       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3391     }
3392   else
3393     {
3394       eid = format (0, "%U", format_lisp_eid_vat,
3395                     mp->eid_type,
3396                     mp->eid,
3397                     mp->eid_prefix_len,
3398                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3399       vec_add1 (eid, 0);
3400       vat_json_object_add_string_copy (node, "eid", eid);
3401       vec_free (eid);
3402     }
3403   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3404   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3405   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3406
3407   if (mp->key_id)
3408     {
3409       vat_json_object_add_uint (node, "key_id",
3410                                 clib_net_to_host_u16 (mp->key_id));
3411       vat_json_object_add_string_copy (node, "key", mp->key);
3412     }
3413 }
3414
3415 static void
3416 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3417 {
3418   vat_main_t *vam = &vat_main;
3419   u8 *seid = 0, *deid = 0;
3420   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3421
3422   deid = format (0, "%U", format_lisp_eid_vat,
3423                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3424
3425   seid = format (0, "%U", format_lisp_eid_vat,
3426                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3427
3428   vec_add1 (deid, 0);
3429   vec_add1 (seid, 0);
3430
3431   if (mp->is_ip4)
3432     format_ip_address_fcn = format_ip4_address;
3433   else
3434     format_ip_address_fcn = format_ip6_address;
3435
3436
3437   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3438          clib_net_to_host_u32 (mp->vni),
3439          seid, deid,
3440          format_ip_address_fcn, mp->lloc,
3441          format_ip_address_fcn, mp->rloc,
3442          clib_net_to_host_u32 (mp->pkt_count),
3443          clib_net_to_host_u32 (mp->bytes));
3444
3445   vec_free (deid);
3446   vec_free (seid);
3447 }
3448
3449 static void
3450 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3451 {
3452   struct in6_addr ip6;
3453   struct in_addr ip4;
3454   vat_main_t *vam = &vat_main;
3455   vat_json_node_t *node = 0;
3456   u8 *deid = 0, *seid = 0;
3457
3458   if (VAT_JSON_ARRAY != vam->json_tree.type)
3459     {
3460       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3461       vat_json_init_array (&vam->json_tree);
3462     }
3463   node = vat_json_array_add (&vam->json_tree);
3464
3465   vat_json_init_object (node);
3466   deid = format (0, "%U", format_lisp_eid_vat,
3467                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3468
3469   seid = format (0, "%U", format_lisp_eid_vat,
3470                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3471
3472   vec_add1 (deid, 0);
3473   vec_add1 (seid, 0);
3474
3475   vat_json_object_add_string_copy (node, "seid", seid);
3476   vat_json_object_add_string_copy (node, "deid", deid);
3477   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3478
3479   if (mp->is_ip4)
3480     {
3481       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3482       vat_json_object_add_ip4 (node, "lloc", ip4);
3483       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3484       vat_json_object_add_ip4 (node, "rloc", ip4);
3485     }
3486   else
3487     {
3488       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3489       vat_json_object_add_ip6 (node, "lloc", ip6);
3490       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3491       vat_json_object_add_ip6 (node, "rloc", ip6);
3492     }
3493   vat_json_object_add_uint (node, "pkt_count",
3494                             clib_net_to_host_u32 (mp->pkt_count));
3495   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3496
3497   vec_free (deid);
3498   vec_free (seid);
3499 }
3500
3501 static void
3502   vl_api_one_eid_table_map_details_t_handler
3503   (vl_api_one_eid_table_map_details_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506
3507   u8 *line = format (0, "%=10d%=10d",
3508                      clib_net_to_host_u32 (mp->vni),
3509                      clib_net_to_host_u32 (mp->dp_table));
3510   print (vam->ofp, "%v", line);
3511   vec_free (line);
3512 }
3513
3514 static void
3515   vl_api_one_eid_table_map_details_t_handler_json
3516   (vl_api_one_eid_table_map_details_t * mp)
3517 {
3518   vat_main_t *vam = &vat_main;
3519   vat_json_node_t *node = NULL;
3520
3521   if (VAT_JSON_ARRAY != vam->json_tree.type)
3522     {
3523       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3524       vat_json_init_array (&vam->json_tree);
3525     }
3526   node = vat_json_array_add (&vam->json_tree);
3527   vat_json_init_object (node);
3528   vat_json_object_add_uint (node, "dp_table",
3529                             clib_net_to_host_u32 (mp->dp_table));
3530   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3531 }
3532
3533 static void
3534   vl_api_one_eid_table_vni_details_t_handler
3535   (vl_api_one_eid_table_vni_details_t * mp)
3536 {
3537   vat_main_t *vam = &vat_main;
3538
3539   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3540   print (vam->ofp, "%v", line);
3541   vec_free (line);
3542 }
3543
3544 static void
3545   vl_api_one_eid_table_vni_details_t_handler_json
3546   (vl_api_one_eid_table_vni_details_t * mp)
3547 {
3548   vat_main_t *vam = &vat_main;
3549   vat_json_node_t *node = NULL;
3550
3551   if (VAT_JSON_ARRAY != vam->json_tree.type)
3552     {
3553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3554       vat_json_init_array (&vam->json_tree);
3555     }
3556   node = vat_json_array_add (&vam->json_tree);
3557   vat_json_init_object (node);
3558   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3559 }
3560
3561 static void
3562   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3563   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3564 {
3565   vat_main_t *vam = &vat_main;
3566   int retval = clib_net_to_host_u32 (mp->retval);
3567
3568   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3569   print (vam->ofp, "fallback threshold value: %d", mp->value);
3570
3571   vam->retval = retval;
3572   vam->result_ready = 1;
3573 }
3574
3575 static void
3576   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3577   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3578 {
3579   vat_main_t *vam = &vat_main;
3580   vat_json_node_t _node, *node = &_node;
3581   int retval = clib_net_to_host_u32 (mp->retval);
3582
3583   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3584   vat_json_init_object (node);
3585   vat_json_object_add_uint (node, "value", mp->value);
3586
3587   vat_json_print (vam->ofp, node);
3588   vat_json_free (node);
3589
3590   vam->retval = retval;
3591   vam->result_ready = 1;
3592 }
3593
3594 static void
3595   vl_api_show_one_map_register_state_reply_t_handler
3596   (vl_api_show_one_map_register_state_reply_t * mp)
3597 {
3598   vat_main_t *vam = &vat_main;
3599   int retval = clib_net_to_host_u32 (mp->retval);
3600
3601   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3602
3603   vam->retval = retval;
3604   vam->result_ready = 1;
3605 }
3606
3607 static void
3608   vl_api_show_one_map_register_state_reply_t_handler_json
3609   (vl_api_show_one_map_register_state_reply_t * mp)
3610 {
3611   vat_main_t *vam = &vat_main;
3612   vat_json_node_t _node, *node = &_node;
3613   int retval = clib_net_to_host_u32 (mp->retval);
3614
3615   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3616
3617   vat_json_init_object (node);
3618   vat_json_object_add_string_copy (node, "state", s);
3619
3620   vat_json_print (vam->ofp, node);
3621   vat_json_free (node);
3622
3623   vam->retval = retval;
3624   vam->result_ready = 1;
3625   vec_free (s);
3626 }
3627
3628 static void
3629   vl_api_show_one_rloc_probe_state_reply_t_handler
3630   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3631 {
3632   vat_main_t *vam = &vat_main;
3633   int retval = clib_net_to_host_u32 (mp->retval);
3634
3635   if (retval)
3636     goto end;
3637
3638   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3639 end:
3640   vam->retval = retval;
3641   vam->result_ready = 1;
3642 }
3643
3644 static void
3645   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3646   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3647 {
3648   vat_main_t *vam = &vat_main;
3649   vat_json_node_t _node, *node = &_node;
3650   int retval = clib_net_to_host_u32 (mp->retval);
3651
3652   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3653   vat_json_init_object (node);
3654   vat_json_object_add_string_copy (node, "state", s);
3655
3656   vat_json_print (vam->ofp, node);
3657   vat_json_free (node);
3658
3659   vam->retval = retval;
3660   vam->result_ready = 1;
3661   vec_free (s);
3662 }
3663
3664 static void
3665   vl_api_show_one_stats_enable_disable_reply_t_handler
3666   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3667 {
3668   vat_main_t *vam = &vat_main;
3669   int retval = clib_net_to_host_u32 (mp->retval);
3670
3671   if (retval)
3672     goto end;
3673
3674   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3675 end:
3676   vam->retval = retval;
3677   vam->result_ready = 1;
3678 }
3679
3680 static void
3681   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3682   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3683 {
3684   vat_main_t *vam = &vat_main;
3685   vat_json_node_t _node, *node = &_node;
3686   int retval = clib_net_to_host_u32 (mp->retval);
3687
3688   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3689   vat_json_init_object (node);
3690   vat_json_object_add_string_copy (node, "state", s);
3691
3692   vat_json_print (vam->ofp, node);
3693   vat_json_free (node);
3694
3695   vam->retval = retval;
3696   vam->result_ready = 1;
3697   vec_free (s);
3698 }
3699
3700 static void
3701 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3702 {
3703   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3704   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3705   e->vni = clib_net_to_host_u32 (e->vni);
3706 }
3707
3708 static void
3709   gpe_fwd_entries_get_reply_t_net_to_host
3710   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3711 {
3712   u32 i;
3713
3714   mp->count = clib_net_to_host_u32 (mp->count);
3715   for (i = 0; i < mp->count; i++)
3716     {
3717       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3718     }
3719 }
3720
3721 static u8 *
3722 format_gpe_encap_mode (u8 * s, va_list * args)
3723 {
3724   u32 mode = va_arg (*args, u32);
3725
3726   switch (mode)
3727     {
3728     case 0:
3729       return format (s, "lisp");
3730     case 1:
3731       return format (s, "vxlan");
3732     }
3733   return 0;
3734 }
3735
3736 static void
3737   vl_api_gpe_get_encap_mode_reply_t_handler
3738   (vl_api_gpe_get_encap_mode_reply_t * mp)
3739 {
3740   vat_main_t *vam = &vat_main;
3741
3742   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3743   vam->retval = ntohl (mp->retval);
3744   vam->result_ready = 1;
3745 }
3746
3747 static void
3748   vl_api_gpe_get_encap_mode_reply_t_handler_json
3749   (vl_api_gpe_get_encap_mode_reply_t * mp)
3750 {
3751   vat_main_t *vam = &vat_main;
3752   vat_json_node_t node;
3753
3754   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3755   vec_add1 (encap_mode, 0);
3756
3757   vat_json_init_object (&node);
3758   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3759
3760   vec_free (encap_mode);
3761   vat_json_print (vam->ofp, &node);
3762   vat_json_free (&node);
3763
3764   vam->retval = ntohl (mp->retval);
3765   vam->result_ready = 1;
3766 }
3767
3768 static void
3769   vl_api_gpe_fwd_entry_path_details_t_handler
3770   (vl_api_gpe_fwd_entry_path_details_t * mp)
3771 {
3772   vat_main_t *vam = &vat_main;
3773   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3774
3775   if (mp->lcl_loc.is_ip4)
3776     format_ip_address_fcn = format_ip4_address;
3777   else
3778     format_ip_address_fcn = format_ip6_address;
3779
3780   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3781          format_ip_address_fcn, &mp->lcl_loc,
3782          format_ip_address_fcn, &mp->rmt_loc);
3783 }
3784
3785 static void
3786 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3787 {
3788   struct in6_addr ip6;
3789   struct in_addr ip4;
3790
3791   if (loc->is_ip4)
3792     {
3793       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3794       vat_json_object_add_ip4 (n, "address", ip4);
3795     }
3796   else
3797     {
3798       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3799       vat_json_object_add_ip6 (n, "address", ip6);
3800     }
3801   vat_json_object_add_uint (n, "weight", loc->weight);
3802 }
3803
3804 static void
3805   vl_api_gpe_fwd_entry_path_details_t_handler_json
3806   (vl_api_gpe_fwd_entry_path_details_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   vat_json_node_t *node = NULL;
3810   vat_json_node_t *loc_node;
3811
3812   if (VAT_JSON_ARRAY != vam->json_tree.type)
3813     {
3814       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3815       vat_json_init_array (&vam->json_tree);
3816     }
3817   node = vat_json_array_add (&vam->json_tree);
3818   vat_json_init_object (node);
3819
3820   loc_node = vat_json_object_add (node, "local_locator");
3821   vat_json_init_object (loc_node);
3822   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3823
3824   loc_node = vat_json_object_add (node, "remote_locator");
3825   vat_json_init_object (loc_node);
3826   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3827 }
3828
3829 static void
3830   vl_api_gpe_fwd_entries_get_reply_t_handler
3831   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3832 {
3833   vat_main_t *vam = &vat_main;
3834   u32 i;
3835   int retval = clib_net_to_host_u32 (mp->retval);
3836   vl_api_gpe_fwd_entry_t *e;
3837
3838   if (retval)
3839     goto end;
3840
3841   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3842
3843   for (i = 0; i < mp->count; i++)
3844     {
3845       e = &mp->entries[i];
3846       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3847              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3848              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3849     }
3850
3851 end:
3852   vam->retval = retval;
3853   vam->result_ready = 1;
3854 }
3855
3856 static void
3857   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3858   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3859 {
3860   u8 *s = 0;
3861   vat_main_t *vam = &vat_main;
3862   vat_json_node_t *e = 0, root;
3863   u32 i;
3864   int retval = clib_net_to_host_u32 (mp->retval);
3865   vl_api_gpe_fwd_entry_t *fwd;
3866
3867   if (retval)
3868     goto end;
3869
3870   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3871   vat_json_init_array (&root);
3872
3873   for (i = 0; i < mp->count; i++)
3874     {
3875       e = vat_json_array_add (&root);
3876       fwd = &mp->entries[i];
3877
3878       vat_json_init_object (e);
3879       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3880       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3881       vat_json_object_add_int (e, "vni", fwd->vni);
3882       vat_json_object_add_int (e, "action", fwd->action);
3883
3884       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3885                   fwd->leid_prefix_len);
3886       vec_add1 (s, 0);
3887       vat_json_object_add_string_copy (e, "leid", s);
3888       vec_free (s);
3889
3890       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3891                   fwd->reid_prefix_len);
3892       vec_add1 (s, 0);
3893       vat_json_object_add_string_copy (e, "reid", s);
3894       vec_free (s);
3895     }
3896
3897   vat_json_print (vam->ofp, &root);
3898   vat_json_free (&root);
3899
3900 end:
3901   vam->retval = retval;
3902   vam->result_ready = 1;
3903 }
3904
3905 static void
3906   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3907   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3908 {
3909   vat_main_t *vam = &vat_main;
3910   u32 i, n;
3911   int retval = clib_net_to_host_u32 (mp->retval);
3912   vl_api_gpe_native_fwd_rpath_t *r;
3913
3914   if (retval)
3915     goto end;
3916
3917   n = clib_net_to_host_u32 (mp->count);
3918
3919   for (i = 0; i < n; i++)
3920     {
3921       r = &mp->entries[i];
3922       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3923              clib_net_to_host_u32 (r->fib_index),
3924              clib_net_to_host_u32 (r->nh_sw_if_index),
3925              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3926     }
3927
3928 end:
3929   vam->retval = retval;
3930   vam->result_ready = 1;
3931 }
3932
3933 static void
3934   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3935   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3936 {
3937   vat_main_t *vam = &vat_main;
3938   vat_json_node_t root, *e;
3939   u32 i, n;
3940   int retval = clib_net_to_host_u32 (mp->retval);
3941   vl_api_gpe_native_fwd_rpath_t *r;
3942   u8 *s;
3943
3944   if (retval)
3945     goto end;
3946
3947   n = clib_net_to_host_u32 (mp->count);
3948   vat_json_init_array (&root);
3949
3950   for (i = 0; i < n; i++)
3951     {
3952       e = vat_json_array_add (&root);
3953       vat_json_init_object (e);
3954       r = &mp->entries[i];
3955       s =
3956         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3957                 r->nh_addr);
3958       vec_add1 (s, 0);
3959       vat_json_object_add_string_copy (e, "ip4", s);
3960       vec_free (s);
3961
3962       vat_json_object_add_uint (e, "fib_index",
3963                                 clib_net_to_host_u32 (r->fib_index));
3964       vat_json_object_add_uint (e, "nh_sw_if_index",
3965                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3966     }
3967
3968   vat_json_print (vam->ofp, &root);
3969   vat_json_free (&root);
3970
3971 end:
3972   vam->retval = retval;
3973   vam->result_ready = 1;
3974 }
3975
3976 static void
3977   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3978   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3979 {
3980   vat_main_t *vam = &vat_main;
3981   u32 i, n;
3982   int retval = clib_net_to_host_u32 (mp->retval);
3983
3984   if (retval)
3985     goto end;
3986
3987   n = clib_net_to_host_u32 (mp->count);
3988
3989   for (i = 0; i < n; i++)
3990     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3991
3992 end:
3993   vam->retval = retval;
3994   vam->result_ready = 1;
3995 }
3996
3997 static void
3998   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3999   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
4000 {
4001   vat_main_t *vam = &vat_main;
4002   vat_json_node_t root;
4003   u32 i, n;
4004   int retval = clib_net_to_host_u32 (mp->retval);
4005
4006   if (retval)
4007     goto end;
4008
4009   n = clib_net_to_host_u32 (mp->count);
4010   vat_json_init_array (&root);
4011
4012   for (i = 0; i < n; i++)
4013     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
4014
4015   vat_json_print (vam->ofp, &root);
4016   vat_json_free (&root);
4017
4018 end:
4019   vam->retval = retval;
4020   vam->result_ready = 1;
4021 }
4022
4023 static void
4024   vl_api_one_ndp_entries_get_reply_t_handler
4025   (vl_api_one_ndp_entries_get_reply_t * mp)
4026 {
4027   vat_main_t *vam = &vat_main;
4028   u32 i, n;
4029   int retval = clib_net_to_host_u32 (mp->retval);
4030
4031   if (retval)
4032     goto end;
4033
4034   n = clib_net_to_host_u32 (mp->count);
4035
4036   for (i = 0; i < n; i++)
4037     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
4038            format_ethernet_address, mp->entries[i].mac);
4039
4040 end:
4041   vam->retval = retval;
4042   vam->result_ready = 1;
4043 }
4044
4045 static void
4046   vl_api_one_ndp_entries_get_reply_t_handler_json
4047   (vl_api_one_ndp_entries_get_reply_t * mp)
4048 {
4049   u8 *s = 0;
4050   vat_main_t *vam = &vat_main;
4051   vat_json_node_t *e = 0, root;
4052   u32 i, n;
4053   int retval = clib_net_to_host_u32 (mp->retval);
4054   vl_api_one_ndp_entry_t *arp_entry;
4055
4056   if (retval)
4057     goto end;
4058
4059   n = clib_net_to_host_u32 (mp->count);
4060   vat_json_init_array (&root);
4061
4062   for (i = 0; i < n; i++)
4063     {
4064       e = vat_json_array_add (&root);
4065       arp_entry = &mp->entries[i];
4066
4067       vat_json_init_object (e);
4068       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4069       vec_add1 (s, 0);
4070
4071       vat_json_object_add_string_copy (e, "mac", s);
4072       vec_free (s);
4073
4074       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4075       vec_add1 (s, 0);
4076       vat_json_object_add_string_copy (e, "ip6", s);
4077       vec_free (s);
4078     }
4079
4080   vat_json_print (vam->ofp, &root);
4081   vat_json_free (&root);
4082
4083 end:
4084   vam->retval = retval;
4085   vam->result_ready = 1;
4086 }
4087
4088 static void
4089   vl_api_one_l2_arp_entries_get_reply_t_handler
4090   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093   u32 i, n;
4094   int retval = clib_net_to_host_u32 (mp->retval);
4095
4096   if (retval)
4097     goto end;
4098
4099   n = clib_net_to_host_u32 (mp->count);
4100
4101   for (i = 0; i < n; i++)
4102     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4103            format_ethernet_address, mp->entries[i].mac);
4104
4105 end:
4106   vam->retval = retval;
4107   vam->result_ready = 1;
4108 }
4109
4110 static void
4111   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4112   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4113 {
4114   u8 *s = 0;
4115   vat_main_t *vam = &vat_main;
4116   vat_json_node_t *e = 0, root;
4117   u32 i, n;
4118   int retval = clib_net_to_host_u32 (mp->retval);
4119   vl_api_one_l2_arp_entry_t *arp_entry;
4120
4121   if (retval)
4122     goto end;
4123
4124   n = clib_net_to_host_u32 (mp->count);
4125   vat_json_init_array (&root);
4126
4127   for (i = 0; i < n; i++)
4128     {
4129       e = vat_json_array_add (&root);
4130       arp_entry = &mp->entries[i];
4131
4132       vat_json_init_object (e);
4133       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4134       vec_add1 (s, 0);
4135
4136       vat_json_object_add_string_copy (e, "mac", s);
4137       vec_free (s);
4138
4139       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4140       vec_add1 (s, 0);
4141       vat_json_object_add_string_copy (e, "ip4", s);
4142       vec_free (s);
4143     }
4144
4145   vat_json_print (vam->ofp, &root);
4146   vat_json_free (&root);
4147
4148 end:
4149   vam->retval = retval;
4150   vam->result_ready = 1;
4151 }
4152
4153 static void
4154 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4155 {
4156   vat_main_t *vam = &vat_main;
4157   u32 i, n;
4158   int retval = clib_net_to_host_u32 (mp->retval);
4159
4160   if (retval)
4161     goto end;
4162
4163   n = clib_net_to_host_u32 (mp->count);
4164
4165   for (i = 0; i < n; i++)
4166     {
4167       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4168     }
4169
4170 end:
4171   vam->retval = retval;
4172   vam->result_ready = 1;
4173 }
4174
4175 static void
4176   vl_api_one_ndp_bd_get_reply_t_handler_json
4177   (vl_api_one_ndp_bd_get_reply_t * mp)
4178 {
4179   vat_main_t *vam = &vat_main;
4180   vat_json_node_t root;
4181   u32 i, n;
4182   int retval = clib_net_to_host_u32 (mp->retval);
4183
4184   if (retval)
4185     goto end;
4186
4187   n = clib_net_to_host_u32 (mp->count);
4188   vat_json_init_array (&root);
4189
4190   for (i = 0; i < n; i++)
4191     {
4192       vat_json_array_add_uint (&root,
4193                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4194     }
4195
4196   vat_json_print (vam->ofp, &root);
4197   vat_json_free (&root);
4198
4199 end:
4200   vam->retval = retval;
4201   vam->result_ready = 1;
4202 }
4203
4204 static void
4205   vl_api_one_l2_arp_bd_get_reply_t_handler
4206   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4207 {
4208   vat_main_t *vam = &vat_main;
4209   u32 i, n;
4210   int retval = clib_net_to_host_u32 (mp->retval);
4211
4212   if (retval)
4213     goto end;
4214
4215   n = clib_net_to_host_u32 (mp->count);
4216
4217   for (i = 0; i < n; i++)
4218     {
4219       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4220     }
4221
4222 end:
4223   vam->retval = retval;
4224   vam->result_ready = 1;
4225 }
4226
4227 static void
4228   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4229   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4230 {
4231   vat_main_t *vam = &vat_main;
4232   vat_json_node_t root;
4233   u32 i, n;
4234   int retval = clib_net_to_host_u32 (mp->retval);
4235
4236   if (retval)
4237     goto end;
4238
4239   n = clib_net_to_host_u32 (mp->count);
4240   vat_json_init_array (&root);
4241
4242   for (i = 0; i < n; i++)
4243     {
4244       vat_json_array_add_uint (&root,
4245                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4246     }
4247
4248   vat_json_print (vam->ofp, &root);
4249   vat_json_free (&root);
4250
4251 end:
4252   vam->retval = retval;
4253   vam->result_ready = 1;
4254 }
4255
4256 static void
4257   vl_api_one_adjacencies_get_reply_t_handler
4258   (vl_api_one_adjacencies_get_reply_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   u32 i, n;
4262   int retval = clib_net_to_host_u32 (mp->retval);
4263   vl_api_one_adjacency_t *a;
4264
4265   if (retval)
4266     goto end;
4267
4268   n = clib_net_to_host_u32 (mp->count);
4269
4270   for (i = 0; i < n; i++)
4271     {
4272       a = &mp->adjacencies[i];
4273       print (vam->ofp, "%U %40U",
4274              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4275              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4276     }
4277
4278 end:
4279   vam->retval = retval;
4280   vam->result_ready = 1;
4281 }
4282
4283 static void
4284   vl_api_one_adjacencies_get_reply_t_handler_json
4285   (vl_api_one_adjacencies_get_reply_t * mp)
4286 {
4287   u8 *s = 0;
4288   vat_main_t *vam = &vat_main;
4289   vat_json_node_t *e = 0, root;
4290   u32 i, n;
4291   int retval = clib_net_to_host_u32 (mp->retval);
4292   vl_api_one_adjacency_t *a;
4293
4294   if (retval)
4295     goto end;
4296
4297   n = clib_net_to_host_u32 (mp->count);
4298   vat_json_init_array (&root);
4299
4300   for (i = 0; i < n; i++)
4301     {
4302       e = vat_json_array_add (&root);
4303       a = &mp->adjacencies[i];
4304
4305       vat_json_init_object (e);
4306       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4307                   a->leid_prefix_len);
4308       vec_add1 (s, 0);
4309       vat_json_object_add_string_copy (e, "leid", s);
4310       vec_free (s);
4311
4312       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4313                   a->reid_prefix_len);
4314       vec_add1 (s, 0);
4315       vat_json_object_add_string_copy (e, "reid", s);
4316       vec_free (s);
4317     }
4318
4319   vat_json_print (vam->ofp, &root);
4320   vat_json_free (&root);
4321
4322 end:
4323   vam->retval = retval;
4324   vam->result_ready = 1;
4325 }
4326
4327 static void
4328 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4329 {
4330   vat_main_t *vam = &vat_main;
4331
4332   print (vam->ofp, "%=20U",
4333          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4334          mp->ip_address);
4335 }
4336
4337 static void
4338   vl_api_one_map_server_details_t_handler_json
4339   (vl_api_one_map_server_details_t * mp)
4340 {
4341   vat_main_t *vam = &vat_main;
4342   vat_json_node_t *node = NULL;
4343   struct in6_addr ip6;
4344   struct in_addr ip4;
4345
4346   if (VAT_JSON_ARRAY != vam->json_tree.type)
4347     {
4348       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4349       vat_json_init_array (&vam->json_tree);
4350     }
4351   node = vat_json_array_add (&vam->json_tree);
4352
4353   vat_json_init_object (node);
4354   if (mp->is_ipv6)
4355     {
4356       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4357       vat_json_object_add_ip6 (node, "map-server", ip6);
4358     }
4359   else
4360     {
4361       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4362       vat_json_object_add_ip4 (node, "map-server", ip4);
4363     }
4364 }
4365
4366 static void
4367 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4368                                            * mp)
4369 {
4370   vat_main_t *vam = &vat_main;
4371
4372   print (vam->ofp, "%=20U",
4373          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4374          mp->ip_address);
4375 }
4376
4377 static void
4378   vl_api_one_map_resolver_details_t_handler_json
4379   (vl_api_one_map_resolver_details_t * mp)
4380 {
4381   vat_main_t *vam = &vat_main;
4382   vat_json_node_t *node = NULL;
4383   struct in6_addr ip6;
4384   struct in_addr ip4;
4385
4386   if (VAT_JSON_ARRAY != vam->json_tree.type)
4387     {
4388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4389       vat_json_init_array (&vam->json_tree);
4390     }
4391   node = vat_json_array_add (&vam->json_tree);
4392
4393   vat_json_init_object (node);
4394   if (mp->is_ipv6)
4395     {
4396       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4397       vat_json_object_add_ip6 (node, "map resolver", ip6);
4398     }
4399   else
4400     {
4401       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4402       vat_json_object_add_ip4 (node, "map resolver", ip4);
4403     }
4404 }
4405
4406 static void
4407 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4408 {
4409   vat_main_t *vam = &vat_main;
4410   i32 retval = ntohl (mp->retval);
4411
4412   if (0 <= retval)
4413     {
4414       print (vam->ofp, "feature: %s\ngpe: %s",
4415              mp->feature_status ? "enabled" : "disabled",
4416              mp->gpe_status ? "enabled" : "disabled");
4417     }
4418
4419   vam->retval = retval;
4420   vam->result_ready = 1;
4421 }
4422
4423 static void
4424   vl_api_show_one_status_reply_t_handler_json
4425   (vl_api_show_one_status_reply_t * mp)
4426 {
4427   vat_main_t *vam = &vat_main;
4428   vat_json_node_t node;
4429   u8 *gpe_status = NULL;
4430   u8 *feature_status = NULL;
4431
4432   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4433   feature_status = format (0, "%s",
4434                            mp->feature_status ? "enabled" : "disabled");
4435   vec_add1 (gpe_status, 0);
4436   vec_add1 (feature_status, 0);
4437
4438   vat_json_init_object (&node);
4439   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4440   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4441
4442   vec_free (gpe_status);
4443   vec_free (feature_status);
4444
4445   vat_json_print (vam->ofp, &node);
4446   vat_json_free (&node);
4447
4448   vam->retval = ntohl (mp->retval);
4449   vam->result_ready = 1;
4450 }
4451
4452 static void
4453   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4454   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4455 {
4456   vat_main_t *vam = &vat_main;
4457   i32 retval = ntohl (mp->retval);
4458
4459   if (retval >= 0)
4460     {
4461       print (vam->ofp, "%=20s", mp->locator_set_name);
4462     }
4463
4464   vam->retval = retval;
4465   vam->result_ready = 1;
4466 }
4467
4468 static void
4469   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4470   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4471 {
4472   vat_main_t *vam = &vat_main;
4473   vat_json_node_t *node = NULL;
4474
4475   if (VAT_JSON_ARRAY != vam->json_tree.type)
4476     {
4477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4478       vat_json_init_array (&vam->json_tree);
4479     }
4480   node = vat_json_array_add (&vam->json_tree);
4481
4482   vat_json_init_object (node);
4483   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4484
4485   vat_json_print (vam->ofp, node);
4486   vat_json_free (node);
4487
4488   vam->retval = ntohl (mp->retval);
4489   vam->result_ready = 1;
4490 }
4491
4492 static u8 *
4493 format_lisp_map_request_mode (u8 * s, va_list * args)
4494 {
4495   u32 mode = va_arg (*args, u32);
4496
4497   switch (mode)
4498     {
4499     case 0:
4500       return format (0, "dst-only");
4501     case 1:
4502       return format (0, "src-dst");
4503     }
4504   return 0;
4505 }
4506
4507 static void
4508   vl_api_show_one_map_request_mode_reply_t_handler
4509   (vl_api_show_one_map_request_mode_reply_t * mp)
4510 {
4511   vat_main_t *vam = &vat_main;
4512   i32 retval = ntohl (mp->retval);
4513
4514   if (0 <= retval)
4515     {
4516       u32 mode = mp->mode;
4517       print (vam->ofp, "map_request_mode: %U",
4518              format_lisp_map_request_mode, mode);
4519     }
4520
4521   vam->retval = retval;
4522   vam->result_ready = 1;
4523 }
4524
4525 static void
4526   vl_api_show_one_map_request_mode_reply_t_handler_json
4527   (vl_api_show_one_map_request_mode_reply_t * mp)
4528 {
4529   vat_main_t *vam = &vat_main;
4530   vat_json_node_t node;
4531   u8 *s = 0;
4532   u32 mode;
4533
4534   mode = mp->mode;
4535   s = format (0, "%U", format_lisp_map_request_mode, mode);
4536   vec_add1 (s, 0);
4537
4538   vat_json_init_object (&node);
4539   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4540   vat_json_print (vam->ofp, &node);
4541   vat_json_free (&node);
4542
4543   vec_free (s);
4544   vam->retval = ntohl (mp->retval);
4545   vam->result_ready = 1;
4546 }
4547
4548 static void
4549   vl_api_one_show_xtr_mode_reply_t_handler
4550   (vl_api_one_show_xtr_mode_reply_t * mp)
4551 {
4552   vat_main_t *vam = &vat_main;
4553   i32 retval = ntohl (mp->retval);
4554
4555   if (0 <= retval)
4556     {
4557       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4558     }
4559
4560   vam->retval = retval;
4561   vam->result_ready = 1;
4562 }
4563
4564 static void
4565   vl_api_one_show_xtr_mode_reply_t_handler_json
4566   (vl_api_one_show_xtr_mode_reply_t * mp)
4567 {
4568   vat_main_t *vam = &vat_main;
4569   vat_json_node_t node;
4570   u8 *status = 0;
4571
4572   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4573   vec_add1 (status, 0);
4574
4575   vat_json_init_object (&node);
4576   vat_json_object_add_string_copy (&node, "status", status);
4577
4578   vec_free (status);
4579
4580   vat_json_print (vam->ofp, &node);
4581   vat_json_free (&node);
4582
4583   vam->retval = ntohl (mp->retval);
4584   vam->result_ready = 1;
4585 }
4586
4587 static void
4588   vl_api_one_show_pitr_mode_reply_t_handler
4589   (vl_api_one_show_pitr_mode_reply_t * mp)
4590 {
4591   vat_main_t *vam = &vat_main;
4592   i32 retval = ntohl (mp->retval);
4593
4594   if (0 <= retval)
4595     {
4596       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4597     }
4598
4599   vam->retval = retval;
4600   vam->result_ready = 1;
4601 }
4602
4603 static void
4604   vl_api_one_show_pitr_mode_reply_t_handler_json
4605   (vl_api_one_show_pitr_mode_reply_t * mp)
4606 {
4607   vat_main_t *vam = &vat_main;
4608   vat_json_node_t node;
4609   u8 *status = 0;
4610
4611   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4612   vec_add1 (status, 0);
4613
4614   vat_json_init_object (&node);
4615   vat_json_object_add_string_copy (&node, "status", status);
4616
4617   vec_free (status);
4618
4619   vat_json_print (vam->ofp, &node);
4620   vat_json_free (&node);
4621
4622   vam->retval = ntohl (mp->retval);
4623   vam->result_ready = 1;
4624 }
4625
4626 static void
4627   vl_api_one_show_petr_mode_reply_t_handler
4628   (vl_api_one_show_petr_mode_reply_t * mp)
4629 {
4630   vat_main_t *vam = &vat_main;
4631   i32 retval = ntohl (mp->retval);
4632
4633   if (0 <= retval)
4634     {
4635       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4636     }
4637
4638   vam->retval = retval;
4639   vam->result_ready = 1;
4640 }
4641
4642 static void
4643   vl_api_one_show_petr_mode_reply_t_handler_json
4644   (vl_api_one_show_petr_mode_reply_t * mp)
4645 {
4646   vat_main_t *vam = &vat_main;
4647   vat_json_node_t node;
4648   u8 *status = 0;
4649
4650   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4651   vec_add1 (status, 0);
4652
4653   vat_json_init_object (&node);
4654   vat_json_object_add_string_copy (&node, "status", status);
4655
4656   vec_free (status);
4657
4658   vat_json_print (vam->ofp, &node);
4659   vat_json_free (&node);
4660
4661   vam->retval = ntohl (mp->retval);
4662   vam->result_ready = 1;
4663 }
4664
4665 static void
4666   vl_api_show_one_use_petr_reply_t_handler
4667   (vl_api_show_one_use_petr_reply_t * mp)
4668 {
4669   vat_main_t *vam = &vat_main;
4670   i32 retval = ntohl (mp->retval);
4671
4672   if (0 <= retval)
4673     {
4674       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4675       if (mp->status)
4676         {
4677           print (vam->ofp, "Proxy-ETR address; %U",
4678                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4679                  mp->address);
4680         }
4681     }
4682
4683   vam->retval = retval;
4684   vam->result_ready = 1;
4685 }
4686
4687 static void
4688   vl_api_show_one_use_petr_reply_t_handler_json
4689   (vl_api_show_one_use_petr_reply_t * mp)
4690 {
4691   vat_main_t *vam = &vat_main;
4692   vat_json_node_t node;
4693   u8 *status = 0;
4694   struct in_addr ip4;
4695   struct in6_addr ip6;
4696
4697   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4698   vec_add1 (status, 0);
4699
4700   vat_json_init_object (&node);
4701   vat_json_object_add_string_copy (&node, "status", status);
4702   if (mp->status)
4703     {
4704       if (mp->is_ip4)
4705         {
4706           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4707           vat_json_object_add_ip6 (&node, "address", ip6);
4708         }
4709       else
4710         {
4711           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4712           vat_json_object_add_ip4 (&node, "address", ip4);
4713         }
4714     }
4715
4716   vec_free (status);
4717
4718   vat_json_print (vam->ofp, &node);
4719   vat_json_free (&node);
4720
4721   vam->retval = ntohl (mp->retval);
4722   vam->result_ready = 1;
4723 }
4724
4725 static void
4726   vl_api_show_one_nsh_mapping_reply_t_handler
4727   (vl_api_show_one_nsh_mapping_reply_t * mp)
4728 {
4729   vat_main_t *vam = &vat_main;
4730   i32 retval = ntohl (mp->retval);
4731
4732   if (0 <= retval)
4733     {
4734       print (vam->ofp, "%-20s%-16s",
4735              mp->is_set ? "set" : "not-set",
4736              mp->is_set ? (char *) mp->locator_set_name : "");
4737     }
4738
4739   vam->retval = retval;
4740   vam->result_ready = 1;
4741 }
4742
4743 static void
4744   vl_api_show_one_nsh_mapping_reply_t_handler_json
4745   (vl_api_show_one_nsh_mapping_reply_t * mp)
4746 {
4747   vat_main_t *vam = &vat_main;
4748   vat_json_node_t node;
4749   u8 *status = 0;
4750
4751   status = format (0, "%s", mp->is_set ? "yes" : "no");
4752   vec_add1 (status, 0);
4753
4754   vat_json_init_object (&node);
4755   vat_json_object_add_string_copy (&node, "is_set", status);
4756   if (mp->is_set)
4757     {
4758       vat_json_object_add_string_copy (&node, "locator_set",
4759                                        mp->locator_set_name);
4760     }
4761
4762   vec_free (status);
4763
4764   vat_json_print (vam->ofp, &node);
4765   vat_json_free (&node);
4766
4767   vam->retval = ntohl (mp->retval);
4768   vam->result_ready = 1;
4769 }
4770
4771 static void
4772   vl_api_show_one_map_register_ttl_reply_t_handler
4773   (vl_api_show_one_map_register_ttl_reply_t * mp)
4774 {
4775   vat_main_t *vam = &vat_main;
4776   i32 retval = ntohl (mp->retval);
4777
4778   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4779
4780   if (0 <= retval)
4781     {
4782       print (vam->ofp, "ttl: %u", mp->ttl);
4783     }
4784
4785   vam->retval = retval;
4786   vam->result_ready = 1;
4787 }
4788
4789 static void
4790   vl_api_show_one_map_register_ttl_reply_t_handler_json
4791   (vl_api_show_one_map_register_ttl_reply_t * mp)
4792 {
4793   vat_main_t *vam = &vat_main;
4794   vat_json_node_t node;
4795
4796   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4797   vat_json_init_object (&node);
4798   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4799
4800   vat_json_print (vam->ofp, &node);
4801   vat_json_free (&node);
4802
4803   vam->retval = ntohl (mp->retval);
4804   vam->result_ready = 1;
4805 }
4806
4807 static void
4808 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4809 {
4810   vat_main_t *vam = &vat_main;
4811   i32 retval = ntohl (mp->retval);
4812
4813   if (0 <= retval)
4814     {
4815       print (vam->ofp, "%-20s%-16s",
4816              mp->status ? "enabled" : "disabled",
4817              mp->status ? (char *) mp->locator_set_name : "");
4818     }
4819
4820   vam->retval = retval;
4821   vam->result_ready = 1;
4822 }
4823
4824 static void
4825 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4826 {
4827   vat_main_t *vam = &vat_main;
4828   vat_json_node_t node;
4829   u8 *status = 0;
4830
4831   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4832   vec_add1 (status, 0);
4833
4834   vat_json_init_object (&node);
4835   vat_json_object_add_string_copy (&node, "status", status);
4836   if (mp->status)
4837     {
4838       vat_json_object_add_string_copy (&node, "locator_set",
4839                                        mp->locator_set_name);
4840     }
4841
4842   vec_free (status);
4843
4844   vat_json_print (vam->ofp, &node);
4845   vat_json_free (&node);
4846
4847   vam->retval = ntohl (mp->retval);
4848   vam->result_ready = 1;
4849 }
4850
4851 static u8 *
4852 format_policer_type (u8 * s, va_list * va)
4853 {
4854   u32 i = va_arg (*va, u32);
4855
4856   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4857     s = format (s, "1r2c");
4858   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4859     s = format (s, "1r3c");
4860   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4861     s = format (s, "2r3c-2698");
4862   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4863     s = format (s, "2r3c-4115");
4864   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4865     s = format (s, "2r3c-mef5cf1");
4866   else
4867     s = format (s, "ILLEGAL");
4868   return s;
4869 }
4870
4871 static u8 *
4872 format_policer_rate_type (u8 * s, va_list * va)
4873 {
4874   u32 i = va_arg (*va, u32);
4875
4876   if (i == SSE2_QOS_RATE_KBPS)
4877     s = format (s, "kbps");
4878   else if (i == SSE2_QOS_RATE_PPS)
4879     s = format (s, "pps");
4880   else
4881     s = format (s, "ILLEGAL");
4882   return s;
4883 }
4884
4885 static u8 *
4886 format_policer_round_type (u8 * s, va_list * va)
4887 {
4888   u32 i = va_arg (*va, u32);
4889
4890   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4891     s = format (s, "closest");
4892   else if (i == SSE2_QOS_ROUND_TO_UP)
4893     s = format (s, "up");
4894   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4895     s = format (s, "down");
4896   else
4897     s = format (s, "ILLEGAL");
4898   return s;
4899 }
4900
4901 static u8 *
4902 format_policer_action_type (u8 * s, va_list * va)
4903 {
4904   u32 i = va_arg (*va, u32);
4905
4906   if (i == SSE2_QOS_ACTION_DROP)
4907     s = format (s, "drop");
4908   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4909     s = format (s, "transmit");
4910   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4911     s = format (s, "mark-and-transmit");
4912   else
4913     s = format (s, "ILLEGAL");
4914   return s;
4915 }
4916
4917 static u8 *
4918 format_dscp (u8 * s, va_list * va)
4919 {
4920   u32 i = va_arg (*va, u32);
4921   char *t = 0;
4922
4923   switch (i)
4924     {
4925 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4926       foreach_vnet_dscp
4927 #undef _
4928     default:
4929       return format (s, "ILLEGAL");
4930     }
4931   s = format (s, "%s", t);
4932   return s;
4933 }
4934
4935 static void
4936 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4937 {
4938   vat_main_t *vam = &vat_main;
4939   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4940
4941   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4942     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4943   else
4944     conform_dscp_str = format (0, "");
4945
4946   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4947     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4948   else
4949     exceed_dscp_str = format (0, "");
4950
4951   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4952     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4953   else
4954     violate_dscp_str = format (0, "");
4955
4956   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4957          "rate type %U, round type %U, %s rate, %s color-aware, "
4958          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4959          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4960          "conform action %U%s, exceed action %U%s, violate action %U%s",
4961          mp->name,
4962          format_policer_type, mp->type,
4963          ntohl (mp->cir),
4964          ntohl (mp->eir),
4965          clib_net_to_host_u64 (mp->cb),
4966          clib_net_to_host_u64 (mp->eb),
4967          format_policer_rate_type, mp->rate_type,
4968          format_policer_round_type, mp->round_type,
4969          mp->single_rate ? "single" : "dual",
4970          mp->color_aware ? "is" : "not",
4971          ntohl (mp->cir_tokens_per_period),
4972          ntohl (mp->pir_tokens_per_period),
4973          ntohl (mp->scale),
4974          ntohl (mp->current_limit),
4975          ntohl (mp->current_bucket),
4976          ntohl (mp->extended_limit),
4977          ntohl (mp->extended_bucket),
4978          clib_net_to_host_u64 (mp->last_update_time),
4979          format_policer_action_type, mp->conform_action_type,
4980          conform_dscp_str,
4981          format_policer_action_type, mp->exceed_action_type,
4982          exceed_dscp_str,
4983          format_policer_action_type, mp->violate_action_type,
4984          violate_dscp_str);
4985
4986   vec_free (conform_dscp_str);
4987   vec_free (exceed_dscp_str);
4988   vec_free (violate_dscp_str);
4989 }
4990
4991 static void vl_api_policer_details_t_handler_json
4992   (vl_api_policer_details_t * mp)
4993 {
4994   vat_main_t *vam = &vat_main;
4995   vat_json_node_t *node;
4996   u8 *rate_type_str, *round_type_str, *type_str;
4997   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4998
4999   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
5000   round_type_str =
5001     format (0, "%U", format_policer_round_type, mp->round_type);
5002   type_str = format (0, "%U", format_policer_type, mp->type);
5003   conform_action_str = format (0, "%U", format_policer_action_type,
5004                                mp->conform_action_type);
5005   exceed_action_str = format (0, "%U", format_policer_action_type,
5006                               mp->exceed_action_type);
5007   violate_action_str = format (0, "%U", format_policer_action_type,
5008                                mp->violate_action_type);
5009
5010   if (VAT_JSON_ARRAY != vam->json_tree.type)
5011     {
5012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5013       vat_json_init_array (&vam->json_tree);
5014     }
5015   node = vat_json_array_add (&vam->json_tree);
5016
5017   vat_json_init_object (node);
5018   vat_json_object_add_string_copy (node, "name", mp->name);
5019   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
5020   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
5021   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
5022   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
5023   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
5024   vat_json_object_add_string_copy (node, "round_type", round_type_str);
5025   vat_json_object_add_string_copy (node, "type", type_str);
5026   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
5027   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
5028   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
5029   vat_json_object_add_uint (node, "cir_tokens_per_period",
5030                             ntohl (mp->cir_tokens_per_period));
5031   vat_json_object_add_uint (node, "eir_tokens_per_period",
5032                             ntohl (mp->pir_tokens_per_period));
5033   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
5034   vat_json_object_add_uint (node, "current_bucket",
5035                             ntohl (mp->current_bucket));
5036   vat_json_object_add_uint (node, "extended_limit",
5037                             ntohl (mp->extended_limit));
5038   vat_json_object_add_uint (node, "extended_bucket",
5039                             ntohl (mp->extended_bucket));
5040   vat_json_object_add_uint (node, "last_update_time",
5041                             ntohl (mp->last_update_time));
5042   vat_json_object_add_string_copy (node, "conform_action",
5043                                    conform_action_str);
5044   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5045     {
5046       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5047       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5048       vec_free (dscp_str);
5049     }
5050   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5051   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5052     {
5053       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5054       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5055       vec_free (dscp_str);
5056     }
5057   vat_json_object_add_string_copy (node, "violate_action",
5058                                    violate_action_str);
5059   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5060     {
5061       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5062       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5063       vec_free (dscp_str);
5064     }
5065
5066   vec_free (rate_type_str);
5067   vec_free (round_type_str);
5068   vec_free (type_str);
5069   vec_free (conform_action_str);
5070   vec_free (exceed_action_str);
5071   vec_free (violate_action_str);
5072 }
5073
5074 static void
5075 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5076                                            mp)
5077 {
5078   vat_main_t *vam = &vat_main;
5079   int i, count = ntohl (mp->count);
5080
5081   if (count > 0)
5082     print (vam->ofp, "classify table ids (%d) : ", count);
5083   for (i = 0; i < count; i++)
5084     {
5085       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5086       print (vam->ofp, (i < count - 1) ? "," : "");
5087     }
5088   vam->retval = ntohl (mp->retval);
5089   vam->result_ready = 1;
5090 }
5091
5092 static void
5093   vl_api_classify_table_ids_reply_t_handler_json
5094   (vl_api_classify_table_ids_reply_t * mp)
5095 {
5096   vat_main_t *vam = &vat_main;
5097   int i, count = ntohl (mp->count);
5098
5099   if (count > 0)
5100     {
5101       vat_json_node_t node;
5102
5103       vat_json_init_object (&node);
5104       for (i = 0; i < count; i++)
5105         {
5106           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5107         }
5108       vat_json_print (vam->ofp, &node);
5109       vat_json_free (&node);
5110     }
5111   vam->retval = ntohl (mp->retval);
5112   vam->result_ready = 1;
5113 }
5114
5115 static void
5116   vl_api_classify_table_by_interface_reply_t_handler
5117   (vl_api_classify_table_by_interface_reply_t * mp)
5118 {
5119   vat_main_t *vam = &vat_main;
5120   u32 table_id;
5121
5122   table_id = ntohl (mp->l2_table_id);
5123   if (table_id != ~0)
5124     print (vam->ofp, "l2 table id : %d", table_id);
5125   else
5126     print (vam->ofp, "l2 table id : No input ACL tables configured");
5127   table_id = ntohl (mp->ip4_table_id);
5128   if (table_id != ~0)
5129     print (vam->ofp, "ip4 table id : %d", table_id);
5130   else
5131     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5132   table_id = ntohl (mp->ip6_table_id);
5133   if (table_id != ~0)
5134     print (vam->ofp, "ip6 table id : %d", table_id);
5135   else
5136     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5137   vam->retval = ntohl (mp->retval);
5138   vam->result_ready = 1;
5139 }
5140
5141 static void
5142   vl_api_classify_table_by_interface_reply_t_handler_json
5143   (vl_api_classify_table_by_interface_reply_t * mp)
5144 {
5145   vat_main_t *vam = &vat_main;
5146   vat_json_node_t node;
5147
5148   vat_json_init_object (&node);
5149
5150   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5151   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5152   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5153
5154   vat_json_print (vam->ofp, &node);
5155   vat_json_free (&node);
5156
5157   vam->retval = ntohl (mp->retval);
5158   vam->result_ready = 1;
5159 }
5160
5161 static void vl_api_policer_add_del_reply_t_handler
5162   (vl_api_policer_add_del_reply_t * mp)
5163 {
5164   vat_main_t *vam = &vat_main;
5165   i32 retval = ntohl (mp->retval);
5166   if (vam->async_mode)
5167     {
5168       vam->async_errors += (retval < 0);
5169     }
5170   else
5171     {
5172       vam->retval = retval;
5173       vam->result_ready = 1;
5174       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5175         /*
5176          * Note: this is just barely thread-safe, depends on
5177          * the main thread spinning waiting for an answer...
5178          */
5179         errmsg ("policer index %d", ntohl (mp->policer_index));
5180     }
5181 }
5182
5183 static void vl_api_policer_add_del_reply_t_handler_json
5184   (vl_api_policer_add_del_reply_t * mp)
5185 {
5186   vat_main_t *vam = &vat_main;
5187   vat_json_node_t node;
5188
5189   vat_json_init_object (&node);
5190   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5191   vat_json_object_add_uint (&node, "policer_index",
5192                             ntohl (mp->policer_index));
5193
5194   vat_json_print (vam->ofp, &node);
5195   vat_json_free (&node);
5196
5197   vam->retval = ntohl (mp->retval);
5198   vam->result_ready = 1;
5199 }
5200
5201 /* Format hex dump. */
5202 u8 *
5203 format_hex_bytes (u8 * s, va_list * va)
5204 {
5205   u8 *bytes = va_arg (*va, u8 *);
5206   int n_bytes = va_arg (*va, int);
5207   uword i;
5208
5209   /* Print short or long form depending on byte count. */
5210   uword short_form = n_bytes <= 32;
5211   u32 indent = format_get_indent (s);
5212
5213   if (n_bytes == 0)
5214     return s;
5215
5216   for (i = 0; i < n_bytes; i++)
5217     {
5218       if (!short_form && (i % 32) == 0)
5219         s = format (s, "%08x: ", i);
5220       s = format (s, "%02x", bytes[i]);
5221       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5222         s = format (s, "\n%U", format_white_space, indent);
5223     }
5224
5225   return s;
5226 }
5227
5228 static void
5229 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5230                                             * mp)
5231 {
5232   vat_main_t *vam = &vat_main;
5233   i32 retval = ntohl (mp->retval);
5234   if (retval == 0)
5235     {
5236       print (vam->ofp, "classify table info :");
5237       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5238              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5239              ntohl (mp->miss_next_index));
5240       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5241              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5242              ntohl (mp->match_n_vectors));
5243       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5244              ntohl (mp->mask_length));
5245     }
5246   vam->retval = retval;
5247   vam->result_ready = 1;
5248 }
5249
5250 static void
5251   vl_api_classify_table_info_reply_t_handler_json
5252   (vl_api_classify_table_info_reply_t * mp)
5253 {
5254   vat_main_t *vam = &vat_main;
5255   vat_json_node_t node;
5256
5257   i32 retval = ntohl (mp->retval);
5258   if (retval == 0)
5259     {
5260       vat_json_init_object (&node);
5261
5262       vat_json_object_add_int (&node, "sessions",
5263                                ntohl (mp->active_sessions));
5264       vat_json_object_add_int (&node, "nexttbl",
5265                                ntohl (mp->next_table_index));
5266       vat_json_object_add_int (&node, "nextnode",
5267                                ntohl (mp->miss_next_index));
5268       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5269       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5270       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5271       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5272                       ntohl (mp->mask_length), 0);
5273       vat_json_object_add_string_copy (&node, "mask", s);
5274
5275       vat_json_print (vam->ofp, &node);
5276       vat_json_free (&node);
5277     }
5278   vam->retval = ntohl (mp->retval);
5279   vam->result_ready = 1;
5280 }
5281
5282 static void
5283 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5284                                            mp)
5285 {
5286   vat_main_t *vam = &vat_main;
5287
5288   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5289          ntohl (mp->hit_next_index), ntohl (mp->advance),
5290          ntohl (mp->opaque_index));
5291   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5292          ntohl (mp->match_length));
5293 }
5294
5295 static void
5296   vl_api_classify_session_details_t_handler_json
5297   (vl_api_classify_session_details_t * mp)
5298 {
5299   vat_main_t *vam = &vat_main;
5300   vat_json_node_t *node = NULL;
5301
5302   if (VAT_JSON_ARRAY != vam->json_tree.type)
5303     {
5304       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5305       vat_json_init_array (&vam->json_tree);
5306     }
5307   node = vat_json_array_add (&vam->json_tree);
5308
5309   vat_json_init_object (node);
5310   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5311   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5312   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5313   u8 *s =
5314     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5315             0);
5316   vat_json_object_add_string_copy (node, "match", s);
5317 }
5318
5319 static void vl_api_pg_create_interface_reply_t_handler
5320   (vl_api_pg_create_interface_reply_t * mp)
5321 {
5322   vat_main_t *vam = &vat_main;
5323
5324   vam->retval = ntohl (mp->retval);
5325   vam->result_ready = 1;
5326 }
5327
5328 static void vl_api_pg_create_interface_reply_t_handler_json
5329   (vl_api_pg_create_interface_reply_t * mp)
5330 {
5331   vat_main_t *vam = &vat_main;
5332   vat_json_node_t node;
5333
5334   i32 retval = ntohl (mp->retval);
5335   if (retval == 0)
5336     {
5337       vat_json_init_object (&node);
5338
5339       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5340
5341       vat_json_print (vam->ofp, &node);
5342       vat_json_free (&node);
5343     }
5344   vam->retval = ntohl (mp->retval);
5345   vam->result_ready = 1;
5346 }
5347
5348 static void vl_api_policer_classify_details_t_handler
5349   (vl_api_policer_classify_details_t * mp)
5350 {
5351   vat_main_t *vam = &vat_main;
5352
5353   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5354          ntohl (mp->table_index));
5355 }
5356
5357 static void vl_api_policer_classify_details_t_handler_json
5358   (vl_api_policer_classify_details_t * mp)
5359 {
5360   vat_main_t *vam = &vat_main;
5361   vat_json_node_t *node;
5362
5363   if (VAT_JSON_ARRAY != vam->json_tree.type)
5364     {
5365       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5366       vat_json_init_array (&vam->json_tree);
5367     }
5368   node = vat_json_array_add (&vam->json_tree);
5369
5370   vat_json_init_object (node);
5371   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5372   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5373 }
5374
5375 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5376   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5377 {
5378   vat_main_t *vam = &vat_main;
5379   i32 retval = ntohl (mp->retval);
5380   if (vam->async_mode)
5381     {
5382       vam->async_errors += (retval < 0);
5383     }
5384   else
5385     {
5386       vam->retval = retval;
5387       vam->sw_if_index = ntohl (mp->sw_if_index);
5388       vam->result_ready = 1;
5389     }
5390   vam->regenerate_interface_table = 1;
5391 }
5392
5393 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5394   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5395 {
5396   vat_main_t *vam = &vat_main;
5397   vat_json_node_t node;
5398
5399   vat_json_init_object (&node);
5400   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5401   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5402
5403   vat_json_print (vam->ofp, &node);
5404   vat_json_free (&node);
5405
5406   vam->retval = ntohl (mp->retval);
5407   vam->result_ready = 1;
5408 }
5409
5410 static void vl_api_flow_classify_details_t_handler
5411   (vl_api_flow_classify_details_t * mp)
5412 {
5413   vat_main_t *vam = &vat_main;
5414
5415   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5416          ntohl (mp->table_index));
5417 }
5418
5419 static void vl_api_flow_classify_details_t_handler_json
5420   (vl_api_flow_classify_details_t * mp)
5421 {
5422   vat_main_t *vam = &vat_main;
5423   vat_json_node_t *node;
5424
5425   if (VAT_JSON_ARRAY != vam->json_tree.type)
5426     {
5427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5428       vat_json_init_array (&vam->json_tree);
5429     }
5430   node = vat_json_array_add (&vam->json_tree);
5431
5432   vat_json_init_object (node);
5433   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5434   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5435 }
5436
5437 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5438 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5439 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5440 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5441 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5442 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5443 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5444 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5445 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5446 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5447 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5448 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5449 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5450 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5451 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5452 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5453 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5454 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5455 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5456 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5457 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5458 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5459
5460 /*
5461  * Generate boilerplate reply handlers, which
5462  * dig the return value out of the xxx_reply_t API message,
5463  * stick it into vam->retval, and set vam->result_ready
5464  *
5465  * Could also do this by pointing N message decode slots at
5466  * a single function, but that could break in subtle ways.
5467  */
5468
5469 #define foreach_standard_reply_retval_handler           \
5470 _(sw_interface_set_flags_reply)                         \
5471 _(sw_interface_add_del_address_reply)                   \
5472 _(sw_interface_set_rx_mode_reply)                       \
5473 _(sw_interface_set_rx_placement_reply)                  \
5474 _(sw_interface_set_table_reply)                         \
5475 _(sw_interface_set_mpls_enable_reply)                   \
5476 _(sw_interface_set_vpath_reply)                         \
5477 _(sw_interface_set_vxlan_bypass_reply)                  \
5478 _(sw_interface_set_geneve_bypass_reply)                 \
5479 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5480 _(sw_interface_set_l2_bridge_reply)                     \
5481 _(bridge_domain_add_del_reply)                          \
5482 _(sw_interface_set_l2_xconnect_reply)                   \
5483 _(l2fib_add_del_reply)                                  \
5484 _(l2fib_flush_int_reply)                                \
5485 _(l2fib_flush_bd_reply)                                 \
5486 _(ip_add_del_route_reply)                               \
5487 _(ip_table_add_del_reply)                               \
5488 _(ip_mroute_add_del_reply)                              \
5489 _(mpls_route_add_del_reply)                             \
5490 _(mpls_table_add_del_reply)                             \
5491 _(mpls_ip_bind_unbind_reply)                            \
5492 _(bier_route_add_del_reply)                             \
5493 _(bier_table_add_del_reply)                             \
5494 _(proxy_arp_add_del_reply)                              \
5495 _(proxy_arp_intfc_enable_disable_reply)                 \
5496 _(sw_interface_set_unnumbered_reply)                    \
5497 _(ip_neighbor_add_del_reply)                            \
5498 _(oam_add_del_reply)                                    \
5499 _(reset_fib_reply)                                      \
5500 _(dhcp_proxy_config_reply)                              \
5501 _(dhcp_proxy_set_vss_reply)                             \
5502 _(dhcp_client_config_reply)                             \
5503 _(set_ip_flow_hash_reply)                               \
5504 _(sw_interface_ip6_enable_disable_reply)                \
5505 _(ip6nd_proxy_add_del_reply)                            \
5506 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5507 _(sw_interface_ip6nd_ra_config_reply)                   \
5508 _(set_arp_neighbor_limit_reply)                         \
5509 _(l2_patch_add_del_reply)                               \
5510 _(sr_mpls_policy_add_reply)                             \
5511 _(sr_mpls_policy_mod_reply)                             \
5512 _(sr_mpls_policy_del_reply)                             \
5513 _(sr_policy_add_reply)                                  \
5514 _(sr_policy_mod_reply)                                  \
5515 _(sr_policy_del_reply)                                  \
5516 _(sr_localsid_add_del_reply)                            \
5517 _(sr_steering_add_del_reply)                            \
5518 _(classify_add_del_session_reply)                       \
5519 _(classify_set_interface_ip_table_reply)                \
5520 _(classify_set_interface_l2_tables_reply)               \
5521 _(l2tpv3_set_tunnel_cookies_reply)                      \
5522 _(l2tpv3_interface_enable_disable_reply)                \
5523 _(l2tpv3_set_lookup_key_reply)                          \
5524 _(l2_fib_clear_table_reply)                             \
5525 _(l2_interface_efp_filter_reply)                        \
5526 _(l2_interface_vlan_tag_rewrite_reply)                  \
5527 _(modify_vhost_user_if_reply)                           \
5528 _(delete_vhost_user_if_reply)                           \
5529 _(ip_probe_neighbor_reply)                              \
5530 _(ip_scan_neighbor_enable_disable_reply)                \
5531 _(want_ip4_arp_events_reply)                            \
5532 _(want_ip6_nd_events_reply)                             \
5533 _(want_l2_macs_events_reply)                            \
5534 _(input_acl_set_interface_reply)                        \
5535 _(ipsec_spd_add_del_reply)                              \
5536 _(ipsec_interface_add_del_spd_reply)                    \
5537 _(ipsec_spd_add_del_entry_reply)                        \
5538 _(ipsec_sad_add_del_entry_reply)                        \
5539 _(ipsec_sa_set_key_reply)                               \
5540 _(ipsec_tunnel_if_add_del_reply)                        \
5541 _(ipsec_tunnel_if_set_key_reply)                        \
5542 _(ipsec_tunnel_if_set_sa_reply)                         \
5543 _(ikev2_profile_add_del_reply)                          \
5544 _(ikev2_profile_set_auth_reply)                         \
5545 _(ikev2_profile_set_id_reply)                           \
5546 _(ikev2_profile_set_ts_reply)                           \
5547 _(ikev2_set_local_key_reply)                            \
5548 _(ikev2_set_responder_reply)                            \
5549 _(ikev2_set_ike_transforms_reply)                       \
5550 _(ikev2_set_esp_transforms_reply)                       \
5551 _(ikev2_set_sa_lifetime_reply)                          \
5552 _(ikev2_initiate_sa_init_reply)                         \
5553 _(ikev2_initiate_del_ike_sa_reply)                      \
5554 _(ikev2_initiate_del_child_sa_reply)                    \
5555 _(ikev2_initiate_rekey_child_sa_reply)                  \
5556 _(delete_loopback_reply)                                \
5557 _(bd_ip_mac_add_del_reply)                              \
5558 _(want_interface_events_reply)                          \
5559 _(want_stats_reply)                                     \
5560 _(cop_interface_enable_disable_reply)                   \
5561 _(cop_whitelist_enable_disable_reply)                   \
5562 _(sw_interface_clear_stats_reply)                       \
5563 _(ioam_enable_reply)                                    \
5564 _(ioam_disable_reply)                                   \
5565 _(one_add_del_locator_reply)                            \
5566 _(one_add_del_local_eid_reply)                          \
5567 _(one_add_del_remote_mapping_reply)                     \
5568 _(one_add_del_adjacency_reply)                          \
5569 _(one_add_del_map_resolver_reply)                       \
5570 _(one_add_del_map_server_reply)                         \
5571 _(one_enable_disable_reply)                             \
5572 _(one_rloc_probe_enable_disable_reply)                  \
5573 _(one_map_register_enable_disable_reply)                \
5574 _(one_map_register_set_ttl_reply)                       \
5575 _(one_set_transport_protocol_reply)                     \
5576 _(one_map_register_fallback_threshold_reply)            \
5577 _(one_pitr_set_locator_set_reply)                       \
5578 _(one_map_request_mode_reply)                           \
5579 _(one_add_del_map_request_itr_rlocs_reply)              \
5580 _(one_eid_table_add_del_map_reply)                      \
5581 _(one_use_petr_reply)                                   \
5582 _(one_stats_enable_disable_reply)                       \
5583 _(one_add_del_l2_arp_entry_reply)                       \
5584 _(one_add_del_ndp_entry_reply)                          \
5585 _(one_stats_flush_reply)                                \
5586 _(one_enable_disable_xtr_mode_reply)                    \
5587 _(one_enable_disable_pitr_mode_reply)                   \
5588 _(one_enable_disable_petr_mode_reply)                   \
5589 _(gpe_enable_disable_reply)                             \
5590 _(gpe_set_encap_mode_reply)                             \
5591 _(gpe_add_del_iface_reply)                              \
5592 _(gpe_add_del_native_fwd_rpath_reply)                   \
5593 _(af_packet_delete_reply)                               \
5594 _(policer_classify_set_interface_reply)                 \
5595 _(netmap_create_reply)                                  \
5596 _(netmap_delete_reply)                                  \
5597 _(set_ipfix_exporter_reply)                             \
5598 _(set_ipfix_classify_stream_reply)                      \
5599 _(ipfix_classify_table_add_del_reply)                   \
5600 _(flow_classify_set_interface_reply)                    \
5601 _(sw_interface_span_enable_disable_reply)               \
5602 _(pg_capture_reply)                                     \
5603 _(pg_enable_disable_reply)                              \
5604 _(ip_source_and_port_range_check_add_del_reply)         \
5605 _(ip_source_and_port_range_check_interface_add_del_reply)\
5606 _(delete_subif_reply)                                   \
5607 _(l2_interface_pbb_tag_rewrite_reply)                   \
5608 _(set_punt_reply)                                       \
5609 _(feature_enable_disable_reply)                         \
5610 _(sw_interface_tag_add_del_reply)                       \
5611 _(hw_interface_set_mtu_reply)                           \
5612 _(p2p_ethernet_add_reply)                               \
5613 _(p2p_ethernet_del_reply)                               \
5614 _(lldp_config_reply)                                    \
5615 _(sw_interface_set_lldp_reply)                          \
5616 _(tcp_configure_src_addresses_reply)                    \
5617 _(dns_enable_disable_reply)                             \
5618 _(dns_name_server_add_del_reply)                        \
5619 _(session_rule_add_del_reply)                           \
5620 _(ip_container_proxy_add_del_reply)                     \
5621 _(output_acl_set_interface_reply)                       \
5622 _(qos_record_enable_disable_reply)
5623
5624 #define _(n)                                    \
5625     static void vl_api_##n##_t_handler          \
5626     (vl_api_##n##_t * mp)                       \
5627     {                                           \
5628         vat_main_t * vam = &vat_main;           \
5629         i32 retval = ntohl(mp->retval);         \
5630         if (vam->async_mode) {                  \
5631             vam->async_errors += (retval < 0);  \
5632         } else {                                \
5633             vam->retval = retval;               \
5634             vam->result_ready = 1;              \
5635         }                                       \
5636     }
5637 foreach_standard_reply_retval_handler;
5638 #undef _
5639
5640 #define _(n)                                    \
5641     static void vl_api_##n##_t_handler_json     \
5642     (vl_api_##n##_t * mp)                       \
5643     {                                           \
5644         vat_main_t * vam = &vat_main;           \
5645         vat_json_node_t node;                   \
5646         vat_json_init_object(&node);            \
5647         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5648         vat_json_print(vam->ofp, &node);        \
5649         vam->retval = ntohl(mp->retval);        \
5650         vam->result_ready = 1;                  \
5651     }
5652 foreach_standard_reply_retval_handler;
5653 #undef _
5654
5655 /*
5656  * Table of message reply handlers, must include boilerplate handlers
5657  * we just generated
5658  */
5659
5660 #define foreach_vpe_api_reply_msg                                       \
5661 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5662 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5663 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5664 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5665 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5666 _(CLI_REPLY, cli_reply)                                                 \
5667 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5668 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5669   sw_interface_add_del_address_reply)                                   \
5670 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5671 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5672 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5673 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5674 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5675 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5676 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5677 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5678 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5679 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5680   sw_interface_set_l2_xconnect_reply)                                   \
5681 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5682   sw_interface_set_l2_bridge_reply)                                     \
5683 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5684 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5685 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5686 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5687 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5688 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5689 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5690 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5691 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5692 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5693 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5694 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5695 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5696 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5697 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5698 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5699 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5700 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5701 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5702 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5703 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5704 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5705 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5706 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5707 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5708 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5709 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5710 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5711 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5712 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5713 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5714   proxy_arp_intfc_enable_disable_reply)                                 \
5715 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5716 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5717   sw_interface_set_unnumbered_reply)                                    \
5718 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5719 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5720 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5721 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5722 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5723 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5724 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5725 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5726 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5727 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5728 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5729   sw_interface_ip6_enable_disable_reply)                                \
5730 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5731 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5732 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5733   sw_interface_ip6nd_ra_prefix_reply)                                   \
5734 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5735   sw_interface_ip6nd_ra_config_reply)                                   \
5736 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5737 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5738 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5739 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5740 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5741 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5742 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5743 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5744 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5745 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5746 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5747 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5748 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5749 classify_set_interface_ip_table_reply)                                  \
5750 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5751   classify_set_interface_l2_tables_reply)                               \
5752 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5753 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5754 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5755 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5756 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5757   l2tpv3_interface_enable_disable_reply)                                \
5758 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5759 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5760 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5761 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5762 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5763 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5764 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5765 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5766 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5767 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5768 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5769 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5770 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5771 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5772 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5773 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5774 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5775 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5776 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5777 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5778 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5779 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5780 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5781 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5782 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5783 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5784 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5785 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5786 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5787 _(L2_MACS_EVENT, l2_macs_event)                                         \
5788 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5789 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5790 _(IP_DETAILS, ip_details)                                               \
5791 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5792 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5793 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5794 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5795 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5796 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5797 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5798 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5799 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5800 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5801 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5802 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5803 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5804 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5805 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5806 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5807 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5808 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5809 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5810 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5811 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5812 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5813 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5814 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5815 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5816 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5817 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5818 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5819 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5820 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5821 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5822 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5823 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5824 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5825 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5826 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5827 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5828 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5829 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5830 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5831 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5832 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5833 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5834 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5835   one_map_register_enable_disable_reply)                                \
5836 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5837 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5838 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5839 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5840   one_map_register_fallback_threshold_reply)                            \
5841 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5842   one_rloc_probe_enable_disable_reply)                                  \
5843 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5844 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5845 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5846 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5847 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5848 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5849 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5850 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5851 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5852 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5853 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5854 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5855 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5856 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5857 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5858 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5859   show_one_stats_enable_disable_reply)                                  \
5860 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5861 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5862 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5863 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5864 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5865 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5866 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5867 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5868   one_enable_disable_pitr_mode_reply)                                   \
5869 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5870   one_enable_disable_petr_mode_reply)                                   \
5871 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5872 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5873 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5874 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5875 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5876 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5877 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5878 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5879 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5880 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5881 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5882 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5883   gpe_add_del_native_fwd_rpath_reply)                                   \
5884 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5885   gpe_fwd_entry_path_details)                                           \
5886 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5887 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5888   one_add_del_map_request_itr_rlocs_reply)                              \
5889 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5890   one_get_map_request_itr_rlocs_reply)                                  \
5891 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5892 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5893 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5894 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5895 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5896 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5897   show_one_map_register_state_reply)                                    \
5898 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5899 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5900   show_one_map_register_fallback_threshold_reply)                       \
5901 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5902 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5903 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5904 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5905 _(POLICER_DETAILS, policer_details)                                     \
5906 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5907 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5908 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5909 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5910 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5911 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5912 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5913 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5914 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5915 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5916 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5917 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5918 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5919 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5920 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5921 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5922 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5923 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5924 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5925 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5926 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5927 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5928 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5929 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5930 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5931  ip_source_and_port_range_check_add_del_reply)                          \
5932 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5933  ip_source_and_port_range_check_interface_add_del_reply)                \
5934 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5935 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5936 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5937 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5938 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5939 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5940 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5941 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5942 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5943 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5944 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5945 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5946 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5947 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5948 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5949 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5950 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5951 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5952 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5953 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5954 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5955 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5956 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5957 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5958 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5959 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5960 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5961 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5962
5963 #define foreach_standalone_reply_msg                                    \
5964 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5965 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5966 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5967 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5968 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5969 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5970 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5971
5972 typedef struct
5973 {
5974   u8 *name;
5975   u32 value;
5976 } name_sort_t;
5977
5978 #define STR_VTR_OP_CASE(op)     \
5979     case L2_VTR_ ## op:         \
5980         return "" # op;
5981
5982 static const char *
5983 str_vtr_op (u32 vtr_op)
5984 {
5985   switch (vtr_op)
5986     {
5987       STR_VTR_OP_CASE (DISABLED);
5988       STR_VTR_OP_CASE (PUSH_1);
5989       STR_VTR_OP_CASE (PUSH_2);
5990       STR_VTR_OP_CASE (POP_1);
5991       STR_VTR_OP_CASE (POP_2);
5992       STR_VTR_OP_CASE (TRANSLATE_1_1);
5993       STR_VTR_OP_CASE (TRANSLATE_1_2);
5994       STR_VTR_OP_CASE (TRANSLATE_2_1);
5995       STR_VTR_OP_CASE (TRANSLATE_2_2);
5996     }
5997
5998   return "UNKNOWN";
5999 }
6000
6001 static int
6002 dump_sub_interface_table (vat_main_t * vam)
6003 {
6004   const sw_interface_subif_t *sub = NULL;
6005
6006   if (vam->json_output)
6007     {
6008       clib_warning
6009         ("JSON output supported only for VPE API calls and dump_stats_table");
6010       return -99;
6011     }
6012
6013   print (vam->ofp,
6014          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
6015          "Interface", "sw_if_index",
6016          "sub id", "dot1ad", "tags", "outer id",
6017          "inner id", "exact", "default", "outer any", "inner any");
6018
6019   vec_foreach (sub, vam->sw_if_subif_table)
6020   {
6021     print (vam->ofp,
6022            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
6023            sub->interface_name,
6024            sub->sw_if_index,
6025            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
6026            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
6027            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
6028            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
6029     if (sub->vtr_op != L2_VTR_DISABLED)
6030       {
6031         print (vam->ofp,
6032                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6033                "tag1: %d tag2: %d ]",
6034                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6035                sub->vtr_tag1, sub->vtr_tag2);
6036       }
6037   }
6038
6039   return 0;
6040 }
6041
6042 static int
6043 name_sort_cmp (void *a1, void *a2)
6044 {
6045   name_sort_t *n1 = a1;
6046   name_sort_t *n2 = a2;
6047
6048   return strcmp ((char *) n1->name, (char *) n2->name);
6049 }
6050
6051 static int
6052 dump_interface_table (vat_main_t * vam)
6053 {
6054   hash_pair_t *p;
6055   name_sort_t *nses = 0, *ns;
6056
6057   if (vam->json_output)
6058     {
6059       clib_warning
6060         ("JSON output supported only for VPE API calls and dump_stats_table");
6061       return -99;
6062     }
6063
6064   /* *INDENT-OFF* */
6065   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6066   ({
6067     vec_add2 (nses, ns, 1);
6068     ns->name = (u8 *)(p->key);
6069     ns->value = (u32) p->value[0];
6070   }));
6071   /* *INDENT-ON* */
6072
6073   vec_sort_with_function (nses, name_sort_cmp);
6074
6075   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6076   vec_foreach (ns, nses)
6077   {
6078     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6079   }
6080   vec_free (nses);
6081   return 0;
6082 }
6083
6084 static int
6085 dump_ip_table (vat_main_t * vam, int is_ipv6)
6086 {
6087   const ip_details_t *det = NULL;
6088   const ip_address_details_t *address = NULL;
6089   u32 i = ~0;
6090
6091   print (vam->ofp, "%-12s", "sw_if_index");
6092
6093   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6094   {
6095     i++;
6096     if (!det->present)
6097       {
6098         continue;
6099       }
6100     print (vam->ofp, "%-12d", i);
6101     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6102     if (!det->addr)
6103       {
6104         continue;
6105       }
6106     vec_foreach (address, det->addr)
6107     {
6108       print (vam->ofp,
6109              "            %-30U%-13d",
6110              is_ipv6 ? format_ip6_address : format_ip4_address,
6111              address->ip, address->prefix_length);
6112     }
6113   }
6114
6115   return 0;
6116 }
6117
6118 static int
6119 dump_ipv4_table (vat_main_t * vam)
6120 {
6121   if (vam->json_output)
6122     {
6123       clib_warning
6124         ("JSON output supported only for VPE API calls and dump_stats_table");
6125       return -99;
6126     }
6127
6128   return dump_ip_table (vam, 0);
6129 }
6130
6131 static int
6132 dump_ipv6_table (vat_main_t * vam)
6133 {
6134   if (vam->json_output)
6135     {
6136       clib_warning
6137         ("JSON output supported only for VPE API calls and dump_stats_table");
6138       return -99;
6139     }
6140
6141   return dump_ip_table (vam, 1);
6142 }
6143
6144 static char *
6145 counter_type_to_str (u8 counter_type, u8 is_combined)
6146 {
6147   if (!is_combined)
6148     {
6149       switch (counter_type)
6150         {
6151         case VNET_INTERFACE_COUNTER_DROP:
6152           return "drop";
6153         case VNET_INTERFACE_COUNTER_PUNT:
6154           return "punt";
6155         case VNET_INTERFACE_COUNTER_IP4:
6156           return "ip4";
6157         case VNET_INTERFACE_COUNTER_IP6:
6158           return "ip6";
6159         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6160           return "rx-no-buf";
6161         case VNET_INTERFACE_COUNTER_RX_MISS:
6162           return "rx-miss";
6163         case VNET_INTERFACE_COUNTER_RX_ERROR:
6164           return "rx-error";
6165         case VNET_INTERFACE_COUNTER_TX_ERROR:
6166           return "tx-error";
6167         default:
6168           return "INVALID-COUNTER-TYPE";
6169         }
6170     }
6171   else
6172     {
6173       switch (counter_type)
6174         {
6175         case VNET_INTERFACE_COUNTER_RX:
6176           return "rx";
6177         case VNET_INTERFACE_COUNTER_TX:
6178           return "tx";
6179         default:
6180           return "INVALID-COUNTER-TYPE";
6181         }
6182     }
6183 }
6184
6185 static int
6186 dump_stats_table (vat_main_t * vam)
6187 {
6188   vat_json_node_t node;
6189   vat_json_node_t *msg_array;
6190   vat_json_node_t *msg;
6191   vat_json_node_t *counter_array;
6192   vat_json_node_t *counter;
6193   interface_counter_t c;
6194   u64 packets;
6195   ip4_fib_counter_t *c4;
6196   ip6_fib_counter_t *c6;
6197   ip4_nbr_counter_t *n4;
6198   ip6_nbr_counter_t *n6;
6199   int i, j;
6200
6201   if (!vam->json_output)
6202     {
6203       clib_warning ("dump_stats_table supported only in JSON format");
6204       return -99;
6205     }
6206
6207   vat_json_init_object (&node);
6208
6209   /* interface counters */
6210   msg_array = vat_json_object_add (&node, "interface_counters");
6211   vat_json_init_array (msg_array);
6212   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6213     {
6214       msg = vat_json_array_add (msg_array);
6215       vat_json_init_object (msg);
6216       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6217                                        (u8 *) counter_type_to_str (i, 0));
6218       vat_json_object_add_int (msg, "is_combined", 0);
6219       counter_array = vat_json_object_add (msg, "data");
6220       vat_json_init_array (counter_array);
6221       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6222         {
6223           packets = vam->simple_interface_counters[i][j];
6224           vat_json_array_add_uint (counter_array, packets);
6225         }
6226     }
6227   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6228     {
6229       msg = vat_json_array_add (msg_array);
6230       vat_json_init_object (msg);
6231       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6232                                        (u8 *) counter_type_to_str (i, 1));
6233       vat_json_object_add_int (msg, "is_combined", 1);
6234       counter_array = vat_json_object_add (msg, "data");
6235       vat_json_init_array (counter_array);
6236       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6237         {
6238           c = vam->combined_interface_counters[i][j];
6239           counter = vat_json_array_add (counter_array);
6240           vat_json_init_object (counter);
6241           vat_json_object_add_uint (counter, "packets", c.packets);
6242           vat_json_object_add_uint (counter, "bytes", c.bytes);
6243         }
6244     }
6245
6246   /* ip4 fib counters */
6247   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6248   vat_json_init_array (msg_array);
6249   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6250     {
6251       msg = vat_json_array_add (msg_array);
6252       vat_json_init_object (msg);
6253       vat_json_object_add_uint (msg, "vrf_id",
6254                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6255       counter_array = vat_json_object_add (msg, "c");
6256       vat_json_init_array (counter_array);
6257       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6258         {
6259           counter = vat_json_array_add (counter_array);
6260           vat_json_init_object (counter);
6261           c4 = &vam->ip4_fib_counters[i][j];
6262           vat_json_object_add_ip4 (counter, "address", c4->address);
6263           vat_json_object_add_uint (counter, "address_length",
6264                                     c4->address_length);
6265           vat_json_object_add_uint (counter, "packets", c4->packets);
6266           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6267         }
6268     }
6269
6270   /* ip6 fib counters */
6271   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6272   vat_json_init_array (msg_array);
6273   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6274     {
6275       msg = vat_json_array_add (msg_array);
6276       vat_json_init_object (msg);
6277       vat_json_object_add_uint (msg, "vrf_id",
6278                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6279       counter_array = vat_json_object_add (msg, "c");
6280       vat_json_init_array (counter_array);
6281       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6282         {
6283           counter = vat_json_array_add (counter_array);
6284           vat_json_init_object (counter);
6285           c6 = &vam->ip6_fib_counters[i][j];
6286           vat_json_object_add_ip6 (counter, "address", c6->address);
6287           vat_json_object_add_uint (counter, "address_length",
6288                                     c6->address_length);
6289           vat_json_object_add_uint (counter, "packets", c6->packets);
6290           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6291         }
6292     }
6293
6294   /* ip4 nbr counters */
6295   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6296   vat_json_init_array (msg_array);
6297   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6298     {
6299       msg = vat_json_array_add (msg_array);
6300       vat_json_init_object (msg);
6301       vat_json_object_add_uint (msg, "sw_if_index", i);
6302       counter_array = vat_json_object_add (msg, "c");
6303       vat_json_init_array (counter_array);
6304       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6305         {
6306           counter = vat_json_array_add (counter_array);
6307           vat_json_init_object (counter);
6308           n4 = &vam->ip4_nbr_counters[i][j];
6309           vat_json_object_add_ip4 (counter, "address", n4->address);
6310           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6311           vat_json_object_add_uint (counter, "packets", n4->packets);
6312           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6313         }
6314     }
6315
6316   /* ip6 nbr counters */
6317   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6318   vat_json_init_array (msg_array);
6319   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6320     {
6321       msg = vat_json_array_add (msg_array);
6322       vat_json_init_object (msg);
6323       vat_json_object_add_uint (msg, "sw_if_index", i);
6324       counter_array = vat_json_object_add (msg, "c");
6325       vat_json_init_array (counter_array);
6326       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6327         {
6328           counter = vat_json_array_add (counter_array);
6329           vat_json_init_object (counter);
6330           n6 = &vam->ip6_nbr_counters[i][j];
6331           vat_json_object_add_ip6 (counter, "address", n6->address);
6332           vat_json_object_add_uint (counter, "packets", n6->packets);
6333           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6334         }
6335     }
6336
6337   vat_json_print (vam->ofp, &node);
6338   vat_json_free (&node);
6339
6340   return 0;
6341 }
6342
6343 /*
6344  * Pass CLI buffers directly in the CLI_INBAND API message,
6345  * instead of an additional shared memory area.
6346  */
6347 static int
6348 exec_inband (vat_main_t * vam)
6349 {
6350   vl_api_cli_inband_t *mp;
6351   unformat_input_t *i = vam->input;
6352   int ret;
6353
6354   if (vec_len (i->buffer) == 0)
6355     return -1;
6356
6357   if (vam->exec_mode == 0 && unformat (i, "mode"))
6358     {
6359       vam->exec_mode = 1;
6360       return 0;
6361     }
6362   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6363     {
6364       vam->exec_mode = 0;
6365       return 0;
6366     }
6367
6368   /*
6369    * In order for the CLI command to work, it
6370    * must be a vector ending in \n, not a C-string ending
6371    * in \n\0.
6372    */
6373   u32 len = vec_len (vam->input->buffer);
6374   M2 (CLI_INBAND, mp, len);
6375   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
6376
6377   S (mp);
6378   W (ret);
6379   /* json responses may or may not include a useful reply... */
6380   if (vec_len (vam->cmd_reply))
6381     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6382   return ret;
6383 }
6384
6385 int
6386 exec (vat_main_t * vam)
6387 {
6388   return exec_inband (vam);
6389 }
6390
6391 static int
6392 api_create_loopback (vat_main_t * vam)
6393 {
6394   unformat_input_t *i = vam->input;
6395   vl_api_create_loopback_t *mp;
6396   vl_api_create_loopback_instance_t *mp_lbi;
6397   u8 mac_address[6];
6398   u8 mac_set = 0;
6399   u8 is_specified = 0;
6400   u32 user_instance = 0;
6401   int ret;
6402
6403   clib_memset (mac_address, 0, sizeof (mac_address));
6404
6405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6406     {
6407       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6408         mac_set = 1;
6409       if (unformat (i, "instance %d", &user_instance))
6410         is_specified = 1;
6411       else
6412         break;
6413     }
6414
6415   if (is_specified)
6416     {
6417       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6418       mp_lbi->is_specified = is_specified;
6419       if (is_specified)
6420         mp_lbi->user_instance = htonl (user_instance);
6421       if (mac_set)
6422         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6423       S (mp_lbi);
6424     }
6425   else
6426     {
6427       /* Construct the API message */
6428       M (CREATE_LOOPBACK, mp);
6429       if (mac_set)
6430         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6431       S (mp);
6432     }
6433
6434   W (ret);
6435   return ret;
6436 }
6437
6438 static int
6439 api_delete_loopback (vat_main_t * vam)
6440 {
6441   unformat_input_t *i = vam->input;
6442   vl_api_delete_loopback_t *mp;
6443   u32 sw_if_index = ~0;
6444   int ret;
6445
6446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6447     {
6448       if (unformat (i, "sw_if_index %d", &sw_if_index))
6449         ;
6450       else
6451         break;
6452     }
6453
6454   if (sw_if_index == ~0)
6455     {
6456       errmsg ("missing sw_if_index");
6457       return -99;
6458     }
6459
6460   /* Construct the API message */
6461   M (DELETE_LOOPBACK, mp);
6462   mp->sw_if_index = ntohl (sw_if_index);
6463
6464   S (mp);
6465   W (ret);
6466   return ret;
6467 }
6468
6469 static int
6470 api_want_stats (vat_main_t * vam)
6471 {
6472   unformat_input_t *i = vam->input;
6473   vl_api_want_stats_t *mp;
6474   int enable = -1;
6475   int ret;
6476
6477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6478     {
6479       if (unformat (i, "enable"))
6480         enable = 1;
6481       else if (unformat (i, "disable"))
6482         enable = 0;
6483       else
6484         break;
6485     }
6486
6487   if (enable == -1)
6488     {
6489       errmsg ("missing enable|disable");
6490       return -99;
6491     }
6492
6493   M (WANT_STATS, mp);
6494   mp->enable_disable = enable;
6495
6496   S (mp);
6497   W (ret);
6498   return ret;
6499 }
6500
6501 static int
6502 api_want_interface_events (vat_main_t * vam)
6503 {
6504   unformat_input_t *i = vam->input;
6505   vl_api_want_interface_events_t *mp;
6506   int enable = -1;
6507   int ret;
6508
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "enable"))
6512         enable = 1;
6513       else if (unformat (i, "disable"))
6514         enable = 0;
6515       else
6516         break;
6517     }
6518
6519   if (enable == -1)
6520     {
6521       errmsg ("missing enable|disable");
6522       return -99;
6523     }
6524
6525   M (WANT_INTERFACE_EVENTS, mp);
6526   mp->enable_disable = enable;
6527
6528   vam->interface_event_display = enable;
6529
6530   S (mp);
6531   W (ret);
6532   return ret;
6533 }
6534
6535
6536 /* Note: non-static, called once to set up the initial intfc table */
6537 int
6538 api_sw_interface_dump (vat_main_t * vam)
6539 {
6540   vl_api_sw_interface_dump_t *mp;
6541   vl_api_control_ping_t *mp_ping;
6542   hash_pair_t *p;
6543   name_sort_t *nses = 0, *ns;
6544   sw_interface_subif_t *sub = NULL;
6545   int ret;
6546
6547   /* Toss the old name table */
6548   /* *INDENT-OFF* */
6549   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6550   ({
6551     vec_add2 (nses, ns, 1);
6552     ns->name = (u8 *)(p->key);
6553     ns->value = (u32) p->value[0];
6554   }));
6555   /* *INDENT-ON* */
6556
6557   hash_free (vam->sw_if_index_by_interface_name);
6558
6559   vec_foreach (ns, nses) vec_free (ns->name);
6560
6561   vec_free (nses);
6562
6563   vec_foreach (sub, vam->sw_if_subif_table)
6564   {
6565     vec_free (sub->interface_name);
6566   }
6567   vec_free (vam->sw_if_subif_table);
6568
6569   /* recreate the interface name hash table */
6570   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6571
6572   /*
6573    * Ask for all interface names. Otherwise, the epic catalog of
6574    * name filters becomes ridiculously long, and vat ends up needing
6575    * to be taught about new interface types.
6576    */
6577   M (SW_INTERFACE_DUMP, mp);
6578   S (mp);
6579
6580   /* Use a control ping for synchronization */
6581   MPING (CONTROL_PING, mp_ping);
6582   S (mp_ping);
6583
6584   W (ret);
6585   return ret;
6586 }
6587
6588 static int
6589 api_sw_interface_set_flags (vat_main_t * vam)
6590 {
6591   unformat_input_t *i = vam->input;
6592   vl_api_sw_interface_set_flags_t *mp;
6593   u32 sw_if_index;
6594   u8 sw_if_index_set = 0;
6595   u8 admin_up = 0;
6596   int ret;
6597
6598   /* Parse args required to build the message */
6599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6600     {
6601       if (unformat (i, "admin-up"))
6602         admin_up = 1;
6603       else if (unformat (i, "admin-down"))
6604         admin_up = 0;
6605       else
6606         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6607         sw_if_index_set = 1;
6608       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6609         sw_if_index_set = 1;
6610       else
6611         break;
6612     }
6613
6614   if (sw_if_index_set == 0)
6615     {
6616       errmsg ("missing interface name or sw_if_index");
6617       return -99;
6618     }
6619
6620   /* Construct the API message */
6621   M (SW_INTERFACE_SET_FLAGS, mp);
6622   mp->sw_if_index = ntohl (sw_if_index);
6623   mp->admin_up_down = admin_up;
6624
6625   /* send it... */
6626   S (mp);
6627
6628   /* Wait for a reply, return the good/bad news... */
6629   W (ret);
6630   return ret;
6631 }
6632
6633 static int
6634 api_sw_interface_set_rx_mode (vat_main_t * vam)
6635 {
6636   unformat_input_t *i = vam->input;
6637   vl_api_sw_interface_set_rx_mode_t *mp;
6638   u32 sw_if_index;
6639   u8 sw_if_index_set = 0;
6640   int ret;
6641   u8 queue_id_valid = 0;
6642   u32 queue_id;
6643   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6644
6645   /* Parse args required to build the message */
6646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6647     {
6648       if (unformat (i, "queue %d", &queue_id))
6649         queue_id_valid = 1;
6650       else if (unformat (i, "polling"))
6651         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6652       else if (unformat (i, "interrupt"))
6653         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6654       else if (unformat (i, "adaptive"))
6655         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6656       else
6657         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6658         sw_if_index_set = 1;
6659       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6660         sw_if_index_set = 1;
6661       else
6662         break;
6663     }
6664
6665   if (sw_if_index_set == 0)
6666     {
6667       errmsg ("missing interface name or sw_if_index");
6668       return -99;
6669     }
6670   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6671     {
6672       errmsg ("missing rx-mode");
6673       return -99;
6674     }
6675
6676   /* Construct the API message */
6677   M (SW_INTERFACE_SET_RX_MODE, mp);
6678   mp->sw_if_index = ntohl (sw_if_index);
6679   mp->mode = mode;
6680   mp->queue_id_valid = queue_id_valid;
6681   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6682
6683   /* send it... */
6684   S (mp);
6685
6686   /* Wait for a reply, return the good/bad news... */
6687   W (ret);
6688   return ret;
6689 }
6690
6691 static int
6692 api_sw_interface_set_rx_placement (vat_main_t * vam)
6693 {
6694   unformat_input_t *i = vam->input;
6695   vl_api_sw_interface_set_rx_placement_t *mp;
6696   u32 sw_if_index;
6697   u8 sw_if_index_set = 0;
6698   int ret;
6699   u8 is_main = 0;
6700   u32 queue_id, thread_index;
6701
6702   /* Parse args required to build the message */
6703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6704     {
6705       if (unformat (i, "queue %d", &queue_id))
6706         ;
6707       else if (unformat (i, "main"))
6708         is_main = 1;
6709       else if (unformat (i, "worker %d", &thread_index))
6710         ;
6711       else
6712         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6713         sw_if_index_set = 1;
6714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6715         sw_if_index_set = 1;
6716       else
6717         break;
6718     }
6719
6720   if (sw_if_index_set == 0)
6721     {
6722       errmsg ("missing interface name or sw_if_index");
6723       return -99;
6724     }
6725
6726   if (is_main)
6727     thread_index = 0;
6728   /* Construct the API message */
6729   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6730   mp->sw_if_index = ntohl (sw_if_index);
6731   mp->worker_id = ntohl (thread_index);
6732   mp->queue_id = ntohl (queue_id);
6733   mp->is_main = is_main;
6734
6735   /* send it... */
6736   S (mp);
6737   /* Wait for a reply, return the good/bad news... */
6738   W (ret);
6739   return ret;
6740 }
6741
6742 static void vl_api_sw_interface_rx_placement_details_t_handler
6743   (vl_api_sw_interface_rx_placement_details_t * mp)
6744 {
6745   vat_main_t *vam = &vat_main;
6746   u32 worker_id = ntohl (mp->worker_id);
6747
6748   print (vam->ofp,
6749          "\n%-11d %-11s %-6d %-5d %-9s",
6750          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6751          worker_id, ntohl (mp->queue_id),
6752          (mp->mode ==
6753           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6754 }
6755
6756 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6757   (vl_api_sw_interface_rx_placement_details_t * mp)
6758 {
6759   vat_main_t *vam = &vat_main;
6760   vat_json_node_t *node = NULL;
6761
6762   if (VAT_JSON_ARRAY != vam->json_tree.type)
6763     {
6764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6765       vat_json_init_array (&vam->json_tree);
6766     }
6767   node = vat_json_array_add (&vam->json_tree);
6768
6769   vat_json_init_object (node);
6770   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6771   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6772   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6773   vat_json_object_add_uint (node, "mode", mp->mode);
6774 }
6775
6776 static int
6777 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6778 {
6779   unformat_input_t *i = vam->input;
6780   vl_api_sw_interface_rx_placement_dump_t *mp;
6781   vl_api_control_ping_t *mp_ping;
6782   int ret;
6783   u32 sw_if_index;
6784   u8 sw_if_index_set = 0;
6785
6786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6787     {
6788       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6789         sw_if_index_set++;
6790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6791         sw_if_index_set++;
6792       else
6793         break;
6794     }
6795
6796   print (vam->ofp,
6797          "\n%-11s %-11s %-6s %-5s %-4s",
6798          "sw_if_index", "main/worker", "thread", "queue", "mode");
6799
6800   /* Dump Interface rx placement */
6801   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6802
6803   if (sw_if_index_set)
6804     mp->sw_if_index = htonl (sw_if_index);
6805   else
6806     mp->sw_if_index = ~0;
6807
6808   S (mp);
6809
6810   /* Use a control ping for synchronization */
6811   MPING (CONTROL_PING, mp_ping);
6812   S (mp_ping);
6813
6814   W (ret);
6815   return ret;
6816 }
6817
6818 static int
6819 api_sw_interface_clear_stats (vat_main_t * vam)
6820 {
6821   unformat_input_t *i = vam->input;
6822   vl_api_sw_interface_clear_stats_t *mp;
6823   u32 sw_if_index;
6824   u8 sw_if_index_set = 0;
6825   int ret;
6826
6827   /* Parse args required to build the message */
6828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6829     {
6830       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6831         sw_if_index_set = 1;
6832       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6833         sw_if_index_set = 1;
6834       else
6835         break;
6836     }
6837
6838   /* Construct the API message */
6839   M (SW_INTERFACE_CLEAR_STATS, mp);
6840
6841   if (sw_if_index_set == 1)
6842     mp->sw_if_index = ntohl (sw_if_index);
6843   else
6844     mp->sw_if_index = ~0;
6845
6846   /* send it... */
6847   S (mp);
6848
6849   /* Wait for a reply, return the good/bad news... */
6850   W (ret);
6851   return ret;
6852 }
6853
6854 static int
6855 api_sw_interface_add_del_address (vat_main_t * vam)
6856 {
6857   unformat_input_t *i = vam->input;
6858   vl_api_sw_interface_add_del_address_t *mp;
6859   u32 sw_if_index;
6860   u8 sw_if_index_set = 0;
6861   u8 is_add = 1, del_all = 0;
6862   u32 address_length = 0;
6863   u8 v4_address_set = 0;
6864   u8 v6_address_set = 0;
6865   ip4_address_t v4address;
6866   ip6_address_t v6address;
6867   int ret;
6868
6869   /* Parse args required to build the message */
6870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6871     {
6872       if (unformat (i, "del-all"))
6873         del_all = 1;
6874       else if (unformat (i, "del"))
6875         is_add = 0;
6876       else
6877         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6878         sw_if_index_set = 1;
6879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6880         sw_if_index_set = 1;
6881       else if (unformat (i, "%U/%d",
6882                          unformat_ip4_address, &v4address, &address_length))
6883         v4_address_set = 1;
6884       else if (unformat (i, "%U/%d",
6885                          unformat_ip6_address, &v6address, &address_length))
6886         v6_address_set = 1;
6887       else
6888         break;
6889     }
6890
6891   if (sw_if_index_set == 0)
6892     {
6893       errmsg ("missing interface name or sw_if_index");
6894       return -99;
6895     }
6896   if (v4_address_set && v6_address_set)
6897     {
6898       errmsg ("both v4 and v6 addresses set");
6899       return -99;
6900     }
6901   if (!v4_address_set && !v6_address_set && !del_all)
6902     {
6903       errmsg ("no addresses set");
6904       return -99;
6905     }
6906
6907   /* Construct the API message */
6908   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6909
6910   mp->sw_if_index = ntohl (sw_if_index);
6911   mp->is_add = is_add;
6912   mp->del_all = del_all;
6913   if (v6_address_set)
6914     {
6915       mp->is_ipv6 = 1;
6916       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6917     }
6918   else
6919     {
6920       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6921     }
6922   mp->address_length = address_length;
6923
6924   /* send it... */
6925   S (mp);
6926
6927   /* Wait for a reply, return good/bad news  */
6928   W (ret);
6929   return ret;
6930 }
6931
6932 static int
6933 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6934 {
6935   unformat_input_t *i = vam->input;
6936   vl_api_sw_interface_set_mpls_enable_t *mp;
6937   u32 sw_if_index;
6938   u8 sw_if_index_set = 0;
6939   u8 enable = 1;
6940   int ret;
6941
6942   /* Parse args required to build the message */
6943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6944     {
6945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6946         sw_if_index_set = 1;
6947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6948         sw_if_index_set = 1;
6949       else if (unformat (i, "disable"))
6950         enable = 0;
6951       else if (unformat (i, "dis"))
6952         enable = 0;
6953       else
6954         break;
6955     }
6956
6957   if (sw_if_index_set == 0)
6958     {
6959       errmsg ("missing interface name or sw_if_index");
6960       return -99;
6961     }
6962
6963   /* Construct the API message */
6964   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6965
6966   mp->sw_if_index = ntohl (sw_if_index);
6967   mp->enable = enable;
6968
6969   /* send it... */
6970   S (mp);
6971
6972   /* Wait for a reply... */
6973   W (ret);
6974   return ret;
6975 }
6976
6977 static int
6978 api_sw_interface_set_table (vat_main_t * vam)
6979 {
6980   unformat_input_t *i = vam->input;
6981   vl_api_sw_interface_set_table_t *mp;
6982   u32 sw_if_index, vrf_id = 0;
6983   u8 sw_if_index_set = 0;
6984   u8 is_ipv6 = 0;
6985   int ret;
6986
6987   /* Parse args required to build the message */
6988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6989     {
6990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6991         sw_if_index_set = 1;
6992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6993         sw_if_index_set = 1;
6994       else if (unformat (i, "vrf %d", &vrf_id))
6995         ;
6996       else if (unformat (i, "ipv6"))
6997         is_ipv6 = 1;
6998       else
6999         break;
7000     }
7001
7002   if (sw_if_index_set == 0)
7003     {
7004       errmsg ("missing interface name or sw_if_index");
7005       return -99;
7006     }
7007
7008   /* Construct the API message */
7009   M (SW_INTERFACE_SET_TABLE, mp);
7010
7011   mp->sw_if_index = ntohl (sw_if_index);
7012   mp->is_ipv6 = is_ipv6;
7013   mp->vrf_id = ntohl (vrf_id);
7014
7015   /* send it... */
7016   S (mp);
7017
7018   /* Wait for a reply... */
7019   W (ret);
7020   return ret;
7021 }
7022
7023 static void vl_api_sw_interface_get_table_reply_t_handler
7024   (vl_api_sw_interface_get_table_reply_t * mp)
7025 {
7026   vat_main_t *vam = &vat_main;
7027
7028   print (vam->ofp, "%d", ntohl (mp->vrf_id));
7029
7030   vam->retval = ntohl (mp->retval);
7031   vam->result_ready = 1;
7032
7033 }
7034
7035 static void vl_api_sw_interface_get_table_reply_t_handler_json
7036   (vl_api_sw_interface_get_table_reply_t * mp)
7037 {
7038   vat_main_t *vam = &vat_main;
7039   vat_json_node_t node;
7040
7041   vat_json_init_object (&node);
7042   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
7043   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
7044
7045   vat_json_print (vam->ofp, &node);
7046   vat_json_free (&node);
7047
7048   vam->retval = ntohl (mp->retval);
7049   vam->result_ready = 1;
7050 }
7051
7052 static int
7053 api_sw_interface_get_table (vat_main_t * vam)
7054 {
7055   unformat_input_t *i = vam->input;
7056   vl_api_sw_interface_get_table_t *mp;
7057   u32 sw_if_index;
7058   u8 sw_if_index_set = 0;
7059   u8 is_ipv6 = 0;
7060   int ret;
7061
7062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7063     {
7064       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7065         sw_if_index_set = 1;
7066       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7067         sw_if_index_set = 1;
7068       else if (unformat (i, "ipv6"))
7069         is_ipv6 = 1;
7070       else
7071         break;
7072     }
7073
7074   if (sw_if_index_set == 0)
7075     {
7076       errmsg ("missing interface name or sw_if_index");
7077       return -99;
7078     }
7079
7080   M (SW_INTERFACE_GET_TABLE, mp);
7081   mp->sw_if_index = htonl (sw_if_index);
7082   mp->is_ipv6 = is_ipv6;
7083
7084   S (mp);
7085   W (ret);
7086   return ret;
7087 }
7088
7089 static int
7090 api_sw_interface_set_vpath (vat_main_t * vam)
7091 {
7092   unformat_input_t *i = vam->input;
7093   vl_api_sw_interface_set_vpath_t *mp;
7094   u32 sw_if_index = 0;
7095   u8 sw_if_index_set = 0;
7096   u8 is_enable = 0;
7097   int ret;
7098
7099   /* Parse args required to build the message */
7100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7101     {
7102       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7103         sw_if_index_set = 1;
7104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7105         sw_if_index_set = 1;
7106       else if (unformat (i, "enable"))
7107         is_enable = 1;
7108       else if (unformat (i, "disable"))
7109         is_enable = 0;
7110       else
7111         break;
7112     }
7113
7114   if (sw_if_index_set == 0)
7115     {
7116       errmsg ("missing interface name or sw_if_index");
7117       return -99;
7118     }
7119
7120   /* Construct the API message */
7121   M (SW_INTERFACE_SET_VPATH, mp);
7122
7123   mp->sw_if_index = ntohl (sw_if_index);
7124   mp->enable = is_enable;
7125
7126   /* send it... */
7127   S (mp);
7128
7129   /* Wait for a reply... */
7130   W (ret);
7131   return ret;
7132 }
7133
7134 static int
7135 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7136 {
7137   unformat_input_t *i = vam->input;
7138   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7139   u32 sw_if_index = 0;
7140   u8 sw_if_index_set = 0;
7141   u8 is_enable = 1;
7142   u8 is_ipv6 = 0;
7143   int ret;
7144
7145   /* Parse args required to build the message */
7146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7147     {
7148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7149         sw_if_index_set = 1;
7150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7151         sw_if_index_set = 1;
7152       else if (unformat (i, "enable"))
7153         is_enable = 1;
7154       else if (unformat (i, "disable"))
7155         is_enable = 0;
7156       else if (unformat (i, "ip4"))
7157         is_ipv6 = 0;
7158       else if (unformat (i, "ip6"))
7159         is_ipv6 = 1;
7160       else
7161         break;
7162     }
7163
7164   if (sw_if_index_set == 0)
7165     {
7166       errmsg ("missing interface name or sw_if_index");
7167       return -99;
7168     }
7169
7170   /* Construct the API message */
7171   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7172
7173   mp->sw_if_index = ntohl (sw_if_index);
7174   mp->enable = is_enable;
7175   mp->is_ipv6 = is_ipv6;
7176
7177   /* send it... */
7178   S (mp);
7179
7180   /* Wait for a reply... */
7181   W (ret);
7182   return ret;
7183 }
7184
7185 static int
7186 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7187 {
7188   unformat_input_t *i = vam->input;
7189   vl_api_sw_interface_set_geneve_bypass_t *mp;
7190   u32 sw_if_index = 0;
7191   u8 sw_if_index_set = 0;
7192   u8 is_enable = 1;
7193   u8 is_ipv6 = 0;
7194   int ret;
7195
7196   /* Parse args required to build the message */
7197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7198     {
7199       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7200         sw_if_index_set = 1;
7201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7202         sw_if_index_set = 1;
7203       else if (unformat (i, "enable"))
7204         is_enable = 1;
7205       else if (unformat (i, "disable"))
7206         is_enable = 0;
7207       else if (unformat (i, "ip4"))
7208         is_ipv6 = 0;
7209       else if (unformat (i, "ip6"))
7210         is_ipv6 = 1;
7211       else
7212         break;
7213     }
7214
7215   if (sw_if_index_set == 0)
7216     {
7217       errmsg ("missing interface name or sw_if_index");
7218       return -99;
7219     }
7220
7221   /* Construct the API message */
7222   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7223
7224   mp->sw_if_index = ntohl (sw_if_index);
7225   mp->enable = is_enable;
7226   mp->is_ipv6 = is_ipv6;
7227
7228   /* send it... */
7229   S (mp);
7230
7231   /* Wait for a reply... */
7232   W (ret);
7233   return ret;
7234 }
7235
7236 static int
7237 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7238 {
7239   unformat_input_t *i = vam->input;
7240   vl_api_sw_interface_set_l2_xconnect_t *mp;
7241   u32 rx_sw_if_index;
7242   u8 rx_sw_if_index_set = 0;
7243   u32 tx_sw_if_index;
7244   u8 tx_sw_if_index_set = 0;
7245   u8 enable = 1;
7246   int ret;
7247
7248   /* Parse args required to build the message */
7249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7250     {
7251       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7252         rx_sw_if_index_set = 1;
7253       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7254         tx_sw_if_index_set = 1;
7255       else if (unformat (i, "rx"))
7256         {
7257           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7258             {
7259               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7260                             &rx_sw_if_index))
7261                 rx_sw_if_index_set = 1;
7262             }
7263           else
7264             break;
7265         }
7266       else if (unformat (i, "tx"))
7267         {
7268           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7269             {
7270               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7271                             &tx_sw_if_index))
7272                 tx_sw_if_index_set = 1;
7273             }
7274           else
7275             break;
7276         }
7277       else if (unformat (i, "enable"))
7278         enable = 1;
7279       else if (unformat (i, "disable"))
7280         enable = 0;
7281       else
7282         break;
7283     }
7284
7285   if (rx_sw_if_index_set == 0)
7286     {
7287       errmsg ("missing rx interface name or rx_sw_if_index");
7288       return -99;
7289     }
7290
7291   if (enable && (tx_sw_if_index_set == 0))
7292     {
7293       errmsg ("missing tx interface name or tx_sw_if_index");
7294       return -99;
7295     }
7296
7297   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7298
7299   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7300   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7301   mp->enable = enable;
7302
7303   S (mp);
7304   W (ret);
7305   return ret;
7306 }
7307
7308 static int
7309 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7310 {
7311   unformat_input_t *i = vam->input;
7312   vl_api_sw_interface_set_l2_bridge_t *mp;
7313   vl_api_l2_port_type_t port_type;
7314   u32 rx_sw_if_index;
7315   u8 rx_sw_if_index_set = 0;
7316   u32 bd_id;
7317   u8 bd_id_set = 0;
7318   u32 shg = 0;
7319   u8 enable = 1;
7320   int ret;
7321
7322   port_type = L2_API_PORT_TYPE_NORMAL;
7323
7324   /* Parse args required to build the message */
7325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326     {
7327       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7328         rx_sw_if_index_set = 1;
7329       else if (unformat (i, "bd_id %d", &bd_id))
7330         bd_id_set = 1;
7331       else
7332         if (unformat
7333             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7334         rx_sw_if_index_set = 1;
7335       else if (unformat (i, "shg %d", &shg))
7336         ;
7337       else if (unformat (i, "bvi"))
7338         port_type = L2_API_PORT_TYPE_BVI;
7339       else if (unformat (i, "uu-fwd"))
7340         port_type = L2_API_PORT_TYPE_UU_FWD;
7341       else if (unformat (i, "enable"))
7342         enable = 1;
7343       else if (unformat (i, "disable"))
7344         enable = 0;
7345       else
7346         break;
7347     }
7348
7349   if (rx_sw_if_index_set == 0)
7350     {
7351       errmsg ("missing rx interface name or sw_if_index");
7352       return -99;
7353     }
7354
7355   if (enable && (bd_id_set == 0))
7356     {
7357       errmsg ("missing bridge domain");
7358       return -99;
7359     }
7360
7361   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7362
7363   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7364   mp->bd_id = ntohl (bd_id);
7365   mp->shg = (u8) shg;
7366   mp->port_type = ntohl (port_type);
7367   mp->enable = enable;
7368
7369   S (mp);
7370   W (ret);
7371   return ret;
7372 }
7373
7374 static int
7375 api_bridge_domain_dump (vat_main_t * vam)
7376 {
7377   unformat_input_t *i = vam->input;
7378   vl_api_bridge_domain_dump_t *mp;
7379   vl_api_control_ping_t *mp_ping;
7380   u32 bd_id = ~0;
7381   int ret;
7382
7383   /* Parse args required to build the message */
7384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7385     {
7386       if (unformat (i, "bd_id %d", &bd_id))
7387         ;
7388       else
7389         break;
7390     }
7391
7392   M (BRIDGE_DOMAIN_DUMP, mp);
7393   mp->bd_id = ntohl (bd_id);
7394   S (mp);
7395
7396   /* Use a control ping for synchronization */
7397   MPING (CONTROL_PING, mp_ping);
7398   S (mp_ping);
7399
7400   W (ret);
7401   return ret;
7402 }
7403
7404 static int
7405 api_bridge_domain_add_del (vat_main_t * vam)
7406 {
7407   unformat_input_t *i = vam->input;
7408   vl_api_bridge_domain_add_del_t *mp;
7409   u32 bd_id = ~0;
7410   u8 is_add = 1;
7411   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7412   u8 *bd_tag = NULL;
7413   u32 mac_age = 0;
7414   int ret;
7415
7416   /* Parse args required to build the message */
7417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7418     {
7419       if (unformat (i, "bd_id %d", &bd_id))
7420         ;
7421       else if (unformat (i, "flood %d", &flood))
7422         ;
7423       else if (unformat (i, "uu-flood %d", &uu_flood))
7424         ;
7425       else if (unformat (i, "forward %d", &forward))
7426         ;
7427       else if (unformat (i, "learn %d", &learn))
7428         ;
7429       else if (unformat (i, "arp-term %d", &arp_term))
7430         ;
7431       else if (unformat (i, "mac-age %d", &mac_age))
7432         ;
7433       else if (unformat (i, "bd-tag %s", &bd_tag))
7434         ;
7435       else if (unformat (i, "del"))
7436         {
7437           is_add = 0;
7438           flood = uu_flood = forward = learn = 0;
7439         }
7440       else
7441         break;
7442     }
7443
7444   if (bd_id == ~0)
7445     {
7446       errmsg ("missing bridge domain");
7447       ret = -99;
7448       goto done;
7449     }
7450
7451   if (mac_age > 255)
7452     {
7453       errmsg ("mac age must be less than 256 ");
7454       ret = -99;
7455       goto done;
7456     }
7457
7458   if ((bd_tag) && (vec_len (bd_tag) > 63))
7459     {
7460       errmsg ("bd-tag cannot be longer than 63");
7461       ret = -99;
7462       goto done;
7463     }
7464
7465   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7466
7467   mp->bd_id = ntohl (bd_id);
7468   mp->flood = flood;
7469   mp->uu_flood = uu_flood;
7470   mp->forward = forward;
7471   mp->learn = learn;
7472   mp->arp_term = arp_term;
7473   mp->is_add = is_add;
7474   mp->mac_age = (u8) mac_age;
7475   if (bd_tag)
7476     {
7477       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7478       mp->bd_tag[vec_len (bd_tag)] = 0;
7479     }
7480   S (mp);
7481   W (ret);
7482
7483 done:
7484   vec_free (bd_tag);
7485   return ret;
7486 }
7487
7488 static int
7489 api_l2fib_flush_bd (vat_main_t * vam)
7490 {
7491   unformat_input_t *i = vam->input;
7492   vl_api_l2fib_flush_bd_t *mp;
7493   u32 bd_id = ~0;
7494   int ret;
7495
7496   /* Parse args required to build the message */
7497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7498     {
7499       if (unformat (i, "bd_id %d", &bd_id));
7500       else
7501         break;
7502     }
7503
7504   if (bd_id == ~0)
7505     {
7506       errmsg ("missing bridge domain");
7507       return -99;
7508     }
7509
7510   M (L2FIB_FLUSH_BD, mp);
7511
7512   mp->bd_id = htonl (bd_id);
7513
7514   S (mp);
7515   W (ret);
7516   return ret;
7517 }
7518
7519 static int
7520 api_l2fib_flush_int (vat_main_t * vam)
7521 {
7522   unformat_input_t *i = vam->input;
7523   vl_api_l2fib_flush_int_t *mp;
7524   u32 sw_if_index = ~0;
7525   int ret;
7526
7527   /* Parse args required to build the message */
7528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7529     {
7530       if (unformat (i, "sw_if_index %d", &sw_if_index));
7531       else
7532         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7533       else
7534         break;
7535     }
7536
7537   if (sw_if_index == ~0)
7538     {
7539       errmsg ("missing interface name or sw_if_index");
7540       return -99;
7541     }
7542
7543   M (L2FIB_FLUSH_INT, mp);
7544
7545   mp->sw_if_index = ntohl (sw_if_index);
7546
7547   S (mp);
7548   W (ret);
7549   return ret;
7550 }
7551
7552 static int
7553 api_l2fib_add_del (vat_main_t * vam)
7554 {
7555   unformat_input_t *i = vam->input;
7556   vl_api_l2fib_add_del_t *mp;
7557   f64 timeout;
7558   u8 mac[6] = { 0 };
7559   u8 mac_set = 0;
7560   u32 bd_id;
7561   u8 bd_id_set = 0;
7562   u32 sw_if_index = 0;
7563   u8 sw_if_index_set = 0;
7564   u8 is_add = 1;
7565   u8 static_mac = 0;
7566   u8 filter_mac = 0;
7567   u8 bvi_mac = 0;
7568   int count = 1;
7569   f64 before = 0;
7570   int j;
7571
7572   /* Parse args required to build the message */
7573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7574     {
7575       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7576         mac_set = 1;
7577       else if (unformat (i, "bd_id %d", &bd_id))
7578         bd_id_set = 1;
7579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7580         sw_if_index_set = 1;
7581       else if (unformat (i, "sw_if"))
7582         {
7583           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7584             {
7585               if (unformat
7586                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7587                 sw_if_index_set = 1;
7588             }
7589           else
7590             break;
7591         }
7592       else if (unformat (i, "static"))
7593         static_mac = 1;
7594       else if (unformat (i, "filter"))
7595         {
7596           filter_mac = 1;
7597           static_mac = 1;
7598         }
7599       else if (unformat (i, "bvi"))
7600         {
7601           bvi_mac = 1;
7602           static_mac = 1;
7603         }
7604       else if (unformat (i, "del"))
7605         is_add = 0;
7606       else if (unformat (i, "count %d", &count))
7607         ;
7608       else
7609         break;
7610     }
7611
7612   if (mac_set == 0)
7613     {
7614       errmsg ("missing mac address");
7615       return -99;
7616     }
7617
7618   if (bd_id_set == 0)
7619     {
7620       errmsg ("missing bridge domain");
7621       return -99;
7622     }
7623
7624   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7625     {
7626       errmsg ("missing interface name or sw_if_index");
7627       return -99;
7628     }
7629
7630   if (count > 1)
7631     {
7632       /* Turn on async mode */
7633       vam->async_mode = 1;
7634       vam->async_errors = 0;
7635       before = vat_time_now (vam);
7636     }
7637
7638   for (j = 0; j < count; j++)
7639     {
7640       M (L2FIB_ADD_DEL, mp);
7641
7642       clib_memcpy (mp->mac, mac, 6);
7643       mp->bd_id = ntohl (bd_id);
7644       mp->is_add = is_add;
7645       mp->sw_if_index = ntohl (sw_if_index);
7646
7647       if (is_add)
7648         {
7649           mp->static_mac = static_mac;
7650           mp->filter_mac = filter_mac;
7651           mp->bvi_mac = bvi_mac;
7652         }
7653       increment_mac_address (mac);
7654       /* send it... */
7655       S (mp);
7656     }
7657
7658   if (count > 1)
7659     {
7660       vl_api_control_ping_t *mp_ping;
7661       f64 after;
7662
7663       /* Shut off async mode */
7664       vam->async_mode = 0;
7665
7666       MPING (CONTROL_PING, mp_ping);
7667       S (mp_ping);
7668
7669       timeout = vat_time_now (vam) + 1.0;
7670       while (vat_time_now (vam) < timeout)
7671         if (vam->result_ready == 1)
7672           goto out;
7673       vam->retval = -99;
7674
7675     out:
7676       if (vam->retval == -99)
7677         errmsg ("timeout");
7678
7679       if (vam->async_errors > 0)
7680         {
7681           errmsg ("%d asynchronous errors", vam->async_errors);
7682           vam->retval = -98;
7683         }
7684       vam->async_errors = 0;
7685       after = vat_time_now (vam);
7686
7687       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7688              count, after - before, count / (after - before));
7689     }
7690   else
7691     {
7692       int ret;
7693
7694       /* Wait for a reply... */
7695       W (ret);
7696       return ret;
7697     }
7698   /* Return the good/bad news */
7699   return (vam->retval);
7700 }
7701
7702 static int
7703 api_bridge_domain_set_mac_age (vat_main_t * vam)
7704 {
7705   unformat_input_t *i = vam->input;
7706   vl_api_bridge_domain_set_mac_age_t *mp;
7707   u32 bd_id = ~0;
7708   u32 mac_age = 0;
7709   int ret;
7710
7711   /* Parse args required to build the message */
7712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7713     {
7714       if (unformat (i, "bd_id %d", &bd_id));
7715       else if (unformat (i, "mac-age %d", &mac_age));
7716       else
7717         break;
7718     }
7719
7720   if (bd_id == ~0)
7721     {
7722       errmsg ("missing bridge domain");
7723       return -99;
7724     }
7725
7726   if (mac_age > 255)
7727     {
7728       errmsg ("mac age must be less than 256 ");
7729       return -99;
7730     }
7731
7732   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7733
7734   mp->bd_id = htonl (bd_id);
7735   mp->mac_age = (u8) mac_age;
7736
7737   S (mp);
7738   W (ret);
7739   return ret;
7740 }
7741
7742 static int
7743 api_l2_flags (vat_main_t * vam)
7744 {
7745   unformat_input_t *i = vam->input;
7746   vl_api_l2_flags_t *mp;
7747   u32 sw_if_index;
7748   u32 flags = 0;
7749   u8 sw_if_index_set = 0;
7750   u8 is_set = 0;
7751   int ret;
7752
7753   /* Parse args required to build the message */
7754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7755     {
7756       if (unformat (i, "sw_if_index %d", &sw_if_index))
7757         sw_if_index_set = 1;
7758       else if (unformat (i, "sw_if"))
7759         {
7760           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7761             {
7762               if (unformat
7763                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7764                 sw_if_index_set = 1;
7765             }
7766           else
7767             break;
7768         }
7769       else if (unformat (i, "learn"))
7770         flags |= L2_LEARN;
7771       else if (unformat (i, "forward"))
7772         flags |= L2_FWD;
7773       else if (unformat (i, "flood"))
7774         flags |= L2_FLOOD;
7775       else if (unformat (i, "uu-flood"))
7776         flags |= L2_UU_FLOOD;
7777       else if (unformat (i, "arp-term"))
7778         flags |= L2_ARP_TERM;
7779       else if (unformat (i, "off"))
7780         is_set = 0;
7781       else if (unformat (i, "disable"))
7782         is_set = 0;
7783       else
7784         break;
7785     }
7786
7787   if (sw_if_index_set == 0)
7788     {
7789       errmsg ("missing interface name or sw_if_index");
7790       return -99;
7791     }
7792
7793   M (L2_FLAGS, mp);
7794
7795   mp->sw_if_index = ntohl (sw_if_index);
7796   mp->feature_bitmap = ntohl (flags);
7797   mp->is_set = is_set;
7798
7799   S (mp);
7800   W (ret);
7801   return ret;
7802 }
7803
7804 static int
7805 api_bridge_flags (vat_main_t * vam)
7806 {
7807   unformat_input_t *i = vam->input;
7808   vl_api_bridge_flags_t *mp;
7809   u32 bd_id;
7810   u8 bd_id_set = 0;
7811   u8 is_set = 1;
7812   bd_flags_t flags = 0;
7813   int ret;
7814
7815   /* Parse args required to build the message */
7816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7817     {
7818       if (unformat (i, "bd_id %d", &bd_id))
7819         bd_id_set = 1;
7820       else if (unformat (i, "learn"))
7821         flags |= BRIDGE_API_FLAG_LEARN;
7822       else if (unformat (i, "forward"))
7823         flags |= BRIDGE_API_FLAG_FWD;
7824       else if (unformat (i, "flood"))
7825         flags |= BRIDGE_API_FLAG_FLOOD;
7826       else if (unformat (i, "uu-flood"))
7827         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7828       else if (unformat (i, "arp-term"))
7829         flags |= BRIDGE_API_FLAG_ARP_TERM;
7830       else if (unformat (i, "off"))
7831         is_set = 0;
7832       else if (unformat (i, "disable"))
7833         is_set = 0;
7834       else
7835         break;
7836     }
7837
7838   if (bd_id_set == 0)
7839     {
7840       errmsg ("missing bridge domain");
7841       return -99;
7842     }
7843
7844   M (BRIDGE_FLAGS, mp);
7845
7846   mp->bd_id = ntohl (bd_id);
7847   mp->flags = ntohl (flags);
7848   mp->is_set = is_set;
7849
7850   S (mp);
7851   W (ret);
7852   return ret;
7853 }
7854
7855 static int
7856 api_bd_ip_mac_add_del (vat_main_t * vam)
7857 {
7858   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7859   vl_api_mac_address_t mac = VL_API_ZERO_MAC_ADDRESS;
7860   unformat_input_t *i = vam->input;
7861   vl_api_bd_ip_mac_add_del_t *mp;
7862   ip46_type_t type;
7863   u32 bd_id;
7864   u8 is_ipv6 = 0;
7865   u8 is_add = 1;
7866   u8 bd_id_set = 0;
7867   u8 ip_set = 0;
7868   u8 mac_set = 0;
7869   u8 macaddr[6];
7870   int ret;
7871
7872
7873   /* Parse args required to build the message */
7874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7875     {
7876       if (unformat (i, "bd_id %d", &bd_id))
7877         {
7878           bd_id_set++;
7879         }
7880       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7881         {
7882           ip_set++;
7883         }
7884       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7885         {
7886           mac_set++;
7887         }
7888       else if (unformat (i, "del"))
7889         is_add = 0;
7890       else
7891         break;
7892     }
7893
7894   if (bd_id_set == 0)
7895     {
7896       errmsg ("missing bridge domain");
7897       return -99;
7898     }
7899   else if (ip_set == 0)
7900     {
7901       errmsg ("missing IP address");
7902       return -99;
7903     }
7904   else if (mac_set == 0)
7905     {
7906       errmsg ("missing MAC address");
7907       return -99;
7908     }
7909
7910   M (BD_IP_MAC_ADD_DEL, mp);
7911
7912   mp->bd_id = ntohl (bd_id);
7913   mp->is_add = is_add;
7914
7915   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7916   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7917
7918   S (mp);
7919   W (ret);
7920   return ret;
7921 }
7922
7923 static void vl_api_bd_ip_mac_details_t_handler
7924   (vl_api_bd_ip_mac_details_t * mp)
7925 {
7926   vat_main_t *vam = &vat_main;
7927   u8 *ip = 0;
7928
7929   if (!mp->is_ipv6)
7930     ip =
7931       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7932   else
7933     ip =
7934       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7935
7936   print (vam->ofp,
7937          "\n%-5d %-7s %-20U %-30s",
7938          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7939          format_ethernet_address, mp->mac_address, ip);
7940
7941   vec_free (ip);
7942 }
7943
7944 static void vl_api_bd_ip_mac_details_t_handler_json
7945   (vl_api_bd_ip_mac_details_t * mp)
7946 {
7947   vat_main_t *vam = &vat_main;
7948   vat_json_node_t *node = NULL;
7949
7950   if (VAT_JSON_ARRAY != vam->json_tree.type)
7951     {
7952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7953       vat_json_init_array (&vam->json_tree);
7954     }
7955   node = vat_json_array_add (&vam->json_tree);
7956
7957   vat_json_init_object (node);
7958   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7959   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7960   vat_json_object_add_string_copy (node, "mac_address",
7961                                    format (0, "%U", format_ethernet_address,
7962                                            &mp->mac_address));
7963   u8 *ip = 0;
7964
7965   if (!mp->is_ipv6)
7966     ip =
7967       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7968   else
7969     ip =
7970       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7971   vat_json_object_add_string_copy (node, "ip_address", ip);
7972   vec_free (ip);
7973 }
7974
7975 static int
7976 api_bd_ip_mac_dump (vat_main_t * vam)
7977 {
7978   unformat_input_t *i = vam->input;
7979   vl_api_bd_ip_mac_dump_t *mp;
7980   vl_api_control_ping_t *mp_ping;
7981   int ret;
7982   u32 bd_id;
7983   u8 bd_id_set = 0;
7984
7985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7986     {
7987       if (unformat (i, "bd_id %d", &bd_id))
7988         {
7989           bd_id_set++;
7990         }
7991       else
7992         break;
7993     }
7994
7995   print (vam->ofp,
7996          "\n%-5s %-7s %-20s %-30s",
7997          "bd_id", "is_ipv6", "mac_address", "ip_address");
7998
7999   /* Dump Bridge Domain Ip to Mac entries */
8000   M (BD_IP_MAC_DUMP, mp);
8001
8002   if (bd_id_set)
8003     mp->bd_id = htonl (bd_id);
8004   else
8005     mp->bd_id = ~0;
8006
8007   S (mp);
8008
8009   /* Use a control ping for synchronization */
8010   MPING (CONTROL_PING, mp_ping);
8011   S (mp_ping);
8012
8013   W (ret);
8014   return ret;
8015 }
8016
8017 static int
8018 api_tap_connect (vat_main_t * vam)
8019 {
8020   unformat_input_t *i = vam->input;
8021   vl_api_tap_connect_t *mp;
8022   u8 mac_address[6];
8023   u8 random_mac = 1;
8024   u8 name_set = 0;
8025   u8 *tap_name;
8026   u8 *tag = 0;
8027   ip4_address_t ip4_address;
8028   u32 ip4_mask_width;
8029   int ip4_address_set = 0;
8030   ip6_address_t ip6_address;
8031   u32 ip6_mask_width;
8032   int ip6_address_set = 0;
8033   int ret;
8034
8035   clib_memset (mac_address, 0, sizeof (mac_address));
8036
8037   /* Parse args required to build the message */
8038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8039     {
8040       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8041         {
8042           random_mac = 0;
8043         }
8044       else if (unformat (i, "random-mac"))
8045         random_mac = 1;
8046       else if (unformat (i, "tapname %s", &tap_name))
8047         name_set = 1;
8048       else if (unformat (i, "tag %s", &tag))
8049         ;
8050       else if (unformat (i, "address %U/%d",
8051                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
8052         ip4_address_set = 1;
8053       else if (unformat (i, "address %U/%d",
8054                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
8055         ip6_address_set = 1;
8056       else
8057         break;
8058     }
8059
8060   if (name_set == 0)
8061     {
8062       errmsg ("missing tap name");
8063       return -99;
8064     }
8065   if (vec_len (tap_name) > 63)
8066     {
8067       errmsg ("tap name too long");
8068       return -99;
8069     }
8070   vec_add1 (tap_name, 0);
8071
8072   if (vec_len (tag) > 63)
8073     {
8074       errmsg ("tag too long");
8075       return -99;
8076     }
8077
8078   /* Construct the API message */
8079   M (TAP_CONNECT, mp);
8080
8081   mp->use_random_mac = random_mac;
8082   clib_memcpy (mp->mac_address, mac_address, 6);
8083   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8084   if (tag)
8085     clib_memcpy (mp->tag, tag, vec_len (tag));
8086
8087   if (ip4_address_set)
8088     {
8089       mp->ip4_address_set = 1;
8090       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
8091       mp->ip4_mask_width = ip4_mask_width;
8092     }
8093   if (ip6_address_set)
8094     {
8095       mp->ip6_address_set = 1;
8096       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
8097       mp->ip6_mask_width = ip6_mask_width;
8098     }
8099
8100   vec_free (tap_name);
8101   vec_free (tag);
8102
8103   /* send it... */
8104   S (mp);
8105
8106   /* Wait for a reply... */
8107   W (ret);
8108   return ret;
8109 }
8110
8111 static int
8112 api_tap_modify (vat_main_t * vam)
8113 {
8114   unformat_input_t *i = vam->input;
8115   vl_api_tap_modify_t *mp;
8116   u8 mac_address[6];
8117   u8 random_mac = 1;
8118   u8 name_set = 0;
8119   u8 *tap_name;
8120   u32 sw_if_index = ~0;
8121   u8 sw_if_index_set = 0;
8122   int ret;
8123
8124   clib_memset (mac_address, 0, sizeof (mac_address));
8125
8126   /* Parse args required to build the message */
8127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8128     {
8129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8130         sw_if_index_set = 1;
8131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8132         sw_if_index_set = 1;
8133       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8134         {
8135           random_mac = 0;
8136         }
8137       else if (unformat (i, "random-mac"))
8138         random_mac = 1;
8139       else if (unformat (i, "tapname %s", &tap_name))
8140         name_set = 1;
8141       else
8142         break;
8143     }
8144
8145   if (sw_if_index_set == 0)
8146     {
8147       errmsg ("missing vpp interface name");
8148       return -99;
8149     }
8150   if (name_set == 0)
8151     {
8152       errmsg ("missing tap name");
8153       return -99;
8154     }
8155   if (vec_len (tap_name) > 63)
8156     {
8157       errmsg ("tap name too long");
8158     }
8159   vec_add1 (tap_name, 0);
8160
8161   /* Construct the API message */
8162   M (TAP_MODIFY, mp);
8163
8164   mp->use_random_mac = random_mac;
8165   mp->sw_if_index = ntohl (sw_if_index);
8166   clib_memcpy (mp->mac_address, mac_address, 6);
8167   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8168   vec_free (tap_name);
8169
8170   /* send it... */
8171   S (mp);
8172
8173   /* Wait for a reply... */
8174   W (ret);
8175   return ret;
8176 }
8177
8178 static int
8179 api_tap_delete (vat_main_t * vam)
8180 {
8181   unformat_input_t *i = vam->input;
8182   vl_api_tap_delete_t *mp;
8183   u32 sw_if_index = ~0;
8184   u8 sw_if_index_set = 0;
8185   int ret;
8186
8187   /* Parse args required to build the message */
8188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8189     {
8190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8191         sw_if_index_set = 1;
8192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8193         sw_if_index_set = 1;
8194       else
8195         break;
8196     }
8197
8198   if (sw_if_index_set == 0)
8199     {
8200       errmsg ("missing vpp interface name");
8201       return -99;
8202     }
8203
8204   /* Construct the API message */
8205   M (TAP_DELETE, mp);
8206
8207   mp->sw_if_index = ntohl (sw_if_index);
8208
8209   /* send it... */
8210   S (mp);
8211
8212   /* Wait for a reply... */
8213   W (ret);
8214   return ret;
8215 }
8216
8217 static int
8218 api_tap_create_v2 (vat_main_t * vam)
8219 {
8220   unformat_input_t *i = vam->input;
8221   vl_api_tap_create_v2_t *mp;
8222   u8 mac_address[6];
8223   u8 random_mac = 1;
8224   u32 id = ~0;
8225   u8 *host_if_name = 0;
8226   u8 *host_ns = 0;
8227   u8 host_mac_addr[6];
8228   u8 host_mac_addr_set = 0;
8229   u8 *host_bridge = 0;
8230   ip4_address_t host_ip4_addr;
8231   ip4_address_t host_ip4_gw;
8232   u8 host_ip4_gw_set = 0;
8233   u32 host_ip4_prefix_len = 0;
8234   ip6_address_t host_ip6_addr;
8235   ip6_address_t host_ip6_gw;
8236   u8 host_ip6_gw_set = 0;
8237   u32 host_ip6_prefix_len = 0;
8238   int ret;
8239   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8240
8241   clib_memset (mac_address, 0, sizeof (mac_address));
8242
8243   /* Parse args required to build the message */
8244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8245     {
8246       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8247         {
8248           random_mac = 0;
8249         }
8250       else if (unformat (i, "id %u", &id))
8251         ;
8252       else if (unformat (i, "host-if-name %s", &host_if_name))
8253         ;
8254       else if (unformat (i, "host-ns %s", &host_ns))
8255         ;
8256       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8257                          host_mac_addr))
8258         host_mac_addr_set = 1;
8259       else if (unformat (i, "host-bridge %s", &host_bridge))
8260         ;
8261       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8262                          &host_ip4_addr, &host_ip4_prefix_len))
8263         ;
8264       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8265                          &host_ip6_addr, &host_ip6_prefix_len))
8266         ;
8267       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8268                          &host_ip4_gw))
8269         host_ip4_gw_set = 1;
8270       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8271                          &host_ip6_gw))
8272         host_ip6_gw_set = 1;
8273       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8274         ;
8275       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8276         ;
8277       else
8278         break;
8279     }
8280
8281   if (vec_len (host_if_name) > 63)
8282     {
8283       errmsg ("tap name too long. ");
8284       return -99;
8285     }
8286   if (vec_len (host_ns) > 63)
8287     {
8288       errmsg ("host name space too long. ");
8289       return -99;
8290     }
8291   if (vec_len (host_bridge) > 63)
8292     {
8293       errmsg ("host bridge name too long. ");
8294       return -99;
8295     }
8296   if (host_ip4_prefix_len > 32)
8297     {
8298       errmsg ("host ip4 prefix length not valid. ");
8299       return -99;
8300     }
8301   if (host_ip6_prefix_len > 128)
8302     {
8303       errmsg ("host ip6 prefix length not valid. ");
8304       return -99;
8305     }
8306   if (!is_pow2 (rx_ring_sz))
8307     {
8308       errmsg ("rx ring size must be power of 2. ");
8309       return -99;
8310     }
8311   if (rx_ring_sz > 32768)
8312     {
8313       errmsg ("rx ring size must be 32768 or lower. ");
8314       return -99;
8315     }
8316   if (!is_pow2 (tx_ring_sz))
8317     {
8318       errmsg ("tx ring size must be power of 2. ");
8319       return -99;
8320     }
8321   if (tx_ring_sz > 32768)
8322     {
8323       errmsg ("tx ring size must be 32768 or lower. ");
8324       return -99;
8325     }
8326
8327   /* Construct the API message */
8328   M (TAP_CREATE_V2, mp);
8329
8330   mp->use_random_mac = random_mac;
8331
8332   mp->id = ntohl (id);
8333   mp->host_namespace_set = host_ns != 0;
8334   mp->host_bridge_set = host_bridge != 0;
8335   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8336   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8337   mp->rx_ring_sz = ntohs (rx_ring_sz);
8338   mp->tx_ring_sz = ntohs (tx_ring_sz);
8339
8340   if (random_mac == 0)
8341     clib_memcpy (mp->mac_address, mac_address, 6);
8342   if (host_mac_addr_set)
8343     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8344   if (host_if_name)
8345     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8346   if (host_ns)
8347     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8348   if (host_bridge)
8349     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8350   if (host_ip4_prefix_len)
8351     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8352   if (host_ip6_prefix_len)
8353     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8354   if (host_ip4_gw_set)
8355     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8356   if (host_ip6_gw_set)
8357     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8358
8359   vec_free (host_ns);
8360   vec_free (host_if_name);
8361   vec_free (host_bridge);
8362
8363   /* send it... */
8364   S (mp);
8365
8366   /* Wait for a reply... */
8367   W (ret);
8368   return ret;
8369 }
8370
8371 static int
8372 api_tap_delete_v2 (vat_main_t * vam)
8373 {
8374   unformat_input_t *i = vam->input;
8375   vl_api_tap_delete_v2_t *mp;
8376   u32 sw_if_index = ~0;
8377   u8 sw_if_index_set = 0;
8378   int ret;
8379
8380   /* Parse args required to build the message */
8381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8382     {
8383       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8384         sw_if_index_set = 1;
8385       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8386         sw_if_index_set = 1;
8387       else
8388         break;
8389     }
8390
8391   if (sw_if_index_set == 0)
8392     {
8393       errmsg ("missing vpp interface name. ");
8394       return -99;
8395     }
8396
8397   /* Construct the API message */
8398   M (TAP_DELETE_V2, mp);
8399
8400   mp->sw_if_index = ntohl (sw_if_index);
8401
8402   /* send it... */
8403   S (mp);
8404
8405   /* Wait for a reply... */
8406   W (ret);
8407   return ret;
8408 }
8409
8410 static int
8411 api_bond_create (vat_main_t * vam)
8412 {
8413   unformat_input_t *i = vam->input;
8414   vl_api_bond_create_t *mp;
8415   u8 mac_address[6];
8416   u8 custom_mac = 0;
8417   int ret;
8418   u8 mode;
8419   u8 lb;
8420   u8 mode_is_set = 0;
8421
8422   clib_memset (mac_address, 0, sizeof (mac_address));
8423   lb = BOND_LB_L2;
8424
8425   /* Parse args required to build the message */
8426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8427     {
8428       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8429         mode_is_set = 1;
8430       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8431                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8432         ;
8433       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8434                          mac_address))
8435         custom_mac = 1;
8436       else
8437         break;
8438     }
8439
8440   if (mode_is_set == 0)
8441     {
8442       errmsg ("Missing bond mode. ");
8443       return -99;
8444     }
8445
8446   /* Construct the API message */
8447   M (BOND_CREATE, mp);
8448
8449   mp->use_custom_mac = custom_mac;
8450
8451   mp->mode = mode;
8452   mp->lb = lb;
8453
8454   if (custom_mac)
8455     clib_memcpy (mp->mac_address, mac_address, 6);
8456
8457   /* send it... */
8458   S (mp);
8459
8460   /* Wait for a reply... */
8461   W (ret);
8462   return ret;
8463 }
8464
8465 static int
8466 api_bond_delete (vat_main_t * vam)
8467 {
8468   unformat_input_t *i = vam->input;
8469   vl_api_bond_delete_t *mp;
8470   u32 sw_if_index = ~0;
8471   u8 sw_if_index_set = 0;
8472   int ret;
8473
8474   /* Parse args required to build the message */
8475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8476     {
8477       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8478         sw_if_index_set = 1;
8479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8480         sw_if_index_set = 1;
8481       else
8482         break;
8483     }
8484
8485   if (sw_if_index_set == 0)
8486     {
8487       errmsg ("missing vpp interface name. ");
8488       return -99;
8489     }
8490
8491   /* Construct the API message */
8492   M (BOND_DELETE, mp);
8493
8494   mp->sw_if_index = ntohl (sw_if_index);
8495
8496   /* send it... */
8497   S (mp);
8498
8499   /* Wait for a reply... */
8500   W (ret);
8501   return ret;
8502 }
8503
8504 static int
8505 api_bond_enslave (vat_main_t * vam)
8506 {
8507   unformat_input_t *i = vam->input;
8508   vl_api_bond_enslave_t *mp;
8509   u32 bond_sw_if_index;
8510   int ret;
8511   u8 is_passive;
8512   u8 is_long_timeout;
8513   u32 bond_sw_if_index_is_set = 0;
8514   u32 sw_if_index;
8515   u8 sw_if_index_is_set = 0;
8516
8517   /* Parse args required to build the message */
8518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8519     {
8520       if (unformat (i, "sw_if_index %d", &sw_if_index))
8521         sw_if_index_is_set = 1;
8522       else if (unformat (i, "bond %u", &bond_sw_if_index))
8523         bond_sw_if_index_is_set = 1;
8524       else if (unformat (i, "passive %d", &is_passive))
8525         ;
8526       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8527         ;
8528       else
8529         break;
8530     }
8531
8532   if (bond_sw_if_index_is_set == 0)
8533     {
8534       errmsg ("Missing bond sw_if_index. ");
8535       return -99;
8536     }
8537   if (sw_if_index_is_set == 0)
8538     {
8539       errmsg ("Missing slave sw_if_index. ");
8540       return -99;
8541     }
8542
8543   /* Construct the API message */
8544   M (BOND_ENSLAVE, mp);
8545
8546   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8547   mp->sw_if_index = ntohl (sw_if_index);
8548   mp->is_long_timeout = is_long_timeout;
8549   mp->is_passive = is_passive;
8550
8551   /* send it... */
8552   S (mp);
8553
8554   /* Wait for a reply... */
8555   W (ret);
8556   return ret;
8557 }
8558
8559 static int
8560 api_bond_detach_slave (vat_main_t * vam)
8561 {
8562   unformat_input_t *i = vam->input;
8563   vl_api_bond_detach_slave_t *mp;
8564   u32 sw_if_index = ~0;
8565   u8 sw_if_index_set = 0;
8566   int ret;
8567
8568   /* Parse args required to build the message */
8569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8570     {
8571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8572         sw_if_index_set = 1;
8573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8574         sw_if_index_set = 1;
8575       else
8576         break;
8577     }
8578
8579   if (sw_if_index_set == 0)
8580     {
8581       errmsg ("missing vpp interface name. ");
8582       return -99;
8583     }
8584
8585   /* Construct the API message */
8586   M (BOND_DETACH_SLAVE, mp);
8587
8588   mp->sw_if_index = ntohl (sw_if_index);
8589
8590   /* send it... */
8591   S (mp);
8592
8593   /* Wait for a reply... */
8594   W (ret);
8595   return ret;
8596 }
8597
8598 static int
8599 api_ip_table_add_del (vat_main_t * vam)
8600 {
8601   unformat_input_t *i = vam->input;
8602   vl_api_ip_table_add_del_t *mp;
8603   u32 table_id = ~0;
8604   u8 is_ipv6 = 0;
8605   u8 is_add = 1;
8606   int ret = 0;
8607
8608   /* Parse args required to build the message */
8609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8610     {
8611       if (unformat (i, "ipv6"))
8612         is_ipv6 = 1;
8613       else if (unformat (i, "del"))
8614         is_add = 0;
8615       else if (unformat (i, "add"))
8616         is_add = 1;
8617       else if (unformat (i, "table %d", &table_id))
8618         ;
8619       else
8620         {
8621           clib_warning ("parse error '%U'", format_unformat_error, i);
8622           return -99;
8623         }
8624     }
8625
8626   if (~0 == table_id)
8627     {
8628       errmsg ("missing table-ID");
8629       return -99;
8630     }
8631
8632   /* Construct the API message */
8633   M (IP_TABLE_ADD_DEL, mp);
8634
8635   mp->table_id = ntohl (table_id);
8636   mp->is_ipv6 = is_ipv6;
8637   mp->is_add = is_add;
8638
8639   /* send it... */
8640   S (mp);
8641
8642   /* Wait for a reply... */
8643   W (ret);
8644
8645   return ret;
8646 }
8647
8648 static int
8649 api_ip_add_del_route (vat_main_t * vam)
8650 {
8651   unformat_input_t *i = vam->input;
8652   vl_api_ip_add_del_route_t *mp;
8653   u32 sw_if_index = ~0, vrf_id = 0;
8654   u8 is_ipv6 = 0;
8655   u8 is_local = 0, is_drop = 0;
8656   u8 is_unreach = 0, is_prohibit = 0;
8657   u8 is_add = 1;
8658   u32 next_hop_weight = 1;
8659   u8 is_multipath = 0;
8660   u8 address_set = 0;
8661   u8 address_length_set = 0;
8662   u32 next_hop_table_id = 0;
8663   u32 resolve_attempts = 0;
8664   u32 dst_address_length = 0;
8665   u8 next_hop_set = 0;
8666   ip4_address_t v4_dst_address, v4_next_hop_address;
8667   ip6_address_t v6_dst_address, v6_next_hop_address;
8668   int count = 1;
8669   int j;
8670   f64 before = 0;
8671   u32 random_add_del = 0;
8672   u32 *random_vector = 0;
8673   uword *random_hash;
8674   u32 random_seed = 0xdeaddabe;
8675   u32 classify_table_index = ~0;
8676   u8 is_classify = 0;
8677   u8 resolve_host = 0, resolve_attached = 0;
8678   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8679   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8680   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8681
8682   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8683   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8684   /* Parse args required to build the message */
8685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8686     {
8687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8688         ;
8689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8690         ;
8691       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8692         {
8693           address_set = 1;
8694           is_ipv6 = 0;
8695         }
8696       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8697         {
8698           address_set = 1;
8699           is_ipv6 = 1;
8700         }
8701       else if (unformat (i, "/%d", &dst_address_length))
8702         {
8703           address_length_set = 1;
8704         }
8705
8706       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8707                                          &v4_next_hop_address))
8708         {
8709           next_hop_set = 1;
8710         }
8711       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8712                                          &v6_next_hop_address))
8713         {
8714           next_hop_set = 1;
8715         }
8716       else
8717         if (unformat
8718             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8719         {
8720           next_hop_set = 1;
8721         }
8722       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8723         {
8724           next_hop_set = 1;
8725         }
8726       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8727         ;
8728       else if (unformat (i, "weight %d", &next_hop_weight))
8729         ;
8730       else if (unformat (i, "drop"))
8731         {
8732           is_drop = 1;
8733         }
8734       else if (unformat (i, "null-send-unreach"))
8735         {
8736           is_unreach = 1;
8737         }
8738       else if (unformat (i, "null-send-prohibit"))
8739         {
8740           is_prohibit = 1;
8741         }
8742       else if (unformat (i, "local"))
8743         {
8744           is_local = 1;
8745         }
8746       else if (unformat (i, "classify %d", &classify_table_index))
8747         {
8748           is_classify = 1;
8749         }
8750       else if (unformat (i, "del"))
8751         is_add = 0;
8752       else if (unformat (i, "add"))
8753         is_add = 1;
8754       else if (unformat (i, "resolve-via-host"))
8755         resolve_host = 1;
8756       else if (unformat (i, "resolve-via-attached"))
8757         resolve_attached = 1;
8758       else if (unformat (i, "multipath"))
8759         is_multipath = 1;
8760       else if (unformat (i, "vrf %d", &vrf_id))
8761         ;
8762       else if (unformat (i, "count %d", &count))
8763         ;
8764       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8765         ;
8766       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8767         ;
8768       else if (unformat (i, "out-label %d", &next_hop_out_label))
8769         {
8770           vl_api_fib_mpls_label_t fib_label = {
8771             .label = ntohl (next_hop_out_label),
8772             .ttl = 64,
8773             .exp = 0,
8774           };
8775           vec_add1 (next_hop_out_label_stack, fib_label);
8776         }
8777       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8778         ;
8779       else if (unformat (i, "random"))
8780         random_add_del = 1;
8781       else if (unformat (i, "seed %d", &random_seed))
8782         ;
8783       else
8784         {
8785           clib_warning ("parse error '%U'", format_unformat_error, i);
8786           return -99;
8787         }
8788     }
8789
8790   if (!next_hop_set && !is_drop && !is_local &&
8791       !is_classify && !is_unreach && !is_prohibit &&
8792       MPLS_LABEL_INVALID == next_hop_via_label)
8793     {
8794       errmsg
8795         ("next hop / local / drop / unreach / prohibit / classify not set");
8796       return -99;
8797     }
8798
8799   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8800     {
8801       errmsg ("next hop and next-hop via label set");
8802       return -99;
8803     }
8804   if (address_set == 0)
8805     {
8806       errmsg ("missing addresses");
8807       return -99;
8808     }
8809
8810   if (address_length_set == 0)
8811     {
8812       errmsg ("missing address length");
8813       return -99;
8814     }
8815
8816   /* Generate a pile of unique, random routes */
8817   if (random_add_del)
8818     {
8819       u32 this_random_address;
8820       random_hash = hash_create (count, sizeof (uword));
8821
8822       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8823       for (j = 0; j <= count; j++)
8824         {
8825           do
8826             {
8827               this_random_address = random_u32 (&random_seed);
8828               this_random_address =
8829                 clib_host_to_net_u32 (this_random_address);
8830             }
8831           while (hash_get (random_hash, this_random_address));
8832           vec_add1 (random_vector, this_random_address);
8833           hash_set (random_hash, this_random_address, 1);
8834         }
8835       hash_free (random_hash);
8836       v4_dst_address.as_u32 = random_vector[0];
8837     }
8838
8839   if (count > 1)
8840     {
8841       /* Turn on async mode */
8842       vam->async_mode = 1;
8843       vam->async_errors = 0;
8844       before = vat_time_now (vam);
8845     }
8846
8847   for (j = 0; j < count; j++)
8848     {
8849       /* Construct the API message */
8850       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8851           vec_len (next_hop_out_label_stack));
8852
8853       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8854       mp->table_id = ntohl (vrf_id);
8855
8856       mp->is_add = is_add;
8857       mp->is_drop = is_drop;
8858       mp->is_unreach = is_unreach;
8859       mp->is_prohibit = is_prohibit;
8860       mp->is_ipv6 = is_ipv6;
8861       mp->is_local = is_local;
8862       mp->is_classify = is_classify;
8863       mp->is_multipath = is_multipath;
8864       mp->is_resolve_host = resolve_host;
8865       mp->is_resolve_attached = resolve_attached;
8866       mp->next_hop_weight = next_hop_weight;
8867       mp->next_hop_preference = 0;
8868       mp->dst_address_length = dst_address_length;
8869       mp->next_hop_table_id = ntohl (next_hop_table_id);
8870       mp->classify_table_index = ntohl (classify_table_index);
8871       mp->next_hop_via_label = ntohl (next_hop_via_label);
8872       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8873       if (0 != mp->next_hop_n_out_labels)
8874         {
8875           memcpy (mp->next_hop_out_label_stack,
8876                   next_hop_out_label_stack,
8877                   (vec_len (next_hop_out_label_stack) *
8878                    sizeof (vl_api_fib_mpls_label_t)));
8879           vec_free (next_hop_out_label_stack);
8880         }
8881
8882       if (is_ipv6)
8883         {
8884           clib_memcpy (mp->dst_address, &v6_dst_address,
8885                        sizeof (v6_dst_address));
8886           if (next_hop_set)
8887             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8888                          sizeof (v6_next_hop_address));
8889           increment_v6_address (&v6_dst_address);
8890         }
8891       else
8892         {
8893           clib_memcpy (mp->dst_address, &v4_dst_address,
8894                        sizeof (v4_dst_address));
8895           if (next_hop_set)
8896             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8897                          sizeof (v4_next_hop_address));
8898           if (random_add_del)
8899             v4_dst_address.as_u32 = random_vector[j + 1];
8900           else
8901             increment_v4_address (&v4_dst_address);
8902         }
8903       /* send it... */
8904       S (mp);
8905       /* If we receive SIGTERM, stop now... */
8906       if (vam->do_exit)
8907         break;
8908     }
8909
8910   /* When testing multiple add/del ops, use a control-ping to sync */
8911   if (count > 1)
8912     {
8913       vl_api_control_ping_t *mp_ping;
8914       f64 after;
8915       f64 timeout;
8916
8917       /* Shut off async mode */
8918       vam->async_mode = 0;
8919
8920       MPING (CONTROL_PING, mp_ping);
8921       S (mp_ping);
8922
8923       timeout = vat_time_now (vam) + 1.0;
8924       while (vat_time_now (vam) < timeout)
8925         if (vam->result_ready == 1)
8926           goto out;
8927       vam->retval = -99;
8928
8929     out:
8930       if (vam->retval == -99)
8931         errmsg ("timeout");
8932
8933       if (vam->async_errors > 0)
8934         {
8935           errmsg ("%d asynchronous errors", vam->async_errors);
8936           vam->retval = -98;
8937         }
8938       vam->async_errors = 0;
8939       after = vat_time_now (vam);
8940
8941       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8942       if (j > 0)
8943         count = j;
8944
8945       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8946              count, after - before, count / (after - before));
8947     }
8948   else
8949     {
8950       int ret;
8951
8952       /* Wait for a reply... */
8953       W (ret);
8954       return ret;
8955     }
8956
8957   /* Return the good/bad news */
8958   return (vam->retval);
8959 }
8960
8961 static int
8962 api_ip_mroute_add_del (vat_main_t * vam)
8963 {
8964   unformat_input_t *i = vam->input;
8965   vl_api_ip_mroute_add_del_t *mp;
8966   u32 sw_if_index = ~0, vrf_id = 0;
8967   u8 is_ipv6 = 0;
8968   u8 is_local = 0;
8969   u8 is_add = 1;
8970   u8 address_set = 0;
8971   u32 grp_address_length = 0;
8972   ip4_address_t v4_grp_address, v4_src_address;
8973   ip6_address_t v6_grp_address, v6_src_address;
8974   mfib_itf_flags_t iflags = 0;
8975   mfib_entry_flags_t eflags = 0;
8976   int ret;
8977
8978   /* Parse args required to build the message */
8979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8980     {
8981       if (unformat (i, "sw_if_index %d", &sw_if_index))
8982         ;
8983       else if (unformat (i, "%U %U",
8984                          unformat_ip4_address, &v4_src_address,
8985                          unformat_ip4_address, &v4_grp_address))
8986         {
8987           grp_address_length = 64;
8988           address_set = 1;
8989           is_ipv6 = 0;
8990         }
8991       else if (unformat (i, "%U %U",
8992                          unformat_ip6_address, &v6_src_address,
8993                          unformat_ip6_address, &v6_grp_address))
8994         {
8995           grp_address_length = 256;
8996           address_set = 1;
8997           is_ipv6 = 1;
8998         }
8999       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
9000         {
9001           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
9002           grp_address_length = 32;
9003           address_set = 1;
9004           is_ipv6 = 0;
9005         }
9006       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
9007         {
9008           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
9009           grp_address_length = 128;
9010           address_set = 1;
9011           is_ipv6 = 1;
9012         }
9013       else if (unformat (i, "/%d", &grp_address_length))
9014         ;
9015       else if (unformat (i, "local"))
9016         {
9017           is_local = 1;
9018         }
9019       else if (unformat (i, "del"))
9020         is_add = 0;
9021       else if (unformat (i, "add"))
9022         is_add = 1;
9023       else if (unformat (i, "vrf %d", &vrf_id))
9024         ;
9025       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
9026         ;
9027       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
9028         ;
9029       else
9030         {
9031           clib_warning ("parse error '%U'", format_unformat_error, i);
9032           return -99;
9033         }
9034     }
9035
9036   if (address_set == 0)
9037     {
9038       errmsg ("missing addresses\n");
9039       return -99;
9040     }
9041
9042   /* Construct the API message */
9043   M (IP_MROUTE_ADD_DEL, mp);
9044
9045   mp->next_hop_sw_if_index = ntohl (sw_if_index);
9046   mp->table_id = ntohl (vrf_id);
9047
9048   mp->is_add = is_add;
9049   mp->is_ipv6 = is_ipv6;
9050   mp->is_local = is_local;
9051   mp->itf_flags = ntohl (iflags);
9052   mp->entry_flags = ntohl (eflags);
9053   mp->grp_address_length = grp_address_length;
9054   mp->grp_address_length = ntohs (mp->grp_address_length);
9055
9056   if (is_ipv6)
9057     {
9058       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
9059       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
9060     }
9061   else
9062     {
9063       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
9064       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
9065
9066     }
9067
9068   /* send it... */
9069   S (mp);
9070   /* Wait for a reply... */
9071   W (ret);
9072   return ret;
9073 }
9074
9075 static int
9076 api_mpls_table_add_del (vat_main_t * vam)
9077 {
9078   unformat_input_t *i = vam->input;
9079   vl_api_mpls_table_add_del_t *mp;
9080   u32 table_id = ~0;
9081   u8 is_add = 1;
9082   int ret = 0;
9083
9084   /* Parse args required to build the message */
9085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9086     {
9087       if (unformat (i, "table %d", &table_id))
9088         ;
9089       else if (unformat (i, "del"))
9090         is_add = 0;
9091       else if (unformat (i, "add"))
9092         is_add = 1;
9093       else
9094         {
9095           clib_warning ("parse error '%U'", format_unformat_error, i);
9096           return -99;
9097         }
9098     }
9099
9100   if (~0 == table_id)
9101     {
9102       errmsg ("missing table-ID");
9103       return -99;
9104     }
9105
9106   /* Construct the API message */
9107   M (MPLS_TABLE_ADD_DEL, mp);
9108
9109   mp->mt_table_id = ntohl (table_id);
9110   mp->mt_is_add = is_add;
9111
9112   /* send it... */
9113   S (mp);
9114
9115   /* Wait for a reply... */
9116   W (ret);
9117
9118   return ret;
9119 }
9120
9121 static int
9122 api_mpls_route_add_del (vat_main_t * vam)
9123 {
9124   unformat_input_t *i = vam->input;
9125   vl_api_mpls_route_add_del_t *mp;
9126   u32 sw_if_index = ~0, table_id = 0;
9127   u8 is_add = 1;
9128   u32 next_hop_weight = 1;
9129   u8 is_multipath = 0;
9130   u32 next_hop_table_id = 0;
9131   u8 next_hop_set = 0;
9132   ip4_address_t v4_next_hop_address = {
9133     .as_u32 = 0,
9134   };
9135   ip6_address_t v6_next_hop_address = { {0} };
9136   int count = 1;
9137   int j;
9138   f64 before = 0;
9139   u32 classify_table_index = ~0;
9140   u8 is_classify = 0;
9141   u8 resolve_host = 0, resolve_attached = 0;
9142   u8 is_interface_rx = 0;
9143   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9144   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9145   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9146   mpls_label_t local_label = MPLS_LABEL_INVALID;
9147   u8 is_eos = 0;
9148   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9149
9150   /* Parse args required to build the message */
9151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9152     {
9153       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9154         ;
9155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9156         ;
9157       else if (unformat (i, "%d", &local_label))
9158         ;
9159       else if (unformat (i, "eos"))
9160         is_eos = 1;
9161       else if (unformat (i, "non-eos"))
9162         is_eos = 0;
9163       else if (unformat (i, "via %U", unformat_ip4_address,
9164                          &v4_next_hop_address))
9165         {
9166           next_hop_set = 1;
9167           next_hop_proto = DPO_PROTO_IP4;
9168         }
9169       else if (unformat (i, "via %U", unformat_ip6_address,
9170                          &v6_next_hop_address))
9171         {
9172           next_hop_set = 1;
9173           next_hop_proto = DPO_PROTO_IP6;
9174         }
9175       else if (unformat (i, "weight %d", &next_hop_weight))
9176         ;
9177       else if (unformat (i, "classify %d", &classify_table_index))
9178         {
9179           is_classify = 1;
9180         }
9181       else if (unformat (i, "del"))
9182         is_add = 0;
9183       else if (unformat (i, "add"))
9184         is_add = 1;
9185       else if (unformat (i, "resolve-via-host"))
9186         resolve_host = 1;
9187       else if (unformat (i, "resolve-via-attached"))
9188         resolve_attached = 1;
9189       else if (unformat (i, "multipath"))
9190         is_multipath = 1;
9191       else if (unformat (i, "count %d", &count))
9192         ;
9193       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9194         {
9195           next_hop_set = 1;
9196           next_hop_proto = DPO_PROTO_IP4;
9197         }
9198       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9199         {
9200           next_hop_set = 1;
9201           next_hop_proto = DPO_PROTO_IP6;
9202         }
9203       else
9204         if (unformat
9205             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9206              &sw_if_index))
9207         {
9208           next_hop_set = 1;
9209           next_hop_proto = DPO_PROTO_ETHERNET;
9210           is_interface_rx = 1;
9211         }
9212       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9213         {
9214           next_hop_set = 1;
9215           next_hop_proto = DPO_PROTO_ETHERNET;
9216           is_interface_rx = 1;
9217         }
9218       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9219         next_hop_set = 1;
9220       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9221         next_hop_set = 1;
9222       else if (unformat (i, "out-label %d", &next_hop_out_label))
9223         {
9224           vl_api_fib_mpls_label_t fib_label = {
9225             .label = ntohl (next_hop_out_label),
9226             .ttl = 64,
9227             .exp = 0,
9228           };
9229           vec_add1 (next_hop_out_label_stack, fib_label);
9230         }
9231       else
9232         {
9233           clib_warning ("parse error '%U'", format_unformat_error, i);
9234           return -99;
9235         }
9236     }
9237
9238   if (!next_hop_set && !is_classify)
9239     {
9240       errmsg ("next hop / classify not set");
9241       return -99;
9242     }
9243
9244   if (MPLS_LABEL_INVALID == local_label)
9245     {
9246       errmsg ("missing label");
9247       return -99;
9248     }
9249
9250   if (count > 1)
9251     {
9252       /* Turn on async mode */
9253       vam->async_mode = 1;
9254       vam->async_errors = 0;
9255       before = vat_time_now (vam);
9256     }
9257
9258   for (j = 0; j < count; j++)
9259     {
9260       /* Construct the API message */
9261       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9262           vec_len (next_hop_out_label_stack));
9263
9264       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9265       mp->mr_table_id = ntohl (table_id);
9266
9267       mp->mr_is_add = is_add;
9268       mp->mr_next_hop_proto = next_hop_proto;
9269       mp->mr_is_classify = is_classify;
9270       mp->mr_is_multipath = is_multipath;
9271       mp->mr_is_resolve_host = resolve_host;
9272       mp->mr_is_resolve_attached = resolve_attached;
9273       mp->mr_is_interface_rx = is_interface_rx;
9274       mp->mr_next_hop_weight = next_hop_weight;
9275       mp->mr_next_hop_preference = 0;
9276       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9277       mp->mr_classify_table_index = ntohl (classify_table_index);
9278       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9279       mp->mr_label = ntohl (local_label);
9280       mp->mr_eos = is_eos;
9281
9282       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9283       if (0 != mp->mr_next_hop_n_out_labels)
9284         {
9285           memcpy (mp->mr_next_hop_out_label_stack,
9286                   next_hop_out_label_stack,
9287                   vec_len (next_hop_out_label_stack) *
9288                   sizeof (vl_api_fib_mpls_label_t));
9289           vec_free (next_hop_out_label_stack);
9290         }
9291
9292       if (next_hop_set)
9293         {
9294           if (DPO_PROTO_IP4 == next_hop_proto)
9295             {
9296               clib_memcpy (mp->mr_next_hop,
9297                            &v4_next_hop_address,
9298                            sizeof (v4_next_hop_address));
9299             }
9300           else if (DPO_PROTO_IP6 == next_hop_proto)
9301
9302             {
9303               clib_memcpy (mp->mr_next_hop,
9304                            &v6_next_hop_address,
9305                            sizeof (v6_next_hop_address));
9306             }
9307         }
9308       local_label++;
9309
9310       /* send it... */
9311       S (mp);
9312       /* If we receive SIGTERM, stop now... */
9313       if (vam->do_exit)
9314         break;
9315     }
9316
9317   /* When testing multiple add/del ops, use a control-ping to sync */
9318   if (count > 1)
9319     {
9320       vl_api_control_ping_t *mp_ping;
9321       f64 after;
9322       f64 timeout;
9323
9324       /* Shut off async mode */
9325       vam->async_mode = 0;
9326
9327       MPING (CONTROL_PING, mp_ping);
9328       S (mp_ping);
9329
9330       timeout = vat_time_now (vam) + 1.0;
9331       while (vat_time_now (vam) < timeout)
9332         if (vam->result_ready == 1)
9333           goto out;
9334       vam->retval = -99;
9335
9336     out:
9337       if (vam->retval == -99)
9338         errmsg ("timeout");
9339
9340       if (vam->async_errors > 0)
9341         {
9342           errmsg ("%d asynchronous errors", vam->async_errors);
9343           vam->retval = -98;
9344         }
9345       vam->async_errors = 0;
9346       after = vat_time_now (vam);
9347
9348       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9349       if (j > 0)
9350         count = j;
9351
9352       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9353              count, after - before, count / (after - before));
9354     }
9355   else
9356     {
9357       int ret;
9358
9359       /* Wait for a reply... */
9360       W (ret);
9361       return ret;
9362     }
9363
9364   /* Return the good/bad news */
9365   return (vam->retval);
9366 }
9367
9368 static int
9369 api_mpls_ip_bind_unbind (vat_main_t * vam)
9370 {
9371   unformat_input_t *i = vam->input;
9372   vl_api_mpls_ip_bind_unbind_t *mp;
9373   u32 ip_table_id = 0;
9374   u8 is_bind = 1;
9375   u8 is_ip4 = 1;
9376   ip4_address_t v4_address;
9377   ip6_address_t v6_address;
9378   u32 address_length;
9379   u8 address_set = 0;
9380   mpls_label_t local_label = MPLS_LABEL_INVALID;
9381   int ret;
9382
9383   /* Parse args required to build the message */
9384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9385     {
9386       if (unformat (i, "%U/%d", unformat_ip4_address,
9387                     &v4_address, &address_length))
9388         {
9389           is_ip4 = 1;
9390           address_set = 1;
9391         }
9392       else if (unformat (i, "%U/%d", unformat_ip6_address,
9393                          &v6_address, &address_length))
9394         {
9395           is_ip4 = 0;
9396           address_set = 1;
9397         }
9398       else if (unformat (i, "%d", &local_label))
9399         ;
9400       else if (unformat (i, "table-id %d", &ip_table_id))
9401         ;
9402       else if (unformat (i, "unbind"))
9403         is_bind = 0;
9404       else if (unformat (i, "bind"))
9405         is_bind = 1;
9406       else
9407         {
9408           clib_warning ("parse error '%U'", format_unformat_error, i);
9409           return -99;
9410         }
9411     }
9412
9413   if (!address_set)
9414     {
9415       errmsg ("IP address not set");
9416       return -99;
9417     }
9418
9419   if (MPLS_LABEL_INVALID == local_label)
9420     {
9421       errmsg ("missing label");
9422       return -99;
9423     }
9424
9425   /* Construct the API message */
9426   M (MPLS_IP_BIND_UNBIND, mp);
9427
9428   mp->mb_is_bind = is_bind;
9429   mp->mb_is_ip4 = is_ip4;
9430   mp->mb_ip_table_id = ntohl (ip_table_id);
9431   mp->mb_mpls_table_id = 0;
9432   mp->mb_label = ntohl (local_label);
9433   mp->mb_address_length = address_length;
9434
9435   if (is_ip4)
9436     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9437   else
9438     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9439
9440   /* send it... */
9441   S (mp);
9442
9443   /* Wait for a reply... */
9444   W (ret);
9445   return ret;
9446 }
9447
9448 static int
9449 api_sr_mpls_policy_add (vat_main_t * vam)
9450 {
9451   unformat_input_t *i = vam->input;
9452   vl_api_sr_mpls_policy_add_t *mp;
9453   u32 bsid = 0;
9454   u32 weight = 1;
9455   u8 type = 0;
9456   u8 n_segments = 0;
9457   u32 sid;
9458   u32 *segments = NULL;
9459   int ret;
9460
9461   /* Parse args required to build the message */
9462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9463     {
9464       if (unformat (i, "bsid %d", &bsid))
9465         ;
9466       else if (unformat (i, "weight %d", &weight))
9467         ;
9468       else if (unformat (i, "spray"))
9469         type = 1;
9470       else if (unformat (i, "next %d", &sid))
9471         {
9472           n_segments += 1;
9473           vec_add1 (segments, htonl (sid));
9474         }
9475       else
9476         {
9477           clib_warning ("parse error '%U'", format_unformat_error, i);
9478           return -99;
9479         }
9480     }
9481
9482   if (bsid == 0)
9483     {
9484       errmsg ("bsid not set");
9485       return -99;
9486     }
9487
9488   if (n_segments == 0)
9489     {
9490       errmsg ("no sid in segment stack");
9491       return -99;
9492     }
9493
9494   /* Construct the API message */
9495   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9496
9497   mp->bsid = htonl (bsid);
9498   mp->weight = htonl (weight);
9499   mp->type = type;
9500   mp->n_segments = n_segments;
9501   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9502   vec_free (segments);
9503
9504   /* send it... */
9505   S (mp);
9506
9507   /* Wait for a reply... */
9508   W (ret);
9509   return ret;
9510 }
9511
9512 static int
9513 api_sr_mpls_policy_del (vat_main_t * vam)
9514 {
9515   unformat_input_t *i = vam->input;
9516   vl_api_sr_mpls_policy_del_t *mp;
9517   u32 bsid = 0;
9518   int ret;
9519
9520   /* Parse args required to build the message */
9521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9522     {
9523       if (unformat (i, "bsid %d", &bsid))
9524         ;
9525       else
9526         {
9527           clib_warning ("parse error '%U'", format_unformat_error, i);
9528           return -99;
9529         }
9530     }
9531
9532   if (bsid == 0)
9533     {
9534       errmsg ("bsid not set");
9535       return -99;
9536     }
9537
9538   /* Construct the API message */
9539   M (SR_MPLS_POLICY_DEL, mp);
9540
9541   mp->bsid = htonl (bsid);
9542
9543   /* send it... */
9544   S (mp);
9545
9546   /* Wait for a reply... */
9547   W (ret);
9548   return ret;
9549 }
9550
9551 static int
9552 api_bier_table_add_del (vat_main_t * vam)
9553 {
9554   unformat_input_t *i = vam->input;
9555   vl_api_bier_table_add_del_t *mp;
9556   u8 is_add = 1;
9557   u32 set = 0, sub_domain = 0, hdr_len = 3;
9558   mpls_label_t local_label = MPLS_LABEL_INVALID;
9559   int ret;
9560
9561   /* Parse args required to build the message */
9562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9563     {
9564       if (unformat (i, "sub-domain %d", &sub_domain))
9565         ;
9566       else if (unformat (i, "set %d", &set))
9567         ;
9568       else if (unformat (i, "label %d", &local_label))
9569         ;
9570       else if (unformat (i, "hdr-len %d", &hdr_len))
9571         ;
9572       else if (unformat (i, "add"))
9573         is_add = 1;
9574       else if (unformat (i, "del"))
9575         is_add = 0;
9576       else
9577         {
9578           clib_warning ("parse error '%U'", format_unformat_error, i);
9579           return -99;
9580         }
9581     }
9582
9583   if (MPLS_LABEL_INVALID == local_label)
9584     {
9585       errmsg ("missing label\n");
9586       return -99;
9587     }
9588
9589   /* Construct the API message */
9590   M (BIER_TABLE_ADD_DEL, mp);
9591
9592   mp->bt_is_add = is_add;
9593   mp->bt_label = ntohl (local_label);
9594   mp->bt_tbl_id.bt_set = set;
9595   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9596   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9597
9598   /* send it... */
9599   S (mp);
9600
9601   /* Wait for a reply... */
9602   W (ret);
9603
9604   return (ret);
9605 }
9606
9607 static int
9608 api_bier_route_add_del (vat_main_t * vam)
9609 {
9610   unformat_input_t *i = vam->input;
9611   vl_api_bier_route_add_del_t *mp;
9612   u8 is_add = 1;
9613   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9614   ip4_address_t v4_next_hop_address;
9615   ip6_address_t v6_next_hop_address;
9616   u8 next_hop_set = 0;
9617   u8 next_hop_proto_is_ip4 = 1;
9618   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9619   int ret;
9620
9621   /* Parse args required to build the message */
9622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9623     {
9624       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9625         {
9626           next_hop_proto_is_ip4 = 1;
9627           next_hop_set = 1;
9628         }
9629       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9630         {
9631           next_hop_proto_is_ip4 = 0;
9632           next_hop_set = 1;
9633         }
9634       if (unformat (i, "sub-domain %d", &sub_domain))
9635         ;
9636       else if (unformat (i, "set %d", &set))
9637         ;
9638       else if (unformat (i, "hdr-len %d", &hdr_len))
9639         ;
9640       else if (unformat (i, "bp %d", &bp))
9641         ;
9642       else if (unformat (i, "add"))
9643         is_add = 1;
9644       else if (unformat (i, "del"))
9645         is_add = 0;
9646       else if (unformat (i, "out-label %d", &next_hop_out_label))
9647         ;
9648       else
9649         {
9650           clib_warning ("parse error '%U'", format_unformat_error, i);
9651           return -99;
9652         }
9653     }
9654
9655   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9656     {
9657       errmsg ("next hop / label set\n");
9658       return -99;
9659     }
9660   if (0 == bp)
9661     {
9662       errmsg ("bit=position not set\n");
9663       return -99;
9664     }
9665
9666   /* Construct the API message */
9667   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9668
9669   mp->br_is_add = is_add;
9670   mp->br_tbl_id.bt_set = set;
9671   mp->br_tbl_id.bt_sub_domain = sub_domain;
9672   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9673   mp->br_bp = ntohs (bp);
9674   mp->br_n_paths = 1;
9675   mp->br_paths[0].n_labels = 1;
9676   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9677   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9678
9679   if (next_hop_proto_is_ip4)
9680     {
9681       clib_memcpy (mp->br_paths[0].next_hop,
9682                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9683     }
9684   else
9685     {
9686       clib_memcpy (mp->br_paths[0].next_hop,
9687                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9688     }
9689
9690   /* send it... */
9691   S (mp);
9692
9693   /* Wait for a reply... */
9694   W (ret);
9695
9696   return (ret);
9697 }
9698
9699 static int
9700 api_proxy_arp_add_del (vat_main_t * vam)
9701 {
9702   unformat_input_t *i = vam->input;
9703   vl_api_proxy_arp_add_del_t *mp;
9704   u32 vrf_id = 0;
9705   u8 is_add = 1;
9706   ip4_address_t lo, hi;
9707   u8 range_set = 0;
9708   int ret;
9709
9710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9711     {
9712       if (unformat (i, "vrf %d", &vrf_id))
9713         ;
9714       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9715                          unformat_ip4_address, &hi))
9716         range_set = 1;
9717       else if (unformat (i, "del"))
9718         is_add = 0;
9719       else
9720         {
9721           clib_warning ("parse error '%U'", format_unformat_error, i);
9722           return -99;
9723         }
9724     }
9725
9726   if (range_set == 0)
9727     {
9728       errmsg ("address range not set");
9729       return -99;
9730     }
9731
9732   M (PROXY_ARP_ADD_DEL, mp);
9733
9734   mp->proxy.vrf_id = ntohl (vrf_id);
9735   mp->is_add = is_add;
9736   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9737   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9738
9739   S (mp);
9740   W (ret);
9741   return ret;
9742 }
9743
9744 static int
9745 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9749   u32 sw_if_index;
9750   u8 enable = 1;
9751   u8 sw_if_index_set = 0;
9752   int ret;
9753
9754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9755     {
9756       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9757         sw_if_index_set = 1;
9758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9759         sw_if_index_set = 1;
9760       else if (unformat (i, "enable"))
9761         enable = 1;
9762       else if (unformat (i, "disable"))
9763         enable = 0;
9764       else
9765         {
9766           clib_warning ("parse error '%U'", format_unformat_error, i);
9767           return -99;
9768         }
9769     }
9770
9771   if (sw_if_index_set == 0)
9772     {
9773       errmsg ("missing interface name or sw_if_index");
9774       return -99;
9775     }
9776
9777   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9778
9779   mp->sw_if_index = ntohl (sw_if_index);
9780   mp->enable_disable = enable;
9781
9782   S (mp);
9783   W (ret);
9784   return ret;
9785 }
9786
9787 static int
9788 api_mpls_tunnel_add_del (vat_main_t * vam)
9789 {
9790   unformat_input_t *i = vam->input;
9791   vl_api_mpls_tunnel_add_del_t *mp;
9792
9793   u8 is_add = 1;
9794   u8 l2_only = 0;
9795   u32 sw_if_index = ~0;
9796   u32 next_hop_sw_if_index = ~0;
9797   u32 next_hop_proto_is_ip4 = 1;
9798
9799   u32 next_hop_table_id = 0;
9800   ip4_address_t v4_next_hop_address = {
9801     .as_u32 = 0,
9802   };
9803   ip6_address_t v6_next_hop_address = { {0} };
9804   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9805   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9806   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9807   int ret;
9808
9809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9810     {
9811       if (unformat (i, "add"))
9812         is_add = 1;
9813       else
9814         if (unformat
9815             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9816         is_add = 0;
9817       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9818         is_add = 0;
9819       else if (unformat (i, "via %U",
9820                          unformat_ip4_address, &v4_next_hop_address))
9821         {
9822           next_hop_proto_is_ip4 = 1;
9823         }
9824       else if (unformat (i, "via %U",
9825                          unformat_ip6_address, &v6_next_hop_address))
9826         {
9827           next_hop_proto_is_ip4 = 0;
9828         }
9829       else if (unformat (i, "via-label %d", &next_hop_via_label))
9830         ;
9831       else
9832         if (unformat
9833             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9834         ;
9835       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9836         ;
9837       else if (unformat (i, "l2-only"))
9838         l2_only = 1;
9839       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9840         ;
9841       else if (unformat (i, "out-label %d", &next_hop_out_label))
9842         {
9843           vl_api_fib_mpls_label_t fib_label = {
9844             .label = ntohl (next_hop_out_label),
9845             .ttl = 64,
9846             .exp = 0,
9847           };
9848           vec_add1 (next_hop_out_label_stack, fib_label);
9849         }
9850       else
9851         {
9852           clib_warning ("parse error '%U'", format_unformat_error, i);
9853           return -99;
9854         }
9855     }
9856
9857   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9858       vec_len (next_hop_out_label_stack));
9859
9860   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9861   mp->mt_sw_if_index = ntohl (sw_if_index);
9862   mp->mt_is_add = is_add;
9863   mp->mt_l2_only = l2_only;
9864   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9865   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9866   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9867   mp->mt_next_hop_weight = 1;
9868   mp->mt_next_hop_preference = 0;
9869
9870   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9871
9872   if (0 != mp->mt_next_hop_n_out_labels)
9873     {
9874       clib_memcpy (mp->mt_next_hop_out_label_stack,
9875                    next_hop_out_label_stack,
9876                    (vec_len (next_hop_out_label_stack) *
9877                     sizeof (vl_api_fib_mpls_label_t)));
9878       vec_free (next_hop_out_label_stack);
9879     }
9880
9881   if (next_hop_proto_is_ip4)
9882     {
9883       clib_memcpy (mp->mt_next_hop,
9884                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9885     }
9886   else
9887     {
9888       clib_memcpy (mp->mt_next_hop,
9889                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9890     }
9891
9892   S (mp);
9893   W (ret);
9894   return ret;
9895 }
9896
9897 static int
9898 api_sw_interface_set_unnumbered (vat_main_t * vam)
9899 {
9900   unformat_input_t *i = vam->input;
9901   vl_api_sw_interface_set_unnumbered_t *mp;
9902   u32 sw_if_index;
9903   u32 unnum_sw_index = ~0;
9904   u8 is_add = 1;
9905   u8 sw_if_index_set = 0;
9906   int ret;
9907
9908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9909     {
9910       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9911         sw_if_index_set = 1;
9912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9913         sw_if_index_set = 1;
9914       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9915         ;
9916       else if (unformat (i, "del"))
9917         is_add = 0;
9918       else
9919         {
9920           clib_warning ("parse error '%U'", format_unformat_error, i);
9921           return -99;
9922         }
9923     }
9924
9925   if (sw_if_index_set == 0)
9926     {
9927       errmsg ("missing interface name or sw_if_index");
9928       return -99;
9929     }
9930
9931   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9932
9933   mp->sw_if_index = ntohl (sw_if_index);
9934   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9935   mp->is_add = is_add;
9936
9937   S (mp);
9938   W (ret);
9939   return ret;
9940 }
9941
9942 static int
9943 api_ip_neighbor_add_del (vat_main_t * vam)
9944 {
9945   unformat_input_t *i = vam->input;
9946   vl_api_ip_neighbor_add_del_t *mp;
9947   u32 sw_if_index;
9948   u8 sw_if_index_set = 0;
9949   u8 is_add = 1;
9950   u8 is_static = 0;
9951   u8 is_no_fib_entry = 0;
9952   u8 mac_address[6];
9953   u8 mac_set = 0;
9954   u8 v4_address_set = 0;
9955   u8 v6_address_set = 0;
9956   ip4_address_t v4address;
9957   ip6_address_t v6address;
9958   int ret;
9959
9960   clib_memset (mac_address, 0, sizeof (mac_address));
9961
9962   /* Parse args required to build the message */
9963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9964     {
9965       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9966         {
9967           mac_set = 1;
9968         }
9969       else if (unformat (i, "del"))
9970         is_add = 0;
9971       else
9972         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9973         sw_if_index_set = 1;
9974       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9975         sw_if_index_set = 1;
9976       else if (unformat (i, "is_static"))
9977         is_static = 1;
9978       else if (unformat (i, "no-fib-entry"))
9979         is_no_fib_entry = 1;
9980       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9981         v4_address_set = 1;
9982       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9983         v6_address_set = 1;
9984       else
9985         {
9986           clib_warning ("parse error '%U'", format_unformat_error, i);
9987           return -99;
9988         }
9989     }
9990
9991   if (sw_if_index_set == 0)
9992     {
9993       errmsg ("missing interface name or sw_if_index");
9994       return -99;
9995     }
9996   if (v4_address_set && v6_address_set)
9997     {
9998       errmsg ("both v4 and v6 addresses set");
9999       return -99;
10000     }
10001   if (!v4_address_set && !v6_address_set)
10002     {
10003       errmsg ("no address set");
10004       return -99;
10005     }
10006
10007   /* Construct the API message */
10008   M (IP_NEIGHBOR_ADD_DEL, mp);
10009
10010   mp->sw_if_index = ntohl (sw_if_index);
10011   mp->is_add = is_add;
10012   mp->is_static = is_static;
10013   mp->is_no_adj_fib = is_no_fib_entry;
10014   if (mac_set)
10015     clib_memcpy (mp->mac_address, mac_address, 6);
10016   if (v6_address_set)
10017     {
10018       mp->is_ipv6 = 1;
10019       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
10020     }
10021   else
10022     {
10023       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
10024       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
10025     }
10026
10027   /* send it... */
10028   S (mp);
10029
10030   /* Wait for a reply, return good/bad news  */
10031   W (ret);
10032   return ret;
10033 }
10034
10035 static int
10036 api_create_vlan_subif (vat_main_t * vam)
10037 {
10038   unformat_input_t *i = vam->input;
10039   vl_api_create_vlan_subif_t *mp;
10040   u32 sw_if_index;
10041   u8 sw_if_index_set = 0;
10042   u32 vlan_id;
10043   u8 vlan_id_set = 0;
10044   int ret;
10045
10046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10047     {
10048       if (unformat (i, "sw_if_index %d", &sw_if_index))
10049         sw_if_index_set = 1;
10050       else
10051         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10052         sw_if_index_set = 1;
10053       else if (unformat (i, "vlan %d", &vlan_id))
10054         vlan_id_set = 1;
10055       else
10056         {
10057           clib_warning ("parse error '%U'", format_unformat_error, i);
10058           return -99;
10059         }
10060     }
10061
10062   if (sw_if_index_set == 0)
10063     {
10064       errmsg ("missing interface name or sw_if_index");
10065       return -99;
10066     }
10067
10068   if (vlan_id_set == 0)
10069     {
10070       errmsg ("missing vlan_id");
10071       return -99;
10072     }
10073   M (CREATE_VLAN_SUBIF, mp);
10074
10075   mp->sw_if_index = ntohl (sw_if_index);
10076   mp->vlan_id = ntohl (vlan_id);
10077
10078   S (mp);
10079   W (ret);
10080   return ret;
10081 }
10082
10083 #define foreach_create_subif_bit                \
10084 _(no_tags)                                      \
10085 _(one_tag)                                      \
10086 _(two_tags)                                     \
10087 _(dot1ad)                                       \
10088 _(exact_match)                                  \
10089 _(default_sub)                                  \
10090 _(outer_vlan_id_any)                            \
10091 _(inner_vlan_id_any)
10092
10093 static int
10094 api_create_subif (vat_main_t * vam)
10095 {
10096   unformat_input_t *i = vam->input;
10097   vl_api_create_subif_t *mp;
10098   u32 sw_if_index;
10099   u8 sw_if_index_set = 0;
10100   u32 sub_id;
10101   u8 sub_id_set = 0;
10102   u32 no_tags = 0;
10103   u32 one_tag = 0;
10104   u32 two_tags = 0;
10105   u32 dot1ad = 0;
10106   u32 exact_match = 0;
10107   u32 default_sub = 0;
10108   u32 outer_vlan_id_any = 0;
10109   u32 inner_vlan_id_any = 0;
10110   u32 tmp;
10111   u16 outer_vlan_id = 0;
10112   u16 inner_vlan_id = 0;
10113   int ret;
10114
10115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10116     {
10117       if (unformat (i, "sw_if_index %d", &sw_if_index))
10118         sw_if_index_set = 1;
10119       else
10120         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10121         sw_if_index_set = 1;
10122       else if (unformat (i, "sub_id %d", &sub_id))
10123         sub_id_set = 1;
10124       else if (unformat (i, "outer_vlan_id %d", &tmp))
10125         outer_vlan_id = tmp;
10126       else if (unformat (i, "inner_vlan_id %d", &tmp))
10127         inner_vlan_id = tmp;
10128
10129 #define _(a) else if (unformat (i, #a)) a = 1 ;
10130       foreach_create_subif_bit
10131 #undef _
10132         else
10133         {
10134           clib_warning ("parse error '%U'", format_unformat_error, i);
10135           return -99;
10136         }
10137     }
10138
10139   if (sw_if_index_set == 0)
10140     {
10141       errmsg ("missing interface name or sw_if_index");
10142       return -99;
10143     }
10144
10145   if (sub_id_set == 0)
10146     {
10147       errmsg ("missing sub_id");
10148       return -99;
10149     }
10150   M (CREATE_SUBIF, mp);
10151
10152   mp->sw_if_index = ntohl (sw_if_index);
10153   mp->sub_id = ntohl (sub_id);
10154
10155 #define _(a) mp->a = a;
10156   foreach_create_subif_bit;
10157 #undef _
10158
10159   mp->outer_vlan_id = ntohs (outer_vlan_id);
10160   mp->inner_vlan_id = ntohs (inner_vlan_id);
10161
10162   S (mp);
10163   W (ret);
10164   return ret;
10165 }
10166
10167 static int
10168 api_oam_add_del (vat_main_t * vam)
10169 {
10170   unformat_input_t *i = vam->input;
10171   vl_api_oam_add_del_t *mp;
10172   u32 vrf_id = 0;
10173   u8 is_add = 1;
10174   ip4_address_t src, dst;
10175   u8 src_set = 0;
10176   u8 dst_set = 0;
10177   int ret;
10178
10179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10180     {
10181       if (unformat (i, "vrf %d", &vrf_id))
10182         ;
10183       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10184         src_set = 1;
10185       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10186         dst_set = 1;
10187       else if (unformat (i, "del"))
10188         is_add = 0;
10189       else
10190         {
10191           clib_warning ("parse error '%U'", format_unformat_error, i);
10192           return -99;
10193         }
10194     }
10195
10196   if (src_set == 0)
10197     {
10198       errmsg ("missing src addr");
10199       return -99;
10200     }
10201
10202   if (dst_set == 0)
10203     {
10204       errmsg ("missing dst addr");
10205       return -99;
10206     }
10207
10208   M (OAM_ADD_DEL, mp);
10209
10210   mp->vrf_id = ntohl (vrf_id);
10211   mp->is_add = is_add;
10212   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10213   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10214
10215   S (mp);
10216   W (ret);
10217   return ret;
10218 }
10219
10220 static int
10221 api_reset_fib (vat_main_t * vam)
10222 {
10223   unformat_input_t *i = vam->input;
10224   vl_api_reset_fib_t *mp;
10225   u32 vrf_id = 0;
10226   u8 is_ipv6 = 0;
10227   u8 vrf_id_set = 0;
10228
10229   int ret;
10230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10231     {
10232       if (unformat (i, "vrf %d", &vrf_id))
10233         vrf_id_set = 1;
10234       else if (unformat (i, "ipv6"))
10235         is_ipv6 = 1;
10236       else
10237         {
10238           clib_warning ("parse error '%U'", format_unformat_error, i);
10239           return -99;
10240         }
10241     }
10242
10243   if (vrf_id_set == 0)
10244     {
10245       errmsg ("missing vrf id");
10246       return -99;
10247     }
10248
10249   M (RESET_FIB, mp);
10250
10251   mp->vrf_id = ntohl (vrf_id);
10252   mp->is_ipv6 = is_ipv6;
10253
10254   S (mp);
10255   W (ret);
10256   return ret;
10257 }
10258
10259 static int
10260 api_dhcp_proxy_config (vat_main_t * vam)
10261 {
10262   unformat_input_t *i = vam->input;
10263   vl_api_dhcp_proxy_config_t *mp;
10264   u32 rx_vrf_id = 0;
10265   u32 server_vrf_id = 0;
10266   u8 is_add = 1;
10267   u8 v4_address_set = 0;
10268   u8 v6_address_set = 0;
10269   ip4_address_t v4address;
10270   ip6_address_t v6address;
10271   u8 v4_src_address_set = 0;
10272   u8 v6_src_address_set = 0;
10273   ip4_address_t v4srcaddress;
10274   ip6_address_t v6srcaddress;
10275   int ret;
10276
10277   /* Parse args required to build the message */
10278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10279     {
10280       if (unformat (i, "del"))
10281         is_add = 0;
10282       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10283         ;
10284       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10285         ;
10286       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10287         v4_address_set = 1;
10288       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10289         v6_address_set = 1;
10290       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10291         v4_src_address_set = 1;
10292       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10293         v6_src_address_set = 1;
10294       else
10295         break;
10296     }
10297
10298   if (v4_address_set && v6_address_set)
10299     {
10300       errmsg ("both v4 and v6 server addresses set");
10301       return -99;
10302     }
10303   if (!v4_address_set && !v6_address_set)
10304     {
10305       errmsg ("no server addresses set");
10306       return -99;
10307     }
10308
10309   if (v4_src_address_set && v6_src_address_set)
10310     {
10311       errmsg ("both v4 and v6  src addresses set");
10312       return -99;
10313     }
10314   if (!v4_src_address_set && !v6_src_address_set)
10315     {
10316       errmsg ("no src addresses set");
10317       return -99;
10318     }
10319
10320   if (!(v4_src_address_set && v4_address_set) &&
10321       !(v6_src_address_set && v6_address_set))
10322     {
10323       errmsg ("no matching server and src addresses set");
10324       return -99;
10325     }
10326
10327   /* Construct the API message */
10328   M (DHCP_PROXY_CONFIG, mp);
10329
10330   mp->is_add = is_add;
10331   mp->rx_vrf_id = ntohl (rx_vrf_id);
10332   mp->server_vrf_id = ntohl (server_vrf_id);
10333   if (v6_address_set)
10334     {
10335       mp->is_ipv6 = 1;
10336       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10337       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10338     }
10339   else
10340     {
10341       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10342       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10343     }
10344
10345   /* send it... */
10346   S (mp);
10347
10348   /* Wait for a reply, return good/bad news  */
10349   W (ret);
10350   return ret;
10351 }
10352
10353 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10354 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10355
10356 static void
10357 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10358 {
10359   vat_main_t *vam = &vat_main;
10360   u32 i, count = mp->count;
10361   vl_api_dhcp_server_t *s;
10362
10363   if (mp->is_ipv6)
10364     print (vam->ofp,
10365            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10366            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10367            ntohl (mp->rx_vrf_id),
10368            format_ip6_address, mp->dhcp_src_address,
10369            mp->vss_type, mp->vss_vpn_ascii_id,
10370            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10371   else
10372     print (vam->ofp,
10373            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10374            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10375            ntohl (mp->rx_vrf_id),
10376            format_ip4_address, mp->dhcp_src_address,
10377            mp->vss_type, mp->vss_vpn_ascii_id,
10378            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10379
10380   for (i = 0; i < count; i++)
10381     {
10382       s = &mp->servers[i];
10383
10384       if (mp->is_ipv6)
10385         print (vam->ofp,
10386                " Server Table-ID %d, Server Address %U",
10387                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10388       else
10389         print (vam->ofp,
10390                " Server Table-ID %d, Server Address %U",
10391                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10392     }
10393 }
10394
10395 static void vl_api_dhcp_proxy_details_t_handler_json
10396   (vl_api_dhcp_proxy_details_t * mp)
10397 {
10398   vat_main_t *vam = &vat_main;
10399   vat_json_node_t *node = NULL;
10400   u32 i, count = mp->count;
10401   struct in_addr ip4;
10402   struct in6_addr ip6;
10403   vl_api_dhcp_server_t *s;
10404
10405   if (VAT_JSON_ARRAY != vam->json_tree.type)
10406     {
10407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10408       vat_json_init_array (&vam->json_tree);
10409     }
10410   node = vat_json_array_add (&vam->json_tree);
10411
10412   vat_json_init_object (node);
10413   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10414   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10415                              sizeof (mp->vss_type));
10416   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10417                                    mp->vss_vpn_ascii_id);
10418   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10419   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10420
10421   if (mp->is_ipv6)
10422     {
10423       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10424       vat_json_object_add_ip6 (node, "src_address", ip6);
10425     }
10426   else
10427     {
10428       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10429       vat_json_object_add_ip4 (node, "src_address", ip4);
10430     }
10431
10432   for (i = 0; i < count; i++)
10433     {
10434       s = &mp->servers[i];
10435
10436       vat_json_object_add_uint (node, "server-table-id",
10437                                 ntohl (s->server_vrf_id));
10438
10439       if (mp->is_ipv6)
10440         {
10441           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10442           vat_json_object_add_ip4 (node, "src_address", ip4);
10443         }
10444       else
10445         {
10446           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10447           vat_json_object_add_ip6 (node, "server_address", ip6);
10448         }
10449     }
10450 }
10451
10452 static int
10453 api_dhcp_proxy_dump (vat_main_t * vam)
10454 {
10455   unformat_input_t *i = vam->input;
10456   vl_api_control_ping_t *mp_ping;
10457   vl_api_dhcp_proxy_dump_t *mp;
10458   u8 is_ipv6 = 0;
10459   int ret;
10460
10461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10462     {
10463       if (unformat (i, "ipv6"))
10464         is_ipv6 = 1;
10465       else
10466         {
10467           clib_warning ("parse error '%U'", format_unformat_error, i);
10468           return -99;
10469         }
10470     }
10471
10472   M (DHCP_PROXY_DUMP, mp);
10473
10474   mp->is_ip6 = is_ipv6;
10475   S (mp);
10476
10477   /* Use a control ping for synchronization */
10478   MPING (CONTROL_PING, mp_ping);
10479   S (mp_ping);
10480
10481   W (ret);
10482   return ret;
10483 }
10484
10485 static int
10486 api_dhcp_proxy_set_vss (vat_main_t * vam)
10487 {
10488   unformat_input_t *i = vam->input;
10489   vl_api_dhcp_proxy_set_vss_t *mp;
10490   u8 is_ipv6 = 0;
10491   u8 is_add = 1;
10492   u32 tbl_id = ~0;
10493   u8 vss_type = VSS_TYPE_DEFAULT;
10494   u8 *vpn_ascii_id = 0;
10495   u32 oui = 0;
10496   u32 fib_id = 0;
10497   int ret;
10498
10499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10500     {
10501       if (unformat (i, "tbl_id %d", &tbl_id))
10502         ;
10503       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10504         vss_type = VSS_TYPE_ASCII;
10505       else if (unformat (i, "fib_id %d", &fib_id))
10506         vss_type = VSS_TYPE_VPN_ID;
10507       else if (unformat (i, "oui %d", &oui))
10508         vss_type = VSS_TYPE_VPN_ID;
10509       else if (unformat (i, "ipv6"))
10510         is_ipv6 = 1;
10511       else if (unformat (i, "del"))
10512         is_add = 0;
10513       else
10514         break;
10515     }
10516
10517   if (tbl_id == ~0)
10518     {
10519       errmsg ("missing tbl_id ");
10520       vec_free (vpn_ascii_id);
10521       return -99;
10522     }
10523
10524   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10525     {
10526       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10527       vec_free (vpn_ascii_id);
10528       return -99;
10529     }
10530
10531   M (DHCP_PROXY_SET_VSS, mp);
10532   mp->tbl_id = ntohl (tbl_id);
10533   mp->vss_type = vss_type;
10534   if (vpn_ascii_id)
10535     {
10536       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10537       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10538     }
10539   mp->vpn_index = ntohl (fib_id);
10540   mp->oui = ntohl (oui);
10541   mp->is_ipv6 = is_ipv6;
10542   mp->is_add = is_add;
10543
10544   S (mp);
10545   W (ret);
10546
10547   vec_free (vpn_ascii_id);
10548   return ret;
10549 }
10550
10551 static int
10552 api_dhcp_client_config (vat_main_t * vam)
10553 {
10554   unformat_input_t *i = vam->input;
10555   vl_api_dhcp_client_config_t *mp;
10556   u32 sw_if_index;
10557   u8 sw_if_index_set = 0;
10558   u8 is_add = 1;
10559   u8 *hostname = 0;
10560   u8 disable_event = 0;
10561   int ret;
10562
10563   /* Parse args required to build the message */
10564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (i, "del"))
10567         is_add = 0;
10568       else
10569         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10570         sw_if_index_set = 1;
10571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10572         sw_if_index_set = 1;
10573       else if (unformat (i, "hostname %s", &hostname))
10574         ;
10575       else if (unformat (i, "disable_event"))
10576         disable_event = 1;
10577       else
10578         break;
10579     }
10580
10581   if (sw_if_index_set == 0)
10582     {
10583       errmsg ("missing interface name or sw_if_index");
10584       return -99;
10585     }
10586
10587   if (vec_len (hostname) > 63)
10588     {
10589       errmsg ("hostname too long");
10590     }
10591   vec_add1 (hostname, 0);
10592
10593   /* Construct the API message */
10594   M (DHCP_CLIENT_CONFIG, mp);
10595
10596   mp->is_add = is_add;
10597   mp->client.sw_if_index = htonl (sw_if_index);
10598   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10599   vec_free (hostname);
10600   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10601   mp->client.pid = htonl (getpid ());
10602
10603   /* send it... */
10604   S (mp);
10605
10606   /* Wait for a reply, return good/bad news  */
10607   W (ret);
10608   return ret;
10609 }
10610
10611 static int
10612 api_set_ip_flow_hash (vat_main_t * vam)
10613 {
10614   unformat_input_t *i = vam->input;
10615   vl_api_set_ip_flow_hash_t *mp;
10616   u32 vrf_id = 0;
10617   u8 is_ipv6 = 0;
10618   u8 vrf_id_set = 0;
10619   u8 src = 0;
10620   u8 dst = 0;
10621   u8 sport = 0;
10622   u8 dport = 0;
10623   u8 proto = 0;
10624   u8 reverse = 0;
10625   int ret;
10626
10627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10628     {
10629       if (unformat (i, "vrf %d", &vrf_id))
10630         vrf_id_set = 1;
10631       else if (unformat (i, "ipv6"))
10632         is_ipv6 = 1;
10633       else if (unformat (i, "src"))
10634         src = 1;
10635       else if (unformat (i, "dst"))
10636         dst = 1;
10637       else if (unformat (i, "sport"))
10638         sport = 1;
10639       else if (unformat (i, "dport"))
10640         dport = 1;
10641       else if (unformat (i, "proto"))
10642         proto = 1;
10643       else if (unformat (i, "reverse"))
10644         reverse = 1;
10645
10646       else
10647         {
10648           clib_warning ("parse error '%U'", format_unformat_error, i);
10649           return -99;
10650         }
10651     }
10652
10653   if (vrf_id_set == 0)
10654     {
10655       errmsg ("missing vrf id");
10656       return -99;
10657     }
10658
10659   M (SET_IP_FLOW_HASH, mp);
10660   mp->src = src;
10661   mp->dst = dst;
10662   mp->sport = sport;
10663   mp->dport = dport;
10664   mp->proto = proto;
10665   mp->reverse = reverse;
10666   mp->vrf_id = ntohl (vrf_id);
10667   mp->is_ipv6 = is_ipv6;
10668
10669   S (mp);
10670   W (ret);
10671   return ret;
10672 }
10673
10674 static int
10675 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10676 {
10677   unformat_input_t *i = vam->input;
10678   vl_api_sw_interface_ip6_enable_disable_t *mp;
10679   u32 sw_if_index;
10680   u8 sw_if_index_set = 0;
10681   u8 enable = 0;
10682   int ret;
10683
10684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10685     {
10686       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10687         sw_if_index_set = 1;
10688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10689         sw_if_index_set = 1;
10690       else if (unformat (i, "enable"))
10691         enable = 1;
10692       else if (unformat (i, "disable"))
10693         enable = 0;
10694       else
10695         {
10696           clib_warning ("parse error '%U'", format_unformat_error, i);
10697           return -99;
10698         }
10699     }
10700
10701   if (sw_if_index_set == 0)
10702     {
10703       errmsg ("missing interface name or sw_if_index");
10704       return -99;
10705     }
10706
10707   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10708
10709   mp->sw_if_index = ntohl (sw_if_index);
10710   mp->enable = enable;
10711
10712   S (mp);
10713   W (ret);
10714   return ret;
10715 }
10716
10717 static int
10718 api_ip6nd_proxy_add_del (vat_main_t * vam)
10719 {
10720   unformat_input_t *i = vam->input;
10721   vl_api_ip6nd_proxy_add_del_t *mp;
10722   u32 sw_if_index = ~0;
10723   u8 v6_address_set = 0;
10724   ip6_address_t v6address;
10725   u8 is_del = 0;
10726   int ret;
10727
10728   /* Parse args required to build the message */
10729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10730     {
10731       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10732         ;
10733       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10734         ;
10735       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10736         v6_address_set = 1;
10737       if (unformat (i, "del"))
10738         is_del = 1;
10739       else
10740         {
10741           clib_warning ("parse error '%U'", format_unformat_error, i);
10742           return -99;
10743         }
10744     }
10745
10746   if (sw_if_index == ~0)
10747     {
10748       errmsg ("missing interface name or sw_if_index");
10749       return -99;
10750     }
10751   if (!v6_address_set)
10752     {
10753       errmsg ("no address set");
10754       return -99;
10755     }
10756
10757   /* Construct the API message */
10758   M (IP6ND_PROXY_ADD_DEL, mp);
10759
10760   mp->is_del = is_del;
10761   mp->sw_if_index = ntohl (sw_if_index);
10762   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10763
10764   /* send it... */
10765   S (mp);
10766
10767   /* Wait for a reply, return good/bad news  */
10768   W (ret);
10769   return ret;
10770 }
10771
10772 static int
10773 api_ip6nd_proxy_dump (vat_main_t * vam)
10774 {
10775   vl_api_ip6nd_proxy_dump_t *mp;
10776   vl_api_control_ping_t *mp_ping;
10777   int ret;
10778
10779   M (IP6ND_PROXY_DUMP, mp);
10780
10781   S (mp);
10782
10783   /* Use a control ping for synchronization */
10784   MPING (CONTROL_PING, mp_ping);
10785   S (mp_ping);
10786
10787   W (ret);
10788   return ret;
10789 }
10790
10791 static void vl_api_ip6nd_proxy_details_t_handler
10792   (vl_api_ip6nd_proxy_details_t * mp)
10793 {
10794   vat_main_t *vam = &vat_main;
10795
10796   print (vam->ofp, "host %U sw_if_index %d",
10797          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10798 }
10799
10800 static void vl_api_ip6nd_proxy_details_t_handler_json
10801   (vl_api_ip6nd_proxy_details_t * mp)
10802 {
10803   vat_main_t *vam = &vat_main;
10804   struct in6_addr ip6;
10805   vat_json_node_t *node = NULL;
10806
10807   if (VAT_JSON_ARRAY != vam->json_tree.type)
10808     {
10809       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10810       vat_json_init_array (&vam->json_tree);
10811     }
10812   node = vat_json_array_add (&vam->json_tree);
10813
10814   vat_json_init_object (node);
10815   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10816
10817   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10818   vat_json_object_add_ip6 (node, "host", ip6);
10819 }
10820
10821 static int
10822 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10823 {
10824   unformat_input_t *i = vam->input;
10825   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10826   u32 sw_if_index;
10827   u8 sw_if_index_set = 0;
10828   u32 address_length = 0;
10829   u8 v6_address_set = 0;
10830   ip6_address_t v6address;
10831   u8 use_default = 0;
10832   u8 no_advertise = 0;
10833   u8 off_link = 0;
10834   u8 no_autoconfig = 0;
10835   u8 no_onlink = 0;
10836   u8 is_no = 0;
10837   u32 val_lifetime = 0;
10838   u32 pref_lifetime = 0;
10839   int ret;
10840
10841   /* Parse args required to build the message */
10842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10843     {
10844       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10845         sw_if_index_set = 1;
10846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10847         sw_if_index_set = 1;
10848       else if (unformat (i, "%U/%d",
10849                          unformat_ip6_address, &v6address, &address_length))
10850         v6_address_set = 1;
10851       else if (unformat (i, "val_life %d", &val_lifetime))
10852         ;
10853       else if (unformat (i, "pref_life %d", &pref_lifetime))
10854         ;
10855       else if (unformat (i, "def"))
10856         use_default = 1;
10857       else if (unformat (i, "noadv"))
10858         no_advertise = 1;
10859       else if (unformat (i, "offl"))
10860         off_link = 1;
10861       else if (unformat (i, "noauto"))
10862         no_autoconfig = 1;
10863       else if (unformat (i, "nolink"))
10864         no_onlink = 1;
10865       else if (unformat (i, "isno"))
10866         is_no = 1;
10867       else
10868         {
10869           clib_warning ("parse error '%U'", format_unformat_error, i);
10870           return -99;
10871         }
10872     }
10873
10874   if (sw_if_index_set == 0)
10875     {
10876       errmsg ("missing interface name or sw_if_index");
10877       return -99;
10878     }
10879   if (!v6_address_set)
10880     {
10881       errmsg ("no address set");
10882       return -99;
10883     }
10884
10885   /* Construct the API message */
10886   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10887
10888   mp->sw_if_index = ntohl (sw_if_index);
10889   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10890   mp->address_length = address_length;
10891   mp->use_default = use_default;
10892   mp->no_advertise = no_advertise;
10893   mp->off_link = off_link;
10894   mp->no_autoconfig = no_autoconfig;
10895   mp->no_onlink = no_onlink;
10896   mp->is_no = is_no;
10897   mp->val_lifetime = ntohl (val_lifetime);
10898   mp->pref_lifetime = ntohl (pref_lifetime);
10899
10900   /* send it... */
10901   S (mp);
10902
10903   /* Wait for a reply, return good/bad news  */
10904   W (ret);
10905   return ret;
10906 }
10907
10908 static int
10909 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10910 {
10911   unformat_input_t *i = vam->input;
10912   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10913   u32 sw_if_index;
10914   u8 sw_if_index_set = 0;
10915   u8 suppress = 0;
10916   u8 managed = 0;
10917   u8 other = 0;
10918   u8 ll_option = 0;
10919   u8 send_unicast = 0;
10920   u8 cease = 0;
10921   u8 is_no = 0;
10922   u8 default_router = 0;
10923   u32 max_interval = 0;
10924   u32 min_interval = 0;
10925   u32 lifetime = 0;
10926   u32 initial_count = 0;
10927   u32 initial_interval = 0;
10928   int ret;
10929
10930
10931   /* Parse args required to build the message */
10932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10933     {
10934       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10935         sw_if_index_set = 1;
10936       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10937         sw_if_index_set = 1;
10938       else if (unformat (i, "maxint %d", &max_interval))
10939         ;
10940       else if (unformat (i, "minint %d", &min_interval))
10941         ;
10942       else if (unformat (i, "life %d", &lifetime))
10943         ;
10944       else if (unformat (i, "count %d", &initial_count))
10945         ;
10946       else if (unformat (i, "interval %d", &initial_interval))
10947         ;
10948       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10949         suppress = 1;
10950       else if (unformat (i, "managed"))
10951         managed = 1;
10952       else if (unformat (i, "other"))
10953         other = 1;
10954       else if (unformat (i, "ll"))
10955         ll_option = 1;
10956       else if (unformat (i, "send"))
10957         send_unicast = 1;
10958       else if (unformat (i, "cease"))
10959         cease = 1;
10960       else if (unformat (i, "isno"))
10961         is_no = 1;
10962       else if (unformat (i, "def"))
10963         default_router = 1;
10964       else
10965         {
10966           clib_warning ("parse error '%U'", format_unformat_error, i);
10967           return -99;
10968         }
10969     }
10970
10971   if (sw_if_index_set == 0)
10972     {
10973       errmsg ("missing interface name or sw_if_index");
10974       return -99;
10975     }
10976
10977   /* Construct the API message */
10978   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10979
10980   mp->sw_if_index = ntohl (sw_if_index);
10981   mp->max_interval = ntohl (max_interval);
10982   mp->min_interval = ntohl (min_interval);
10983   mp->lifetime = ntohl (lifetime);
10984   mp->initial_count = ntohl (initial_count);
10985   mp->initial_interval = ntohl (initial_interval);
10986   mp->suppress = suppress;
10987   mp->managed = managed;
10988   mp->other = other;
10989   mp->ll_option = ll_option;
10990   mp->send_unicast = send_unicast;
10991   mp->cease = cease;
10992   mp->is_no = is_no;
10993   mp->default_router = default_router;
10994
10995   /* send it... */
10996   S (mp);
10997
10998   /* Wait for a reply, return good/bad news  */
10999   W (ret);
11000   return ret;
11001 }
11002
11003 static int
11004 api_set_arp_neighbor_limit (vat_main_t * vam)
11005 {
11006   unformat_input_t *i = vam->input;
11007   vl_api_set_arp_neighbor_limit_t *mp;
11008   u32 arp_nbr_limit;
11009   u8 limit_set = 0;
11010   u8 is_ipv6 = 0;
11011   int ret;
11012
11013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11014     {
11015       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
11016         limit_set = 1;
11017       else if (unformat (i, "ipv6"))
11018         is_ipv6 = 1;
11019       else
11020         {
11021           clib_warning ("parse error '%U'", format_unformat_error, i);
11022           return -99;
11023         }
11024     }
11025
11026   if (limit_set == 0)
11027     {
11028       errmsg ("missing limit value");
11029       return -99;
11030     }
11031
11032   M (SET_ARP_NEIGHBOR_LIMIT, mp);
11033
11034   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
11035   mp->is_ipv6 = is_ipv6;
11036
11037   S (mp);
11038   W (ret);
11039   return ret;
11040 }
11041
11042 static int
11043 api_l2_patch_add_del (vat_main_t * vam)
11044 {
11045   unformat_input_t *i = vam->input;
11046   vl_api_l2_patch_add_del_t *mp;
11047   u32 rx_sw_if_index;
11048   u8 rx_sw_if_index_set = 0;
11049   u32 tx_sw_if_index;
11050   u8 tx_sw_if_index_set = 0;
11051   u8 is_add = 1;
11052   int ret;
11053
11054   /* Parse args required to build the message */
11055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11056     {
11057       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
11058         rx_sw_if_index_set = 1;
11059       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
11060         tx_sw_if_index_set = 1;
11061       else if (unformat (i, "rx"))
11062         {
11063           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11064             {
11065               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11066                             &rx_sw_if_index))
11067                 rx_sw_if_index_set = 1;
11068             }
11069           else
11070             break;
11071         }
11072       else if (unformat (i, "tx"))
11073         {
11074           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11075             {
11076               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11077                             &tx_sw_if_index))
11078                 tx_sw_if_index_set = 1;
11079             }
11080           else
11081             break;
11082         }
11083       else if (unformat (i, "del"))
11084         is_add = 0;
11085       else
11086         break;
11087     }
11088
11089   if (rx_sw_if_index_set == 0)
11090     {
11091       errmsg ("missing rx interface name or rx_sw_if_index");
11092       return -99;
11093     }
11094
11095   if (tx_sw_if_index_set == 0)
11096     {
11097       errmsg ("missing tx interface name or tx_sw_if_index");
11098       return -99;
11099     }
11100
11101   M (L2_PATCH_ADD_DEL, mp);
11102
11103   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11104   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11105   mp->is_add = is_add;
11106
11107   S (mp);
11108   W (ret);
11109   return ret;
11110 }
11111
11112 u8 is_del;
11113 u8 localsid_addr[16];
11114 u8 end_psp;
11115 u8 behavior;
11116 u32 sw_if_index;
11117 u32 vlan_index;
11118 u32 fib_table;
11119 u8 nh_addr[16];
11120
11121 static int
11122 api_sr_localsid_add_del (vat_main_t * vam)
11123 {
11124   unformat_input_t *i = vam->input;
11125   vl_api_sr_localsid_add_del_t *mp;
11126
11127   u8 is_del;
11128   ip6_address_t localsid;
11129   u8 end_psp = 0;
11130   u8 behavior = ~0;
11131   u32 sw_if_index;
11132   u32 fib_table = ~(u32) 0;
11133   ip6_address_t nh_addr6;
11134   ip4_address_t nh_addr4;
11135   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
11136   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
11137
11138   bool nexthop_set = 0;
11139
11140   int ret;
11141
11142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11143     {
11144       if (unformat (i, "del"))
11145         is_del = 1;
11146       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11147       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11148         nexthop_set = 1;
11149       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11150         nexthop_set = 1;
11151       else if (unformat (i, "behavior %u", &behavior));
11152       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11153       else if (unformat (i, "fib-table %u", &fib_table));
11154       else if (unformat (i, "end.psp %u", &behavior));
11155       else
11156         break;
11157     }
11158
11159   M (SR_LOCALSID_ADD_DEL, mp);
11160
11161   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11162   if (nexthop_set)
11163     {
11164       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11165       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11166     }
11167   mp->behavior = behavior;
11168   mp->sw_if_index = ntohl (sw_if_index);
11169   mp->fib_table = ntohl (fib_table);
11170   mp->end_psp = end_psp;
11171   mp->is_del = is_del;
11172
11173   S (mp);
11174   W (ret);
11175   return ret;
11176 }
11177
11178 static int
11179 api_ioam_enable (vat_main_t * vam)
11180 {
11181   unformat_input_t *input = vam->input;
11182   vl_api_ioam_enable_t *mp;
11183   u32 id = 0;
11184   int has_trace_option = 0;
11185   int has_pot_option = 0;
11186   int has_seqno_option = 0;
11187   int has_analyse_option = 0;
11188   int ret;
11189
11190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11191     {
11192       if (unformat (input, "trace"))
11193         has_trace_option = 1;
11194       else if (unformat (input, "pot"))
11195         has_pot_option = 1;
11196       else if (unformat (input, "seqno"))
11197         has_seqno_option = 1;
11198       else if (unformat (input, "analyse"))
11199         has_analyse_option = 1;
11200       else
11201         break;
11202     }
11203   M (IOAM_ENABLE, mp);
11204   mp->id = htons (id);
11205   mp->seqno = has_seqno_option;
11206   mp->analyse = has_analyse_option;
11207   mp->pot_enable = has_pot_option;
11208   mp->trace_enable = has_trace_option;
11209
11210   S (mp);
11211   W (ret);
11212   return ret;
11213 }
11214
11215
11216 static int
11217 api_ioam_disable (vat_main_t * vam)
11218 {
11219   vl_api_ioam_disable_t *mp;
11220   int ret;
11221
11222   M (IOAM_DISABLE, mp);
11223   S (mp);
11224   W (ret);
11225   return ret;
11226 }
11227
11228 #define foreach_tcp_proto_field                 \
11229 _(src_port)                                     \
11230 _(dst_port)
11231
11232 #define foreach_udp_proto_field                 \
11233 _(src_port)                                     \
11234 _(dst_port)
11235
11236 #define foreach_ip4_proto_field                 \
11237 _(src_address)                                  \
11238 _(dst_address)                                  \
11239 _(tos)                                          \
11240 _(length)                                       \
11241 _(fragment_id)                                  \
11242 _(ttl)                                          \
11243 _(protocol)                                     \
11244 _(checksum)
11245
11246 typedef struct
11247 {
11248   u16 src_port, dst_port;
11249 } tcpudp_header_t;
11250
11251 #if VPP_API_TEST_BUILTIN == 0
11252 uword
11253 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11254 {
11255   u8 **maskp = va_arg (*args, u8 **);
11256   u8 *mask = 0;
11257   u8 found_something = 0;
11258   tcp_header_t *tcp;
11259
11260 #define _(a) u8 a=0;
11261   foreach_tcp_proto_field;
11262 #undef _
11263
11264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11265     {
11266       if (0);
11267 #define _(a) else if (unformat (input, #a)) a=1;
11268       foreach_tcp_proto_field
11269 #undef _
11270         else
11271         break;
11272     }
11273
11274 #define _(a) found_something += a;
11275   foreach_tcp_proto_field;
11276 #undef _
11277
11278   if (found_something == 0)
11279     return 0;
11280
11281   vec_validate (mask, sizeof (*tcp) - 1);
11282
11283   tcp = (tcp_header_t *) mask;
11284
11285 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
11286   foreach_tcp_proto_field;
11287 #undef _
11288
11289   *maskp = mask;
11290   return 1;
11291 }
11292
11293 uword
11294 unformat_udp_mask (unformat_input_t * input, va_list * args)
11295 {
11296   u8 **maskp = va_arg (*args, u8 **);
11297   u8 *mask = 0;
11298   u8 found_something = 0;
11299   udp_header_t *udp;
11300
11301 #define _(a) u8 a=0;
11302   foreach_udp_proto_field;
11303 #undef _
11304
11305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11306     {
11307       if (0);
11308 #define _(a) else if (unformat (input, #a)) a=1;
11309       foreach_udp_proto_field
11310 #undef _
11311         else
11312         break;
11313     }
11314
11315 #define _(a) found_something += a;
11316   foreach_udp_proto_field;
11317 #undef _
11318
11319   if (found_something == 0)
11320     return 0;
11321
11322   vec_validate (mask, sizeof (*udp) - 1);
11323
11324   udp = (udp_header_t *) mask;
11325
11326 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
11327   foreach_udp_proto_field;
11328 #undef _
11329
11330   *maskp = mask;
11331   return 1;
11332 }
11333
11334 uword
11335 unformat_l4_mask (unformat_input_t * input, va_list * args)
11336 {
11337   u8 **maskp = va_arg (*args, u8 **);
11338   u16 src_port = 0, dst_port = 0;
11339   tcpudp_header_t *tcpudp;
11340
11341   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11342     {
11343       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11344         return 1;
11345       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11346         return 1;
11347       else if (unformat (input, "src_port"))
11348         src_port = 0xFFFF;
11349       else if (unformat (input, "dst_port"))
11350         dst_port = 0xFFFF;
11351       else
11352         return 0;
11353     }
11354
11355   if (!src_port && !dst_port)
11356     return 0;
11357
11358   u8 *mask = 0;
11359   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11360
11361   tcpudp = (tcpudp_header_t *) mask;
11362   tcpudp->src_port = src_port;
11363   tcpudp->dst_port = dst_port;
11364
11365   *maskp = mask;
11366
11367   return 1;
11368 }
11369
11370 uword
11371 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11372 {
11373   u8 **maskp = va_arg (*args, u8 **);
11374   u8 *mask = 0;
11375   u8 found_something = 0;
11376   ip4_header_t *ip;
11377
11378 #define _(a) u8 a=0;
11379   foreach_ip4_proto_field;
11380 #undef _
11381   u8 version = 0;
11382   u8 hdr_length = 0;
11383
11384
11385   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11386     {
11387       if (unformat (input, "version"))
11388         version = 1;
11389       else if (unformat (input, "hdr_length"))
11390         hdr_length = 1;
11391       else if (unformat (input, "src"))
11392         src_address = 1;
11393       else if (unformat (input, "dst"))
11394         dst_address = 1;
11395       else if (unformat (input, "proto"))
11396         protocol = 1;
11397
11398 #define _(a) else if (unformat (input, #a)) a=1;
11399       foreach_ip4_proto_field
11400 #undef _
11401         else
11402         break;
11403     }
11404
11405 #define _(a) found_something += a;
11406   foreach_ip4_proto_field;
11407 #undef _
11408
11409   if (found_something == 0)
11410     return 0;
11411
11412   vec_validate (mask, sizeof (*ip) - 1);
11413
11414   ip = (ip4_header_t *) mask;
11415
11416 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11417   foreach_ip4_proto_field;
11418 #undef _
11419
11420   ip->ip_version_and_header_length = 0;
11421
11422   if (version)
11423     ip->ip_version_and_header_length |= 0xF0;
11424
11425   if (hdr_length)
11426     ip->ip_version_and_header_length |= 0x0F;
11427
11428   *maskp = mask;
11429   return 1;
11430 }
11431
11432 #define foreach_ip6_proto_field                 \
11433 _(src_address)                                  \
11434 _(dst_address)                                  \
11435 _(payload_length)                               \
11436 _(hop_limit)                                    \
11437 _(protocol)
11438
11439 uword
11440 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11441 {
11442   u8 **maskp = va_arg (*args, u8 **);
11443   u8 *mask = 0;
11444   u8 found_something = 0;
11445   ip6_header_t *ip;
11446   u32 ip_version_traffic_class_and_flow_label;
11447
11448 #define _(a) u8 a=0;
11449   foreach_ip6_proto_field;
11450 #undef _
11451   u8 version = 0;
11452   u8 traffic_class = 0;
11453   u8 flow_label = 0;
11454
11455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11456     {
11457       if (unformat (input, "version"))
11458         version = 1;
11459       else if (unformat (input, "traffic-class"))
11460         traffic_class = 1;
11461       else if (unformat (input, "flow-label"))
11462         flow_label = 1;
11463       else if (unformat (input, "src"))
11464         src_address = 1;
11465       else if (unformat (input, "dst"))
11466         dst_address = 1;
11467       else if (unformat (input, "proto"))
11468         protocol = 1;
11469
11470 #define _(a) else if (unformat (input, #a)) a=1;
11471       foreach_ip6_proto_field
11472 #undef _
11473         else
11474         break;
11475     }
11476
11477 #define _(a) found_something += a;
11478   foreach_ip6_proto_field;
11479 #undef _
11480
11481   if (found_something == 0)
11482     return 0;
11483
11484   vec_validate (mask, sizeof (*ip) - 1);
11485
11486   ip = (ip6_header_t *) mask;
11487
11488 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11489   foreach_ip6_proto_field;
11490 #undef _
11491
11492   ip_version_traffic_class_and_flow_label = 0;
11493
11494   if (version)
11495     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11496
11497   if (traffic_class)
11498     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11499
11500   if (flow_label)
11501     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11502
11503   ip->ip_version_traffic_class_and_flow_label =
11504     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11505
11506   *maskp = mask;
11507   return 1;
11508 }
11509
11510 uword
11511 unformat_l3_mask (unformat_input_t * input, va_list * args)
11512 {
11513   u8 **maskp = va_arg (*args, u8 **);
11514
11515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11516     {
11517       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11518         return 1;
11519       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11520         return 1;
11521       else
11522         break;
11523     }
11524   return 0;
11525 }
11526
11527 uword
11528 unformat_l2_mask (unformat_input_t * input, va_list * args)
11529 {
11530   u8 **maskp = va_arg (*args, u8 **);
11531   u8 *mask = 0;
11532   u8 src = 0;
11533   u8 dst = 0;
11534   u8 proto = 0;
11535   u8 tag1 = 0;
11536   u8 tag2 = 0;
11537   u8 ignore_tag1 = 0;
11538   u8 ignore_tag2 = 0;
11539   u8 cos1 = 0;
11540   u8 cos2 = 0;
11541   u8 dot1q = 0;
11542   u8 dot1ad = 0;
11543   int len = 14;
11544
11545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11546     {
11547       if (unformat (input, "src"))
11548         src = 1;
11549       else if (unformat (input, "dst"))
11550         dst = 1;
11551       else if (unformat (input, "proto"))
11552         proto = 1;
11553       else if (unformat (input, "tag1"))
11554         tag1 = 1;
11555       else if (unformat (input, "tag2"))
11556         tag2 = 1;
11557       else if (unformat (input, "ignore-tag1"))
11558         ignore_tag1 = 1;
11559       else if (unformat (input, "ignore-tag2"))
11560         ignore_tag2 = 1;
11561       else if (unformat (input, "cos1"))
11562         cos1 = 1;
11563       else if (unformat (input, "cos2"))
11564         cos2 = 1;
11565       else if (unformat (input, "dot1q"))
11566         dot1q = 1;
11567       else if (unformat (input, "dot1ad"))
11568         dot1ad = 1;
11569       else
11570         break;
11571     }
11572   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11573        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11574     return 0;
11575
11576   if (tag1 || ignore_tag1 || cos1 || dot1q)
11577     len = 18;
11578   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11579     len = 22;
11580
11581   vec_validate (mask, len - 1);
11582
11583   if (dst)
11584     clib_memset (mask, 0xff, 6);
11585
11586   if (src)
11587     clib_memset (mask + 6, 0xff, 6);
11588
11589   if (tag2 || dot1ad)
11590     {
11591       /* inner vlan tag */
11592       if (tag2)
11593         {
11594           mask[19] = 0xff;
11595           mask[18] = 0x0f;
11596         }
11597       if (cos2)
11598         mask[18] |= 0xe0;
11599       if (proto)
11600         mask[21] = mask[20] = 0xff;
11601       if (tag1)
11602         {
11603           mask[15] = 0xff;
11604           mask[14] = 0x0f;
11605         }
11606       if (cos1)
11607         mask[14] |= 0xe0;
11608       *maskp = mask;
11609       return 1;
11610     }
11611   if (tag1 | dot1q)
11612     {
11613       if (tag1)
11614         {
11615           mask[15] = 0xff;
11616           mask[14] = 0x0f;
11617         }
11618       if (cos1)
11619         mask[14] |= 0xe0;
11620       if (proto)
11621         mask[16] = mask[17] = 0xff;
11622
11623       *maskp = mask;
11624       return 1;
11625     }
11626   if (cos2)
11627     mask[18] |= 0xe0;
11628   if (cos1)
11629     mask[14] |= 0xe0;
11630   if (proto)
11631     mask[12] = mask[13] = 0xff;
11632
11633   *maskp = mask;
11634   return 1;
11635 }
11636
11637 uword
11638 unformat_classify_mask (unformat_input_t * input, va_list * args)
11639 {
11640   u8 **maskp = va_arg (*args, u8 **);
11641   u32 *skipp = va_arg (*args, u32 *);
11642   u32 *matchp = va_arg (*args, u32 *);
11643   u32 match;
11644   u8 *mask = 0;
11645   u8 *l2 = 0;
11646   u8 *l3 = 0;
11647   u8 *l4 = 0;
11648   int i;
11649
11650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11651     {
11652       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11653         ;
11654       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11655         ;
11656       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11657         ;
11658       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11659         ;
11660       else
11661         break;
11662     }
11663
11664   if (l4 && !l3)
11665     {
11666       vec_free (mask);
11667       vec_free (l2);
11668       vec_free (l4);
11669       return 0;
11670     }
11671
11672   if (mask || l2 || l3 || l4)
11673     {
11674       if (l2 || l3 || l4)
11675         {
11676           /* "With a free Ethernet header in every package" */
11677           if (l2 == 0)
11678             vec_validate (l2, 13);
11679           mask = l2;
11680           if (vec_len (l3))
11681             {
11682               vec_append (mask, l3);
11683               vec_free (l3);
11684             }
11685           if (vec_len (l4))
11686             {
11687               vec_append (mask, l4);
11688               vec_free (l4);
11689             }
11690         }
11691
11692       /* Scan forward looking for the first significant mask octet */
11693       for (i = 0; i < vec_len (mask); i++)
11694         if (mask[i])
11695           break;
11696
11697       /* compute (skip, match) params */
11698       *skipp = i / sizeof (u32x4);
11699       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11700
11701       /* Pad mask to an even multiple of the vector size */
11702       while (vec_len (mask) % sizeof (u32x4))
11703         vec_add1 (mask, 0);
11704
11705       match = vec_len (mask) / sizeof (u32x4);
11706
11707       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11708         {
11709           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11710           if (*tmp || *(tmp + 1))
11711             break;
11712           match--;
11713         }
11714       if (match == 0)
11715         clib_warning ("BUG: match 0");
11716
11717       _vec_len (mask) = match * sizeof (u32x4);
11718
11719       *matchp = match;
11720       *maskp = mask;
11721
11722       return 1;
11723     }
11724
11725   return 0;
11726 }
11727 #endif /* VPP_API_TEST_BUILTIN */
11728
11729 #define foreach_l2_next                         \
11730 _(drop, DROP)                                   \
11731 _(ethernet, ETHERNET_INPUT)                     \
11732 _(ip4, IP4_INPUT)                               \
11733 _(ip6, IP6_INPUT)
11734
11735 uword
11736 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11737 {
11738   u32 *miss_next_indexp = va_arg (*args, u32 *);
11739   u32 next_index = 0;
11740   u32 tmp;
11741
11742 #define _(n,N) \
11743   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11744   foreach_l2_next;
11745 #undef _
11746
11747   if (unformat (input, "%d", &tmp))
11748     {
11749       next_index = tmp;
11750       goto out;
11751     }
11752
11753   return 0;
11754
11755 out:
11756   *miss_next_indexp = next_index;
11757   return 1;
11758 }
11759
11760 #define foreach_ip_next                         \
11761 _(drop, DROP)                                   \
11762 _(local, LOCAL)                                 \
11763 _(rewrite, REWRITE)
11764
11765 uword
11766 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11767 {
11768   u32 *miss_next_indexp = va_arg (*args, u32 *);
11769   u32 next_index = 0;
11770   u32 tmp;
11771
11772 #define _(n,N) \
11773   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11774   foreach_ip_next;
11775 #undef _
11776
11777   if (unformat (input, "%d", &tmp))
11778     {
11779       next_index = tmp;
11780       goto out;
11781     }
11782
11783   return 0;
11784
11785 out:
11786   *miss_next_indexp = next_index;
11787   return 1;
11788 }
11789
11790 #define foreach_acl_next                        \
11791 _(deny, DENY)
11792
11793 uword
11794 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11795 {
11796   u32 *miss_next_indexp = va_arg (*args, u32 *);
11797   u32 next_index = 0;
11798   u32 tmp;
11799
11800 #define _(n,N) \
11801   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11802   foreach_acl_next;
11803 #undef _
11804
11805   if (unformat (input, "permit"))
11806     {
11807       next_index = ~0;
11808       goto out;
11809     }
11810   else if (unformat (input, "%d", &tmp))
11811     {
11812       next_index = tmp;
11813       goto out;
11814     }
11815
11816   return 0;
11817
11818 out:
11819   *miss_next_indexp = next_index;
11820   return 1;
11821 }
11822
11823 uword
11824 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11825 {
11826   u32 *r = va_arg (*args, u32 *);
11827
11828   if (unformat (input, "conform-color"))
11829     *r = POLICE_CONFORM;
11830   else if (unformat (input, "exceed-color"))
11831     *r = POLICE_EXCEED;
11832   else
11833     return 0;
11834
11835   return 1;
11836 }
11837
11838 static int
11839 api_classify_add_del_table (vat_main_t * vam)
11840 {
11841   unformat_input_t *i = vam->input;
11842   vl_api_classify_add_del_table_t *mp;
11843
11844   u32 nbuckets = 2;
11845   u32 skip = ~0;
11846   u32 match = ~0;
11847   int is_add = 1;
11848   int del_chain = 0;
11849   u32 table_index = ~0;
11850   u32 next_table_index = ~0;
11851   u32 miss_next_index = ~0;
11852   u32 memory_size = 32 << 20;
11853   u8 *mask = 0;
11854   u32 current_data_flag = 0;
11855   int current_data_offset = 0;
11856   int ret;
11857
11858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11859     {
11860       if (unformat (i, "del"))
11861         is_add = 0;
11862       else if (unformat (i, "del-chain"))
11863         {
11864           is_add = 0;
11865           del_chain = 1;
11866         }
11867       else if (unformat (i, "buckets %d", &nbuckets))
11868         ;
11869       else if (unformat (i, "memory_size %d", &memory_size))
11870         ;
11871       else if (unformat (i, "skip %d", &skip))
11872         ;
11873       else if (unformat (i, "match %d", &match))
11874         ;
11875       else if (unformat (i, "table %d", &table_index))
11876         ;
11877       else if (unformat (i, "mask %U", unformat_classify_mask,
11878                          &mask, &skip, &match))
11879         ;
11880       else if (unformat (i, "next-table %d", &next_table_index))
11881         ;
11882       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11883                          &miss_next_index))
11884         ;
11885       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11886                          &miss_next_index))
11887         ;
11888       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11889                          &miss_next_index))
11890         ;
11891       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11892         ;
11893       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11894         ;
11895       else
11896         break;
11897     }
11898
11899   if (is_add && mask == 0)
11900     {
11901       errmsg ("Mask required");
11902       return -99;
11903     }
11904
11905   if (is_add && skip == ~0)
11906     {
11907       errmsg ("skip count required");
11908       return -99;
11909     }
11910
11911   if (is_add && match == ~0)
11912     {
11913       errmsg ("match count required");
11914       return -99;
11915     }
11916
11917   if (!is_add && table_index == ~0)
11918     {
11919       errmsg ("table index required for delete");
11920       return -99;
11921     }
11922
11923   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11924
11925   mp->is_add = is_add;
11926   mp->del_chain = del_chain;
11927   mp->table_index = ntohl (table_index);
11928   mp->nbuckets = ntohl (nbuckets);
11929   mp->memory_size = ntohl (memory_size);
11930   mp->skip_n_vectors = ntohl (skip);
11931   mp->match_n_vectors = ntohl (match);
11932   mp->next_table_index = ntohl (next_table_index);
11933   mp->miss_next_index = ntohl (miss_next_index);
11934   mp->current_data_flag = ntohl (current_data_flag);
11935   mp->current_data_offset = ntohl (current_data_offset);
11936   mp->mask_len = ntohl (vec_len (mask));
11937   clib_memcpy (mp->mask, mask, vec_len (mask));
11938
11939   vec_free (mask);
11940
11941   S (mp);
11942   W (ret);
11943   return ret;
11944 }
11945
11946 #if VPP_API_TEST_BUILTIN == 0
11947 uword
11948 unformat_l4_match (unformat_input_t * input, va_list * args)
11949 {
11950   u8 **matchp = va_arg (*args, u8 **);
11951
11952   u8 *proto_header = 0;
11953   int src_port = 0;
11954   int dst_port = 0;
11955
11956   tcpudp_header_t h;
11957
11958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11959     {
11960       if (unformat (input, "src_port %d", &src_port))
11961         ;
11962       else if (unformat (input, "dst_port %d", &dst_port))
11963         ;
11964       else
11965         return 0;
11966     }
11967
11968   h.src_port = clib_host_to_net_u16 (src_port);
11969   h.dst_port = clib_host_to_net_u16 (dst_port);
11970   vec_validate (proto_header, sizeof (h) - 1);
11971   memcpy (proto_header, &h, sizeof (h));
11972
11973   *matchp = proto_header;
11974
11975   return 1;
11976 }
11977
11978 uword
11979 unformat_ip4_match (unformat_input_t * input, va_list * args)
11980 {
11981   u8 **matchp = va_arg (*args, u8 **);
11982   u8 *match = 0;
11983   ip4_header_t *ip;
11984   int version = 0;
11985   u32 version_val;
11986   int hdr_length = 0;
11987   u32 hdr_length_val;
11988   int src = 0, dst = 0;
11989   ip4_address_t src_val, dst_val;
11990   int proto = 0;
11991   u32 proto_val;
11992   int tos = 0;
11993   u32 tos_val;
11994   int length = 0;
11995   u32 length_val;
11996   int fragment_id = 0;
11997   u32 fragment_id_val;
11998   int ttl = 0;
11999   int ttl_val;
12000   int checksum = 0;
12001   u32 checksum_val;
12002
12003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12004     {
12005       if (unformat (input, "version %d", &version_val))
12006         version = 1;
12007       else if (unformat (input, "hdr_length %d", &hdr_length_val))
12008         hdr_length = 1;
12009       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
12010         src = 1;
12011       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
12012         dst = 1;
12013       else if (unformat (input, "proto %d", &proto_val))
12014         proto = 1;
12015       else if (unformat (input, "tos %d", &tos_val))
12016         tos = 1;
12017       else if (unformat (input, "length %d", &length_val))
12018         length = 1;
12019       else if (unformat (input, "fragment_id %d", &fragment_id_val))
12020         fragment_id = 1;
12021       else if (unformat (input, "ttl %d", &ttl_val))
12022         ttl = 1;
12023       else if (unformat (input, "checksum %d", &checksum_val))
12024         checksum = 1;
12025       else
12026         break;
12027     }
12028
12029   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
12030       + ttl + checksum == 0)
12031     return 0;
12032
12033   /*
12034    * Aligned because we use the real comparison functions
12035    */
12036   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12037
12038   ip = (ip4_header_t *) match;
12039
12040   /* These are realistically matched in practice */
12041   if (src)
12042     ip->src_address.as_u32 = src_val.as_u32;
12043
12044   if (dst)
12045     ip->dst_address.as_u32 = dst_val.as_u32;
12046
12047   if (proto)
12048     ip->protocol = proto_val;
12049
12050
12051   /* These are not, but they're included for completeness */
12052   if (version)
12053     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
12054
12055   if (hdr_length)
12056     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
12057
12058   if (tos)
12059     ip->tos = tos_val;
12060
12061   if (length)
12062     ip->length = clib_host_to_net_u16 (length_val);
12063
12064   if (ttl)
12065     ip->ttl = ttl_val;
12066
12067   if (checksum)
12068     ip->checksum = clib_host_to_net_u16 (checksum_val);
12069
12070   *matchp = match;
12071   return 1;
12072 }
12073
12074 uword
12075 unformat_ip6_match (unformat_input_t * input, va_list * args)
12076 {
12077   u8 **matchp = va_arg (*args, u8 **);
12078   u8 *match = 0;
12079   ip6_header_t *ip;
12080   int version = 0;
12081   u32 version_val;
12082   u8 traffic_class = 0;
12083   u32 traffic_class_val = 0;
12084   u8 flow_label = 0;
12085   u8 flow_label_val;
12086   int src = 0, dst = 0;
12087   ip6_address_t src_val, dst_val;
12088   int proto = 0;
12089   u32 proto_val;
12090   int payload_length = 0;
12091   u32 payload_length_val;
12092   int hop_limit = 0;
12093   int hop_limit_val;
12094   u32 ip_version_traffic_class_and_flow_label;
12095
12096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12097     {
12098       if (unformat (input, "version %d", &version_val))
12099         version = 1;
12100       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12101         traffic_class = 1;
12102       else if (unformat (input, "flow_label %d", &flow_label_val))
12103         flow_label = 1;
12104       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12105         src = 1;
12106       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12107         dst = 1;
12108       else if (unformat (input, "proto %d", &proto_val))
12109         proto = 1;
12110       else if (unformat (input, "payload_length %d", &payload_length_val))
12111         payload_length = 1;
12112       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12113         hop_limit = 1;
12114       else
12115         break;
12116     }
12117
12118   if (version + traffic_class + flow_label + src + dst + proto +
12119       payload_length + hop_limit == 0)
12120     return 0;
12121
12122   /*
12123    * Aligned because we use the real comparison functions
12124    */
12125   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12126
12127   ip = (ip6_header_t *) match;
12128
12129   if (src)
12130     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12131
12132   if (dst)
12133     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12134
12135   if (proto)
12136     ip->protocol = proto_val;
12137
12138   ip_version_traffic_class_and_flow_label = 0;
12139
12140   if (version)
12141     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12142
12143   if (traffic_class)
12144     ip_version_traffic_class_and_flow_label |=
12145       (traffic_class_val & 0xFF) << 20;
12146
12147   if (flow_label)
12148     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12149
12150   ip->ip_version_traffic_class_and_flow_label =
12151     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12152
12153   if (payload_length)
12154     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12155
12156   if (hop_limit)
12157     ip->hop_limit = hop_limit_val;
12158
12159   *matchp = match;
12160   return 1;
12161 }
12162
12163 uword
12164 unformat_l3_match (unformat_input_t * input, va_list * args)
12165 {
12166   u8 **matchp = va_arg (*args, u8 **);
12167
12168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12169     {
12170       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12171         return 1;
12172       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12173         return 1;
12174       else
12175         break;
12176     }
12177   return 0;
12178 }
12179
12180 uword
12181 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12182 {
12183   u8 *tagp = va_arg (*args, u8 *);
12184   u32 tag;
12185
12186   if (unformat (input, "%d", &tag))
12187     {
12188       tagp[0] = (tag >> 8) & 0x0F;
12189       tagp[1] = tag & 0xFF;
12190       return 1;
12191     }
12192
12193   return 0;
12194 }
12195
12196 uword
12197 unformat_l2_match (unformat_input_t * input, va_list * args)
12198 {
12199   u8 **matchp = va_arg (*args, u8 **);
12200   u8 *match = 0;
12201   u8 src = 0;
12202   u8 src_val[6];
12203   u8 dst = 0;
12204   u8 dst_val[6];
12205   u8 proto = 0;
12206   u16 proto_val;
12207   u8 tag1 = 0;
12208   u8 tag1_val[2];
12209   u8 tag2 = 0;
12210   u8 tag2_val[2];
12211   int len = 14;
12212   u8 ignore_tag1 = 0;
12213   u8 ignore_tag2 = 0;
12214   u8 cos1 = 0;
12215   u8 cos2 = 0;
12216   u32 cos1_val = 0;
12217   u32 cos2_val = 0;
12218
12219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12220     {
12221       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12222         src = 1;
12223       else
12224         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12225         dst = 1;
12226       else if (unformat (input, "proto %U",
12227                          unformat_ethernet_type_host_byte_order, &proto_val))
12228         proto = 1;
12229       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12230         tag1 = 1;
12231       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12232         tag2 = 1;
12233       else if (unformat (input, "ignore-tag1"))
12234         ignore_tag1 = 1;
12235       else if (unformat (input, "ignore-tag2"))
12236         ignore_tag2 = 1;
12237       else if (unformat (input, "cos1 %d", &cos1_val))
12238         cos1 = 1;
12239       else if (unformat (input, "cos2 %d", &cos2_val))
12240         cos2 = 1;
12241       else
12242         break;
12243     }
12244   if ((src + dst + proto + tag1 + tag2 +
12245        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12246     return 0;
12247
12248   if (tag1 || ignore_tag1 || cos1)
12249     len = 18;
12250   if (tag2 || ignore_tag2 || cos2)
12251     len = 22;
12252
12253   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12254
12255   if (dst)
12256     clib_memcpy (match, dst_val, 6);
12257
12258   if (src)
12259     clib_memcpy (match + 6, src_val, 6);
12260
12261   if (tag2)
12262     {
12263       /* inner vlan tag */
12264       match[19] = tag2_val[1];
12265       match[18] = tag2_val[0];
12266       if (cos2)
12267         match[18] |= (cos2_val & 0x7) << 5;
12268       if (proto)
12269         {
12270           match[21] = proto_val & 0xff;
12271           match[20] = proto_val >> 8;
12272         }
12273       if (tag1)
12274         {
12275           match[15] = tag1_val[1];
12276           match[14] = tag1_val[0];
12277         }
12278       if (cos1)
12279         match[14] |= (cos1_val & 0x7) << 5;
12280       *matchp = match;
12281       return 1;
12282     }
12283   if (tag1)
12284     {
12285       match[15] = tag1_val[1];
12286       match[14] = tag1_val[0];
12287       if (proto)
12288         {
12289           match[17] = proto_val & 0xff;
12290           match[16] = proto_val >> 8;
12291         }
12292       if (cos1)
12293         match[14] |= (cos1_val & 0x7) << 5;
12294
12295       *matchp = match;
12296       return 1;
12297     }
12298   if (cos2)
12299     match[18] |= (cos2_val & 0x7) << 5;
12300   if (cos1)
12301     match[14] |= (cos1_val & 0x7) << 5;
12302   if (proto)
12303     {
12304       match[13] = proto_val & 0xff;
12305       match[12] = proto_val >> 8;
12306     }
12307
12308   *matchp = match;
12309   return 1;
12310 }
12311
12312 uword
12313 unformat_qos_source (unformat_input_t * input, va_list * args)
12314 {
12315   int *qs = va_arg (*args, int *);
12316
12317   if (unformat (input, "ip"))
12318     *qs = QOS_SOURCE_IP;
12319   else if (unformat (input, "mpls"))
12320     *qs = QOS_SOURCE_MPLS;
12321   else if (unformat (input, "ext"))
12322     *qs = QOS_SOURCE_EXT;
12323   else if (unformat (input, "vlan"))
12324     *qs = QOS_SOURCE_VLAN;
12325   else
12326     return 0;
12327
12328   return 1;
12329 }
12330 #endif
12331
12332 uword
12333 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12334 {
12335   u8 **matchp = va_arg (*args, u8 **);
12336   u32 skip_n_vectors = va_arg (*args, u32);
12337   u32 match_n_vectors = va_arg (*args, u32);
12338
12339   u8 *match = 0;
12340   u8 *l2 = 0;
12341   u8 *l3 = 0;
12342   u8 *l4 = 0;
12343
12344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12345     {
12346       if (unformat (input, "hex %U", unformat_hex_string, &match))
12347         ;
12348       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12349         ;
12350       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12351         ;
12352       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12353         ;
12354       else
12355         break;
12356     }
12357
12358   if (l4 && !l3)
12359     {
12360       vec_free (match);
12361       vec_free (l2);
12362       vec_free (l4);
12363       return 0;
12364     }
12365
12366   if (match || l2 || l3 || l4)
12367     {
12368       if (l2 || l3 || l4)
12369         {
12370           /* "Win a free Ethernet header in every packet" */
12371           if (l2 == 0)
12372             vec_validate_aligned (l2, 13, sizeof (u32x4));
12373           match = l2;
12374           if (vec_len (l3))
12375             {
12376               vec_append_aligned (match, l3, sizeof (u32x4));
12377               vec_free (l3);
12378             }
12379           if (vec_len (l4))
12380             {
12381               vec_append_aligned (match, l4, sizeof (u32x4));
12382               vec_free (l4);
12383             }
12384         }
12385
12386       /* Make sure the vector is big enough even if key is all 0's */
12387       vec_validate_aligned
12388         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12389          sizeof (u32x4));
12390
12391       /* Set size, include skipped vectors */
12392       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12393
12394       *matchp = match;
12395
12396       return 1;
12397     }
12398
12399   return 0;
12400 }
12401
12402 static int
12403 api_classify_add_del_session (vat_main_t * vam)
12404 {
12405   unformat_input_t *i = vam->input;
12406   vl_api_classify_add_del_session_t *mp;
12407   int is_add = 1;
12408   u32 table_index = ~0;
12409   u32 hit_next_index = ~0;
12410   u32 opaque_index = ~0;
12411   u8 *match = 0;
12412   i32 advance = 0;
12413   u32 skip_n_vectors = 0;
12414   u32 match_n_vectors = 0;
12415   u32 action = 0;
12416   u32 metadata = 0;
12417   int ret;
12418
12419   /*
12420    * Warning: you have to supply skip_n and match_n
12421    * because the API client cant simply look at the classify
12422    * table object.
12423    */
12424
12425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12426     {
12427       if (unformat (i, "del"))
12428         is_add = 0;
12429       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12430                          &hit_next_index))
12431         ;
12432       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12433                          &hit_next_index))
12434         ;
12435       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12436                          &hit_next_index))
12437         ;
12438       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12439         ;
12440       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12441         ;
12442       else if (unformat (i, "opaque-index %d", &opaque_index))
12443         ;
12444       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12445         ;
12446       else if (unformat (i, "match_n %d", &match_n_vectors))
12447         ;
12448       else if (unformat (i, "match %U", api_unformat_classify_match,
12449                          &match, skip_n_vectors, match_n_vectors))
12450         ;
12451       else if (unformat (i, "advance %d", &advance))
12452         ;
12453       else if (unformat (i, "table-index %d", &table_index))
12454         ;
12455       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12456         action = 1;
12457       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12458         action = 2;
12459       else if (unformat (i, "action %d", &action))
12460         ;
12461       else if (unformat (i, "metadata %d", &metadata))
12462         ;
12463       else
12464         break;
12465     }
12466
12467   if (table_index == ~0)
12468     {
12469       errmsg ("Table index required");
12470       return -99;
12471     }
12472
12473   if (is_add && match == 0)
12474     {
12475       errmsg ("Match value required");
12476       return -99;
12477     }
12478
12479   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12480
12481   mp->is_add = is_add;
12482   mp->table_index = ntohl (table_index);
12483   mp->hit_next_index = ntohl (hit_next_index);
12484   mp->opaque_index = ntohl (opaque_index);
12485   mp->advance = ntohl (advance);
12486   mp->action = action;
12487   mp->metadata = ntohl (metadata);
12488   mp->match_len = ntohl (vec_len (match));
12489   clib_memcpy (mp->match, match, vec_len (match));
12490   vec_free (match);
12491
12492   S (mp);
12493   W (ret);
12494   return ret;
12495 }
12496
12497 static int
12498 api_classify_set_interface_ip_table (vat_main_t * vam)
12499 {
12500   unformat_input_t *i = vam->input;
12501   vl_api_classify_set_interface_ip_table_t *mp;
12502   u32 sw_if_index;
12503   int sw_if_index_set;
12504   u32 table_index = ~0;
12505   u8 is_ipv6 = 0;
12506   int ret;
12507
12508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12509     {
12510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12511         sw_if_index_set = 1;
12512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12513         sw_if_index_set = 1;
12514       else if (unformat (i, "table %d", &table_index))
12515         ;
12516       else
12517         {
12518           clib_warning ("parse error '%U'", format_unformat_error, i);
12519           return -99;
12520         }
12521     }
12522
12523   if (sw_if_index_set == 0)
12524     {
12525       errmsg ("missing interface name or sw_if_index");
12526       return -99;
12527     }
12528
12529
12530   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12531
12532   mp->sw_if_index = ntohl (sw_if_index);
12533   mp->table_index = ntohl (table_index);
12534   mp->is_ipv6 = is_ipv6;
12535
12536   S (mp);
12537   W (ret);
12538   return ret;
12539 }
12540
12541 static int
12542 api_classify_set_interface_l2_tables (vat_main_t * vam)
12543 {
12544   unformat_input_t *i = vam->input;
12545   vl_api_classify_set_interface_l2_tables_t *mp;
12546   u32 sw_if_index;
12547   int sw_if_index_set;
12548   u32 ip4_table_index = ~0;
12549   u32 ip6_table_index = ~0;
12550   u32 other_table_index = ~0;
12551   u32 is_input = 1;
12552   int ret;
12553
12554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12555     {
12556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12557         sw_if_index_set = 1;
12558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12559         sw_if_index_set = 1;
12560       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12561         ;
12562       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12563         ;
12564       else if (unformat (i, "other-table %d", &other_table_index))
12565         ;
12566       else if (unformat (i, "is-input %d", &is_input))
12567         ;
12568       else
12569         {
12570           clib_warning ("parse error '%U'", format_unformat_error, i);
12571           return -99;
12572         }
12573     }
12574
12575   if (sw_if_index_set == 0)
12576     {
12577       errmsg ("missing interface name or sw_if_index");
12578       return -99;
12579     }
12580
12581
12582   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12583
12584   mp->sw_if_index = ntohl (sw_if_index);
12585   mp->ip4_table_index = ntohl (ip4_table_index);
12586   mp->ip6_table_index = ntohl (ip6_table_index);
12587   mp->other_table_index = ntohl (other_table_index);
12588   mp->is_input = (u8) is_input;
12589
12590   S (mp);
12591   W (ret);
12592   return ret;
12593 }
12594
12595 static int
12596 api_set_ipfix_exporter (vat_main_t * vam)
12597 {
12598   unformat_input_t *i = vam->input;
12599   vl_api_set_ipfix_exporter_t *mp;
12600   ip4_address_t collector_address;
12601   u8 collector_address_set = 0;
12602   u32 collector_port = ~0;
12603   ip4_address_t src_address;
12604   u8 src_address_set = 0;
12605   u32 vrf_id = ~0;
12606   u32 path_mtu = ~0;
12607   u32 template_interval = ~0;
12608   u8 udp_checksum = 0;
12609   int ret;
12610
12611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12612     {
12613       if (unformat (i, "collector_address %U", unformat_ip4_address,
12614                     &collector_address))
12615         collector_address_set = 1;
12616       else if (unformat (i, "collector_port %d", &collector_port))
12617         ;
12618       else if (unformat (i, "src_address %U", unformat_ip4_address,
12619                          &src_address))
12620         src_address_set = 1;
12621       else if (unformat (i, "vrf_id %d", &vrf_id))
12622         ;
12623       else if (unformat (i, "path_mtu %d", &path_mtu))
12624         ;
12625       else if (unformat (i, "template_interval %d", &template_interval))
12626         ;
12627       else if (unformat (i, "udp_checksum"))
12628         udp_checksum = 1;
12629       else
12630         break;
12631     }
12632
12633   if (collector_address_set == 0)
12634     {
12635       errmsg ("collector_address required");
12636       return -99;
12637     }
12638
12639   if (src_address_set == 0)
12640     {
12641       errmsg ("src_address required");
12642       return -99;
12643     }
12644
12645   M (SET_IPFIX_EXPORTER, mp);
12646
12647   memcpy (mp->collector_address, collector_address.data,
12648           sizeof (collector_address.data));
12649   mp->collector_port = htons ((u16) collector_port);
12650   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12651   mp->vrf_id = htonl (vrf_id);
12652   mp->path_mtu = htonl (path_mtu);
12653   mp->template_interval = htonl (template_interval);
12654   mp->udp_checksum = udp_checksum;
12655
12656   S (mp);
12657   W (ret);
12658   return ret;
12659 }
12660
12661 static int
12662 api_set_ipfix_classify_stream (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_set_ipfix_classify_stream_t *mp;
12666   u32 domain_id = 0;
12667   u32 src_port = UDP_DST_PORT_ipfix;
12668   int ret;
12669
12670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12671     {
12672       if (unformat (i, "domain %d", &domain_id))
12673         ;
12674       else if (unformat (i, "src_port %d", &src_port))
12675         ;
12676       else
12677         {
12678           errmsg ("unknown input `%U'", format_unformat_error, i);
12679           return -99;
12680         }
12681     }
12682
12683   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12684
12685   mp->domain_id = htonl (domain_id);
12686   mp->src_port = htons ((u16) src_port);
12687
12688   S (mp);
12689   W (ret);
12690   return ret;
12691 }
12692
12693 static int
12694 api_ipfix_classify_table_add_del (vat_main_t * vam)
12695 {
12696   unformat_input_t *i = vam->input;
12697   vl_api_ipfix_classify_table_add_del_t *mp;
12698   int is_add = -1;
12699   u32 classify_table_index = ~0;
12700   u8 ip_version = 0;
12701   u8 transport_protocol = 255;
12702   int ret;
12703
12704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12705     {
12706       if (unformat (i, "add"))
12707         is_add = 1;
12708       else if (unformat (i, "del"))
12709         is_add = 0;
12710       else if (unformat (i, "table %d", &classify_table_index))
12711         ;
12712       else if (unformat (i, "ip4"))
12713         ip_version = 4;
12714       else if (unformat (i, "ip6"))
12715         ip_version = 6;
12716       else if (unformat (i, "tcp"))
12717         transport_protocol = 6;
12718       else if (unformat (i, "udp"))
12719         transport_protocol = 17;
12720       else
12721         {
12722           errmsg ("unknown input `%U'", format_unformat_error, i);
12723           return -99;
12724         }
12725     }
12726
12727   if (is_add == -1)
12728     {
12729       errmsg ("expecting: add|del");
12730       return -99;
12731     }
12732   if (classify_table_index == ~0)
12733     {
12734       errmsg ("classifier table not specified");
12735       return -99;
12736     }
12737   if (ip_version == 0)
12738     {
12739       errmsg ("IP version not specified");
12740       return -99;
12741     }
12742
12743   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12744
12745   mp->is_add = is_add;
12746   mp->table_id = htonl (classify_table_index);
12747   mp->ip_version = ip_version;
12748   mp->transport_protocol = transport_protocol;
12749
12750   S (mp);
12751   W (ret);
12752   return ret;
12753 }
12754
12755 static int
12756 api_get_node_index (vat_main_t * vam)
12757 {
12758   unformat_input_t *i = vam->input;
12759   vl_api_get_node_index_t *mp;
12760   u8 *name = 0;
12761   int ret;
12762
12763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12764     {
12765       if (unformat (i, "node %s", &name))
12766         ;
12767       else
12768         break;
12769     }
12770   if (name == 0)
12771     {
12772       errmsg ("node name required");
12773       return -99;
12774     }
12775   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12776     {
12777       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12778       return -99;
12779     }
12780
12781   M (GET_NODE_INDEX, mp);
12782   clib_memcpy (mp->node_name, name, vec_len (name));
12783   vec_free (name);
12784
12785   S (mp);
12786   W (ret);
12787   return ret;
12788 }
12789
12790 static int
12791 api_get_next_index (vat_main_t * vam)
12792 {
12793   unformat_input_t *i = vam->input;
12794   vl_api_get_next_index_t *mp;
12795   u8 *node_name = 0, *next_node_name = 0;
12796   int ret;
12797
12798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12799     {
12800       if (unformat (i, "node-name %s", &node_name))
12801         ;
12802       else if (unformat (i, "next-node-name %s", &next_node_name))
12803         break;
12804     }
12805
12806   if (node_name == 0)
12807     {
12808       errmsg ("node name required");
12809       return -99;
12810     }
12811   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12812     {
12813       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12814       return -99;
12815     }
12816
12817   if (next_node_name == 0)
12818     {
12819       errmsg ("next node name required");
12820       return -99;
12821     }
12822   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12823     {
12824       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12825       return -99;
12826     }
12827
12828   M (GET_NEXT_INDEX, mp);
12829   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12830   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12831   vec_free (node_name);
12832   vec_free (next_node_name);
12833
12834   S (mp);
12835   W (ret);
12836   return ret;
12837 }
12838
12839 static int
12840 api_add_node_next (vat_main_t * vam)
12841 {
12842   unformat_input_t *i = vam->input;
12843   vl_api_add_node_next_t *mp;
12844   u8 *name = 0;
12845   u8 *next = 0;
12846   int ret;
12847
12848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12849     {
12850       if (unformat (i, "node %s", &name))
12851         ;
12852       else if (unformat (i, "next %s", &next))
12853         ;
12854       else
12855         break;
12856     }
12857   if (name == 0)
12858     {
12859       errmsg ("node name required");
12860       return -99;
12861     }
12862   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12863     {
12864       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12865       return -99;
12866     }
12867   if (next == 0)
12868     {
12869       errmsg ("next node required");
12870       return -99;
12871     }
12872   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12873     {
12874       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12875       return -99;
12876     }
12877
12878   M (ADD_NODE_NEXT, mp);
12879   clib_memcpy (mp->node_name, name, vec_len (name));
12880   clib_memcpy (mp->next_name, next, vec_len (next));
12881   vec_free (name);
12882   vec_free (next);
12883
12884   S (mp);
12885   W (ret);
12886   return ret;
12887 }
12888
12889 static int
12890 api_l2tpv3_create_tunnel (vat_main_t * vam)
12891 {
12892   unformat_input_t *i = vam->input;
12893   ip6_address_t client_address, our_address;
12894   int client_address_set = 0;
12895   int our_address_set = 0;
12896   u32 local_session_id = 0;
12897   u32 remote_session_id = 0;
12898   u64 local_cookie = 0;
12899   u64 remote_cookie = 0;
12900   u8 l2_sublayer_present = 0;
12901   vl_api_l2tpv3_create_tunnel_t *mp;
12902   int ret;
12903
12904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12905     {
12906       if (unformat (i, "client_address %U", unformat_ip6_address,
12907                     &client_address))
12908         client_address_set = 1;
12909       else if (unformat (i, "our_address %U", unformat_ip6_address,
12910                          &our_address))
12911         our_address_set = 1;
12912       else if (unformat (i, "local_session_id %d", &local_session_id))
12913         ;
12914       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12915         ;
12916       else if (unformat (i, "local_cookie %lld", &local_cookie))
12917         ;
12918       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12919         ;
12920       else if (unformat (i, "l2-sublayer-present"))
12921         l2_sublayer_present = 1;
12922       else
12923         break;
12924     }
12925
12926   if (client_address_set == 0)
12927     {
12928       errmsg ("client_address required");
12929       return -99;
12930     }
12931
12932   if (our_address_set == 0)
12933     {
12934       errmsg ("our_address required");
12935       return -99;
12936     }
12937
12938   M (L2TPV3_CREATE_TUNNEL, mp);
12939
12940   clib_memcpy (mp->client_address, client_address.as_u8,
12941                sizeof (mp->client_address));
12942
12943   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12944
12945   mp->local_session_id = ntohl (local_session_id);
12946   mp->remote_session_id = ntohl (remote_session_id);
12947   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12948   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12949   mp->l2_sublayer_present = l2_sublayer_present;
12950   mp->is_ipv6 = 1;
12951
12952   S (mp);
12953   W (ret);
12954   return ret;
12955 }
12956
12957 static int
12958 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12959 {
12960   unformat_input_t *i = vam->input;
12961   u32 sw_if_index;
12962   u8 sw_if_index_set = 0;
12963   u64 new_local_cookie = 0;
12964   u64 new_remote_cookie = 0;
12965   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12966   int ret;
12967
12968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12969     {
12970       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12971         sw_if_index_set = 1;
12972       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12973         sw_if_index_set = 1;
12974       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12975         ;
12976       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12977         ;
12978       else
12979         break;
12980     }
12981
12982   if (sw_if_index_set == 0)
12983     {
12984       errmsg ("missing interface name or sw_if_index");
12985       return -99;
12986     }
12987
12988   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12989
12990   mp->sw_if_index = ntohl (sw_if_index);
12991   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12992   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12993
12994   S (mp);
12995   W (ret);
12996   return ret;
12997 }
12998
12999 static int
13000 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
13001 {
13002   unformat_input_t *i = vam->input;
13003   vl_api_l2tpv3_interface_enable_disable_t *mp;
13004   u32 sw_if_index;
13005   u8 sw_if_index_set = 0;
13006   u8 enable_disable = 1;
13007   int ret;
13008
13009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13010     {
13011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13012         sw_if_index_set = 1;
13013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13014         sw_if_index_set = 1;
13015       else if (unformat (i, "enable"))
13016         enable_disable = 1;
13017       else if (unformat (i, "disable"))
13018         enable_disable = 0;
13019       else
13020         break;
13021     }
13022
13023   if (sw_if_index_set == 0)
13024     {
13025       errmsg ("missing interface name or sw_if_index");
13026       return -99;
13027     }
13028
13029   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
13030
13031   mp->sw_if_index = ntohl (sw_if_index);
13032   mp->enable_disable = enable_disable;
13033
13034   S (mp);
13035   W (ret);
13036   return ret;
13037 }
13038
13039 static int
13040 api_l2tpv3_set_lookup_key (vat_main_t * vam)
13041 {
13042   unformat_input_t *i = vam->input;
13043   vl_api_l2tpv3_set_lookup_key_t *mp;
13044   u8 key = ~0;
13045   int ret;
13046
13047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13048     {
13049       if (unformat (i, "lookup_v6_src"))
13050         key = L2T_LOOKUP_SRC_ADDRESS;
13051       else if (unformat (i, "lookup_v6_dst"))
13052         key = L2T_LOOKUP_DST_ADDRESS;
13053       else if (unformat (i, "lookup_session_id"))
13054         key = L2T_LOOKUP_SESSION_ID;
13055       else
13056         break;
13057     }
13058
13059   if (key == (u8) ~ 0)
13060     {
13061       errmsg ("l2tp session lookup key unset");
13062       return -99;
13063     }
13064
13065   M (L2TPV3_SET_LOOKUP_KEY, mp);
13066
13067   mp->key = key;
13068
13069   S (mp);
13070   W (ret);
13071   return ret;
13072 }
13073
13074 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
13075   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13076 {
13077   vat_main_t *vam = &vat_main;
13078
13079   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
13080          format_ip6_address, mp->our_address,
13081          format_ip6_address, mp->client_address,
13082          clib_net_to_host_u32 (mp->sw_if_index));
13083
13084   print (vam->ofp,
13085          "   local cookies %016llx %016llx remote cookie %016llx",
13086          clib_net_to_host_u64 (mp->local_cookie[0]),
13087          clib_net_to_host_u64 (mp->local_cookie[1]),
13088          clib_net_to_host_u64 (mp->remote_cookie));
13089
13090   print (vam->ofp, "   local session-id %d remote session-id %d",
13091          clib_net_to_host_u32 (mp->local_session_id),
13092          clib_net_to_host_u32 (mp->remote_session_id));
13093
13094   print (vam->ofp, "   l2 specific sublayer %s\n",
13095          mp->l2_sublayer_present ? "preset" : "absent");
13096
13097 }
13098
13099 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13100   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13101 {
13102   vat_main_t *vam = &vat_main;
13103   vat_json_node_t *node = NULL;
13104   struct in6_addr addr;
13105
13106   if (VAT_JSON_ARRAY != vam->json_tree.type)
13107     {
13108       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13109       vat_json_init_array (&vam->json_tree);
13110     }
13111   node = vat_json_array_add (&vam->json_tree);
13112
13113   vat_json_init_object (node);
13114
13115   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13116   vat_json_object_add_ip6 (node, "our_address", addr);
13117   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13118   vat_json_object_add_ip6 (node, "client_address", addr);
13119
13120   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13121   vat_json_init_array (lc);
13122   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13123   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13124   vat_json_object_add_uint (node, "remote_cookie",
13125                             clib_net_to_host_u64 (mp->remote_cookie));
13126
13127   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13128   vat_json_object_add_uint (node, "local_session_id",
13129                             clib_net_to_host_u32 (mp->local_session_id));
13130   vat_json_object_add_uint (node, "remote_session_id",
13131                             clib_net_to_host_u32 (mp->remote_session_id));
13132   vat_json_object_add_string_copy (node, "l2_sublayer",
13133                                    mp->l2_sublayer_present ? (u8 *) "present"
13134                                    : (u8 *) "absent");
13135 }
13136
13137 static int
13138 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13139 {
13140   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13141   vl_api_control_ping_t *mp_ping;
13142   int ret;
13143
13144   /* Get list of l2tpv3-tunnel interfaces */
13145   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13146   S (mp);
13147
13148   /* Use a control ping for synchronization */
13149   MPING (CONTROL_PING, mp_ping);
13150   S (mp_ping);
13151
13152   W (ret);
13153   return ret;
13154 }
13155
13156
13157 static void vl_api_sw_interface_tap_details_t_handler
13158   (vl_api_sw_interface_tap_details_t * mp)
13159 {
13160   vat_main_t *vam = &vat_main;
13161
13162   print (vam->ofp, "%-16s %d",
13163          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13164 }
13165
13166 static void vl_api_sw_interface_tap_details_t_handler_json
13167   (vl_api_sw_interface_tap_details_t * mp)
13168 {
13169   vat_main_t *vam = &vat_main;
13170   vat_json_node_t *node = NULL;
13171
13172   if (VAT_JSON_ARRAY != vam->json_tree.type)
13173     {
13174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13175       vat_json_init_array (&vam->json_tree);
13176     }
13177   node = vat_json_array_add (&vam->json_tree);
13178
13179   vat_json_init_object (node);
13180   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13181   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13182 }
13183
13184 static int
13185 api_sw_interface_tap_dump (vat_main_t * vam)
13186 {
13187   vl_api_sw_interface_tap_dump_t *mp;
13188   vl_api_control_ping_t *mp_ping;
13189   int ret;
13190
13191   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13192   /* Get list of tap interfaces */
13193   M (SW_INTERFACE_TAP_DUMP, mp);
13194   S (mp);
13195
13196   /* Use a control ping for synchronization */
13197   MPING (CONTROL_PING, mp_ping);
13198   S (mp_ping);
13199
13200   W (ret);
13201   return ret;
13202 }
13203
13204 static void vl_api_sw_interface_tap_v2_details_t_handler
13205   (vl_api_sw_interface_tap_v2_details_t * mp)
13206 {
13207   vat_main_t *vam = &vat_main;
13208
13209   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13210                     mp->host_ip4_prefix_len);
13211   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13212                     mp->host_ip6_prefix_len);
13213
13214   print (vam->ofp,
13215          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13216          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13217          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13218          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13219          mp->host_bridge, ip4, ip6);
13220
13221   vec_free (ip4);
13222   vec_free (ip6);
13223 }
13224
13225 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13226   (vl_api_sw_interface_tap_v2_details_t * mp)
13227 {
13228   vat_main_t *vam = &vat_main;
13229   vat_json_node_t *node = NULL;
13230
13231   if (VAT_JSON_ARRAY != vam->json_tree.type)
13232     {
13233       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13234       vat_json_init_array (&vam->json_tree);
13235     }
13236   node = vat_json_array_add (&vam->json_tree);
13237
13238   vat_json_init_object (node);
13239   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13240   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13241   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13242   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13243   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13244   vat_json_object_add_string_copy (node, "host_mac_addr",
13245                                    format (0, "%U", format_ethernet_address,
13246                                            &mp->host_mac_addr));
13247   vat_json_object_add_string_copy (node, "host_namespace",
13248                                    mp->host_namespace);
13249   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13250   vat_json_object_add_string_copy (node, "host_ip4_addr",
13251                                    format (0, "%U/%d", format_ip4_address,
13252                                            mp->host_ip4_addr,
13253                                            mp->host_ip4_prefix_len));
13254   vat_json_object_add_string_copy (node, "host_ip6_addr",
13255                                    format (0, "%U/%d", format_ip6_address,
13256                                            mp->host_ip6_addr,
13257                                            mp->host_ip6_prefix_len));
13258
13259 }
13260
13261 static int
13262 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13263 {
13264   vl_api_sw_interface_tap_v2_dump_t *mp;
13265   vl_api_control_ping_t *mp_ping;
13266   int ret;
13267
13268   print (vam->ofp,
13269          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13270          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13271          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13272          "host_ip6_addr");
13273
13274   /* Get list of tap interfaces */
13275   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13276   S (mp);
13277
13278   /* Use a control ping for synchronization */
13279   MPING (CONTROL_PING, mp_ping);
13280   S (mp_ping);
13281
13282   W (ret);
13283   return ret;
13284 }
13285
13286 static int
13287 api_vxlan_offload_rx (vat_main_t * vam)
13288 {
13289   unformat_input_t *line_input = vam->input;
13290   vl_api_vxlan_offload_rx_t *mp;
13291   u32 hw_if_index = ~0, rx_if_index = ~0;
13292   u8 is_add = 1;
13293   int ret;
13294
13295   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13296     {
13297       if (unformat (line_input, "del"))
13298         is_add = 0;
13299       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13300                          &hw_if_index))
13301         ;
13302       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13303         ;
13304       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13305                          &rx_if_index))
13306         ;
13307       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13308         ;
13309       else
13310         {
13311           errmsg ("parse error '%U'", format_unformat_error, line_input);
13312           return -99;
13313         }
13314     }
13315
13316   if (hw_if_index == ~0)
13317     {
13318       errmsg ("no hw interface");
13319       return -99;
13320     }
13321
13322   if (rx_if_index == ~0)
13323     {
13324       errmsg ("no rx tunnel");
13325       return -99;
13326     }
13327
13328   M (VXLAN_OFFLOAD_RX, mp);
13329
13330   mp->hw_if_index = ntohl (hw_if_index);
13331   mp->sw_if_index = ntohl (rx_if_index);
13332   mp->enable = is_add;
13333
13334   S (mp);
13335   W (ret);
13336   return ret;
13337 }
13338
13339 static uword unformat_vxlan_decap_next
13340   (unformat_input_t * input, va_list * args)
13341 {
13342   u32 *result = va_arg (*args, u32 *);
13343   u32 tmp;
13344
13345   if (unformat (input, "l2"))
13346     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13347   else if (unformat (input, "%d", &tmp))
13348     *result = tmp;
13349   else
13350     return 0;
13351   return 1;
13352 }
13353
13354 static int
13355 api_vxlan_add_del_tunnel (vat_main_t * vam)
13356 {
13357   unformat_input_t *line_input = vam->input;
13358   vl_api_vxlan_add_del_tunnel_t *mp;
13359   ip46_address_t src, dst;
13360   u8 is_add = 1;
13361   u8 ipv4_set = 0, ipv6_set = 0;
13362   u8 src_set = 0;
13363   u8 dst_set = 0;
13364   u8 grp_set = 0;
13365   u32 instance = ~0;
13366   u32 mcast_sw_if_index = ~0;
13367   u32 encap_vrf_id = 0;
13368   u32 decap_next_index = ~0;
13369   u32 vni = 0;
13370   int ret;
13371
13372   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13373   clib_memset (&src, 0, sizeof src);
13374   clib_memset (&dst, 0, sizeof dst);
13375
13376   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13377     {
13378       if (unformat (line_input, "del"))
13379         is_add = 0;
13380       else if (unformat (line_input, "instance %d", &instance))
13381         ;
13382       else
13383         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13384         {
13385           ipv4_set = 1;
13386           src_set = 1;
13387         }
13388       else
13389         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13390         {
13391           ipv4_set = 1;
13392           dst_set = 1;
13393         }
13394       else
13395         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13396         {
13397           ipv6_set = 1;
13398           src_set = 1;
13399         }
13400       else
13401         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13402         {
13403           ipv6_set = 1;
13404           dst_set = 1;
13405         }
13406       else if (unformat (line_input, "group %U %U",
13407                          unformat_ip4_address, &dst.ip4,
13408                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13409         {
13410           grp_set = dst_set = 1;
13411           ipv4_set = 1;
13412         }
13413       else if (unformat (line_input, "group %U",
13414                          unformat_ip4_address, &dst.ip4))
13415         {
13416           grp_set = dst_set = 1;
13417           ipv4_set = 1;
13418         }
13419       else if (unformat (line_input, "group %U %U",
13420                          unformat_ip6_address, &dst.ip6,
13421                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13422         {
13423           grp_set = dst_set = 1;
13424           ipv6_set = 1;
13425         }
13426       else if (unformat (line_input, "group %U",
13427                          unformat_ip6_address, &dst.ip6))
13428         {
13429           grp_set = dst_set = 1;
13430           ipv6_set = 1;
13431         }
13432       else
13433         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13434         ;
13435       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13436         ;
13437       else if (unformat (line_input, "decap-next %U",
13438                          unformat_vxlan_decap_next, &decap_next_index))
13439         ;
13440       else if (unformat (line_input, "vni %d", &vni))
13441         ;
13442       else
13443         {
13444           errmsg ("parse error '%U'", format_unformat_error, line_input);
13445           return -99;
13446         }
13447     }
13448
13449   if (src_set == 0)
13450     {
13451       errmsg ("tunnel src address not specified");
13452       return -99;
13453     }
13454   if (dst_set == 0)
13455     {
13456       errmsg ("tunnel dst address not specified");
13457       return -99;
13458     }
13459
13460   if (grp_set && !ip46_address_is_multicast (&dst))
13461     {
13462       errmsg ("tunnel group address not multicast");
13463       return -99;
13464     }
13465   if (grp_set && mcast_sw_if_index == ~0)
13466     {
13467       errmsg ("tunnel nonexistent multicast device");
13468       return -99;
13469     }
13470   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13471     {
13472       errmsg ("tunnel dst address must be unicast");
13473       return -99;
13474     }
13475
13476
13477   if (ipv4_set && ipv6_set)
13478     {
13479       errmsg ("both IPv4 and IPv6 addresses specified");
13480       return -99;
13481     }
13482
13483   if ((vni == 0) || (vni >> 24))
13484     {
13485       errmsg ("vni not specified or out of range");
13486       return -99;
13487     }
13488
13489   M (VXLAN_ADD_DEL_TUNNEL, mp);
13490
13491   if (ipv6_set)
13492     {
13493       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13494       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13495     }
13496   else
13497     {
13498       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13499       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13500     }
13501
13502   mp->instance = htonl (instance);
13503   mp->encap_vrf_id = ntohl (encap_vrf_id);
13504   mp->decap_next_index = ntohl (decap_next_index);
13505   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13506   mp->vni = ntohl (vni);
13507   mp->is_add = is_add;
13508   mp->is_ipv6 = ipv6_set;
13509
13510   S (mp);
13511   W (ret);
13512   return ret;
13513 }
13514
13515 static void vl_api_vxlan_tunnel_details_t_handler
13516   (vl_api_vxlan_tunnel_details_t * mp)
13517 {
13518   vat_main_t *vam = &vat_main;
13519   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13520   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13521
13522   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13523          ntohl (mp->sw_if_index),
13524          ntohl (mp->instance),
13525          format_ip46_address, &src, IP46_TYPE_ANY,
13526          format_ip46_address, &dst, IP46_TYPE_ANY,
13527          ntohl (mp->encap_vrf_id),
13528          ntohl (mp->decap_next_index), ntohl (mp->vni),
13529          ntohl (mp->mcast_sw_if_index));
13530 }
13531
13532 static void vl_api_vxlan_tunnel_details_t_handler_json
13533   (vl_api_vxlan_tunnel_details_t * mp)
13534 {
13535   vat_main_t *vam = &vat_main;
13536   vat_json_node_t *node = NULL;
13537
13538   if (VAT_JSON_ARRAY != vam->json_tree.type)
13539     {
13540       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13541       vat_json_init_array (&vam->json_tree);
13542     }
13543   node = vat_json_array_add (&vam->json_tree);
13544
13545   vat_json_init_object (node);
13546   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13547
13548   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13549
13550   if (mp->is_ipv6)
13551     {
13552       struct in6_addr ip6;
13553
13554       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13555       vat_json_object_add_ip6 (node, "src_address", ip6);
13556       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13557       vat_json_object_add_ip6 (node, "dst_address", ip6);
13558     }
13559   else
13560     {
13561       struct in_addr ip4;
13562
13563       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13564       vat_json_object_add_ip4 (node, "src_address", ip4);
13565       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13566       vat_json_object_add_ip4 (node, "dst_address", ip4);
13567     }
13568   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13569   vat_json_object_add_uint (node, "decap_next_index",
13570                             ntohl (mp->decap_next_index));
13571   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13572   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13573   vat_json_object_add_uint (node, "mcast_sw_if_index",
13574                             ntohl (mp->mcast_sw_if_index));
13575 }
13576
13577 static int
13578 api_vxlan_tunnel_dump (vat_main_t * vam)
13579 {
13580   unformat_input_t *i = vam->input;
13581   vl_api_vxlan_tunnel_dump_t *mp;
13582   vl_api_control_ping_t *mp_ping;
13583   u32 sw_if_index;
13584   u8 sw_if_index_set = 0;
13585   int ret;
13586
13587   /* Parse args required to build the message */
13588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13589     {
13590       if (unformat (i, "sw_if_index %d", &sw_if_index))
13591         sw_if_index_set = 1;
13592       else
13593         break;
13594     }
13595
13596   if (sw_if_index_set == 0)
13597     {
13598       sw_if_index = ~0;
13599     }
13600
13601   if (!vam->json_output)
13602     {
13603       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13604              "sw_if_index", "instance", "src_address", "dst_address",
13605              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13606     }
13607
13608   /* Get list of vxlan-tunnel interfaces */
13609   M (VXLAN_TUNNEL_DUMP, mp);
13610
13611   mp->sw_if_index = htonl (sw_if_index);
13612
13613   S (mp);
13614
13615   /* Use a control ping for synchronization */
13616   MPING (CONTROL_PING, mp_ping);
13617   S (mp_ping);
13618
13619   W (ret);
13620   return ret;
13621 }
13622
13623 static uword unformat_geneve_decap_next
13624   (unformat_input_t * input, va_list * args)
13625 {
13626   u32 *result = va_arg (*args, u32 *);
13627   u32 tmp;
13628
13629   if (unformat (input, "l2"))
13630     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13631   else if (unformat (input, "%d", &tmp))
13632     *result = tmp;
13633   else
13634     return 0;
13635   return 1;
13636 }
13637
13638 static int
13639 api_geneve_add_del_tunnel (vat_main_t * vam)
13640 {
13641   unformat_input_t *line_input = vam->input;
13642   vl_api_geneve_add_del_tunnel_t *mp;
13643   ip46_address_t src, dst;
13644   u8 is_add = 1;
13645   u8 ipv4_set = 0, ipv6_set = 0;
13646   u8 src_set = 0;
13647   u8 dst_set = 0;
13648   u8 grp_set = 0;
13649   u32 mcast_sw_if_index = ~0;
13650   u32 encap_vrf_id = 0;
13651   u32 decap_next_index = ~0;
13652   u32 vni = 0;
13653   int ret;
13654
13655   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13656   clib_memset (&src, 0, sizeof src);
13657   clib_memset (&dst, 0, sizeof dst);
13658
13659   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13660     {
13661       if (unformat (line_input, "del"))
13662         is_add = 0;
13663       else
13664         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13665         {
13666           ipv4_set = 1;
13667           src_set = 1;
13668         }
13669       else
13670         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13671         {
13672           ipv4_set = 1;
13673           dst_set = 1;
13674         }
13675       else
13676         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13677         {
13678           ipv6_set = 1;
13679           src_set = 1;
13680         }
13681       else
13682         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13683         {
13684           ipv6_set = 1;
13685           dst_set = 1;
13686         }
13687       else if (unformat (line_input, "group %U %U",
13688                          unformat_ip4_address, &dst.ip4,
13689                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13690         {
13691           grp_set = dst_set = 1;
13692           ipv4_set = 1;
13693         }
13694       else if (unformat (line_input, "group %U",
13695                          unformat_ip4_address, &dst.ip4))
13696         {
13697           grp_set = dst_set = 1;
13698           ipv4_set = 1;
13699         }
13700       else if (unformat (line_input, "group %U %U",
13701                          unformat_ip6_address, &dst.ip6,
13702                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13703         {
13704           grp_set = dst_set = 1;
13705           ipv6_set = 1;
13706         }
13707       else if (unformat (line_input, "group %U",
13708                          unformat_ip6_address, &dst.ip6))
13709         {
13710           grp_set = dst_set = 1;
13711           ipv6_set = 1;
13712         }
13713       else
13714         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13715         ;
13716       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13717         ;
13718       else if (unformat (line_input, "decap-next %U",
13719                          unformat_geneve_decap_next, &decap_next_index))
13720         ;
13721       else if (unformat (line_input, "vni %d", &vni))
13722         ;
13723       else
13724         {
13725           errmsg ("parse error '%U'", format_unformat_error, line_input);
13726           return -99;
13727         }
13728     }
13729
13730   if (src_set == 0)
13731     {
13732       errmsg ("tunnel src address not specified");
13733       return -99;
13734     }
13735   if (dst_set == 0)
13736     {
13737       errmsg ("tunnel dst address not specified");
13738       return -99;
13739     }
13740
13741   if (grp_set && !ip46_address_is_multicast (&dst))
13742     {
13743       errmsg ("tunnel group address not multicast");
13744       return -99;
13745     }
13746   if (grp_set && mcast_sw_if_index == ~0)
13747     {
13748       errmsg ("tunnel nonexistent multicast device");
13749       return -99;
13750     }
13751   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13752     {
13753       errmsg ("tunnel dst address must be unicast");
13754       return -99;
13755     }
13756
13757
13758   if (ipv4_set && ipv6_set)
13759     {
13760       errmsg ("both IPv4 and IPv6 addresses specified");
13761       return -99;
13762     }
13763
13764   if ((vni == 0) || (vni >> 24))
13765     {
13766       errmsg ("vni not specified or out of range");
13767       return -99;
13768     }
13769
13770   M (GENEVE_ADD_DEL_TUNNEL, mp);
13771
13772   if (ipv6_set)
13773     {
13774       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13775       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13776     }
13777   else
13778     {
13779       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13780       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13781     }
13782   mp->encap_vrf_id = ntohl (encap_vrf_id);
13783   mp->decap_next_index = ntohl (decap_next_index);
13784   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13785   mp->vni = ntohl (vni);
13786   mp->is_add = is_add;
13787   mp->is_ipv6 = ipv6_set;
13788
13789   S (mp);
13790   W (ret);
13791   return ret;
13792 }
13793
13794 static void vl_api_geneve_tunnel_details_t_handler
13795   (vl_api_geneve_tunnel_details_t * mp)
13796 {
13797   vat_main_t *vam = &vat_main;
13798   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13799   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13800
13801   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13802          ntohl (mp->sw_if_index),
13803          format_ip46_address, &src, IP46_TYPE_ANY,
13804          format_ip46_address, &dst, IP46_TYPE_ANY,
13805          ntohl (mp->encap_vrf_id),
13806          ntohl (mp->decap_next_index), ntohl (mp->vni),
13807          ntohl (mp->mcast_sw_if_index));
13808 }
13809
13810 static void vl_api_geneve_tunnel_details_t_handler_json
13811   (vl_api_geneve_tunnel_details_t * mp)
13812 {
13813   vat_main_t *vam = &vat_main;
13814   vat_json_node_t *node = NULL;
13815
13816   if (VAT_JSON_ARRAY != vam->json_tree.type)
13817     {
13818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13819       vat_json_init_array (&vam->json_tree);
13820     }
13821   node = vat_json_array_add (&vam->json_tree);
13822
13823   vat_json_init_object (node);
13824   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13825   if (mp->is_ipv6)
13826     {
13827       struct in6_addr ip6;
13828
13829       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13830       vat_json_object_add_ip6 (node, "src_address", ip6);
13831       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13832       vat_json_object_add_ip6 (node, "dst_address", ip6);
13833     }
13834   else
13835     {
13836       struct in_addr ip4;
13837
13838       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13839       vat_json_object_add_ip4 (node, "src_address", ip4);
13840       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13841       vat_json_object_add_ip4 (node, "dst_address", ip4);
13842     }
13843   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13844   vat_json_object_add_uint (node, "decap_next_index",
13845                             ntohl (mp->decap_next_index));
13846   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13847   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13848   vat_json_object_add_uint (node, "mcast_sw_if_index",
13849                             ntohl (mp->mcast_sw_if_index));
13850 }
13851
13852 static int
13853 api_geneve_tunnel_dump (vat_main_t * vam)
13854 {
13855   unformat_input_t *i = vam->input;
13856   vl_api_geneve_tunnel_dump_t *mp;
13857   vl_api_control_ping_t *mp_ping;
13858   u32 sw_if_index;
13859   u8 sw_if_index_set = 0;
13860   int ret;
13861
13862   /* Parse args required to build the message */
13863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13864     {
13865       if (unformat (i, "sw_if_index %d", &sw_if_index))
13866         sw_if_index_set = 1;
13867       else
13868         break;
13869     }
13870
13871   if (sw_if_index_set == 0)
13872     {
13873       sw_if_index = ~0;
13874     }
13875
13876   if (!vam->json_output)
13877     {
13878       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13879              "sw_if_index", "local_address", "remote_address",
13880              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13881     }
13882
13883   /* Get list of geneve-tunnel interfaces */
13884   M (GENEVE_TUNNEL_DUMP, mp);
13885
13886   mp->sw_if_index = htonl (sw_if_index);
13887
13888   S (mp);
13889
13890   /* Use a control ping for synchronization */
13891   M (CONTROL_PING, mp_ping);
13892   S (mp_ping);
13893
13894   W (ret);
13895   return ret;
13896 }
13897
13898 static int
13899 api_gre_add_del_tunnel (vat_main_t * vam)
13900 {
13901   unformat_input_t *line_input = vam->input;
13902   vl_api_gre_add_del_tunnel_t *mp;
13903   ip4_address_t src4, dst4;
13904   ip6_address_t src6, dst6;
13905   u8 is_add = 1;
13906   u8 ipv4_set = 0;
13907   u8 ipv6_set = 0;
13908   u8 t_type = GRE_TUNNEL_TYPE_L3;
13909   u8 src_set = 0;
13910   u8 dst_set = 0;
13911   u32 outer_fib_id = 0;
13912   u32 session_id = 0;
13913   u32 instance = ~0;
13914   int ret;
13915
13916   clib_memset (&src4, 0, sizeof src4);
13917   clib_memset (&dst4, 0, sizeof dst4);
13918   clib_memset (&src6, 0, sizeof src6);
13919   clib_memset (&dst6, 0, sizeof dst6);
13920
13921   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13922     {
13923       if (unformat (line_input, "del"))
13924         is_add = 0;
13925       else if (unformat (line_input, "instance %d", &instance))
13926         ;
13927       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13928         {
13929           src_set = 1;
13930           ipv4_set = 1;
13931         }
13932       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13933         {
13934           dst_set = 1;
13935           ipv4_set = 1;
13936         }
13937       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13938         {
13939           src_set = 1;
13940           ipv6_set = 1;
13941         }
13942       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13943         {
13944           dst_set = 1;
13945           ipv6_set = 1;
13946         }
13947       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13948         ;
13949       else if (unformat (line_input, "teb"))
13950         t_type = GRE_TUNNEL_TYPE_TEB;
13951       else if (unformat (line_input, "erspan %d", &session_id))
13952         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13953       else
13954         {
13955           errmsg ("parse error '%U'", format_unformat_error, line_input);
13956           return -99;
13957         }
13958     }
13959
13960   if (src_set == 0)
13961     {
13962       errmsg ("tunnel src address not specified");
13963       return -99;
13964     }
13965   if (dst_set == 0)
13966     {
13967       errmsg ("tunnel dst address not specified");
13968       return -99;
13969     }
13970   if (ipv4_set && ipv6_set)
13971     {
13972       errmsg ("both IPv4 and IPv6 addresses specified");
13973       return -99;
13974     }
13975
13976
13977   M (GRE_ADD_DEL_TUNNEL, mp);
13978
13979   if (ipv4_set)
13980     {
13981       clib_memcpy (&mp->src_address, &src4, 4);
13982       clib_memcpy (&mp->dst_address, &dst4, 4);
13983     }
13984   else
13985     {
13986       clib_memcpy (&mp->src_address, &src6, 16);
13987       clib_memcpy (&mp->dst_address, &dst6, 16);
13988     }
13989   mp->instance = htonl (instance);
13990   mp->outer_fib_id = htonl (outer_fib_id);
13991   mp->is_add = is_add;
13992   mp->session_id = htons ((u16) session_id);
13993   mp->tunnel_type = t_type;
13994   mp->is_ipv6 = ipv6_set;
13995
13996   S (mp);
13997   W (ret);
13998   return ret;
13999 }
14000
14001 static void vl_api_gre_tunnel_details_t_handler
14002   (vl_api_gre_tunnel_details_t * mp)
14003 {
14004   vat_main_t *vam = &vat_main;
14005   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
14006   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
14007
14008   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
14009          ntohl (mp->sw_if_index),
14010          ntohl (mp->instance),
14011          format_ip46_address, &src, IP46_TYPE_ANY,
14012          format_ip46_address, &dst, IP46_TYPE_ANY,
14013          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
14014 }
14015
14016 static void vl_api_gre_tunnel_details_t_handler_json
14017   (vl_api_gre_tunnel_details_t * mp)
14018 {
14019   vat_main_t *vam = &vat_main;
14020   vat_json_node_t *node = NULL;
14021   struct in_addr ip4;
14022   struct in6_addr ip6;
14023
14024   if (VAT_JSON_ARRAY != vam->json_tree.type)
14025     {
14026       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14027       vat_json_init_array (&vam->json_tree);
14028     }
14029   node = vat_json_array_add (&vam->json_tree);
14030
14031   vat_json_init_object (node);
14032   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14033   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
14034   if (!mp->is_ipv6)
14035     {
14036       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14037       vat_json_object_add_ip4 (node, "src_address", ip4);
14038       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14039       vat_json_object_add_ip4 (node, "dst_address", ip4);
14040     }
14041   else
14042     {
14043       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
14044       vat_json_object_add_ip6 (node, "src_address", ip6);
14045       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
14046       vat_json_object_add_ip6 (node, "dst_address", ip6);
14047     }
14048   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
14049   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
14050   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
14051   vat_json_object_add_uint (node, "session_id", mp->session_id);
14052 }
14053
14054 static int
14055 api_gre_tunnel_dump (vat_main_t * vam)
14056 {
14057   unformat_input_t *i = vam->input;
14058   vl_api_gre_tunnel_dump_t *mp;
14059   vl_api_control_ping_t *mp_ping;
14060   u32 sw_if_index;
14061   u8 sw_if_index_set = 0;
14062   int ret;
14063
14064   /* Parse args required to build the message */
14065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14066     {
14067       if (unformat (i, "sw_if_index %d", &sw_if_index))
14068         sw_if_index_set = 1;
14069       else
14070         break;
14071     }
14072
14073   if (sw_if_index_set == 0)
14074     {
14075       sw_if_index = ~0;
14076     }
14077
14078   if (!vam->json_output)
14079     {
14080       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
14081              "sw_if_index", "instance", "src_address", "dst_address",
14082              "tunnel_type", "outer_fib_id", "session_id");
14083     }
14084
14085   /* Get list of gre-tunnel interfaces */
14086   M (GRE_TUNNEL_DUMP, mp);
14087
14088   mp->sw_if_index = htonl (sw_if_index);
14089
14090   S (mp);
14091
14092   /* Use a control ping for synchronization */
14093   MPING (CONTROL_PING, mp_ping);
14094   S (mp_ping);
14095
14096   W (ret);
14097   return ret;
14098 }
14099
14100 static int
14101 api_l2_fib_clear_table (vat_main_t * vam)
14102 {
14103 //  unformat_input_t * i = vam->input;
14104   vl_api_l2_fib_clear_table_t *mp;
14105   int ret;
14106
14107   M (L2_FIB_CLEAR_TABLE, mp);
14108
14109   S (mp);
14110   W (ret);
14111   return ret;
14112 }
14113
14114 static int
14115 api_l2_interface_efp_filter (vat_main_t * vam)
14116 {
14117   unformat_input_t *i = vam->input;
14118   vl_api_l2_interface_efp_filter_t *mp;
14119   u32 sw_if_index;
14120   u8 enable = 1;
14121   u8 sw_if_index_set = 0;
14122   int ret;
14123
14124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14125     {
14126       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14127         sw_if_index_set = 1;
14128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14129         sw_if_index_set = 1;
14130       else if (unformat (i, "enable"))
14131         enable = 1;
14132       else if (unformat (i, "disable"))
14133         enable = 0;
14134       else
14135         {
14136           clib_warning ("parse error '%U'", format_unformat_error, i);
14137           return -99;
14138         }
14139     }
14140
14141   if (sw_if_index_set == 0)
14142     {
14143       errmsg ("missing sw_if_index");
14144       return -99;
14145     }
14146
14147   M (L2_INTERFACE_EFP_FILTER, mp);
14148
14149   mp->sw_if_index = ntohl (sw_if_index);
14150   mp->enable_disable = enable;
14151
14152   S (mp);
14153   W (ret);
14154   return ret;
14155 }
14156
14157 #define foreach_vtr_op                          \
14158 _("disable",  L2_VTR_DISABLED)                  \
14159 _("push-1",  L2_VTR_PUSH_1)                     \
14160 _("push-2",  L2_VTR_PUSH_2)                     \
14161 _("pop-1",  L2_VTR_POP_1)                       \
14162 _("pop-2",  L2_VTR_POP_2)                       \
14163 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14164 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14165 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14166 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14167
14168 static int
14169 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14170 {
14171   unformat_input_t *i = vam->input;
14172   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14173   u32 sw_if_index;
14174   u8 sw_if_index_set = 0;
14175   u8 vtr_op_set = 0;
14176   u32 vtr_op = 0;
14177   u32 push_dot1q = 1;
14178   u32 tag1 = ~0;
14179   u32 tag2 = ~0;
14180   int ret;
14181
14182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14183     {
14184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14185         sw_if_index_set = 1;
14186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14187         sw_if_index_set = 1;
14188       else if (unformat (i, "vtr_op %d", &vtr_op))
14189         vtr_op_set = 1;
14190 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14191       foreach_vtr_op
14192 #undef _
14193         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14194         ;
14195       else if (unformat (i, "tag1 %d", &tag1))
14196         ;
14197       else if (unformat (i, "tag2 %d", &tag2))
14198         ;
14199       else
14200         {
14201           clib_warning ("parse error '%U'", format_unformat_error, i);
14202           return -99;
14203         }
14204     }
14205
14206   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14207     {
14208       errmsg ("missing vtr operation or sw_if_index");
14209       return -99;
14210     }
14211
14212   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14213   mp->sw_if_index = ntohl (sw_if_index);
14214   mp->vtr_op = ntohl (vtr_op);
14215   mp->push_dot1q = ntohl (push_dot1q);
14216   mp->tag1 = ntohl (tag1);
14217   mp->tag2 = ntohl (tag2);
14218
14219   S (mp);
14220   W (ret);
14221   return ret;
14222 }
14223
14224 static int
14225 api_create_vhost_user_if (vat_main_t * vam)
14226 {
14227   unformat_input_t *i = vam->input;
14228   vl_api_create_vhost_user_if_t *mp;
14229   u8 *file_name;
14230   u8 is_server = 0;
14231   u8 file_name_set = 0;
14232   u32 custom_dev_instance = ~0;
14233   u8 hwaddr[6];
14234   u8 use_custom_mac = 0;
14235   u8 disable_mrg_rxbuf = 0;
14236   u8 disable_indirect_desc = 0;
14237   u8 *tag = 0;
14238   int ret;
14239
14240   /* Shut up coverity */
14241   clib_memset (hwaddr, 0, sizeof (hwaddr));
14242
14243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14244     {
14245       if (unformat (i, "socket %s", &file_name))
14246         {
14247           file_name_set = 1;
14248         }
14249       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14250         ;
14251       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14252         use_custom_mac = 1;
14253       else if (unformat (i, "server"))
14254         is_server = 1;
14255       else if (unformat (i, "disable_mrg_rxbuf"))
14256         disable_mrg_rxbuf = 1;
14257       else if (unformat (i, "disable_indirect_desc"))
14258         disable_indirect_desc = 1;
14259       else if (unformat (i, "tag %s", &tag))
14260         ;
14261       else
14262         break;
14263     }
14264
14265   if (file_name_set == 0)
14266     {
14267       errmsg ("missing socket file name");
14268       return -99;
14269     }
14270
14271   if (vec_len (file_name) > 255)
14272     {
14273       errmsg ("socket file name too long");
14274       return -99;
14275     }
14276   vec_add1 (file_name, 0);
14277
14278   M (CREATE_VHOST_USER_IF, mp);
14279
14280   mp->is_server = is_server;
14281   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14282   mp->disable_indirect_desc = disable_indirect_desc;
14283   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14284   vec_free (file_name);
14285   if (custom_dev_instance != ~0)
14286     {
14287       mp->renumber = 1;
14288       mp->custom_dev_instance = ntohl (custom_dev_instance);
14289     }
14290
14291   mp->use_custom_mac = use_custom_mac;
14292   clib_memcpy (mp->mac_address, hwaddr, 6);
14293   if (tag)
14294     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14295   vec_free (tag);
14296
14297   S (mp);
14298   W (ret);
14299   return ret;
14300 }
14301
14302 static int
14303 api_modify_vhost_user_if (vat_main_t * vam)
14304 {
14305   unformat_input_t *i = vam->input;
14306   vl_api_modify_vhost_user_if_t *mp;
14307   u8 *file_name;
14308   u8 is_server = 0;
14309   u8 file_name_set = 0;
14310   u32 custom_dev_instance = ~0;
14311   u8 sw_if_index_set = 0;
14312   u32 sw_if_index = (u32) ~ 0;
14313   int ret;
14314
14315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14316     {
14317       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14318         sw_if_index_set = 1;
14319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14320         sw_if_index_set = 1;
14321       else if (unformat (i, "socket %s", &file_name))
14322         {
14323           file_name_set = 1;
14324         }
14325       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14326         ;
14327       else if (unformat (i, "server"))
14328         is_server = 1;
14329       else
14330         break;
14331     }
14332
14333   if (sw_if_index_set == 0)
14334     {
14335       errmsg ("missing sw_if_index or interface name");
14336       return -99;
14337     }
14338
14339   if (file_name_set == 0)
14340     {
14341       errmsg ("missing socket file name");
14342       return -99;
14343     }
14344
14345   if (vec_len (file_name) > 255)
14346     {
14347       errmsg ("socket file name too long");
14348       return -99;
14349     }
14350   vec_add1 (file_name, 0);
14351
14352   M (MODIFY_VHOST_USER_IF, mp);
14353
14354   mp->sw_if_index = ntohl (sw_if_index);
14355   mp->is_server = is_server;
14356   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14357   vec_free (file_name);
14358   if (custom_dev_instance != ~0)
14359     {
14360       mp->renumber = 1;
14361       mp->custom_dev_instance = ntohl (custom_dev_instance);
14362     }
14363
14364   S (mp);
14365   W (ret);
14366   return ret;
14367 }
14368
14369 static int
14370 api_delete_vhost_user_if (vat_main_t * vam)
14371 {
14372   unformat_input_t *i = vam->input;
14373   vl_api_delete_vhost_user_if_t *mp;
14374   u32 sw_if_index = ~0;
14375   u8 sw_if_index_set = 0;
14376   int ret;
14377
14378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14379     {
14380       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14381         sw_if_index_set = 1;
14382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14383         sw_if_index_set = 1;
14384       else
14385         break;
14386     }
14387
14388   if (sw_if_index_set == 0)
14389     {
14390       errmsg ("missing sw_if_index or interface name");
14391       return -99;
14392     }
14393
14394
14395   M (DELETE_VHOST_USER_IF, mp);
14396
14397   mp->sw_if_index = ntohl (sw_if_index);
14398
14399   S (mp);
14400   W (ret);
14401   return ret;
14402 }
14403
14404 static void vl_api_sw_interface_vhost_user_details_t_handler
14405   (vl_api_sw_interface_vhost_user_details_t * mp)
14406 {
14407   vat_main_t *vam = &vat_main;
14408
14409   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14410          (char *) mp->interface_name,
14411          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14412          clib_net_to_host_u64 (mp->features), mp->is_server,
14413          ntohl (mp->num_regions), (char *) mp->sock_filename);
14414   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14415 }
14416
14417 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14418   (vl_api_sw_interface_vhost_user_details_t * mp)
14419 {
14420   vat_main_t *vam = &vat_main;
14421   vat_json_node_t *node = NULL;
14422
14423   if (VAT_JSON_ARRAY != vam->json_tree.type)
14424     {
14425       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14426       vat_json_init_array (&vam->json_tree);
14427     }
14428   node = vat_json_array_add (&vam->json_tree);
14429
14430   vat_json_init_object (node);
14431   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14432   vat_json_object_add_string_copy (node, "interface_name",
14433                                    mp->interface_name);
14434   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14435                             ntohl (mp->virtio_net_hdr_sz));
14436   vat_json_object_add_uint (node, "features",
14437                             clib_net_to_host_u64 (mp->features));
14438   vat_json_object_add_uint (node, "is_server", mp->is_server);
14439   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14440   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14441   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14442 }
14443
14444 static int
14445 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14446 {
14447   vl_api_sw_interface_vhost_user_dump_t *mp;
14448   vl_api_control_ping_t *mp_ping;
14449   int ret;
14450   print (vam->ofp,
14451          "Interface name            idx hdr_sz features server regions filename");
14452
14453   /* Get list of vhost-user interfaces */
14454   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14455   S (mp);
14456
14457   /* Use a control ping for synchronization */
14458   MPING (CONTROL_PING, mp_ping);
14459   S (mp_ping);
14460
14461   W (ret);
14462   return ret;
14463 }
14464
14465 static int
14466 api_show_version (vat_main_t * vam)
14467 {
14468   vl_api_show_version_t *mp;
14469   int ret;
14470
14471   M (SHOW_VERSION, mp);
14472
14473   S (mp);
14474   W (ret);
14475   return ret;
14476 }
14477
14478
14479 static int
14480 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14481 {
14482   unformat_input_t *line_input = vam->input;
14483   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14484   ip4_address_t local4, remote4;
14485   ip6_address_t local6, remote6;
14486   u8 is_add = 1;
14487   u8 ipv4_set = 0, ipv6_set = 0;
14488   u8 local_set = 0;
14489   u8 remote_set = 0;
14490   u8 grp_set = 0;
14491   u32 mcast_sw_if_index = ~0;
14492   u32 encap_vrf_id = 0;
14493   u32 decap_vrf_id = 0;
14494   u8 protocol = ~0;
14495   u32 vni;
14496   u8 vni_set = 0;
14497   int ret;
14498
14499   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14500   clib_memset (&local4, 0, sizeof local4);
14501   clib_memset (&remote4, 0, sizeof remote4);
14502   clib_memset (&local6, 0, sizeof local6);
14503   clib_memset (&remote6, 0, sizeof remote6);
14504
14505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14506     {
14507       if (unformat (line_input, "del"))
14508         is_add = 0;
14509       else if (unformat (line_input, "local %U",
14510                          unformat_ip4_address, &local4))
14511         {
14512           local_set = 1;
14513           ipv4_set = 1;
14514         }
14515       else if (unformat (line_input, "remote %U",
14516                          unformat_ip4_address, &remote4))
14517         {
14518           remote_set = 1;
14519           ipv4_set = 1;
14520         }
14521       else if (unformat (line_input, "local %U",
14522                          unformat_ip6_address, &local6))
14523         {
14524           local_set = 1;
14525           ipv6_set = 1;
14526         }
14527       else if (unformat (line_input, "remote %U",
14528                          unformat_ip6_address, &remote6))
14529         {
14530           remote_set = 1;
14531           ipv6_set = 1;
14532         }
14533       else if (unformat (line_input, "group %U %U",
14534                          unformat_ip4_address, &remote4,
14535                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14536         {
14537           grp_set = remote_set = 1;
14538           ipv4_set = 1;
14539         }
14540       else if (unformat (line_input, "group %U",
14541                          unformat_ip4_address, &remote4))
14542         {
14543           grp_set = remote_set = 1;
14544           ipv4_set = 1;
14545         }
14546       else if (unformat (line_input, "group %U %U",
14547                          unformat_ip6_address, &remote6,
14548                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14549         {
14550           grp_set = remote_set = 1;
14551           ipv6_set = 1;
14552         }
14553       else if (unformat (line_input, "group %U",
14554                          unformat_ip6_address, &remote6))
14555         {
14556           grp_set = remote_set = 1;
14557           ipv6_set = 1;
14558         }
14559       else
14560         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14561         ;
14562       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14563         ;
14564       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14565         ;
14566       else if (unformat (line_input, "vni %d", &vni))
14567         vni_set = 1;
14568       else if (unformat (line_input, "next-ip4"))
14569         protocol = 1;
14570       else if (unformat (line_input, "next-ip6"))
14571         protocol = 2;
14572       else if (unformat (line_input, "next-ethernet"))
14573         protocol = 3;
14574       else if (unformat (line_input, "next-nsh"))
14575         protocol = 4;
14576       else
14577         {
14578           errmsg ("parse error '%U'", format_unformat_error, line_input);
14579           return -99;
14580         }
14581     }
14582
14583   if (local_set == 0)
14584     {
14585       errmsg ("tunnel local address not specified");
14586       return -99;
14587     }
14588   if (remote_set == 0)
14589     {
14590       errmsg ("tunnel remote address not specified");
14591       return -99;
14592     }
14593   if (grp_set && mcast_sw_if_index == ~0)
14594     {
14595       errmsg ("tunnel nonexistent multicast device");
14596       return -99;
14597     }
14598   if (ipv4_set && ipv6_set)
14599     {
14600       errmsg ("both IPv4 and IPv6 addresses specified");
14601       return -99;
14602     }
14603
14604   if (vni_set == 0)
14605     {
14606       errmsg ("vni not specified");
14607       return -99;
14608     }
14609
14610   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14611
14612
14613   if (ipv6_set)
14614     {
14615       clib_memcpy (&mp->local, &local6, sizeof (local6));
14616       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14617     }
14618   else
14619     {
14620       clib_memcpy (&mp->local, &local4, sizeof (local4));
14621       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14622     }
14623
14624   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14625   mp->encap_vrf_id = ntohl (encap_vrf_id);
14626   mp->decap_vrf_id = ntohl (decap_vrf_id);
14627   mp->protocol = protocol;
14628   mp->vni = ntohl (vni);
14629   mp->is_add = is_add;
14630   mp->is_ipv6 = ipv6_set;
14631
14632   S (mp);
14633   W (ret);
14634   return ret;
14635 }
14636
14637 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14638   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14639 {
14640   vat_main_t *vam = &vat_main;
14641   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14642   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14643
14644   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14645          ntohl (mp->sw_if_index),
14646          format_ip46_address, &local, IP46_TYPE_ANY,
14647          format_ip46_address, &remote, IP46_TYPE_ANY,
14648          ntohl (mp->vni), mp->protocol,
14649          ntohl (mp->mcast_sw_if_index),
14650          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14651 }
14652
14653
14654 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14655   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14656 {
14657   vat_main_t *vam = &vat_main;
14658   vat_json_node_t *node = NULL;
14659   struct in_addr ip4;
14660   struct in6_addr ip6;
14661
14662   if (VAT_JSON_ARRAY != vam->json_tree.type)
14663     {
14664       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14665       vat_json_init_array (&vam->json_tree);
14666     }
14667   node = vat_json_array_add (&vam->json_tree);
14668
14669   vat_json_init_object (node);
14670   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14671   if (mp->is_ipv6)
14672     {
14673       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14674       vat_json_object_add_ip6 (node, "local", ip6);
14675       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14676       vat_json_object_add_ip6 (node, "remote", ip6);
14677     }
14678   else
14679     {
14680       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14681       vat_json_object_add_ip4 (node, "local", ip4);
14682       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14683       vat_json_object_add_ip4 (node, "remote", ip4);
14684     }
14685   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14686   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14687   vat_json_object_add_uint (node, "mcast_sw_if_index",
14688                             ntohl (mp->mcast_sw_if_index));
14689   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14690   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14691   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14692 }
14693
14694 static int
14695 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14696 {
14697   unformat_input_t *i = vam->input;
14698   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14699   vl_api_control_ping_t *mp_ping;
14700   u32 sw_if_index;
14701   u8 sw_if_index_set = 0;
14702   int ret;
14703
14704   /* Parse args required to build the message */
14705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14706     {
14707       if (unformat (i, "sw_if_index %d", &sw_if_index))
14708         sw_if_index_set = 1;
14709       else
14710         break;
14711     }
14712
14713   if (sw_if_index_set == 0)
14714     {
14715       sw_if_index = ~0;
14716     }
14717
14718   if (!vam->json_output)
14719     {
14720       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14721              "sw_if_index", "local", "remote", "vni",
14722              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14723     }
14724
14725   /* Get list of vxlan-tunnel interfaces */
14726   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14727
14728   mp->sw_if_index = htonl (sw_if_index);
14729
14730   S (mp);
14731
14732   /* Use a control ping for synchronization */
14733   MPING (CONTROL_PING, mp_ping);
14734   S (mp_ping);
14735
14736   W (ret);
14737   return ret;
14738 }
14739
14740 static void vl_api_l2_fib_table_details_t_handler
14741   (vl_api_l2_fib_table_details_t * mp)
14742 {
14743   vat_main_t *vam = &vat_main;
14744
14745   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14746          "       %d       %d     %d",
14747          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14748          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14749          mp->bvi_mac);
14750 }
14751
14752 static void vl_api_l2_fib_table_details_t_handler_json
14753   (vl_api_l2_fib_table_details_t * mp)
14754 {
14755   vat_main_t *vam = &vat_main;
14756   vat_json_node_t *node = NULL;
14757
14758   if (VAT_JSON_ARRAY != vam->json_tree.type)
14759     {
14760       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14761       vat_json_init_array (&vam->json_tree);
14762     }
14763   node = vat_json_array_add (&vam->json_tree);
14764
14765   vat_json_init_object (node);
14766   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14767   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14768   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14769   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14770   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14771   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14772 }
14773
14774 static int
14775 api_l2_fib_table_dump (vat_main_t * vam)
14776 {
14777   unformat_input_t *i = vam->input;
14778   vl_api_l2_fib_table_dump_t *mp;
14779   vl_api_control_ping_t *mp_ping;
14780   u32 bd_id;
14781   u8 bd_id_set = 0;
14782   int ret;
14783
14784   /* Parse args required to build the message */
14785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14786     {
14787       if (unformat (i, "bd_id %d", &bd_id))
14788         bd_id_set = 1;
14789       else
14790         break;
14791     }
14792
14793   if (bd_id_set == 0)
14794     {
14795       errmsg ("missing bridge domain");
14796       return -99;
14797     }
14798
14799   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14800
14801   /* Get list of l2 fib entries */
14802   M (L2_FIB_TABLE_DUMP, mp);
14803
14804   mp->bd_id = ntohl (bd_id);
14805   S (mp);
14806
14807   /* Use a control ping for synchronization */
14808   MPING (CONTROL_PING, mp_ping);
14809   S (mp_ping);
14810
14811   W (ret);
14812   return ret;
14813 }
14814
14815
14816 static int
14817 api_interface_name_renumber (vat_main_t * vam)
14818 {
14819   unformat_input_t *line_input = vam->input;
14820   vl_api_interface_name_renumber_t *mp;
14821   u32 sw_if_index = ~0;
14822   u32 new_show_dev_instance = ~0;
14823   int ret;
14824
14825   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14826     {
14827       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14828                     &sw_if_index))
14829         ;
14830       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14831         ;
14832       else if (unformat (line_input, "new_show_dev_instance %d",
14833                          &new_show_dev_instance))
14834         ;
14835       else
14836         break;
14837     }
14838
14839   if (sw_if_index == ~0)
14840     {
14841       errmsg ("missing interface name or sw_if_index");
14842       return -99;
14843     }
14844
14845   if (new_show_dev_instance == ~0)
14846     {
14847       errmsg ("missing new_show_dev_instance");
14848       return -99;
14849     }
14850
14851   M (INTERFACE_NAME_RENUMBER, mp);
14852
14853   mp->sw_if_index = ntohl (sw_if_index);
14854   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14855
14856   S (mp);
14857   W (ret);
14858   return ret;
14859 }
14860
14861 static int
14862 api_ip_probe_neighbor (vat_main_t * vam)
14863 {
14864   unformat_input_t *i = vam->input;
14865   vl_api_ip_probe_neighbor_t *mp;
14866   u8 int_set = 0;
14867   u8 adr_set = 0;
14868   u8 is_ipv6 = 0;
14869   u8 dst_adr[16];
14870   u32 sw_if_index;
14871   int ret;
14872
14873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14874     {
14875       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14876         int_set = 1;
14877       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14878         int_set = 1;
14879       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14880         adr_set = 1;
14881       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14882         {
14883           adr_set = 1;
14884           is_ipv6 = 1;
14885         }
14886       else
14887         break;
14888     }
14889
14890   if (int_set == 0)
14891     {
14892       errmsg ("missing interface");
14893       return -99;
14894     }
14895
14896   if (adr_set == 0)
14897     {
14898       errmsg ("missing addresses");
14899       return -99;
14900     }
14901
14902   M (IP_PROBE_NEIGHBOR, mp);
14903
14904   mp->sw_if_index = ntohl (sw_if_index);
14905   mp->is_ipv6 = is_ipv6;
14906   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14907
14908   S (mp);
14909   W (ret);
14910   return ret;
14911 }
14912
14913 static int
14914 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14915 {
14916   unformat_input_t *i = vam->input;
14917   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14918   u8 mode = IP_SCAN_V46_NEIGHBORS;
14919   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14920   int ret;
14921
14922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14923     {
14924       if (unformat (i, "ip4"))
14925         mode = IP_SCAN_V4_NEIGHBORS;
14926       else if (unformat (i, "ip6"))
14927         mode = IP_SCAN_V6_NEIGHBORS;
14928       if (unformat (i, "both"))
14929         mode = IP_SCAN_V46_NEIGHBORS;
14930       else if (unformat (i, "disable"))
14931         mode = IP_SCAN_DISABLED;
14932       else if (unformat (i, "interval %d", &interval))
14933         ;
14934       else if (unformat (i, "max-time %d", &time))
14935         ;
14936       else if (unformat (i, "max-update %d", &update))
14937         ;
14938       else if (unformat (i, "delay %d", &delay))
14939         ;
14940       else if (unformat (i, "stale %d", &stale))
14941         ;
14942       else
14943         break;
14944     }
14945
14946   if (interval > 255)
14947     {
14948       errmsg ("interval cannot exceed 255 minutes.");
14949       return -99;
14950     }
14951   if (time > 255)
14952     {
14953       errmsg ("max-time cannot exceed 255 usec.");
14954       return -99;
14955     }
14956   if (update > 255)
14957     {
14958       errmsg ("max-update cannot exceed 255.");
14959       return -99;
14960     }
14961   if (delay > 255)
14962     {
14963       errmsg ("delay cannot exceed 255 msec.");
14964       return -99;
14965     }
14966   if (stale > 255)
14967     {
14968       errmsg ("stale cannot exceed 255 minutes.");
14969       return -99;
14970     }
14971
14972   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14973   mp->mode = mode;
14974   mp->scan_interval = interval;
14975   mp->max_proc_time = time;
14976   mp->max_update = update;
14977   mp->scan_int_delay = delay;
14978   mp->stale_threshold = stale;
14979
14980   S (mp);
14981   W (ret);
14982   return ret;
14983 }
14984
14985 static int
14986 api_want_ip4_arp_events (vat_main_t * vam)
14987 {
14988   unformat_input_t *line_input = vam->input;
14989   vl_api_want_ip4_arp_events_t *mp;
14990   ip4_address_t address;
14991   int address_set = 0;
14992   u32 enable_disable = 1;
14993   int ret;
14994
14995   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14996     {
14997       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14998         address_set = 1;
14999       else if (unformat (line_input, "del"))
15000         enable_disable = 0;
15001       else
15002         break;
15003     }
15004
15005   if (address_set == 0)
15006     {
15007       errmsg ("missing addresses");
15008       return -99;
15009     }
15010
15011   M (WANT_IP4_ARP_EVENTS, mp);
15012   mp->enable_disable = enable_disable;
15013   mp->pid = htonl (getpid ());
15014   mp->address = address.as_u32;
15015
15016   S (mp);
15017   W (ret);
15018   return ret;
15019 }
15020
15021 static int
15022 api_want_ip6_nd_events (vat_main_t * vam)
15023 {
15024   unformat_input_t *line_input = vam->input;
15025   vl_api_want_ip6_nd_events_t *mp;
15026   ip6_address_t address;
15027   int address_set = 0;
15028   u32 enable_disable = 1;
15029   int ret;
15030
15031   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15032     {
15033       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
15034         address_set = 1;
15035       else if (unformat (line_input, "del"))
15036         enable_disable = 0;
15037       else
15038         break;
15039     }
15040
15041   if (address_set == 0)
15042     {
15043       errmsg ("missing addresses");
15044       return -99;
15045     }
15046
15047   M (WANT_IP6_ND_EVENTS, mp);
15048   mp->enable_disable = enable_disable;
15049   mp->pid = htonl (getpid ());
15050   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
15051
15052   S (mp);
15053   W (ret);
15054   return ret;
15055 }
15056
15057 static int
15058 api_want_l2_macs_events (vat_main_t * vam)
15059 {
15060   unformat_input_t *line_input = vam->input;
15061   vl_api_want_l2_macs_events_t *mp;
15062   u8 enable_disable = 1;
15063   u32 scan_delay = 0;
15064   u32 max_macs_in_event = 0;
15065   u32 learn_limit = 0;
15066   int ret;
15067
15068   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15069     {
15070       if (unformat (line_input, "learn-limit %d", &learn_limit))
15071         ;
15072       else if (unformat (line_input, "scan-delay %d", &scan_delay))
15073         ;
15074       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
15075         ;
15076       else if (unformat (line_input, "disable"))
15077         enable_disable = 0;
15078       else
15079         break;
15080     }
15081
15082   M (WANT_L2_MACS_EVENTS, mp);
15083   mp->enable_disable = enable_disable;
15084   mp->pid = htonl (getpid ());
15085   mp->learn_limit = htonl (learn_limit);
15086   mp->scan_delay = (u8) scan_delay;
15087   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15088   S (mp);
15089   W (ret);
15090   return ret;
15091 }
15092
15093 static int
15094 api_input_acl_set_interface (vat_main_t * vam)
15095 {
15096   unformat_input_t *i = vam->input;
15097   vl_api_input_acl_set_interface_t *mp;
15098   u32 sw_if_index;
15099   int sw_if_index_set;
15100   u32 ip4_table_index = ~0;
15101   u32 ip6_table_index = ~0;
15102   u32 l2_table_index = ~0;
15103   u8 is_add = 1;
15104   int ret;
15105
15106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15107     {
15108       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15109         sw_if_index_set = 1;
15110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15111         sw_if_index_set = 1;
15112       else if (unformat (i, "del"))
15113         is_add = 0;
15114       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15115         ;
15116       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15117         ;
15118       else if (unformat (i, "l2-table %d", &l2_table_index))
15119         ;
15120       else
15121         {
15122           clib_warning ("parse error '%U'", format_unformat_error, i);
15123           return -99;
15124         }
15125     }
15126
15127   if (sw_if_index_set == 0)
15128     {
15129       errmsg ("missing interface name or sw_if_index");
15130       return -99;
15131     }
15132
15133   M (INPUT_ACL_SET_INTERFACE, mp);
15134
15135   mp->sw_if_index = ntohl (sw_if_index);
15136   mp->ip4_table_index = ntohl (ip4_table_index);
15137   mp->ip6_table_index = ntohl (ip6_table_index);
15138   mp->l2_table_index = ntohl (l2_table_index);
15139   mp->is_add = is_add;
15140
15141   S (mp);
15142   W (ret);
15143   return ret;
15144 }
15145
15146 static int
15147 api_output_acl_set_interface (vat_main_t * vam)
15148 {
15149   unformat_input_t *i = vam->input;
15150   vl_api_output_acl_set_interface_t *mp;
15151   u32 sw_if_index;
15152   int sw_if_index_set;
15153   u32 ip4_table_index = ~0;
15154   u32 ip6_table_index = ~0;
15155   u32 l2_table_index = ~0;
15156   u8 is_add = 1;
15157   int ret;
15158
15159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15160     {
15161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15162         sw_if_index_set = 1;
15163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15164         sw_if_index_set = 1;
15165       else if (unformat (i, "del"))
15166         is_add = 0;
15167       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15168         ;
15169       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15170         ;
15171       else if (unformat (i, "l2-table %d", &l2_table_index))
15172         ;
15173       else
15174         {
15175           clib_warning ("parse error '%U'", format_unformat_error, i);
15176           return -99;
15177         }
15178     }
15179
15180   if (sw_if_index_set == 0)
15181     {
15182       errmsg ("missing interface name or sw_if_index");
15183       return -99;
15184     }
15185
15186   M (OUTPUT_ACL_SET_INTERFACE, mp);
15187
15188   mp->sw_if_index = ntohl (sw_if_index);
15189   mp->ip4_table_index = ntohl (ip4_table_index);
15190   mp->ip6_table_index = ntohl (ip6_table_index);
15191   mp->l2_table_index = ntohl (l2_table_index);
15192   mp->is_add = is_add;
15193
15194   S (mp);
15195   W (ret);
15196   return ret;
15197 }
15198
15199 static int
15200 api_ip_address_dump (vat_main_t * vam)
15201 {
15202   unformat_input_t *i = vam->input;
15203   vl_api_ip_address_dump_t *mp;
15204   vl_api_control_ping_t *mp_ping;
15205   u32 sw_if_index = ~0;
15206   u8 sw_if_index_set = 0;
15207   u8 ipv4_set = 0;
15208   u8 ipv6_set = 0;
15209   int ret;
15210
15211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15212     {
15213       if (unformat (i, "sw_if_index %d", &sw_if_index))
15214         sw_if_index_set = 1;
15215       else
15216         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15217         sw_if_index_set = 1;
15218       else if (unformat (i, "ipv4"))
15219         ipv4_set = 1;
15220       else if (unformat (i, "ipv6"))
15221         ipv6_set = 1;
15222       else
15223         break;
15224     }
15225
15226   if (ipv4_set && ipv6_set)
15227     {
15228       errmsg ("ipv4 and ipv6 flags cannot be both set");
15229       return -99;
15230     }
15231
15232   if ((!ipv4_set) && (!ipv6_set))
15233     {
15234       errmsg ("no ipv4 nor ipv6 flag set");
15235       return -99;
15236     }
15237
15238   if (sw_if_index_set == 0)
15239     {
15240       errmsg ("missing interface name or sw_if_index");
15241       return -99;
15242     }
15243
15244   vam->current_sw_if_index = sw_if_index;
15245   vam->is_ipv6 = ipv6_set;
15246
15247   M (IP_ADDRESS_DUMP, mp);
15248   mp->sw_if_index = ntohl (sw_if_index);
15249   mp->is_ipv6 = ipv6_set;
15250   S (mp);
15251
15252   /* Use a control ping for synchronization */
15253   MPING (CONTROL_PING, mp_ping);
15254   S (mp_ping);
15255
15256   W (ret);
15257   return ret;
15258 }
15259
15260 static int
15261 api_ip_dump (vat_main_t * vam)
15262 {
15263   vl_api_ip_dump_t *mp;
15264   vl_api_control_ping_t *mp_ping;
15265   unformat_input_t *in = vam->input;
15266   int ipv4_set = 0;
15267   int ipv6_set = 0;
15268   int is_ipv6;
15269   int i;
15270   int ret;
15271
15272   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15273     {
15274       if (unformat (in, "ipv4"))
15275         ipv4_set = 1;
15276       else if (unformat (in, "ipv6"))
15277         ipv6_set = 1;
15278       else
15279         break;
15280     }
15281
15282   if (ipv4_set && ipv6_set)
15283     {
15284       errmsg ("ipv4 and ipv6 flags cannot be both set");
15285       return -99;
15286     }
15287
15288   if ((!ipv4_set) && (!ipv6_set))
15289     {
15290       errmsg ("no ipv4 nor ipv6 flag set");
15291       return -99;
15292     }
15293
15294   is_ipv6 = ipv6_set;
15295   vam->is_ipv6 = is_ipv6;
15296
15297   /* free old data */
15298   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15299     {
15300       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15301     }
15302   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15303
15304   M (IP_DUMP, mp);
15305   mp->is_ipv6 = ipv6_set;
15306   S (mp);
15307
15308   /* Use a control ping for synchronization */
15309   MPING (CONTROL_PING, mp_ping);
15310   S (mp_ping);
15311
15312   W (ret);
15313   return ret;
15314 }
15315
15316 static int
15317 api_ipsec_spd_add_del (vat_main_t * vam)
15318 {
15319   unformat_input_t *i = vam->input;
15320   vl_api_ipsec_spd_add_del_t *mp;
15321   u32 spd_id = ~0;
15322   u8 is_add = 1;
15323   int ret;
15324
15325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15326     {
15327       if (unformat (i, "spd_id %d", &spd_id))
15328         ;
15329       else if (unformat (i, "del"))
15330         is_add = 0;
15331       else
15332         {
15333           clib_warning ("parse error '%U'", format_unformat_error, i);
15334           return -99;
15335         }
15336     }
15337   if (spd_id == ~0)
15338     {
15339       errmsg ("spd_id must be set");
15340       return -99;
15341     }
15342
15343   M (IPSEC_SPD_ADD_DEL, mp);
15344
15345   mp->spd_id = ntohl (spd_id);
15346   mp->is_add = is_add;
15347
15348   S (mp);
15349   W (ret);
15350   return ret;
15351 }
15352
15353 static int
15354 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15355 {
15356   unformat_input_t *i = vam->input;
15357   vl_api_ipsec_interface_add_del_spd_t *mp;
15358   u32 sw_if_index;
15359   u8 sw_if_index_set = 0;
15360   u32 spd_id = (u32) ~ 0;
15361   u8 is_add = 1;
15362   int ret;
15363
15364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15365     {
15366       if (unformat (i, "del"))
15367         is_add = 0;
15368       else if (unformat (i, "spd_id %d", &spd_id))
15369         ;
15370       else
15371         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15372         sw_if_index_set = 1;
15373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15374         sw_if_index_set = 1;
15375       else
15376         {
15377           clib_warning ("parse error '%U'", format_unformat_error, i);
15378           return -99;
15379         }
15380
15381     }
15382
15383   if (spd_id == (u32) ~ 0)
15384     {
15385       errmsg ("spd_id must be set");
15386       return -99;
15387     }
15388
15389   if (sw_if_index_set == 0)
15390     {
15391       errmsg ("missing interface name or sw_if_index");
15392       return -99;
15393     }
15394
15395   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15396
15397   mp->spd_id = ntohl (spd_id);
15398   mp->sw_if_index = ntohl (sw_if_index);
15399   mp->is_add = is_add;
15400
15401   S (mp);
15402   W (ret);
15403   return ret;
15404 }
15405
15406 static int
15407 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15408 {
15409   unformat_input_t *i = vam->input;
15410   vl_api_ipsec_spd_add_del_entry_t *mp;
15411   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15412   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15413   i32 priority = 0;
15414   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15415   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15416   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15417   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15418   int ret;
15419
15420   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15421   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15422   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15423   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15424   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15425   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15426
15427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15428     {
15429       if (unformat (i, "del"))
15430         is_add = 0;
15431       if (unformat (i, "outbound"))
15432         is_outbound = 1;
15433       if (unformat (i, "inbound"))
15434         is_outbound = 0;
15435       else if (unformat (i, "spd_id %d", &spd_id))
15436         ;
15437       else if (unformat (i, "sa_id %d", &sa_id))
15438         ;
15439       else if (unformat (i, "priority %d", &priority))
15440         ;
15441       else if (unformat (i, "protocol %d", &protocol))
15442         ;
15443       else if (unformat (i, "lport_start %d", &lport_start))
15444         ;
15445       else if (unformat (i, "lport_stop %d", &lport_stop))
15446         ;
15447       else if (unformat (i, "rport_start %d", &rport_start))
15448         ;
15449       else if (unformat (i, "rport_stop %d", &rport_stop))
15450         ;
15451       else
15452         if (unformat
15453             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15454         {
15455           is_ipv6 = 0;
15456           is_ip_any = 0;
15457         }
15458       else
15459         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15460         {
15461           is_ipv6 = 0;
15462           is_ip_any = 0;
15463         }
15464       else
15465         if (unformat
15466             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15467         {
15468           is_ipv6 = 0;
15469           is_ip_any = 0;
15470         }
15471       else
15472         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15473         {
15474           is_ipv6 = 0;
15475           is_ip_any = 0;
15476         }
15477       else
15478         if (unformat
15479             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15480         {
15481           is_ipv6 = 1;
15482           is_ip_any = 0;
15483         }
15484       else
15485         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15486         {
15487           is_ipv6 = 1;
15488           is_ip_any = 0;
15489         }
15490       else
15491         if (unformat
15492             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15493         {
15494           is_ipv6 = 1;
15495           is_ip_any = 0;
15496         }
15497       else
15498         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15499         {
15500           is_ipv6 = 1;
15501           is_ip_any = 0;
15502         }
15503       else
15504         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15505         {
15506           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15507             {
15508               clib_warning ("unsupported action: 'resolve'");
15509               return -99;
15510             }
15511         }
15512       else
15513         {
15514           clib_warning ("parse error '%U'", format_unformat_error, i);
15515           return -99;
15516         }
15517
15518     }
15519
15520   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15521
15522   mp->spd_id = ntohl (spd_id);
15523   mp->priority = ntohl (priority);
15524   mp->is_outbound = is_outbound;
15525
15526   mp->is_ipv6 = is_ipv6;
15527   if (is_ipv6 || is_ip_any)
15528     {
15529       clib_memcpy (mp->remote_address_start, &raddr6_start,
15530                    sizeof (ip6_address_t));
15531       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15532                    sizeof (ip6_address_t));
15533       clib_memcpy (mp->local_address_start, &laddr6_start,
15534                    sizeof (ip6_address_t));
15535       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15536                    sizeof (ip6_address_t));
15537     }
15538   else
15539     {
15540       clib_memcpy (mp->remote_address_start, &raddr4_start,
15541                    sizeof (ip4_address_t));
15542       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15543                    sizeof (ip4_address_t));
15544       clib_memcpy (mp->local_address_start, &laddr4_start,
15545                    sizeof (ip4_address_t));
15546       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15547                    sizeof (ip4_address_t));
15548     }
15549   mp->protocol = (u8) protocol;
15550   mp->local_port_start = ntohs ((u16) lport_start);
15551   mp->local_port_stop = ntohs ((u16) lport_stop);
15552   mp->remote_port_start = ntohs ((u16) rport_start);
15553   mp->remote_port_stop = ntohs ((u16) rport_stop);
15554   mp->policy = (u8) policy;
15555   mp->sa_id = ntohl (sa_id);
15556   mp->is_add = is_add;
15557   mp->is_ip_any = is_ip_any;
15558   S (mp);
15559   W (ret);
15560   return ret;
15561 }
15562
15563 static int
15564 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15565 {
15566   unformat_input_t *i = vam->input;
15567   vl_api_ipsec_sad_add_del_entry_t *mp;
15568   u32 sad_id = 0, spi = 0;
15569   u8 *ck = 0, *ik = 0;
15570   u8 is_add = 1;
15571
15572   u8 protocol = IPSEC_PROTOCOL_AH;
15573   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15574   u32 crypto_alg = 0, integ_alg = 0;
15575   ip4_address_t tun_src4;
15576   ip4_address_t tun_dst4;
15577   ip6_address_t tun_src6;
15578   ip6_address_t tun_dst6;
15579   int ret;
15580
15581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15582     {
15583       if (unformat (i, "del"))
15584         is_add = 0;
15585       else if (unformat (i, "sad_id %d", &sad_id))
15586         ;
15587       else if (unformat (i, "spi %d", &spi))
15588         ;
15589       else if (unformat (i, "esp"))
15590         protocol = IPSEC_PROTOCOL_ESP;
15591       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15592         {
15593           is_tunnel = 1;
15594           is_tunnel_ipv6 = 0;
15595         }
15596       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15597         {
15598           is_tunnel = 1;
15599           is_tunnel_ipv6 = 0;
15600         }
15601       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15602         {
15603           is_tunnel = 1;
15604           is_tunnel_ipv6 = 1;
15605         }
15606       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15607         {
15608           is_tunnel = 1;
15609           is_tunnel_ipv6 = 1;
15610         }
15611       else
15612         if (unformat
15613             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15614         {
15615           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15616             {
15617               clib_warning ("unsupported crypto-alg: '%U'",
15618                             format_ipsec_crypto_alg, crypto_alg);
15619               return -99;
15620             }
15621         }
15622       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15623         ;
15624       else
15625         if (unformat
15626             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15627         {
15628           if (integ_alg >= IPSEC_INTEG_N_ALG)
15629             {
15630               clib_warning ("unsupported integ-alg: '%U'",
15631                             format_ipsec_integ_alg, integ_alg);
15632               return -99;
15633             }
15634         }
15635       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15636         ;
15637       else
15638         {
15639           clib_warning ("parse error '%U'", format_unformat_error, i);
15640           return -99;
15641         }
15642
15643     }
15644
15645   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15646
15647   mp->sad_id = ntohl (sad_id);
15648   mp->is_add = is_add;
15649   mp->protocol = protocol;
15650   mp->spi = ntohl (spi);
15651   mp->is_tunnel = is_tunnel;
15652   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15653   mp->crypto_algorithm = crypto_alg;
15654   mp->integrity_algorithm = integ_alg;
15655   mp->crypto_key_length = vec_len (ck);
15656   mp->integrity_key_length = vec_len (ik);
15657
15658   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15659     mp->crypto_key_length = sizeof (mp->crypto_key);
15660
15661   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15662     mp->integrity_key_length = sizeof (mp->integrity_key);
15663
15664   if (ck)
15665     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15666   if (ik)
15667     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15668
15669   if (is_tunnel)
15670     {
15671       if (is_tunnel_ipv6)
15672         {
15673           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15674                        sizeof (ip6_address_t));
15675           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15676                        sizeof (ip6_address_t));
15677         }
15678       else
15679         {
15680           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15681                        sizeof (ip4_address_t));
15682           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15683                        sizeof (ip4_address_t));
15684         }
15685     }
15686
15687   S (mp);
15688   W (ret);
15689   return ret;
15690 }
15691
15692 static int
15693 api_ipsec_sa_set_key (vat_main_t * vam)
15694 {
15695   unformat_input_t *i = vam->input;
15696   vl_api_ipsec_sa_set_key_t *mp;
15697   u32 sa_id;
15698   u8 *ck = 0, *ik = 0;
15699   int ret;
15700
15701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15702     {
15703       if (unformat (i, "sa_id %d", &sa_id))
15704         ;
15705       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15706         ;
15707       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15708         ;
15709       else
15710         {
15711           clib_warning ("parse error '%U'", format_unformat_error, i);
15712           return -99;
15713         }
15714     }
15715
15716   M (IPSEC_SA_SET_KEY, mp);
15717
15718   mp->sa_id = ntohl (sa_id);
15719   mp->crypto_key_length = vec_len (ck);
15720   mp->integrity_key_length = vec_len (ik);
15721
15722   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15723     mp->crypto_key_length = sizeof (mp->crypto_key);
15724
15725   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15726     mp->integrity_key_length = sizeof (mp->integrity_key);
15727
15728   if (ck)
15729     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15730   if (ik)
15731     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15732
15733   S (mp);
15734   W (ret);
15735   return ret;
15736 }
15737
15738 static int
15739 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15740 {
15741   unformat_input_t *i = vam->input;
15742   vl_api_ipsec_tunnel_if_add_del_t *mp;
15743   u32 local_spi = 0, remote_spi = 0;
15744   u32 crypto_alg = 0, integ_alg = 0;
15745   u8 *lck = NULL, *rck = NULL;
15746   u8 *lik = NULL, *rik = NULL;
15747   ip4_address_t local_ip = { {0} };
15748   ip4_address_t remote_ip = { {0} };
15749   u8 is_add = 1;
15750   u8 esn = 0;
15751   u8 anti_replay = 0;
15752   u8 renumber = 0;
15753   u32 instance = ~0;
15754   int ret;
15755
15756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15757     {
15758       if (unformat (i, "del"))
15759         is_add = 0;
15760       else if (unformat (i, "esn"))
15761         esn = 1;
15762       else if (unformat (i, "anti_replay"))
15763         anti_replay = 1;
15764       else if (unformat (i, "local_spi %d", &local_spi))
15765         ;
15766       else if (unformat (i, "remote_spi %d", &remote_spi))
15767         ;
15768       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15769         ;
15770       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15771         ;
15772       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15773         ;
15774       else
15775         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15776         ;
15777       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15778         ;
15779       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15780         ;
15781       else
15782         if (unformat
15783             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15784         {
15785           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15786             {
15787               errmsg ("unsupported crypto-alg: '%U'\n",
15788                       format_ipsec_crypto_alg, crypto_alg);
15789               return -99;
15790             }
15791         }
15792       else
15793         if (unformat
15794             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15795         {
15796           if (integ_alg >= IPSEC_INTEG_N_ALG)
15797             {
15798               errmsg ("unsupported integ-alg: '%U'\n",
15799                       format_ipsec_integ_alg, integ_alg);
15800               return -99;
15801             }
15802         }
15803       else if (unformat (i, "instance %u", &instance))
15804         renumber = 1;
15805       else
15806         {
15807           errmsg ("parse error '%U'\n", format_unformat_error, i);
15808           return -99;
15809         }
15810     }
15811
15812   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15813
15814   mp->is_add = is_add;
15815   mp->esn = esn;
15816   mp->anti_replay = anti_replay;
15817
15818   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15819   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15820
15821   mp->local_spi = htonl (local_spi);
15822   mp->remote_spi = htonl (remote_spi);
15823   mp->crypto_alg = (u8) crypto_alg;
15824
15825   mp->local_crypto_key_len = 0;
15826   if (lck)
15827     {
15828       mp->local_crypto_key_len = vec_len (lck);
15829       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15830         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15831       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15832     }
15833
15834   mp->remote_crypto_key_len = 0;
15835   if (rck)
15836     {
15837       mp->remote_crypto_key_len = vec_len (rck);
15838       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15839         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15840       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15841     }
15842
15843   mp->integ_alg = (u8) integ_alg;
15844
15845   mp->local_integ_key_len = 0;
15846   if (lik)
15847     {
15848       mp->local_integ_key_len = vec_len (lik);
15849       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15850         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15851       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15852     }
15853
15854   mp->remote_integ_key_len = 0;
15855   if (rik)
15856     {
15857       mp->remote_integ_key_len = vec_len (rik);
15858       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15859         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15860       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15861     }
15862
15863   if (renumber)
15864     {
15865       mp->renumber = renumber;
15866       mp->show_instance = ntohl (instance);
15867     }
15868
15869   S (mp);
15870   W (ret);
15871   return ret;
15872 }
15873
15874 static void
15875 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15876 {
15877   vat_main_t *vam = &vat_main;
15878
15879   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15880          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15881          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15882          "tunnel_src_addr %U tunnel_dst_addr %U "
15883          "salt %u seq_outbound %lu last_seq_inbound %lu "
15884          "replay_window %lu total_data_size %lu\n",
15885          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15886          mp->protocol,
15887          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15888          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15889          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15890          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15891          mp->tunnel_src_addr,
15892          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15893          mp->tunnel_dst_addr,
15894          ntohl (mp->salt),
15895          clib_net_to_host_u64 (mp->seq_outbound),
15896          clib_net_to_host_u64 (mp->last_seq_inbound),
15897          clib_net_to_host_u64 (mp->replay_window),
15898          clib_net_to_host_u64 (mp->total_data_size));
15899 }
15900
15901 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15902 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15903
15904 static void vl_api_ipsec_sa_details_t_handler_json
15905   (vl_api_ipsec_sa_details_t * mp)
15906 {
15907   vat_main_t *vam = &vat_main;
15908   vat_json_node_t *node = NULL;
15909   struct in_addr src_ip4, dst_ip4;
15910   struct in6_addr src_ip6, dst_ip6;
15911
15912   if (VAT_JSON_ARRAY != vam->json_tree.type)
15913     {
15914       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15915       vat_json_init_array (&vam->json_tree);
15916     }
15917   node = vat_json_array_add (&vam->json_tree);
15918
15919   vat_json_init_object (node);
15920   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15921   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15922   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15923   vat_json_object_add_uint (node, "proto", mp->protocol);
15924   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15925   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15926   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15927   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15928   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15929   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15930   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15931                              mp->crypto_key_len);
15932   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15933                              mp->integ_key_len);
15934   if (mp->is_tunnel_ip6)
15935     {
15936       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15937       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15938       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15939       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15940     }
15941   else
15942     {
15943       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15944       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15945       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15946       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15947     }
15948   vat_json_object_add_uint (node, "replay_window",
15949                             clib_net_to_host_u64 (mp->replay_window));
15950   vat_json_object_add_uint (node, "total_data_size",
15951                             clib_net_to_host_u64 (mp->total_data_size));
15952
15953 }
15954
15955 static int
15956 api_ipsec_sa_dump (vat_main_t * vam)
15957 {
15958   unformat_input_t *i = vam->input;
15959   vl_api_ipsec_sa_dump_t *mp;
15960   vl_api_control_ping_t *mp_ping;
15961   u32 sa_id = ~0;
15962   int ret;
15963
15964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15965     {
15966       if (unformat (i, "sa_id %d", &sa_id))
15967         ;
15968       else
15969         {
15970           clib_warning ("parse error '%U'", format_unformat_error, i);
15971           return -99;
15972         }
15973     }
15974
15975   M (IPSEC_SA_DUMP, mp);
15976
15977   mp->sa_id = ntohl (sa_id);
15978
15979   S (mp);
15980
15981   /* Use a control ping for synchronization */
15982   M (CONTROL_PING, mp_ping);
15983   S (mp_ping);
15984
15985   W (ret);
15986   return ret;
15987 }
15988
15989 static int
15990 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15991 {
15992   unformat_input_t *i = vam->input;
15993   vl_api_ipsec_tunnel_if_set_key_t *mp;
15994   u32 sw_if_index = ~0;
15995   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15996   u8 *key = 0;
15997   u32 alg = ~0;
15998   int ret;
15999
16000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16001     {
16002       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16003         ;
16004       else
16005         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
16006         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
16007       else
16008         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
16009         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
16010       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
16011         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
16012       else
16013         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
16014         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
16015       else if (unformat (i, "%U", unformat_hex_string, &key))
16016         ;
16017       else
16018         {
16019           clib_warning ("parse error '%U'", format_unformat_error, i);
16020           return -99;
16021         }
16022     }
16023
16024   if (sw_if_index == ~0)
16025     {
16026       errmsg ("interface must be specified");
16027       return -99;
16028     }
16029
16030   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
16031     {
16032       errmsg ("key type must be specified");
16033       return -99;
16034     }
16035
16036   if (alg == ~0)
16037     {
16038       errmsg ("algorithm must be specified");
16039       return -99;
16040     }
16041
16042   if (vec_len (key) == 0)
16043     {
16044       errmsg ("key must be specified");
16045       return -99;
16046     }
16047
16048   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
16049
16050   mp->sw_if_index = htonl (sw_if_index);
16051   mp->alg = alg;
16052   mp->key_type = key_type;
16053   mp->key_len = vec_len (key);
16054   clib_memcpy (mp->key, key, vec_len (key));
16055
16056   S (mp);
16057   W (ret);
16058
16059   return ret;
16060 }
16061
16062 static int
16063 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
16064 {
16065   unformat_input_t *i = vam->input;
16066   vl_api_ipsec_tunnel_if_set_sa_t *mp;
16067   u32 sw_if_index = ~0;
16068   u32 sa_id = ~0;
16069   u8 is_outbound = (u8) ~ 0;
16070   int ret;
16071
16072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16073     {
16074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16075         ;
16076       else if (unformat (i, "sa_id %d", &sa_id))
16077         ;
16078       else if (unformat (i, "outbound"))
16079         is_outbound = 1;
16080       else if (unformat (i, "inbound"))
16081         is_outbound = 0;
16082       else
16083         {
16084           clib_warning ("parse error '%U'", format_unformat_error, i);
16085           return -99;
16086         }
16087     }
16088
16089   if (sw_if_index == ~0)
16090     {
16091       errmsg ("interface must be specified");
16092       return -99;
16093     }
16094
16095   if (sa_id == ~0)
16096     {
16097       errmsg ("SA ID must be specified");
16098       return -99;
16099     }
16100
16101   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16102
16103   mp->sw_if_index = htonl (sw_if_index);
16104   mp->sa_id = htonl (sa_id);
16105   mp->is_outbound = is_outbound;
16106
16107   S (mp);
16108   W (ret);
16109
16110   return ret;
16111 }
16112
16113 static int
16114 api_ikev2_profile_add_del (vat_main_t * vam)
16115 {
16116   unformat_input_t *i = vam->input;
16117   vl_api_ikev2_profile_add_del_t *mp;
16118   u8 is_add = 1;
16119   u8 *name = 0;
16120   int ret;
16121
16122   const char *valid_chars = "a-zA-Z0-9_";
16123
16124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16125     {
16126       if (unformat (i, "del"))
16127         is_add = 0;
16128       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16129         vec_add1 (name, 0);
16130       else
16131         {
16132           errmsg ("parse error '%U'", format_unformat_error, i);
16133           return -99;
16134         }
16135     }
16136
16137   if (!vec_len (name))
16138     {
16139       errmsg ("profile name must be specified");
16140       return -99;
16141     }
16142
16143   if (vec_len (name) > 64)
16144     {
16145       errmsg ("profile name too long");
16146       return -99;
16147     }
16148
16149   M (IKEV2_PROFILE_ADD_DEL, mp);
16150
16151   clib_memcpy (mp->name, name, vec_len (name));
16152   mp->is_add = is_add;
16153   vec_free (name);
16154
16155   S (mp);
16156   W (ret);
16157   return ret;
16158 }
16159
16160 static int
16161 api_ikev2_profile_set_auth (vat_main_t * vam)
16162 {
16163   unformat_input_t *i = vam->input;
16164   vl_api_ikev2_profile_set_auth_t *mp;
16165   u8 *name = 0;
16166   u8 *data = 0;
16167   u32 auth_method = 0;
16168   u8 is_hex = 0;
16169   int ret;
16170
16171   const char *valid_chars = "a-zA-Z0-9_";
16172
16173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16174     {
16175       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16176         vec_add1 (name, 0);
16177       else if (unformat (i, "auth_method %U",
16178                          unformat_ikev2_auth_method, &auth_method))
16179         ;
16180       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16181         is_hex = 1;
16182       else if (unformat (i, "auth_data %v", &data))
16183         ;
16184       else
16185         {
16186           errmsg ("parse error '%U'", format_unformat_error, i);
16187           return -99;
16188         }
16189     }
16190
16191   if (!vec_len (name))
16192     {
16193       errmsg ("profile name must be specified");
16194       return -99;
16195     }
16196
16197   if (vec_len (name) > 64)
16198     {
16199       errmsg ("profile name too long");
16200       return -99;
16201     }
16202
16203   if (!vec_len (data))
16204     {
16205       errmsg ("auth_data must be specified");
16206       return -99;
16207     }
16208
16209   if (!auth_method)
16210     {
16211       errmsg ("auth_method must be specified");
16212       return -99;
16213     }
16214
16215   M (IKEV2_PROFILE_SET_AUTH, mp);
16216
16217   mp->is_hex = is_hex;
16218   mp->auth_method = (u8) auth_method;
16219   mp->data_len = vec_len (data);
16220   clib_memcpy (mp->name, name, vec_len (name));
16221   clib_memcpy (mp->data, data, vec_len (data));
16222   vec_free (name);
16223   vec_free (data);
16224
16225   S (mp);
16226   W (ret);
16227   return ret;
16228 }
16229
16230 static int
16231 api_ikev2_profile_set_id (vat_main_t * vam)
16232 {
16233   unformat_input_t *i = vam->input;
16234   vl_api_ikev2_profile_set_id_t *mp;
16235   u8 *name = 0;
16236   u8 *data = 0;
16237   u8 is_local = 0;
16238   u32 id_type = 0;
16239   ip4_address_t ip4;
16240   int ret;
16241
16242   const char *valid_chars = "a-zA-Z0-9_";
16243
16244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16247         vec_add1 (name, 0);
16248       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16249         ;
16250       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16251         {
16252           data = vec_new (u8, 4);
16253           clib_memcpy (data, ip4.as_u8, 4);
16254         }
16255       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16256         ;
16257       else if (unformat (i, "id_data %v", &data))
16258         ;
16259       else if (unformat (i, "local"))
16260         is_local = 1;
16261       else if (unformat (i, "remote"))
16262         is_local = 0;
16263       else
16264         {
16265           errmsg ("parse error '%U'", format_unformat_error, i);
16266           return -99;
16267         }
16268     }
16269
16270   if (!vec_len (name))
16271     {
16272       errmsg ("profile name must be specified");
16273       return -99;
16274     }
16275
16276   if (vec_len (name) > 64)
16277     {
16278       errmsg ("profile name too long");
16279       return -99;
16280     }
16281
16282   if (!vec_len (data))
16283     {
16284       errmsg ("id_data must be specified");
16285       return -99;
16286     }
16287
16288   if (!id_type)
16289     {
16290       errmsg ("id_type must be specified");
16291       return -99;
16292     }
16293
16294   M (IKEV2_PROFILE_SET_ID, mp);
16295
16296   mp->is_local = is_local;
16297   mp->id_type = (u8) id_type;
16298   mp->data_len = vec_len (data);
16299   clib_memcpy (mp->name, name, vec_len (name));
16300   clib_memcpy (mp->data, data, vec_len (data));
16301   vec_free (name);
16302   vec_free (data);
16303
16304   S (mp);
16305   W (ret);
16306   return ret;
16307 }
16308
16309 static int
16310 api_ikev2_profile_set_ts (vat_main_t * vam)
16311 {
16312   unformat_input_t *i = vam->input;
16313   vl_api_ikev2_profile_set_ts_t *mp;
16314   u8 *name = 0;
16315   u8 is_local = 0;
16316   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16317   ip4_address_t start_addr, end_addr;
16318
16319   const char *valid_chars = "a-zA-Z0-9_";
16320   int ret;
16321
16322   start_addr.as_u32 = 0;
16323   end_addr.as_u32 = (u32) ~ 0;
16324
16325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16326     {
16327       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16328         vec_add1 (name, 0);
16329       else if (unformat (i, "protocol %d", &proto))
16330         ;
16331       else if (unformat (i, "start_port %d", &start_port))
16332         ;
16333       else if (unformat (i, "end_port %d", &end_port))
16334         ;
16335       else
16336         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16337         ;
16338       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16339         ;
16340       else if (unformat (i, "local"))
16341         is_local = 1;
16342       else if (unformat (i, "remote"))
16343         is_local = 0;
16344       else
16345         {
16346           errmsg ("parse error '%U'", format_unformat_error, i);
16347           return -99;
16348         }
16349     }
16350
16351   if (!vec_len (name))
16352     {
16353       errmsg ("profile name must be specified");
16354       return -99;
16355     }
16356
16357   if (vec_len (name) > 64)
16358     {
16359       errmsg ("profile name too long");
16360       return -99;
16361     }
16362
16363   M (IKEV2_PROFILE_SET_TS, mp);
16364
16365   mp->is_local = is_local;
16366   mp->proto = (u8) proto;
16367   mp->start_port = (u16) start_port;
16368   mp->end_port = (u16) end_port;
16369   mp->start_addr = start_addr.as_u32;
16370   mp->end_addr = end_addr.as_u32;
16371   clib_memcpy (mp->name, name, vec_len (name));
16372   vec_free (name);
16373
16374   S (mp);
16375   W (ret);
16376   return ret;
16377 }
16378
16379 static int
16380 api_ikev2_set_local_key (vat_main_t * vam)
16381 {
16382   unformat_input_t *i = vam->input;
16383   vl_api_ikev2_set_local_key_t *mp;
16384   u8 *file = 0;
16385   int ret;
16386
16387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16388     {
16389       if (unformat (i, "file %v", &file))
16390         vec_add1 (file, 0);
16391       else
16392         {
16393           errmsg ("parse error '%U'", format_unformat_error, i);
16394           return -99;
16395         }
16396     }
16397
16398   if (!vec_len (file))
16399     {
16400       errmsg ("RSA key file must be specified");
16401       return -99;
16402     }
16403
16404   if (vec_len (file) > 256)
16405     {
16406       errmsg ("file name too long");
16407       return -99;
16408     }
16409
16410   M (IKEV2_SET_LOCAL_KEY, mp);
16411
16412   clib_memcpy (mp->key_file, file, vec_len (file));
16413   vec_free (file);
16414
16415   S (mp);
16416   W (ret);
16417   return ret;
16418 }
16419
16420 static int
16421 api_ikev2_set_responder (vat_main_t * vam)
16422 {
16423   unformat_input_t *i = vam->input;
16424   vl_api_ikev2_set_responder_t *mp;
16425   int ret;
16426   u8 *name = 0;
16427   u32 sw_if_index = ~0;
16428   ip4_address_t address;
16429
16430   const char *valid_chars = "a-zA-Z0-9_";
16431
16432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16433     {
16434       if (unformat
16435           (i, "%U interface %d address %U", unformat_token, valid_chars,
16436            &name, &sw_if_index, unformat_ip4_address, &address))
16437         vec_add1 (name, 0);
16438       else
16439         {
16440           errmsg ("parse error '%U'", format_unformat_error, i);
16441           return -99;
16442         }
16443     }
16444
16445   if (!vec_len (name))
16446     {
16447       errmsg ("profile name must be specified");
16448       return -99;
16449     }
16450
16451   if (vec_len (name) > 64)
16452     {
16453       errmsg ("profile name too long");
16454       return -99;
16455     }
16456
16457   M (IKEV2_SET_RESPONDER, mp);
16458
16459   clib_memcpy (mp->name, name, vec_len (name));
16460   vec_free (name);
16461
16462   mp->sw_if_index = sw_if_index;
16463   clib_memcpy (mp->address, &address, sizeof (address));
16464
16465   S (mp);
16466   W (ret);
16467   return ret;
16468 }
16469
16470 static int
16471 api_ikev2_set_ike_transforms (vat_main_t * vam)
16472 {
16473   unformat_input_t *i = vam->input;
16474   vl_api_ikev2_set_ike_transforms_t *mp;
16475   int ret;
16476   u8 *name = 0;
16477   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16478
16479   const char *valid_chars = "a-zA-Z0-9_";
16480
16481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16482     {
16483       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16484                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16485         vec_add1 (name, 0);
16486       else
16487         {
16488           errmsg ("parse error '%U'", format_unformat_error, i);
16489           return -99;
16490         }
16491     }
16492
16493   if (!vec_len (name))
16494     {
16495       errmsg ("profile name must be specified");
16496       return -99;
16497     }
16498
16499   if (vec_len (name) > 64)
16500     {
16501       errmsg ("profile name too long");
16502       return -99;
16503     }
16504
16505   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16506
16507   clib_memcpy (mp->name, name, vec_len (name));
16508   vec_free (name);
16509   mp->crypto_alg = crypto_alg;
16510   mp->crypto_key_size = crypto_key_size;
16511   mp->integ_alg = integ_alg;
16512   mp->dh_group = dh_group;
16513
16514   S (mp);
16515   W (ret);
16516   return ret;
16517 }
16518
16519
16520 static int
16521 api_ikev2_set_esp_transforms (vat_main_t * vam)
16522 {
16523   unformat_input_t *i = vam->input;
16524   vl_api_ikev2_set_esp_transforms_t *mp;
16525   int ret;
16526   u8 *name = 0;
16527   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16528
16529   const char *valid_chars = "a-zA-Z0-9_";
16530
16531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16532     {
16533       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16534                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16535         vec_add1 (name, 0);
16536       else
16537         {
16538           errmsg ("parse error '%U'", format_unformat_error, i);
16539           return -99;
16540         }
16541     }
16542
16543   if (!vec_len (name))
16544     {
16545       errmsg ("profile name must be specified");
16546       return -99;
16547     }
16548
16549   if (vec_len (name) > 64)
16550     {
16551       errmsg ("profile name too long");
16552       return -99;
16553     }
16554
16555   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16556
16557   clib_memcpy (mp->name, name, vec_len (name));
16558   vec_free (name);
16559   mp->crypto_alg = crypto_alg;
16560   mp->crypto_key_size = crypto_key_size;
16561   mp->integ_alg = integ_alg;
16562   mp->dh_group = dh_group;
16563
16564   S (mp);
16565   W (ret);
16566   return ret;
16567 }
16568
16569 static int
16570 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16571 {
16572   unformat_input_t *i = vam->input;
16573   vl_api_ikev2_set_sa_lifetime_t *mp;
16574   int ret;
16575   u8 *name = 0;
16576   u64 lifetime, lifetime_maxdata;
16577   u32 lifetime_jitter, handover;
16578
16579   const char *valid_chars = "a-zA-Z0-9_";
16580
16581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16582     {
16583       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16584                     &lifetime, &lifetime_jitter, &handover,
16585                     &lifetime_maxdata))
16586         vec_add1 (name, 0);
16587       else
16588         {
16589           errmsg ("parse error '%U'", format_unformat_error, i);
16590           return -99;
16591         }
16592     }
16593
16594   if (!vec_len (name))
16595     {
16596       errmsg ("profile name must be specified");
16597       return -99;
16598     }
16599
16600   if (vec_len (name) > 64)
16601     {
16602       errmsg ("profile name too long");
16603       return -99;
16604     }
16605
16606   M (IKEV2_SET_SA_LIFETIME, mp);
16607
16608   clib_memcpy (mp->name, name, vec_len (name));
16609   vec_free (name);
16610   mp->lifetime = lifetime;
16611   mp->lifetime_jitter = lifetime_jitter;
16612   mp->handover = handover;
16613   mp->lifetime_maxdata = lifetime_maxdata;
16614
16615   S (mp);
16616   W (ret);
16617   return ret;
16618 }
16619
16620 static int
16621 api_ikev2_initiate_sa_init (vat_main_t * vam)
16622 {
16623   unformat_input_t *i = vam->input;
16624   vl_api_ikev2_initiate_sa_init_t *mp;
16625   int ret;
16626   u8 *name = 0;
16627
16628   const char *valid_chars = "a-zA-Z0-9_";
16629
16630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16631     {
16632       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16633         vec_add1 (name, 0);
16634       else
16635         {
16636           errmsg ("parse error '%U'", format_unformat_error, i);
16637           return -99;
16638         }
16639     }
16640
16641   if (!vec_len (name))
16642     {
16643       errmsg ("profile name must be specified");
16644       return -99;
16645     }
16646
16647   if (vec_len (name) > 64)
16648     {
16649       errmsg ("profile name too long");
16650       return -99;
16651     }
16652
16653   M (IKEV2_INITIATE_SA_INIT, mp);
16654
16655   clib_memcpy (mp->name, name, vec_len (name));
16656   vec_free (name);
16657
16658   S (mp);
16659   W (ret);
16660   return ret;
16661 }
16662
16663 static int
16664 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16665 {
16666   unformat_input_t *i = vam->input;
16667   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16668   int ret;
16669   u64 ispi;
16670
16671
16672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16673     {
16674       if (unformat (i, "%lx", &ispi))
16675         ;
16676       else
16677         {
16678           errmsg ("parse error '%U'", format_unformat_error, i);
16679           return -99;
16680         }
16681     }
16682
16683   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16684
16685   mp->ispi = ispi;
16686
16687   S (mp);
16688   W (ret);
16689   return ret;
16690 }
16691
16692 static int
16693 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16694 {
16695   unformat_input_t *i = vam->input;
16696   vl_api_ikev2_initiate_del_child_sa_t *mp;
16697   int ret;
16698   u32 ispi;
16699
16700
16701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16702     {
16703       if (unformat (i, "%x", &ispi))
16704         ;
16705       else
16706         {
16707           errmsg ("parse error '%U'", format_unformat_error, i);
16708           return -99;
16709         }
16710     }
16711
16712   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16713
16714   mp->ispi = ispi;
16715
16716   S (mp);
16717   W (ret);
16718   return ret;
16719 }
16720
16721 static int
16722 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16723 {
16724   unformat_input_t *i = vam->input;
16725   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16726   int ret;
16727   u32 ispi;
16728
16729
16730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16731     {
16732       if (unformat (i, "%x", &ispi))
16733         ;
16734       else
16735         {
16736           errmsg ("parse error '%U'", format_unformat_error, i);
16737           return -99;
16738         }
16739     }
16740
16741   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16742
16743   mp->ispi = ispi;
16744
16745   S (mp);
16746   W (ret);
16747   return ret;
16748 }
16749
16750 static int
16751 api_get_first_msg_id (vat_main_t * vam)
16752 {
16753   vl_api_get_first_msg_id_t *mp;
16754   unformat_input_t *i = vam->input;
16755   u8 *name;
16756   u8 name_set = 0;
16757   int ret;
16758
16759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16760     {
16761       if (unformat (i, "client %s", &name))
16762         name_set = 1;
16763       else
16764         break;
16765     }
16766
16767   if (name_set == 0)
16768     {
16769       errmsg ("missing client name");
16770       return -99;
16771     }
16772   vec_add1 (name, 0);
16773
16774   if (vec_len (name) > 63)
16775     {
16776       errmsg ("client name too long");
16777       return -99;
16778     }
16779
16780   M (GET_FIRST_MSG_ID, mp);
16781   clib_memcpy (mp->name, name, vec_len (name));
16782   S (mp);
16783   W (ret);
16784   return ret;
16785 }
16786
16787 static int
16788 api_cop_interface_enable_disable (vat_main_t * vam)
16789 {
16790   unformat_input_t *line_input = vam->input;
16791   vl_api_cop_interface_enable_disable_t *mp;
16792   u32 sw_if_index = ~0;
16793   u8 enable_disable = 1;
16794   int ret;
16795
16796   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16797     {
16798       if (unformat (line_input, "disable"))
16799         enable_disable = 0;
16800       if (unformat (line_input, "enable"))
16801         enable_disable = 1;
16802       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16803                          vam, &sw_if_index))
16804         ;
16805       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16806         ;
16807       else
16808         break;
16809     }
16810
16811   if (sw_if_index == ~0)
16812     {
16813       errmsg ("missing interface name or sw_if_index");
16814       return -99;
16815     }
16816
16817   /* Construct the API message */
16818   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16819   mp->sw_if_index = ntohl (sw_if_index);
16820   mp->enable_disable = enable_disable;
16821
16822   /* send it... */
16823   S (mp);
16824   /* Wait for the reply */
16825   W (ret);
16826   return ret;
16827 }
16828
16829 static int
16830 api_cop_whitelist_enable_disable (vat_main_t * vam)
16831 {
16832   unformat_input_t *line_input = vam->input;
16833   vl_api_cop_whitelist_enable_disable_t *mp;
16834   u32 sw_if_index = ~0;
16835   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16836   u32 fib_id = 0;
16837   int ret;
16838
16839   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16840     {
16841       if (unformat (line_input, "ip4"))
16842         ip4 = 1;
16843       else if (unformat (line_input, "ip6"))
16844         ip6 = 1;
16845       else if (unformat (line_input, "default"))
16846         default_cop = 1;
16847       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16848                          vam, &sw_if_index))
16849         ;
16850       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16851         ;
16852       else if (unformat (line_input, "fib-id %d", &fib_id))
16853         ;
16854       else
16855         break;
16856     }
16857
16858   if (sw_if_index == ~0)
16859     {
16860       errmsg ("missing interface name or sw_if_index");
16861       return -99;
16862     }
16863
16864   /* Construct the API message */
16865   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16866   mp->sw_if_index = ntohl (sw_if_index);
16867   mp->fib_id = ntohl (fib_id);
16868   mp->ip4 = ip4;
16869   mp->ip6 = ip6;
16870   mp->default_cop = default_cop;
16871
16872   /* send it... */
16873   S (mp);
16874   /* Wait for the reply */
16875   W (ret);
16876   return ret;
16877 }
16878
16879 static int
16880 api_get_node_graph (vat_main_t * vam)
16881 {
16882   vl_api_get_node_graph_t *mp;
16883   int ret;
16884
16885   M (GET_NODE_GRAPH, mp);
16886
16887   /* send it... */
16888   S (mp);
16889   /* Wait for the reply */
16890   W (ret);
16891   return ret;
16892 }
16893
16894 /* *INDENT-OFF* */
16895 /** Used for parsing LISP eids */
16896 typedef CLIB_PACKED(struct{
16897   u8 addr[16];   /**< eid address */
16898   u32 len;       /**< prefix length if IP */
16899   u8 type;      /**< type of eid */
16900 }) lisp_eid_vat_t;
16901 /* *INDENT-ON* */
16902
16903 static uword
16904 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16905 {
16906   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16907
16908   clib_memset (a, 0, sizeof (a[0]));
16909
16910   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16911     {
16912       a->type = 0;              /* ipv4 type */
16913     }
16914   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16915     {
16916       a->type = 1;              /* ipv6 type */
16917     }
16918   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16919     {
16920       a->type = 2;              /* mac type */
16921     }
16922   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16923     {
16924       a->type = 3;              /* NSH type */
16925       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16926       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16927     }
16928   else
16929     {
16930       return 0;
16931     }
16932
16933   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16934     {
16935       return 0;
16936     }
16937
16938   return 1;
16939 }
16940
16941 static int
16942 lisp_eid_size_vat (u8 type)
16943 {
16944   switch (type)
16945     {
16946     case 0:
16947       return 4;
16948     case 1:
16949       return 16;
16950     case 2:
16951       return 6;
16952     case 3:
16953       return 5;
16954     }
16955   return 0;
16956 }
16957
16958 static void
16959 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16960 {
16961   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16962 }
16963
16964 static int
16965 api_one_add_del_locator_set (vat_main_t * vam)
16966 {
16967   unformat_input_t *input = vam->input;
16968   vl_api_one_add_del_locator_set_t *mp;
16969   u8 is_add = 1;
16970   u8 *locator_set_name = NULL;
16971   u8 locator_set_name_set = 0;
16972   vl_api_local_locator_t locator, *locators = 0;
16973   u32 sw_if_index, priority, weight;
16974   u32 data_len = 0;
16975
16976   int ret;
16977   /* Parse args required to build the message */
16978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16979     {
16980       if (unformat (input, "del"))
16981         {
16982           is_add = 0;
16983         }
16984       else if (unformat (input, "locator-set %s", &locator_set_name))
16985         {
16986           locator_set_name_set = 1;
16987         }
16988       else if (unformat (input, "sw_if_index %u p %u w %u",
16989                          &sw_if_index, &priority, &weight))
16990         {
16991           locator.sw_if_index = htonl (sw_if_index);
16992           locator.priority = priority;
16993           locator.weight = weight;
16994           vec_add1 (locators, locator);
16995         }
16996       else
16997         if (unformat
16998             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16999              &sw_if_index, &priority, &weight))
17000         {
17001           locator.sw_if_index = htonl (sw_if_index);
17002           locator.priority = priority;
17003           locator.weight = weight;
17004           vec_add1 (locators, locator);
17005         }
17006       else
17007         break;
17008     }
17009
17010   if (locator_set_name_set == 0)
17011     {
17012       errmsg ("missing locator-set name");
17013       vec_free (locators);
17014       return -99;
17015     }
17016
17017   if (vec_len (locator_set_name) > 64)
17018     {
17019       errmsg ("locator-set name too long");
17020       vec_free (locator_set_name);
17021       vec_free (locators);
17022       return -99;
17023     }
17024   vec_add1 (locator_set_name, 0);
17025
17026   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
17027
17028   /* Construct the API message */
17029   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
17030
17031   mp->is_add = is_add;
17032   clib_memcpy (mp->locator_set_name, locator_set_name,
17033                vec_len (locator_set_name));
17034   vec_free (locator_set_name);
17035
17036   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
17037   if (locators)
17038     clib_memcpy (mp->locators, locators, data_len);
17039   vec_free (locators);
17040
17041   /* send it... */
17042   S (mp);
17043
17044   /* Wait for a reply... */
17045   W (ret);
17046   return ret;
17047 }
17048
17049 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
17050
17051 static int
17052 api_one_add_del_locator (vat_main_t * vam)
17053 {
17054   unformat_input_t *input = vam->input;
17055   vl_api_one_add_del_locator_t *mp;
17056   u32 tmp_if_index = ~0;
17057   u32 sw_if_index = ~0;
17058   u8 sw_if_index_set = 0;
17059   u8 sw_if_index_if_name_set = 0;
17060   u32 priority = ~0;
17061   u8 priority_set = 0;
17062   u32 weight = ~0;
17063   u8 weight_set = 0;
17064   u8 is_add = 1;
17065   u8 *locator_set_name = NULL;
17066   u8 locator_set_name_set = 0;
17067   int ret;
17068
17069   /* Parse args required to build the message */
17070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17071     {
17072       if (unformat (input, "del"))
17073         {
17074           is_add = 0;
17075         }
17076       else if (unformat (input, "locator-set %s", &locator_set_name))
17077         {
17078           locator_set_name_set = 1;
17079         }
17080       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
17081                          &tmp_if_index))
17082         {
17083           sw_if_index_if_name_set = 1;
17084           sw_if_index = tmp_if_index;
17085         }
17086       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17087         {
17088           sw_if_index_set = 1;
17089           sw_if_index = tmp_if_index;
17090         }
17091       else if (unformat (input, "p %d", &priority))
17092         {
17093           priority_set = 1;
17094         }
17095       else if (unformat (input, "w %d", &weight))
17096         {
17097           weight_set = 1;
17098         }
17099       else
17100         break;
17101     }
17102
17103   if (locator_set_name_set == 0)
17104     {
17105       errmsg ("missing locator-set name");
17106       return -99;
17107     }
17108
17109   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17110     {
17111       errmsg ("missing sw_if_index");
17112       vec_free (locator_set_name);
17113       return -99;
17114     }
17115
17116   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17117     {
17118       errmsg ("cannot use both params interface name and sw_if_index");
17119       vec_free (locator_set_name);
17120       return -99;
17121     }
17122
17123   if (priority_set == 0)
17124     {
17125       errmsg ("missing locator-set priority");
17126       vec_free (locator_set_name);
17127       return -99;
17128     }
17129
17130   if (weight_set == 0)
17131     {
17132       errmsg ("missing locator-set weight");
17133       vec_free (locator_set_name);
17134       return -99;
17135     }
17136
17137   if (vec_len (locator_set_name) > 64)
17138     {
17139       errmsg ("locator-set name too long");
17140       vec_free (locator_set_name);
17141       return -99;
17142     }
17143   vec_add1 (locator_set_name, 0);
17144
17145   /* Construct the API message */
17146   M (ONE_ADD_DEL_LOCATOR, mp);
17147
17148   mp->is_add = is_add;
17149   mp->sw_if_index = ntohl (sw_if_index);
17150   mp->priority = priority;
17151   mp->weight = weight;
17152   clib_memcpy (mp->locator_set_name, locator_set_name,
17153                vec_len (locator_set_name));
17154   vec_free (locator_set_name);
17155
17156   /* send it... */
17157   S (mp);
17158
17159   /* Wait for a reply... */
17160   W (ret);
17161   return ret;
17162 }
17163
17164 #define api_lisp_add_del_locator api_one_add_del_locator
17165
17166 uword
17167 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17168 {
17169   u32 *key_id = va_arg (*args, u32 *);
17170   u8 *s = 0;
17171
17172   if (unformat (input, "%s", &s))
17173     {
17174       if (!strcmp ((char *) s, "sha1"))
17175         key_id[0] = HMAC_SHA_1_96;
17176       else if (!strcmp ((char *) s, "sha256"))
17177         key_id[0] = HMAC_SHA_256_128;
17178       else
17179         {
17180           clib_warning ("invalid key_id: '%s'", s);
17181           key_id[0] = HMAC_NO_KEY;
17182         }
17183     }
17184   else
17185     return 0;
17186
17187   vec_free (s);
17188   return 1;
17189 }
17190
17191 static int
17192 api_one_add_del_local_eid (vat_main_t * vam)
17193 {
17194   unformat_input_t *input = vam->input;
17195   vl_api_one_add_del_local_eid_t *mp;
17196   u8 is_add = 1;
17197   u8 eid_set = 0;
17198   lisp_eid_vat_t _eid, *eid = &_eid;
17199   u8 *locator_set_name = 0;
17200   u8 locator_set_name_set = 0;
17201   u32 vni = 0;
17202   u16 key_id = 0;
17203   u8 *key = 0;
17204   int ret;
17205
17206   /* Parse args required to build the message */
17207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17208     {
17209       if (unformat (input, "del"))
17210         {
17211           is_add = 0;
17212         }
17213       else if (unformat (input, "vni %d", &vni))
17214         {
17215           ;
17216         }
17217       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17218         {
17219           eid_set = 1;
17220         }
17221       else if (unformat (input, "locator-set %s", &locator_set_name))
17222         {
17223           locator_set_name_set = 1;
17224         }
17225       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17226         ;
17227       else if (unformat (input, "secret-key %_%v%_", &key))
17228         ;
17229       else
17230         break;
17231     }
17232
17233   if (locator_set_name_set == 0)
17234     {
17235       errmsg ("missing locator-set name");
17236       return -99;
17237     }
17238
17239   if (0 == eid_set)
17240     {
17241       errmsg ("EID address not set!");
17242       vec_free (locator_set_name);
17243       return -99;
17244     }
17245
17246   if (key && (0 == key_id))
17247     {
17248       errmsg ("invalid key_id!");
17249       return -99;
17250     }
17251
17252   if (vec_len (key) > 64)
17253     {
17254       errmsg ("key too long");
17255       vec_free (key);
17256       return -99;
17257     }
17258
17259   if (vec_len (locator_set_name) > 64)
17260     {
17261       errmsg ("locator-set name too long");
17262       vec_free (locator_set_name);
17263       return -99;
17264     }
17265   vec_add1 (locator_set_name, 0);
17266
17267   /* Construct the API message */
17268   M (ONE_ADD_DEL_LOCAL_EID, mp);
17269
17270   mp->is_add = is_add;
17271   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17272   mp->eid_type = eid->type;
17273   mp->prefix_len = eid->len;
17274   mp->vni = clib_host_to_net_u32 (vni);
17275   mp->key_id = clib_host_to_net_u16 (key_id);
17276   clib_memcpy (mp->locator_set_name, locator_set_name,
17277                vec_len (locator_set_name));
17278   clib_memcpy (mp->key, key, vec_len (key));
17279
17280   vec_free (locator_set_name);
17281   vec_free (key);
17282
17283   /* send it... */
17284   S (mp);
17285
17286   /* Wait for a reply... */
17287   W (ret);
17288   return ret;
17289 }
17290
17291 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17292
17293 static int
17294 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17295 {
17296   u32 dp_table = 0, vni = 0;;
17297   unformat_input_t *input = vam->input;
17298   vl_api_gpe_add_del_fwd_entry_t *mp;
17299   u8 is_add = 1;
17300   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17301   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17302   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17303   u32 action = ~0, w;
17304   ip4_address_t rmt_rloc4, lcl_rloc4;
17305   ip6_address_t rmt_rloc6, lcl_rloc6;
17306   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17307   int ret;
17308
17309   clib_memset (&rloc, 0, sizeof (rloc));
17310
17311   /* Parse args required to build the message */
17312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17313     {
17314       if (unformat (input, "del"))
17315         is_add = 0;
17316       else if (unformat (input, "add"))
17317         is_add = 1;
17318       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17319         {
17320           rmt_eid_set = 1;
17321         }
17322       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17323         {
17324           lcl_eid_set = 1;
17325         }
17326       else if (unformat (input, "vrf %d", &dp_table))
17327         ;
17328       else if (unformat (input, "bd %d", &dp_table))
17329         ;
17330       else if (unformat (input, "vni %d", &vni))
17331         ;
17332       else if (unformat (input, "w %d", &w))
17333         {
17334           if (!curr_rloc)
17335             {
17336               errmsg ("No RLOC configured for setting priority/weight!");
17337               return -99;
17338             }
17339           curr_rloc->weight = w;
17340         }
17341       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17342                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17343         {
17344           rloc.is_ip4 = 1;
17345
17346           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17347           rloc.weight = 0;
17348           vec_add1 (lcl_locs, rloc);
17349
17350           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17351           vec_add1 (rmt_locs, rloc);
17352           /* weight saved in rmt loc */
17353           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17354         }
17355       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17356                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17357         {
17358           rloc.is_ip4 = 0;
17359           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17360           rloc.weight = 0;
17361           vec_add1 (lcl_locs, rloc);
17362
17363           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17364           vec_add1 (rmt_locs, rloc);
17365           /* weight saved in rmt loc */
17366           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17367         }
17368       else if (unformat (input, "action %d", &action))
17369         {
17370           ;
17371         }
17372       else
17373         {
17374           clib_warning ("parse error '%U'", format_unformat_error, input);
17375           return -99;
17376         }
17377     }
17378
17379   if (!rmt_eid_set)
17380     {
17381       errmsg ("remote eid addresses not set");
17382       return -99;
17383     }
17384
17385   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17386     {
17387       errmsg ("eid types don't match");
17388       return -99;
17389     }
17390
17391   if (0 == rmt_locs && (u32) ~ 0 == action)
17392     {
17393       errmsg ("action not set for negative mapping");
17394       return -99;
17395     }
17396
17397   /* Construct the API message */
17398   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17399       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17400
17401   mp->is_add = is_add;
17402   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17403   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17404   mp->eid_type = rmt_eid->type;
17405   mp->dp_table = clib_host_to_net_u32 (dp_table);
17406   mp->vni = clib_host_to_net_u32 (vni);
17407   mp->rmt_len = rmt_eid->len;
17408   mp->lcl_len = lcl_eid->len;
17409   mp->action = action;
17410
17411   if (0 != rmt_locs && 0 != lcl_locs)
17412     {
17413       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17414       clib_memcpy (mp->locs, lcl_locs,
17415                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17416
17417       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17418       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17419                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17420     }
17421   vec_free (lcl_locs);
17422   vec_free (rmt_locs);
17423
17424   /* send it... */
17425   S (mp);
17426
17427   /* Wait for a reply... */
17428   W (ret);
17429   return ret;
17430 }
17431
17432 static int
17433 api_one_add_del_map_server (vat_main_t * vam)
17434 {
17435   unformat_input_t *input = vam->input;
17436   vl_api_one_add_del_map_server_t *mp;
17437   u8 is_add = 1;
17438   u8 ipv4_set = 0;
17439   u8 ipv6_set = 0;
17440   ip4_address_t ipv4;
17441   ip6_address_t ipv6;
17442   int ret;
17443
17444   /* Parse args required to build the message */
17445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17446     {
17447       if (unformat (input, "del"))
17448         {
17449           is_add = 0;
17450         }
17451       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17452         {
17453           ipv4_set = 1;
17454         }
17455       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17456         {
17457           ipv6_set = 1;
17458         }
17459       else
17460         break;
17461     }
17462
17463   if (ipv4_set && ipv6_set)
17464     {
17465       errmsg ("both eid v4 and v6 addresses set");
17466       return -99;
17467     }
17468
17469   if (!ipv4_set && !ipv6_set)
17470     {
17471       errmsg ("eid addresses not set");
17472       return -99;
17473     }
17474
17475   /* Construct the API message */
17476   M (ONE_ADD_DEL_MAP_SERVER, mp);
17477
17478   mp->is_add = is_add;
17479   if (ipv6_set)
17480     {
17481       mp->is_ipv6 = 1;
17482       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17483     }
17484   else
17485     {
17486       mp->is_ipv6 = 0;
17487       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17488     }
17489
17490   /* send it... */
17491   S (mp);
17492
17493   /* Wait for a reply... */
17494   W (ret);
17495   return ret;
17496 }
17497
17498 #define api_lisp_add_del_map_server api_one_add_del_map_server
17499
17500 static int
17501 api_one_add_del_map_resolver (vat_main_t * vam)
17502 {
17503   unformat_input_t *input = vam->input;
17504   vl_api_one_add_del_map_resolver_t *mp;
17505   u8 is_add = 1;
17506   u8 ipv4_set = 0;
17507   u8 ipv6_set = 0;
17508   ip4_address_t ipv4;
17509   ip6_address_t ipv6;
17510   int ret;
17511
17512   /* Parse args required to build the message */
17513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17514     {
17515       if (unformat (input, "del"))
17516         {
17517           is_add = 0;
17518         }
17519       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17520         {
17521           ipv4_set = 1;
17522         }
17523       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17524         {
17525           ipv6_set = 1;
17526         }
17527       else
17528         break;
17529     }
17530
17531   if (ipv4_set && ipv6_set)
17532     {
17533       errmsg ("both eid v4 and v6 addresses set");
17534       return -99;
17535     }
17536
17537   if (!ipv4_set && !ipv6_set)
17538     {
17539       errmsg ("eid addresses not set");
17540       return -99;
17541     }
17542
17543   /* Construct the API message */
17544   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17545
17546   mp->is_add = is_add;
17547   if (ipv6_set)
17548     {
17549       mp->is_ipv6 = 1;
17550       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17551     }
17552   else
17553     {
17554       mp->is_ipv6 = 0;
17555       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17556     }
17557
17558   /* send it... */
17559   S (mp);
17560
17561   /* Wait for a reply... */
17562   W (ret);
17563   return ret;
17564 }
17565
17566 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17567
17568 static int
17569 api_lisp_gpe_enable_disable (vat_main_t * vam)
17570 {
17571   unformat_input_t *input = vam->input;
17572   vl_api_gpe_enable_disable_t *mp;
17573   u8 is_set = 0;
17574   u8 is_en = 1;
17575   int ret;
17576
17577   /* Parse args required to build the message */
17578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17579     {
17580       if (unformat (input, "enable"))
17581         {
17582           is_set = 1;
17583           is_en = 1;
17584         }
17585       else if (unformat (input, "disable"))
17586         {
17587           is_set = 1;
17588           is_en = 0;
17589         }
17590       else
17591         break;
17592     }
17593
17594   if (is_set == 0)
17595     {
17596       errmsg ("Value not set");
17597       return -99;
17598     }
17599
17600   /* Construct the API message */
17601   M (GPE_ENABLE_DISABLE, mp);
17602
17603   mp->is_en = is_en;
17604
17605   /* send it... */
17606   S (mp);
17607
17608   /* Wait for a reply... */
17609   W (ret);
17610   return ret;
17611 }
17612
17613 static int
17614 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17615 {
17616   unformat_input_t *input = vam->input;
17617   vl_api_one_rloc_probe_enable_disable_t *mp;
17618   u8 is_set = 0;
17619   u8 is_en = 0;
17620   int ret;
17621
17622   /* Parse args required to build the message */
17623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17624     {
17625       if (unformat (input, "enable"))
17626         {
17627           is_set = 1;
17628           is_en = 1;
17629         }
17630       else if (unformat (input, "disable"))
17631         is_set = 1;
17632       else
17633         break;
17634     }
17635
17636   if (!is_set)
17637     {
17638       errmsg ("Value not set");
17639       return -99;
17640     }
17641
17642   /* Construct the API message */
17643   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17644
17645   mp->is_enabled = is_en;
17646
17647   /* send it... */
17648   S (mp);
17649
17650   /* Wait for a reply... */
17651   W (ret);
17652   return ret;
17653 }
17654
17655 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17656
17657 static int
17658 api_one_map_register_enable_disable (vat_main_t * vam)
17659 {
17660   unformat_input_t *input = vam->input;
17661   vl_api_one_map_register_enable_disable_t *mp;
17662   u8 is_set = 0;
17663   u8 is_en = 0;
17664   int ret;
17665
17666   /* Parse args required to build the message */
17667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17668     {
17669       if (unformat (input, "enable"))
17670         {
17671           is_set = 1;
17672           is_en = 1;
17673         }
17674       else if (unformat (input, "disable"))
17675         is_set = 1;
17676       else
17677         break;
17678     }
17679
17680   if (!is_set)
17681     {
17682       errmsg ("Value not set");
17683       return -99;
17684     }
17685
17686   /* Construct the API message */
17687   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17688
17689   mp->is_enabled = is_en;
17690
17691   /* send it... */
17692   S (mp);
17693
17694   /* Wait for a reply... */
17695   W (ret);
17696   return ret;
17697 }
17698
17699 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17700
17701 static int
17702 api_one_enable_disable (vat_main_t * vam)
17703 {
17704   unformat_input_t *input = vam->input;
17705   vl_api_one_enable_disable_t *mp;
17706   u8 is_set = 0;
17707   u8 is_en = 0;
17708   int ret;
17709
17710   /* Parse args required to build the message */
17711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17712     {
17713       if (unformat (input, "enable"))
17714         {
17715           is_set = 1;
17716           is_en = 1;
17717         }
17718       else if (unformat (input, "disable"))
17719         {
17720           is_set = 1;
17721         }
17722       else
17723         break;
17724     }
17725
17726   if (!is_set)
17727     {
17728       errmsg ("Value not set");
17729       return -99;
17730     }
17731
17732   /* Construct the API message */
17733   M (ONE_ENABLE_DISABLE, mp);
17734
17735   mp->is_en = is_en;
17736
17737   /* send it... */
17738   S (mp);
17739
17740   /* Wait for a reply... */
17741   W (ret);
17742   return ret;
17743 }
17744
17745 #define api_lisp_enable_disable api_one_enable_disable
17746
17747 static int
17748 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17749 {
17750   unformat_input_t *input = vam->input;
17751   vl_api_one_enable_disable_xtr_mode_t *mp;
17752   u8 is_set = 0;
17753   u8 is_en = 0;
17754   int ret;
17755
17756   /* Parse args required to build the message */
17757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17758     {
17759       if (unformat (input, "enable"))
17760         {
17761           is_set = 1;
17762           is_en = 1;
17763         }
17764       else if (unformat (input, "disable"))
17765         {
17766           is_set = 1;
17767         }
17768       else
17769         break;
17770     }
17771
17772   if (!is_set)
17773     {
17774       errmsg ("Value not set");
17775       return -99;
17776     }
17777
17778   /* Construct the API message */
17779   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17780
17781   mp->is_en = is_en;
17782
17783   /* send it... */
17784   S (mp);
17785
17786   /* Wait for a reply... */
17787   W (ret);
17788   return ret;
17789 }
17790
17791 static int
17792 api_one_show_xtr_mode (vat_main_t * vam)
17793 {
17794   vl_api_one_show_xtr_mode_t *mp;
17795   int ret;
17796
17797   /* Construct the API message */
17798   M (ONE_SHOW_XTR_MODE, mp);
17799
17800   /* send it... */
17801   S (mp);
17802
17803   /* Wait for a reply... */
17804   W (ret);
17805   return ret;
17806 }
17807
17808 static int
17809 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17810 {
17811   unformat_input_t *input = vam->input;
17812   vl_api_one_enable_disable_pitr_mode_t *mp;
17813   u8 is_set = 0;
17814   u8 is_en = 0;
17815   int ret;
17816
17817   /* Parse args required to build the message */
17818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17819     {
17820       if (unformat (input, "enable"))
17821         {
17822           is_set = 1;
17823           is_en = 1;
17824         }
17825       else if (unformat (input, "disable"))
17826         {
17827           is_set = 1;
17828         }
17829       else
17830         break;
17831     }
17832
17833   if (!is_set)
17834     {
17835       errmsg ("Value not set");
17836       return -99;
17837     }
17838
17839   /* Construct the API message */
17840   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17841
17842   mp->is_en = is_en;
17843
17844   /* send it... */
17845   S (mp);
17846
17847   /* Wait for a reply... */
17848   W (ret);
17849   return ret;
17850 }
17851
17852 static int
17853 api_one_show_pitr_mode (vat_main_t * vam)
17854 {
17855   vl_api_one_show_pitr_mode_t *mp;
17856   int ret;
17857
17858   /* Construct the API message */
17859   M (ONE_SHOW_PITR_MODE, mp);
17860
17861   /* send it... */
17862   S (mp);
17863
17864   /* Wait for a reply... */
17865   W (ret);
17866   return ret;
17867 }
17868
17869 static int
17870 api_one_enable_disable_petr_mode (vat_main_t * vam)
17871 {
17872   unformat_input_t *input = vam->input;
17873   vl_api_one_enable_disable_petr_mode_t *mp;
17874   u8 is_set = 0;
17875   u8 is_en = 0;
17876   int ret;
17877
17878   /* Parse args required to build the message */
17879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17880     {
17881       if (unformat (input, "enable"))
17882         {
17883           is_set = 1;
17884           is_en = 1;
17885         }
17886       else if (unformat (input, "disable"))
17887         {
17888           is_set = 1;
17889         }
17890       else
17891         break;
17892     }
17893
17894   if (!is_set)
17895     {
17896       errmsg ("Value not set");
17897       return -99;
17898     }
17899
17900   /* Construct the API message */
17901   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17902
17903   mp->is_en = is_en;
17904
17905   /* send it... */
17906   S (mp);
17907
17908   /* Wait for a reply... */
17909   W (ret);
17910   return ret;
17911 }
17912
17913 static int
17914 api_one_show_petr_mode (vat_main_t * vam)
17915 {
17916   vl_api_one_show_petr_mode_t *mp;
17917   int ret;
17918
17919   /* Construct the API message */
17920   M (ONE_SHOW_PETR_MODE, mp);
17921
17922   /* send it... */
17923   S (mp);
17924
17925   /* Wait for a reply... */
17926   W (ret);
17927   return ret;
17928 }
17929
17930 static int
17931 api_show_one_map_register_state (vat_main_t * vam)
17932 {
17933   vl_api_show_one_map_register_state_t *mp;
17934   int ret;
17935
17936   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17937
17938   /* send */
17939   S (mp);
17940
17941   /* wait for reply */
17942   W (ret);
17943   return ret;
17944 }
17945
17946 #define api_show_lisp_map_register_state api_show_one_map_register_state
17947
17948 static int
17949 api_show_one_rloc_probe_state (vat_main_t * vam)
17950 {
17951   vl_api_show_one_rloc_probe_state_t *mp;
17952   int ret;
17953
17954   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17955
17956   /* send */
17957   S (mp);
17958
17959   /* wait for reply */
17960   W (ret);
17961   return ret;
17962 }
17963
17964 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17965
17966 static int
17967 api_one_add_del_ndp_entry (vat_main_t * vam)
17968 {
17969   vl_api_one_add_del_ndp_entry_t *mp;
17970   unformat_input_t *input = vam->input;
17971   u8 is_add = 1;
17972   u8 mac_set = 0;
17973   u8 bd_set = 0;
17974   u8 ip_set = 0;
17975   u8 mac[6] = { 0, };
17976   u8 ip6[16] = { 0, };
17977   u32 bd = ~0;
17978   int ret;
17979
17980   /* Parse args required to build the message */
17981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17982     {
17983       if (unformat (input, "del"))
17984         is_add = 0;
17985       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17986         mac_set = 1;
17987       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17988         ip_set = 1;
17989       else if (unformat (input, "bd %d", &bd))
17990         bd_set = 1;
17991       else
17992         {
17993           errmsg ("parse error '%U'", format_unformat_error, input);
17994           return -99;
17995         }
17996     }
17997
17998   if (!bd_set || !ip_set || (!mac_set && is_add))
17999     {
18000       errmsg ("Missing BD, IP or MAC!");
18001       return -99;
18002     }
18003
18004   M (ONE_ADD_DEL_NDP_ENTRY, mp);
18005   mp->is_add = is_add;
18006   clib_memcpy (mp->mac, mac, 6);
18007   mp->bd = clib_host_to_net_u32 (bd);
18008   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
18009
18010   /* send */
18011   S (mp);
18012
18013   /* wait for reply */
18014   W (ret);
18015   return ret;
18016 }
18017
18018 static int
18019 api_one_add_del_l2_arp_entry (vat_main_t * vam)
18020 {
18021   vl_api_one_add_del_l2_arp_entry_t *mp;
18022   unformat_input_t *input = vam->input;
18023   u8 is_add = 1;
18024   u8 mac_set = 0;
18025   u8 bd_set = 0;
18026   u8 ip_set = 0;
18027   u8 mac[6] = { 0, };
18028   u32 ip4 = 0, bd = ~0;
18029   int ret;
18030
18031   /* Parse args required to build the message */
18032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18033     {
18034       if (unformat (input, "del"))
18035         is_add = 0;
18036       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18037         mac_set = 1;
18038       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
18039         ip_set = 1;
18040       else if (unformat (input, "bd %d", &bd))
18041         bd_set = 1;
18042       else
18043         {
18044           errmsg ("parse error '%U'", format_unformat_error, input);
18045           return -99;
18046         }
18047     }
18048
18049   if (!bd_set || !ip_set || (!mac_set && is_add))
18050     {
18051       errmsg ("Missing BD, IP or MAC!");
18052       return -99;
18053     }
18054
18055   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
18056   mp->is_add = is_add;
18057   clib_memcpy (mp->mac, mac, 6);
18058   mp->bd = clib_host_to_net_u32 (bd);
18059   mp->ip4 = ip4;
18060
18061   /* send */
18062   S (mp);
18063
18064   /* wait for reply */
18065   W (ret);
18066   return ret;
18067 }
18068
18069 static int
18070 api_one_ndp_bd_get (vat_main_t * vam)
18071 {
18072   vl_api_one_ndp_bd_get_t *mp;
18073   int ret;
18074
18075   M (ONE_NDP_BD_GET, mp);
18076
18077   /* send */
18078   S (mp);
18079
18080   /* wait for reply */
18081   W (ret);
18082   return ret;
18083 }
18084
18085 static int
18086 api_one_ndp_entries_get (vat_main_t * vam)
18087 {
18088   vl_api_one_ndp_entries_get_t *mp;
18089   unformat_input_t *input = vam->input;
18090   u8 bd_set = 0;
18091   u32 bd = ~0;
18092   int ret;
18093
18094   /* Parse args required to build the message */
18095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18096     {
18097       if (unformat (input, "bd %d", &bd))
18098         bd_set = 1;
18099       else
18100         {
18101           errmsg ("parse error '%U'", format_unformat_error, input);
18102           return -99;
18103         }
18104     }
18105
18106   if (!bd_set)
18107     {
18108       errmsg ("Expected bridge domain!");
18109       return -99;
18110     }
18111
18112   M (ONE_NDP_ENTRIES_GET, mp);
18113   mp->bd = clib_host_to_net_u32 (bd);
18114
18115   /* send */
18116   S (mp);
18117
18118   /* wait for reply */
18119   W (ret);
18120   return ret;
18121 }
18122
18123 static int
18124 api_one_l2_arp_bd_get (vat_main_t * vam)
18125 {
18126   vl_api_one_l2_arp_bd_get_t *mp;
18127   int ret;
18128
18129   M (ONE_L2_ARP_BD_GET, mp);
18130
18131   /* send */
18132   S (mp);
18133
18134   /* wait for reply */
18135   W (ret);
18136   return ret;
18137 }
18138
18139 static int
18140 api_one_l2_arp_entries_get (vat_main_t * vam)
18141 {
18142   vl_api_one_l2_arp_entries_get_t *mp;
18143   unformat_input_t *input = vam->input;
18144   u8 bd_set = 0;
18145   u32 bd = ~0;
18146   int ret;
18147
18148   /* Parse args required to build the message */
18149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18150     {
18151       if (unformat (input, "bd %d", &bd))
18152         bd_set = 1;
18153       else
18154         {
18155           errmsg ("parse error '%U'", format_unformat_error, input);
18156           return -99;
18157         }
18158     }
18159
18160   if (!bd_set)
18161     {
18162       errmsg ("Expected bridge domain!");
18163       return -99;
18164     }
18165
18166   M (ONE_L2_ARP_ENTRIES_GET, mp);
18167   mp->bd = clib_host_to_net_u32 (bd);
18168
18169   /* send */
18170   S (mp);
18171
18172   /* wait for reply */
18173   W (ret);
18174   return ret;
18175 }
18176
18177 static int
18178 api_one_stats_enable_disable (vat_main_t * vam)
18179 {
18180   vl_api_one_stats_enable_disable_t *mp;
18181   unformat_input_t *input = vam->input;
18182   u8 is_set = 0;
18183   u8 is_en = 0;
18184   int ret;
18185
18186   /* Parse args required to build the message */
18187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18188     {
18189       if (unformat (input, "enable"))
18190         {
18191           is_set = 1;
18192           is_en = 1;
18193         }
18194       else if (unformat (input, "disable"))
18195         {
18196           is_set = 1;
18197         }
18198       else
18199         break;
18200     }
18201
18202   if (!is_set)
18203     {
18204       errmsg ("Value not set");
18205       return -99;
18206     }
18207
18208   M (ONE_STATS_ENABLE_DISABLE, mp);
18209   mp->is_en = is_en;
18210
18211   /* send */
18212   S (mp);
18213
18214   /* wait for reply */
18215   W (ret);
18216   return ret;
18217 }
18218
18219 static int
18220 api_show_one_stats_enable_disable (vat_main_t * vam)
18221 {
18222   vl_api_show_one_stats_enable_disable_t *mp;
18223   int ret;
18224
18225   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18226
18227   /* send */
18228   S (mp);
18229
18230   /* wait for reply */
18231   W (ret);
18232   return ret;
18233 }
18234
18235 static int
18236 api_show_one_map_request_mode (vat_main_t * vam)
18237 {
18238   vl_api_show_one_map_request_mode_t *mp;
18239   int ret;
18240
18241   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18242
18243   /* send */
18244   S (mp);
18245
18246   /* wait for reply */
18247   W (ret);
18248   return ret;
18249 }
18250
18251 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18252
18253 static int
18254 api_one_map_request_mode (vat_main_t * vam)
18255 {
18256   unformat_input_t *input = vam->input;
18257   vl_api_one_map_request_mode_t *mp;
18258   u8 mode = 0;
18259   int ret;
18260
18261   /* Parse args required to build the message */
18262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18263     {
18264       if (unformat (input, "dst-only"))
18265         mode = 0;
18266       else if (unformat (input, "src-dst"))
18267         mode = 1;
18268       else
18269         {
18270           errmsg ("parse error '%U'", format_unformat_error, input);
18271           return -99;
18272         }
18273     }
18274
18275   M (ONE_MAP_REQUEST_MODE, mp);
18276
18277   mp->mode = mode;
18278
18279   /* send */
18280   S (mp);
18281
18282   /* wait for reply */
18283   W (ret);
18284   return ret;
18285 }
18286
18287 #define api_lisp_map_request_mode api_one_map_request_mode
18288
18289 /**
18290  * Enable/disable ONE proxy ITR.
18291  *
18292  * @param vam vpp API test context
18293  * @return return code
18294  */
18295 static int
18296 api_one_pitr_set_locator_set (vat_main_t * vam)
18297 {
18298   u8 ls_name_set = 0;
18299   unformat_input_t *input = vam->input;
18300   vl_api_one_pitr_set_locator_set_t *mp;
18301   u8 is_add = 1;
18302   u8 *ls_name = 0;
18303   int ret;
18304
18305   /* Parse args required to build the message */
18306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18307     {
18308       if (unformat (input, "del"))
18309         is_add = 0;
18310       else if (unformat (input, "locator-set %s", &ls_name))
18311         ls_name_set = 1;
18312       else
18313         {
18314           errmsg ("parse error '%U'", format_unformat_error, input);
18315           return -99;
18316         }
18317     }
18318
18319   if (!ls_name_set)
18320     {
18321       errmsg ("locator-set name not set!");
18322       return -99;
18323     }
18324
18325   M (ONE_PITR_SET_LOCATOR_SET, mp);
18326
18327   mp->is_add = is_add;
18328   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18329   vec_free (ls_name);
18330
18331   /* send */
18332   S (mp);
18333
18334   /* wait for reply */
18335   W (ret);
18336   return ret;
18337 }
18338
18339 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18340
18341 static int
18342 api_one_nsh_set_locator_set (vat_main_t * vam)
18343 {
18344   u8 ls_name_set = 0;
18345   unformat_input_t *input = vam->input;
18346   vl_api_one_nsh_set_locator_set_t *mp;
18347   u8 is_add = 1;
18348   u8 *ls_name = 0;
18349   int ret;
18350
18351   /* Parse args required to build the message */
18352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18353     {
18354       if (unformat (input, "del"))
18355         is_add = 0;
18356       else if (unformat (input, "ls %s", &ls_name))
18357         ls_name_set = 1;
18358       else
18359         {
18360           errmsg ("parse error '%U'", format_unformat_error, input);
18361           return -99;
18362         }
18363     }
18364
18365   if (!ls_name_set && is_add)
18366     {
18367       errmsg ("locator-set name not set!");
18368       return -99;
18369     }
18370
18371   M (ONE_NSH_SET_LOCATOR_SET, mp);
18372
18373   mp->is_add = is_add;
18374   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18375   vec_free (ls_name);
18376
18377   /* send */
18378   S (mp);
18379
18380   /* wait for reply */
18381   W (ret);
18382   return ret;
18383 }
18384
18385 static int
18386 api_show_one_pitr (vat_main_t * vam)
18387 {
18388   vl_api_show_one_pitr_t *mp;
18389   int ret;
18390
18391   if (!vam->json_output)
18392     {
18393       print (vam->ofp, "%=20s", "lisp status:");
18394     }
18395
18396   M (SHOW_ONE_PITR, mp);
18397   /* send it... */
18398   S (mp);
18399
18400   /* Wait for a reply... */
18401   W (ret);
18402   return ret;
18403 }
18404
18405 #define api_show_lisp_pitr api_show_one_pitr
18406
18407 static int
18408 api_one_use_petr (vat_main_t * vam)
18409 {
18410   unformat_input_t *input = vam->input;
18411   vl_api_one_use_petr_t *mp;
18412   u8 is_add = 0;
18413   ip_address_t ip;
18414   int ret;
18415
18416   clib_memset (&ip, 0, sizeof (ip));
18417
18418   /* Parse args required to build the message */
18419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18420     {
18421       if (unformat (input, "disable"))
18422         is_add = 0;
18423       else
18424         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18425         {
18426           is_add = 1;
18427           ip_addr_version (&ip) = IP4;
18428         }
18429       else
18430         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18431         {
18432           is_add = 1;
18433           ip_addr_version (&ip) = IP6;
18434         }
18435       else
18436         {
18437           errmsg ("parse error '%U'", format_unformat_error, input);
18438           return -99;
18439         }
18440     }
18441
18442   M (ONE_USE_PETR, mp);
18443
18444   mp->is_add = is_add;
18445   if (is_add)
18446     {
18447       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18448       if (mp->is_ip4)
18449         clib_memcpy (mp->address, &ip, 4);
18450       else
18451         clib_memcpy (mp->address, &ip, 16);
18452     }
18453
18454   /* send */
18455   S (mp);
18456
18457   /* wait for reply */
18458   W (ret);
18459   return ret;
18460 }
18461
18462 #define api_lisp_use_petr api_one_use_petr
18463
18464 static int
18465 api_show_one_nsh_mapping (vat_main_t * vam)
18466 {
18467   vl_api_show_one_use_petr_t *mp;
18468   int ret;
18469
18470   if (!vam->json_output)
18471     {
18472       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18473     }
18474
18475   M (SHOW_ONE_NSH_MAPPING, mp);
18476   /* send it... */
18477   S (mp);
18478
18479   /* Wait for a reply... */
18480   W (ret);
18481   return ret;
18482 }
18483
18484 static int
18485 api_show_one_use_petr (vat_main_t * vam)
18486 {
18487   vl_api_show_one_use_petr_t *mp;
18488   int ret;
18489
18490   if (!vam->json_output)
18491     {
18492       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18493     }
18494
18495   M (SHOW_ONE_USE_PETR, mp);
18496   /* send it... */
18497   S (mp);
18498
18499   /* Wait for a reply... */
18500   W (ret);
18501   return ret;
18502 }
18503
18504 #define api_show_lisp_use_petr api_show_one_use_petr
18505
18506 /**
18507  * Add/delete mapping between vni and vrf
18508  */
18509 static int
18510 api_one_eid_table_add_del_map (vat_main_t * vam)
18511 {
18512   unformat_input_t *input = vam->input;
18513   vl_api_one_eid_table_add_del_map_t *mp;
18514   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18515   u32 vni, vrf, bd_index;
18516   int ret;
18517
18518   /* Parse args required to build the message */
18519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18520     {
18521       if (unformat (input, "del"))
18522         is_add = 0;
18523       else if (unformat (input, "vrf %d", &vrf))
18524         vrf_set = 1;
18525       else if (unformat (input, "bd_index %d", &bd_index))
18526         bd_index_set = 1;
18527       else if (unformat (input, "vni %d", &vni))
18528         vni_set = 1;
18529       else
18530         break;
18531     }
18532
18533   if (!vni_set || (!vrf_set && !bd_index_set))
18534     {
18535       errmsg ("missing arguments!");
18536       return -99;
18537     }
18538
18539   if (vrf_set && bd_index_set)
18540     {
18541       errmsg ("error: both vrf and bd entered!");
18542       return -99;
18543     }
18544
18545   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18546
18547   mp->is_add = is_add;
18548   mp->vni = htonl (vni);
18549   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18550   mp->is_l2 = bd_index_set;
18551
18552   /* send */
18553   S (mp);
18554
18555   /* wait for reply */
18556   W (ret);
18557   return ret;
18558 }
18559
18560 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18561
18562 uword
18563 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18564 {
18565   u32 *action = va_arg (*args, u32 *);
18566   u8 *s = 0;
18567
18568   if (unformat (input, "%s", &s))
18569     {
18570       if (!strcmp ((char *) s, "no-action"))
18571         action[0] = 0;
18572       else if (!strcmp ((char *) s, "natively-forward"))
18573         action[0] = 1;
18574       else if (!strcmp ((char *) s, "send-map-request"))
18575         action[0] = 2;
18576       else if (!strcmp ((char *) s, "drop"))
18577         action[0] = 3;
18578       else
18579         {
18580           clib_warning ("invalid action: '%s'", s);
18581           action[0] = 3;
18582         }
18583     }
18584   else
18585     return 0;
18586
18587   vec_free (s);
18588   return 1;
18589 }
18590
18591 /**
18592  * Add/del remote mapping to/from ONE control plane
18593  *
18594  * @param vam vpp API test context
18595  * @return return code
18596  */
18597 static int
18598 api_one_add_del_remote_mapping (vat_main_t * vam)
18599 {
18600   unformat_input_t *input = vam->input;
18601   vl_api_one_add_del_remote_mapping_t *mp;
18602   u32 vni = 0;
18603   lisp_eid_vat_t _eid, *eid = &_eid;
18604   lisp_eid_vat_t _seid, *seid = &_seid;
18605   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18606   u32 action = ~0, p, w, data_len;
18607   ip4_address_t rloc4;
18608   ip6_address_t rloc6;
18609   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18610   int ret;
18611
18612   clib_memset (&rloc, 0, sizeof (rloc));
18613
18614   /* Parse args required to build the message */
18615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18616     {
18617       if (unformat (input, "del-all"))
18618         {
18619           del_all = 1;
18620         }
18621       else if (unformat (input, "del"))
18622         {
18623           is_add = 0;
18624         }
18625       else if (unformat (input, "add"))
18626         {
18627           is_add = 1;
18628         }
18629       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18630         {
18631           eid_set = 1;
18632         }
18633       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18634         {
18635           seid_set = 1;
18636         }
18637       else if (unformat (input, "vni %d", &vni))
18638         {
18639           ;
18640         }
18641       else if (unformat (input, "p %d w %d", &p, &w))
18642         {
18643           if (!curr_rloc)
18644             {
18645               errmsg ("No RLOC configured for setting priority/weight!");
18646               return -99;
18647             }
18648           curr_rloc->priority = p;
18649           curr_rloc->weight = w;
18650         }
18651       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18652         {
18653           rloc.is_ip4 = 1;
18654           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18655           vec_add1 (rlocs, rloc);
18656           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18657         }
18658       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18659         {
18660           rloc.is_ip4 = 0;
18661           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18662           vec_add1 (rlocs, rloc);
18663           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18664         }
18665       else if (unformat (input, "action %U",
18666                          unformat_negative_mapping_action, &action))
18667         {
18668           ;
18669         }
18670       else
18671         {
18672           clib_warning ("parse error '%U'", format_unformat_error, input);
18673           return -99;
18674         }
18675     }
18676
18677   if (0 == eid_set)
18678     {
18679       errmsg ("missing params!");
18680       return -99;
18681     }
18682
18683   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18684     {
18685       errmsg ("no action set for negative map-reply!");
18686       return -99;
18687     }
18688
18689   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18690
18691   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18692   mp->is_add = is_add;
18693   mp->vni = htonl (vni);
18694   mp->action = (u8) action;
18695   mp->is_src_dst = seid_set;
18696   mp->eid_len = eid->len;
18697   mp->seid_len = seid->len;
18698   mp->del_all = del_all;
18699   mp->eid_type = eid->type;
18700   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18701   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18702
18703   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18704   clib_memcpy (mp->rlocs, rlocs, data_len);
18705   vec_free (rlocs);
18706
18707   /* send it... */
18708   S (mp);
18709
18710   /* Wait for a reply... */
18711   W (ret);
18712   return ret;
18713 }
18714
18715 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18716
18717 /**
18718  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18719  * forwarding entries in data-plane accordingly.
18720  *
18721  * @param vam vpp API test context
18722  * @return return code
18723  */
18724 static int
18725 api_one_add_del_adjacency (vat_main_t * vam)
18726 {
18727   unformat_input_t *input = vam->input;
18728   vl_api_one_add_del_adjacency_t *mp;
18729   u32 vni = 0;
18730   ip4_address_t leid4, reid4;
18731   ip6_address_t leid6, reid6;
18732   u8 reid_mac[6] = { 0 };
18733   u8 leid_mac[6] = { 0 };
18734   u8 reid_type, leid_type;
18735   u32 leid_len = 0, reid_len = 0, len;
18736   u8 is_add = 1;
18737   int ret;
18738
18739   leid_type = reid_type = (u8) ~ 0;
18740
18741   /* Parse args required to build the message */
18742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18743     {
18744       if (unformat (input, "del"))
18745         {
18746           is_add = 0;
18747         }
18748       else if (unformat (input, "add"))
18749         {
18750           is_add = 1;
18751         }
18752       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18753                          &reid4, &len))
18754         {
18755           reid_type = 0;        /* ipv4 */
18756           reid_len = len;
18757         }
18758       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18759                          &reid6, &len))
18760         {
18761           reid_type = 1;        /* ipv6 */
18762           reid_len = len;
18763         }
18764       else if (unformat (input, "reid %U", unformat_ethernet_address,
18765                          reid_mac))
18766         {
18767           reid_type = 2;        /* mac */
18768         }
18769       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18770                          &leid4, &len))
18771         {
18772           leid_type = 0;        /* ipv4 */
18773           leid_len = len;
18774         }
18775       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18776                          &leid6, &len))
18777         {
18778           leid_type = 1;        /* ipv6 */
18779           leid_len = len;
18780         }
18781       else if (unformat (input, "leid %U", unformat_ethernet_address,
18782                          leid_mac))
18783         {
18784           leid_type = 2;        /* mac */
18785         }
18786       else if (unformat (input, "vni %d", &vni))
18787         {
18788           ;
18789         }
18790       else
18791         {
18792           errmsg ("parse error '%U'", format_unformat_error, input);
18793           return -99;
18794         }
18795     }
18796
18797   if ((u8) ~ 0 == reid_type)
18798     {
18799       errmsg ("missing params!");
18800       return -99;
18801     }
18802
18803   if (leid_type != reid_type)
18804     {
18805       errmsg ("remote and local EIDs are of different types!");
18806       return -99;
18807     }
18808
18809   M (ONE_ADD_DEL_ADJACENCY, mp);
18810   mp->is_add = is_add;
18811   mp->vni = htonl (vni);
18812   mp->leid_len = leid_len;
18813   mp->reid_len = reid_len;
18814   mp->eid_type = reid_type;
18815
18816   switch (mp->eid_type)
18817     {
18818     case 0:
18819       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18820       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18821       break;
18822     case 1:
18823       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18824       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18825       break;
18826     case 2:
18827       clib_memcpy (mp->leid, leid_mac, 6);
18828       clib_memcpy (mp->reid, reid_mac, 6);
18829       break;
18830     default:
18831       errmsg ("unknown EID type %d!", mp->eid_type);
18832       return 0;
18833     }
18834
18835   /* send it... */
18836   S (mp);
18837
18838   /* Wait for a reply... */
18839   W (ret);
18840   return ret;
18841 }
18842
18843 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18844
18845 uword
18846 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18847 {
18848   u32 *mode = va_arg (*args, u32 *);
18849
18850   if (unformat (input, "lisp"))
18851     *mode = 0;
18852   else if (unformat (input, "vxlan"))
18853     *mode = 1;
18854   else
18855     return 0;
18856
18857   return 1;
18858 }
18859
18860 static int
18861 api_gpe_get_encap_mode (vat_main_t * vam)
18862 {
18863   vl_api_gpe_get_encap_mode_t *mp;
18864   int ret;
18865
18866   /* Construct the API message */
18867   M (GPE_GET_ENCAP_MODE, mp);
18868
18869   /* send it... */
18870   S (mp);
18871
18872   /* Wait for a reply... */
18873   W (ret);
18874   return ret;
18875 }
18876
18877 static int
18878 api_gpe_set_encap_mode (vat_main_t * vam)
18879 {
18880   unformat_input_t *input = vam->input;
18881   vl_api_gpe_set_encap_mode_t *mp;
18882   int ret;
18883   u32 mode = 0;
18884
18885   /* Parse args required to build the message */
18886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18887     {
18888       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18889         ;
18890       else
18891         break;
18892     }
18893
18894   /* Construct the API message */
18895   M (GPE_SET_ENCAP_MODE, mp);
18896
18897   mp->mode = mode;
18898
18899   /* send it... */
18900   S (mp);
18901
18902   /* Wait for a reply... */
18903   W (ret);
18904   return ret;
18905 }
18906
18907 static int
18908 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18909 {
18910   unformat_input_t *input = vam->input;
18911   vl_api_gpe_add_del_iface_t *mp;
18912   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18913   u32 dp_table = 0, vni = 0;
18914   int ret;
18915
18916   /* Parse args required to build the message */
18917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18918     {
18919       if (unformat (input, "up"))
18920         {
18921           action_set = 1;
18922           is_add = 1;
18923         }
18924       else if (unformat (input, "down"))
18925         {
18926           action_set = 1;
18927           is_add = 0;
18928         }
18929       else if (unformat (input, "table_id %d", &dp_table))
18930         {
18931           dp_table_set = 1;
18932         }
18933       else if (unformat (input, "bd_id %d", &dp_table))
18934         {
18935           dp_table_set = 1;
18936           is_l2 = 1;
18937         }
18938       else if (unformat (input, "vni %d", &vni))
18939         {
18940           vni_set = 1;
18941         }
18942       else
18943         break;
18944     }
18945
18946   if (action_set == 0)
18947     {
18948       errmsg ("Action not set");
18949       return -99;
18950     }
18951   if (dp_table_set == 0 || vni_set == 0)
18952     {
18953       errmsg ("vni and dp_table must be set");
18954       return -99;
18955     }
18956
18957   /* Construct the API message */
18958   M (GPE_ADD_DEL_IFACE, mp);
18959
18960   mp->is_add = is_add;
18961   mp->dp_table = clib_host_to_net_u32 (dp_table);
18962   mp->is_l2 = is_l2;
18963   mp->vni = clib_host_to_net_u32 (vni);
18964
18965   /* send it... */
18966   S (mp);
18967
18968   /* Wait for a reply... */
18969   W (ret);
18970   return ret;
18971 }
18972
18973 static int
18974 api_one_map_register_fallback_threshold (vat_main_t * vam)
18975 {
18976   unformat_input_t *input = vam->input;
18977   vl_api_one_map_register_fallback_threshold_t *mp;
18978   u32 value = 0;
18979   u8 is_set = 0;
18980   int ret;
18981
18982   /* Parse args required to build the message */
18983   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18984     {
18985       if (unformat (input, "%u", &value))
18986         is_set = 1;
18987       else
18988         {
18989           clib_warning ("parse error '%U'", format_unformat_error, input);
18990           return -99;
18991         }
18992     }
18993
18994   if (!is_set)
18995     {
18996       errmsg ("fallback threshold value is missing!");
18997       return -99;
18998     }
18999
19000   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19001   mp->value = clib_host_to_net_u32 (value);
19002
19003   /* send it... */
19004   S (mp);
19005
19006   /* Wait for a reply... */
19007   W (ret);
19008   return ret;
19009 }
19010
19011 static int
19012 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
19013 {
19014   vl_api_show_one_map_register_fallback_threshold_t *mp;
19015   int ret;
19016
19017   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19018
19019   /* send it... */
19020   S (mp);
19021
19022   /* Wait for a reply... */
19023   W (ret);
19024   return ret;
19025 }
19026
19027 uword
19028 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
19029 {
19030   u32 *proto = va_arg (*args, u32 *);
19031
19032   if (unformat (input, "udp"))
19033     *proto = 1;
19034   else if (unformat (input, "api"))
19035     *proto = 2;
19036   else
19037     return 0;
19038
19039   return 1;
19040 }
19041
19042 static int
19043 api_one_set_transport_protocol (vat_main_t * vam)
19044 {
19045   unformat_input_t *input = vam->input;
19046   vl_api_one_set_transport_protocol_t *mp;
19047   u8 is_set = 0;
19048   u32 protocol = 0;
19049   int ret;
19050
19051   /* Parse args required to build the message */
19052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19053     {
19054       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
19055         is_set = 1;
19056       else
19057         {
19058           clib_warning ("parse error '%U'", format_unformat_error, input);
19059           return -99;
19060         }
19061     }
19062
19063   if (!is_set)
19064     {
19065       errmsg ("Transport protocol missing!");
19066       return -99;
19067     }
19068
19069   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
19070   mp->protocol = (u8) protocol;
19071
19072   /* send it... */
19073   S (mp);
19074
19075   /* Wait for a reply... */
19076   W (ret);
19077   return ret;
19078 }
19079
19080 static int
19081 api_one_get_transport_protocol (vat_main_t * vam)
19082 {
19083   vl_api_one_get_transport_protocol_t *mp;
19084   int ret;
19085
19086   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19087
19088   /* send it... */
19089   S (mp);
19090
19091   /* Wait for a reply... */
19092   W (ret);
19093   return ret;
19094 }
19095
19096 static int
19097 api_one_map_register_set_ttl (vat_main_t * vam)
19098 {
19099   unformat_input_t *input = vam->input;
19100   vl_api_one_map_register_set_ttl_t *mp;
19101   u32 ttl = 0;
19102   u8 is_set = 0;
19103   int ret;
19104
19105   /* Parse args required to build the message */
19106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19107     {
19108       if (unformat (input, "%u", &ttl))
19109         is_set = 1;
19110       else
19111         {
19112           clib_warning ("parse error '%U'", format_unformat_error, input);
19113           return -99;
19114         }
19115     }
19116
19117   if (!is_set)
19118     {
19119       errmsg ("TTL value missing!");
19120       return -99;
19121     }
19122
19123   M (ONE_MAP_REGISTER_SET_TTL, mp);
19124   mp->ttl = clib_host_to_net_u32 (ttl);
19125
19126   /* send it... */
19127   S (mp);
19128
19129   /* Wait for a reply... */
19130   W (ret);
19131   return ret;
19132 }
19133
19134 static int
19135 api_show_one_map_register_ttl (vat_main_t * vam)
19136 {
19137   vl_api_show_one_map_register_ttl_t *mp;
19138   int ret;
19139
19140   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19141
19142   /* send it... */
19143   S (mp);
19144
19145   /* Wait for a reply... */
19146   W (ret);
19147   return ret;
19148 }
19149
19150 /**
19151  * Add/del map request itr rlocs from ONE control plane and updates
19152  *
19153  * @param vam vpp API test context
19154  * @return return code
19155  */
19156 static int
19157 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19158 {
19159   unformat_input_t *input = vam->input;
19160   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19161   u8 *locator_set_name = 0;
19162   u8 locator_set_name_set = 0;
19163   u8 is_add = 1;
19164   int ret;
19165
19166   /* Parse args required to build the message */
19167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19168     {
19169       if (unformat (input, "del"))
19170         {
19171           is_add = 0;
19172         }
19173       else if (unformat (input, "%_%v%_", &locator_set_name))
19174         {
19175           locator_set_name_set = 1;
19176         }
19177       else
19178         {
19179           clib_warning ("parse error '%U'", format_unformat_error, input);
19180           return -99;
19181         }
19182     }
19183
19184   if (is_add && !locator_set_name_set)
19185     {
19186       errmsg ("itr-rloc is not set!");
19187       return -99;
19188     }
19189
19190   if (is_add && vec_len (locator_set_name) > 64)
19191     {
19192       errmsg ("itr-rloc locator-set name too long");
19193       vec_free (locator_set_name);
19194       return -99;
19195     }
19196
19197   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19198   mp->is_add = is_add;
19199   if (is_add)
19200     {
19201       clib_memcpy (mp->locator_set_name, locator_set_name,
19202                    vec_len (locator_set_name));
19203     }
19204   else
19205     {
19206       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19207     }
19208   vec_free (locator_set_name);
19209
19210   /* send it... */
19211   S (mp);
19212
19213   /* Wait for a reply... */
19214   W (ret);
19215   return ret;
19216 }
19217
19218 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19219
19220 static int
19221 api_one_locator_dump (vat_main_t * vam)
19222 {
19223   unformat_input_t *input = vam->input;
19224   vl_api_one_locator_dump_t *mp;
19225   vl_api_control_ping_t *mp_ping;
19226   u8 is_index_set = 0, is_name_set = 0;
19227   u8 *ls_name = 0;
19228   u32 ls_index = ~0;
19229   int ret;
19230
19231   /* Parse args required to build the message */
19232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19233     {
19234       if (unformat (input, "ls_name %_%v%_", &ls_name))
19235         {
19236           is_name_set = 1;
19237         }
19238       else if (unformat (input, "ls_index %d", &ls_index))
19239         {
19240           is_index_set = 1;
19241         }
19242       else
19243         {
19244           errmsg ("parse error '%U'", format_unformat_error, input);
19245           return -99;
19246         }
19247     }
19248
19249   if (!is_index_set && !is_name_set)
19250     {
19251       errmsg ("error: expected one of index or name!");
19252       return -99;
19253     }
19254
19255   if (is_index_set && is_name_set)
19256     {
19257       errmsg ("error: only one param expected!");
19258       return -99;
19259     }
19260
19261   if (vec_len (ls_name) > 62)
19262     {
19263       errmsg ("error: locator set name too long!");
19264       return -99;
19265     }
19266
19267   if (!vam->json_output)
19268     {
19269       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19270     }
19271
19272   M (ONE_LOCATOR_DUMP, mp);
19273   mp->is_index_set = is_index_set;
19274
19275   if (is_index_set)
19276     mp->ls_index = clib_host_to_net_u32 (ls_index);
19277   else
19278     {
19279       vec_add1 (ls_name, 0);
19280       strncpy ((char *) mp->ls_name, (char *) ls_name,
19281                sizeof (mp->ls_name) - 1);
19282     }
19283
19284   /* send it... */
19285   S (mp);
19286
19287   /* Use a control ping for synchronization */
19288   MPING (CONTROL_PING, mp_ping);
19289   S (mp_ping);
19290
19291   /* Wait for a reply... */
19292   W (ret);
19293   return ret;
19294 }
19295
19296 #define api_lisp_locator_dump api_one_locator_dump
19297
19298 static int
19299 api_one_locator_set_dump (vat_main_t * vam)
19300 {
19301   vl_api_one_locator_set_dump_t *mp;
19302   vl_api_control_ping_t *mp_ping;
19303   unformat_input_t *input = vam->input;
19304   u8 filter = 0;
19305   int ret;
19306
19307   /* Parse args required to build the message */
19308   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19309     {
19310       if (unformat (input, "local"))
19311         {
19312           filter = 1;
19313         }
19314       else if (unformat (input, "remote"))
19315         {
19316           filter = 2;
19317         }
19318       else
19319         {
19320           errmsg ("parse error '%U'", format_unformat_error, input);
19321           return -99;
19322         }
19323     }
19324
19325   if (!vam->json_output)
19326     {
19327       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19328     }
19329
19330   M (ONE_LOCATOR_SET_DUMP, mp);
19331
19332   mp->filter = filter;
19333
19334   /* send it... */
19335   S (mp);
19336
19337   /* Use a control ping for synchronization */
19338   MPING (CONTROL_PING, mp_ping);
19339   S (mp_ping);
19340
19341   /* Wait for a reply... */
19342   W (ret);
19343   return ret;
19344 }
19345
19346 #define api_lisp_locator_set_dump api_one_locator_set_dump
19347
19348 static int
19349 api_one_eid_table_map_dump (vat_main_t * vam)
19350 {
19351   u8 is_l2 = 0;
19352   u8 mode_set = 0;
19353   unformat_input_t *input = vam->input;
19354   vl_api_one_eid_table_map_dump_t *mp;
19355   vl_api_control_ping_t *mp_ping;
19356   int ret;
19357
19358   /* Parse args required to build the message */
19359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19360     {
19361       if (unformat (input, "l2"))
19362         {
19363           is_l2 = 1;
19364           mode_set = 1;
19365         }
19366       else if (unformat (input, "l3"))
19367         {
19368           is_l2 = 0;
19369           mode_set = 1;
19370         }
19371       else
19372         {
19373           errmsg ("parse error '%U'", format_unformat_error, input);
19374           return -99;
19375         }
19376     }
19377
19378   if (!mode_set)
19379     {
19380       errmsg ("expected one of 'l2' or 'l3' parameter!");
19381       return -99;
19382     }
19383
19384   if (!vam->json_output)
19385     {
19386       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19387     }
19388
19389   M (ONE_EID_TABLE_MAP_DUMP, mp);
19390   mp->is_l2 = is_l2;
19391
19392   /* send it... */
19393   S (mp);
19394
19395   /* Use a control ping for synchronization */
19396   MPING (CONTROL_PING, mp_ping);
19397   S (mp_ping);
19398
19399   /* Wait for a reply... */
19400   W (ret);
19401   return ret;
19402 }
19403
19404 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19405
19406 static int
19407 api_one_eid_table_vni_dump (vat_main_t * vam)
19408 {
19409   vl_api_one_eid_table_vni_dump_t *mp;
19410   vl_api_control_ping_t *mp_ping;
19411   int ret;
19412
19413   if (!vam->json_output)
19414     {
19415       print (vam->ofp, "VNI");
19416     }
19417
19418   M (ONE_EID_TABLE_VNI_DUMP, mp);
19419
19420   /* send it... */
19421   S (mp);
19422
19423   /* Use a control ping for synchronization */
19424   MPING (CONTROL_PING, mp_ping);
19425   S (mp_ping);
19426
19427   /* Wait for a reply... */
19428   W (ret);
19429   return ret;
19430 }
19431
19432 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19433
19434 static int
19435 api_one_eid_table_dump (vat_main_t * vam)
19436 {
19437   unformat_input_t *i = vam->input;
19438   vl_api_one_eid_table_dump_t *mp;
19439   vl_api_control_ping_t *mp_ping;
19440   struct in_addr ip4;
19441   struct in6_addr ip6;
19442   u8 mac[6];
19443   u8 eid_type = ~0, eid_set = 0;
19444   u32 prefix_length = ~0, t, vni = 0;
19445   u8 filter = 0;
19446   int ret;
19447   lisp_nsh_api_t nsh;
19448
19449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19450     {
19451       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19452         {
19453           eid_set = 1;
19454           eid_type = 0;
19455           prefix_length = t;
19456         }
19457       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19458         {
19459           eid_set = 1;
19460           eid_type = 1;
19461           prefix_length = t;
19462         }
19463       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19464         {
19465           eid_set = 1;
19466           eid_type = 2;
19467         }
19468       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19469         {
19470           eid_set = 1;
19471           eid_type = 3;
19472         }
19473       else if (unformat (i, "vni %d", &t))
19474         {
19475           vni = t;
19476         }
19477       else if (unformat (i, "local"))
19478         {
19479           filter = 1;
19480         }
19481       else if (unformat (i, "remote"))
19482         {
19483           filter = 2;
19484         }
19485       else
19486         {
19487           errmsg ("parse error '%U'", format_unformat_error, i);
19488           return -99;
19489         }
19490     }
19491
19492   if (!vam->json_output)
19493     {
19494       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19495              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19496     }
19497
19498   M (ONE_EID_TABLE_DUMP, mp);
19499
19500   mp->filter = filter;
19501   if (eid_set)
19502     {
19503       mp->eid_set = 1;
19504       mp->vni = htonl (vni);
19505       mp->eid_type = eid_type;
19506       switch (eid_type)
19507         {
19508         case 0:
19509           mp->prefix_length = prefix_length;
19510           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19511           break;
19512         case 1:
19513           mp->prefix_length = prefix_length;
19514           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19515           break;
19516         case 2:
19517           clib_memcpy (mp->eid, mac, sizeof (mac));
19518           break;
19519         case 3:
19520           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19521           break;
19522         default:
19523           errmsg ("unknown EID type %d!", eid_type);
19524           return -99;
19525         }
19526     }
19527
19528   /* send it... */
19529   S (mp);
19530
19531   /* Use a control ping for synchronization */
19532   MPING (CONTROL_PING, mp_ping);
19533   S (mp_ping);
19534
19535   /* Wait for a reply... */
19536   W (ret);
19537   return ret;
19538 }
19539
19540 #define api_lisp_eid_table_dump api_one_eid_table_dump
19541
19542 static int
19543 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19544 {
19545   unformat_input_t *i = vam->input;
19546   vl_api_gpe_fwd_entries_get_t *mp;
19547   u8 vni_set = 0;
19548   u32 vni = ~0;
19549   int ret;
19550
19551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19552     {
19553       if (unformat (i, "vni %d", &vni))
19554         {
19555           vni_set = 1;
19556         }
19557       else
19558         {
19559           errmsg ("parse error '%U'", format_unformat_error, i);
19560           return -99;
19561         }
19562     }
19563
19564   if (!vni_set)
19565     {
19566       errmsg ("vni not set!");
19567       return -99;
19568     }
19569
19570   if (!vam->json_output)
19571     {
19572       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19573              "leid", "reid");
19574     }
19575
19576   M (GPE_FWD_ENTRIES_GET, mp);
19577   mp->vni = clib_host_to_net_u32 (vni);
19578
19579   /* send it... */
19580   S (mp);
19581
19582   /* Wait for a reply... */
19583   W (ret);
19584   return ret;
19585 }
19586
19587 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19588 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19589 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19590 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19591 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19592 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19593 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19594 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19595
19596 static int
19597 api_one_adjacencies_get (vat_main_t * vam)
19598 {
19599   unformat_input_t *i = vam->input;
19600   vl_api_one_adjacencies_get_t *mp;
19601   u8 vni_set = 0;
19602   u32 vni = ~0;
19603   int ret;
19604
19605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19606     {
19607       if (unformat (i, "vni %d", &vni))
19608         {
19609           vni_set = 1;
19610         }
19611       else
19612         {
19613           errmsg ("parse error '%U'", format_unformat_error, i);
19614           return -99;
19615         }
19616     }
19617
19618   if (!vni_set)
19619     {
19620       errmsg ("vni not set!");
19621       return -99;
19622     }
19623
19624   if (!vam->json_output)
19625     {
19626       print (vam->ofp, "%s %40s", "leid", "reid");
19627     }
19628
19629   M (ONE_ADJACENCIES_GET, mp);
19630   mp->vni = clib_host_to_net_u32 (vni);
19631
19632   /* send it... */
19633   S (mp);
19634
19635   /* Wait for a reply... */
19636   W (ret);
19637   return ret;
19638 }
19639
19640 #define api_lisp_adjacencies_get api_one_adjacencies_get
19641
19642 static int
19643 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19644 {
19645   unformat_input_t *i = vam->input;
19646   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19647   int ret;
19648   u8 ip_family_set = 0, is_ip4 = 1;
19649
19650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19651     {
19652       if (unformat (i, "ip4"))
19653         {
19654           ip_family_set = 1;
19655           is_ip4 = 1;
19656         }
19657       else if (unformat (i, "ip6"))
19658         {
19659           ip_family_set = 1;
19660           is_ip4 = 0;
19661         }
19662       else
19663         {
19664           errmsg ("parse error '%U'", format_unformat_error, i);
19665           return -99;
19666         }
19667     }
19668
19669   if (!ip_family_set)
19670     {
19671       errmsg ("ip family not set!");
19672       return -99;
19673     }
19674
19675   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19676   mp->is_ip4 = is_ip4;
19677
19678   /* send it... */
19679   S (mp);
19680
19681   /* Wait for a reply... */
19682   W (ret);
19683   return ret;
19684 }
19685
19686 static int
19687 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19688 {
19689   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19690   int ret;
19691
19692   if (!vam->json_output)
19693     {
19694       print (vam->ofp, "VNIs");
19695     }
19696
19697   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19698
19699   /* send it... */
19700   S (mp);
19701
19702   /* Wait for a reply... */
19703   W (ret);
19704   return ret;
19705 }
19706
19707 static int
19708 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19709 {
19710   unformat_input_t *i = vam->input;
19711   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19712   int ret = 0;
19713   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19714   struct in_addr ip4;
19715   struct in6_addr ip6;
19716   u32 table_id = 0, nh_sw_if_index = ~0;
19717
19718   clib_memset (&ip4, 0, sizeof (ip4));
19719   clib_memset (&ip6, 0, sizeof (ip6));
19720
19721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19722     {
19723       if (unformat (i, "del"))
19724         is_add = 0;
19725       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19726                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19727         {
19728           ip_set = 1;
19729           is_ip4 = 1;
19730         }
19731       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19732                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19733         {
19734           ip_set = 1;
19735           is_ip4 = 0;
19736         }
19737       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19738         {
19739           ip_set = 1;
19740           is_ip4 = 1;
19741           nh_sw_if_index = ~0;
19742         }
19743       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19744         {
19745           ip_set = 1;
19746           is_ip4 = 0;
19747           nh_sw_if_index = ~0;
19748         }
19749       else if (unformat (i, "table %d", &table_id))
19750         ;
19751       else
19752         {
19753           errmsg ("parse error '%U'", format_unformat_error, i);
19754           return -99;
19755         }
19756     }
19757
19758   if (!ip_set)
19759     {
19760       errmsg ("nh addr not set!");
19761       return -99;
19762     }
19763
19764   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19765   mp->is_add = is_add;
19766   mp->table_id = clib_host_to_net_u32 (table_id);
19767   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19768   mp->is_ip4 = is_ip4;
19769   if (is_ip4)
19770     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19771   else
19772     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19773
19774   /* send it... */
19775   S (mp);
19776
19777   /* Wait for a reply... */
19778   W (ret);
19779   return ret;
19780 }
19781
19782 static int
19783 api_one_map_server_dump (vat_main_t * vam)
19784 {
19785   vl_api_one_map_server_dump_t *mp;
19786   vl_api_control_ping_t *mp_ping;
19787   int ret;
19788
19789   if (!vam->json_output)
19790     {
19791       print (vam->ofp, "%=20s", "Map server");
19792     }
19793
19794   M (ONE_MAP_SERVER_DUMP, mp);
19795   /* send it... */
19796   S (mp);
19797
19798   /* Use a control ping for synchronization */
19799   MPING (CONTROL_PING, mp_ping);
19800   S (mp_ping);
19801
19802   /* Wait for a reply... */
19803   W (ret);
19804   return ret;
19805 }
19806
19807 #define api_lisp_map_server_dump api_one_map_server_dump
19808
19809 static int
19810 api_one_map_resolver_dump (vat_main_t * vam)
19811 {
19812   vl_api_one_map_resolver_dump_t *mp;
19813   vl_api_control_ping_t *mp_ping;
19814   int ret;
19815
19816   if (!vam->json_output)
19817     {
19818       print (vam->ofp, "%=20s", "Map resolver");
19819     }
19820
19821   M (ONE_MAP_RESOLVER_DUMP, mp);
19822   /* send it... */
19823   S (mp);
19824
19825   /* Use a control ping for synchronization */
19826   MPING (CONTROL_PING, mp_ping);
19827   S (mp_ping);
19828
19829   /* Wait for a reply... */
19830   W (ret);
19831   return ret;
19832 }
19833
19834 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19835
19836 static int
19837 api_one_stats_flush (vat_main_t * vam)
19838 {
19839   vl_api_one_stats_flush_t *mp;
19840   int ret = 0;
19841
19842   M (ONE_STATS_FLUSH, mp);
19843   S (mp);
19844   W (ret);
19845   return ret;
19846 }
19847
19848 static int
19849 api_one_stats_dump (vat_main_t * vam)
19850 {
19851   vl_api_one_stats_dump_t *mp;
19852   vl_api_control_ping_t *mp_ping;
19853   int ret;
19854
19855   M (ONE_STATS_DUMP, mp);
19856   /* send it... */
19857   S (mp);
19858
19859   /* Use a control ping for synchronization */
19860   MPING (CONTROL_PING, mp_ping);
19861   S (mp_ping);
19862
19863   /* Wait for a reply... */
19864   W (ret);
19865   return ret;
19866 }
19867
19868 static int
19869 api_show_one_status (vat_main_t * vam)
19870 {
19871   vl_api_show_one_status_t *mp;
19872   int ret;
19873
19874   if (!vam->json_output)
19875     {
19876       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19877     }
19878
19879   M (SHOW_ONE_STATUS, mp);
19880   /* send it... */
19881   S (mp);
19882   /* Wait for a reply... */
19883   W (ret);
19884   return ret;
19885 }
19886
19887 #define api_show_lisp_status api_show_one_status
19888
19889 static int
19890 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19891 {
19892   vl_api_gpe_fwd_entry_path_dump_t *mp;
19893   vl_api_control_ping_t *mp_ping;
19894   unformat_input_t *i = vam->input;
19895   u32 fwd_entry_index = ~0;
19896   int ret;
19897
19898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19899     {
19900       if (unformat (i, "index %d", &fwd_entry_index))
19901         ;
19902       else
19903         break;
19904     }
19905
19906   if (~0 == fwd_entry_index)
19907     {
19908       errmsg ("no index specified!");
19909       return -99;
19910     }
19911
19912   if (!vam->json_output)
19913     {
19914       print (vam->ofp, "first line");
19915     }
19916
19917   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19918
19919   /* send it... */
19920   S (mp);
19921   /* Use a control ping for synchronization */
19922   MPING (CONTROL_PING, mp_ping);
19923   S (mp_ping);
19924
19925   /* Wait for a reply... */
19926   W (ret);
19927   return ret;
19928 }
19929
19930 static int
19931 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19932 {
19933   vl_api_one_get_map_request_itr_rlocs_t *mp;
19934   int ret;
19935
19936   if (!vam->json_output)
19937     {
19938       print (vam->ofp, "%=20s", "itr-rlocs:");
19939     }
19940
19941   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19942   /* send it... */
19943   S (mp);
19944   /* Wait for a reply... */
19945   W (ret);
19946   return ret;
19947 }
19948
19949 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19950
19951 static int
19952 api_af_packet_create (vat_main_t * vam)
19953 {
19954   unformat_input_t *i = vam->input;
19955   vl_api_af_packet_create_t *mp;
19956   u8 *host_if_name = 0;
19957   u8 hw_addr[6];
19958   u8 random_hw_addr = 1;
19959   int ret;
19960
19961   clib_memset (hw_addr, 0, sizeof (hw_addr));
19962
19963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19964     {
19965       if (unformat (i, "name %s", &host_if_name))
19966         vec_add1 (host_if_name, 0);
19967       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19968         random_hw_addr = 0;
19969       else
19970         break;
19971     }
19972
19973   if (!vec_len (host_if_name))
19974     {
19975       errmsg ("host-interface name must be specified");
19976       return -99;
19977     }
19978
19979   if (vec_len (host_if_name) > 64)
19980     {
19981       errmsg ("host-interface name too long");
19982       return -99;
19983     }
19984
19985   M (AF_PACKET_CREATE, mp);
19986
19987   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19988   clib_memcpy (mp->hw_addr, hw_addr, 6);
19989   mp->use_random_hw_addr = random_hw_addr;
19990   vec_free (host_if_name);
19991
19992   S (mp);
19993
19994   /* *INDENT-OFF* */
19995   W2 (ret,
19996       ({
19997         if (ret == 0)
19998           fprintf (vam->ofp ? vam->ofp : stderr,
19999                    " new sw_if_index = %d\n", vam->sw_if_index);
20000       }));
20001   /* *INDENT-ON* */
20002   return ret;
20003 }
20004
20005 static int
20006 api_af_packet_delete (vat_main_t * vam)
20007 {
20008   unformat_input_t *i = vam->input;
20009   vl_api_af_packet_delete_t *mp;
20010   u8 *host_if_name = 0;
20011   int ret;
20012
20013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20014     {
20015       if (unformat (i, "name %s", &host_if_name))
20016         vec_add1 (host_if_name, 0);
20017       else
20018         break;
20019     }
20020
20021   if (!vec_len (host_if_name))
20022     {
20023       errmsg ("host-interface name must be specified");
20024       return -99;
20025     }
20026
20027   if (vec_len (host_if_name) > 64)
20028     {
20029       errmsg ("host-interface name too long");
20030       return -99;
20031     }
20032
20033   M (AF_PACKET_DELETE, mp);
20034
20035   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20036   vec_free (host_if_name);
20037
20038   S (mp);
20039   W (ret);
20040   return ret;
20041 }
20042
20043 static void vl_api_af_packet_details_t_handler
20044   (vl_api_af_packet_details_t * mp)
20045 {
20046   vat_main_t *vam = &vat_main;
20047
20048   print (vam->ofp, "%-16s %d",
20049          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
20050 }
20051
20052 static void vl_api_af_packet_details_t_handler_json
20053   (vl_api_af_packet_details_t * mp)
20054 {
20055   vat_main_t *vam = &vat_main;
20056   vat_json_node_t *node = NULL;
20057
20058   if (VAT_JSON_ARRAY != vam->json_tree.type)
20059     {
20060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20061       vat_json_init_array (&vam->json_tree);
20062     }
20063   node = vat_json_array_add (&vam->json_tree);
20064
20065   vat_json_init_object (node);
20066   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20067   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
20068 }
20069
20070 static int
20071 api_af_packet_dump (vat_main_t * vam)
20072 {
20073   vl_api_af_packet_dump_t *mp;
20074   vl_api_control_ping_t *mp_ping;
20075   int ret;
20076
20077   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
20078   /* Get list of tap interfaces */
20079   M (AF_PACKET_DUMP, mp);
20080   S (mp);
20081
20082   /* Use a control ping for synchronization */
20083   MPING (CONTROL_PING, mp_ping);
20084   S (mp_ping);
20085
20086   W (ret);
20087   return ret;
20088 }
20089
20090 static int
20091 api_policer_add_del (vat_main_t * vam)
20092 {
20093   unformat_input_t *i = vam->input;
20094   vl_api_policer_add_del_t *mp;
20095   u8 is_add = 1;
20096   u8 *name = 0;
20097   u32 cir = 0;
20098   u32 eir = 0;
20099   u64 cb = 0;
20100   u64 eb = 0;
20101   u8 rate_type = 0;
20102   u8 round_type = 0;
20103   u8 type = 0;
20104   u8 color_aware = 0;
20105   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20106   int ret;
20107
20108   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20109   conform_action.dscp = 0;
20110   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20111   exceed_action.dscp = 0;
20112   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20113   violate_action.dscp = 0;
20114
20115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20116     {
20117       if (unformat (i, "del"))
20118         is_add = 0;
20119       else if (unformat (i, "name %s", &name))
20120         vec_add1 (name, 0);
20121       else if (unformat (i, "cir %u", &cir))
20122         ;
20123       else if (unformat (i, "eir %u", &eir))
20124         ;
20125       else if (unformat (i, "cb %u", &cb))
20126         ;
20127       else if (unformat (i, "eb %u", &eb))
20128         ;
20129       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20130                          &rate_type))
20131         ;
20132       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20133                          &round_type))
20134         ;
20135       else if (unformat (i, "type %U", unformat_policer_type, &type))
20136         ;
20137       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20138                          &conform_action))
20139         ;
20140       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20141                          &exceed_action))
20142         ;
20143       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20144                          &violate_action))
20145         ;
20146       else if (unformat (i, "color-aware"))
20147         color_aware = 1;
20148       else
20149         break;
20150     }
20151
20152   if (!vec_len (name))
20153     {
20154       errmsg ("policer name must be specified");
20155       return -99;
20156     }
20157
20158   if (vec_len (name) > 64)
20159     {
20160       errmsg ("policer name too long");
20161       return -99;
20162     }
20163
20164   M (POLICER_ADD_DEL, mp);
20165
20166   clib_memcpy (mp->name, name, vec_len (name));
20167   vec_free (name);
20168   mp->is_add = is_add;
20169   mp->cir = ntohl (cir);
20170   mp->eir = ntohl (eir);
20171   mp->cb = clib_net_to_host_u64 (cb);
20172   mp->eb = clib_net_to_host_u64 (eb);
20173   mp->rate_type = rate_type;
20174   mp->round_type = round_type;
20175   mp->type = type;
20176   mp->conform_action_type = conform_action.action_type;
20177   mp->conform_dscp = conform_action.dscp;
20178   mp->exceed_action_type = exceed_action.action_type;
20179   mp->exceed_dscp = exceed_action.dscp;
20180   mp->violate_action_type = violate_action.action_type;
20181   mp->violate_dscp = violate_action.dscp;
20182   mp->color_aware = color_aware;
20183
20184   S (mp);
20185   W (ret);
20186   return ret;
20187 }
20188
20189 static int
20190 api_policer_dump (vat_main_t * vam)
20191 {
20192   unformat_input_t *i = vam->input;
20193   vl_api_policer_dump_t *mp;
20194   vl_api_control_ping_t *mp_ping;
20195   u8 *match_name = 0;
20196   u8 match_name_valid = 0;
20197   int ret;
20198
20199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20200     {
20201       if (unformat (i, "name %s", &match_name))
20202         {
20203           vec_add1 (match_name, 0);
20204           match_name_valid = 1;
20205         }
20206       else
20207         break;
20208     }
20209
20210   M (POLICER_DUMP, mp);
20211   mp->match_name_valid = match_name_valid;
20212   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20213   vec_free (match_name);
20214   /* send it... */
20215   S (mp);
20216
20217   /* Use a control ping for synchronization */
20218   MPING (CONTROL_PING, mp_ping);
20219   S (mp_ping);
20220
20221   /* Wait for a reply... */
20222   W (ret);
20223   return ret;
20224 }
20225
20226 static int
20227 api_policer_classify_set_interface (vat_main_t * vam)
20228 {
20229   unformat_input_t *i = vam->input;
20230   vl_api_policer_classify_set_interface_t *mp;
20231   u32 sw_if_index;
20232   int sw_if_index_set;
20233   u32 ip4_table_index = ~0;
20234   u32 ip6_table_index = ~0;
20235   u32 l2_table_index = ~0;
20236   u8 is_add = 1;
20237   int ret;
20238
20239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20240     {
20241       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20242         sw_if_index_set = 1;
20243       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20244         sw_if_index_set = 1;
20245       else if (unformat (i, "del"))
20246         is_add = 0;
20247       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20248         ;
20249       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20250         ;
20251       else if (unformat (i, "l2-table %d", &l2_table_index))
20252         ;
20253       else
20254         {
20255           clib_warning ("parse error '%U'", format_unformat_error, i);
20256           return -99;
20257         }
20258     }
20259
20260   if (sw_if_index_set == 0)
20261     {
20262       errmsg ("missing interface name or sw_if_index");
20263       return -99;
20264     }
20265
20266   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20267
20268   mp->sw_if_index = ntohl (sw_if_index);
20269   mp->ip4_table_index = ntohl (ip4_table_index);
20270   mp->ip6_table_index = ntohl (ip6_table_index);
20271   mp->l2_table_index = ntohl (l2_table_index);
20272   mp->is_add = is_add;
20273
20274   S (mp);
20275   W (ret);
20276   return ret;
20277 }
20278
20279 static int
20280 api_policer_classify_dump (vat_main_t * vam)
20281 {
20282   unformat_input_t *i = vam->input;
20283   vl_api_policer_classify_dump_t *mp;
20284   vl_api_control_ping_t *mp_ping;
20285   u8 type = POLICER_CLASSIFY_N_TABLES;
20286   int ret;
20287
20288   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20289     ;
20290   else
20291     {
20292       errmsg ("classify table type must be specified");
20293       return -99;
20294     }
20295
20296   if (!vam->json_output)
20297     {
20298       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20299     }
20300
20301   M (POLICER_CLASSIFY_DUMP, mp);
20302   mp->type = type;
20303   /* send it... */
20304   S (mp);
20305
20306   /* Use a control ping for synchronization */
20307   MPING (CONTROL_PING, mp_ping);
20308   S (mp_ping);
20309
20310   /* Wait for a reply... */
20311   W (ret);
20312   return ret;
20313 }
20314
20315 static int
20316 api_netmap_create (vat_main_t * vam)
20317 {
20318   unformat_input_t *i = vam->input;
20319   vl_api_netmap_create_t *mp;
20320   u8 *if_name = 0;
20321   u8 hw_addr[6];
20322   u8 random_hw_addr = 1;
20323   u8 is_pipe = 0;
20324   u8 is_master = 0;
20325   int ret;
20326
20327   clib_memset (hw_addr, 0, sizeof (hw_addr));
20328
20329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20330     {
20331       if (unformat (i, "name %s", &if_name))
20332         vec_add1 (if_name, 0);
20333       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20334         random_hw_addr = 0;
20335       else if (unformat (i, "pipe"))
20336         is_pipe = 1;
20337       else if (unformat (i, "master"))
20338         is_master = 1;
20339       else if (unformat (i, "slave"))
20340         is_master = 0;
20341       else
20342         break;
20343     }
20344
20345   if (!vec_len (if_name))
20346     {
20347       errmsg ("interface name must be specified");
20348       return -99;
20349     }
20350
20351   if (vec_len (if_name) > 64)
20352     {
20353       errmsg ("interface name too long");
20354       return -99;
20355     }
20356
20357   M (NETMAP_CREATE, mp);
20358
20359   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20360   clib_memcpy (mp->hw_addr, hw_addr, 6);
20361   mp->use_random_hw_addr = random_hw_addr;
20362   mp->is_pipe = is_pipe;
20363   mp->is_master = is_master;
20364   vec_free (if_name);
20365
20366   S (mp);
20367   W (ret);
20368   return ret;
20369 }
20370
20371 static int
20372 api_netmap_delete (vat_main_t * vam)
20373 {
20374   unformat_input_t *i = vam->input;
20375   vl_api_netmap_delete_t *mp;
20376   u8 *if_name = 0;
20377   int ret;
20378
20379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20380     {
20381       if (unformat (i, "name %s", &if_name))
20382         vec_add1 (if_name, 0);
20383       else
20384         break;
20385     }
20386
20387   if (!vec_len (if_name))
20388     {
20389       errmsg ("interface name must be specified");
20390       return -99;
20391     }
20392
20393   if (vec_len (if_name) > 64)
20394     {
20395       errmsg ("interface name too long");
20396       return -99;
20397     }
20398
20399   M (NETMAP_DELETE, mp);
20400
20401   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20402   vec_free (if_name);
20403
20404   S (mp);
20405   W (ret);
20406   return ret;
20407 }
20408
20409 static void
20410 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20411 {
20412   if (fp->afi == IP46_TYPE_IP6)
20413     print (vam->ofp,
20414            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20415            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20416            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
20417            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20418            format_ip6_address, fp->next_hop);
20419   else if (fp->afi == IP46_TYPE_IP4)
20420     print (vam->ofp,
20421            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20422            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20423            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
20424            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20425            format_ip4_address, fp->next_hop);
20426 }
20427
20428 static void
20429 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20430                                  vl_api_fib_path_t * fp)
20431 {
20432   struct in_addr ip4;
20433   struct in6_addr ip6;
20434
20435   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20436   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20437   vat_json_object_add_uint (node, "is_local", fp->is_local);
20438   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20439   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20440   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20441   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20442   if (fp->afi == IP46_TYPE_IP4)
20443     {
20444       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20445       vat_json_object_add_ip4 (node, "next_hop", ip4);
20446     }
20447   else if (fp->afi == IP46_TYPE_IP6)
20448     {
20449       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20450       vat_json_object_add_ip6 (node, "next_hop", ip6);
20451     }
20452 }
20453
20454 static void
20455 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20456 {
20457   vat_main_t *vam = &vat_main;
20458   int count = ntohl (mp->mt_count);
20459   vl_api_fib_path_t *fp;
20460   i32 i;
20461
20462   print (vam->ofp, "[%d]: sw_if_index %d via:",
20463          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20464   fp = mp->mt_paths;
20465   for (i = 0; i < count; i++)
20466     {
20467       vl_api_mpls_fib_path_print (vam, fp);
20468       fp++;
20469     }
20470
20471   print (vam->ofp, "");
20472 }
20473
20474 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20475 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20476
20477 static void
20478 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20479 {
20480   vat_main_t *vam = &vat_main;
20481   vat_json_node_t *node = NULL;
20482   int count = ntohl (mp->mt_count);
20483   vl_api_fib_path_t *fp;
20484   i32 i;
20485
20486   if (VAT_JSON_ARRAY != vam->json_tree.type)
20487     {
20488       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20489       vat_json_init_array (&vam->json_tree);
20490     }
20491   node = vat_json_array_add (&vam->json_tree);
20492
20493   vat_json_init_object (node);
20494   vat_json_object_add_uint (node, "tunnel_index",
20495                             ntohl (mp->mt_tunnel_index));
20496   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20497
20498   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20499
20500   fp = mp->mt_paths;
20501   for (i = 0; i < count; i++)
20502     {
20503       vl_api_mpls_fib_path_json_print (node, fp);
20504       fp++;
20505     }
20506 }
20507
20508 static int
20509 api_mpls_tunnel_dump (vat_main_t * vam)
20510 {
20511   vl_api_mpls_tunnel_dump_t *mp;
20512   vl_api_control_ping_t *mp_ping;
20513   u32 sw_if_index = ~0;
20514   int ret;
20515
20516   /* Parse args required to build the message */
20517   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20518     {
20519       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20520         ;
20521     }
20522
20523   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20524
20525   M (MPLS_TUNNEL_DUMP, mp);
20526   mp->sw_if_index = htonl (sw_if_index);
20527   S (mp);
20528
20529   /* Use a control ping for synchronization */
20530   MPING (CONTROL_PING, mp_ping);
20531   S (mp_ping);
20532
20533   W (ret);
20534   return ret;
20535 }
20536
20537 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20538 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20539
20540
20541 static void
20542 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20543 {
20544   vat_main_t *vam = &vat_main;
20545   int count = ntohl (mp->count);
20546   vl_api_fib_path_t *fp;
20547   int i;
20548
20549   print (vam->ofp,
20550          "table-id %d, label %u, ess_bit %u",
20551          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20552   fp = mp->path;
20553   for (i = 0; i < count; i++)
20554     {
20555       vl_api_mpls_fib_path_print (vam, fp);
20556       fp++;
20557     }
20558 }
20559
20560 static void vl_api_mpls_fib_details_t_handler_json
20561   (vl_api_mpls_fib_details_t * mp)
20562 {
20563   vat_main_t *vam = &vat_main;
20564   int count = ntohl (mp->count);
20565   vat_json_node_t *node = NULL;
20566   vl_api_fib_path_t *fp;
20567   int i;
20568
20569   if (VAT_JSON_ARRAY != vam->json_tree.type)
20570     {
20571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20572       vat_json_init_array (&vam->json_tree);
20573     }
20574   node = vat_json_array_add (&vam->json_tree);
20575
20576   vat_json_init_object (node);
20577   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20578   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20579   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20580   vat_json_object_add_uint (node, "path_count", count);
20581   fp = mp->path;
20582   for (i = 0; i < count; i++)
20583     {
20584       vl_api_mpls_fib_path_json_print (node, fp);
20585       fp++;
20586     }
20587 }
20588
20589 static int
20590 api_mpls_fib_dump (vat_main_t * vam)
20591 {
20592   vl_api_mpls_fib_dump_t *mp;
20593   vl_api_control_ping_t *mp_ping;
20594   int ret;
20595
20596   M (MPLS_FIB_DUMP, mp);
20597   S (mp);
20598
20599   /* Use a control ping for synchronization */
20600   MPING (CONTROL_PING, mp_ping);
20601   S (mp_ping);
20602
20603   W (ret);
20604   return ret;
20605 }
20606
20607 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20608 #define vl_api_ip_fib_details_t_print vl_noop_handler
20609
20610 static void
20611 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20612 {
20613   vat_main_t *vam = &vat_main;
20614   int count = ntohl (mp->count);
20615   vl_api_fib_path_t *fp;
20616   int i;
20617
20618   print (vam->ofp,
20619          "table-id %d, prefix %U/%d stats-index %d",
20620          ntohl (mp->table_id), format_ip4_address, mp->address,
20621          mp->address_length, ntohl (mp->stats_index));
20622   fp = mp->path;
20623   for (i = 0; i < count; i++)
20624     {
20625       if (fp->afi == IP46_TYPE_IP6)
20626         print (vam->ofp,
20627                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20628                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20629                "next_hop_table %d",
20630                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20631                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20632                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20633       else if (fp->afi == IP46_TYPE_IP4)
20634         print (vam->ofp,
20635                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20636                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20637                "next_hop_table %d",
20638                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20639                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20640                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20641       fp++;
20642     }
20643 }
20644
20645 static void vl_api_ip_fib_details_t_handler_json
20646   (vl_api_ip_fib_details_t * mp)
20647 {
20648   vat_main_t *vam = &vat_main;
20649   int count = ntohl (mp->count);
20650   vat_json_node_t *node = NULL;
20651   struct in_addr ip4;
20652   struct in6_addr ip6;
20653   vl_api_fib_path_t *fp;
20654   int i;
20655
20656   if (VAT_JSON_ARRAY != vam->json_tree.type)
20657     {
20658       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20659       vat_json_init_array (&vam->json_tree);
20660     }
20661   node = vat_json_array_add (&vam->json_tree);
20662
20663   vat_json_init_object (node);
20664   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20665   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20666   vat_json_object_add_ip4 (node, "prefix", ip4);
20667   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20668   vat_json_object_add_uint (node, "path_count", count);
20669   fp = mp->path;
20670   for (i = 0; i < count; i++)
20671     {
20672       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20673       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20674       vat_json_object_add_uint (node, "is_local", fp->is_local);
20675       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20676       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20677       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20678       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20679       if (fp->afi == IP46_TYPE_IP4)
20680         {
20681           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20682           vat_json_object_add_ip4 (node, "next_hop", ip4);
20683         }
20684       else if (fp->afi == IP46_TYPE_IP6)
20685         {
20686           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20687           vat_json_object_add_ip6 (node, "next_hop", ip6);
20688         }
20689     }
20690 }
20691
20692 static int
20693 api_ip_fib_dump (vat_main_t * vam)
20694 {
20695   vl_api_ip_fib_dump_t *mp;
20696   vl_api_control_ping_t *mp_ping;
20697   int ret;
20698
20699   M (IP_FIB_DUMP, mp);
20700   S (mp);
20701
20702   /* Use a control ping for synchronization */
20703   MPING (CONTROL_PING, mp_ping);
20704   S (mp_ping);
20705
20706   W (ret);
20707   return ret;
20708 }
20709
20710 static int
20711 api_ip_mfib_dump (vat_main_t * vam)
20712 {
20713   vl_api_ip_mfib_dump_t *mp;
20714   vl_api_control_ping_t *mp_ping;
20715   int ret;
20716
20717   M (IP_MFIB_DUMP, mp);
20718   S (mp);
20719
20720   /* Use a control ping for synchronization */
20721   MPING (CONTROL_PING, mp_ping);
20722   S (mp_ping);
20723
20724   W (ret);
20725   return ret;
20726 }
20727
20728 static void vl_api_ip_neighbor_details_t_handler
20729   (vl_api_ip_neighbor_details_t * mp)
20730 {
20731   vat_main_t *vam = &vat_main;
20732
20733   print (vam->ofp, "%c %U %U",
20734          (mp->is_static) ? 'S' : 'D',
20735          format_ethernet_address, &mp->mac_address,
20736          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20737          &mp->ip_address);
20738 }
20739
20740 static void vl_api_ip_neighbor_details_t_handler_json
20741   (vl_api_ip_neighbor_details_t * mp)
20742 {
20743
20744   vat_main_t *vam = &vat_main;
20745   vat_json_node_t *node;
20746   struct in_addr ip4;
20747   struct in6_addr ip6;
20748
20749   if (VAT_JSON_ARRAY != vam->json_tree.type)
20750     {
20751       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20752       vat_json_init_array (&vam->json_tree);
20753     }
20754   node = vat_json_array_add (&vam->json_tree);
20755
20756   vat_json_init_object (node);
20757   vat_json_object_add_string_copy (node, "flag",
20758                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20759                                    "dynamic");
20760
20761   vat_json_object_add_string_copy (node, "link_layer",
20762                                    format (0, "%U", format_ethernet_address,
20763                                            &mp->mac_address));
20764
20765   if (mp->is_ipv6)
20766     {
20767       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20768       vat_json_object_add_ip6 (node, "ip_address", ip6);
20769     }
20770   else
20771     {
20772       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20773       vat_json_object_add_ip4 (node, "ip_address", ip4);
20774     }
20775 }
20776
20777 static int
20778 api_ip_neighbor_dump (vat_main_t * vam)
20779 {
20780   unformat_input_t *i = vam->input;
20781   vl_api_ip_neighbor_dump_t *mp;
20782   vl_api_control_ping_t *mp_ping;
20783   u8 is_ipv6 = 0;
20784   u32 sw_if_index = ~0;
20785   int ret;
20786
20787   /* Parse args required to build the message */
20788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20789     {
20790       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20791         ;
20792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20793         ;
20794       else if (unformat (i, "ip6"))
20795         is_ipv6 = 1;
20796       else
20797         break;
20798     }
20799
20800   if (sw_if_index == ~0)
20801     {
20802       errmsg ("missing interface name or sw_if_index");
20803       return -99;
20804     }
20805
20806   M (IP_NEIGHBOR_DUMP, mp);
20807   mp->is_ipv6 = (u8) is_ipv6;
20808   mp->sw_if_index = ntohl (sw_if_index);
20809   S (mp);
20810
20811   /* Use a control ping for synchronization */
20812   MPING (CONTROL_PING, mp_ping);
20813   S (mp_ping);
20814
20815   W (ret);
20816   return ret;
20817 }
20818
20819 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20820 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20821
20822 static void
20823 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20824 {
20825   vat_main_t *vam = &vat_main;
20826   int count = ntohl (mp->count);
20827   vl_api_fib_path_t *fp;
20828   int i;
20829
20830   print (vam->ofp,
20831          "table-id %d, prefix %U/%d stats-index %d",
20832          ntohl (mp->table_id), format_ip6_address, mp->address,
20833          mp->address_length, ntohl (mp->stats_index));
20834   fp = mp->path;
20835   for (i = 0; i < count; i++)
20836     {
20837       if (fp->afi == IP46_TYPE_IP6)
20838         print (vam->ofp,
20839                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20840                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20841                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20842                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20843                format_ip6_address, fp->next_hop);
20844       else if (fp->afi == IP46_TYPE_IP4)
20845         print (vam->ofp,
20846                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20847                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20848                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20849                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20850                format_ip4_address, fp->next_hop);
20851       fp++;
20852     }
20853 }
20854
20855 static void vl_api_ip6_fib_details_t_handler_json
20856   (vl_api_ip6_fib_details_t * mp)
20857 {
20858   vat_main_t *vam = &vat_main;
20859   int count = ntohl (mp->count);
20860   vat_json_node_t *node = NULL;
20861   struct in_addr ip4;
20862   struct in6_addr ip6;
20863   vl_api_fib_path_t *fp;
20864   int i;
20865
20866   if (VAT_JSON_ARRAY != vam->json_tree.type)
20867     {
20868       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20869       vat_json_init_array (&vam->json_tree);
20870     }
20871   node = vat_json_array_add (&vam->json_tree);
20872
20873   vat_json_init_object (node);
20874   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20875   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20876   vat_json_object_add_ip6 (node, "prefix", ip6);
20877   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20878   vat_json_object_add_uint (node, "path_count", count);
20879   fp = mp->path;
20880   for (i = 0; i < count; i++)
20881     {
20882       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20883       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20884       vat_json_object_add_uint (node, "is_local", fp->is_local);
20885       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20886       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20887       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20888       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20889       if (fp->afi == IP46_TYPE_IP4)
20890         {
20891           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20892           vat_json_object_add_ip4 (node, "next_hop", ip4);
20893         }
20894       else if (fp->afi == IP46_TYPE_IP6)
20895         {
20896           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20897           vat_json_object_add_ip6 (node, "next_hop", ip6);
20898         }
20899     }
20900 }
20901
20902 static int
20903 api_ip6_fib_dump (vat_main_t * vam)
20904 {
20905   vl_api_ip6_fib_dump_t *mp;
20906   vl_api_control_ping_t *mp_ping;
20907   int ret;
20908
20909   M (IP6_FIB_DUMP, mp);
20910   S (mp);
20911
20912   /* Use a control ping for synchronization */
20913   MPING (CONTROL_PING, mp_ping);
20914   S (mp_ping);
20915
20916   W (ret);
20917   return ret;
20918 }
20919
20920 static int
20921 api_ip6_mfib_dump (vat_main_t * vam)
20922 {
20923   vl_api_ip6_mfib_dump_t *mp;
20924   vl_api_control_ping_t *mp_ping;
20925   int ret;
20926
20927   M (IP6_MFIB_DUMP, mp);
20928   S (mp);
20929
20930   /* Use a control ping for synchronization */
20931   MPING (CONTROL_PING, mp_ping);
20932   S (mp_ping);
20933
20934   W (ret);
20935   return ret;
20936 }
20937
20938 int
20939 api_classify_table_ids (vat_main_t * vam)
20940 {
20941   vl_api_classify_table_ids_t *mp;
20942   int ret;
20943
20944   /* Construct the API message */
20945   M (CLASSIFY_TABLE_IDS, mp);
20946   mp->context = 0;
20947
20948   S (mp);
20949   W (ret);
20950   return ret;
20951 }
20952
20953 int
20954 api_classify_table_by_interface (vat_main_t * vam)
20955 {
20956   unformat_input_t *input = vam->input;
20957   vl_api_classify_table_by_interface_t *mp;
20958
20959   u32 sw_if_index = ~0;
20960   int ret;
20961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20962     {
20963       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20964         ;
20965       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20966         ;
20967       else
20968         break;
20969     }
20970   if (sw_if_index == ~0)
20971     {
20972       errmsg ("missing interface name or sw_if_index");
20973       return -99;
20974     }
20975
20976   /* Construct the API message */
20977   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20978   mp->context = 0;
20979   mp->sw_if_index = ntohl (sw_if_index);
20980
20981   S (mp);
20982   W (ret);
20983   return ret;
20984 }
20985
20986 int
20987 api_classify_table_info (vat_main_t * vam)
20988 {
20989   unformat_input_t *input = vam->input;
20990   vl_api_classify_table_info_t *mp;
20991
20992   u32 table_id = ~0;
20993   int ret;
20994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20995     {
20996       if (unformat (input, "table_id %d", &table_id))
20997         ;
20998       else
20999         break;
21000     }
21001   if (table_id == ~0)
21002     {
21003       errmsg ("missing table id");
21004       return -99;
21005     }
21006
21007   /* Construct the API message */
21008   M (CLASSIFY_TABLE_INFO, mp);
21009   mp->context = 0;
21010   mp->table_id = ntohl (table_id);
21011
21012   S (mp);
21013   W (ret);
21014   return ret;
21015 }
21016
21017 int
21018 api_classify_session_dump (vat_main_t * vam)
21019 {
21020   unformat_input_t *input = vam->input;
21021   vl_api_classify_session_dump_t *mp;
21022   vl_api_control_ping_t *mp_ping;
21023
21024   u32 table_id = ~0;
21025   int ret;
21026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21027     {
21028       if (unformat (input, "table_id %d", &table_id))
21029         ;
21030       else
21031         break;
21032     }
21033   if (table_id == ~0)
21034     {
21035       errmsg ("missing table id");
21036       return -99;
21037     }
21038
21039   /* Construct the API message */
21040   M (CLASSIFY_SESSION_DUMP, mp);
21041   mp->context = 0;
21042   mp->table_id = ntohl (table_id);
21043   S (mp);
21044
21045   /* Use a control ping for synchronization */
21046   MPING (CONTROL_PING, mp_ping);
21047   S (mp_ping);
21048
21049   W (ret);
21050   return ret;
21051 }
21052
21053 static void
21054 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
21055 {
21056   vat_main_t *vam = &vat_main;
21057
21058   print (vam->ofp, "collector_address %U, collector_port %d, "
21059          "src_address %U, vrf_id %d, path_mtu %u, "
21060          "template_interval %u, udp_checksum %d",
21061          format_ip4_address, mp->collector_address,
21062          ntohs (mp->collector_port),
21063          format_ip4_address, mp->src_address,
21064          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
21065          ntohl (mp->template_interval), mp->udp_checksum);
21066
21067   vam->retval = 0;
21068   vam->result_ready = 1;
21069 }
21070
21071 static void
21072   vl_api_ipfix_exporter_details_t_handler_json
21073   (vl_api_ipfix_exporter_details_t * mp)
21074 {
21075   vat_main_t *vam = &vat_main;
21076   vat_json_node_t node;
21077   struct in_addr collector_address;
21078   struct in_addr src_address;
21079
21080   vat_json_init_object (&node);
21081   clib_memcpy (&collector_address, &mp->collector_address,
21082                sizeof (collector_address));
21083   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
21084   vat_json_object_add_uint (&node, "collector_port",
21085                             ntohs (mp->collector_port));
21086   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21087   vat_json_object_add_ip4 (&node, "src_address", src_address);
21088   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21089   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21090   vat_json_object_add_uint (&node, "template_interval",
21091                             ntohl (mp->template_interval));
21092   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21093
21094   vat_json_print (vam->ofp, &node);
21095   vat_json_free (&node);
21096   vam->retval = 0;
21097   vam->result_ready = 1;
21098 }
21099
21100 int
21101 api_ipfix_exporter_dump (vat_main_t * vam)
21102 {
21103   vl_api_ipfix_exporter_dump_t *mp;
21104   int ret;
21105
21106   /* Construct the API message */
21107   M (IPFIX_EXPORTER_DUMP, mp);
21108   mp->context = 0;
21109
21110   S (mp);
21111   W (ret);
21112   return ret;
21113 }
21114
21115 static int
21116 api_ipfix_classify_stream_dump (vat_main_t * vam)
21117 {
21118   vl_api_ipfix_classify_stream_dump_t *mp;
21119   int ret;
21120
21121   /* Construct the API message */
21122   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21123   mp->context = 0;
21124
21125   S (mp);
21126   W (ret);
21127   return ret;
21128   /* NOTREACHED */
21129   return 0;
21130 }
21131
21132 static void
21133   vl_api_ipfix_classify_stream_details_t_handler
21134   (vl_api_ipfix_classify_stream_details_t * mp)
21135 {
21136   vat_main_t *vam = &vat_main;
21137   print (vam->ofp, "domain_id %d, src_port %d",
21138          ntohl (mp->domain_id), ntohs (mp->src_port));
21139   vam->retval = 0;
21140   vam->result_ready = 1;
21141 }
21142
21143 static void
21144   vl_api_ipfix_classify_stream_details_t_handler_json
21145   (vl_api_ipfix_classify_stream_details_t * mp)
21146 {
21147   vat_main_t *vam = &vat_main;
21148   vat_json_node_t node;
21149
21150   vat_json_init_object (&node);
21151   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21152   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21153
21154   vat_json_print (vam->ofp, &node);
21155   vat_json_free (&node);
21156   vam->retval = 0;
21157   vam->result_ready = 1;
21158 }
21159
21160 static int
21161 api_ipfix_classify_table_dump (vat_main_t * vam)
21162 {
21163   vl_api_ipfix_classify_table_dump_t *mp;
21164   vl_api_control_ping_t *mp_ping;
21165   int ret;
21166
21167   if (!vam->json_output)
21168     {
21169       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21170              "transport_protocol");
21171     }
21172
21173   /* Construct the API message */
21174   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21175
21176   /* send it... */
21177   S (mp);
21178
21179   /* Use a control ping for synchronization */
21180   MPING (CONTROL_PING, mp_ping);
21181   S (mp_ping);
21182
21183   W (ret);
21184   return ret;
21185 }
21186
21187 static void
21188   vl_api_ipfix_classify_table_details_t_handler
21189   (vl_api_ipfix_classify_table_details_t * mp)
21190 {
21191   vat_main_t *vam = &vat_main;
21192   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21193          mp->transport_protocol);
21194 }
21195
21196 static void
21197   vl_api_ipfix_classify_table_details_t_handler_json
21198   (vl_api_ipfix_classify_table_details_t * mp)
21199 {
21200   vat_json_node_t *node = NULL;
21201   vat_main_t *vam = &vat_main;
21202
21203   if (VAT_JSON_ARRAY != vam->json_tree.type)
21204     {
21205       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21206       vat_json_init_array (&vam->json_tree);
21207     }
21208
21209   node = vat_json_array_add (&vam->json_tree);
21210   vat_json_init_object (node);
21211
21212   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21213   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21214   vat_json_object_add_uint (node, "transport_protocol",
21215                             mp->transport_protocol);
21216 }
21217
21218 static int
21219 api_sw_interface_span_enable_disable (vat_main_t * vam)
21220 {
21221   unformat_input_t *i = vam->input;
21222   vl_api_sw_interface_span_enable_disable_t *mp;
21223   u32 src_sw_if_index = ~0;
21224   u32 dst_sw_if_index = ~0;
21225   u8 state = 3;
21226   int ret;
21227   u8 is_l2 = 0;
21228
21229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21230     {
21231       if (unformat
21232           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21233         ;
21234       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21235         ;
21236       else
21237         if (unformat
21238             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21239         ;
21240       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21241         ;
21242       else if (unformat (i, "disable"))
21243         state = 0;
21244       else if (unformat (i, "rx"))
21245         state = 1;
21246       else if (unformat (i, "tx"))
21247         state = 2;
21248       else if (unformat (i, "both"))
21249         state = 3;
21250       else if (unformat (i, "l2"))
21251         is_l2 = 1;
21252       else
21253         break;
21254     }
21255
21256   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21257
21258   mp->sw_if_index_from = htonl (src_sw_if_index);
21259   mp->sw_if_index_to = htonl (dst_sw_if_index);
21260   mp->state = state;
21261   mp->is_l2 = is_l2;
21262
21263   S (mp);
21264   W (ret);
21265   return ret;
21266 }
21267
21268 static void
21269 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21270                                             * mp)
21271 {
21272   vat_main_t *vam = &vat_main;
21273   u8 *sw_if_from_name = 0;
21274   u8 *sw_if_to_name = 0;
21275   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21276   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21277   char *states[] = { "none", "rx", "tx", "both" };
21278   hash_pair_t *p;
21279
21280   /* *INDENT-OFF* */
21281   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21282   ({
21283     if ((u32) p->value[0] == sw_if_index_from)
21284       {
21285         sw_if_from_name = (u8 *)(p->key);
21286         if (sw_if_to_name)
21287           break;
21288       }
21289     if ((u32) p->value[0] == sw_if_index_to)
21290       {
21291         sw_if_to_name = (u8 *)(p->key);
21292         if (sw_if_from_name)
21293           break;
21294       }
21295   }));
21296   /* *INDENT-ON* */
21297   print (vam->ofp, "%20s => %20s (%s) %s",
21298          sw_if_from_name, sw_if_to_name, states[mp->state],
21299          mp->is_l2 ? "l2" : "device");
21300 }
21301
21302 static void
21303   vl_api_sw_interface_span_details_t_handler_json
21304   (vl_api_sw_interface_span_details_t * mp)
21305 {
21306   vat_main_t *vam = &vat_main;
21307   vat_json_node_t *node = NULL;
21308   u8 *sw_if_from_name = 0;
21309   u8 *sw_if_to_name = 0;
21310   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21311   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21312   hash_pair_t *p;
21313
21314   /* *INDENT-OFF* */
21315   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21316   ({
21317     if ((u32) p->value[0] == sw_if_index_from)
21318       {
21319         sw_if_from_name = (u8 *)(p->key);
21320         if (sw_if_to_name)
21321           break;
21322       }
21323     if ((u32) p->value[0] == sw_if_index_to)
21324       {
21325         sw_if_to_name = (u8 *)(p->key);
21326         if (sw_if_from_name)
21327           break;
21328       }
21329   }));
21330   /* *INDENT-ON* */
21331
21332   if (VAT_JSON_ARRAY != vam->json_tree.type)
21333     {
21334       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21335       vat_json_init_array (&vam->json_tree);
21336     }
21337   node = vat_json_array_add (&vam->json_tree);
21338
21339   vat_json_init_object (node);
21340   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21341   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21342   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21343   if (0 != sw_if_to_name)
21344     {
21345       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21346     }
21347   vat_json_object_add_uint (node, "state", mp->state);
21348   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21349 }
21350
21351 static int
21352 api_sw_interface_span_dump (vat_main_t * vam)
21353 {
21354   unformat_input_t *input = vam->input;
21355   vl_api_sw_interface_span_dump_t *mp;
21356   vl_api_control_ping_t *mp_ping;
21357   u8 is_l2 = 0;
21358   int ret;
21359
21360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21361     {
21362       if (unformat (input, "l2"))
21363         is_l2 = 1;
21364       else
21365         break;
21366     }
21367
21368   M (SW_INTERFACE_SPAN_DUMP, mp);
21369   mp->is_l2 = is_l2;
21370   S (mp);
21371
21372   /* Use a control ping for synchronization */
21373   MPING (CONTROL_PING, mp_ping);
21374   S (mp_ping);
21375
21376   W (ret);
21377   return ret;
21378 }
21379
21380 int
21381 api_pg_create_interface (vat_main_t * vam)
21382 {
21383   unformat_input_t *input = vam->input;
21384   vl_api_pg_create_interface_t *mp;
21385
21386   u32 if_id = ~0;
21387   int ret;
21388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21389     {
21390       if (unformat (input, "if_id %d", &if_id))
21391         ;
21392       else
21393         break;
21394     }
21395   if (if_id == ~0)
21396     {
21397       errmsg ("missing pg interface index");
21398       return -99;
21399     }
21400
21401   /* Construct the API message */
21402   M (PG_CREATE_INTERFACE, mp);
21403   mp->context = 0;
21404   mp->interface_id = ntohl (if_id);
21405
21406   S (mp);
21407   W (ret);
21408   return ret;
21409 }
21410
21411 int
21412 api_pg_capture (vat_main_t * vam)
21413 {
21414   unformat_input_t *input = vam->input;
21415   vl_api_pg_capture_t *mp;
21416
21417   u32 if_id = ~0;
21418   u8 enable = 1;
21419   u32 count = 1;
21420   u8 pcap_file_set = 0;
21421   u8 *pcap_file = 0;
21422   int ret;
21423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21424     {
21425       if (unformat (input, "if_id %d", &if_id))
21426         ;
21427       else if (unformat (input, "pcap %s", &pcap_file))
21428         pcap_file_set = 1;
21429       else if (unformat (input, "count %d", &count))
21430         ;
21431       else if (unformat (input, "disable"))
21432         enable = 0;
21433       else
21434         break;
21435     }
21436   if (if_id == ~0)
21437     {
21438       errmsg ("missing pg interface index");
21439       return -99;
21440     }
21441   if (pcap_file_set > 0)
21442     {
21443       if (vec_len (pcap_file) > 255)
21444         {
21445           errmsg ("pcap file name is too long");
21446           return -99;
21447         }
21448     }
21449
21450   u32 name_len = vec_len (pcap_file);
21451   /* Construct the API message */
21452   M (PG_CAPTURE, mp);
21453   mp->context = 0;
21454   mp->interface_id = ntohl (if_id);
21455   mp->is_enabled = enable;
21456   mp->count = ntohl (count);
21457   mp->pcap_name_length = ntohl (name_len);
21458   if (pcap_file_set != 0)
21459     {
21460       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21461     }
21462   vec_free (pcap_file);
21463
21464   S (mp);
21465   W (ret);
21466   return ret;
21467 }
21468
21469 int
21470 api_pg_enable_disable (vat_main_t * vam)
21471 {
21472   unformat_input_t *input = vam->input;
21473   vl_api_pg_enable_disable_t *mp;
21474
21475   u8 enable = 1;
21476   u8 stream_name_set = 0;
21477   u8 *stream_name = 0;
21478   int ret;
21479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21480     {
21481       if (unformat (input, "stream %s", &stream_name))
21482         stream_name_set = 1;
21483       else if (unformat (input, "disable"))
21484         enable = 0;
21485       else
21486         break;
21487     }
21488
21489   if (stream_name_set > 0)
21490     {
21491       if (vec_len (stream_name) > 255)
21492         {
21493           errmsg ("stream name too long");
21494           return -99;
21495         }
21496     }
21497
21498   u32 name_len = vec_len (stream_name);
21499   /* Construct the API message */
21500   M (PG_ENABLE_DISABLE, mp);
21501   mp->context = 0;
21502   mp->is_enabled = enable;
21503   if (stream_name_set != 0)
21504     {
21505       mp->stream_name_length = ntohl (name_len);
21506       clib_memcpy (mp->stream_name, stream_name, name_len);
21507     }
21508   vec_free (stream_name);
21509
21510   S (mp);
21511   W (ret);
21512   return ret;
21513 }
21514
21515 int
21516 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21517 {
21518   unformat_input_t *input = vam->input;
21519   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21520
21521   u16 *low_ports = 0;
21522   u16 *high_ports = 0;
21523   u16 this_low;
21524   u16 this_hi;
21525   ip4_address_t ip4_addr;
21526   ip6_address_t ip6_addr;
21527   u32 length;
21528   u32 tmp, tmp2;
21529   u8 prefix_set = 0;
21530   u32 vrf_id = ~0;
21531   u8 is_add = 1;
21532   u8 is_ipv6 = 0;
21533   int ret;
21534
21535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21536     {
21537       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21538         {
21539           prefix_set = 1;
21540         }
21541       else
21542         if (unformat
21543             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21544         {
21545           prefix_set = 1;
21546           is_ipv6 = 1;
21547         }
21548       else if (unformat (input, "vrf %d", &vrf_id))
21549         ;
21550       else if (unformat (input, "del"))
21551         is_add = 0;
21552       else if (unformat (input, "port %d", &tmp))
21553         {
21554           if (tmp == 0 || tmp > 65535)
21555             {
21556               errmsg ("port %d out of range", tmp);
21557               return -99;
21558             }
21559           this_low = tmp;
21560           this_hi = this_low + 1;
21561           vec_add1 (low_ports, this_low);
21562           vec_add1 (high_ports, this_hi);
21563         }
21564       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21565         {
21566           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21567             {
21568               errmsg ("incorrect range parameters");
21569               return -99;
21570             }
21571           this_low = tmp;
21572           /* Note: in debug CLI +1 is added to high before
21573              passing to real fn that does "the work"
21574              (ip_source_and_port_range_check_add_del).
21575              This fn is a wrapper around the binary API fn a
21576              control plane will call, which expects this increment
21577              to have occurred. Hence letting the binary API control
21578              plane fn do the increment for consistency between VAT
21579              and other control planes.
21580            */
21581           this_hi = tmp2;
21582           vec_add1 (low_ports, this_low);
21583           vec_add1 (high_ports, this_hi);
21584         }
21585       else
21586         break;
21587     }
21588
21589   if (prefix_set == 0)
21590     {
21591       errmsg ("<address>/<mask> not specified");
21592       return -99;
21593     }
21594
21595   if (vrf_id == ~0)
21596     {
21597       errmsg ("VRF ID required, not specified");
21598       return -99;
21599     }
21600
21601   if (vrf_id == 0)
21602     {
21603       errmsg
21604         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21605       return -99;
21606     }
21607
21608   if (vec_len (low_ports) == 0)
21609     {
21610       errmsg ("At least one port or port range required");
21611       return -99;
21612     }
21613
21614   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21615
21616   mp->is_add = is_add;
21617
21618   if (is_ipv6)
21619     {
21620       mp->is_ipv6 = 1;
21621       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21622     }
21623   else
21624     {
21625       mp->is_ipv6 = 0;
21626       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21627     }
21628
21629   mp->mask_length = length;
21630   mp->number_of_ranges = vec_len (low_ports);
21631
21632   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21633   vec_free (low_ports);
21634
21635   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21636   vec_free (high_ports);
21637
21638   mp->vrf_id = ntohl (vrf_id);
21639
21640   S (mp);
21641   W (ret);
21642   return ret;
21643 }
21644
21645 int
21646 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21647 {
21648   unformat_input_t *input = vam->input;
21649   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21650   u32 sw_if_index = ~0;
21651   int vrf_set = 0;
21652   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21653   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21654   u8 is_add = 1;
21655   int ret;
21656
21657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21658     {
21659       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21660         ;
21661       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21662         ;
21663       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21664         vrf_set = 1;
21665       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21666         vrf_set = 1;
21667       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21668         vrf_set = 1;
21669       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21670         vrf_set = 1;
21671       else if (unformat (input, "del"))
21672         is_add = 0;
21673       else
21674         break;
21675     }
21676
21677   if (sw_if_index == ~0)
21678     {
21679       errmsg ("Interface required but not specified");
21680       return -99;
21681     }
21682
21683   if (vrf_set == 0)
21684     {
21685       errmsg ("VRF ID required but not specified");
21686       return -99;
21687     }
21688
21689   if (tcp_out_vrf_id == 0
21690       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21691     {
21692       errmsg
21693         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21694       return -99;
21695     }
21696
21697   /* Construct the API message */
21698   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21699
21700   mp->sw_if_index = ntohl (sw_if_index);
21701   mp->is_add = is_add;
21702   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21703   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21704   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21705   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21706
21707   /* send it... */
21708   S (mp);
21709
21710   /* Wait for a reply... */
21711   W (ret);
21712   return ret;
21713 }
21714
21715 static int
21716 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21717 {
21718   unformat_input_t *i = vam->input;
21719   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21720   u32 local_sa_id = 0;
21721   u32 remote_sa_id = 0;
21722   ip4_address_t src_address;
21723   ip4_address_t dst_address;
21724   u8 is_add = 1;
21725   int ret;
21726
21727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21728     {
21729       if (unformat (i, "local_sa %d", &local_sa_id))
21730         ;
21731       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21732         ;
21733       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21734         ;
21735       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21736         ;
21737       else if (unformat (i, "del"))
21738         is_add = 0;
21739       else
21740         {
21741           clib_warning ("parse error '%U'", format_unformat_error, i);
21742           return -99;
21743         }
21744     }
21745
21746   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21747
21748   mp->local_sa_id = ntohl (local_sa_id);
21749   mp->remote_sa_id = ntohl (remote_sa_id);
21750   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21751   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21752   mp->is_add = is_add;
21753
21754   S (mp);
21755   W (ret);
21756   return ret;
21757 }
21758
21759 static int
21760 api_set_punt (vat_main_t * vam)
21761 {
21762   unformat_input_t *i = vam->input;
21763   vl_api_set_punt_t *mp;
21764   u32 ipv = ~0;
21765   u32 protocol = ~0;
21766   u32 port = ~0;
21767   int is_add = 1;
21768   int ret;
21769
21770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21771     {
21772       if (unformat (i, "ip %d", &ipv))
21773         ;
21774       else if (unformat (i, "protocol %d", &protocol))
21775         ;
21776       else if (unformat (i, "port %d", &port))
21777         ;
21778       else if (unformat (i, "del"))
21779         is_add = 0;
21780       else
21781         {
21782           clib_warning ("parse error '%U'", format_unformat_error, i);
21783           return -99;
21784         }
21785     }
21786
21787   M (SET_PUNT, mp);
21788
21789   mp->is_add = (u8) is_add;
21790   mp->punt.ipv = (u8) ipv;
21791   mp->punt.l4_protocol = (u8) protocol;
21792   mp->punt.l4_port = htons ((u16) port);
21793
21794   S (mp);
21795   W (ret);
21796   return ret;
21797 }
21798
21799 static void vl_api_ipsec_gre_tunnel_details_t_handler
21800   (vl_api_ipsec_gre_tunnel_details_t * mp)
21801 {
21802   vat_main_t *vam = &vat_main;
21803
21804   print (vam->ofp, "%11d%15U%15U%14d%14d",
21805          ntohl (mp->sw_if_index),
21806          format_ip4_address, &mp->src_address,
21807          format_ip4_address, &mp->dst_address,
21808          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21809 }
21810
21811 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21812   (vl_api_ipsec_gre_tunnel_details_t * mp)
21813 {
21814   vat_main_t *vam = &vat_main;
21815   vat_json_node_t *node = NULL;
21816   struct in_addr ip4;
21817
21818   if (VAT_JSON_ARRAY != vam->json_tree.type)
21819     {
21820       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21821       vat_json_init_array (&vam->json_tree);
21822     }
21823   node = vat_json_array_add (&vam->json_tree);
21824
21825   vat_json_init_object (node);
21826   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21827   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21828   vat_json_object_add_ip4 (node, "src_address", ip4);
21829   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21830   vat_json_object_add_ip4 (node, "dst_address", ip4);
21831   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21832   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21833 }
21834
21835 static int
21836 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21837 {
21838   unformat_input_t *i = vam->input;
21839   vl_api_ipsec_gre_tunnel_dump_t *mp;
21840   vl_api_control_ping_t *mp_ping;
21841   u32 sw_if_index;
21842   u8 sw_if_index_set = 0;
21843   int ret;
21844
21845   /* Parse args required to build the message */
21846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21847     {
21848       if (unformat (i, "sw_if_index %d", &sw_if_index))
21849         sw_if_index_set = 1;
21850       else
21851         break;
21852     }
21853
21854   if (sw_if_index_set == 0)
21855     {
21856       sw_if_index = ~0;
21857     }
21858
21859   if (!vam->json_output)
21860     {
21861       print (vam->ofp, "%11s%15s%15s%14s%14s",
21862              "sw_if_index", "src_address", "dst_address",
21863              "local_sa_id", "remote_sa_id");
21864     }
21865
21866   /* Get list of gre-tunnel interfaces */
21867   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21868
21869   mp->sw_if_index = htonl (sw_if_index);
21870
21871   S (mp);
21872
21873   /* Use a control ping for synchronization */
21874   MPING (CONTROL_PING, mp_ping);
21875   S (mp_ping);
21876
21877   W (ret);
21878   return ret;
21879 }
21880
21881 static int
21882 api_delete_subif (vat_main_t * vam)
21883 {
21884   unformat_input_t *i = vam->input;
21885   vl_api_delete_subif_t *mp;
21886   u32 sw_if_index = ~0;
21887   int ret;
21888
21889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21890     {
21891       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21892         ;
21893       if (unformat (i, "sw_if_index %d", &sw_if_index))
21894         ;
21895       else
21896         break;
21897     }
21898
21899   if (sw_if_index == ~0)
21900     {
21901       errmsg ("missing sw_if_index");
21902       return -99;
21903     }
21904
21905   /* Construct the API message */
21906   M (DELETE_SUBIF, mp);
21907   mp->sw_if_index = ntohl (sw_if_index);
21908
21909   S (mp);
21910   W (ret);
21911   return ret;
21912 }
21913
21914 #define foreach_pbb_vtr_op      \
21915 _("disable",  L2_VTR_DISABLED)  \
21916 _("pop",  L2_VTR_POP_2)         \
21917 _("push",  L2_VTR_PUSH_2)
21918
21919 static int
21920 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21921 {
21922   unformat_input_t *i = vam->input;
21923   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21924   u32 sw_if_index = ~0, vtr_op = ~0;
21925   u16 outer_tag = ~0;
21926   u8 dmac[6], smac[6];
21927   u8 dmac_set = 0, smac_set = 0;
21928   u16 vlanid = 0;
21929   u32 sid = ~0;
21930   u32 tmp;
21931   int ret;
21932
21933   /* Shut up coverity */
21934   clib_memset (dmac, 0, sizeof (dmac));
21935   clib_memset (smac, 0, sizeof (smac));
21936
21937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21938     {
21939       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21940         ;
21941       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21942         ;
21943       else if (unformat (i, "vtr_op %d", &vtr_op))
21944         ;
21945 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21946       foreach_pbb_vtr_op
21947 #undef _
21948         else if (unformat (i, "translate_pbb_stag"))
21949         {
21950           if (unformat (i, "%d", &tmp))
21951             {
21952               vtr_op = L2_VTR_TRANSLATE_2_1;
21953               outer_tag = tmp;
21954             }
21955           else
21956             {
21957               errmsg
21958                 ("translate_pbb_stag operation requires outer tag definition");
21959               return -99;
21960             }
21961         }
21962       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21963         dmac_set++;
21964       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21965         smac_set++;
21966       else if (unformat (i, "sid %d", &sid))
21967         ;
21968       else if (unformat (i, "vlanid %d", &tmp))
21969         vlanid = tmp;
21970       else
21971         {
21972           clib_warning ("parse error '%U'", format_unformat_error, i);
21973           return -99;
21974         }
21975     }
21976
21977   if ((sw_if_index == ~0) || (vtr_op == ~0))
21978     {
21979       errmsg ("missing sw_if_index or vtr operation");
21980       return -99;
21981     }
21982   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21983       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21984     {
21985       errmsg
21986         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21987       return -99;
21988     }
21989
21990   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21991   mp->sw_if_index = ntohl (sw_if_index);
21992   mp->vtr_op = ntohl (vtr_op);
21993   mp->outer_tag = ntohs (outer_tag);
21994   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21995   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21996   mp->b_vlanid = ntohs (vlanid);
21997   mp->i_sid = ntohl (sid);
21998
21999   S (mp);
22000   W (ret);
22001   return ret;
22002 }
22003
22004 static int
22005 api_flow_classify_set_interface (vat_main_t * vam)
22006 {
22007   unformat_input_t *i = vam->input;
22008   vl_api_flow_classify_set_interface_t *mp;
22009   u32 sw_if_index;
22010   int sw_if_index_set;
22011   u32 ip4_table_index = ~0;
22012   u32 ip6_table_index = ~0;
22013   u8 is_add = 1;
22014   int ret;
22015
22016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22017     {
22018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22019         sw_if_index_set = 1;
22020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22021         sw_if_index_set = 1;
22022       else if (unformat (i, "del"))
22023         is_add = 0;
22024       else if (unformat (i, "ip4-table %d", &ip4_table_index))
22025         ;
22026       else if (unformat (i, "ip6-table %d", &ip6_table_index))
22027         ;
22028       else
22029         {
22030           clib_warning ("parse error '%U'", format_unformat_error, i);
22031           return -99;
22032         }
22033     }
22034
22035   if (sw_if_index_set == 0)
22036     {
22037       errmsg ("missing interface name or sw_if_index");
22038       return -99;
22039     }
22040
22041   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
22042
22043   mp->sw_if_index = ntohl (sw_if_index);
22044   mp->ip4_table_index = ntohl (ip4_table_index);
22045   mp->ip6_table_index = ntohl (ip6_table_index);
22046   mp->is_add = is_add;
22047
22048   S (mp);
22049   W (ret);
22050   return ret;
22051 }
22052
22053 static int
22054 api_flow_classify_dump (vat_main_t * vam)
22055 {
22056   unformat_input_t *i = vam->input;
22057   vl_api_flow_classify_dump_t *mp;
22058   vl_api_control_ping_t *mp_ping;
22059   u8 type = FLOW_CLASSIFY_N_TABLES;
22060   int ret;
22061
22062   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
22063     ;
22064   else
22065     {
22066       errmsg ("classify table type must be specified");
22067       return -99;
22068     }
22069
22070   if (!vam->json_output)
22071     {
22072       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
22073     }
22074
22075   M (FLOW_CLASSIFY_DUMP, mp);
22076   mp->type = type;
22077   /* send it... */
22078   S (mp);
22079
22080   /* Use a control ping for synchronization */
22081   MPING (CONTROL_PING, mp_ping);
22082   S (mp_ping);
22083
22084   /* Wait for a reply... */
22085   W (ret);
22086   return ret;
22087 }
22088
22089 static int
22090 api_feature_enable_disable (vat_main_t * vam)
22091 {
22092   unformat_input_t *i = vam->input;
22093   vl_api_feature_enable_disable_t *mp;
22094   u8 *arc_name = 0;
22095   u8 *feature_name = 0;
22096   u32 sw_if_index = ~0;
22097   u8 enable = 1;
22098   int ret;
22099
22100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22101     {
22102       if (unformat (i, "arc_name %s", &arc_name))
22103         ;
22104       else if (unformat (i, "feature_name %s", &feature_name))
22105         ;
22106       else
22107         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22108         ;
22109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22110         ;
22111       else if (unformat (i, "disable"))
22112         enable = 0;
22113       else
22114         break;
22115     }
22116
22117   if (arc_name == 0)
22118     {
22119       errmsg ("missing arc name");
22120       return -99;
22121     }
22122   if (vec_len (arc_name) > 63)
22123     {
22124       errmsg ("arc name too long");
22125     }
22126
22127   if (feature_name == 0)
22128     {
22129       errmsg ("missing feature name");
22130       return -99;
22131     }
22132   if (vec_len (feature_name) > 63)
22133     {
22134       errmsg ("feature name too long");
22135     }
22136
22137   if (sw_if_index == ~0)
22138     {
22139       errmsg ("missing interface name or sw_if_index");
22140       return -99;
22141     }
22142
22143   /* Construct the API message */
22144   M (FEATURE_ENABLE_DISABLE, mp);
22145   mp->sw_if_index = ntohl (sw_if_index);
22146   mp->enable = enable;
22147   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22148   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22149   vec_free (arc_name);
22150   vec_free (feature_name);
22151
22152   S (mp);
22153   W (ret);
22154   return ret;
22155 }
22156
22157 static int
22158 api_sw_interface_tag_add_del (vat_main_t * vam)
22159 {
22160   unformat_input_t *i = vam->input;
22161   vl_api_sw_interface_tag_add_del_t *mp;
22162   u32 sw_if_index = ~0;
22163   u8 *tag = 0;
22164   u8 enable = 1;
22165   int ret;
22166
22167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22168     {
22169       if (unformat (i, "tag %s", &tag))
22170         ;
22171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22172         ;
22173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22174         ;
22175       else if (unformat (i, "del"))
22176         enable = 0;
22177       else
22178         break;
22179     }
22180
22181   if (sw_if_index == ~0)
22182     {
22183       errmsg ("missing interface name or sw_if_index");
22184       return -99;
22185     }
22186
22187   if (enable && (tag == 0))
22188     {
22189       errmsg ("no tag specified");
22190       return -99;
22191     }
22192
22193   /* Construct the API message */
22194   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22195   mp->sw_if_index = ntohl (sw_if_index);
22196   mp->is_add = enable;
22197   if (enable)
22198     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22199   vec_free (tag);
22200
22201   S (mp);
22202   W (ret);
22203   return ret;
22204 }
22205
22206 static void vl_api_l2_xconnect_details_t_handler
22207   (vl_api_l2_xconnect_details_t * mp)
22208 {
22209   vat_main_t *vam = &vat_main;
22210
22211   print (vam->ofp, "%15d%15d",
22212          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22213 }
22214
22215 static void vl_api_l2_xconnect_details_t_handler_json
22216   (vl_api_l2_xconnect_details_t * mp)
22217 {
22218   vat_main_t *vam = &vat_main;
22219   vat_json_node_t *node = NULL;
22220
22221   if (VAT_JSON_ARRAY != vam->json_tree.type)
22222     {
22223       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22224       vat_json_init_array (&vam->json_tree);
22225     }
22226   node = vat_json_array_add (&vam->json_tree);
22227
22228   vat_json_init_object (node);
22229   vat_json_object_add_uint (node, "rx_sw_if_index",
22230                             ntohl (mp->rx_sw_if_index));
22231   vat_json_object_add_uint (node, "tx_sw_if_index",
22232                             ntohl (mp->tx_sw_if_index));
22233 }
22234
22235 static int
22236 api_l2_xconnect_dump (vat_main_t * vam)
22237 {
22238   vl_api_l2_xconnect_dump_t *mp;
22239   vl_api_control_ping_t *mp_ping;
22240   int ret;
22241
22242   if (!vam->json_output)
22243     {
22244       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22245     }
22246
22247   M (L2_XCONNECT_DUMP, mp);
22248
22249   S (mp);
22250
22251   /* Use a control ping for synchronization */
22252   MPING (CONTROL_PING, mp_ping);
22253   S (mp_ping);
22254
22255   W (ret);
22256   return ret;
22257 }
22258
22259 static int
22260 api_hw_interface_set_mtu (vat_main_t * vam)
22261 {
22262   unformat_input_t *i = vam->input;
22263   vl_api_hw_interface_set_mtu_t *mp;
22264   u32 sw_if_index = ~0;
22265   u32 mtu = 0;
22266   int ret;
22267
22268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22269     {
22270       if (unformat (i, "mtu %d", &mtu))
22271         ;
22272       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22273         ;
22274       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22275         ;
22276       else
22277         break;
22278     }
22279
22280   if (sw_if_index == ~0)
22281     {
22282       errmsg ("missing interface name or sw_if_index");
22283       return -99;
22284     }
22285
22286   if (mtu == 0)
22287     {
22288       errmsg ("no mtu specified");
22289       return -99;
22290     }
22291
22292   /* Construct the API message */
22293   M (HW_INTERFACE_SET_MTU, mp);
22294   mp->sw_if_index = ntohl (sw_if_index);
22295   mp->mtu = ntohs ((u16) mtu);
22296
22297   S (mp);
22298   W (ret);
22299   return ret;
22300 }
22301
22302 static int
22303 api_p2p_ethernet_add (vat_main_t * vam)
22304 {
22305   unformat_input_t *i = vam->input;
22306   vl_api_p2p_ethernet_add_t *mp;
22307   u32 parent_if_index = ~0;
22308   u32 sub_id = ~0;
22309   u8 remote_mac[6];
22310   u8 mac_set = 0;
22311   int ret;
22312
22313   clib_memset (remote_mac, 0, sizeof (remote_mac));
22314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22315     {
22316       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22317         ;
22318       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22319         ;
22320       else
22321         if (unformat
22322             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22323         mac_set++;
22324       else if (unformat (i, "sub_id %d", &sub_id))
22325         ;
22326       else
22327         {
22328           clib_warning ("parse error '%U'", format_unformat_error, i);
22329           return -99;
22330         }
22331     }
22332
22333   if (parent_if_index == ~0)
22334     {
22335       errmsg ("missing interface name or sw_if_index");
22336       return -99;
22337     }
22338   if (mac_set == 0)
22339     {
22340       errmsg ("missing remote mac address");
22341       return -99;
22342     }
22343   if (sub_id == ~0)
22344     {
22345       errmsg ("missing sub-interface id");
22346       return -99;
22347     }
22348
22349   M (P2P_ETHERNET_ADD, mp);
22350   mp->parent_if_index = ntohl (parent_if_index);
22351   mp->subif_id = ntohl (sub_id);
22352   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22353
22354   S (mp);
22355   W (ret);
22356   return ret;
22357 }
22358
22359 static int
22360 api_p2p_ethernet_del (vat_main_t * vam)
22361 {
22362   unformat_input_t *i = vam->input;
22363   vl_api_p2p_ethernet_del_t *mp;
22364   u32 parent_if_index = ~0;
22365   u8 remote_mac[6];
22366   u8 mac_set = 0;
22367   int ret;
22368
22369   clib_memset (remote_mac, 0, sizeof (remote_mac));
22370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22371     {
22372       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22373         ;
22374       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22375         ;
22376       else
22377         if (unformat
22378             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22379         mac_set++;
22380       else
22381         {
22382           clib_warning ("parse error '%U'", format_unformat_error, i);
22383           return -99;
22384         }
22385     }
22386
22387   if (parent_if_index == ~0)
22388     {
22389       errmsg ("missing interface name or sw_if_index");
22390       return -99;
22391     }
22392   if (mac_set == 0)
22393     {
22394       errmsg ("missing remote mac address");
22395       return -99;
22396     }
22397
22398   M (P2P_ETHERNET_DEL, mp);
22399   mp->parent_if_index = ntohl (parent_if_index);
22400   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22401
22402   S (mp);
22403   W (ret);
22404   return ret;
22405 }
22406
22407 static int
22408 api_lldp_config (vat_main_t * vam)
22409 {
22410   unformat_input_t *i = vam->input;
22411   vl_api_lldp_config_t *mp;
22412   int tx_hold = 0;
22413   int tx_interval = 0;
22414   u8 *sys_name = NULL;
22415   int ret;
22416
22417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22418     {
22419       if (unformat (i, "system-name %s", &sys_name))
22420         ;
22421       else if (unformat (i, "tx-hold %d", &tx_hold))
22422         ;
22423       else if (unformat (i, "tx-interval %d", &tx_interval))
22424         ;
22425       else
22426         {
22427           clib_warning ("parse error '%U'", format_unformat_error, i);
22428           return -99;
22429         }
22430     }
22431
22432   vec_add1 (sys_name, 0);
22433
22434   M (LLDP_CONFIG, mp);
22435   mp->tx_hold = htonl (tx_hold);
22436   mp->tx_interval = htonl (tx_interval);
22437   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22438   vec_free (sys_name);
22439
22440   S (mp);
22441   W (ret);
22442   return ret;
22443 }
22444
22445 static int
22446 api_sw_interface_set_lldp (vat_main_t * vam)
22447 {
22448   unformat_input_t *i = vam->input;
22449   vl_api_sw_interface_set_lldp_t *mp;
22450   u32 sw_if_index = ~0;
22451   u32 enable = 1;
22452   u8 *port_desc = NULL, *mgmt_oid = NULL;
22453   ip4_address_t ip4_addr;
22454   ip6_address_t ip6_addr;
22455   int ret;
22456
22457   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
22458   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
22459
22460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22461     {
22462       if (unformat (i, "disable"))
22463         enable = 0;
22464       else
22465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22466         ;
22467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22468         ;
22469       else if (unformat (i, "port-desc %s", &port_desc))
22470         ;
22471       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22472         ;
22473       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22474         ;
22475       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22476         ;
22477       else
22478         break;
22479     }
22480
22481   if (sw_if_index == ~0)
22482     {
22483       errmsg ("missing interface name or sw_if_index");
22484       return -99;
22485     }
22486
22487   /* Construct the API message */
22488   vec_add1 (port_desc, 0);
22489   vec_add1 (mgmt_oid, 0);
22490   M (SW_INTERFACE_SET_LLDP, mp);
22491   mp->sw_if_index = ntohl (sw_if_index);
22492   mp->enable = enable;
22493   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22494   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22495   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22496   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22497   vec_free (port_desc);
22498   vec_free (mgmt_oid);
22499
22500   S (mp);
22501   W (ret);
22502   return ret;
22503 }
22504
22505 static int
22506 api_tcp_configure_src_addresses (vat_main_t * vam)
22507 {
22508   vl_api_tcp_configure_src_addresses_t *mp;
22509   unformat_input_t *i = vam->input;
22510   ip4_address_t v4first, v4last;
22511   ip6_address_t v6first, v6last;
22512   u8 range_set = 0;
22513   u32 vrf_id = 0;
22514   int ret;
22515
22516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22517     {
22518       if (unformat (i, "%U - %U",
22519                     unformat_ip4_address, &v4first,
22520                     unformat_ip4_address, &v4last))
22521         {
22522           if (range_set)
22523             {
22524               errmsg ("one range per message (range already set)");
22525               return -99;
22526             }
22527           range_set = 1;
22528         }
22529       else if (unformat (i, "%U - %U",
22530                          unformat_ip6_address, &v6first,
22531                          unformat_ip6_address, &v6last))
22532         {
22533           if (range_set)
22534             {
22535               errmsg ("one range per message (range already set)");
22536               return -99;
22537             }
22538           range_set = 2;
22539         }
22540       else if (unformat (i, "vrf %d", &vrf_id))
22541         ;
22542       else
22543         break;
22544     }
22545
22546   if (range_set == 0)
22547     {
22548       errmsg ("address range not set");
22549       return -99;
22550     }
22551
22552   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22553   mp->vrf_id = ntohl (vrf_id);
22554   /* ipv6? */
22555   if (range_set == 2)
22556     {
22557       mp->is_ipv6 = 1;
22558       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22559       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22560     }
22561   else
22562     {
22563       mp->is_ipv6 = 0;
22564       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22565       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22566     }
22567   S (mp);
22568   W (ret);
22569   return ret;
22570 }
22571
22572 static void vl_api_app_namespace_add_del_reply_t_handler
22573   (vl_api_app_namespace_add_del_reply_t * mp)
22574 {
22575   vat_main_t *vam = &vat_main;
22576   i32 retval = ntohl (mp->retval);
22577   if (vam->async_mode)
22578     {
22579       vam->async_errors += (retval < 0);
22580     }
22581   else
22582     {
22583       vam->retval = retval;
22584       if (retval == 0)
22585         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22586       vam->result_ready = 1;
22587     }
22588 }
22589
22590 static void vl_api_app_namespace_add_del_reply_t_handler_json
22591   (vl_api_app_namespace_add_del_reply_t * mp)
22592 {
22593   vat_main_t *vam = &vat_main;
22594   vat_json_node_t node;
22595
22596   vat_json_init_object (&node);
22597   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22598   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22599
22600   vat_json_print (vam->ofp, &node);
22601   vat_json_free (&node);
22602
22603   vam->retval = ntohl (mp->retval);
22604   vam->result_ready = 1;
22605 }
22606
22607 static int
22608 api_app_namespace_add_del (vat_main_t * vam)
22609 {
22610   vl_api_app_namespace_add_del_t *mp;
22611   unformat_input_t *i = vam->input;
22612   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22613   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22614   u64 secret;
22615   int ret;
22616
22617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22618     {
22619       if (unformat (i, "id %_%v%_", &ns_id))
22620         ;
22621       else if (unformat (i, "secret %lu", &secret))
22622         secret_set = 1;
22623       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22624         sw_if_index_set = 1;
22625       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22626         ;
22627       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22628         ;
22629       else
22630         break;
22631     }
22632   if (!ns_id || !secret_set || !sw_if_index_set)
22633     {
22634       errmsg ("namespace id, secret and sw_if_index must be set");
22635       return -99;
22636     }
22637   if (vec_len (ns_id) > 64)
22638     {
22639       errmsg ("namespace id too long");
22640       return -99;
22641     }
22642   M (APP_NAMESPACE_ADD_DEL, mp);
22643
22644   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22645   mp->namespace_id_len = vec_len (ns_id);
22646   mp->secret = clib_host_to_net_u64 (secret);
22647   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22648   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22649   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22650   vec_free (ns_id);
22651   S (mp);
22652   W (ret);
22653   return ret;
22654 }
22655
22656 static int
22657 api_sock_init_shm (vat_main_t * vam)
22658 {
22659 #if VPP_API_TEST_BUILTIN == 0
22660   unformat_input_t *i = vam->input;
22661   vl_api_shm_elem_config_t *config = 0;
22662   u64 size = 64 << 20;
22663   int rv;
22664
22665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22666     {
22667       if (unformat (i, "size %U", unformat_memory_size, &size))
22668         ;
22669       else
22670         break;
22671     }
22672
22673   /*
22674    * Canned custom ring allocator config.
22675    * Should probably parse all of this
22676    */
22677   vec_validate (config, 6);
22678   config[0].type = VL_API_VLIB_RING;
22679   config[0].size = 256;
22680   config[0].count = 32;
22681
22682   config[1].type = VL_API_VLIB_RING;
22683   config[1].size = 1024;
22684   config[1].count = 16;
22685
22686   config[2].type = VL_API_VLIB_RING;
22687   config[2].size = 4096;
22688   config[2].count = 2;
22689
22690   config[3].type = VL_API_CLIENT_RING;
22691   config[3].size = 256;
22692   config[3].count = 32;
22693
22694   config[4].type = VL_API_CLIENT_RING;
22695   config[4].size = 1024;
22696   config[4].count = 16;
22697
22698   config[5].type = VL_API_CLIENT_RING;
22699   config[5].size = 4096;
22700   config[5].count = 2;
22701
22702   config[6].type = VL_API_QUEUE;
22703   config[6].count = 128;
22704   config[6].size = sizeof (uword);
22705
22706   rv = vl_socket_client_init_shm (config);
22707   if (!rv)
22708     vam->client_index_invalid = 1;
22709   return rv;
22710 #else
22711   return -99;
22712 #endif
22713 }
22714
22715 static int
22716 api_dns_enable_disable (vat_main_t * vam)
22717 {
22718   unformat_input_t *line_input = vam->input;
22719   vl_api_dns_enable_disable_t *mp;
22720   u8 enable_disable = 1;
22721   int ret;
22722
22723   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22724     {
22725       if (unformat (line_input, "disable"))
22726         enable_disable = 0;
22727       if (unformat (line_input, "enable"))
22728         enable_disable = 1;
22729       else
22730         break;
22731     }
22732
22733   /* Construct the API message */
22734   M (DNS_ENABLE_DISABLE, mp);
22735   mp->enable = enable_disable;
22736
22737   /* send it... */
22738   S (mp);
22739   /* Wait for the reply */
22740   W (ret);
22741   return ret;
22742 }
22743
22744 static int
22745 api_dns_resolve_name (vat_main_t * vam)
22746 {
22747   unformat_input_t *line_input = vam->input;
22748   vl_api_dns_resolve_name_t *mp;
22749   u8 *name = 0;
22750   int ret;
22751
22752   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22753     {
22754       if (unformat (line_input, "%s", &name))
22755         ;
22756       else
22757         break;
22758     }
22759
22760   if (vec_len (name) > 127)
22761     {
22762       errmsg ("name too long");
22763       return -99;
22764     }
22765
22766   /* Construct the API message */
22767   M (DNS_RESOLVE_NAME, mp);
22768   memcpy (mp->name, name, vec_len (name));
22769   vec_free (name);
22770
22771   /* send it... */
22772   S (mp);
22773   /* Wait for the reply */
22774   W (ret);
22775   return ret;
22776 }
22777
22778 static int
22779 api_dns_resolve_ip (vat_main_t * vam)
22780 {
22781   unformat_input_t *line_input = vam->input;
22782   vl_api_dns_resolve_ip_t *mp;
22783   int is_ip6 = -1;
22784   ip4_address_t addr4;
22785   ip6_address_t addr6;
22786   int ret;
22787
22788   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22789     {
22790       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22791         is_ip6 = 1;
22792       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22793         is_ip6 = 0;
22794       else
22795         break;
22796     }
22797
22798   if (is_ip6 == -1)
22799     {
22800       errmsg ("missing address");
22801       return -99;
22802     }
22803
22804   /* Construct the API message */
22805   M (DNS_RESOLVE_IP, mp);
22806   mp->is_ip6 = is_ip6;
22807   if (is_ip6)
22808     memcpy (mp->address, &addr6, sizeof (addr6));
22809   else
22810     memcpy (mp->address, &addr4, sizeof (addr4));
22811
22812   /* send it... */
22813   S (mp);
22814   /* Wait for the reply */
22815   W (ret);
22816   return ret;
22817 }
22818
22819 static int
22820 api_dns_name_server_add_del (vat_main_t * vam)
22821 {
22822   unformat_input_t *i = vam->input;
22823   vl_api_dns_name_server_add_del_t *mp;
22824   u8 is_add = 1;
22825   ip6_address_t ip6_server;
22826   ip4_address_t ip4_server;
22827   int ip6_set = 0;
22828   int ip4_set = 0;
22829   int ret = 0;
22830
22831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22832     {
22833       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22834         ip6_set = 1;
22835       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22836         ip4_set = 1;
22837       else if (unformat (i, "del"))
22838         is_add = 0;
22839       else
22840         {
22841           clib_warning ("parse error '%U'", format_unformat_error, i);
22842           return -99;
22843         }
22844     }
22845
22846   if (ip4_set && ip6_set)
22847     {
22848       errmsg ("Only one server address allowed per message");
22849       return -99;
22850     }
22851   if ((ip4_set + ip6_set) == 0)
22852     {
22853       errmsg ("Server address required");
22854       return -99;
22855     }
22856
22857   /* Construct the API message */
22858   M (DNS_NAME_SERVER_ADD_DEL, mp);
22859
22860   if (ip6_set)
22861     {
22862       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22863       mp->is_ip6 = 1;
22864     }
22865   else
22866     {
22867       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22868       mp->is_ip6 = 0;
22869     }
22870
22871   mp->is_add = is_add;
22872
22873   /* send it... */
22874   S (mp);
22875
22876   /* Wait for a reply, return good/bad news  */
22877   W (ret);
22878   return ret;
22879 }
22880
22881 static void
22882 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22883 {
22884   vat_main_t *vam = &vat_main;
22885
22886   if (mp->is_ip4)
22887     {
22888       print (vam->ofp,
22889              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22890              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22891              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22892              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22893              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22894              clib_net_to_host_u32 (mp->action_index), mp->tag);
22895     }
22896   else
22897     {
22898       print (vam->ofp,
22899              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22900              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22901              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22902              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22903              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22904              clib_net_to_host_u32 (mp->action_index), mp->tag);
22905     }
22906 }
22907
22908 static void
22909 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22910                                              mp)
22911 {
22912   vat_main_t *vam = &vat_main;
22913   vat_json_node_t *node = NULL;
22914   struct in6_addr ip6;
22915   struct in_addr ip4;
22916
22917   if (VAT_JSON_ARRAY != vam->json_tree.type)
22918     {
22919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22920       vat_json_init_array (&vam->json_tree);
22921     }
22922   node = vat_json_array_add (&vam->json_tree);
22923   vat_json_init_object (node);
22924
22925   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22926   vat_json_object_add_uint (node, "appns_index",
22927                             clib_net_to_host_u32 (mp->appns_index));
22928   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22929   vat_json_object_add_uint (node, "scope", mp->scope);
22930   vat_json_object_add_uint (node, "action_index",
22931                             clib_net_to_host_u32 (mp->action_index));
22932   vat_json_object_add_uint (node, "lcl_port",
22933                             clib_net_to_host_u16 (mp->lcl_port));
22934   vat_json_object_add_uint (node, "rmt_port",
22935                             clib_net_to_host_u16 (mp->rmt_port));
22936   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22937   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22938   vat_json_object_add_string_copy (node, "tag", mp->tag);
22939   if (mp->is_ip4)
22940     {
22941       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22942       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22943       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22944       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22945     }
22946   else
22947     {
22948       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22949       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22950       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22951       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22952     }
22953 }
22954
22955 static int
22956 api_session_rule_add_del (vat_main_t * vam)
22957 {
22958   vl_api_session_rule_add_del_t *mp;
22959   unformat_input_t *i = vam->input;
22960   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22961   u32 appns_index = 0, scope = 0;
22962   ip4_address_t lcl_ip4, rmt_ip4;
22963   ip6_address_t lcl_ip6, rmt_ip6;
22964   u8 is_ip4 = 1, conn_set = 0;
22965   u8 is_add = 1, *tag = 0;
22966   int ret;
22967
22968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22969     {
22970       if (unformat (i, "del"))
22971         is_add = 0;
22972       else if (unformat (i, "add"))
22973         ;
22974       else if (unformat (i, "proto tcp"))
22975         proto = 0;
22976       else if (unformat (i, "proto udp"))
22977         proto = 1;
22978       else if (unformat (i, "appns %d", &appns_index))
22979         ;
22980       else if (unformat (i, "scope %d", &scope))
22981         ;
22982       else if (unformat (i, "tag %_%v%_", &tag))
22983         ;
22984       else
22985         if (unformat
22986             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22987              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22988              &rmt_port))
22989         {
22990           is_ip4 = 1;
22991           conn_set = 1;
22992         }
22993       else
22994         if (unformat
22995             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22996              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22997              &rmt_port))
22998         {
22999           is_ip4 = 0;
23000           conn_set = 1;
23001         }
23002       else if (unformat (i, "action %d", &action))
23003         ;
23004       else
23005         break;
23006     }
23007   if (proto == ~0 || !conn_set || action == ~0)
23008     {
23009       errmsg ("transport proto, connection and action must be set");
23010       return -99;
23011     }
23012
23013   if (scope > 3)
23014     {
23015       errmsg ("scope should be 0-3");
23016       return -99;
23017     }
23018
23019   M (SESSION_RULE_ADD_DEL, mp);
23020
23021   mp->is_ip4 = is_ip4;
23022   mp->transport_proto = proto;
23023   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
23024   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
23025   mp->lcl_plen = lcl_plen;
23026   mp->rmt_plen = rmt_plen;
23027   mp->action_index = clib_host_to_net_u32 (action);
23028   mp->appns_index = clib_host_to_net_u32 (appns_index);
23029   mp->scope = scope;
23030   mp->is_add = is_add;
23031   if (is_ip4)
23032     {
23033       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
23034       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
23035     }
23036   else
23037     {
23038       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23039       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23040     }
23041   if (tag)
23042     {
23043       clib_memcpy (mp->tag, tag, vec_len (tag));
23044       vec_free (tag);
23045     }
23046
23047   S (mp);
23048   W (ret);
23049   return ret;
23050 }
23051
23052 static int
23053 api_session_rules_dump (vat_main_t * vam)
23054 {
23055   vl_api_session_rules_dump_t *mp;
23056   vl_api_control_ping_t *mp_ping;
23057   int ret;
23058
23059   if (!vam->json_output)
23060     {
23061       print (vam->ofp, "%=20s", "Session Rules");
23062     }
23063
23064   M (SESSION_RULES_DUMP, mp);
23065   /* send it... */
23066   S (mp);
23067
23068   /* Use a control ping for synchronization */
23069   MPING (CONTROL_PING, mp_ping);
23070   S (mp_ping);
23071
23072   /* Wait for a reply... */
23073   W (ret);
23074   return ret;
23075 }
23076
23077 static int
23078 api_ip_container_proxy_add_del (vat_main_t * vam)
23079 {
23080   vl_api_ip_container_proxy_add_del_t *mp;
23081   unformat_input_t *i = vam->input;
23082   u32 plen = ~0, sw_if_index = ~0;
23083   ip4_address_t ip4;
23084   ip6_address_t ip6;
23085   u8 is_ip4 = 1;
23086   u8 is_add = 1;
23087   int ret;
23088
23089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23090     {
23091       if (unformat (i, "del"))
23092         is_add = 0;
23093       else if (unformat (i, "add"))
23094         ;
23095       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23096         {
23097           is_ip4 = 1;
23098           plen = 32;
23099         }
23100       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23101         {
23102           is_ip4 = 0;
23103           plen = 128;
23104         }
23105       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23106         ;
23107       else
23108         break;
23109     }
23110   if (sw_if_index == ~0 || plen == ~0)
23111     {
23112       errmsg ("address and sw_if_index must be set");
23113       return -99;
23114     }
23115
23116   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23117
23118   mp->is_ip4 = is_ip4;
23119   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23120   mp->plen = plen;
23121   mp->is_add = is_add;
23122   if (is_ip4)
23123     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23124   else
23125     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23126
23127   S (mp);
23128   W (ret);
23129   return ret;
23130 }
23131
23132 static int
23133 api_qos_record_enable_disable (vat_main_t * vam)
23134 {
23135   unformat_input_t *i = vam->input;
23136   vl_api_qos_record_enable_disable_t *mp;
23137   u32 sw_if_index, qs = 0xff;
23138   u8 sw_if_index_set = 0;
23139   u8 enable = 1;
23140   int ret;
23141
23142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23143     {
23144       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23145         sw_if_index_set = 1;
23146       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23147         sw_if_index_set = 1;
23148       else if (unformat (i, "%U", unformat_qos_source, &qs))
23149         ;
23150       else if (unformat (i, "disable"))
23151         enable = 0;
23152       else
23153         {
23154           clib_warning ("parse error '%U'", format_unformat_error, i);
23155           return -99;
23156         }
23157     }
23158
23159   if (sw_if_index_set == 0)
23160     {
23161       errmsg ("missing interface name or sw_if_index");
23162       return -99;
23163     }
23164   if (qs == 0xff)
23165     {
23166       errmsg ("input location must be specified");
23167       return -99;
23168     }
23169
23170   M (QOS_RECORD_ENABLE_DISABLE, mp);
23171
23172   mp->sw_if_index = ntohl (sw_if_index);
23173   mp->input_source = qs;
23174   mp->enable = enable;
23175
23176   S (mp);
23177   W (ret);
23178   return ret;
23179 }
23180
23181
23182 static int
23183 q_or_quit (vat_main_t * vam)
23184 {
23185 #if VPP_API_TEST_BUILTIN == 0
23186   longjmp (vam->jump_buf, 1);
23187 #endif
23188   return 0;                     /* not so much */
23189 }
23190
23191 static int
23192 q (vat_main_t * vam)
23193 {
23194   return q_or_quit (vam);
23195 }
23196
23197 static int
23198 quit (vat_main_t * vam)
23199 {
23200   return q_or_quit (vam);
23201 }
23202
23203 static int
23204 comment (vat_main_t * vam)
23205 {
23206   return 0;
23207 }
23208
23209 static int
23210 statseg (vat_main_t * vam)
23211 {
23212   ssvm_private_t *ssvmp = &vam->stat_segment;
23213   ssvm_shared_header_t *shared_header = ssvmp->sh;
23214   vlib_counter_t **counters;
23215   u64 thread0_index1_packets;
23216   u64 thread0_index1_bytes;
23217   f64 vector_rate, input_rate;
23218   uword *p;
23219
23220   uword *counter_vector_by_name;
23221   if (vam->stat_segment_lockp == 0)
23222     {
23223       errmsg ("Stat segment not mapped...");
23224       return -99;
23225     }
23226
23227   /* look up "/if/rx for sw_if_index 1 as a test */
23228
23229   clib_spinlock_lock (vam->stat_segment_lockp);
23230
23231   counter_vector_by_name = (uword *) shared_header->opaque[1];
23232
23233   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23234   if (p == 0)
23235     {
23236       clib_spinlock_unlock (vam->stat_segment_lockp);
23237       errmsg ("/if/tx not found?");
23238       return -99;
23239     }
23240
23241   /* Fish per-thread vector of combined counters from shared memory */
23242   counters = (vlib_counter_t **) p[0];
23243
23244   if (vec_len (counters[0]) < 2)
23245     {
23246       clib_spinlock_unlock (vam->stat_segment_lockp);
23247       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23248       return -99;
23249     }
23250
23251   /* Read thread 0 sw_if_index 1 counter */
23252   thread0_index1_packets = counters[0][1].packets;
23253   thread0_index1_bytes = counters[0][1].bytes;
23254
23255   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23256   if (p == 0)
23257     {
23258       clib_spinlock_unlock (vam->stat_segment_lockp);
23259       errmsg ("vector_rate not found?");
23260       return -99;
23261     }
23262
23263   vector_rate = *(f64 *) (p[0]);
23264   p = hash_get_mem (counter_vector_by_name, "input_rate");
23265   if (p == 0)
23266     {
23267       clib_spinlock_unlock (vam->stat_segment_lockp);
23268       errmsg ("input_rate not found?");
23269       return -99;
23270     }
23271   input_rate = *(f64 *) (p[0]);
23272
23273   clib_spinlock_unlock (vam->stat_segment_lockp);
23274
23275   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23276          vector_rate, input_rate);
23277   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23278          thread0_index1_packets, thread0_index1_bytes);
23279
23280   return 0;
23281 }
23282
23283 static int
23284 cmd_cmp (void *a1, void *a2)
23285 {
23286   u8 **c1 = a1;
23287   u8 **c2 = a2;
23288
23289   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23290 }
23291
23292 static int
23293 help (vat_main_t * vam)
23294 {
23295   u8 **cmds = 0;
23296   u8 *name = 0;
23297   hash_pair_t *p;
23298   unformat_input_t *i = vam->input;
23299   int j;
23300
23301   if (unformat (i, "%s", &name))
23302     {
23303       uword *hs;
23304
23305       vec_add1 (name, 0);
23306
23307       hs = hash_get_mem (vam->help_by_name, name);
23308       if (hs)
23309         print (vam->ofp, "usage: %s %s", name, hs[0]);
23310       else
23311         print (vam->ofp, "No such msg / command '%s'", name);
23312       vec_free (name);
23313       return 0;
23314     }
23315
23316   print (vam->ofp, "Help is available for the following:");
23317
23318     /* *INDENT-OFF* */
23319     hash_foreach_pair (p, vam->function_by_name,
23320     ({
23321       vec_add1 (cmds, (u8 *)(p->key));
23322     }));
23323     /* *INDENT-ON* */
23324
23325   vec_sort_with_function (cmds, cmd_cmp);
23326
23327   for (j = 0; j < vec_len (cmds); j++)
23328     print (vam->ofp, "%s", cmds[j]);
23329
23330   vec_free (cmds);
23331   return 0;
23332 }
23333
23334 static int
23335 set (vat_main_t * vam)
23336 {
23337   u8 *name = 0, *value = 0;
23338   unformat_input_t *i = vam->input;
23339
23340   if (unformat (i, "%s", &name))
23341     {
23342       /* The input buffer is a vector, not a string. */
23343       value = vec_dup (i->buffer);
23344       vec_delete (value, i->index, 0);
23345       /* Almost certainly has a trailing newline */
23346       if (value[vec_len (value) - 1] == '\n')
23347         value[vec_len (value) - 1] = 0;
23348       /* Make sure it's a proper string, one way or the other */
23349       vec_add1 (value, 0);
23350       (void) clib_macro_set_value (&vam->macro_main,
23351                                    (char *) name, (char *) value);
23352     }
23353   else
23354     errmsg ("usage: set <name> <value>");
23355
23356   vec_free (name);
23357   vec_free (value);
23358   return 0;
23359 }
23360
23361 static int
23362 unset (vat_main_t * vam)
23363 {
23364   u8 *name = 0;
23365
23366   if (unformat (vam->input, "%s", &name))
23367     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23368       errmsg ("unset: %s wasn't set", name);
23369   vec_free (name);
23370   return 0;
23371 }
23372
23373 typedef struct
23374 {
23375   u8 *name;
23376   u8 *value;
23377 } macro_sort_t;
23378
23379
23380 static int
23381 macro_sort_cmp (void *a1, void *a2)
23382 {
23383   macro_sort_t *s1 = a1;
23384   macro_sort_t *s2 = a2;
23385
23386   return strcmp ((char *) (s1->name), (char *) (s2->name));
23387 }
23388
23389 static int
23390 dump_macro_table (vat_main_t * vam)
23391 {
23392   macro_sort_t *sort_me = 0, *sm;
23393   int i;
23394   hash_pair_t *p;
23395
23396     /* *INDENT-OFF* */
23397     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23398     ({
23399       vec_add2 (sort_me, sm, 1);
23400       sm->name = (u8 *)(p->key);
23401       sm->value = (u8 *) (p->value[0]);
23402     }));
23403     /* *INDENT-ON* */
23404
23405   vec_sort_with_function (sort_me, macro_sort_cmp);
23406
23407   if (vec_len (sort_me))
23408     print (vam->ofp, "%-15s%s", "Name", "Value");
23409   else
23410     print (vam->ofp, "The macro table is empty...");
23411
23412   for (i = 0; i < vec_len (sort_me); i++)
23413     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23414   return 0;
23415 }
23416
23417 static int
23418 dump_node_table (vat_main_t * vam)
23419 {
23420   int i, j;
23421   vlib_node_t *node, *next_node;
23422
23423   if (vec_len (vam->graph_nodes) == 0)
23424     {
23425       print (vam->ofp, "Node table empty, issue get_node_graph...");
23426       return 0;
23427     }
23428
23429   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23430     {
23431       node = vam->graph_nodes[0][i];
23432       print (vam->ofp, "[%d] %s", i, node->name);
23433       for (j = 0; j < vec_len (node->next_nodes); j++)
23434         {
23435           if (node->next_nodes[j] != ~0)
23436             {
23437               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23438               print (vam->ofp, "  [%d] %s", j, next_node->name);
23439             }
23440         }
23441     }
23442   return 0;
23443 }
23444
23445 static int
23446 value_sort_cmp (void *a1, void *a2)
23447 {
23448   name_sort_t *n1 = a1;
23449   name_sort_t *n2 = a2;
23450
23451   if (n1->value < n2->value)
23452     return -1;
23453   if (n1->value > n2->value)
23454     return 1;
23455   return 0;
23456 }
23457
23458
23459 static int
23460 dump_msg_api_table (vat_main_t * vam)
23461 {
23462   api_main_t *am = &api_main;
23463   name_sort_t *nses = 0, *ns;
23464   hash_pair_t *hp;
23465   int i;
23466
23467   /* *INDENT-OFF* */
23468   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23469   ({
23470     vec_add2 (nses, ns, 1);
23471     ns->name = (u8 *)(hp->key);
23472     ns->value = (u32) hp->value[0];
23473   }));
23474   /* *INDENT-ON* */
23475
23476   vec_sort_with_function (nses, value_sort_cmp);
23477
23478   for (i = 0; i < vec_len (nses); i++)
23479     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23480   vec_free (nses);
23481   return 0;
23482 }
23483
23484 static int
23485 get_msg_id (vat_main_t * vam)
23486 {
23487   u8 *name_and_crc;
23488   u32 message_index;
23489
23490   if (unformat (vam->input, "%s", &name_and_crc))
23491     {
23492       message_index = vl_msg_api_get_msg_index (name_and_crc);
23493       if (message_index == ~0)
23494         {
23495           print (vam->ofp, " '%s' not found", name_and_crc);
23496           return 0;
23497         }
23498       print (vam->ofp, " '%s' has message index %d",
23499              name_and_crc, message_index);
23500       return 0;
23501     }
23502   errmsg ("name_and_crc required...");
23503   return 0;
23504 }
23505
23506 static int
23507 search_node_table (vat_main_t * vam)
23508 {
23509   unformat_input_t *line_input = vam->input;
23510   u8 *node_to_find;
23511   int j;
23512   vlib_node_t *node, *next_node;
23513   uword *p;
23514
23515   if (vam->graph_node_index_by_name == 0)
23516     {
23517       print (vam->ofp, "Node table empty, issue get_node_graph...");
23518       return 0;
23519     }
23520
23521   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23522     {
23523       if (unformat (line_input, "%s", &node_to_find))
23524         {
23525           vec_add1 (node_to_find, 0);
23526           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23527           if (p == 0)
23528             {
23529               print (vam->ofp, "%s not found...", node_to_find);
23530               goto out;
23531             }
23532           node = vam->graph_nodes[0][p[0]];
23533           print (vam->ofp, "[%d] %s", p[0], node->name);
23534           for (j = 0; j < vec_len (node->next_nodes); j++)
23535             {
23536               if (node->next_nodes[j] != ~0)
23537                 {
23538                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23539                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23540                 }
23541             }
23542         }
23543
23544       else
23545         {
23546           clib_warning ("parse error '%U'", format_unformat_error,
23547                         line_input);
23548           return -99;
23549         }
23550
23551     out:
23552       vec_free (node_to_find);
23553
23554     }
23555
23556   return 0;
23557 }
23558
23559
23560 static int
23561 script (vat_main_t * vam)
23562 {
23563 #if (VPP_API_TEST_BUILTIN==0)
23564   u8 *s = 0;
23565   char *save_current_file;
23566   unformat_input_t save_input;
23567   jmp_buf save_jump_buf;
23568   u32 save_line_number;
23569
23570   FILE *new_fp, *save_ifp;
23571
23572   if (unformat (vam->input, "%s", &s))
23573     {
23574       new_fp = fopen ((char *) s, "r");
23575       if (new_fp == 0)
23576         {
23577           errmsg ("Couldn't open script file %s", s);
23578           vec_free (s);
23579           return -99;
23580         }
23581     }
23582   else
23583     {
23584       errmsg ("Missing script name");
23585       return -99;
23586     }
23587
23588   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23589   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23590   save_ifp = vam->ifp;
23591   save_line_number = vam->input_line_number;
23592   save_current_file = (char *) vam->current_file;
23593
23594   vam->input_line_number = 0;
23595   vam->ifp = new_fp;
23596   vam->current_file = s;
23597   do_one_file (vam);
23598
23599   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23600   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23601   vam->ifp = save_ifp;
23602   vam->input_line_number = save_line_number;
23603   vam->current_file = (u8 *) save_current_file;
23604   vec_free (s);
23605
23606   return 0;
23607 #else
23608   clib_warning ("use the exec command...");
23609   return -99;
23610 #endif
23611 }
23612
23613 static int
23614 echo (vat_main_t * vam)
23615 {
23616   print (vam->ofp, "%v", vam->input->buffer);
23617   return 0;
23618 }
23619
23620 /* List of API message constructors, CLI names map to api_xxx */
23621 #define foreach_vpe_api_msg                                             \
23622 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23623 _(sw_interface_dump,"")                                                 \
23624 _(sw_interface_set_flags,                                               \
23625   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23626 _(sw_interface_add_del_address,                                         \
23627   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23628 _(sw_interface_set_rx_mode,                                             \
23629   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23630 _(sw_interface_set_rx_placement,                                        \
23631   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23632 _(sw_interface_rx_placement_dump,                                       \
23633   "[<intfc> | sw_if_index <id>]")                                         \
23634 _(sw_interface_set_table,                                               \
23635   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23636 _(sw_interface_set_mpls_enable,                                         \
23637   "<intfc> | sw_if_index [disable | dis]")                              \
23638 _(sw_interface_set_vpath,                                               \
23639   "<intfc> | sw_if_index <id> enable | disable")                        \
23640 _(sw_interface_set_vxlan_bypass,                                        \
23641   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23642 _(sw_interface_set_geneve_bypass,                                       \
23643   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23644 _(sw_interface_set_l2_xconnect,                                         \
23645   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23646   "enable | disable")                                                   \
23647 _(sw_interface_set_l2_bridge,                                           \
23648   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23649   "[shg <split-horizon-group>] [bvi]\n"                                 \
23650   "enable | disable")                                                   \
23651 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23652 _(bridge_domain_add_del,                                                \
23653   "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") \
23654 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23655 _(l2fib_add_del,                                                        \
23656   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23657 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23658 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23659 _(l2_flags,                                                             \
23660   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23661 _(bridge_flags,                                                         \
23662   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23663 _(tap_connect,                                                          \
23664   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23665 _(tap_modify,                                                           \
23666   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23667 _(tap_delete,                                                           \
23668   "<vpp-if-name> | sw_if_index <id>")                                   \
23669 _(sw_interface_tap_dump, "")                                            \
23670 _(tap_create_v2,                                                        \
23671   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23672 _(tap_delete_v2,                                                        \
23673   "<vpp-if-name> | sw_if_index <id>")                                   \
23674 _(sw_interface_tap_v2_dump, "")                                         \
23675 _(bond_create,                                                          \
23676   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23677   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23678 _(bond_delete,                                                          \
23679   "<vpp-if-name> | sw_if_index <id>")                                   \
23680 _(bond_enslave,                                                         \
23681   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23682 _(bond_detach_slave,                                                    \
23683   "sw_if_index <n>")                                                    \
23684 _(sw_interface_bond_dump, "")                                           \
23685 _(sw_interface_slave_dump,                                              \
23686   "<vpp-if-name> | sw_if_index <id>")                                   \
23687 _(ip_table_add_del,                                                     \
23688   "table <n> [ipv6] [add | del]\n")                                     \
23689 _(ip_add_del_route,                                                     \
23690   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23691   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23692   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23693   "[multipath] [count <n>] [del]")                                      \
23694 _(ip_mroute_add_del,                                                    \
23695   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23696   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23697 _(mpls_table_add_del,                                                   \
23698   "table <n> [add | del]\n")                                            \
23699 _(mpls_route_add_del,                                                   \
23700   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23701   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23702   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23703   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23704   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23705   "[count <n>] [del]")                                                  \
23706 _(mpls_ip_bind_unbind,                                                  \
23707   "<label> <addr/len>")                                                 \
23708 _(mpls_tunnel_add_del,                                                  \
23709   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23710   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23711   "[l2-only]  [out-label <n>]")                                         \
23712 _(sr_mpls_policy_add,                                                   \
23713   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23714 _(sr_mpls_policy_del,                                                   \
23715   "bsid <id>")                                                          \
23716 _(bier_table_add_del,                                                   \
23717   "<label> <sub-domain> <set> <bsl> [del]")                             \
23718 _(bier_route_add_del,                                                   \
23719   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23720   "[<intfc> | sw_if_index <id>]"                                        \
23721   "[weight <n>] [del] [multipath]")                                     \
23722 _(proxy_arp_add_del,                                                    \
23723   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23724 _(proxy_arp_intfc_enable_disable,                                       \
23725   "<intfc> | sw_if_index <id> enable | disable")                        \
23726 _(sw_interface_set_unnumbered,                                          \
23727   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23728 _(ip_neighbor_add_del,                                                  \
23729   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23730   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23731 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23732 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23733   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23734   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23735   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23736 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23737 _(reset_fib, "vrf <n> [ipv6]")                                          \
23738 _(dhcp_proxy_config,                                                    \
23739   "svr <v46-address> src <v46-address>\n"                               \
23740    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23741 _(dhcp_proxy_set_vss,                                                   \
23742   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23743 _(dhcp_proxy_dump, "ip6")                                               \
23744 _(dhcp_client_config,                                                   \
23745   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23746 _(set_ip_flow_hash,                                                     \
23747   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23748 _(sw_interface_ip6_enable_disable,                                      \
23749   "<intfc> | sw_if_index <id> enable | disable")                        \
23750 _(ip6nd_proxy_add_del,                                                  \
23751   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23752 _(ip6nd_proxy_dump, "")                                                 \
23753 _(sw_interface_ip6nd_ra_prefix,                                         \
23754   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23755   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23756   "[nolink] [isno]")                                                    \
23757 _(sw_interface_ip6nd_ra_config,                                         \
23758   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23759   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23760   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23761 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23762 _(l2_patch_add_del,                                                     \
23763   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23764   "enable | disable")                                                   \
23765 _(sr_localsid_add_del,                                                  \
23766   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23767   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23768 _(classify_add_del_table,                                               \
23769   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23770   " [del] [del-chain] mask <mask-value>\n"                              \
23771   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23772   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23773 _(classify_add_del_session,                                             \
23774   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23775   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23776   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23777   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23778 _(classify_set_interface_ip_table,                                      \
23779   "<intfc> | sw_if_index <nn> table <nn>")                              \
23780 _(classify_set_interface_l2_tables,                                     \
23781   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23782   "  [other-table <nn>]")                                               \
23783 _(get_node_index, "node <node-name")                                    \
23784 _(add_node_next, "node <node-name> next <next-node-name>")              \
23785 _(l2tpv3_create_tunnel,                                                 \
23786   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23787   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23788   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23789 _(l2tpv3_set_tunnel_cookies,                                            \
23790   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23791   "[new_remote_cookie <nn>]\n")                                         \
23792 _(l2tpv3_interface_enable_disable,                                      \
23793   "<intfc> | sw_if_index <nn> enable | disable")                        \
23794 _(l2tpv3_set_lookup_key,                                                \
23795   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23796 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23797 _(vxlan_offload_rx,                                                     \
23798   "hw { <interface name> | hw_if_index <nn>} "                          \
23799   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23800 _(vxlan_add_del_tunnel,                                                 \
23801   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23802   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23803   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23804 _(geneve_add_del_tunnel,                                                \
23805   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23806   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23807   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23808 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23809 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23810 _(gre_add_del_tunnel,                                                   \
23811   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23812   "[teb | erspan <session-id>] [del]")                                  \
23813 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23814 _(l2_fib_clear_table, "")                                               \
23815 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23816 _(l2_interface_vlan_tag_rewrite,                                        \
23817   "<intfc> | sw_if_index <nn> \n"                                       \
23818   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23819   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23820 _(create_vhost_user_if,                                                 \
23821         "socket <filename> [server] [renumber <dev_instance>] "         \
23822         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23823         "[mac <mac_address>]")                                          \
23824 _(modify_vhost_user_if,                                                 \
23825         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23826         "[server] [renumber <dev_instance>]")                           \
23827 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23828 _(sw_interface_vhost_user_dump, "")                                     \
23829 _(show_version, "")                                                     \
23830 _(show_threads, "")                                                     \
23831 _(vxlan_gpe_add_del_tunnel,                                             \
23832   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23833   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23834   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23835   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23836 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23837 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23838 _(interface_name_renumber,                                              \
23839   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23840 _(input_acl_set_interface,                                              \
23841   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23842   "  [l2-table <nn>] [del]")                                            \
23843 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23844 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23845   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23846 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23847 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23848 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23849 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23850 _(ip_dump, "ipv4 | ipv6")                                               \
23851 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23852 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23853   "  spid_id <n> ")                                                     \
23854 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23855   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23856   "  integ_alg <alg> integ_key <hex>")                                  \
23857 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23858   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23859   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23860   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23861 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23862 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23863   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23864   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23865   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23866   "  [instance <n>]")     \
23867 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23868 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23869   "  <alg> <hex>\n")                                                    \
23870 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23871 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23872 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23873   "(auth_data 0x<data> | auth_data <data>)")                            \
23874 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23875   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23876 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23877   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23878   "(local|remote)")                                                     \
23879 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23880 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23881 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23882 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23883 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23884 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23885 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23886 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23887 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23888 _(delete_loopback,"sw_if_index <nn>")                                   \
23889 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23890 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23891 _(want_interface_events,  "enable|disable")                             \
23892 _(want_stats,"enable|disable")                                          \
23893 _(get_first_msg_id, "client <name>")                                    \
23894 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23895 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23896   "fib-id <nn> [ip4][ip6][default]")                                    \
23897 _(get_node_graph, " ")                                                  \
23898 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23899 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23900 _(ioam_disable, "")                                                     \
23901 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23902                             " sw_if_index <sw_if_index> p <priority> "  \
23903                             "w <weight>] [del]")                        \
23904 _(one_add_del_locator, "locator-set <locator_name> "                    \
23905                         "iface <intf> | sw_if_index <sw_if_index> "     \
23906                         "p <priority> w <weight> [del]")                \
23907 _(one_add_del_local_eid,"vni <vni> eid "                                \
23908                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23909                          "locator-set <locator_name> [del]"             \
23910                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23911 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23912 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23913 _(one_enable_disable, "enable|disable")                                 \
23914 _(one_map_register_enable_disable, "enable|disable")                    \
23915 _(one_map_register_fallback_threshold, "<value>")                       \
23916 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23917 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23918                                "[seid <seid>] "                         \
23919                                "rloc <locator> p <prio> "               \
23920                                "w <weight> [rloc <loc> ... ] "          \
23921                                "action <action> [del-all]")             \
23922 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23923                           "<local-eid>")                                \
23924 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23925 _(one_use_petr, "ip-address> | disable")                                \
23926 _(one_map_request_mode, "src-dst|dst-only")                             \
23927 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23928 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23929 _(one_locator_set_dump, "[local | remote]")                             \
23930 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23931 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23932                        "[local] | [remote]")                            \
23933 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23934 _(one_ndp_bd_get, "")                                                   \
23935 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23936 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23937 _(one_l2_arp_bd_get, "")                                                \
23938 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23939 _(one_stats_enable_disable, "enable|disable")                           \
23940 _(show_one_stats_enable_disable, "")                                    \
23941 _(one_eid_table_vni_dump, "")                                           \
23942 _(one_eid_table_map_dump, "l2|l3")                                      \
23943 _(one_map_resolver_dump, "")                                            \
23944 _(one_map_server_dump, "")                                              \
23945 _(one_adjacencies_get, "vni <vni>")                                     \
23946 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23947 _(show_one_rloc_probe_state, "")                                        \
23948 _(show_one_map_register_state, "")                                      \
23949 _(show_one_status, "")                                                  \
23950 _(one_stats_dump, "")                                                   \
23951 _(one_stats_flush, "")                                                  \
23952 _(one_get_map_request_itr_rlocs, "")                                    \
23953 _(one_map_register_set_ttl, "<ttl>")                                    \
23954 _(one_set_transport_protocol, "udp|api")                                \
23955 _(one_get_transport_protocol, "")                                       \
23956 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23957 _(one_show_xtr_mode, "")                                                \
23958 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23959 _(one_show_pitr_mode, "")                                               \
23960 _(one_enable_disable_petr_mode, "enable|disable")                       \
23961 _(one_show_petr_mode, "")                                               \
23962 _(show_one_nsh_mapping, "")                                             \
23963 _(show_one_pitr, "")                                                    \
23964 _(show_one_use_petr, "")                                                \
23965 _(show_one_map_request_mode, "")                                        \
23966 _(show_one_map_register_ttl, "")                                        \
23967 _(show_one_map_register_fallback_threshold, "")                         \
23968 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23969                             " sw_if_index <sw_if_index> p <priority> "  \
23970                             "w <weight>] [del]")                        \
23971 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23972                         "iface <intf> | sw_if_index <sw_if_index> "     \
23973                         "p <priority> w <weight> [del]")                \
23974 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23975                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23976                          "locator-set <locator_name> [del]"             \
23977                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23978 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23979 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23980 _(lisp_enable_disable, "enable|disable")                                \
23981 _(lisp_map_register_enable_disable, "enable|disable")                   \
23982 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23983 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23984                                "[seid <seid>] "                         \
23985                                "rloc <locator> p <prio> "               \
23986                                "w <weight> [rloc <loc> ... ] "          \
23987                                "action <action> [del-all]")             \
23988 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23989                           "<local-eid>")                                \
23990 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23991 _(lisp_use_petr, "<ip-address> | disable")                              \
23992 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23993 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23994 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23995 _(lisp_locator_set_dump, "[local | remote]")                            \
23996 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23997 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23998                        "[local] | [remote]")                            \
23999 _(lisp_eid_table_vni_dump, "")                                          \
24000 _(lisp_eid_table_map_dump, "l2|l3")                                     \
24001 _(lisp_map_resolver_dump, "")                                           \
24002 _(lisp_map_server_dump, "")                                             \
24003 _(lisp_adjacencies_get, "vni <vni>")                                    \
24004 _(gpe_fwd_entry_vnis_get, "")                                           \
24005 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
24006 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
24007                                 "[table <table-id>]")                   \
24008 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
24009 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
24010 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
24011 _(gpe_get_encap_mode, "")                                               \
24012 _(lisp_gpe_add_del_iface, "up|down")                                    \
24013 _(lisp_gpe_enable_disable, "enable|disable")                            \
24014 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
24015   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
24016 _(show_lisp_rloc_probe_state, "")                                       \
24017 _(show_lisp_map_register_state, "")                                     \
24018 _(show_lisp_status, "")                                                 \
24019 _(lisp_get_map_request_itr_rlocs, "")                                   \
24020 _(show_lisp_pitr, "")                                                   \
24021 _(show_lisp_use_petr, "")                                               \
24022 _(show_lisp_map_request_mode, "")                                       \
24023 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
24024 _(af_packet_delete, "name <host interface name>")                       \
24025 _(af_packet_dump, "")                                                   \
24026 _(policer_add_del, "name <policer name> <params> [del]")                \
24027 _(policer_dump, "[name <policer name>]")                                \
24028 _(policer_classify_set_interface,                                       \
24029   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24030   "  [l2-table <nn>] [del]")                                            \
24031 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
24032 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
24033     "[master|slave]")                                                   \
24034 _(netmap_delete, "name <interface name>")                               \
24035 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
24036 _(mpls_fib_dump, "")                                                    \
24037 _(classify_table_ids, "")                                               \
24038 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24039 _(classify_table_info, "table_id <nn>")                                 \
24040 _(classify_session_dump, "table_id <nn>")                               \
24041 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24042     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24043     "[template_interval <nn>] [udp_checksum]")                          \
24044 _(ipfix_exporter_dump, "")                                              \
24045 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24046 _(ipfix_classify_stream_dump, "")                                       \
24047 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24048 _(ipfix_classify_table_dump, "")                                        \
24049 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24050 _(sw_interface_span_dump, "[l2]")                                           \
24051 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24052 _(pg_create_interface, "if_id <nn>")                                    \
24053 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24054 _(pg_enable_disable, "[stream <id>] disable")                           \
24055 _(ip_source_and_port_range_check_add_del,                               \
24056   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24057 _(ip_source_and_port_range_check_interface_add_del,                     \
24058   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24059   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24060 _(ipsec_gre_add_del_tunnel,                                             \
24061   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24062 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24063 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24064 _(l2_interface_pbb_tag_rewrite,                                         \
24065   "<intfc> | sw_if_index <nn> \n"                                       \
24066   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24067   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24068 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24069 _(flow_classify_set_interface,                                          \
24070   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24071 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24072 _(ip_fib_dump, "")                                                      \
24073 _(ip_mfib_dump, "")                                                     \
24074 _(ip6_fib_dump, "")                                                     \
24075 _(ip6_mfib_dump, "")                                                    \
24076 _(feature_enable_disable, "arc_name <arc_name> "                        \
24077   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24078 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24079 "[disable]")                                                            \
24080 _(l2_xconnect_dump, "")                                                 \
24081 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24082 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24083 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24084 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24085 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24086 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24087 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24088   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24089 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24090 _(sock_init_shm, "size <nnn>")                                          \
24091 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24092 _(dns_enable_disable, "[enable][disable]")                              \
24093 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24094 _(dns_resolve_name, "<hostname>")                                       \
24095 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24096 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24097 _(dns_resolve_name, "<hostname>")                                       \
24098 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24099   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24100 _(session_rules_dump, "")                                               \
24101 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24102 _(output_acl_set_interface,                                             \
24103   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24104   "  [l2-table <nn>] [del]")                                            \
24105 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24106
24107 /* List of command functions, CLI names map directly to functions */
24108 #define foreach_cli_function                                    \
24109 _(comment, "usage: comment <ignore-rest-of-line>")              \
24110 _(dump_interface_table, "usage: dump_interface_table")          \
24111 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24112 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24113 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24114 _(dump_stats_table, "usage: dump_stats_table")                  \
24115 _(dump_macro_table, "usage: dump_macro_table ")                 \
24116 _(dump_node_table, "usage: dump_node_table")                    \
24117 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24118 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24119 _(echo, "usage: echo <message>")                                \
24120 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24121 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24122 _(help, "usage: help")                                          \
24123 _(q, "usage: quit")                                             \
24124 _(quit, "usage: quit")                                          \
24125 _(search_node_table, "usage: search_node_table <name>...")      \
24126 _(set, "usage: set <variable-name> <value>")                    \
24127 _(script, "usage: script <file-name>")                          \
24128 _(statseg, "usage: statseg");                                   \
24129 _(unset, "usage: unset <variable-name>")
24130
24131 #define _(N,n)                                  \
24132     static void vl_api_##n##_t_handler_uni      \
24133     (vl_api_##n##_t * mp)                       \
24134     {                                           \
24135         vat_main_t * vam = &vat_main;           \
24136         if (vam->json_output) {                 \
24137             vl_api_##n##_t_handler_json(mp);    \
24138         } else {                                \
24139             vl_api_##n##_t_handler(mp);         \
24140         }                                       \
24141     }
24142 foreach_vpe_api_reply_msg;
24143 #if VPP_API_TEST_BUILTIN == 0
24144 foreach_standalone_reply_msg;
24145 #endif
24146 #undef _
24147
24148 void
24149 vat_api_hookup (vat_main_t * vam)
24150 {
24151 #define _(N,n)                                                  \
24152     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24153                            vl_api_##n##_t_handler_uni,          \
24154                            vl_noop_handler,                     \
24155                            vl_api_##n##_t_endian,               \
24156                            vl_api_##n##_t_print,                \
24157                            sizeof(vl_api_##n##_t), 1);
24158   foreach_vpe_api_reply_msg;
24159 #if VPP_API_TEST_BUILTIN == 0
24160   foreach_standalone_reply_msg;
24161 #endif
24162 #undef _
24163
24164 #if (VPP_API_TEST_BUILTIN==0)
24165   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24166
24167   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24168
24169   vam->function_by_name = hash_create_string (0, sizeof (uword));
24170
24171   vam->help_by_name = hash_create_string (0, sizeof (uword));
24172 #endif
24173
24174   /* API messages we can send */
24175 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24176   foreach_vpe_api_msg;
24177 #undef _
24178
24179   /* Help strings */
24180 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24181   foreach_vpe_api_msg;
24182 #undef _
24183
24184   /* CLI functions */
24185 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24186   foreach_cli_function;
24187 #undef _
24188
24189   /* Help strings */
24190 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24191   foreach_cli_function;
24192 #undef _
24193 }
24194
24195 #if VPP_API_TEST_BUILTIN
24196 static clib_error_t *
24197 vat_api_hookup_shim (vlib_main_t * vm)
24198 {
24199   vat_api_hookup (&vat_main);
24200   return 0;
24201 }
24202
24203 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24204 #endif
24205
24206 /*
24207  * fd.io coding-style-patch-verification: ON
24208  *
24209  * Local Variables:
24210  * eval: (c-set-style "gnu")
24211  * End:
24212  */