BD ARP entry use common API types
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/l2/l2_input.h>
28 #include <vnet/l2tp/l2tp.h>
29 #include <vnet/vxlan/vxlan.h>
30 #include <vnet/geneve/geneve.h>
31 #include <vnet/gre/gre.h>
32 #include <vnet/vxlan-gpe/vxlan_gpe.h>
33 #include <vnet/lisp-gpe/lisp_gpe.h>
34
35 #include <vpp/api/vpe_msg_enum.h>
36 #include <vnet/l2/l2_classify.h>
37 #include <vnet/l2/l2_vtr.h>
38 #include <vnet/classify/in_out_acl.h>
39 #include <vnet/classify/policer_classify.h>
40 #include <vnet/classify/flow_classify.h>
41 #include <vnet/mpls/mpls.h>
42 #include <vnet/ipsec/ipsec.h>
43 #include <vnet/ipsec/ikev2.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #define vl_print(handle, ...)
75 #define vl_printfun
76 #include <vpp/api/vpe_all_api_h.h>
77 #undef vl_printfun
78
79 #define __plugin_msg_base 0
80 #include <vlibapi/vat_helper_macros.h>
81
82 #if VPP_API_TEST_BUILTIN == 0
83 #include <netdb.h>
84
85 /* *INDENT-OFF* */
86 const mac_address_t ZERO_MAC_ADDRESS = {
87   .bytes = {
88     0, 0, 0, 0, 0, 0,
89   },
90 };
91 /* *INDENT-ON* */
92
93 u32
94 vl (void *p)
95 {
96   return vec_len (p);
97 }
98
99 int
100 vat_socket_connect (vat_main_t * vam)
101 {
102   vam->socket_client_main = &socket_client_main;
103   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
104                                    0 /* default socket rx, tx buffer */ );
105 }
106 #else /* vpp built-in case, we don't do sockets... */
107 int
108 vat_socket_connect (vat_main_t * vam)
109 {
110   return 0;
111 }
112
113 int
114 vl_socket_client_read (int wait)
115 {
116   return -1;
117 };
118
119 int
120 vl_socket_client_write ()
121 {
122   return -1;
123 };
124
125 void *
126 vl_socket_client_msg_alloc (int nbytes)
127 {
128   return 0;
129 }
130 #endif
131
132
133 f64
134 vat_time_now (vat_main_t * vam)
135 {
136 #if VPP_API_TEST_BUILTIN
137   return vlib_time_now (vam->vlib_main);
138 #else
139   return clib_time_now (&vam->clib_time);
140 #endif
141 }
142
143 void
144 errmsg (char *fmt, ...)
145 {
146   vat_main_t *vam = &vat_main;
147   va_list va;
148   u8 *s;
149
150   va_start (va, fmt);
151   s = va_format (0, fmt, &va);
152   va_end (va);
153
154   vec_add1 (s, 0);
155
156 #if VPP_API_TEST_BUILTIN
157   vlib_cli_output (vam->vlib_main, (char *) s);
158 #else
159   {
160     if (vam->ifp != stdin)
161       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
162                vam->input_line_number);
163     fformat (vam->ofp, (char *) s);
164     fflush (vam->ofp);
165   }
166 #endif
167
168   vec_free (s);
169 }
170
171 #if VPP_API_TEST_BUILTIN == 0
172 static uword
173 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
174 {
175   vat_main_t *vam = va_arg (*args, vat_main_t *);
176   u32 *result = va_arg (*args, u32 *);
177   u8 *if_name;
178   uword *p;
179
180   if (!unformat (input, "%s", &if_name))
181     return 0;
182
183   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
184   if (p == 0)
185     return 0;
186   *result = p[0];
187   return 1;
188 }
189
190 static uword
191 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
192 {
193   return 0;
194 }
195
196 /* Parse an IP4 address %d.%d.%d.%d. */
197 uword
198 unformat_ip4_address (unformat_input_t * input, va_list * args)
199 {
200   u8 *result = va_arg (*args, u8 *);
201   unsigned a[4];
202
203   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
204     return 0;
205
206   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
207     return 0;
208
209   result[0] = a[0];
210   result[1] = a[1];
211   result[2] = a[2];
212   result[3] = a[3];
213
214   return 1;
215 }
216
217 uword
218 unformat_ethernet_address (unformat_input_t * input, va_list * args)
219 {
220   u8 *result = va_arg (*args, u8 *);
221   u32 i, a[6];
222
223   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
224                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
225     return 0;
226
227   /* Check range. */
228   for (i = 0; i < 6; i++)
229     if (a[i] >= (1 << 8))
230       return 0;
231
232   for (i = 0; i < 6; i++)
233     result[i] = a[i];
234
235   return 1;
236 }
237
238 /* Returns ethernet type as an int in host byte order. */
239 uword
240 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
241                                         va_list * args)
242 {
243   u16 *result = va_arg (*args, u16 *);
244   int type;
245
246   /* Numeric type. */
247   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
248     {
249       if (type >= (1 << 16))
250         return 0;
251       *result = type;
252       return 1;
253     }
254   return 0;
255 }
256
257 /* Parse an IP6 address. */
258 uword
259 unformat_ip6_address (unformat_input_t * input, va_list * args)
260 {
261   ip6_address_t *result = va_arg (*args, ip6_address_t *);
262   u16 hex_quads[8];
263   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
264   uword c, n_colon, double_colon_index;
265
266   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
267   double_colon_index = ARRAY_LEN (hex_quads);
268   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
269     {
270       hex_digit = 16;
271       if (c >= '0' && c <= '9')
272         hex_digit = c - '0';
273       else if (c >= 'a' && c <= 'f')
274         hex_digit = c + 10 - 'a';
275       else if (c >= 'A' && c <= 'F')
276         hex_digit = c + 10 - 'A';
277       else if (c == ':' && n_colon < 2)
278         n_colon++;
279       else
280         {
281           unformat_put_input (input);
282           break;
283         }
284
285       /* Too many hex quads. */
286       if (n_hex_quads >= ARRAY_LEN (hex_quads))
287         return 0;
288
289       if (hex_digit < 16)
290         {
291           hex_quad = (hex_quad << 4) | hex_digit;
292
293           /* Hex quad must fit in 16 bits. */
294           if (n_hex_digits >= 4)
295             return 0;
296
297           n_colon = 0;
298           n_hex_digits++;
299         }
300
301       /* Save position of :: */
302       if (n_colon == 2)
303         {
304           /* More than one :: ? */
305           if (double_colon_index < ARRAY_LEN (hex_quads))
306             return 0;
307           double_colon_index = n_hex_quads;
308         }
309
310       if (n_colon > 0 && n_hex_digits > 0)
311         {
312           hex_quads[n_hex_quads++] = hex_quad;
313           hex_quad = 0;
314           n_hex_digits = 0;
315         }
316     }
317
318   if (n_hex_digits > 0)
319     hex_quads[n_hex_quads++] = hex_quad;
320
321   {
322     word i;
323
324     /* Expand :: to appropriate number of zero hex quads. */
325     if (double_colon_index < ARRAY_LEN (hex_quads))
326       {
327         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
328
329         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
330           hex_quads[n_zero + i] = hex_quads[i];
331
332         for (i = 0; i < n_zero; i++)
333           hex_quads[double_colon_index + i] = 0;
334
335         n_hex_quads = ARRAY_LEN (hex_quads);
336       }
337
338     /* Too few hex quads given. */
339     if (n_hex_quads < ARRAY_LEN (hex_quads))
340       return 0;
341
342     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
343       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
344
345     return 1;
346   }
347 }
348
349 uword
350 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
351 {
352   u32 *r = va_arg (*args, u32 *);
353
354   if (0);
355 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
356   foreach_ipsec_policy_action
357 #undef _
358     else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
370   foreach_ipsec_crypto_alg
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 u8 *
378 format_ipsec_crypto_alg (u8 * s, va_list * args)
379 {
380   u32 i = va_arg (*args, u32);
381   u8 *t = 0;
382
383   switch (i)
384     {
385 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
386       foreach_ipsec_crypto_alg
387 #undef _
388     default:
389       return format (s, "unknown");
390     }
391   return format (s, "%s", t);
392 }
393
394 uword
395 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
396 {
397   u32 *r = va_arg (*args, u32 *);
398
399   if (0);
400 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
401   foreach_ipsec_integ_alg
402 #undef _
403     else
404     return 0;
405   return 1;
406 }
407
408 u8 *
409 format_ipsec_integ_alg (u8 * s, va_list * args)
410 {
411   u32 i = va_arg (*args, u32);
412   u8 *t = 0;
413
414   switch (i)
415     {
416 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
417       foreach_ipsec_integ_alg
418 #undef _
419     default:
420       return format (s, "unknown");
421     }
422   return format (s, "%s", t);
423 }
424
425 uword
426 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
427 {
428   u32 *r = va_arg (*args, u32 *);
429
430   if (0);
431 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
432   foreach_ikev2_auth_method
433 #undef _
434     else
435     return 0;
436   return 1;
437 }
438
439 uword
440 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
441 {
442   u32 *r = va_arg (*args, u32 *);
443
444   if (0);
445 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
446   foreach_ikev2_id_type
447 #undef _
448     else
449     return 0;
450   return 1;
451 }
452 #else /* VPP_API_TEST_BUILTIN == 1 */
453 static uword
454 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
455 {
456   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
457   vnet_main_t *vnm = vnet_get_main ();
458   u32 *result = va_arg (*args, u32 *);
459
460   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
461 }
462
463 static uword
464 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
465 {
466   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
467   vnet_main_t *vnm = vnet_get_main ();
468   u32 *result = va_arg (*args, u32 *);
469
470   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
471 }
472
473 #endif /* VPP_API_TEST_BUILTIN */
474
475 static uword
476 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
477 {
478   u8 *r = va_arg (*args, u8 *);
479
480   if (unformat (input, "kbps"))
481     *r = SSE2_QOS_RATE_KBPS;
482   else if (unformat (input, "pps"))
483     *r = SSE2_QOS_RATE_PPS;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_policer_round_type (unformat_input_t * input, va_list * args)
491 {
492   u8 *r = va_arg (*args, u8 *);
493
494   if (unformat (input, "closest"))
495     *r = SSE2_QOS_ROUND_TO_CLOSEST;
496   else if (unformat (input, "up"))
497     *r = SSE2_QOS_ROUND_TO_UP;
498   else if (unformat (input, "down"))
499     *r = SSE2_QOS_ROUND_TO_DOWN;
500   else
501     return 0;
502   return 1;
503 }
504
505 static uword
506 unformat_policer_type (unformat_input_t * input, va_list * args)
507 {
508   u8 *r = va_arg (*args, u8 *);
509
510   if (unformat (input, "1r2c"))
511     *r = SSE2_QOS_POLICER_TYPE_1R2C;
512   else if (unformat (input, "1r3c"))
513     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
514   else if (unformat (input, "2r3c-2698"))
515     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
516   else if (unformat (input, "2r3c-4115"))
517     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
518   else if (unformat (input, "2r3c-mef5cf1"))
519     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
520   else
521     return 0;
522   return 1;
523 }
524
525 static uword
526 unformat_dscp (unformat_input_t * input, va_list * va)
527 {
528   u8 *r = va_arg (*va, u8 *);
529
530   if (0);
531 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
532   foreach_vnet_dscp
533 #undef _
534     else
535     return 0;
536   return 1;
537 }
538
539 static uword
540 unformat_policer_action_type (unformat_input_t * input, va_list * va)
541 {
542   sse2_qos_pol_action_params_st *a
543     = va_arg (*va, sse2_qos_pol_action_params_st *);
544
545   if (unformat (input, "drop"))
546     a->action_type = SSE2_QOS_ACTION_DROP;
547   else if (unformat (input, "transmit"))
548     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
549   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
550     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
551   else
552     return 0;
553   return 1;
554 }
555
556 static uword
557 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
558 {
559   u32 *r = va_arg (*va, u32 *);
560   u32 tid;
561
562   if (unformat (input, "ip4"))
563     tid = POLICER_CLASSIFY_TABLE_IP4;
564   else if (unformat (input, "ip6"))
565     tid = POLICER_CLASSIFY_TABLE_IP6;
566   else if (unformat (input, "l2"))
567     tid = POLICER_CLASSIFY_TABLE_L2;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 static uword
576 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
577 {
578   u32 *r = va_arg (*va, u32 *);
579   u32 tid;
580
581   if (unformat (input, "ip4"))
582     tid = FLOW_CLASSIFY_TABLE_IP4;
583   else if (unformat (input, "ip6"))
584     tid = FLOW_CLASSIFY_TABLE_IP6;
585   else
586     return 0;
587
588   *r = tid;
589   return 1;
590 }
591
592 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
593 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
594 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
595 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
596
597 #if (VPP_API_TEST_BUILTIN==0)
598 uword
599 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
600 {
601   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
602   mfib_itf_attribute_t attr;
603
604   old = *iflags;
605   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
606   {
607     if (unformat (input, mfib_itf_flag_long_names[attr]))
608       *iflags |= (1 << attr);
609   }
610   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_itf_flag_names[attr]))
613       *iflags |= (1 << attr);
614   }
615
616   return (old == *iflags ? 0 : 1);
617 }
618
619 uword
620 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
621 {
622   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
623   mfib_entry_attribute_t attr;
624
625   old = *eflags;
626   FOR_EACH_MFIB_ATTRIBUTE (attr)
627   {
628     if (unformat (input, mfib_flag_long_names[attr]))
629       *eflags |= (1 << attr);
630   }
631   FOR_EACH_MFIB_ATTRIBUTE (attr)
632   {
633     if (unformat (input, mfib_flag_names[attr]))
634       *eflags |= (1 << attr);
635   }
636
637   return (old == *eflags ? 0 : 1);
638 }
639
640 u8 *
641 format_ip4_address (u8 * s, va_list * args)
642 {
643   u8 *a = va_arg (*args, u8 *);
644   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
645 }
646
647 u8 *
648 format_ip6_address (u8 * s, va_list * args)
649 {
650   ip6_address_t *a = va_arg (*args, ip6_address_t *);
651   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
652
653   i_max_n_zero = ARRAY_LEN (a->as_u16);
654   max_n_zeros = 0;
655   i_first_zero = i_max_n_zero;
656   n_zeros = 0;
657   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
658     {
659       u32 is_zero = a->as_u16[i] == 0;
660       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
661         {
662           i_first_zero = i;
663           n_zeros = 0;
664         }
665       n_zeros += is_zero;
666       if ((!is_zero && n_zeros > max_n_zeros)
667           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
668         {
669           i_max_n_zero = i_first_zero;
670           max_n_zeros = n_zeros;
671           i_first_zero = ARRAY_LEN (a->as_u16);
672           n_zeros = 0;
673         }
674     }
675
676   last_double_colon = 0;
677   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
678     {
679       if (i == i_max_n_zero && max_n_zeros > 1)
680         {
681           s = format (s, "::");
682           i += max_n_zeros - 1;
683           last_double_colon = 1;
684         }
685       else
686         {
687           s = format (s, "%s%x",
688                       (last_double_colon || i == 0) ? "" : ":",
689                       clib_net_to_host_u16 (a->as_u16[i]));
690           last_double_colon = 0;
691         }
692     }
693
694   return s;
695 }
696
697 /* Format an IP46 address. */
698 u8 *
699 format_ip46_address (u8 * s, va_list * args)
700 {
701   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
702   ip46_type_t type = va_arg (*args, ip46_type_t);
703   int is_ip4 = 1;
704
705   switch (type)
706     {
707     case IP46_TYPE_ANY:
708       is_ip4 = ip46_address_is_ip4 (ip46);
709       break;
710     case IP46_TYPE_IP4:
711       is_ip4 = 1;
712       break;
713     case IP46_TYPE_IP6:
714       is_ip4 = 0;
715       break;
716     }
717
718   return is_ip4 ?
719     format (s, "%U", format_ip4_address, &ip46->ip4) :
720     format (s, "%U", format_ip6_address, &ip46->ip6);
721 }
722
723 u8 *
724 format_ethernet_address (u8 * s, va_list * args)
725 {
726   u8 *a = va_arg (*args, u8 *);
727
728   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
729                  a[0], a[1], a[2], a[3], a[4], a[5]);
730 }
731 #endif
732
733 static void
734 increment_v4_address (ip4_address_t * a)
735 {
736   u32 v;
737
738   v = ntohl (a->as_u32) + 1;
739   a->as_u32 = ntohl (v);
740 }
741
742 static void
743 increment_v6_address (ip6_address_t * a)
744 {
745   u64 v0, v1;
746
747   v0 = clib_net_to_host_u64 (a->as_u64[0]);
748   v1 = clib_net_to_host_u64 (a->as_u64[1]);
749
750   v1 += 1;
751   if (v1 == 0)
752     v0 += 1;
753   a->as_u64[0] = clib_net_to_host_u64 (v0);
754   a->as_u64[1] = clib_net_to_host_u64 (v1);
755 }
756
757 static void
758 increment_mac_address (u8 * mac)
759 {
760   u64 tmp = *((u64 *) mac);
761   tmp = clib_net_to_host_u64 (tmp);
762   tmp += 1 << 16;               /* skip unused (least significant) octets */
763   tmp = clib_host_to_net_u64 (tmp);
764
765   clib_memcpy (mac, &tmp, 6);
766 }
767
768 static void vl_api_create_loopback_reply_t_handler
769   (vl_api_create_loopback_reply_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   i32 retval = ntohl (mp->retval);
773
774   vam->retval = retval;
775   vam->regenerate_interface_table = 1;
776   vam->sw_if_index = ntohl (mp->sw_if_index);
777   vam->result_ready = 1;
778 }
779
780 static void vl_api_create_loopback_reply_t_handler_json
781   (vl_api_create_loopback_reply_t * mp)
782 {
783   vat_main_t *vam = &vat_main;
784   vat_json_node_t node;
785
786   vat_json_init_object (&node);
787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
788   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
789
790   vat_json_print (vam->ofp, &node);
791   vat_json_free (&node);
792   vam->retval = ntohl (mp->retval);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_loopback_instance_reply_t_handler
797   (vl_api_create_loopback_instance_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   i32 retval = ntohl (mp->retval);
801
802   vam->retval = retval;
803   vam->regenerate_interface_table = 1;
804   vam->sw_if_index = ntohl (mp->sw_if_index);
805   vam->result_ready = 1;
806 }
807
808 static void vl_api_create_loopback_instance_reply_t_handler_json
809   (vl_api_create_loopback_instance_reply_t * mp)
810 {
811   vat_main_t *vam = &vat_main;
812   vat_json_node_t node;
813
814   vat_json_init_object (&node);
815   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
816   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
817
818   vat_json_print (vam->ofp, &node);
819   vat_json_free (&node);
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_af_packet_create_reply_t_handler
825   (vl_api_af_packet_create_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_af_packet_create_reply_t_handler_json
837   (vl_api_af_packet_create_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848
849   vam->retval = ntohl (mp->retval);
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_create_vlan_subif_reply_t_handler
854   (vl_api_create_vlan_subif_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   i32 retval = ntohl (mp->retval);
858
859   vam->retval = retval;
860   vam->regenerate_interface_table = 1;
861   vam->sw_if_index = ntohl (mp->sw_if_index);
862   vam->result_ready = 1;
863 }
864
865 static void vl_api_create_vlan_subif_reply_t_handler_json
866   (vl_api_create_vlan_subif_reply_t * mp)
867 {
868   vat_main_t *vam = &vat_main;
869   vat_json_node_t node;
870
871   vat_json_init_object (&node);
872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875   vat_json_print (vam->ofp, &node);
876   vat_json_free (&node);
877
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_create_subif_reply_t_handler
883   (vl_api_create_subif_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->sw_if_index = ntohl (mp->sw_if_index);
891   vam->result_ready = 1;
892 }
893
894 static void vl_api_create_subif_reply_t_handler_json
895   (vl_api_create_subif_reply_t * mp)
896 {
897   vat_main_t *vam = &vat_main;
898   vat_json_node_t node;
899
900   vat_json_init_object (&node);
901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
902   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
903
904   vat_json_print (vam->ofp, &node);
905   vat_json_free (&node);
906
907   vam->retval = ntohl (mp->retval);
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_interface_name_renumber_reply_t_handler
912   (vl_api_interface_name_renumber_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   i32 retval = ntohl (mp->retval);
916
917   vam->retval = retval;
918   vam->regenerate_interface_table = 1;
919   vam->result_ready = 1;
920 }
921
922 static void vl_api_interface_name_renumber_reply_t_handler_json
923   (vl_api_interface_name_renumber_reply_t * mp)
924 {
925   vat_main_t *vam = &vat_main;
926   vat_json_node_t node;
927
928   vat_json_init_object (&node);
929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
930
931   vat_json_print (vam->ofp, &node);
932   vat_json_free (&node);
933
934   vam->retval = ntohl (mp->retval);
935   vam->result_ready = 1;
936 }
937
938 /*
939  * Special-case: build the interface table, maintain
940  * the next loopback sw_if_index vbl.
941  */
942 static void vl_api_sw_interface_details_t_handler
943   (vl_api_sw_interface_details_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   u8 *s = format (0, "%s%c", mp->interface_name, 0);
947
948   hash_set_mem (vam->sw_if_index_by_interface_name, s,
949                 ntohl (mp->sw_if_index));
950
951   /* In sub interface case, fill the sub interface table entry */
952   if (mp->sw_if_index != mp->sup_sw_if_index)
953     {
954       sw_interface_subif_t *sub = NULL;
955
956       vec_add2 (vam->sw_if_subif_table, sub, 1);
957
958       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
959       strncpy ((char *) sub->interface_name, (char *) s,
960                vec_len (sub->interface_name));
961       sub->sw_if_index = ntohl (mp->sw_if_index);
962       sub->sub_id = ntohl (mp->sub_id);
963
964       sub->sub_dot1ad = mp->sub_dot1ad;
965       sub->sub_number_of_tags = mp->sub_number_of_tags;
966       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
967       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
968       sub->sub_exact_match = mp->sub_exact_match;
969       sub->sub_default = mp->sub_default;
970       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
971       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
972
973       /* vlan tag rewrite */
974       sub->vtr_op = ntohl (mp->vtr_op);
975       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
976       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
977       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
978     }
979 }
980
981 static void vl_api_sw_interface_details_t_handler_json
982   (vl_api_sw_interface_details_t * mp)
983 {
984   vat_main_t *vam = &vat_main;
985   vat_json_node_t *node = NULL;
986
987   if (VAT_JSON_ARRAY != vam->json_tree.type)
988     {
989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
990       vat_json_init_array (&vam->json_tree);
991     }
992   node = vat_json_array_add (&vam->json_tree);
993
994   vat_json_init_object (node);
995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
996   vat_json_object_add_uint (node, "sup_sw_if_index",
997                             ntohl (mp->sup_sw_if_index));
998   vat_json_object_add_uint (node, "l2_address_length",
999                             ntohl (mp->l2_address_length));
1000   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1001                              sizeof (mp->l2_address));
1002   vat_json_object_add_string_copy (node, "interface_name",
1003                                    mp->interface_name);
1004   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1005   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1006   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1007   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1008   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1009   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1010   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1011   vat_json_object_add_uint (node, "sub_number_of_tags",
1012                             mp->sub_number_of_tags);
1013   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1014                             ntohs (mp->sub_outer_vlan_id));
1015   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1016                             ntohs (mp->sub_inner_vlan_id));
1017   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1018   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1019   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1020                             mp->sub_outer_vlan_id_any);
1021   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1022                             mp->sub_inner_vlan_id_any);
1023   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1024   vat_json_object_add_uint (node, "vtr_push_dot1q",
1025                             ntohl (mp->vtr_push_dot1q));
1026   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1027   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1028   if (mp->sub_dot1ah)
1029     {
1030       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1031                                        format (0, "%U",
1032                                                format_ethernet_address,
1033                                                &mp->b_dmac));
1034       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1035                                        format (0, "%U",
1036                                                format_ethernet_address,
1037                                                &mp->b_smac));
1038       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1039       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1040     }
1041 }
1042
1043 #if VPP_API_TEST_BUILTIN == 0
1044 static void vl_api_sw_interface_event_t_handler
1045   (vl_api_sw_interface_event_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   if (vam->interface_event_display)
1049     errmsg ("interface flags: sw_if_index %d %s %s",
1050             ntohl (mp->sw_if_index),
1051             mp->admin_up_down ? "admin-up" : "admin-down",
1052             mp->link_up_down ? "link-up" : "link-down");
1053 }
1054 #endif
1055
1056 static void vl_api_sw_interface_event_t_handler_json
1057   (vl_api_sw_interface_event_t * mp)
1058 {
1059   /* JSON output not supported */
1060 }
1061
1062 static void
1063 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067
1068   vam->retval = retval;
1069   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1070   vam->result_ready = 1;
1071 }
1072
1073 static void
1074 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1075 {
1076   vat_main_t *vam = &vat_main;
1077   vat_json_node_t node;
1078   api_main_t *am = &api_main;
1079   void *oldheap;
1080   u8 *reply;
1081
1082   vat_json_init_object (&node);
1083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1084   vat_json_object_add_uint (&node, "reply_in_shmem",
1085                             ntohl (mp->reply_in_shmem));
1086   /* Toss the shared-memory original... */
1087   pthread_mutex_lock (&am->vlib_rp->mutex);
1088   oldheap = svm_push_data_heap (am->vlib_rp);
1089
1090   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1091   vec_free (reply);
1092
1093   svm_pop_heap (oldheap);
1094   pthread_mutex_unlock (&am->vlib_rp->mutex);
1095
1096   vat_json_print (vam->ofp, &node);
1097   vat_json_free (&node);
1098
1099   vam->retval = ntohl (mp->retval);
1100   vam->result_ready = 1;
1101 }
1102
1103 static void
1104 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1105 {
1106   vat_main_t *vam = &vat_main;
1107   i32 retval = ntohl (mp->retval);
1108   u32 length = ntohl (mp->length);
1109
1110   vec_reset_length (vam->cmd_reply);
1111
1112   vam->retval = retval;
1113   if (retval == 0)
1114     {
1115       vec_validate (vam->cmd_reply, length);
1116       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1117       vam->cmd_reply[length] = 0;
1118     }
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   vat_json_node_t node;
1127
1128   vec_reset_length (vam->cmd_reply);
1129
1130   vat_json_init_object (&node);
1131   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1132   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1133
1134   vat_json_print (vam->ofp, &node);
1135   vat_json_free (&node);
1136
1137   vam->retval = ntohl (mp->retval);
1138   vam->result_ready = 1;
1139 }
1140
1141 static void vl_api_classify_add_del_table_reply_t_handler
1142   (vl_api_classify_add_del_table_reply_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   i32 retval = ntohl (mp->retval);
1146   if (vam->async_mode)
1147     {
1148       vam->async_errors += (retval < 0);
1149     }
1150   else
1151     {
1152       vam->retval = retval;
1153       if (retval == 0 &&
1154           ((mp->new_table_index != 0xFFFFFFFF) ||
1155            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1156            (mp->match_n_vectors != 0xFFFFFFFF)))
1157         /*
1158          * Note: this is just barely thread-safe, depends on
1159          * the main thread spinning waiting for an answer...
1160          */
1161         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1162                 ntohl (mp->new_table_index),
1163                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1164       vam->result_ready = 1;
1165     }
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler_json
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   vat_json_node_t node;
1173
1174   vat_json_init_object (&node);
1175   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1176   vat_json_object_add_uint (&node, "new_table_index",
1177                             ntohl (mp->new_table_index));
1178   vat_json_object_add_uint (&node, "skip_n_vectors",
1179                             ntohl (mp->skip_n_vectors));
1180   vat_json_object_add_uint (&node, "match_n_vectors",
1181                             ntohl (mp->match_n_vectors));
1182
1183   vat_json_print (vam->ofp, &node);
1184   vat_json_free (&node);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_get_node_index_reply_t_handler
1191   (vl_api_get_node_index_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0)
1203         errmsg ("node index %d", ntohl (mp->node_index));
1204       vam->result_ready = 1;
1205     }
1206 }
1207
1208 static void vl_api_get_node_index_reply_t_handler_json
1209   (vl_api_get_node_index_reply_t * mp)
1210 {
1211   vat_main_t *vam = &vat_main;
1212   vat_json_node_t node;
1213
1214   vat_json_init_object (&node);
1215   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1216   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void vl_api_get_next_index_reply_t_handler
1226   (vl_api_get_next_index_reply_t * mp)
1227 {
1228   vat_main_t *vam = &vat_main;
1229   i32 retval = ntohl (mp->retval);
1230   if (vam->async_mode)
1231     {
1232       vam->async_errors += (retval < 0);
1233     }
1234   else
1235     {
1236       vam->retval = retval;
1237       if (retval == 0)
1238         errmsg ("next node index %d", ntohl (mp->next_index));
1239       vam->result_ready = 1;
1240     }
1241 }
1242
1243 static void vl_api_get_next_index_reply_t_handler_json
1244   (vl_api_get_next_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   vat_json_node_t node;
1248
1249   vat_json_init_object (&node);
1250   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1251   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1252
1253   vat_json_print (vam->ofp, &node);
1254   vat_json_free (&node);
1255
1256   vam->retval = ntohl (mp->retval);
1257   vam->result_ready = 1;
1258 }
1259
1260 static void vl_api_add_node_next_reply_t_handler
1261   (vl_api_add_node_next_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   i32 retval = ntohl (mp->retval);
1265   if (vam->async_mode)
1266     {
1267       vam->async_errors += (retval < 0);
1268     }
1269   else
1270     {
1271       vam->retval = retval;
1272       if (retval == 0)
1273         errmsg ("next index %d", ntohl (mp->next_index));
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_add_node_next_reply_t_handler_json
1279   (vl_api_add_node_next_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   vat_json_node_t node;
1283
1284   vat_json_init_object (&node);
1285   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1286   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1287
1288   vat_json_print (vam->ofp, &node);
1289   vat_json_free (&node);
1290
1291   vam->retval = ntohl (mp->retval);
1292   vam->result_ready = 1;
1293 }
1294
1295 static void vl_api_show_version_reply_t_handler
1296   (vl_api_show_version_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   i32 retval = ntohl (mp->retval);
1300
1301   if (retval >= 0)
1302     {
1303       errmsg ("        program: %s", mp->program);
1304       errmsg ("        version: %s", mp->version);
1305       errmsg ("     build date: %s", mp->build_date);
1306       errmsg ("build directory: %s", mp->build_directory);
1307     }
1308   vam->retval = retval;
1309   vam->result_ready = 1;
1310 }
1311
1312 static void vl_api_show_version_reply_t_handler_json
1313   (vl_api_show_version_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   vat_json_node_t node;
1317
1318   vat_json_init_object (&node);
1319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1320   vat_json_object_add_string_copy (&node, "program", mp->program);
1321   vat_json_object_add_string_copy (&node, "version", mp->version);
1322   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1323   vat_json_object_add_string_copy (&node, "build_directory",
1324                                    mp->build_directory);
1325
1326   vat_json_print (vam->ofp, &node);
1327   vat_json_free (&node);
1328
1329   vam->retval = ntohl (mp->retval);
1330   vam->result_ready = 1;
1331 }
1332
1333 static void vl_api_show_threads_reply_t_handler
1334   (vl_api_show_threads_reply_t * mp)
1335 {
1336   vat_main_t *vam = &vat_main;
1337   i32 retval = ntohl (mp->retval);
1338   int i, count = 0;
1339
1340   if (retval >= 0)
1341     count = ntohl (mp->count);
1342
1343   for (i = 0; i < count; i++)
1344     print (vam->ofp,
1345            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1346            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1347            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1348            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1349            ntohl (mp->thread_data[i].cpu_socket));
1350
1351   vam->retval = retval;
1352   vam->result_ready = 1;
1353 }
1354
1355 static void vl_api_show_threads_reply_t_handler_json
1356   (vl_api_show_threads_reply_t * mp)
1357 {
1358   vat_main_t *vam = &vat_main;
1359   vat_json_node_t node;
1360   vl_api_thread_data_t *td;
1361   i32 retval = ntohl (mp->retval);
1362   int i, count = 0;
1363
1364   if (retval >= 0)
1365     count = ntohl (mp->count);
1366
1367   vat_json_init_object (&node);
1368   vat_json_object_add_int (&node, "retval", retval);
1369   vat_json_object_add_uint (&node, "count", count);
1370
1371   for (i = 0; i < count; i++)
1372     {
1373       td = &mp->thread_data[i];
1374       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1375       vat_json_object_add_string_copy (&node, "name", td->name);
1376       vat_json_object_add_string_copy (&node, "type", td->type);
1377       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1378       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1379       vat_json_object_add_int (&node, "core", ntohl (td->id));
1380       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1381     }
1382
1383   vat_json_print (vam->ofp, &node);
1384   vat_json_free (&node);
1385
1386   vam->retval = retval;
1387   vam->result_ready = 1;
1388 }
1389
1390 static int
1391 api_show_threads (vat_main_t * vam)
1392 {
1393   vl_api_show_threads_t *mp;
1394   int ret;
1395
1396   print (vam->ofp,
1397          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1398          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1399
1400   M (SHOW_THREADS, mp);
1401
1402   S (mp);
1403   W (ret);
1404   return ret;
1405 }
1406
1407 static void
1408 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1409 {
1410   u32 sw_if_index = ntohl (mp->sw_if_index);
1411   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1412           mp->mac_ip ? "mac/ip binding" : "address resolution",
1413           ntohl (mp->pid), format_ip4_address, &mp->address,
1414           format_ethernet_address, mp->new_mac, sw_if_index);
1415 }
1416
1417 static void
1418 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1419 {
1420   /* JSON output not supported */
1421 }
1422
1423 static void
1424 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1425 {
1426   u32 sw_if_index = ntohl (mp->sw_if_index);
1427   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1428           mp->mac_ip ? "mac/ip binding" : "address resolution",
1429           ntohl (mp->pid), format_ip6_address, mp->address,
1430           format_ethernet_address, mp->new_mac, sw_if_index);
1431 }
1432
1433 static void
1434 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1435 {
1436   /* JSON output not supported */
1437 }
1438
1439 static void
1440 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1441 {
1442   u32 n_macs = ntohl (mp->n_macs);
1443   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1444           ntohl (mp->pid), mp->client_index, n_macs);
1445   int i;
1446   for (i = 0; i < n_macs; i++)
1447     {
1448       vl_api_mac_entry_t *mac = &mp->mac[i];
1449       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1450               i + 1, ntohl (mac->sw_if_index),
1451               format_ethernet_address, mac->mac_addr, mac->action);
1452       if (i == 1000)
1453         break;
1454     }
1455 }
1456
1457 static void
1458 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1459 {
1460   /* JSON output not supported */
1461 }
1462
1463 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1464 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1465
1466 /*
1467  * Special-case: build the bridge domain table, maintain
1468  * the next bd id vbl.
1469  */
1470 static void vl_api_bridge_domain_details_t_handler
1471   (vl_api_bridge_domain_details_t * mp)
1472 {
1473   vat_main_t *vam = &vat_main;
1474   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1475   int i;
1476
1477   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1478          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1479
1480   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1481          ntohl (mp->bd_id), mp->learn, mp->forward,
1482          mp->flood, ntohl (mp->bvi_sw_if_index),
1483          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1484
1485   if (n_sw_ifs)
1486     {
1487       vl_api_bridge_domain_sw_if_t *sw_ifs;
1488       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1489              "Interface Name");
1490
1491       sw_ifs = mp->sw_if_details;
1492       for (i = 0; i < n_sw_ifs; i++)
1493         {
1494           u8 *sw_if_name = 0;
1495           u32 sw_if_index;
1496           hash_pair_t *p;
1497
1498           sw_if_index = ntohl (sw_ifs->sw_if_index);
1499
1500           /* *INDENT-OFF* */
1501           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1502                              ({
1503                                if ((u32) p->value[0] == sw_if_index)
1504                                  {
1505                                    sw_if_name = (u8 *)(p->key);
1506                                    break;
1507                                  }
1508                              }));
1509           /* *INDENT-ON* */
1510           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1511                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1512                  "sw_if_index not found!");
1513
1514           sw_ifs++;
1515         }
1516     }
1517 }
1518
1519 static void vl_api_bridge_domain_details_t_handler_json
1520   (vl_api_bridge_domain_details_t * mp)
1521 {
1522   vat_main_t *vam = &vat_main;
1523   vat_json_node_t *node, *array = NULL;
1524   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1525
1526   if (VAT_JSON_ARRAY != vam->json_tree.type)
1527     {
1528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1529       vat_json_init_array (&vam->json_tree);
1530     }
1531   node = vat_json_array_add (&vam->json_tree);
1532
1533   vat_json_init_object (node);
1534   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1535   vat_json_object_add_uint (node, "flood", mp->flood);
1536   vat_json_object_add_uint (node, "forward", mp->forward);
1537   vat_json_object_add_uint (node, "learn", mp->learn);
1538   vat_json_object_add_uint (node, "bvi_sw_if_index",
1539                             ntohl (mp->bvi_sw_if_index));
1540   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1541   array = vat_json_object_add (node, "sw_if");
1542   vat_json_init_array (array);
1543
1544
1545
1546   if (n_sw_ifs)
1547     {
1548       vl_api_bridge_domain_sw_if_t *sw_ifs;
1549       int i;
1550
1551       sw_ifs = mp->sw_if_details;
1552       for (i = 0; i < n_sw_ifs; i++)
1553         {
1554           node = vat_json_array_add (array);
1555           vat_json_init_object (node);
1556           vat_json_object_add_uint (node, "sw_if_index",
1557                                     ntohl (sw_ifs->sw_if_index));
1558           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1559           sw_ifs++;
1560         }
1561     }
1562 }
1563
1564 static void vl_api_control_ping_reply_t_handler
1565   (vl_api_control_ping_reply_t * mp)
1566 {
1567   vat_main_t *vam = &vat_main;
1568   i32 retval = ntohl (mp->retval);
1569   if (vam->async_mode)
1570     {
1571       vam->async_errors += (retval < 0);
1572     }
1573   else
1574     {
1575       vam->retval = retval;
1576       vam->result_ready = 1;
1577     }
1578   if (vam->socket_client_main)
1579     vam->socket_client_main->control_pings_outstanding--;
1580 }
1581
1582 static void vl_api_control_ping_reply_t_handler_json
1583   (vl_api_control_ping_reply_t * mp)
1584 {
1585   vat_main_t *vam = &vat_main;
1586   i32 retval = ntohl (mp->retval);
1587
1588   if (VAT_JSON_NONE != vam->json_tree.type)
1589     {
1590       vat_json_print (vam->ofp, &vam->json_tree);
1591       vat_json_free (&vam->json_tree);
1592       vam->json_tree.type = VAT_JSON_NONE;
1593     }
1594   else
1595     {
1596       /* just print [] */
1597       vat_json_init_array (&vam->json_tree);
1598       vat_json_print (vam->ofp, &vam->json_tree);
1599       vam->json_tree.type = VAT_JSON_NONE;
1600     }
1601
1602   vam->retval = retval;
1603   vam->result_ready = 1;
1604 }
1605
1606 static void
1607   vl_api_bridge_domain_set_mac_age_reply_t_handler
1608   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612   if (vam->async_mode)
1613     {
1614       vam->async_errors += (retval < 0);
1615     }
1616   else
1617     {
1618       vam->retval = retval;
1619       vam->result_ready = 1;
1620     }
1621 }
1622
1623 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1624   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1625 {
1626   vat_main_t *vam = &vat_main;
1627   vat_json_node_t node;
1628
1629   vat_json_init_object (&node);
1630   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1631
1632   vat_json_print (vam->ofp, &node);
1633   vat_json_free (&node);
1634
1635   vam->retval = ntohl (mp->retval);
1636   vam->result_ready = 1;
1637 }
1638
1639 static void
1640 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   i32 retval = ntohl (mp->retval);
1644   if (vam->async_mode)
1645     {
1646       vam->async_errors += (retval < 0);
1647     }
1648   else
1649     {
1650       vam->retval = retval;
1651       vam->result_ready = 1;
1652     }
1653 }
1654
1655 static void vl_api_l2_flags_reply_t_handler_json
1656   (vl_api_l2_flags_reply_t * mp)
1657 {
1658   vat_main_t *vam = &vat_main;
1659   vat_json_node_t node;
1660
1661   vat_json_init_object (&node);
1662   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1663   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1664                             ntohl (mp->resulting_feature_bitmap));
1665
1666   vat_json_print (vam->ofp, &node);
1667   vat_json_free (&node);
1668
1669   vam->retval = ntohl (mp->retval);
1670   vam->result_ready = 1;
1671 }
1672
1673 static void vl_api_bridge_flags_reply_t_handler
1674   (vl_api_bridge_flags_reply_t * mp)
1675 {
1676   vat_main_t *vam = &vat_main;
1677   i32 retval = ntohl (mp->retval);
1678   if (vam->async_mode)
1679     {
1680       vam->async_errors += (retval < 0);
1681     }
1682   else
1683     {
1684       vam->retval = retval;
1685       vam->result_ready = 1;
1686     }
1687 }
1688
1689 static void vl_api_bridge_flags_reply_t_handler_json
1690   (vl_api_bridge_flags_reply_t * mp)
1691 {
1692   vat_main_t *vam = &vat_main;
1693   vat_json_node_t node;
1694
1695   vat_json_init_object (&node);
1696   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1697   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1698                             ntohl (mp->resulting_feature_bitmap));
1699
1700   vat_json_print (vam->ofp, &node);
1701   vat_json_free (&node);
1702
1703   vam->retval = ntohl (mp->retval);
1704   vam->result_ready = 1;
1705 }
1706
1707 static void vl_api_tap_connect_reply_t_handler
1708   (vl_api_tap_connect_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   i32 retval = ntohl (mp->retval);
1712   if (vam->async_mode)
1713     {
1714       vam->async_errors += (retval < 0);
1715     }
1716   else
1717     {
1718       vam->retval = retval;
1719       vam->sw_if_index = ntohl (mp->sw_if_index);
1720       vam->result_ready = 1;
1721     }
1722
1723 }
1724
1725 static void vl_api_tap_connect_reply_t_handler_json
1726   (vl_api_tap_connect_reply_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   vat_json_node_t node;
1730
1731   vat_json_init_object (&node);
1732   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1733   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1734
1735   vat_json_print (vam->ofp, &node);
1736   vat_json_free (&node);
1737
1738   vam->retval = ntohl (mp->retval);
1739   vam->result_ready = 1;
1740
1741 }
1742
1743 static void
1744 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1745 {
1746   vat_main_t *vam = &vat_main;
1747   i32 retval = ntohl (mp->retval);
1748   if (vam->async_mode)
1749     {
1750       vam->async_errors += (retval < 0);
1751     }
1752   else
1753     {
1754       vam->retval = retval;
1755       vam->sw_if_index = ntohl (mp->sw_if_index);
1756       vam->result_ready = 1;
1757     }
1758 }
1759
1760 static void vl_api_tap_modify_reply_t_handler_json
1761   (vl_api_tap_modify_reply_t * mp)
1762 {
1763   vat_main_t *vam = &vat_main;
1764   vat_json_node_t node;
1765
1766   vat_json_init_object (&node);
1767   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1768   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1769
1770   vat_json_print (vam->ofp, &node);
1771   vat_json_free (&node);
1772
1773   vam->retval = ntohl (mp->retval);
1774   vam->result_ready = 1;
1775 }
1776
1777 static void
1778 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1779 {
1780   vat_main_t *vam = &vat_main;
1781   i32 retval = ntohl (mp->retval);
1782   if (vam->async_mode)
1783     {
1784       vam->async_errors += (retval < 0);
1785     }
1786   else
1787     {
1788       vam->retval = retval;
1789       vam->result_ready = 1;
1790     }
1791 }
1792
1793 static void vl_api_tap_delete_reply_t_handler_json
1794   (vl_api_tap_delete_reply_t * mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   vat_json_node_t node;
1798
1799   vat_json_init_object (&node);
1800   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1801
1802   vat_json_print (vam->ofp, &node);
1803   vat_json_free (&node);
1804
1805   vam->retval = ntohl (mp->retval);
1806   vam->result_ready = 1;
1807 }
1808
1809 static void
1810 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813   i32 retval = ntohl (mp->retval);
1814   if (vam->async_mode)
1815     {
1816       vam->async_errors += (retval < 0);
1817     }
1818   else
1819     {
1820       vam->retval = retval;
1821       vam->sw_if_index = ntohl (mp->sw_if_index);
1822       vam->result_ready = 1;
1823     }
1824
1825 }
1826
1827 static void vl_api_tap_create_v2_reply_t_handler_json
1828   (vl_api_tap_create_v2_reply_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   vat_json_node_t node;
1832
1833   vat_json_init_object (&node);
1834   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1835   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1836
1837   vat_json_print (vam->ofp, &node);
1838   vat_json_free (&node);
1839
1840   vam->retval = ntohl (mp->retval);
1841   vam->result_ready = 1;
1842
1843 }
1844
1845 static void
1846 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1847 {
1848   vat_main_t *vam = &vat_main;
1849   i32 retval = ntohl (mp->retval);
1850   if (vam->async_mode)
1851     {
1852       vam->async_errors += (retval < 0);
1853     }
1854   else
1855     {
1856       vam->retval = retval;
1857       vam->result_ready = 1;
1858     }
1859 }
1860
1861 static void vl_api_tap_delete_v2_reply_t_handler_json
1862   (vl_api_tap_delete_v2_reply_t * mp)
1863 {
1864   vat_main_t *vam = &vat_main;
1865   vat_json_node_t node;
1866
1867   vat_json_init_object (&node);
1868   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1869
1870   vat_json_print (vam->ofp, &node);
1871   vat_json_free (&node);
1872
1873   vam->retval = ntohl (mp->retval);
1874   vam->result_ready = 1;
1875 }
1876
1877 static void
1878 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1879 {
1880   vat_main_t *vam = &vat_main;
1881   i32 retval = ntohl (mp->retval);
1882
1883   if (vam->async_mode)
1884     {
1885       vam->async_errors += (retval < 0);
1886     }
1887   else
1888     {
1889       vam->retval = retval;
1890       vam->sw_if_index = ntohl (mp->sw_if_index);
1891       vam->result_ready = 1;
1892     }
1893 }
1894
1895 static void vl_api_bond_create_reply_t_handler_json
1896   (vl_api_bond_create_reply_t * mp)
1897 {
1898   vat_main_t *vam = &vat_main;
1899   vat_json_node_t node;
1900
1901   vat_json_init_object (&node);
1902   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1903   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1904
1905   vat_json_print (vam->ofp, &node);
1906   vat_json_free (&node);
1907
1908   vam->retval = ntohl (mp->retval);
1909   vam->result_ready = 1;
1910 }
1911
1912 static void
1913 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1914 {
1915   vat_main_t *vam = &vat_main;
1916   i32 retval = ntohl (mp->retval);
1917
1918   if (vam->async_mode)
1919     {
1920       vam->async_errors += (retval < 0);
1921     }
1922   else
1923     {
1924       vam->retval = retval;
1925       vam->result_ready = 1;
1926     }
1927 }
1928
1929 static void vl_api_bond_delete_reply_t_handler_json
1930   (vl_api_bond_delete_reply_t * mp)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   vat_json_node_t node;
1934
1935   vat_json_init_object (&node);
1936   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1937
1938   vat_json_print (vam->ofp, &node);
1939   vat_json_free (&node);
1940
1941   vam->retval = ntohl (mp->retval);
1942   vam->result_ready = 1;
1943 }
1944
1945 static void
1946 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   i32 retval = ntohl (mp->retval);
1950
1951   if (vam->async_mode)
1952     {
1953       vam->async_errors += (retval < 0);
1954     }
1955   else
1956     {
1957       vam->retval = retval;
1958       vam->result_ready = 1;
1959     }
1960 }
1961
1962 static void vl_api_bond_enslave_reply_t_handler_json
1963   (vl_api_bond_enslave_reply_t * mp)
1964 {
1965   vat_main_t *vam = &vat_main;
1966   vat_json_node_t node;
1967
1968   vat_json_init_object (&node);
1969   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1970
1971   vat_json_print (vam->ofp, &node);
1972   vat_json_free (&node);
1973
1974   vam->retval = ntohl (mp->retval);
1975   vam->result_ready = 1;
1976 }
1977
1978 static void
1979 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1980                                           mp)
1981 {
1982   vat_main_t *vam = &vat_main;
1983   i32 retval = ntohl (mp->retval);
1984
1985   if (vam->async_mode)
1986     {
1987       vam->async_errors += (retval < 0);
1988     }
1989   else
1990     {
1991       vam->retval = retval;
1992       vam->result_ready = 1;
1993     }
1994 }
1995
1996 static void vl_api_bond_detach_slave_reply_t_handler_json
1997   (vl_api_bond_detach_slave_reply_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vat_json_node_t node;
2001
2002   vat_json_init_object (&node);
2003   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2004
2005   vat_json_print (vam->ofp, &node);
2006   vat_json_free (&node);
2007
2008   vam->retval = ntohl (mp->retval);
2009   vam->result_ready = 1;
2010 }
2011
2012 static void vl_api_sw_interface_bond_details_t_handler
2013   (vl_api_sw_interface_bond_details_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016
2017   print (vam->ofp,
2018          "%-16s %-12d %-12U %-13U %-14u %-14u",
2019          mp->interface_name, ntohl (mp->sw_if_index),
2020          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2021          ntohl (mp->active_slaves), ntohl (mp->slaves));
2022 }
2023
2024 static void vl_api_sw_interface_bond_details_t_handler_json
2025   (vl_api_sw_interface_bond_details_t * mp)
2026 {
2027   vat_main_t *vam = &vat_main;
2028   vat_json_node_t *node = NULL;
2029
2030   if (VAT_JSON_ARRAY != vam->json_tree.type)
2031     {
2032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2033       vat_json_init_array (&vam->json_tree);
2034     }
2035   node = vat_json_array_add (&vam->json_tree);
2036
2037   vat_json_init_object (node);
2038   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2039   vat_json_object_add_string_copy (node, "interface_name",
2040                                    mp->interface_name);
2041   vat_json_object_add_uint (node, "mode", mp->mode);
2042   vat_json_object_add_uint (node, "load_balance", mp->lb);
2043   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2044   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2045 }
2046
2047 static int
2048 api_sw_interface_bond_dump (vat_main_t * vam)
2049 {
2050   vl_api_sw_interface_bond_dump_t *mp;
2051   vl_api_control_ping_t *mp_ping;
2052   int ret;
2053
2054   print (vam->ofp,
2055          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2056          "interface name", "sw_if_index", "mode", "load balance",
2057          "active slaves", "slaves");
2058
2059   /* Get list of bond interfaces */
2060   M (SW_INTERFACE_BOND_DUMP, mp);
2061   S (mp);
2062
2063   /* Use a control ping for synchronization */
2064   MPING (CONTROL_PING, mp_ping);
2065   S (mp_ping);
2066
2067   W (ret);
2068   return ret;
2069 }
2070
2071 static void vl_api_sw_interface_slave_details_t_handler
2072   (vl_api_sw_interface_slave_details_t * mp)
2073 {
2074   vat_main_t *vam = &vat_main;
2075
2076   print (vam->ofp,
2077          "%-25s %-12d %-12d %d", mp->interface_name,
2078          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2079 }
2080
2081 static void vl_api_sw_interface_slave_details_t_handler_json
2082   (vl_api_sw_interface_slave_details_t * mp)
2083 {
2084   vat_main_t *vam = &vat_main;
2085   vat_json_node_t *node = NULL;
2086
2087   if (VAT_JSON_ARRAY != vam->json_tree.type)
2088     {
2089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2090       vat_json_init_array (&vam->json_tree);
2091     }
2092   node = vat_json_array_add (&vam->json_tree);
2093
2094   vat_json_init_object (node);
2095   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2096   vat_json_object_add_string_copy (node, "interface_name",
2097                                    mp->interface_name);
2098   vat_json_object_add_uint (node, "passive", mp->is_passive);
2099   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2100 }
2101
2102 static int
2103 api_sw_interface_slave_dump (vat_main_t * vam)
2104 {
2105   unformat_input_t *i = vam->input;
2106   vl_api_sw_interface_slave_dump_t *mp;
2107   vl_api_control_ping_t *mp_ping;
2108   u32 sw_if_index = ~0;
2109   u8 sw_if_index_set = 0;
2110   int ret;
2111
2112   /* Parse args required to build the message */
2113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2114     {
2115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2116         sw_if_index_set = 1;
2117       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2118         sw_if_index_set = 1;
2119       else
2120         break;
2121     }
2122
2123   if (sw_if_index_set == 0)
2124     {
2125       errmsg ("missing vpp interface name. ");
2126       return -99;
2127     }
2128
2129   print (vam->ofp,
2130          "\n%-25s %-12s %-12s %s",
2131          "slave interface name", "sw_if_index", "passive", "long_timeout");
2132
2133   /* Get list of bond interfaces */
2134   M (SW_INTERFACE_SLAVE_DUMP, mp);
2135   mp->sw_if_index = ntohl (sw_if_index);
2136   S (mp);
2137
2138   /* Use a control ping for synchronization */
2139   MPING (CONTROL_PING, mp_ping);
2140   S (mp_ping);
2141
2142   W (ret);
2143   return ret;
2144 }
2145
2146 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2147   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2148 {
2149   vat_main_t *vam = &vat_main;
2150   i32 retval = ntohl (mp->retval);
2151   if (vam->async_mode)
2152     {
2153       vam->async_errors += (retval < 0);
2154     }
2155   else
2156     {
2157       vam->retval = retval;
2158       vam->sw_if_index = ntohl (mp->sw_if_index);
2159       vam->result_ready = 1;
2160     }
2161   vam->regenerate_interface_table = 1;
2162 }
2163
2164 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2165   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vat_json_node_t node;
2169
2170   vat_json_init_object (&node);
2171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2172   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2173                             ntohl (mp->sw_if_index));
2174
2175   vat_json_print (vam->ofp, &node);
2176   vat_json_free (&node);
2177
2178   vam->retval = ntohl (mp->retval);
2179   vam->result_ready = 1;
2180 }
2181
2182 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2183   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   i32 retval = ntohl (mp->retval);
2187   if (vam->async_mode)
2188     {
2189       vam->async_errors += (retval < 0);
2190     }
2191   else
2192     {
2193       vam->retval = retval;
2194       vam->sw_if_index = ntohl (mp->sw_if_index);
2195       vam->result_ready = 1;
2196     }
2197 }
2198
2199 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2200   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vat_json_node_t node;
2204
2205   vat_json_init_object (&node);
2206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2207   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2208
2209   vat_json_print (vam->ofp, &node);
2210   vat_json_free (&node);
2211
2212   vam->retval = ntohl (mp->retval);
2213   vam->result_ready = 1;
2214 }
2215
2216 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2217   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   i32 retval = ntohl (mp->retval);
2221   if (vam->async_mode)
2222     {
2223       vam->async_errors += (retval < 0);
2224     }
2225   else
2226     {
2227       vam->retval = retval;
2228       vam->result_ready = 1;
2229     }
2230 }
2231
2232 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2233   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   vat_json_node_t node;
2237
2238   vat_json_init_object (&node);
2239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2240   vat_json_object_add_uint (&node, "fwd_entry_index",
2241                             clib_net_to_host_u32 (mp->fwd_entry_index));
2242
2243   vat_json_print (vam->ofp, &node);
2244   vat_json_free (&node);
2245
2246   vam->retval = ntohl (mp->retval);
2247   vam->result_ready = 1;
2248 }
2249
2250 u8 *
2251 format_lisp_transport_protocol (u8 * s, va_list * args)
2252 {
2253   u32 proto = va_arg (*args, u32);
2254
2255   switch (proto)
2256     {
2257     case 1:
2258       return format (s, "udp");
2259     case 2:
2260       return format (s, "api");
2261     default:
2262       return 0;
2263     }
2264   return 0;
2265 }
2266
2267 static void vl_api_one_get_transport_protocol_reply_t_handler
2268   (vl_api_one_get_transport_protocol_reply_t * mp)
2269 {
2270   vat_main_t *vam = &vat_main;
2271   i32 retval = ntohl (mp->retval);
2272   if (vam->async_mode)
2273     {
2274       vam->async_errors += (retval < 0);
2275     }
2276   else
2277     {
2278       u32 proto = mp->protocol;
2279       print (vam->ofp, "Transport protocol: %U",
2280              format_lisp_transport_protocol, proto);
2281       vam->retval = retval;
2282       vam->result_ready = 1;
2283     }
2284 }
2285
2286 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2287   (vl_api_one_get_transport_protocol_reply_t * mp)
2288 {
2289   vat_main_t *vam = &vat_main;
2290   vat_json_node_t node;
2291   u8 *s;
2292
2293   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2294   vec_add1 (s, 0);
2295
2296   vat_json_init_object (&node);
2297   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2298   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2299
2300   vec_free (s);
2301   vat_json_print (vam->ofp, &node);
2302   vat_json_free (&node);
2303
2304   vam->retval = ntohl (mp->retval);
2305   vam->result_ready = 1;
2306 }
2307
2308 static void vl_api_one_add_del_locator_set_reply_t_handler
2309   (vl_api_one_add_del_locator_set_reply_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   i32 retval = ntohl (mp->retval);
2313   if (vam->async_mode)
2314     {
2315       vam->async_errors += (retval < 0);
2316     }
2317   else
2318     {
2319       vam->retval = retval;
2320       vam->result_ready = 1;
2321     }
2322 }
2323
2324 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2325   (vl_api_one_add_del_locator_set_reply_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t node;
2329
2330   vat_json_init_object (&node);
2331   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2332   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2333
2334   vat_json_print (vam->ofp, &node);
2335   vat_json_free (&node);
2336
2337   vam->retval = ntohl (mp->retval);
2338   vam->result_ready = 1;
2339 }
2340
2341 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2342   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   i32 retval = ntohl (mp->retval);
2346   if (vam->async_mode)
2347     {
2348       vam->async_errors += (retval < 0);
2349     }
2350   else
2351     {
2352       vam->retval = retval;
2353       vam->sw_if_index = ntohl (mp->sw_if_index);
2354       vam->result_ready = 1;
2355     }
2356   vam->regenerate_interface_table = 1;
2357 }
2358
2359 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2360   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   vat_json_node_t node;
2364
2365   vat_json_init_object (&node);
2366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2368
2369   vat_json_print (vam->ofp, &node);
2370   vat_json_free (&node);
2371
2372   vam->retval = ntohl (mp->retval);
2373   vam->result_ready = 1;
2374 }
2375
2376 static void vl_api_vxlan_offload_rx_reply_t_handler
2377   (vl_api_vxlan_offload_rx_reply_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   i32 retval = ntohl (mp->retval);
2381   if (vam->async_mode)
2382     {
2383       vam->async_errors += (retval < 0);
2384     }
2385   else
2386     {
2387       vam->retval = retval;
2388       vam->result_ready = 1;
2389     }
2390 }
2391
2392 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2393   (vl_api_vxlan_offload_rx_reply_t * mp)
2394 {
2395   vat_main_t *vam = &vat_main;
2396   vat_json_node_t node;
2397
2398   vat_json_init_object (&node);
2399   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2400
2401   vat_json_print (vam->ofp, &node);
2402   vat_json_free (&node);
2403
2404   vam->retval = ntohl (mp->retval);
2405   vam->result_ready = 1;
2406 }
2407
2408 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2409   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   i32 retval = ntohl (mp->retval);
2413   if (vam->async_mode)
2414     {
2415       vam->async_errors += (retval < 0);
2416     }
2417   else
2418     {
2419       vam->retval = retval;
2420       vam->sw_if_index = ntohl (mp->sw_if_index);
2421       vam->result_ready = 1;
2422     }
2423 }
2424
2425 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2426   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   vat_json_node_t node;
2430
2431   vat_json_init_object (&node);
2432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2433   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2434
2435   vat_json_print (vam->ofp, &node);
2436   vat_json_free (&node);
2437
2438   vam->retval = ntohl (mp->retval);
2439   vam->result_ready = 1;
2440 }
2441
2442 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2443   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2444 {
2445   vat_main_t *vam = &vat_main;
2446   i32 retval = ntohl (mp->retval);
2447   if (vam->async_mode)
2448     {
2449       vam->async_errors += (retval < 0);
2450     }
2451   else
2452     {
2453       vam->retval = retval;
2454       vam->sw_if_index = ntohl (mp->sw_if_index);
2455       vam->result_ready = 1;
2456     }
2457   vam->regenerate_interface_table = 1;
2458 }
2459
2460 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2461   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464   vat_json_node_t node;
2465
2466   vat_json_init_object (&node);
2467   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2468   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void vl_api_gre_add_del_tunnel_reply_t_handler
2478   (vl_api_gre_add_del_tunnel_reply_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   i32 retval = ntohl (mp->retval);
2482   if (vam->async_mode)
2483     {
2484       vam->async_errors += (retval < 0);
2485     }
2486   else
2487     {
2488       vam->retval = retval;
2489       vam->sw_if_index = ntohl (mp->sw_if_index);
2490       vam->result_ready = 1;
2491     }
2492 }
2493
2494 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2495   (vl_api_gre_add_del_tunnel_reply_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   vat_json_node_t node;
2499
2500   vat_json_init_object (&node);
2501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2503
2504   vat_json_print (vam->ofp, &node);
2505   vat_json_free (&node);
2506
2507   vam->retval = ntohl (mp->retval);
2508   vam->result_ready = 1;
2509 }
2510
2511 static void vl_api_create_vhost_user_if_reply_t_handler
2512   (vl_api_create_vhost_user_if_reply_t * mp)
2513 {
2514   vat_main_t *vam = &vat_main;
2515   i32 retval = ntohl (mp->retval);
2516   if (vam->async_mode)
2517     {
2518       vam->async_errors += (retval < 0);
2519     }
2520   else
2521     {
2522       vam->retval = retval;
2523       vam->sw_if_index = ntohl (mp->sw_if_index);
2524       vam->result_ready = 1;
2525     }
2526   vam->regenerate_interface_table = 1;
2527 }
2528
2529 static void vl_api_create_vhost_user_if_reply_t_handler_json
2530   (vl_api_create_vhost_user_if_reply_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   vat_json_node_t node;
2534
2535   vat_json_init_object (&node);
2536   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2537   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2538
2539   vat_json_print (vam->ofp, &node);
2540   vat_json_free (&node);
2541
2542   vam->retval = ntohl (mp->retval);
2543   vam->result_ready = 1;
2544 }
2545
2546 static void vl_api_dns_resolve_name_reply_t_handler
2547   (vl_api_dns_resolve_name_reply_t * mp)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   i32 retval = ntohl (mp->retval);
2551   if (vam->async_mode)
2552     {
2553       vam->async_errors += (retval < 0);
2554     }
2555   else
2556     {
2557       vam->retval = retval;
2558       vam->result_ready = 1;
2559
2560       if (retval == 0)
2561         {
2562           if (mp->ip4_set)
2563             clib_warning ("ip4 address %U", format_ip4_address,
2564                           (ip4_address_t *) mp->ip4_address);
2565           if (mp->ip6_set)
2566             clib_warning ("ip6 address %U", format_ip6_address,
2567                           (ip6_address_t *) mp->ip6_address);
2568         }
2569       else
2570         clib_warning ("retval %d", retval);
2571     }
2572 }
2573
2574 static void vl_api_dns_resolve_name_reply_t_handler_json
2575   (vl_api_dns_resolve_name_reply_t * mp)
2576 {
2577   clib_warning ("not implemented");
2578 }
2579
2580 static void vl_api_dns_resolve_ip_reply_t_handler
2581   (vl_api_dns_resolve_ip_reply_t * mp)
2582 {
2583   vat_main_t *vam = &vat_main;
2584   i32 retval = ntohl (mp->retval);
2585   if (vam->async_mode)
2586     {
2587       vam->async_errors += (retval < 0);
2588     }
2589   else
2590     {
2591       vam->retval = retval;
2592       vam->result_ready = 1;
2593
2594       if (retval == 0)
2595         {
2596           clib_warning ("canonical name %s", mp->name);
2597         }
2598       else
2599         clib_warning ("retval %d", retval);
2600     }
2601 }
2602
2603 static void vl_api_dns_resolve_ip_reply_t_handler_json
2604   (vl_api_dns_resolve_ip_reply_t * mp)
2605 {
2606   clib_warning ("not implemented");
2607 }
2608
2609
2610 static void vl_api_ip_address_details_t_handler
2611   (vl_api_ip_address_details_t * mp)
2612 {
2613   vat_main_t *vam = &vat_main;
2614   static ip_address_details_t empty_ip_address_details = { {0} };
2615   ip_address_details_t *address = NULL;
2616   ip_details_t *current_ip_details = NULL;
2617   ip_details_t *details = NULL;
2618
2619   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2620
2621   if (!details || vam->current_sw_if_index >= vec_len (details)
2622       || !details[vam->current_sw_if_index].present)
2623     {
2624       errmsg ("ip address details arrived but not stored");
2625       errmsg ("ip_dump should be called first");
2626       return;
2627     }
2628
2629   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2630
2631 #define addresses (current_ip_details->addr)
2632
2633   vec_validate_init_empty (addresses, vec_len (addresses),
2634                            empty_ip_address_details);
2635
2636   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2637
2638   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2639   address->prefix_length = mp->prefix_length;
2640 #undef addresses
2641 }
2642
2643 static void vl_api_ip_address_details_t_handler_json
2644   (vl_api_ip_address_details_t * mp)
2645 {
2646   vat_main_t *vam = &vat_main;
2647   vat_json_node_t *node = NULL;
2648   struct in6_addr ip6;
2649   struct in_addr ip4;
2650
2651   if (VAT_JSON_ARRAY != vam->json_tree.type)
2652     {
2653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2654       vat_json_init_array (&vam->json_tree);
2655     }
2656   node = vat_json_array_add (&vam->json_tree);
2657
2658   vat_json_init_object (node);
2659   if (vam->is_ipv6)
2660     {
2661       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2662       vat_json_object_add_ip6 (node, "ip", ip6);
2663     }
2664   else
2665     {
2666       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2667       vat_json_object_add_ip4 (node, "ip", ip4);
2668     }
2669   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2670 }
2671
2672 static void
2673 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2674 {
2675   vat_main_t *vam = &vat_main;
2676   static ip_details_t empty_ip_details = { 0 };
2677   ip_details_t *ip = NULL;
2678   u32 sw_if_index = ~0;
2679
2680   sw_if_index = ntohl (mp->sw_if_index);
2681
2682   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2683                            sw_if_index, empty_ip_details);
2684
2685   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2686                          sw_if_index);
2687
2688   ip->present = 1;
2689 }
2690
2691 static void
2692 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695
2696   if (VAT_JSON_ARRAY != vam->json_tree.type)
2697     {
2698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2699       vat_json_init_array (&vam->json_tree);
2700     }
2701   vat_json_array_add_uint (&vam->json_tree,
2702                            clib_net_to_host_u32 (mp->sw_if_index));
2703 }
2704
2705 static void
2706 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2707 {
2708   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2709           "router_addr %U host_mac %U",
2710           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2711           mp->lease.hostname,
2712           format_ip4_address, &mp->lease.host_address,
2713           format_ip4_address, &mp->lease.router_address,
2714           format_ethernet_address, mp->lease.host_mac);
2715 }
2716
2717 static void vl_api_dhcp_compl_event_t_handler_json
2718   (vl_api_dhcp_compl_event_t * mp)
2719 {
2720   /* JSON output not supported */
2721 }
2722
2723 static void
2724 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2725                               u32 counter)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   static u64 default_counter = 0;
2729
2730   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2731                            NULL);
2732   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2733                            sw_if_index, default_counter);
2734   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2735 }
2736
2737 static void
2738 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2739                                 interface_counter_t counter)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   static interface_counter_t default_counter = { 0, };
2743
2744   vec_validate_init_empty (vam->combined_interface_counters,
2745                            vnet_counter_type, NULL);
2746   vec_validate_init_empty (vam->combined_interface_counters
2747                            [vnet_counter_type], sw_if_index, default_counter);
2748   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2749 }
2750
2751 static void vl_api_vnet_interface_simple_counters_t_handler
2752   (vl_api_vnet_interface_simple_counters_t * mp)
2753 {
2754   /* not supported */
2755 }
2756
2757 static void vl_api_vnet_interface_combined_counters_t_handler
2758   (vl_api_vnet_interface_combined_counters_t * mp)
2759 {
2760   /* not supported */
2761 }
2762
2763 static void vl_api_vnet_interface_simple_counters_t_handler_json
2764   (vl_api_vnet_interface_simple_counters_t * mp)
2765 {
2766   u64 *v_packets;
2767   u64 packets;
2768   u32 count;
2769   u32 first_sw_if_index;
2770   int i;
2771
2772   count = ntohl (mp->count);
2773   first_sw_if_index = ntohl (mp->first_sw_if_index);
2774
2775   v_packets = (u64 *) & mp->data;
2776   for (i = 0; i < count; i++)
2777     {
2778       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2779       set_simple_interface_counter (mp->vnet_counter_type,
2780                                     first_sw_if_index + i, packets);
2781       v_packets++;
2782     }
2783 }
2784
2785 static void vl_api_vnet_interface_combined_counters_t_handler_json
2786   (vl_api_vnet_interface_combined_counters_t * mp)
2787 {
2788   interface_counter_t counter;
2789   vlib_counter_t *v;
2790   u32 first_sw_if_index;
2791   int i;
2792   u32 count;
2793
2794   count = ntohl (mp->count);
2795   first_sw_if_index = ntohl (mp->first_sw_if_index);
2796
2797   v = (vlib_counter_t *) & mp->data;
2798   for (i = 0; i < count; i++)
2799     {
2800       counter.packets =
2801         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2802       counter.bytes =
2803         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2804       set_combined_interface_counter (mp->vnet_counter_type,
2805                                       first_sw_if_index + i, counter);
2806       v++;
2807     }
2808 }
2809
2810 static u32
2811 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2812 {
2813   vat_main_t *vam = &vat_main;
2814   u32 i;
2815
2816   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2817     {
2818       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2819         {
2820           return i;
2821         }
2822     }
2823   return ~0;
2824 }
2825
2826 static u32
2827 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   u32 i;
2831
2832   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2833     {
2834       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2835         {
2836           return i;
2837         }
2838     }
2839   return ~0;
2840 }
2841
2842 static void vl_api_vnet_ip4_fib_counters_t_handler
2843   (vl_api_vnet_ip4_fib_counters_t * mp)
2844 {
2845   /* not supported */
2846 }
2847
2848 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2849   (vl_api_vnet_ip4_fib_counters_t * mp)
2850 {
2851   vat_main_t *vam = &vat_main;
2852   vl_api_ip4_fib_counter_t *v;
2853   ip4_fib_counter_t *counter;
2854   struct in_addr ip4;
2855   u32 vrf_id;
2856   u32 vrf_index;
2857   u32 count;
2858   int i;
2859
2860   vrf_id = ntohl (mp->vrf_id);
2861   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2862   if (~0 == vrf_index)
2863     {
2864       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2865       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2866       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2867       vec_validate (vam->ip4_fib_counters, vrf_index);
2868       vam->ip4_fib_counters[vrf_index] = NULL;
2869     }
2870
2871   vec_free (vam->ip4_fib_counters[vrf_index]);
2872   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2873   count = ntohl (mp->count);
2874   for (i = 0; i < count; i++)
2875     {
2876       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2877       counter = &vam->ip4_fib_counters[vrf_index][i];
2878       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2879       counter->address = ip4;
2880       counter->address_length = v->address_length;
2881       counter->packets = clib_net_to_host_u64 (v->packets);
2882       counter->bytes = clib_net_to_host_u64 (v->bytes);
2883       v++;
2884     }
2885 }
2886
2887 static void vl_api_vnet_ip4_nbr_counters_t_handler
2888   (vl_api_vnet_ip4_nbr_counters_t * mp)
2889 {
2890   /* not supported */
2891 }
2892
2893 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2894   (vl_api_vnet_ip4_nbr_counters_t * mp)
2895 {
2896   vat_main_t *vam = &vat_main;
2897   vl_api_ip4_nbr_counter_t *v;
2898   ip4_nbr_counter_t *counter;
2899   u32 sw_if_index;
2900   u32 count;
2901   int i;
2902
2903   sw_if_index = ntohl (mp->sw_if_index);
2904   count = ntohl (mp->count);
2905   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2906
2907   if (mp->begin)
2908     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2909
2910   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2911   for (i = 0; i < count; i++)
2912     {
2913       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2914       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2915       counter->address.s_addr = v->address;
2916       counter->packets = clib_net_to_host_u64 (v->packets);
2917       counter->bytes = clib_net_to_host_u64 (v->bytes);
2918       counter->linkt = v->link_type;
2919       v++;
2920     }
2921 }
2922
2923 static void vl_api_vnet_ip6_fib_counters_t_handler
2924   (vl_api_vnet_ip6_fib_counters_t * mp)
2925 {
2926   /* not supported */
2927 }
2928
2929 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2930   (vl_api_vnet_ip6_fib_counters_t * mp)
2931 {
2932   vat_main_t *vam = &vat_main;
2933   vl_api_ip6_fib_counter_t *v;
2934   ip6_fib_counter_t *counter;
2935   struct in6_addr ip6;
2936   u32 vrf_id;
2937   u32 vrf_index;
2938   u32 count;
2939   int i;
2940
2941   vrf_id = ntohl (mp->vrf_id);
2942   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2943   if (~0 == vrf_index)
2944     {
2945       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2946       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2947       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2948       vec_validate (vam->ip6_fib_counters, vrf_index);
2949       vam->ip6_fib_counters[vrf_index] = NULL;
2950     }
2951
2952   vec_free (vam->ip6_fib_counters[vrf_index]);
2953   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2954   count = ntohl (mp->count);
2955   for (i = 0; i < count; i++)
2956     {
2957       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2958       counter = &vam->ip6_fib_counters[vrf_index][i];
2959       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2960       counter->address = ip6;
2961       counter->address_length = v->address_length;
2962       counter->packets = clib_net_to_host_u64 (v->packets);
2963       counter->bytes = clib_net_to_host_u64 (v->bytes);
2964       v++;
2965     }
2966 }
2967
2968 static void vl_api_vnet_ip6_nbr_counters_t_handler
2969   (vl_api_vnet_ip6_nbr_counters_t * mp)
2970 {
2971   /* not supported */
2972 }
2973
2974 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2975   (vl_api_vnet_ip6_nbr_counters_t * mp)
2976 {
2977   vat_main_t *vam = &vat_main;
2978   vl_api_ip6_nbr_counter_t *v;
2979   ip6_nbr_counter_t *counter;
2980   struct in6_addr ip6;
2981   u32 sw_if_index;
2982   u32 count;
2983   int i;
2984
2985   sw_if_index = ntohl (mp->sw_if_index);
2986   count = ntohl (mp->count);
2987   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2988
2989   if (mp->begin)
2990     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2991
2992   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2993   for (i = 0; i < count; i++)
2994     {
2995       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2996       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2997       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2998       counter->address = ip6;
2999       counter->packets = clib_net_to_host_u64 (v->packets);
3000       counter->bytes = clib_net_to_host_u64 (v->bytes);
3001       v++;
3002     }
3003 }
3004
3005 static void vl_api_get_first_msg_id_reply_t_handler
3006   (vl_api_get_first_msg_id_reply_t * mp)
3007 {
3008   vat_main_t *vam = &vat_main;
3009   i32 retval = ntohl (mp->retval);
3010
3011   if (vam->async_mode)
3012     {
3013       vam->async_errors += (retval < 0);
3014     }
3015   else
3016     {
3017       vam->retval = retval;
3018       vam->result_ready = 1;
3019     }
3020   if (retval >= 0)
3021     {
3022       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3023     }
3024 }
3025
3026 static void vl_api_get_first_msg_id_reply_t_handler_json
3027   (vl_api_get_first_msg_id_reply_t * mp)
3028 {
3029   vat_main_t *vam = &vat_main;
3030   vat_json_node_t node;
3031
3032   vat_json_init_object (&node);
3033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3034   vat_json_object_add_uint (&node, "first_msg_id",
3035                             (uint) ntohs (mp->first_msg_id));
3036
3037   vat_json_print (vam->ofp, &node);
3038   vat_json_free (&node);
3039
3040   vam->retval = ntohl (mp->retval);
3041   vam->result_ready = 1;
3042 }
3043
3044 static void vl_api_get_node_graph_reply_t_handler
3045   (vl_api_get_node_graph_reply_t * mp)
3046 {
3047   vat_main_t *vam = &vat_main;
3048   api_main_t *am = &api_main;
3049   i32 retval = ntohl (mp->retval);
3050   u8 *pvt_copy, *reply;
3051   void *oldheap;
3052   vlib_node_t *node;
3053   int i;
3054
3055   if (vam->async_mode)
3056     {
3057       vam->async_errors += (retval < 0);
3058     }
3059   else
3060     {
3061       vam->retval = retval;
3062       vam->result_ready = 1;
3063     }
3064
3065   /* "Should never happen..." */
3066   if (retval != 0)
3067     return;
3068
3069   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3070   pvt_copy = vec_dup (reply);
3071
3072   /* Toss the shared-memory original... */
3073   pthread_mutex_lock (&am->vlib_rp->mutex);
3074   oldheap = svm_push_data_heap (am->vlib_rp);
3075
3076   vec_free (reply);
3077
3078   svm_pop_heap (oldheap);
3079   pthread_mutex_unlock (&am->vlib_rp->mutex);
3080
3081   if (vam->graph_nodes)
3082     {
3083       hash_free (vam->graph_node_index_by_name);
3084
3085       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3086         {
3087           node = vam->graph_nodes[0][i];
3088           vec_free (node->name);
3089           vec_free (node->next_nodes);
3090           vec_free (node);
3091         }
3092       vec_free (vam->graph_nodes[0]);
3093       vec_free (vam->graph_nodes);
3094     }
3095
3096   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3097   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3098   vec_free (pvt_copy);
3099
3100   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3101     {
3102       node = vam->graph_nodes[0][i];
3103       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3104     }
3105 }
3106
3107 static void vl_api_get_node_graph_reply_t_handler_json
3108   (vl_api_get_node_graph_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   api_main_t *am = &api_main;
3112   void *oldheap;
3113   vat_json_node_t node;
3114   u8 *reply;
3115
3116   /* $$$$ make this real? */
3117   vat_json_init_object (&node);
3118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3119   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3120
3121   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3122
3123   /* Toss the shared-memory original... */
3124   pthread_mutex_lock (&am->vlib_rp->mutex);
3125   oldheap = svm_push_data_heap (am->vlib_rp);
3126
3127   vec_free (reply);
3128
3129   svm_pop_heap (oldheap);
3130   pthread_mutex_unlock (&am->vlib_rp->mutex);
3131
3132   vat_json_print (vam->ofp, &node);
3133   vat_json_free (&node);
3134
3135   vam->retval = ntohl (mp->retval);
3136   vam->result_ready = 1;
3137 }
3138
3139 static void
3140 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3141 {
3142   vat_main_t *vam = &vat_main;
3143   u8 *s = 0;
3144
3145   if (mp->local)
3146     {
3147       s = format (s, "%=16d%=16d%=16d",
3148                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3149     }
3150   else
3151     {
3152       s = format (s, "%=16U%=16d%=16d",
3153                   mp->is_ipv6 ? format_ip6_address :
3154                   format_ip4_address,
3155                   mp->ip_address, mp->priority, mp->weight);
3156     }
3157
3158   print (vam->ofp, "%v", s);
3159   vec_free (s);
3160 }
3161
3162 static void
3163 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t *node = NULL;
3167   struct in6_addr ip6;
3168   struct in_addr ip4;
3169
3170   if (VAT_JSON_ARRAY != vam->json_tree.type)
3171     {
3172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3173       vat_json_init_array (&vam->json_tree);
3174     }
3175   node = vat_json_array_add (&vam->json_tree);
3176   vat_json_init_object (node);
3177
3178   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3179   vat_json_object_add_uint (node, "priority", mp->priority);
3180   vat_json_object_add_uint (node, "weight", mp->weight);
3181
3182   if (mp->local)
3183     vat_json_object_add_uint (node, "sw_if_index",
3184                               clib_net_to_host_u32 (mp->sw_if_index));
3185   else
3186     {
3187       if (mp->is_ipv6)
3188         {
3189           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3190           vat_json_object_add_ip6 (node, "address", ip6);
3191         }
3192       else
3193         {
3194           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3195           vat_json_object_add_ip4 (node, "address", ip4);
3196         }
3197     }
3198 }
3199
3200 static void
3201 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3202                                           mp)
3203 {
3204   vat_main_t *vam = &vat_main;
3205   u8 *ls_name = 0;
3206
3207   ls_name = format (0, "%s", mp->ls_name);
3208
3209   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3210          ls_name);
3211   vec_free (ls_name);
3212 }
3213
3214 static void
3215   vl_api_one_locator_set_details_t_handler_json
3216   (vl_api_one_locator_set_details_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t *node = 0;
3220   u8 *ls_name = 0;
3221
3222   ls_name = format (0, "%s", mp->ls_name);
3223   vec_add1 (ls_name, 0);
3224
3225   if (VAT_JSON_ARRAY != vam->json_tree.type)
3226     {
3227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3228       vat_json_init_array (&vam->json_tree);
3229     }
3230   node = vat_json_array_add (&vam->json_tree);
3231
3232   vat_json_init_object (node);
3233   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3234   vat_json_object_add_uint (node, "ls_index",
3235                             clib_net_to_host_u32 (mp->ls_index));
3236   vec_free (ls_name);
3237 }
3238
3239 typedef struct
3240 {
3241   u32 spi;
3242   u8 si;
3243 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3244
3245 uword
3246 unformat_nsh_address (unformat_input_t * input, va_list * args)
3247 {
3248   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3249   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3250 }
3251
3252 u8 *
3253 format_nsh_address_vat (u8 * s, va_list * args)
3254 {
3255   nsh_t *a = va_arg (*args, nsh_t *);
3256   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3257 }
3258
3259 static u8 *
3260 format_lisp_flat_eid (u8 * s, va_list * args)
3261 {
3262   u32 type = va_arg (*args, u32);
3263   u8 *eid = va_arg (*args, u8 *);
3264   u32 eid_len = va_arg (*args, u32);
3265
3266   switch (type)
3267     {
3268     case 0:
3269       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3270     case 1:
3271       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3272     case 2:
3273       return format (s, "%U", format_ethernet_address, eid);
3274     case 3:
3275       return format (s, "%U", format_nsh_address_vat, eid);
3276     }
3277   return 0;
3278 }
3279
3280 static u8 *
3281 format_lisp_eid_vat (u8 * s, va_list * args)
3282 {
3283   u32 type = va_arg (*args, u32);
3284   u8 *eid = va_arg (*args, u8 *);
3285   u32 eid_len = va_arg (*args, u32);
3286   u8 *seid = va_arg (*args, u8 *);
3287   u32 seid_len = va_arg (*args, u32);
3288   u32 is_src_dst = va_arg (*args, u32);
3289
3290   if (is_src_dst)
3291     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3292
3293   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3294
3295   return s;
3296 }
3297
3298 static void
3299 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3300 {
3301   vat_main_t *vam = &vat_main;
3302   u8 *s = 0, *eid = 0;
3303
3304   if (~0 == mp->locator_set_index)
3305     s = format (0, "action: %d", mp->action);
3306   else
3307     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3308
3309   eid = format (0, "%U", format_lisp_eid_vat,
3310                 mp->eid_type,
3311                 mp->eid,
3312                 mp->eid_prefix_len,
3313                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3314   vec_add1 (eid, 0);
3315
3316   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3317          clib_net_to_host_u32 (mp->vni),
3318          eid,
3319          mp->is_local ? "local" : "remote",
3320          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3321          clib_net_to_host_u16 (mp->key_id), mp->key);
3322
3323   vec_free (s);
3324   vec_free (eid);
3325 }
3326
3327 static void
3328 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3329                                              * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332   vat_json_node_t *node = 0;
3333   u8 *eid = 0;
3334
3335   if (VAT_JSON_ARRAY != vam->json_tree.type)
3336     {
3337       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3338       vat_json_init_array (&vam->json_tree);
3339     }
3340   node = vat_json_array_add (&vam->json_tree);
3341
3342   vat_json_init_object (node);
3343   if (~0 == mp->locator_set_index)
3344     vat_json_object_add_uint (node, "action", mp->action);
3345   else
3346     vat_json_object_add_uint (node, "locator_set_index",
3347                               clib_net_to_host_u32 (mp->locator_set_index));
3348
3349   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3350   if (mp->eid_type == 3)
3351     {
3352       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3353       vat_json_init_object (nsh_json);
3354       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3355       vat_json_object_add_uint (nsh_json, "spi",
3356                                 clib_net_to_host_u32 (nsh->spi));
3357       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3358     }
3359   else
3360     {
3361       eid = format (0, "%U", format_lisp_eid_vat,
3362                     mp->eid_type,
3363                     mp->eid,
3364                     mp->eid_prefix_len,
3365                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3366       vec_add1 (eid, 0);
3367       vat_json_object_add_string_copy (node, "eid", eid);
3368       vec_free (eid);
3369     }
3370   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3371   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3372   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3373
3374   if (mp->key_id)
3375     {
3376       vat_json_object_add_uint (node, "key_id",
3377                                 clib_net_to_host_u16 (mp->key_id));
3378       vat_json_object_add_string_copy (node, "key", mp->key);
3379     }
3380 }
3381
3382 static void
3383 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3384 {
3385   vat_main_t *vam = &vat_main;
3386   u8 *seid = 0, *deid = 0;
3387   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3388
3389   deid = format (0, "%U", format_lisp_eid_vat,
3390                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3391
3392   seid = format (0, "%U", format_lisp_eid_vat,
3393                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3394
3395   vec_add1 (deid, 0);
3396   vec_add1 (seid, 0);
3397
3398   if (mp->is_ip4)
3399     format_ip_address_fcn = format_ip4_address;
3400   else
3401     format_ip_address_fcn = format_ip6_address;
3402
3403
3404   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3405          clib_net_to_host_u32 (mp->vni),
3406          seid, deid,
3407          format_ip_address_fcn, mp->lloc,
3408          format_ip_address_fcn, mp->rloc,
3409          clib_net_to_host_u32 (mp->pkt_count),
3410          clib_net_to_host_u32 (mp->bytes));
3411
3412   vec_free (deid);
3413   vec_free (seid);
3414 }
3415
3416 static void
3417 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3418 {
3419   struct in6_addr ip6;
3420   struct in_addr ip4;
3421   vat_main_t *vam = &vat_main;
3422   vat_json_node_t *node = 0;
3423   u8 *deid = 0, *seid = 0;
3424
3425   if (VAT_JSON_ARRAY != vam->json_tree.type)
3426     {
3427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3428       vat_json_init_array (&vam->json_tree);
3429     }
3430   node = vat_json_array_add (&vam->json_tree);
3431
3432   vat_json_init_object (node);
3433   deid = format (0, "%U", format_lisp_eid_vat,
3434                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3435
3436   seid = format (0, "%U", format_lisp_eid_vat,
3437                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3438
3439   vec_add1 (deid, 0);
3440   vec_add1 (seid, 0);
3441
3442   vat_json_object_add_string_copy (node, "seid", seid);
3443   vat_json_object_add_string_copy (node, "deid", deid);
3444   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3445
3446   if (mp->is_ip4)
3447     {
3448       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3449       vat_json_object_add_ip4 (node, "lloc", ip4);
3450       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3451       vat_json_object_add_ip4 (node, "rloc", ip4);
3452     }
3453   else
3454     {
3455       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3456       vat_json_object_add_ip6 (node, "lloc", ip6);
3457       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3458       vat_json_object_add_ip6 (node, "rloc", ip6);
3459     }
3460   vat_json_object_add_uint (node, "pkt_count",
3461                             clib_net_to_host_u32 (mp->pkt_count));
3462   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3463
3464   vec_free (deid);
3465   vec_free (seid);
3466 }
3467
3468 static void
3469   vl_api_one_eid_table_map_details_t_handler
3470   (vl_api_one_eid_table_map_details_t * mp)
3471 {
3472   vat_main_t *vam = &vat_main;
3473
3474   u8 *line = format (0, "%=10d%=10d",
3475                      clib_net_to_host_u32 (mp->vni),
3476                      clib_net_to_host_u32 (mp->dp_table));
3477   print (vam->ofp, "%v", line);
3478   vec_free (line);
3479 }
3480
3481 static void
3482   vl_api_one_eid_table_map_details_t_handler_json
3483   (vl_api_one_eid_table_map_details_t * mp)
3484 {
3485   vat_main_t *vam = &vat_main;
3486   vat_json_node_t *node = NULL;
3487
3488   if (VAT_JSON_ARRAY != vam->json_tree.type)
3489     {
3490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3491       vat_json_init_array (&vam->json_tree);
3492     }
3493   node = vat_json_array_add (&vam->json_tree);
3494   vat_json_init_object (node);
3495   vat_json_object_add_uint (node, "dp_table",
3496                             clib_net_to_host_u32 (mp->dp_table));
3497   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3498 }
3499
3500 static void
3501   vl_api_one_eid_table_vni_details_t_handler
3502   (vl_api_one_eid_table_vni_details_t * mp)
3503 {
3504   vat_main_t *vam = &vat_main;
3505
3506   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3507   print (vam->ofp, "%v", line);
3508   vec_free (line);
3509 }
3510
3511 static void
3512   vl_api_one_eid_table_vni_details_t_handler_json
3513   (vl_api_one_eid_table_vni_details_t * mp)
3514 {
3515   vat_main_t *vam = &vat_main;
3516   vat_json_node_t *node = NULL;
3517
3518   if (VAT_JSON_ARRAY != vam->json_tree.type)
3519     {
3520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3521       vat_json_init_array (&vam->json_tree);
3522     }
3523   node = vat_json_array_add (&vam->json_tree);
3524   vat_json_init_object (node);
3525   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3526 }
3527
3528 static void
3529   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3530   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3531 {
3532   vat_main_t *vam = &vat_main;
3533   int retval = clib_net_to_host_u32 (mp->retval);
3534
3535   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3536   print (vam->ofp, "fallback threshold value: %d", mp->value);
3537
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540 }
3541
3542 static void
3543   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3544   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3545 {
3546   vat_main_t *vam = &vat_main;
3547   vat_json_node_t _node, *node = &_node;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549
3550   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3551   vat_json_init_object (node);
3552   vat_json_object_add_uint (node, "value", mp->value);
3553
3554   vat_json_print (vam->ofp, node);
3555   vat_json_free (node);
3556
3557   vam->retval = retval;
3558   vam->result_ready = 1;
3559 }
3560
3561 static void
3562   vl_api_show_one_map_register_state_reply_t_handler
3563   (vl_api_show_one_map_register_state_reply_t * mp)
3564 {
3565   vat_main_t *vam = &vat_main;
3566   int retval = clib_net_to_host_u32 (mp->retval);
3567
3568   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3569
3570   vam->retval = retval;
3571   vam->result_ready = 1;
3572 }
3573
3574 static void
3575   vl_api_show_one_map_register_state_reply_t_handler_json
3576   (vl_api_show_one_map_register_state_reply_t * mp)
3577 {
3578   vat_main_t *vam = &vat_main;
3579   vat_json_node_t _node, *node = &_node;
3580   int retval = clib_net_to_host_u32 (mp->retval);
3581
3582   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3583
3584   vat_json_init_object (node);
3585   vat_json_object_add_string_copy (node, "state", s);
3586
3587   vat_json_print (vam->ofp, node);
3588   vat_json_free (node);
3589
3590   vam->retval = retval;
3591   vam->result_ready = 1;
3592   vec_free (s);
3593 }
3594
3595 static void
3596   vl_api_show_one_rloc_probe_state_reply_t_handler
3597   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3598 {
3599   vat_main_t *vam = &vat_main;
3600   int retval = clib_net_to_host_u32 (mp->retval);
3601
3602   if (retval)
3603     goto end;
3604
3605   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3606 end:
3607   vam->retval = retval;
3608   vam->result_ready = 1;
3609 }
3610
3611 static void
3612   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3613   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3614 {
3615   vat_main_t *vam = &vat_main;
3616   vat_json_node_t _node, *node = &_node;
3617   int retval = clib_net_to_host_u32 (mp->retval);
3618
3619   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3620   vat_json_init_object (node);
3621   vat_json_object_add_string_copy (node, "state", s);
3622
3623   vat_json_print (vam->ofp, node);
3624   vat_json_free (node);
3625
3626   vam->retval = retval;
3627   vam->result_ready = 1;
3628   vec_free (s);
3629 }
3630
3631 static void
3632   vl_api_show_one_stats_enable_disable_reply_t_handler
3633   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3634 {
3635   vat_main_t *vam = &vat_main;
3636   int retval = clib_net_to_host_u32 (mp->retval);
3637
3638   if (retval)
3639     goto end;
3640
3641   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3642 end:
3643   vam->retval = retval;
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3649   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   vat_json_node_t _node, *node = &_node;
3653   int retval = clib_net_to_host_u32 (mp->retval);
3654
3655   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3656   vat_json_init_object (node);
3657   vat_json_object_add_string_copy (node, "state", s);
3658
3659   vat_json_print (vam->ofp, node);
3660   vat_json_free (node);
3661
3662   vam->retval = retval;
3663   vam->result_ready = 1;
3664   vec_free (s);
3665 }
3666
3667 static void
3668 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3669 {
3670   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3671   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3672   e->vni = clib_net_to_host_u32 (e->vni);
3673 }
3674
3675 static void
3676   gpe_fwd_entries_get_reply_t_net_to_host
3677   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3678 {
3679   u32 i;
3680
3681   mp->count = clib_net_to_host_u32 (mp->count);
3682   for (i = 0; i < mp->count; i++)
3683     {
3684       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3685     }
3686 }
3687
3688 static u8 *
3689 format_gpe_encap_mode (u8 * s, va_list * args)
3690 {
3691   u32 mode = va_arg (*args, u32);
3692
3693   switch (mode)
3694     {
3695     case 0:
3696       return format (s, "lisp");
3697     case 1:
3698       return format (s, "vxlan");
3699     }
3700   return 0;
3701 }
3702
3703 static void
3704   vl_api_gpe_get_encap_mode_reply_t_handler
3705   (vl_api_gpe_get_encap_mode_reply_t * mp)
3706 {
3707   vat_main_t *vam = &vat_main;
3708
3709   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3710   vam->retval = ntohl (mp->retval);
3711   vam->result_ready = 1;
3712 }
3713
3714 static void
3715   vl_api_gpe_get_encap_mode_reply_t_handler_json
3716   (vl_api_gpe_get_encap_mode_reply_t * mp)
3717 {
3718   vat_main_t *vam = &vat_main;
3719   vat_json_node_t node;
3720
3721   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3722   vec_add1 (encap_mode, 0);
3723
3724   vat_json_init_object (&node);
3725   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3726
3727   vec_free (encap_mode);
3728   vat_json_print (vam->ofp, &node);
3729   vat_json_free (&node);
3730
3731   vam->retval = ntohl (mp->retval);
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_fwd_entry_path_details_t_handler
3737   (vl_api_gpe_fwd_entry_path_details_t * mp)
3738 {
3739   vat_main_t *vam = &vat_main;
3740   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3741
3742   if (mp->lcl_loc.is_ip4)
3743     format_ip_address_fcn = format_ip4_address;
3744   else
3745     format_ip_address_fcn = format_ip6_address;
3746
3747   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3748          format_ip_address_fcn, &mp->lcl_loc,
3749          format_ip_address_fcn, &mp->rmt_loc);
3750 }
3751
3752 static void
3753 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3754 {
3755   struct in6_addr ip6;
3756   struct in_addr ip4;
3757
3758   if (loc->is_ip4)
3759     {
3760       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3761       vat_json_object_add_ip4 (n, "address", ip4);
3762     }
3763   else
3764     {
3765       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3766       vat_json_object_add_ip6 (n, "address", ip6);
3767     }
3768   vat_json_object_add_uint (n, "weight", loc->weight);
3769 }
3770
3771 static void
3772   vl_api_gpe_fwd_entry_path_details_t_handler_json
3773   (vl_api_gpe_fwd_entry_path_details_t * mp)
3774 {
3775   vat_main_t *vam = &vat_main;
3776   vat_json_node_t *node = NULL;
3777   vat_json_node_t *loc_node;
3778
3779   if (VAT_JSON_ARRAY != vam->json_tree.type)
3780     {
3781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3782       vat_json_init_array (&vam->json_tree);
3783     }
3784   node = vat_json_array_add (&vam->json_tree);
3785   vat_json_init_object (node);
3786
3787   loc_node = vat_json_object_add (node, "local_locator");
3788   vat_json_init_object (loc_node);
3789   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3790
3791   loc_node = vat_json_object_add (node, "remote_locator");
3792   vat_json_init_object (loc_node);
3793   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3794 }
3795
3796 static void
3797   vl_api_gpe_fwd_entries_get_reply_t_handler
3798   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3799 {
3800   vat_main_t *vam = &vat_main;
3801   u32 i;
3802   int retval = clib_net_to_host_u32 (mp->retval);
3803   vl_api_gpe_fwd_entry_t *e;
3804
3805   if (retval)
3806     goto end;
3807
3808   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3809
3810   for (i = 0; i < mp->count; i++)
3811     {
3812       e = &mp->entries[i];
3813       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3814              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3815              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3816     }
3817
3818 end:
3819   vam->retval = retval;
3820   vam->result_ready = 1;
3821 }
3822
3823 static void
3824   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3825   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3826 {
3827   u8 *s = 0;
3828   vat_main_t *vam = &vat_main;
3829   vat_json_node_t *e = 0, root;
3830   u32 i;
3831   int retval = clib_net_to_host_u32 (mp->retval);
3832   vl_api_gpe_fwd_entry_t *fwd;
3833
3834   if (retval)
3835     goto end;
3836
3837   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3838   vat_json_init_array (&root);
3839
3840   for (i = 0; i < mp->count; i++)
3841     {
3842       e = vat_json_array_add (&root);
3843       fwd = &mp->entries[i];
3844
3845       vat_json_init_object (e);
3846       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3847       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3848       vat_json_object_add_int (e, "vni", fwd->vni);
3849       vat_json_object_add_int (e, "action", fwd->action);
3850
3851       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3852                   fwd->leid_prefix_len);
3853       vec_add1 (s, 0);
3854       vat_json_object_add_string_copy (e, "leid", s);
3855       vec_free (s);
3856
3857       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3858                   fwd->reid_prefix_len);
3859       vec_add1 (s, 0);
3860       vat_json_object_add_string_copy (e, "reid", s);
3861       vec_free (s);
3862     }
3863
3864   vat_json_print (vam->ofp, &root);
3865   vat_json_free (&root);
3866
3867 end:
3868   vam->retval = retval;
3869   vam->result_ready = 1;
3870 }
3871
3872 static void
3873   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3874   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3875 {
3876   vat_main_t *vam = &vat_main;
3877   u32 i, n;
3878   int retval = clib_net_to_host_u32 (mp->retval);
3879   vl_api_gpe_native_fwd_rpath_t *r;
3880
3881   if (retval)
3882     goto end;
3883
3884   n = clib_net_to_host_u32 (mp->count);
3885
3886   for (i = 0; i < n; i++)
3887     {
3888       r = &mp->entries[i];
3889       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3890              clib_net_to_host_u32 (r->fib_index),
3891              clib_net_to_host_u32 (r->nh_sw_if_index),
3892              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3893     }
3894
3895 end:
3896   vam->retval = retval;
3897   vam->result_ready = 1;
3898 }
3899
3900 static void
3901   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3902   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3903 {
3904   vat_main_t *vam = &vat_main;
3905   vat_json_node_t root, *e;
3906   u32 i, n;
3907   int retval = clib_net_to_host_u32 (mp->retval);
3908   vl_api_gpe_native_fwd_rpath_t *r;
3909   u8 *s;
3910
3911   if (retval)
3912     goto end;
3913
3914   n = clib_net_to_host_u32 (mp->count);
3915   vat_json_init_array (&root);
3916
3917   for (i = 0; i < n; i++)
3918     {
3919       e = vat_json_array_add (&root);
3920       vat_json_init_object (e);
3921       r = &mp->entries[i];
3922       s =
3923         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3924                 r->nh_addr);
3925       vec_add1 (s, 0);
3926       vat_json_object_add_string_copy (e, "ip4", s);
3927       vec_free (s);
3928
3929       vat_json_object_add_uint (e, "fib_index",
3930                                 clib_net_to_host_u32 (r->fib_index));
3931       vat_json_object_add_uint (e, "nh_sw_if_index",
3932                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3933     }
3934
3935   vat_json_print (vam->ofp, &root);
3936   vat_json_free (&root);
3937
3938 end:
3939   vam->retval = retval;
3940   vam->result_ready = 1;
3941 }
3942
3943 static void
3944   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3945   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3946 {
3947   vat_main_t *vam = &vat_main;
3948   u32 i, n;
3949   int retval = clib_net_to_host_u32 (mp->retval);
3950
3951   if (retval)
3952     goto end;
3953
3954   n = clib_net_to_host_u32 (mp->count);
3955
3956   for (i = 0; i < n; i++)
3957     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3958
3959 end:
3960   vam->retval = retval;
3961   vam->result_ready = 1;
3962 }
3963
3964 static void
3965   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3966   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3967 {
3968   vat_main_t *vam = &vat_main;
3969   vat_json_node_t root;
3970   u32 i, n;
3971   int retval = clib_net_to_host_u32 (mp->retval);
3972
3973   if (retval)
3974     goto end;
3975
3976   n = clib_net_to_host_u32 (mp->count);
3977   vat_json_init_array (&root);
3978
3979   for (i = 0; i < n; i++)
3980     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3981
3982   vat_json_print (vam->ofp, &root);
3983   vat_json_free (&root);
3984
3985 end:
3986   vam->retval = retval;
3987   vam->result_ready = 1;
3988 }
3989
3990 static void
3991   vl_api_one_ndp_entries_get_reply_t_handler
3992   (vl_api_one_ndp_entries_get_reply_t * mp)
3993 {
3994   vat_main_t *vam = &vat_main;
3995   u32 i, n;
3996   int retval = clib_net_to_host_u32 (mp->retval);
3997
3998   if (retval)
3999     goto end;
4000
4001   n = clib_net_to_host_u32 (mp->count);
4002
4003   for (i = 0; i < n; i++)
4004     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
4005            format_ethernet_address, mp->entries[i].mac);
4006
4007 end:
4008   vam->retval = retval;
4009   vam->result_ready = 1;
4010 }
4011
4012 static void
4013   vl_api_one_ndp_entries_get_reply_t_handler_json
4014   (vl_api_one_ndp_entries_get_reply_t * mp)
4015 {
4016   u8 *s = 0;
4017   vat_main_t *vam = &vat_main;
4018   vat_json_node_t *e = 0, root;
4019   u32 i, n;
4020   int retval = clib_net_to_host_u32 (mp->retval);
4021   vl_api_one_ndp_entry_t *arp_entry;
4022
4023   if (retval)
4024     goto end;
4025
4026   n = clib_net_to_host_u32 (mp->count);
4027   vat_json_init_array (&root);
4028
4029   for (i = 0; i < n; i++)
4030     {
4031       e = vat_json_array_add (&root);
4032       arp_entry = &mp->entries[i];
4033
4034       vat_json_init_object (e);
4035       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4036       vec_add1 (s, 0);
4037
4038       vat_json_object_add_string_copy (e, "mac", s);
4039       vec_free (s);
4040
4041       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4042       vec_add1 (s, 0);
4043       vat_json_object_add_string_copy (e, "ip6", s);
4044       vec_free (s);
4045     }
4046
4047   vat_json_print (vam->ofp, &root);
4048   vat_json_free (&root);
4049
4050 end:
4051   vam->retval = retval;
4052   vam->result_ready = 1;
4053 }
4054
4055 static void
4056   vl_api_one_l2_arp_entries_get_reply_t_handler
4057   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4058 {
4059   vat_main_t *vam = &vat_main;
4060   u32 i, n;
4061   int retval = clib_net_to_host_u32 (mp->retval);
4062
4063   if (retval)
4064     goto end;
4065
4066   n = clib_net_to_host_u32 (mp->count);
4067
4068   for (i = 0; i < n; i++)
4069     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4070            format_ethernet_address, mp->entries[i].mac);
4071
4072 end:
4073   vam->retval = retval;
4074   vam->result_ready = 1;
4075 }
4076
4077 static void
4078   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4079   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4080 {
4081   u8 *s = 0;
4082   vat_main_t *vam = &vat_main;
4083   vat_json_node_t *e = 0, root;
4084   u32 i, n;
4085   int retval = clib_net_to_host_u32 (mp->retval);
4086   vl_api_one_l2_arp_entry_t *arp_entry;
4087
4088   if (retval)
4089     goto end;
4090
4091   n = clib_net_to_host_u32 (mp->count);
4092   vat_json_init_array (&root);
4093
4094   for (i = 0; i < n; i++)
4095     {
4096       e = vat_json_array_add (&root);
4097       arp_entry = &mp->entries[i];
4098
4099       vat_json_init_object (e);
4100       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4101       vec_add1 (s, 0);
4102
4103       vat_json_object_add_string_copy (e, "mac", s);
4104       vec_free (s);
4105
4106       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4107       vec_add1 (s, 0);
4108       vat_json_object_add_string_copy (e, "ip4", s);
4109       vec_free (s);
4110     }
4111
4112   vat_json_print (vam->ofp, &root);
4113   vat_json_free (&root);
4114
4115 end:
4116   vam->retval = retval;
4117   vam->result_ready = 1;
4118 }
4119
4120 static void
4121 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4122 {
4123   vat_main_t *vam = &vat_main;
4124   u32 i, n;
4125   int retval = clib_net_to_host_u32 (mp->retval);
4126
4127   if (retval)
4128     goto end;
4129
4130   n = clib_net_to_host_u32 (mp->count);
4131
4132   for (i = 0; i < n; i++)
4133     {
4134       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4135     }
4136
4137 end:
4138   vam->retval = retval;
4139   vam->result_ready = 1;
4140 }
4141
4142 static void
4143   vl_api_one_ndp_bd_get_reply_t_handler_json
4144   (vl_api_one_ndp_bd_get_reply_t * mp)
4145 {
4146   vat_main_t *vam = &vat_main;
4147   vat_json_node_t root;
4148   u32 i, n;
4149   int retval = clib_net_to_host_u32 (mp->retval);
4150
4151   if (retval)
4152     goto end;
4153
4154   n = clib_net_to_host_u32 (mp->count);
4155   vat_json_init_array (&root);
4156
4157   for (i = 0; i < n; i++)
4158     {
4159       vat_json_array_add_uint (&root,
4160                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4161     }
4162
4163   vat_json_print (vam->ofp, &root);
4164   vat_json_free (&root);
4165
4166 end:
4167   vam->retval = retval;
4168   vam->result_ready = 1;
4169 }
4170
4171 static void
4172   vl_api_one_l2_arp_bd_get_reply_t_handler
4173   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4174 {
4175   vat_main_t *vam = &vat_main;
4176   u32 i, n;
4177   int retval = clib_net_to_host_u32 (mp->retval);
4178
4179   if (retval)
4180     goto end;
4181
4182   n = clib_net_to_host_u32 (mp->count);
4183
4184   for (i = 0; i < n; i++)
4185     {
4186       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4187     }
4188
4189 end:
4190   vam->retval = retval;
4191   vam->result_ready = 1;
4192 }
4193
4194 static void
4195   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4196   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   vat_json_node_t root;
4200   u32 i, n;
4201   int retval = clib_net_to_host_u32 (mp->retval);
4202
4203   if (retval)
4204     goto end;
4205
4206   n = clib_net_to_host_u32 (mp->count);
4207   vat_json_init_array (&root);
4208
4209   for (i = 0; i < n; i++)
4210     {
4211       vat_json_array_add_uint (&root,
4212                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4213     }
4214
4215   vat_json_print (vam->ofp, &root);
4216   vat_json_free (&root);
4217
4218 end:
4219   vam->retval = retval;
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_one_adjacencies_get_reply_t_handler
4225   (vl_api_one_adjacencies_get_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   u32 i, n;
4229   int retval = clib_net_to_host_u32 (mp->retval);
4230   vl_api_one_adjacency_t *a;
4231
4232   if (retval)
4233     goto end;
4234
4235   n = clib_net_to_host_u32 (mp->count);
4236
4237   for (i = 0; i < n; i++)
4238     {
4239       a = &mp->adjacencies[i];
4240       print (vam->ofp, "%U %40U",
4241              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4242              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4243     }
4244
4245 end:
4246   vam->retval = retval;
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_adjacencies_get_reply_t_handler_json
4252   (vl_api_one_adjacencies_get_reply_t * mp)
4253 {
4254   u8 *s = 0;
4255   vat_main_t *vam = &vat_main;
4256   vat_json_node_t *e = 0, root;
4257   u32 i, n;
4258   int retval = clib_net_to_host_u32 (mp->retval);
4259   vl_api_one_adjacency_t *a;
4260
4261   if (retval)
4262     goto end;
4263
4264   n = clib_net_to_host_u32 (mp->count);
4265   vat_json_init_array (&root);
4266
4267   for (i = 0; i < n; i++)
4268     {
4269       e = vat_json_array_add (&root);
4270       a = &mp->adjacencies[i];
4271
4272       vat_json_init_object (e);
4273       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4274                   a->leid_prefix_len);
4275       vec_add1 (s, 0);
4276       vat_json_object_add_string_copy (e, "leid", s);
4277       vec_free (s);
4278
4279       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4280                   a->reid_prefix_len);
4281       vec_add1 (s, 0);
4282       vat_json_object_add_string_copy (e, "reid", s);
4283       vec_free (s);
4284     }
4285
4286   vat_json_print (vam->ofp, &root);
4287   vat_json_free (&root);
4288
4289 end:
4290   vam->retval = retval;
4291   vam->result_ready = 1;
4292 }
4293
4294 static void
4295 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4296 {
4297   vat_main_t *vam = &vat_main;
4298
4299   print (vam->ofp, "%=20U",
4300          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4301          mp->ip_address);
4302 }
4303
4304 static void
4305   vl_api_one_map_server_details_t_handler_json
4306   (vl_api_one_map_server_details_t * mp)
4307 {
4308   vat_main_t *vam = &vat_main;
4309   vat_json_node_t *node = NULL;
4310   struct in6_addr ip6;
4311   struct in_addr ip4;
4312
4313   if (VAT_JSON_ARRAY != vam->json_tree.type)
4314     {
4315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4316       vat_json_init_array (&vam->json_tree);
4317     }
4318   node = vat_json_array_add (&vam->json_tree);
4319
4320   vat_json_init_object (node);
4321   if (mp->is_ipv6)
4322     {
4323       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4324       vat_json_object_add_ip6 (node, "map-server", ip6);
4325     }
4326   else
4327     {
4328       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4329       vat_json_object_add_ip4 (node, "map-server", ip4);
4330     }
4331 }
4332
4333 static void
4334 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4335                                            * mp)
4336 {
4337   vat_main_t *vam = &vat_main;
4338
4339   print (vam->ofp, "%=20U",
4340          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4341          mp->ip_address);
4342 }
4343
4344 static void
4345   vl_api_one_map_resolver_details_t_handler_json
4346   (vl_api_one_map_resolver_details_t * mp)
4347 {
4348   vat_main_t *vam = &vat_main;
4349   vat_json_node_t *node = NULL;
4350   struct in6_addr ip6;
4351   struct in_addr ip4;
4352
4353   if (VAT_JSON_ARRAY != vam->json_tree.type)
4354     {
4355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4356       vat_json_init_array (&vam->json_tree);
4357     }
4358   node = vat_json_array_add (&vam->json_tree);
4359
4360   vat_json_init_object (node);
4361   if (mp->is_ipv6)
4362     {
4363       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4364       vat_json_object_add_ip6 (node, "map resolver", ip6);
4365     }
4366   else
4367     {
4368       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4369       vat_json_object_add_ip4 (node, "map resolver", ip4);
4370     }
4371 }
4372
4373 static void
4374 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4375 {
4376   vat_main_t *vam = &vat_main;
4377   i32 retval = ntohl (mp->retval);
4378
4379   if (0 <= retval)
4380     {
4381       print (vam->ofp, "feature: %s\ngpe: %s",
4382              mp->feature_status ? "enabled" : "disabled",
4383              mp->gpe_status ? "enabled" : "disabled");
4384     }
4385
4386   vam->retval = retval;
4387   vam->result_ready = 1;
4388 }
4389
4390 static void
4391   vl_api_show_one_status_reply_t_handler_json
4392   (vl_api_show_one_status_reply_t * mp)
4393 {
4394   vat_main_t *vam = &vat_main;
4395   vat_json_node_t node;
4396   u8 *gpe_status = NULL;
4397   u8 *feature_status = NULL;
4398
4399   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4400   feature_status = format (0, "%s",
4401                            mp->feature_status ? "enabled" : "disabled");
4402   vec_add1 (gpe_status, 0);
4403   vec_add1 (feature_status, 0);
4404
4405   vat_json_init_object (&node);
4406   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4407   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4408
4409   vec_free (gpe_status);
4410   vec_free (feature_status);
4411
4412   vat_json_print (vam->ofp, &node);
4413   vat_json_free (&node);
4414
4415   vam->retval = ntohl (mp->retval);
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4421   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   i32 retval = ntohl (mp->retval);
4425
4426   if (retval >= 0)
4427     {
4428       print (vam->ofp, "%=20s", mp->locator_set_name);
4429     }
4430
4431   vam->retval = retval;
4432   vam->result_ready = 1;
4433 }
4434
4435 static void
4436   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4437   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4438 {
4439   vat_main_t *vam = &vat_main;
4440   vat_json_node_t *node = NULL;
4441
4442   if (VAT_JSON_ARRAY != vam->json_tree.type)
4443     {
4444       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4445       vat_json_init_array (&vam->json_tree);
4446     }
4447   node = vat_json_array_add (&vam->json_tree);
4448
4449   vat_json_init_object (node);
4450   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4451
4452   vat_json_print (vam->ofp, node);
4453   vat_json_free (node);
4454
4455   vam->retval = ntohl (mp->retval);
4456   vam->result_ready = 1;
4457 }
4458
4459 static u8 *
4460 format_lisp_map_request_mode (u8 * s, va_list * args)
4461 {
4462   u32 mode = va_arg (*args, u32);
4463
4464   switch (mode)
4465     {
4466     case 0:
4467       return format (0, "dst-only");
4468     case 1:
4469       return format (0, "src-dst");
4470     }
4471   return 0;
4472 }
4473
4474 static void
4475   vl_api_show_one_map_request_mode_reply_t_handler
4476   (vl_api_show_one_map_request_mode_reply_t * mp)
4477 {
4478   vat_main_t *vam = &vat_main;
4479   i32 retval = ntohl (mp->retval);
4480
4481   if (0 <= retval)
4482     {
4483       u32 mode = mp->mode;
4484       print (vam->ofp, "map_request_mode: %U",
4485              format_lisp_map_request_mode, mode);
4486     }
4487
4488   vam->retval = retval;
4489   vam->result_ready = 1;
4490 }
4491
4492 static void
4493   vl_api_show_one_map_request_mode_reply_t_handler_json
4494   (vl_api_show_one_map_request_mode_reply_t * mp)
4495 {
4496   vat_main_t *vam = &vat_main;
4497   vat_json_node_t node;
4498   u8 *s = 0;
4499   u32 mode;
4500
4501   mode = mp->mode;
4502   s = format (0, "%U", format_lisp_map_request_mode, mode);
4503   vec_add1 (s, 0);
4504
4505   vat_json_init_object (&node);
4506   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4507   vat_json_print (vam->ofp, &node);
4508   vat_json_free (&node);
4509
4510   vec_free (s);
4511   vam->retval = ntohl (mp->retval);
4512   vam->result_ready = 1;
4513 }
4514
4515 static void
4516   vl_api_one_show_xtr_mode_reply_t_handler
4517   (vl_api_one_show_xtr_mode_reply_t * mp)
4518 {
4519   vat_main_t *vam = &vat_main;
4520   i32 retval = ntohl (mp->retval);
4521
4522   if (0 <= retval)
4523     {
4524       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4525     }
4526
4527   vam->retval = retval;
4528   vam->result_ready = 1;
4529 }
4530
4531 static void
4532   vl_api_one_show_xtr_mode_reply_t_handler_json
4533   (vl_api_one_show_xtr_mode_reply_t * mp)
4534 {
4535   vat_main_t *vam = &vat_main;
4536   vat_json_node_t node;
4537   u8 *status = 0;
4538
4539   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4540   vec_add1 (status, 0);
4541
4542   vat_json_init_object (&node);
4543   vat_json_object_add_string_copy (&node, "status", status);
4544
4545   vec_free (status);
4546
4547   vat_json_print (vam->ofp, &node);
4548   vat_json_free (&node);
4549
4550   vam->retval = ntohl (mp->retval);
4551   vam->result_ready = 1;
4552 }
4553
4554 static void
4555   vl_api_one_show_pitr_mode_reply_t_handler
4556   (vl_api_one_show_pitr_mode_reply_t * mp)
4557 {
4558   vat_main_t *vam = &vat_main;
4559   i32 retval = ntohl (mp->retval);
4560
4561   if (0 <= retval)
4562     {
4563       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4564     }
4565
4566   vam->retval = retval;
4567   vam->result_ready = 1;
4568 }
4569
4570 static void
4571   vl_api_one_show_pitr_mode_reply_t_handler_json
4572   (vl_api_one_show_pitr_mode_reply_t * mp)
4573 {
4574   vat_main_t *vam = &vat_main;
4575   vat_json_node_t node;
4576   u8 *status = 0;
4577
4578   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4579   vec_add1 (status, 0);
4580
4581   vat_json_init_object (&node);
4582   vat_json_object_add_string_copy (&node, "status", status);
4583
4584   vec_free (status);
4585
4586   vat_json_print (vam->ofp, &node);
4587   vat_json_free (&node);
4588
4589   vam->retval = ntohl (mp->retval);
4590   vam->result_ready = 1;
4591 }
4592
4593 static void
4594   vl_api_one_show_petr_mode_reply_t_handler
4595   (vl_api_one_show_petr_mode_reply_t * mp)
4596 {
4597   vat_main_t *vam = &vat_main;
4598   i32 retval = ntohl (mp->retval);
4599
4600   if (0 <= retval)
4601     {
4602       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4603     }
4604
4605   vam->retval = retval;
4606   vam->result_ready = 1;
4607 }
4608
4609 static void
4610   vl_api_one_show_petr_mode_reply_t_handler_json
4611   (vl_api_one_show_petr_mode_reply_t * mp)
4612 {
4613   vat_main_t *vam = &vat_main;
4614   vat_json_node_t node;
4615   u8 *status = 0;
4616
4617   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4618   vec_add1 (status, 0);
4619
4620   vat_json_init_object (&node);
4621   vat_json_object_add_string_copy (&node, "status", status);
4622
4623   vec_free (status);
4624
4625   vat_json_print (vam->ofp, &node);
4626   vat_json_free (&node);
4627
4628   vam->retval = ntohl (mp->retval);
4629   vam->result_ready = 1;
4630 }
4631
4632 static void
4633   vl_api_show_one_use_petr_reply_t_handler
4634   (vl_api_show_one_use_petr_reply_t * mp)
4635 {
4636   vat_main_t *vam = &vat_main;
4637   i32 retval = ntohl (mp->retval);
4638
4639   if (0 <= retval)
4640     {
4641       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4642       if (mp->status)
4643         {
4644           print (vam->ofp, "Proxy-ETR address; %U",
4645                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4646                  mp->address);
4647         }
4648     }
4649
4650   vam->retval = retval;
4651   vam->result_ready = 1;
4652 }
4653
4654 static void
4655   vl_api_show_one_use_petr_reply_t_handler_json
4656   (vl_api_show_one_use_petr_reply_t * mp)
4657 {
4658   vat_main_t *vam = &vat_main;
4659   vat_json_node_t node;
4660   u8 *status = 0;
4661   struct in_addr ip4;
4662   struct in6_addr ip6;
4663
4664   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4665   vec_add1 (status, 0);
4666
4667   vat_json_init_object (&node);
4668   vat_json_object_add_string_copy (&node, "status", status);
4669   if (mp->status)
4670     {
4671       if (mp->is_ip4)
4672         {
4673           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4674           vat_json_object_add_ip6 (&node, "address", ip6);
4675         }
4676       else
4677         {
4678           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4679           vat_json_object_add_ip4 (&node, "address", ip4);
4680         }
4681     }
4682
4683   vec_free (status);
4684
4685   vat_json_print (vam->ofp, &node);
4686   vat_json_free (&node);
4687
4688   vam->retval = ntohl (mp->retval);
4689   vam->result_ready = 1;
4690 }
4691
4692 static void
4693   vl_api_show_one_nsh_mapping_reply_t_handler
4694   (vl_api_show_one_nsh_mapping_reply_t * mp)
4695 {
4696   vat_main_t *vam = &vat_main;
4697   i32 retval = ntohl (mp->retval);
4698
4699   if (0 <= retval)
4700     {
4701       print (vam->ofp, "%-20s%-16s",
4702              mp->is_set ? "set" : "not-set",
4703              mp->is_set ? (char *) mp->locator_set_name : "");
4704     }
4705
4706   vam->retval = retval;
4707   vam->result_ready = 1;
4708 }
4709
4710 static void
4711   vl_api_show_one_nsh_mapping_reply_t_handler_json
4712   (vl_api_show_one_nsh_mapping_reply_t * mp)
4713 {
4714   vat_main_t *vam = &vat_main;
4715   vat_json_node_t node;
4716   u8 *status = 0;
4717
4718   status = format (0, "%s", mp->is_set ? "yes" : "no");
4719   vec_add1 (status, 0);
4720
4721   vat_json_init_object (&node);
4722   vat_json_object_add_string_copy (&node, "is_set", status);
4723   if (mp->is_set)
4724     {
4725       vat_json_object_add_string_copy (&node, "locator_set",
4726                                        mp->locator_set_name);
4727     }
4728
4729   vec_free (status);
4730
4731   vat_json_print (vam->ofp, &node);
4732   vat_json_free (&node);
4733
4734   vam->retval = ntohl (mp->retval);
4735   vam->result_ready = 1;
4736 }
4737
4738 static void
4739   vl_api_show_one_map_register_ttl_reply_t_handler
4740   (vl_api_show_one_map_register_ttl_reply_t * mp)
4741 {
4742   vat_main_t *vam = &vat_main;
4743   i32 retval = ntohl (mp->retval);
4744
4745   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4746
4747   if (0 <= retval)
4748     {
4749       print (vam->ofp, "ttl: %u", mp->ttl);
4750     }
4751
4752   vam->retval = retval;
4753   vam->result_ready = 1;
4754 }
4755
4756 static void
4757   vl_api_show_one_map_register_ttl_reply_t_handler_json
4758   (vl_api_show_one_map_register_ttl_reply_t * mp)
4759 {
4760   vat_main_t *vam = &vat_main;
4761   vat_json_node_t node;
4762
4763   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4764   vat_json_init_object (&node);
4765   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4766
4767   vat_json_print (vam->ofp, &node);
4768   vat_json_free (&node);
4769
4770   vam->retval = ntohl (mp->retval);
4771   vam->result_ready = 1;
4772 }
4773
4774 static void
4775 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   i32 retval = ntohl (mp->retval);
4779
4780   if (0 <= retval)
4781     {
4782       print (vam->ofp, "%-20s%-16s",
4783              mp->status ? "enabled" : "disabled",
4784              mp->status ? (char *) mp->locator_set_name : "");
4785     }
4786
4787   vam->retval = retval;
4788   vam->result_ready = 1;
4789 }
4790
4791 static void
4792 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4793 {
4794   vat_main_t *vam = &vat_main;
4795   vat_json_node_t node;
4796   u8 *status = 0;
4797
4798   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4799   vec_add1 (status, 0);
4800
4801   vat_json_init_object (&node);
4802   vat_json_object_add_string_copy (&node, "status", status);
4803   if (mp->status)
4804     {
4805       vat_json_object_add_string_copy (&node, "locator_set",
4806                                        mp->locator_set_name);
4807     }
4808
4809   vec_free (status);
4810
4811   vat_json_print (vam->ofp, &node);
4812   vat_json_free (&node);
4813
4814   vam->retval = ntohl (mp->retval);
4815   vam->result_ready = 1;
4816 }
4817
4818 static u8 *
4819 format_policer_type (u8 * s, va_list * va)
4820 {
4821   u32 i = va_arg (*va, u32);
4822
4823   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4824     s = format (s, "1r2c");
4825   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4826     s = format (s, "1r3c");
4827   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4828     s = format (s, "2r3c-2698");
4829   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4830     s = format (s, "2r3c-4115");
4831   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4832     s = format (s, "2r3c-mef5cf1");
4833   else
4834     s = format (s, "ILLEGAL");
4835   return s;
4836 }
4837
4838 static u8 *
4839 format_policer_rate_type (u8 * s, va_list * va)
4840 {
4841   u32 i = va_arg (*va, u32);
4842
4843   if (i == SSE2_QOS_RATE_KBPS)
4844     s = format (s, "kbps");
4845   else if (i == SSE2_QOS_RATE_PPS)
4846     s = format (s, "pps");
4847   else
4848     s = format (s, "ILLEGAL");
4849   return s;
4850 }
4851
4852 static u8 *
4853 format_policer_round_type (u8 * s, va_list * va)
4854 {
4855   u32 i = va_arg (*va, u32);
4856
4857   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4858     s = format (s, "closest");
4859   else if (i == SSE2_QOS_ROUND_TO_UP)
4860     s = format (s, "up");
4861   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4862     s = format (s, "down");
4863   else
4864     s = format (s, "ILLEGAL");
4865   return s;
4866 }
4867
4868 static u8 *
4869 format_policer_action_type (u8 * s, va_list * va)
4870 {
4871   u32 i = va_arg (*va, u32);
4872
4873   if (i == SSE2_QOS_ACTION_DROP)
4874     s = format (s, "drop");
4875   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4876     s = format (s, "transmit");
4877   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4878     s = format (s, "mark-and-transmit");
4879   else
4880     s = format (s, "ILLEGAL");
4881   return s;
4882 }
4883
4884 static u8 *
4885 format_dscp (u8 * s, va_list * va)
4886 {
4887   u32 i = va_arg (*va, u32);
4888   char *t = 0;
4889
4890   switch (i)
4891     {
4892 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4893       foreach_vnet_dscp
4894 #undef _
4895     default:
4896       return format (s, "ILLEGAL");
4897     }
4898   s = format (s, "%s", t);
4899   return s;
4900 }
4901
4902 static void
4903 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4904 {
4905   vat_main_t *vam = &vat_main;
4906   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4907
4908   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4909     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4910   else
4911     conform_dscp_str = format (0, "");
4912
4913   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4914     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4915   else
4916     exceed_dscp_str = format (0, "");
4917
4918   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4919     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4920   else
4921     violate_dscp_str = format (0, "");
4922
4923   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4924          "rate type %U, round type %U, %s rate, %s color-aware, "
4925          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4926          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4927          "conform action %U%s, exceed action %U%s, violate action %U%s",
4928          mp->name,
4929          format_policer_type, mp->type,
4930          ntohl (mp->cir),
4931          ntohl (mp->eir),
4932          clib_net_to_host_u64 (mp->cb),
4933          clib_net_to_host_u64 (mp->eb),
4934          format_policer_rate_type, mp->rate_type,
4935          format_policer_round_type, mp->round_type,
4936          mp->single_rate ? "single" : "dual",
4937          mp->color_aware ? "is" : "not",
4938          ntohl (mp->cir_tokens_per_period),
4939          ntohl (mp->pir_tokens_per_period),
4940          ntohl (mp->scale),
4941          ntohl (mp->current_limit),
4942          ntohl (mp->current_bucket),
4943          ntohl (mp->extended_limit),
4944          ntohl (mp->extended_bucket),
4945          clib_net_to_host_u64 (mp->last_update_time),
4946          format_policer_action_type, mp->conform_action_type,
4947          conform_dscp_str,
4948          format_policer_action_type, mp->exceed_action_type,
4949          exceed_dscp_str,
4950          format_policer_action_type, mp->violate_action_type,
4951          violate_dscp_str);
4952
4953   vec_free (conform_dscp_str);
4954   vec_free (exceed_dscp_str);
4955   vec_free (violate_dscp_str);
4956 }
4957
4958 static void vl_api_policer_details_t_handler_json
4959   (vl_api_policer_details_t * mp)
4960 {
4961   vat_main_t *vam = &vat_main;
4962   vat_json_node_t *node;
4963   u8 *rate_type_str, *round_type_str, *type_str;
4964   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4965
4966   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4967   round_type_str =
4968     format (0, "%U", format_policer_round_type, mp->round_type);
4969   type_str = format (0, "%U", format_policer_type, mp->type);
4970   conform_action_str = format (0, "%U", format_policer_action_type,
4971                                mp->conform_action_type);
4972   exceed_action_str = format (0, "%U", format_policer_action_type,
4973                               mp->exceed_action_type);
4974   violate_action_str = format (0, "%U", format_policer_action_type,
4975                                mp->violate_action_type);
4976
4977   if (VAT_JSON_ARRAY != vam->json_tree.type)
4978     {
4979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4980       vat_json_init_array (&vam->json_tree);
4981     }
4982   node = vat_json_array_add (&vam->json_tree);
4983
4984   vat_json_init_object (node);
4985   vat_json_object_add_string_copy (node, "name", mp->name);
4986   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4987   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4988   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4989   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4990   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4991   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4992   vat_json_object_add_string_copy (node, "type", type_str);
4993   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4994   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4995   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4996   vat_json_object_add_uint (node, "cir_tokens_per_period",
4997                             ntohl (mp->cir_tokens_per_period));
4998   vat_json_object_add_uint (node, "eir_tokens_per_period",
4999                             ntohl (mp->pir_tokens_per_period));
5000   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
5001   vat_json_object_add_uint (node, "current_bucket",
5002                             ntohl (mp->current_bucket));
5003   vat_json_object_add_uint (node, "extended_limit",
5004                             ntohl (mp->extended_limit));
5005   vat_json_object_add_uint (node, "extended_bucket",
5006                             ntohl (mp->extended_bucket));
5007   vat_json_object_add_uint (node, "last_update_time",
5008                             ntohl (mp->last_update_time));
5009   vat_json_object_add_string_copy (node, "conform_action",
5010                                    conform_action_str);
5011   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5012     {
5013       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5014       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5015       vec_free (dscp_str);
5016     }
5017   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5018   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5019     {
5020       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5021       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5022       vec_free (dscp_str);
5023     }
5024   vat_json_object_add_string_copy (node, "violate_action",
5025                                    violate_action_str);
5026   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5027     {
5028       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5029       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5030       vec_free (dscp_str);
5031     }
5032
5033   vec_free (rate_type_str);
5034   vec_free (round_type_str);
5035   vec_free (type_str);
5036   vec_free (conform_action_str);
5037   vec_free (exceed_action_str);
5038   vec_free (violate_action_str);
5039 }
5040
5041 static void
5042 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5043                                            mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046   int i, count = ntohl (mp->count);
5047
5048   if (count > 0)
5049     print (vam->ofp, "classify table ids (%d) : ", count);
5050   for (i = 0; i < count; i++)
5051     {
5052       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5053       print (vam->ofp, (i < count - 1) ? "," : "");
5054     }
5055   vam->retval = ntohl (mp->retval);
5056   vam->result_ready = 1;
5057 }
5058
5059 static void
5060   vl_api_classify_table_ids_reply_t_handler_json
5061   (vl_api_classify_table_ids_reply_t * mp)
5062 {
5063   vat_main_t *vam = &vat_main;
5064   int i, count = ntohl (mp->count);
5065
5066   if (count > 0)
5067     {
5068       vat_json_node_t node;
5069
5070       vat_json_init_object (&node);
5071       for (i = 0; i < count; i++)
5072         {
5073           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5074         }
5075       vat_json_print (vam->ofp, &node);
5076       vat_json_free (&node);
5077     }
5078   vam->retval = ntohl (mp->retval);
5079   vam->result_ready = 1;
5080 }
5081
5082 static void
5083   vl_api_classify_table_by_interface_reply_t_handler
5084   (vl_api_classify_table_by_interface_reply_t * mp)
5085 {
5086   vat_main_t *vam = &vat_main;
5087   u32 table_id;
5088
5089   table_id = ntohl (mp->l2_table_id);
5090   if (table_id != ~0)
5091     print (vam->ofp, "l2 table id : %d", table_id);
5092   else
5093     print (vam->ofp, "l2 table id : No input ACL tables configured");
5094   table_id = ntohl (mp->ip4_table_id);
5095   if (table_id != ~0)
5096     print (vam->ofp, "ip4 table id : %d", table_id);
5097   else
5098     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5099   table_id = ntohl (mp->ip6_table_id);
5100   if (table_id != ~0)
5101     print (vam->ofp, "ip6 table id : %d", table_id);
5102   else
5103     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5104   vam->retval = ntohl (mp->retval);
5105   vam->result_ready = 1;
5106 }
5107
5108 static void
5109   vl_api_classify_table_by_interface_reply_t_handler_json
5110   (vl_api_classify_table_by_interface_reply_t * mp)
5111 {
5112   vat_main_t *vam = &vat_main;
5113   vat_json_node_t node;
5114
5115   vat_json_init_object (&node);
5116
5117   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5118   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5119   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5120
5121   vat_json_print (vam->ofp, &node);
5122   vat_json_free (&node);
5123
5124   vam->retval = ntohl (mp->retval);
5125   vam->result_ready = 1;
5126 }
5127
5128 static void vl_api_policer_add_del_reply_t_handler
5129   (vl_api_policer_add_del_reply_t * mp)
5130 {
5131   vat_main_t *vam = &vat_main;
5132   i32 retval = ntohl (mp->retval);
5133   if (vam->async_mode)
5134     {
5135       vam->async_errors += (retval < 0);
5136     }
5137   else
5138     {
5139       vam->retval = retval;
5140       vam->result_ready = 1;
5141       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5142         /*
5143          * Note: this is just barely thread-safe, depends on
5144          * the main thread spinning waiting for an answer...
5145          */
5146         errmsg ("policer index %d", ntohl (mp->policer_index));
5147     }
5148 }
5149
5150 static void vl_api_policer_add_del_reply_t_handler_json
5151   (vl_api_policer_add_del_reply_t * mp)
5152 {
5153   vat_main_t *vam = &vat_main;
5154   vat_json_node_t node;
5155
5156   vat_json_init_object (&node);
5157   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5158   vat_json_object_add_uint (&node, "policer_index",
5159                             ntohl (mp->policer_index));
5160
5161   vat_json_print (vam->ofp, &node);
5162   vat_json_free (&node);
5163
5164   vam->retval = ntohl (mp->retval);
5165   vam->result_ready = 1;
5166 }
5167
5168 /* Format hex dump. */
5169 u8 *
5170 format_hex_bytes (u8 * s, va_list * va)
5171 {
5172   u8 *bytes = va_arg (*va, u8 *);
5173   int n_bytes = va_arg (*va, int);
5174   uword i;
5175
5176   /* Print short or long form depending on byte count. */
5177   uword short_form = n_bytes <= 32;
5178   u32 indent = format_get_indent (s);
5179
5180   if (n_bytes == 0)
5181     return s;
5182
5183   for (i = 0; i < n_bytes; i++)
5184     {
5185       if (!short_form && (i % 32) == 0)
5186         s = format (s, "%08x: ", i);
5187       s = format (s, "%02x", bytes[i]);
5188       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5189         s = format (s, "\n%U", format_white_space, indent);
5190     }
5191
5192   return s;
5193 }
5194
5195 static void
5196 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5197                                             * mp)
5198 {
5199   vat_main_t *vam = &vat_main;
5200   i32 retval = ntohl (mp->retval);
5201   if (retval == 0)
5202     {
5203       print (vam->ofp, "classify table info :");
5204       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5205              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5206              ntohl (mp->miss_next_index));
5207       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5208              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5209              ntohl (mp->match_n_vectors));
5210       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5211              ntohl (mp->mask_length));
5212     }
5213   vam->retval = retval;
5214   vam->result_ready = 1;
5215 }
5216
5217 static void
5218   vl_api_classify_table_info_reply_t_handler_json
5219   (vl_api_classify_table_info_reply_t * mp)
5220 {
5221   vat_main_t *vam = &vat_main;
5222   vat_json_node_t node;
5223
5224   i32 retval = ntohl (mp->retval);
5225   if (retval == 0)
5226     {
5227       vat_json_init_object (&node);
5228
5229       vat_json_object_add_int (&node, "sessions",
5230                                ntohl (mp->active_sessions));
5231       vat_json_object_add_int (&node, "nexttbl",
5232                                ntohl (mp->next_table_index));
5233       vat_json_object_add_int (&node, "nextnode",
5234                                ntohl (mp->miss_next_index));
5235       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5236       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5237       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5238       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5239                       ntohl (mp->mask_length), 0);
5240       vat_json_object_add_string_copy (&node, "mask", s);
5241
5242       vat_json_print (vam->ofp, &node);
5243       vat_json_free (&node);
5244     }
5245   vam->retval = ntohl (mp->retval);
5246   vam->result_ready = 1;
5247 }
5248
5249 static void
5250 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5251                                            mp)
5252 {
5253   vat_main_t *vam = &vat_main;
5254
5255   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5256          ntohl (mp->hit_next_index), ntohl (mp->advance),
5257          ntohl (mp->opaque_index));
5258   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5259          ntohl (mp->match_length));
5260 }
5261
5262 static void
5263   vl_api_classify_session_details_t_handler_json
5264   (vl_api_classify_session_details_t * mp)
5265 {
5266   vat_main_t *vam = &vat_main;
5267   vat_json_node_t *node = NULL;
5268
5269   if (VAT_JSON_ARRAY != vam->json_tree.type)
5270     {
5271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5272       vat_json_init_array (&vam->json_tree);
5273     }
5274   node = vat_json_array_add (&vam->json_tree);
5275
5276   vat_json_init_object (node);
5277   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5278   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5279   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5280   u8 *s =
5281     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5282             0);
5283   vat_json_object_add_string_copy (node, "match", s);
5284 }
5285
5286 static void vl_api_pg_create_interface_reply_t_handler
5287   (vl_api_pg_create_interface_reply_t * mp)
5288 {
5289   vat_main_t *vam = &vat_main;
5290
5291   vam->retval = ntohl (mp->retval);
5292   vam->result_ready = 1;
5293 }
5294
5295 static void vl_api_pg_create_interface_reply_t_handler_json
5296   (vl_api_pg_create_interface_reply_t * mp)
5297 {
5298   vat_main_t *vam = &vat_main;
5299   vat_json_node_t node;
5300
5301   i32 retval = ntohl (mp->retval);
5302   if (retval == 0)
5303     {
5304       vat_json_init_object (&node);
5305
5306       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5307
5308       vat_json_print (vam->ofp, &node);
5309       vat_json_free (&node);
5310     }
5311   vam->retval = ntohl (mp->retval);
5312   vam->result_ready = 1;
5313 }
5314
5315 static void vl_api_policer_classify_details_t_handler
5316   (vl_api_policer_classify_details_t * mp)
5317 {
5318   vat_main_t *vam = &vat_main;
5319
5320   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5321          ntohl (mp->table_index));
5322 }
5323
5324 static void vl_api_policer_classify_details_t_handler_json
5325   (vl_api_policer_classify_details_t * mp)
5326 {
5327   vat_main_t *vam = &vat_main;
5328   vat_json_node_t *node;
5329
5330   if (VAT_JSON_ARRAY != vam->json_tree.type)
5331     {
5332       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5333       vat_json_init_array (&vam->json_tree);
5334     }
5335   node = vat_json_array_add (&vam->json_tree);
5336
5337   vat_json_init_object (node);
5338   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5339   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5340 }
5341
5342 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5343   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5344 {
5345   vat_main_t *vam = &vat_main;
5346   i32 retval = ntohl (mp->retval);
5347   if (vam->async_mode)
5348     {
5349       vam->async_errors += (retval < 0);
5350     }
5351   else
5352     {
5353       vam->retval = retval;
5354       vam->sw_if_index = ntohl (mp->sw_if_index);
5355       vam->result_ready = 1;
5356     }
5357   vam->regenerate_interface_table = 1;
5358 }
5359
5360 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5361   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5362 {
5363   vat_main_t *vam = &vat_main;
5364   vat_json_node_t node;
5365
5366   vat_json_init_object (&node);
5367   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5368   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5369
5370   vat_json_print (vam->ofp, &node);
5371   vat_json_free (&node);
5372
5373   vam->retval = ntohl (mp->retval);
5374   vam->result_ready = 1;
5375 }
5376
5377 static void vl_api_flow_classify_details_t_handler
5378   (vl_api_flow_classify_details_t * mp)
5379 {
5380   vat_main_t *vam = &vat_main;
5381
5382   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5383          ntohl (mp->table_index));
5384 }
5385
5386 static void vl_api_flow_classify_details_t_handler_json
5387   (vl_api_flow_classify_details_t * mp)
5388 {
5389   vat_main_t *vam = &vat_main;
5390   vat_json_node_t *node;
5391
5392   if (VAT_JSON_ARRAY != vam->json_tree.type)
5393     {
5394       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5395       vat_json_init_array (&vam->json_tree);
5396     }
5397   node = vat_json_array_add (&vam->json_tree);
5398
5399   vat_json_init_object (node);
5400   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5401   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5402 }
5403
5404 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5405 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5406 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5407 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5408 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5409 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5410 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5411 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5412 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5413 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5414 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5415 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5416 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5417 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5418 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5419 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5420 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5421 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5422 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5423 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5424 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5425 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5426
5427 /*
5428  * Generate boilerplate reply handlers, which
5429  * dig the return value out of the xxx_reply_t API message,
5430  * stick it into vam->retval, and set vam->result_ready
5431  *
5432  * Could also do this by pointing N message decode slots at
5433  * a single function, but that could break in subtle ways.
5434  */
5435
5436 #define foreach_standard_reply_retval_handler           \
5437 _(sw_interface_set_flags_reply)                         \
5438 _(sw_interface_add_del_address_reply)                   \
5439 _(sw_interface_set_rx_mode_reply)                       \
5440 _(sw_interface_set_rx_placement_reply)                  \
5441 _(sw_interface_set_table_reply)                         \
5442 _(sw_interface_set_mpls_enable_reply)                   \
5443 _(sw_interface_set_vpath_reply)                         \
5444 _(sw_interface_set_vxlan_bypass_reply)                  \
5445 _(sw_interface_set_geneve_bypass_reply)                 \
5446 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5447 _(sw_interface_set_l2_bridge_reply)                     \
5448 _(bridge_domain_add_del_reply)                          \
5449 _(sw_interface_set_l2_xconnect_reply)                   \
5450 _(l2fib_add_del_reply)                                  \
5451 _(l2fib_flush_int_reply)                                \
5452 _(l2fib_flush_bd_reply)                                 \
5453 _(ip_add_del_route_reply)                               \
5454 _(ip_table_add_del_reply)                               \
5455 _(ip_mroute_add_del_reply)                              \
5456 _(mpls_route_add_del_reply)                             \
5457 _(mpls_table_add_del_reply)                             \
5458 _(mpls_ip_bind_unbind_reply)                            \
5459 _(bier_route_add_del_reply)                             \
5460 _(bier_table_add_del_reply)                             \
5461 _(proxy_arp_add_del_reply)                              \
5462 _(proxy_arp_intfc_enable_disable_reply)                 \
5463 _(sw_interface_set_unnumbered_reply)                    \
5464 _(ip_neighbor_add_del_reply)                            \
5465 _(oam_add_del_reply)                                    \
5466 _(reset_fib_reply)                                      \
5467 _(dhcp_proxy_config_reply)                              \
5468 _(dhcp_proxy_set_vss_reply)                             \
5469 _(dhcp_client_config_reply)                             \
5470 _(set_ip_flow_hash_reply)                               \
5471 _(sw_interface_ip6_enable_disable_reply)                \
5472 _(sw_interface_ip6_set_link_local_address_reply)        \
5473 _(ip6nd_proxy_add_del_reply)                            \
5474 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5475 _(sw_interface_ip6nd_ra_config_reply)                   \
5476 _(set_arp_neighbor_limit_reply)                         \
5477 _(l2_patch_add_del_reply)                               \
5478 _(sr_mpls_policy_add_reply)                             \
5479 _(sr_mpls_policy_mod_reply)                             \
5480 _(sr_mpls_policy_del_reply)                             \
5481 _(sr_policy_add_reply)                                  \
5482 _(sr_policy_mod_reply)                                  \
5483 _(sr_policy_del_reply)                                  \
5484 _(sr_localsid_add_del_reply)                            \
5485 _(sr_steering_add_del_reply)                            \
5486 _(classify_add_del_session_reply)                       \
5487 _(classify_set_interface_ip_table_reply)                \
5488 _(classify_set_interface_l2_tables_reply)               \
5489 _(l2tpv3_set_tunnel_cookies_reply)                      \
5490 _(l2tpv3_interface_enable_disable_reply)                \
5491 _(l2tpv3_set_lookup_key_reply)                          \
5492 _(l2_fib_clear_table_reply)                             \
5493 _(l2_interface_efp_filter_reply)                        \
5494 _(l2_interface_vlan_tag_rewrite_reply)                  \
5495 _(modify_vhost_user_if_reply)                           \
5496 _(delete_vhost_user_if_reply)                           \
5497 _(ip_probe_neighbor_reply)                              \
5498 _(ip_scan_neighbor_enable_disable_reply)                \
5499 _(want_ip4_arp_events_reply)                            \
5500 _(want_ip6_nd_events_reply)                             \
5501 _(want_l2_macs_events_reply)                            \
5502 _(input_acl_set_interface_reply)                        \
5503 _(ipsec_spd_add_del_reply)                              \
5504 _(ipsec_interface_add_del_spd_reply)                    \
5505 _(ipsec_spd_add_del_entry_reply)                        \
5506 _(ipsec_sad_add_del_entry_reply)                        \
5507 _(ipsec_sa_set_key_reply)                               \
5508 _(ipsec_tunnel_if_add_del_reply)                        \
5509 _(ipsec_tunnel_if_set_key_reply)                        \
5510 _(ipsec_tunnel_if_set_sa_reply)                         \
5511 _(ikev2_profile_add_del_reply)                          \
5512 _(ikev2_profile_set_auth_reply)                         \
5513 _(ikev2_profile_set_id_reply)                           \
5514 _(ikev2_profile_set_ts_reply)                           \
5515 _(ikev2_set_local_key_reply)                            \
5516 _(ikev2_set_responder_reply)                            \
5517 _(ikev2_set_ike_transforms_reply)                       \
5518 _(ikev2_set_esp_transforms_reply)                       \
5519 _(ikev2_set_sa_lifetime_reply)                          \
5520 _(ikev2_initiate_sa_init_reply)                         \
5521 _(ikev2_initiate_del_ike_sa_reply)                      \
5522 _(ikev2_initiate_del_child_sa_reply)                    \
5523 _(ikev2_initiate_rekey_child_sa_reply)                  \
5524 _(delete_loopback_reply)                                \
5525 _(bd_ip_mac_add_del_reply)                              \
5526 _(want_interface_events_reply)                          \
5527 _(want_stats_reply)                                     \
5528 _(cop_interface_enable_disable_reply)                   \
5529 _(cop_whitelist_enable_disable_reply)                   \
5530 _(sw_interface_clear_stats_reply)                       \
5531 _(ioam_enable_reply)                                    \
5532 _(ioam_disable_reply)                                   \
5533 _(one_add_del_locator_reply)                            \
5534 _(one_add_del_local_eid_reply)                          \
5535 _(one_add_del_remote_mapping_reply)                     \
5536 _(one_add_del_adjacency_reply)                          \
5537 _(one_add_del_map_resolver_reply)                       \
5538 _(one_add_del_map_server_reply)                         \
5539 _(one_enable_disable_reply)                             \
5540 _(one_rloc_probe_enable_disable_reply)                  \
5541 _(one_map_register_enable_disable_reply)                \
5542 _(one_map_register_set_ttl_reply)                       \
5543 _(one_set_transport_protocol_reply)                     \
5544 _(one_map_register_fallback_threshold_reply)            \
5545 _(one_pitr_set_locator_set_reply)                       \
5546 _(one_map_request_mode_reply)                           \
5547 _(one_add_del_map_request_itr_rlocs_reply)              \
5548 _(one_eid_table_add_del_map_reply)                      \
5549 _(one_use_petr_reply)                                   \
5550 _(one_stats_enable_disable_reply)                       \
5551 _(one_add_del_l2_arp_entry_reply)                       \
5552 _(one_add_del_ndp_entry_reply)                          \
5553 _(one_stats_flush_reply)                                \
5554 _(one_enable_disable_xtr_mode_reply)                    \
5555 _(one_enable_disable_pitr_mode_reply)                   \
5556 _(one_enable_disable_petr_mode_reply)                   \
5557 _(gpe_enable_disable_reply)                             \
5558 _(gpe_set_encap_mode_reply)                             \
5559 _(gpe_add_del_iface_reply)                              \
5560 _(gpe_add_del_native_fwd_rpath_reply)                   \
5561 _(af_packet_delete_reply)                               \
5562 _(policer_classify_set_interface_reply)                 \
5563 _(netmap_create_reply)                                  \
5564 _(netmap_delete_reply)                                  \
5565 _(set_ipfix_exporter_reply)                             \
5566 _(set_ipfix_classify_stream_reply)                      \
5567 _(ipfix_classify_table_add_del_reply)                   \
5568 _(flow_classify_set_interface_reply)                    \
5569 _(sw_interface_span_enable_disable_reply)               \
5570 _(pg_capture_reply)                                     \
5571 _(pg_enable_disable_reply)                              \
5572 _(ip_source_and_port_range_check_add_del_reply)         \
5573 _(ip_source_and_port_range_check_interface_add_del_reply)\
5574 _(delete_subif_reply)                                   \
5575 _(l2_interface_pbb_tag_rewrite_reply)                   \
5576 _(punt_reply)                                           \
5577 _(feature_enable_disable_reply)                         \
5578 _(sw_interface_tag_add_del_reply)                       \
5579 _(hw_interface_set_mtu_reply)                           \
5580 _(p2p_ethernet_add_reply)                               \
5581 _(p2p_ethernet_del_reply)                               \
5582 _(lldp_config_reply)                                    \
5583 _(sw_interface_set_lldp_reply)                          \
5584 _(tcp_configure_src_addresses_reply)                    \
5585 _(dns_enable_disable_reply)                             \
5586 _(dns_name_server_add_del_reply)                        \
5587 _(session_rule_add_del_reply)                           \
5588 _(ip_container_proxy_add_del_reply)                     \
5589 _(output_acl_set_interface_reply)                       \
5590 _(qos_record_enable_disable_reply)
5591
5592 #define _(n)                                    \
5593     static void vl_api_##n##_t_handler          \
5594     (vl_api_##n##_t * mp)                       \
5595     {                                           \
5596         vat_main_t * vam = &vat_main;           \
5597         i32 retval = ntohl(mp->retval);         \
5598         if (vam->async_mode) {                  \
5599             vam->async_errors += (retval < 0);  \
5600         } else {                                \
5601             vam->retval = retval;               \
5602             vam->result_ready = 1;              \
5603         }                                       \
5604     }
5605 foreach_standard_reply_retval_handler;
5606 #undef _
5607
5608 #define _(n)                                    \
5609     static void vl_api_##n##_t_handler_json     \
5610     (vl_api_##n##_t * mp)                       \
5611     {                                           \
5612         vat_main_t * vam = &vat_main;           \
5613         vat_json_node_t node;                   \
5614         vat_json_init_object(&node);            \
5615         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5616         vat_json_print(vam->ofp, &node);        \
5617         vam->retval = ntohl(mp->retval);        \
5618         vam->result_ready = 1;                  \
5619     }
5620 foreach_standard_reply_retval_handler;
5621 #undef _
5622
5623 /*
5624  * Table of message reply handlers, must include boilerplate handlers
5625  * we just generated
5626  */
5627
5628 #define foreach_vpe_api_reply_msg                                       \
5629 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5630 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5631 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5632 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5633 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5634 _(CLI_REPLY, cli_reply)                                                 \
5635 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5636 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5637   sw_interface_add_del_address_reply)                                   \
5638 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5639 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5640 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5641 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5642 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5643 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5644 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5645 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5646 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5647 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5648   sw_interface_set_l2_xconnect_reply)                                   \
5649 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5650   sw_interface_set_l2_bridge_reply)                                     \
5651 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5652 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5653 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5654 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5655 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5656 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5657 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5658 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5659 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5660 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5661 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5662 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5663 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5664 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5665 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5666 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5667 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5668 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5669 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5670 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5671 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5672 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5673 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5674 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5675 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5676 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5677 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5678 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5679 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5680 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5681 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5682   proxy_arp_intfc_enable_disable_reply)                                 \
5683 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5684 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5685   sw_interface_set_unnumbered_reply)                                    \
5686 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5687 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5688 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5689 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5690 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5691 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5692 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5693 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5694 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5695 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5696 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5697   sw_interface_ip6_enable_disable_reply)                                \
5698 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5699   sw_interface_ip6_set_link_local_address_reply)                        \
5700 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5701 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5702 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5703   sw_interface_ip6nd_ra_prefix_reply)                                   \
5704 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5705   sw_interface_ip6nd_ra_config_reply)                                   \
5706 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5707 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5708 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5709 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5710 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5711 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5712 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5713 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5714 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5715 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5716 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5717 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5718 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5719 classify_set_interface_ip_table_reply)                                  \
5720 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5721   classify_set_interface_l2_tables_reply)                               \
5722 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5723 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5724 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5725 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5726 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5727   l2tpv3_interface_enable_disable_reply)                                \
5728 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5729 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5730 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5731 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5732 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5733 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5734 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5735 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5736 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5737 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5738 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5739 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5740 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5741 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5742 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5743 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5744 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5745 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5746 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5747 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5748 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5749 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5750 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5751 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5752 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5753 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5754 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5755 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5756 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5757 _(L2_MACS_EVENT, l2_macs_event)                                         \
5758 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5759 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5760 _(IP_DETAILS, ip_details)                                               \
5761 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5762 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5763 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5764 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5765 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5766 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5767 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5768 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5769 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5770 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5771 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5772 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5773 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5774 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5775 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5776 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5777 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5778 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5779 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5780 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5781 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5782 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5783 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5784 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5785 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5786 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5787 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5788 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5789 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5790 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5791 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5792 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5793 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5794 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5795 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5796 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5797 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5798 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5799 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5800 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5801 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5802 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5803 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5804 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5805   one_map_register_enable_disable_reply)                                \
5806 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5807 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5808 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5809 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5810   one_map_register_fallback_threshold_reply)                            \
5811 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5812   one_rloc_probe_enable_disable_reply)                                  \
5813 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5814 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5815 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5816 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5817 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5818 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5819 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5820 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5821 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5822 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5823 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5824 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5825 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5826 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5827 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5828 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5829   show_one_stats_enable_disable_reply)                                  \
5830 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5831 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5832 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5833 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5834 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5835 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5836 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5837 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5838   one_enable_disable_pitr_mode_reply)                                   \
5839 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5840   one_enable_disable_petr_mode_reply)                                   \
5841 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5842 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5843 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5844 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5845 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5846 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5847 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5848 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5849 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5850 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5851 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5852 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5853   gpe_add_del_native_fwd_rpath_reply)                                   \
5854 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5855   gpe_fwd_entry_path_details)                                           \
5856 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5857 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5858   one_add_del_map_request_itr_rlocs_reply)                              \
5859 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5860   one_get_map_request_itr_rlocs_reply)                                  \
5861 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5862 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5863 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5864 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5865 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5866 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5867   show_one_map_register_state_reply)                                    \
5868 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5869 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5870   show_one_map_register_fallback_threshold_reply)                       \
5871 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5872 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5873 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5874 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5875 _(POLICER_DETAILS, policer_details)                                     \
5876 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5877 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5878 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5879 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5880 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5881 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5882 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5883 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5884 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5885 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5886 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5887 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5888 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5889 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5890 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5891 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5892 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5893 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5894 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5895 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5896 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5897 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5898 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5899 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5900 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5901  ip_source_and_port_range_check_add_del_reply)                          \
5902 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5903  ip_source_and_port_range_check_interface_add_del_reply)                \
5904 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5905 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5906 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5907 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5908 _(PUNT_REPLY, punt_reply)                                               \
5909 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5910 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5911 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5912 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5913 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5914 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5915 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5916 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5917 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5918 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5919 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5920 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5921 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5922 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5923 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5924 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5925 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5926 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5927 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5928 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5929 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5930 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5931 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5932
5933 #define foreach_standalone_reply_msg                                    \
5934 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5935 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5936 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5937 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5938 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5939 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5940 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5941
5942 typedef struct
5943 {
5944   u8 *name;
5945   u32 value;
5946 } name_sort_t;
5947
5948 #define STR_VTR_OP_CASE(op)     \
5949     case L2_VTR_ ## op:         \
5950         return "" # op;
5951
5952 static const char *
5953 str_vtr_op (u32 vtr_op)
5954 {
5955   switch (vtr_op)
5956     {
5957       STR_VTR_OP_CASE (DISABLED);
5958       STR_VTR_OP_CASE (PUSH_1);
5959       STR_VTR_OP_CASE (PUSH_2);
5960       STR_VTR_OP_CASE (POP_1);
5961       STR_VTR_OP_CASE (POP_2);
5962       STR_VTR_OP_CASE (TRANSLATE_1_1);
5963       STR_VTR_OP_CASE (TRANSLATE_1_2);
5964       STR_VTR_OP_CASE (TRANSLATE_2_1);
5965       STR_VTR_OP_CASE (TRANSLATE_2_2);
5966     }
5967
5968   return "UNKNOWN";
5969 }
5970
5971 static int
5972 dump_sub_interface_table (vat_main_t * vam)
5973 {
5974   const sw_interface_subif_t *sub = NULL;
5975
5976   if (vam->json_output)
5977     {
5978       clib_warning
5979         ("JSON output supported only for VPE API calls and dump_stats_table");
5980       return -99;
5981     }
5982
5983   print (vam->ofp,
5984          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5985          "Interface", "sw_if_index",
5986          "sub id", "dot1ad", "tags", "outer id",
5987          "inner id", "exact", "default", "outer any", "inner any");
5988
5989   vec_foreach (sub, vam->sw_if_subif_table)
5990   {
5991     print (vam->ofp,
5992            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5993            sub->interface_name,
5994            sub->sw_if_index,
5995            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5996            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5997            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5998            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5999     if (sub->vtr_op != L2_VTR_DISABLED)
6000       {
6001         print (vam->ofp,
6002                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
6003                "tag1: %d tag2: %d ]",
6004                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
6005                sub->vtr_tag1, sub->vtr_tag2);
6006       }
6007   }
6008
6009   return 0;
6010 }
6011
6012 static int
6013 name_sort_cmp (void *a1, void *a2)
6014 {
6015   name_sort_t *n1 = a1;
6016   name_sort_t *n2 = a2;
6017
6018   return strcmp ((char *) n1->name, (char *) n2->name);
6019 }
6020
6021 static int
6022 dump_interface_table (vat_main_t * vam)
6023 {
6024   hash_pair_t *p;
6025   name_sort_t *nses = 0, *ns;
6026
6027   if (vam->json_output)
6028     {
6029       clib_warning
6030         ("JSON output supported only for VPE API calls and dump_stats_table");
6031       return -99;
6032     }
6033
6034   /* *INDENT-OFF* */
6035   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6036   ({
6037     vec_add2 (nses, ns, 1);
6038     ns->name = (u8 *)(p->key);
6039     ns->value = (u32) p->value[0];
6040   }));
6041   /* *INDENT-ON* */
6042
6043   vec_sort_with_function (nses, name_sort_cmp);
6044
6045   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6046   vec_foreach (ns, nses)
6047   {
6048     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6049   }
6050   vec_free (nses);
6051   return 0;
6052 }
6053
6054 static int
6055 dump_ip_table (vat_main_t * vam, int is_ipv6)
6056 {
6057   const ip_details_t *det = NULL;
6058   const ip_address_details_t *address = NULL;
6059   u32 i = ~0;
6060
6061   print (vam->ofp, "%-12s", "sw_if_index");
6062
6063   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6064   {
6065     i++;
6066     if (!det->present)
6067       {
6068         continue;
6069       }
6070     print (vam->ofp, "%-12d", i);
6071     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6072     if (!det->addr)
6073       {
6074         continue;
6075       }
6076     vec_foreach (address, det->addr)
6077     {
6078       print (vam->ofp,
6079              "            %-30U%-13d",
6080              is_ipv6 ? format_ip6_address : format_ip4_address,
6081              address->ip, address->prefix_length);
6082     }
6083   }
6084
6085   return 0;
6086 }
6087
6088 static int
6089 dump_ipv4_table (vat_main_t * vam)
6090 {
6091   if (vam->json_output)
6092     {
6093       clib_warning
6094         ("JSON output supported only for VPE API calls and dump_stats_table");
6095       return -99;
6096     }
6097
6098   return dump_ip_table (vam, 0);
6099 }
6100
6101 static int
6102 dump_ipv6_table (vat_main_t * vam)
6103 {
6104   if (vam->json_output)
6105     {
6106       clib_warning
6107         ("JSON output supported only for VPE API calls and dump_stats_table");
6108       return -99;
6109     }
6110
6111   return dump_ip_table (vam, 1);
6112 }
6113
6114 static char *
6115 counter_type_to_str (u8 counter_type, u8 is_combined)
6116 {
6117   if (!is_combined)
6118     {
6119       switch (counter_type)
6120         {
6121         case VNET_INTERFACE_COUNTER_DROP:
6122           return "drop";
6123         case VNET_INTERFACE_COUNTER_PUNT:
6124           return "punt";
6125         case VNET_INTERFACE_COUNTER_IP4:
6126           return "ip4";
6127         case VNET_INTERFACE_COUNTER_IP6:
6128           return "ip6";
6129         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6130           return "rx-no-buf";
6131         case VNET_INTERFACE_COUNTER_RX_MISS:
6132           return "rx-miss";
6133         case VNET_INTERFACE_COUNTER_RX_ERROR:
6134           return "rx-error";
6135         case VNET_INTERFACE_COUNTER_TX_ERROR:
6136           return "tx-error";
6137         default:
6138           return "INVALID-COUNTER-TYPE";
6139         }
6140     }
6141   else
6142     {
6143       switch (counter_type)
6144         {
6145         case VNET_INTERFACE_COUNTER_RX:
6146           return "rx";
6147         case VNET_INTERFACE_COUNTER_TX:
6148           return "tx";
6149         default:
6150           return "INVALID-COUNTER-TYPE";
6151         }
6152     }
6153 }
6154
6155 static int
6156 dump_stats_table (vat_main_t * vam)
6157 {
6158   vat_json_node_t node;
6159   vat_json_node_t *msg_array;
6160   vat_json_node_t *msg;
6161   vat_json_node_t *counter_array;
6162   vat_json_node_t *counter;
6163   interface_counter_t c;
6164   u64 packets;
6165   ip4_fib_counter_t *c4;
6166   ip6_fib_counter_t *c6;
6167   ip4_nbr_counter_t *n4;
6168   ip6_nbr_counter_t *n6;
6169   int i, j;
6170
6171   if (!vam->json_output)
6172     {
6173       clib_warning ("dump_stats_table supported only in JSON format");
6174       return -99;
6175     }
6176
6177   vat_json_init_object (&node);
6178
6179   /* interface counters */
6180   msg_array = vat_json_object_add (&node, "interface_counters");
6181   vat_json_init_array (msg_array);
6182   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6183     {
6184       msg = vat_json_array_add (msg_array);
6185       vat_json_init_object (msg);
6186       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6187                                        (u8 *) counter_type_to_str (i, 0));
6188       vat_json_object_add_int (msg, "is_combined", 0);
6189       counter_array = vat_json_object_add (msg, "data");
6190       vat_json_init_array (counter_array);
6191       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6192         {
6193           packets = vam->simple_interface_counters[i][j];
6194           vat_json_array_add_uint (counter_array, packets);
6195         }
6196     }
6197   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6198     {
6199       msg = vat_json_array_add (msg_array);
6200       vat_json_init_object (msg);
6201       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6202                                        (u8 *) counter_type_to_str (i, 1));
6203       vat_json_object_add_int (msg, "is_combined", 1);
6204       counter_array = vat_json_object_add (msg, "data");
6205       vat_json_init_array (counter_array);
6206       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6207         {
6208           c = vam->combined_interface_counters[i][j];
6209           counter = vat_json_array_add (counter_array);
6210           vat_json_init_object (counter);
6211           vat_json_object_add_uint (counter, "packets", c.packets);
6212           vat_json_object_add_uint (counter, "bytes", c.bytes);
6213         }
6214     }
6215
6216   /* ip4 fib counters */
6217   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6218   vat_json_init_array (msg_array);
6219   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6220     {
6221       msg = vat_json_array_add (msg_array);
6222       vat_json_init_object (msg);
6223       vat_json_object_add_uint (msg, "vrf_id",
6224                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6225       counter_array = vat_json_object_add (msg, "c");
6226       vat_json_init_array (counter_array);
6227       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6228         {
6229           counter = vat_json_array_add (counter_array);
6230           vat_json_init_object (counter);
6231           c4 = &vam->ip4_fib_counters[i][j];
6232           vat_json_object_add_ip4 (counter, "address", c4->address);
6233           vat_json_object_add_uint (counter, "address_length",
6234                                     c4->address_length);
6235           vat_json_object_add_uint (counter, "packets", c4->packets);
6236           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6237         }
6238     }
6239
6240   /* ip6 fib counters */
6241   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6242   vat_json_init_array (msg_array);
6243   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6244     {
6245       msg = vat_json_array_add (msg_array);
6246       vat_json_init_object (msg);
6247       vat_json_object_add_uint (msg, "vrf_id",
6248                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6249       counter_array = vat_json_object_add (msg, "c");
6250       vat_json_init_array (counter_array);
6251       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6252         {
6253           counter = vat_json_array_add (counter_array);
6254           vat_json_init_object (counter);
6255           c6 = &vam->ip6_fib_counters[i][j];
6256           vat_json_object_add_ip6 (counter, "address", c6->address);
6257           vat_json_object_add_uint (counter, "address_length",
6258                                     c6->address_length);
6259           vat_json_object_add_uint (counter, "packets", c6->packets);
6260           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6261         }
6262     }
6263
6264   /* ip4 nbr counters */
6265   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6266   vat_json_init_array (msg_array);
6267   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6268     {
6269       msg = vat_json_array_add (msg_array);
6270       vat_json_init_object (msg);
6271       vat_json_object_add_uint (msg, "sw_if_index", i);
6272       counter_array = vat_json_object_add (msg, "c");
6273       vat_json_init_array (counter_array);
6274       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6275         {
6276           counter = vat_json_array_add (counter_array);
6277           vat_json_init_object (counter);
6278           n4 = &vam->ip4_nbr_counters[i][j];
6279           vat_json_object_add_ip4 (counter, "address", n4->address);
6280           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6281           vat_json_object_add_uint (counter, "packets", n4->packets);
6282           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6283         }
6284     }
6285
6286   /* ip6 nbr counters */
6287   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6288   vat_json_init_array (msg_array);
6289   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6290     {
6291       msg = vat_json_array_add (msg_array);
6292       vat_json_init_object (msg);
6293       vat_json_object_add_uint (msg, "sw_if_index", i);
6294       counter_array = vat_json_object_add (msg, "c");
6295       vat_json_init_array (counter_array);
6296       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6297         {
6298           counter = vat_json_array_add (counter_array);
6299           vat_json_init_object (counter);
6300           n6 = &vam->ip6_nbr_counters[i][j];
6301           vat_json_object_add_ip6 (counter, "address", n6->address);
6302           vat_json_object_add_uint (counter, "packets", n6->packets);
6303           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6304         }
6305     }
6306
6307   vat_json_print (vam->ofp, &node);
6308   vat_json_free (&node);
6309
6310   return 0;
6311 }
6312
6313 /*
6314  * Pass CLI buffers directly in the CLI_INBAND API message,
6315  * instead of an additional shared memory area.
6316  */
6317 static int
6318 exec_inband (vat_main_t * vam)
6319 {
6320   vl_api_cli_inband_t *mp;
6321   unformat_input_t *i = vam->input;
6322   int ret;
6323
6324   if (vec_len (i->buffer) == 0)
6325     return -1;
6326
6327   if (vam->exec_mode == 0 && unformat (i, "mode"))
6328     {
6329       vam->exec_mode = 1;
6330       return 0;
6331     }
6332   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6333     {
6334       vam->exec_mode = 0;
6335       return 0;
6336     }
6337
6338   /*
6339    * In order for the CLI command to work, it
6340    * must be a vector ending in \n, not a C-string ending
6341    * in \n\0.
6342    */
6343   u32 len = vec_len (vam->input->buffer);
6344   M2 (CLI_INBAND, mp, len);
6345   clib_memcpy (mp->cmd, vam->input->buffer, len);
6346   mp->length = htonl (len);
6347
6348   S (mp);
6349   W (ret);
6350   /* json responses may or may not include a useful reply... */
6351   if (vec_len (vam->cmd_reply))
6352     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6353   return ret;
6354 }
6355
6356 int
6357 exec (vat_main_t * vam)
6358 {
6359   return exec_inband (vam);
6360 }
6361
6362 static int
6363 api_create_loopback (vat_main_t * vam)
6364 {
6365   unformat_input_t *i = vam->input;
6366   vl_api_create_loopback_t *mp;
6367   vl_api_create_loopback_instance_t *mp_lbi;
6368   u8 mac_address[6];
6369   u8 mac_set = 0;
6370   u8 is_specified = 0;
6371   u32 user_instance = 0;
6372   int ret;
6373
6374   clib_memset (mac_address, 0, sizeof (mac_address));
6375
6376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6377     {
6378       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6379         mac_set = 1;
6380       if (unformat (i, "instance %d", &user_instance))
6381         is_specified = 1;
6382       else
6383         break;
6384     }
6385
6386   if (is_specified)
6387     {
6388       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6389       mp_lbi->is_specified = is_specified;
6390       if (is_specified)
6391         mp_lbi->user_instance = htonl (user_instance);
6392       if (mac_set)
6393         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6394       S (mp_lbi);
6395     }
6396   else
6397     {
6398       /* Construct the API message */
6399       M (CREATE_LOOPBACK, mp);
6400       if (mac_set)
6401         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6402       S (mp);
6403     }
6404
6405   W (ret);
6406   return ret;
6407 }
6408
6409 static int
6410 api_delete_loopback (vat_main_t * vam)
6411 {
6412   unformat_input_t *i = vam->input;
6413   vl_api_delete_loopback_t *mp;
6414   u32 sw_if_index = ~0;
6415   int ret;
6416
6417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6418     {
6419       if (unformat (i, "sw_if_index %d", &sw_if_index))
6420         ;
6421       else
6422         break;
6423     }
6424
6425   if (sw_if_index == ~0)
6426     {
6427       errmsg ("missing sw_if_index");
6428       return -99;
6429     }
6430
6431   /* Construct the API message */
6432   M (DELETE_LOOPBACK, mp);
6433   mp->sw_if_index = ntohl (sw_if_index);
6434
6435   S (mp);
6436   W (ret);
6437   return ret;
6438 }
6439
6440 static int
6441 api_want_stats (vat_main_t * vam)
6442 {
6443   unformat_input_t *i = vam->input;
6444   vl_api_want_stats_t *mp;
6445   int enable = -1;
6446   int ret;
6447
6448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6449     {
6450       if (unformat (i, "enable"))
6451         enable = 1;
6452       else if (unformat (i, "disable"))
6453         enable = 0;
6454       else
6455         break;
6456     }
6457
6458   if (enable == -1)
6459     {
6460       errmsg ("missing enable|disable");
6461       return -99;
6462     }
6463
6464   M (WANT_STATS, mp);
6465   mp->enable_disable = enable;
6466
6467   S (mp);
6468   W (ret);
6469   return ret;
6470 }
6471
6472 static int
6473 api_want_interface_events (vat_main_t * vam)
6474 {
6475   unformat_input_t *i = vam->input;
6476   vl_api_want_interface_events_t *mp;
6477   int enable = -1;
6478   int ret;
6479
6480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6481     {
6482       if (unformat (i, "enable"))
6483         enable = 1;
6484       else if (unformat (i, "disable"))
6485         enable = 0;
6486       else
6487         break;
6488     }
6489
6490   if (enable == -1)
6491     {
6492       errmsg ("missing enable|disable");
6493       return -99;
6494     }
6495
6496   M (WANT_INTERFACE_EVENTS, mp);
6497   mp->enable_disable = enable;
6498
6499   vam->interface_event_display = enable;
6500
6501   S (mp);
6502   W (ret);
6503   return ret;
6504 }
6505
6506
6507 /* Note: non-static, called once to set up the initial intfc table */
6508 int
6509 api_sw_interface_dump (vat_main_t * vam)
6510 {
6511   vl_api_sw_interface_dump_t *mp;
6512   vl_api_control_ping_t *mp_ping;
6513   hash_pair_t *p;
6514   name_sort_t *nses = 0, *ns;
6515   sw_interface_subif_t *sub = NULL;
6516   int ret;
6517
6518   /* Toss the old name table */
6519   /* *INDENT-OFF* */
6520   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6521   ({
6522     vec_add2 (nses, ns, 1);
6523     ns->name = (u8 *)(p->key);
6524     ns->value = (u32) p->value[0];
6525   }));
6526   /* *INDENT-ON* */
6527
6528   hash_free (vam->sw_if_index_by_interface_name);
6529
6530   vec_foreach (ns, nses) vec_free (ns->name);
6531
6532   vec_free (nses);
6533
6534   vec_foreach (sub, vam->sw_if_subif_table)
6535   {
6536     vec_free (sub->interface_name);
6537   }
6538   vec_free (vam->sw_if_subif_table);
6539
6540   /* recreate the interface name hash table */
6541   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6542
6543   /*
6544    * Ask for all interface names. Otherwise, the epic catalog of
6545    * name filters becomes ridiculously long, and vat ends up needing
6546    * to be taught about new interface types.
6547    */
6548   M (SW_INTERFACE_DUMP, mp);
6549   S (mp);
6550
6551   /* Use a control ping for synchronization */
6552   MPING (CONTROL_PING, mp_ping);
6553   S (mp_ping);
6554
6555   W (ret);
6556   return ret;
6557 }
6558
6559 static int
6560 api_sw_interface_set_flags (vat_main_t * vam)
6561 {
6562   unformat_input_t *i = vam->input;
6563   vl_api_sw_interface_set_flags_t *mp;
6564   u32 sw_if_index;
6565   u8 sw_if_index_set = 0;
6566   u8 admin_up = 0;
6567   int ret;
6568
6569   /* Parse args required to build the message */
6570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6571     {
6572       if (unformat (i, "admin-up"))
6573         admin_up = 1;
6574       else if (unformat (i, "admin-down"))
6575         admin_up = 0;
6576       else
6577         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6578         sw_if_index_set = 1;
6579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6580         sw_if_index_set = 1;
6581       else
6582         break;
6583     }
6584
6585   if (sw_if_index_set == 0)
6586     {
6587       errmsg ("missing interface name or sw_if_index");
6588       return -99;
6589     }
6590
6591   /* Construct the API message */
6592   M (SW_INTERFACE_SET_FLAGS, mp);
6593   mp->sw_if_index = ntohl (sw_if_index);
6594   mp->admin_up_down = admin_up;
6595
6596   /* send it... */
6597   S (mp);
6598
6599   /* Wait for a reply, return the good/bad news... */
6600   W (ret);
6601   return ret;
6602 }
6603
6604 static int
6605 api_sw_interface_set_rx_mode (vat_main_t * vam)
6606 {
6607   unformat_input_t *i = vam->input;
6608   vl_api_sw_interface_set_rx_mode_t *mp;
6609   u32 sw_if_index;
6610   u8 sw_if_index_set = 0;
6611   int ret;
6612   u8 queue_id_valid = 0;
6613   u32 queue_id;
6614   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6615
6616   /* Parse args required to build the message */
6617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6618     {
6619       if (unformat (i, "queue %d", &queue_id))
6620         queue_id_valid = 1;
6621       else if (unformat (i, "polling"))
6622         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6623       else if (unformat (i, "interrupt"))
6624         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6625       else if (unformat (i, "adaptive"))
6626         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6627       else
6628         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6631         sw_if_index_set = 1;
6632       else
6633         break;
6634     }
6635
6636   if (sw_if_index_set == 0)
6637     {
6638       errmsg ("missing interface name or sw_if_index");
6639       return -99;
6640     }
6641   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6642     {
6643       errmsg ("missing rx-mode");
6644       return -99;
6645     }
6646
6647   /* Construct the API message */
6648   M (SW_INTERFACE_SET_RX_MODE, mp);
6649   mp->sw_if_index = ntohl (sw_if_index);
6650   mp->mode = mode;
6651   mp->queue_id_valid = queue_id_valid;
6652   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6653
6654   /* send it... */
6655   S (mp);
6656
6657   /* Wait for a reply, return the good/bad news... */
6658   W (ret);
6659   return ret;
6660 }
6661
6662 static int
6663 api_sw_interface_set_rx_placement (vat_main_t * vam)
6664 {
6665   unformat_input_t *i = vam->input;
6666   vl_api_sw_interface_set_rx_placement_t *mp;
6667   u32 sw_if_index;
6668   u8 sw_if_index_set = 0;
6669   int ret;
6670   u8 is_main = 0;
6671   u32 queue_id, thread_index;
6672
6673   /* Parse args required to build the message */
6674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6675     {
6676       if (unformat (i, "queue %d", &queue_id))
6677         ;
6678       else if (unformat (i, "main"))
6679         is_main = 1;
6680       else if (unformat (i, "worker %d", &thread_index))
6681         ;
6682       else
6683         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6684         sw_if_index_set = 1;
6685       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6686         sw_if_index_set = 1;
6687       else
6688         break;
6689     }
6690
6691   if (sw_if_index_set == 0)
6692     {
6693       errmsg ("missing interface name or sw_if_index");
6694       return -99;
6695     }
6696
6697   if (is_main)
6698     thread_index = 0;
6699   /* Construct the API message */
6700   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6701   mp->sw_if_index = ntohl (sw_if_index);
6702   mp->worker_id = ntohl (thread_index);
6703   mp->queue_id = ntohl (queue_id);
6704   mp->is_main = is_main;
6705
6706   /* send it... */
6707   S (mp);
6708   /* Wait for a reply, return the good/bad news... */
6709   W (ret);
6710   return ret;
6711 }
6712
6713 static void vl_api_sw_interface_rx_placement_details_t_handler
6714   (vl_api_sw_interface_rx_placement_details_t * mp)
6715 {
6716   vat_main_t *vam = &vat_main;
6717   u32 worker_id = ntohl (mp->worker_id);
6718
6719   print (vam->ofp,
6720          "\n%-11d %-11s %-6d %-5d %-9s",
6721          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6722          worker_id, ntohl (mp->queue_id),
6723          (mp->mode ==
6724           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6725 }
6726
6727 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6728   (vl_api_sw_interface_rx_placement_details_t * mp)
6729 {
6730   vat_main_t *vam = &vat_main;
6731   vat_json_node_t *node = NULL;
6732
6733   if (VAT_JSON_ARRAY != vam->json_tree.type)
6734     {
6735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6736       vat_json_init_array (&vam->json_tree);
6737     }
6738   node = vat_json_array_add (&vam->json_tree);
6739
6740   vat_json_init_object (node);
6741   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6742   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6743   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6744   vat_json_object_add_uint (node, "mode", mp->mode);
6745 }
6746
6747 static int
6748 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6749 {
6750   unformat_input_t *i = vam->input;
6751   vl_api_sw_interface_rx_placement_dump_t *mp;
6752   vl_api_control_ping_t *mp_ping;
6753   int ret;
6754   u32 sw_if_index;
6755   u8 sw_if_index_set = 0;
6756
6757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6758     {
6759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6760         sw_if_index_set++;
6761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6762         sw_if_index_set++;
6763       else
6764         break;
6765     }
6766
6767   print (vam->ofp,
6768          "\n%-11s %-11s %-6s %-5s %-4s",
6769          "sw_if_index", "main/worker", "thread", "queue", "mode");
6770
6771   /* Dump Interface rx placement */
6772   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6773
6774   if (sw_if_index_set)
6775     mp->sw_if_index = htonl (sw_if_index);
6776   else
6777     mp->sw_if_index = ~0;
6778
6779   S (mp);
6780
6781   /* Use a control ping for synchronization */
6782   MPING (CONTROL_PING, mp_ping);
6783   S (mp_ping);
6784
6785   W (ret);
6786   return ret;
6787 }
6788
6789 static int
6790 api_sw_interface_clear_stats (vat_main_t * vam)
6791 {
6792   unformat_input_t *i = vam->input;
6793   vl_api_sw_interface_clear_stats_t *mp;
6794   u32 sw_if_index;
6795   u8 sw_if_index_set = 0;
6796   int ret;
6797
6798   /* Parse args required to build the message */
6799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6800     {
6801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6802         sw_if_index_set = 1;
6803       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6804         sw_if_index_set = 1;
6805       else
6806         break;
6807     }
6808
6809   /* Construct the API message */
6810   M (SW_INTERFACE_CLEAR_STATS, mp);
6811
6812   if (sw_if_index_set == 1)
6813     mp->sw_if_index = ntohl (sw_if_index);
6814   else
6815     mp->sw_if_index = ~0;
6816
6817   /* send it... */
6818   S (mp);
6819
6820   /* Wait for a reply, return the good/bad news... */
6821   W (ret);
6822   return ret;
6823 }
6824
6825 static int
6826 api_sw_interface_add_del_address (vat_main_t * vam)
6827 {
6828   unformat_input_t *i = vam->input;
6829   vl_api_sw_interface_add_del_address_t *mp;
6830   u32 sw_if_index;
6831   u8 sw_if_index_set = 0;
6832   u8 is_add = 1, del_all = 0;
6833   u32 address_length = 0;
6834   u8 v4_address_set = 0;
6835   u8 v6_address_set = 0;
6836   ip4_address_t v4address;
6837   ip6_address_t v6address;
6838   int ret;
6839
6840   /* Parse args required to build the message */
6841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6842     {
6843       if (unformat (i, "del-all"))
6844         del_all = 1;
6845       else if (unformat (i, "del"))
6846         is_add = 0;
6847       else
6848         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6849         sw_if_index_set = 1;
6850       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6851         sw_if_index_set = 1;
6852       else if (unformat (i, "%U/%d",
6853                          unformat_ip4_address, &v4address, &address_length))
6854         v4_address_set = 1;
6855       else if (unformat (i, "%U/%d",
6856                          unformat_ip6_address, &v6address, &address_length))
6857         v6_address_set = 1;
6858       else
6859         break;
6860     }
6861
6862   if (sw_if_index_set == 0)
6863     {
6864       errmsg ("missing interface name or sw_if_index");
6865       return -99;
6866     }
6867   if (v4_address_set && v6_address_set)
6868     {
6869       errmsg ("both v4 and v6 addresses set");
6870       return -99;
6871     }
6872   if (!v4_address_set && !v6_address_set && !del_all)
6873     {
6874       errmsg ("no addresses set");
6875       return -99;
6876     }
6877
6878   /* Construct the API message */
6879   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6880
6881   mp->sw_if_index = ntohl (sw_if_index);
6882   mp->is_add = is_add;
6883   mp->del_all = del_all;
6884   if (v6_address_set)
6885     {
6886       mp->is_ipv6 = 1;
6887       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6888     }
6889   else
6890     {
6891       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6892     }
6893   mp->address_length = address_length;
6894
6895   /* send it... */
6896   S (mp);
6897
6898   /* Wait for a reply, return good/bad news  */
6899   W (ret);
6900   return ret;
6901 }
6902
6903 static int
6904 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6905 {
6906   unformat_input_t *i = vam->input;
6907   vl_api_sw_interface_set_mpls_enable_t *mp;
6908   u32 sw_if_index;
6909   u8 sw_if_index_set = 0;
6910   u8 enable = 1;
6911   int ret;
6912
6913   /* Parse args required to build the message */
6914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6915     {
6916       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6917         sw_if_index_set = 1;
6918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6919         sw_if_index_set = 1;
6920       else if (unformat (i, "disable"))
6921         enable = 0;
6922       else if (unformat (i, "dis"))
6923         enable = 0;
6924       else
6925         break;
6926     }
6927
6928   if (sw_if_index_set == 0)
6929     {
6930       errmsg ("missing interface name or sw_if_index");
6931       return -99;
6932     }
6933
6934   /* Construct the API message */
6935   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6936
6937   mp->sw_if_index = ntohl (sw_if_index);
6938   mp->enable = enable;
6939
6940   /* send it... */
6941   S (mp);
6942
6943   /* Wait for a reply... */
6944   W (ret);
6945   return ret;
6946 }
6947
6948 static int
6949 api_sw_interface_set_table (vat_main_t * vam)
6950 {
6951   unformat_input_t *i = vam->input;
6952   vl_api_sw_interface_set_table_t *mp;
6953   u32 sw_if_index, vrf_id = 0;
6954   u8 sw_if_index_set = 0;
6955   u8 is_ipv6 = 0;
6956   int ret;
6957
6958   /* Parse args required to build the message */
6959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6960     {
6961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6962         sw_if_index_set = 1;
6963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6964         sw_if_index_set = 1;
6965       else if (unformat (i, "vrf %d", &vrf_id))
6966         ;
6967       else if (unformat (i, "ipv6"))
6968         is_ipv6 = 1;
6969       else
6970         break;
6971     }
6972
6973   if (sw_if_index_set == 0)
6974     {
6975       errmsg ("missing interface name or sw_if_index");
6976       return -99;
6977     }
6978
6979   /* Construct the API message */
6980   M (SW_INTERFACE_SET_TABLE, mp);
6981
6982   mp->sw_if_index = ntohl (sw_if_index);
6983   mp->is_ipv6 = is_ipv6;
6984   mp->vrf_id = ntohl (vrf_id);
6985
6986   /* send it... */
6987   S (mp);
6988
6989   /* Wait for a reply... */
6990   W (ret);
6991   return ret;
6992 }
6993
6994 static void vl_api_sw_interface_get_table_reply_t_handler
6995   (vl_api_sw_interface_get_table_reply_t * mp)
6996 {
6997   vat_main_t *vam = &vat_main;
6998
6999   print (vam->ofp, "%d", ntohl (mp->vrf_id));
7000
7001   vam->retval = ntohl (mp->retval);
7002   vam->result_ready = 1;
7003
7004 }
7005
7006 static void vl_api_sw_interface_get_table_reply_t_handler_json
7007   (vl_api_sw_interface_get_table_reply_t * mp)
7008 {
7009   vat_main_t *vam = &vat_main;
7010   vat_json_node_t node;
7011
7012   vat_json_init_object (&node);
7013   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
7014   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
7015
7016   vat_json_print (vam->ofp, &node);
7017   vat_json_free (&node);
7018
7019   vam->retval = ntohl (mp->retval);
7020   vam->result_ready = 1;
7021 }
7022
7023 static int
7024 api_sw_interface_get_table (vat_main_t * vam)
7025 {
7026   unformat_input_t *i = vam->input;
7027   vl_api_sw_interface_get_table_t *mp;
7028   u32 sw_if_index;
7029   u8 sw_if_index_set = 0;
7030   u8 is_ipv6 = 0;
7031   int ret;
7032
7033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7034     {
7035       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7036         sw_if_index_set = 1;
7037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7038         sw_if_index_set = 1;
7039       else if (unformat (i, "ipv6"))
7040         is_ipv6 = 1;
7041       else
7042         break;
7043     }
7044
7045   if (sw_if_index_set == 0)
7046     {
7047       errmsg ("missing interface name or sw_if_index");
7048       return -99;
7049     }
7050
7051   M (SW_INTERFACE_GET_TABLE, mp);
7052   mp->sw_if_index = htonl (sw_if_index);
7053   mp->is_ipv6 = is_ipv6;
7054
7055   S (mp);
7056   W (ret);
7057   return ret;
7058 }
7059
7060 static int
7061 api_sw_interface_set_vpath (vat_main_t * vam)
7062 {
7063   unformat_input_t *i = vam->input;
7064   vl_api_sw_interface_set_vpath_t *mp;
7065   u32 sw_if_index = 0;
7066   u8 sw_if_index_set = 0;
7067   u8 is_enable = 0;
7068   int ret;
7069
7070   /* Parse args required to build the message */
7071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072     {
7073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7074         sw_if_index_set = 1;
7075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7076         sw_if_index_set = 1;
7077       else if (unformat (i, "enable"))
7078         is_enable = 1;
7079       else if (unformat (i, "disable"))
7080         is_enable = 0;
7081       else
7082         break;
7083     }
7084
7085   if (sw_if_index_set == 0)
7086     {
7087       errmsg ("missing interface name or sw_if_index");
7088       return -99;
7089     }
7090
7091   /* Construct the API message */
7092   M (SW_INTERFACE_SET_VPATH, mp);
7093
7094   mp->sw_if_index = ntohl (sw_if_index);
7095   mp->enable = is_enable;
7096
7097   /* send it... */
7098   S (mp);
7099
7100   /* Wait for a reply... */
7101   W (ret);
7102   return ret;
7103 }
7104
7105 static int
7106 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7107 {
7108   unformat_input_t *i = vam->input;
7109   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7110   u32 sw_if_index = 0;
7111   u8 sw_if_index_set = 0;
7112   u8 is_enable = 1;
7113   u8 is_ipv6 = 0;
7114   int ret;
7115
7116   /* Parse args required to build the message */
7117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7118     {
7119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7120         sw_if_index_set = 1;
7121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7122         sw_if_index_set = 1;
7123       else if (unformat (i, "enable"))
7124         is_enable = 1;
7125       else if (unformat (i, "disable"))
7126         is_enable = 0;
7127       else if (unformat (i, "ip4"))
7128         is_ipv6 = 0;
7129       else if (unformat (i, "ip6"))
7130         is_ipv6 = 1;
7131       else
7132         break;
7133     }
7134
7135   if (sw_if_index_set == 0)
7136     {
7137       errmsg ("missing interface name or sw_if_index");
7138       return -99;
7139     }
7140
7141   /* Construct the API message */
7142   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7143
7144   mp->sw_if_index = ntohl (sw_if_index);
7145   mp->enable = is_enable;
7146   mp->is_ipv6 = is_ipv6;
7147
7148   /* send it... */
7149   S (mp);
7150
7151   /* Wait for a reply... */
7152   W (ret);
7153   return ret;
7154 }
7155
7156 static int
7157 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7158 {
7159   unformat_input_t *i = vam->input;
7160   vl_api_sw_interface_set_geneve_bypass_t *mp;
7161   u32 sw_if_index = 0;
7162   u8 sw_if_index_set = 0;
7163   u8 is_enable = 1;
7164   u8 is_ipv6 = 0;
7165   int ret;
7166
7167   /* Parse args required to build the message */
7168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7169     {
7170       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7171         sw_if_index_set = 1;
7172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7173         sw_if_index_set = 1;
7174       else if (unformat (i, "enable"))
7175         is_enable = 1;
7176       else if (unformat (i, "disable"))
7177         is_enable = 0;
7178       else if (unformat (i, "ip4"))
7179         is_ipv6 = 0;
7180       else if (unformat (i, "ip6"))
7181         is_ipv6 = 1;
7182       else
7183         break;
7184     }
7185
7186   if (sw_if_index_set == 0)
7187     {
7188       errmsg ("missing interface name or sw_if_index");
7189       return -99;
7190     }
7191
7192   /* Construct the API message */
7193   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7194
7195   mp->sw_if_index = ntohl (sw_if_index);
7196   mp->enable = is_enable;
7197   mp->is_ipv6 = is_ipv6;
7198
7199   /* send it... */
7200   S (mp);
7201
7202   /* Wait for a reply... */
7203   W (ret);
7204   return ret;
7205 }
7206
7207 static int
7208 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7209 {
7210   unformat_input_t *i = vam->input;
7211   vl_api_sw_interface_set_l2_xconnect_t *mp;
7212   u32 rx_sw_if_index;
7213   u8 rx_sw_if_index_set = 0;
7214   u32 tx_sw_if_index;
7215   u8 tx_sw_if_index_set = 0;
7216   u8 enable = 1;
7217   int ret;
7218
7219   /* Parse args required to build the message */
7220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7221     {
7222       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7223         rx_sw_if_index_set = 1;
7224       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7225         tx_sw_if_index_set = 1;
7226       else if (unformat (i, "rx"))
7227         {
7228           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7229             {
7230               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7231                             &rx_sw_if_index))
7232                 rx_sw_if_index_set = 1;
7233             }
7234           else
7235             break;
7236         }
7237       else if (unformat (i, "tx"))
7238         {
7239           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7240             {
7241               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7242                             &tx_sw_if_index))
7243                 tx_sw_if_index_set = 1;
7244             }
7245           else
7246             break;
7247         }
7248       else if (unformat (i, "enable"))
7249         enable = 1;
7250       else if (unformat (i, "disable"))
7251         enable = 0;
7252       else
7253         break;
7254     }
7255
7256   if (rx_sw_if_index_set == 0)
7257     {
7258       errmsg ("missing rx interface name or rx_sw_if_index");
7259       return -99;
7260     }
7261
7262   if (enable && (tx_sw_if_index_set == 0))
7263     {
7264       errmsg ("missing tx interface name or tx_sw_if_index");
7265       return -99;
7266     }
7267
7268   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7269
7270   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7271   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7272   mp->enable = enable;
7273
7274   S (mp);
7275   W (ret);
7276   return ret;
7277 }
7278
7279 static int
7280 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7281 {
7282   unformat_input_t *i = vam->input;
7283   vl_api_sw_interface_set_l2_bridge_t *mp;
7284   vl_api_l2_port_type_t port_type;
7285   u32 rx_sw_if_index;
7286   u8 rx_sw_if_index_set = 0;
7287   u32 bd_id;
7288   u8 bd_id_set = 0;
7289   u32 shg = 0;
7290   u8 enable = 1;
7291   int ret;
7292
7293   port_type = L2_API_PORT_TYPE_NORMAL;
7294
7295   /* Parse args required to build the message */
7296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7297     {
7298       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7299         rx_sw_if_index_set = 1;
7300       else if (unformat (i, "bd_id %d", &bd_id))
7301         bd_id_set = 1;
7302       else
7303         if (unformat
7304             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7305         rx_sw_if_index_set = 1;
7306       else if (unformat (i, "shg %d", &shg))
7307         ;
7308       else if (unformat (i, "bvi"))
7309         port_type = L2_API_PORT_TYPE_BVI;
7310       else if (unformat (i, "uu-fwd"))
7311         port_type = L2_API_PORT_TYPE_UU_FWD;
7312       else if (unformat (i, "enable"))
7313         enable = 1;
7314       else if (unformat (i, "disable"))
7315         enable = 0;
7316       else
7317         break;
7318     }
7319
7320   if (rx_sw_if_index_set == 0)
7321     {
7322       errmsg ("missing rx interface name or sw_if_index");
7323       return -99;
7324     }
7325
7326   if (enable && (bd_id_set == 0))
7327     {
7328       errmsg ("missing bridge domain");
7329       return -99;
7330     }
7331
7332   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7333
7334   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7335   mp->bd_id = ntohl (bd_id);
7336   mp->shg = (u8) shg;
7337   mp->port_type = ntohl (port_type);
7338   mp->enable = enable;
7339
7340   S (mp);
7341   W (ret);
7342   return ret;
7343 }
7344
7345 static int
7346 api_bridge_domain_dump (vat_main_t * vam)
7347 {
7348   unformat_input_t *i = vam->input;
7349   vl_api_bridge_domain_dump_t *mp;
7350   vl_api_control_ping_t *mp_ping;
7351   u32 bd_id = ~0;
7352   int ret;
7353
7354   /* Parse args required to build the message */
7355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7356     {
7357       if (unformat (i, "bd_id %d", &bd_id))
7358         ;
7359       else
7360         break;
7361     }
7362
7363   M (BRIDGE_DOMAIN_DUMP, mp);
7364   mp->bd_id = ntohl (bd_id);
7365   S (mp);
7366
7367   /* Use a control ping for synchronization */
7368   MPING (CONTROL_PING, mp_ping);
7369   S (mp_ping);
7370
7371   W (ret);
7372   return ret;
7373 }
7374
7375 static int
7376 api_bridge_domain_add_del (vat_main_t * vam)
7377 {
7378   unformat_input_t *i = vam->input;
7379   vl_api_bridge_domain_add_del_t *mp;
7380   u32 bd_id = ~0;
7381   u8 is_add = 1;
7382   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7383   u8 *bd_tag = NULL;
7384   u32 mac_age = 0;
7385   int ret;
7386
7387   /* Parse args required to build the message */
7388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7389     {
7390       if (unformat (i, "bd_id %d", &bd_id))
7391         ;
7392       else if (unformat (i, "flood %d", &flood))
7393         ;
7394       else if (unformat (i, "uu-flood %d", &uu_flood))
7395         ;
7396       else if (unformat (i, "forward %d", &forward))
7397         ;
7398       else if (unformat (i, "learn %d", &learn))
7399         ;
7400       else if (unformat (i, "arp-term %d", &arp_term))
7401         ;
7402       else if (unformat (i, "mac-age %d", &mac_age))
7403         ;
7404       else if (unformat (i, "bd-tag %s", &bd_tag))
7405         ;
7406       else if (unformat (i, "del"))
7407         {
7408           is_add = 0;
7409           flood = uu_flood = forward = learn = 0;
7410         }
7411       else
7412         break;
7413     }
7414
7415   if (bd_id == ~0)
7416     {
7417       errmsg ("missing bridge domain");
7418       ret = -99;
7419       goto done;
7420     }
7421
7422   if (mac_age > 255)
7423     {
7424       errmsg ("mac age must be less than 256 ");
7425       ret = -99;
7426       goto done;
7427     }
7428
7429   if ((bd_tag) && (vec_len (bd_tag) > 63))
7430     {
7431       errmsg ("bd-tag cannot be longer than 63");
7432       ret = -99;
7433       goto done;
7434     }
7435
7436   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7437
7438   mp->bd_id = ntohl (bd_id);
7439   mp->flood = flood;
7440   mp->uu_flood = uu_flood;
7441   mp->forward = forward;
7442   mp->learn = learn;
7443   mp->arp_term = arp_term;
7444   mp->is_add = is_add;
7445   mp->mac_age = (u8) mac_age;
7446   if (bd_tag)
7447     {
7448       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7449       mp->bd_tag[vec_len (bd_tag)] = 0;
7450     }
7451   S (mp);
7452   W (ret);
7453
7454 done:
7455   vec_free (bd_tag);
7456   return ret;
7457 }
7458
7459 static int
7460 api_l2fib_flush_bd (vat_main_t * vam)
7461 {
7462   unformat_input_t *i = vam->input;
7463   vl_api_l2fib_flush_bd_t *mp;
7464   u32 bd_id = ~0;
7465   int ret;
7466
7467   /* Parse args required to build the message */
7468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7469     {
7470       if (unformat (i, "bd_id %d", &bd_id));
7471       else
7472         break;
7473     }
7474
7475   if (bd_id == ~0)
7476     {
7477       errmsg ("missing bridge domain");
7478       return -99;
7479     }
7480
7481   M (L2FIB_FLUSH_BD, mp);
7482
7483   mp->bd_id = htonl (bd_id);
7484
7485   S (mp);
7486   W (ret);
7487   return ret;
7488 }
7489
7490 static int
7491 api_l2fib_flush_int (vat_main_t * vam)
7492 {
7493   unformat_input_t *i = vam->input;
7494   vl_api_l2fib_flush_int_t *mp;
7495   u32 sw_if_index = ~0;
7496   int ret;
7497
7498   /* Parse args required to build the message */
7499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7500     {
7501       if (unformat (i, "sw_if_index %d", &sw_if_index));
7502       else
7503         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7504       else
7505         break;
7506     }
7507
7508   if (sw_if_index == ~0)
7509     {
7510       errmsg ("missing interface name or sw_if_index");
7511       return -99;
7512     }
7513
7514   M (L2FIB_FLUSH_INT, mp);
7515
7516   mp->sw_if_index = ntohl (sw_if_index);
7517
7518   S (mp);
7519   W (ret);
7520   return ret;
7521 }
7522
7523 static int
7524 api_l2fib_add_del (vat_main_t * vam)
7525 {
7526   unformat_input_t *i = vam->input;
7527   vl_api_l2fib_add_del_t *mp;
7528   f64 timeout;
7529   u8 mac[6] = { 0 };
7530   u8 mac_set = 0;
7531   u32 bd_id;
7532   u8 bd_id_set = 0;
7533   u32 sw_if_index = 0;
7534   u8 sw_if_index_set = 0;
7535   u8 is_add = 1;
7536   u8 static_mac = 0;
7537   u8 filter_mac = 0;
7538   u8 bvi_mac = 0;
7539   int count = 1;
7540   f64 before = 0;
7541   int j;
7542
7543   /* Parse args required to build the message */
7544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7545     {
7546       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7547         mac_set = 1;
7548       else if (unformat (i, "bd_id %d", &bd_id))
7549         bd_id_set = 1;
7550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7551         sw_if_index_set = 1;
7552       else if (unformat (i, "sw_if"))
7553         {
7554           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7555             {
7556               if (unformat
7557                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7558                 sw_if_index_set = 1;
7559             }
7560           else
7561             break;
7562         }
7563       else if (unformat (i, "static"))
7564         static_mac = 1;
7565       else if (unformat (i, "filter"))
7566         {
7567           filter_mac = 1;
7568           static_mac = 1;
7569         }
7570       else if (unformat (i, "bvi"))
7571         {
7572           bvi_mac = 1;
7573           static_mac = 1;
7574         }
7575       else if (unformat (i, "del"))
7576         is_add = 0;
7577       else if (unformat (i, "count %d", &count))
7578         ;
7579       else
7580         break;
7581     }
7582
7583   if (mac_set == 0)
7584     {
7585       errmsg ("missing mac address");
7586       return -99;
7587     }
7588
7589   if (bd_id_set == 0)
7590     {
7591       errmsg ("missing bridge domain");
7592       return -99;
7593     }
7594
7595   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7596     {
7597       errmsg ("missing interface name or sw_if_index");
7598       return -99;
7599     }
7600
7601   if (count > 1)
7602     {
7603       /* Turn on async mode */
7604       vam->async_mode = 1;
7605       vam->async_errors = 0;
7606       before = vat_time_now (vam);
7607     }
7608
7609   for (j = 0; j < count; j++)
7610     {
7611       M (L2FIB_ADD_DEL, mp);
7612
7613       clib_memcpy (mp->mac, mac, 6);
7614       mp->bd_id = ntohl (bd_id);
7615       mp->is_add = is_add;
7616       mp->sw_if_index = ntohl (sw_if_index);
7617
7618       if (is_add)
7619         {
7620           mp->static_mac = static_mac;
7621           mp->filter_mac = filter_mac;
7622           mp->bvi_mac = bvi_mac;
7623         }
7624       increment_mac_address (mac);
7625       /* send it... */
7626       S (mp);
7627     }
7628
7629   if (count > 1)
7630     {
7631       vl_api_control_ping_t *mp_ping;
7632       f64 after;
7633
7634       /* Shut off async mode */
7635       vam->async_mode = 0;
7636
7637       MPING (CONTROL_PING, mp_ping);
7638       S (mp_ping);
7639
7640       timeout = vat_time_now (vam) + 1.0;
7641       while (vat_time_now (vam) < timeout)
7642         if (vam->result_ready == 1)
7643           goto out;
7644       vam->retval = -99;
7645
7646     out:
7647       if (vam->retval == -99)
7648         errmsg ("timeout");
7649
7650       if (vam->async_errors > 0)
7651         {
7652           errmsg ("%d asynchronous errors", vam->async_errors);
7653           vam->retval = -98;
7654         }
7655       vam->async_errors = 0;
7656       after = vat_time_now (vam);
7657
7658       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7659              count, after - before, count / (after - before));
7660     }
7661   else
7662     {
7663       int ret;
7664
7665       /* Wait for a reply... */
7666       W (ret);
7667       return ret;
7668     }
7669   /* Return the good/bad news */
7670   return (vam->retval);
7671 }
7672
7673 static int
7674 api_bridge_domain_set_mac_age (vat_main_t * vam)
7675 {
7676   unformat_input_t *i = vam->input;
7677   vl_api_bridge_domain_set_mac_age_t *mp;
7678   u32 bd_id = ~0;
7679   u32 mac_age = 0;
7680   int ret;
7681
7682   /* Parse args required to build the message */
7683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7684     {
7685       if (unformat (i, "bd_id %d", &bd_id));
7686       else if (unformat (i, "mac-age %d", &mac_age));
7687       else
7688         break;
7689     }
7690
7691   if (bd_id == ~0)
7692     {
7693       errmsg ("missing bridge domain");
7694       return -99;
7695     }
7696
7697   if (mac_age > 255)
7698     {
7699       errmsg ("mac age must be less than 256 ");
7700       return -99;
7701     }
7702
7703   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7704
7705   mp->bd_id = htonl (bd_id);
7706   mp->mac_age = (u8) mac_age;
7707
7708   S (mp);
7709   W (ret);
7710   return ret;
7711 }
7712
7713 static int
7714 api_l2_flags (vat_main_t * vam)
7715 {
7716   unformat_input_t *i = vam->input;
7717   vl_api_l2_flags_t *mp;
7718   u32 sw_if_index;
7719   u32 flags = 0;
7720   u8 sw_if_index_set = 0;
7721   u8 is_set = 0;
7722   int ret;
7723
7724   /* Parse args required to build the message */
7725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7726     {
7727       if (unformat (i, "sw_if_index %d", &sw_if_index))
7728         sw_if_index_set = 1;
7729       else if (unformat (i, "sw_if"))
7730         {
7731           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7732             {
7733               if (unformat
7734                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7735                 sw_if_index_set = 1;
7736             }
7737           else
7738             break;
7739         }
7740       else if (unformat (i, "learn"))
7741         flags |= L2_LEARN;
7742       else if (unformat (i, "forward"))
7743         flags |= L2_FWD;
7744       else if (unformat (i, "flood"))
7745         flags |= L2_FLOOD;
7746       else if (unformat (i, "uu-flood"))
7747         flags |= L2_UU_FLOOD;
7748       else if (unformat (i, "arp-term"))
7749         flags |= L2_ARP_TERM;
7750       else if (unformat (i, "off"))
7751         is_set = 0;
7752       else if (unformat (i, "disable"))
7753         is_set = 0;
7754       else
7755         break;
7756     }
7757
7758   if (sw_if_index_set == 0)
7759     {
7760       errmsg ("missing interface name or sw_if_index");
7761       return -99;
7762     }
7763
7764   M (L2_FLAGS, mp);
7765
7766   mp->sw_if_index = ntohl (sw_if_index);
7767   mp->feature_bitmap = ntohl (flags);
7768   mp->is_set = is_set;
7769
7770   S (mp);
7771   W (ret);
7772   return ret;
7773 }
7774
7775 static int
7776 api_bridge_flags (vat_main_t * vam)
7777 {
7778   unformat_input_t *i = vam->input;
7779   vl_api_bridge_flags_t *mp;
7780   u32 bd_id;
7781   u8 bd_id_set = 0;
7782   u8 is_set = 1;
7783   bd_flags_t flags = 0;
7784   int ret;
7785
7786   /* Parse args required to build the message */
7787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7788     {
7789       if (unformat (i, "bd_id %d", &bd_id))
7790         bd_id_set = 1;
7791       else if (unformat (i, "learn"))
7792         flags |= BRIDGE_API_FLAG_LEARN;
7793       else if (unformat (i, "forward"))
7794         flags |= BRIDGE_API_FLAG_FWD;
7795       else if (unformat (i, "flood"))
7796         flags |= BRIDGE_API_FLAG_FLOOD;
7797       else if (unformat (i, "uu-flood"))
7798         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7799       else if (unformat (i, "arp-term"))
7800         flags |= BRIDGE_API_FLAG_ARP_TERM;
7801       else if (unformat (i, "off"))
7802         is_set = 0;
7803       else if (unformat (i, "disable"))
7804         is_set = 0;
7805       else
7806         break;
7807     }
7808
7809   if (bd_id_set == 0)
7810     {
7811       errmsg ("missing bridge domain");
7812       return -99;
7813     }
7814
7815   M (BRIDGE_FLAGS, mp);
7816
7817   mp->bd_id = ntohl (bd_id);
7818   mp->flags = ntohl (flags);
7819   mp->is_set = is_set;
7820
7821   S (mp);
7822   W (ret);
7823   return ret;
7824 }
7825
7826 static int
7827 api_bd_ip_mac_add_del (vat_main_t * vam)
7828 {
7829   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7830   vl_api_mac_address_t mac = VL_API_ZERO_MAC_ADDRESS;
7831   unformat_input_t *i = vam->input;
7832   vl_api_bd_ip_mac_add_del_t *mp;
7833   ip46_type_t type;
7834   u32 bd_id;
7835   u8 is_ipv6 = 0;
7836   u8 is_add = 1;
7837   u8 bd_id_set = 0;
7838   u8 ip_set = 0;
7839   u8 mac_set = 0;
7840   u8 macaddr[6];
7841   int ret;
7842
7843
7844   /* Parse args required to build the message */
7845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7846     {
7847       if (unformat (i, "bd_id %d", &bd_id))
7848         {
7849           bd_id_set++;
7850         }
7851       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7852         {
7853           ip_set++;
7854         }
7855       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7856         {
7857           mac_set++;
7858         }
7859       else if (unformat (i, "del"))
7860         is_add = 0;
7861       else
7862         break;
7863     }
7864
7865   if (bd_id_set == 0)
7866     {
7867       errmsg ("missing bridge domain");
7868       return -99;
7869     }
7870   else if (ip_set == 0)
7871     {
7872       errmsg ("missing IP address");
7873       return -99;
7874     }
7875   else if (mac_set == 0)
7876     {
7877       errmsg ("missing MAC address");
7878       return -99;
7879     }
7880
7881   M (BD_IP_MAC_ADD_DEL, mp);
7882
7883   mp->bd_id = ntohl (bd_id);
7884   mp->is_add = is_add;
7885
7886   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7887   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7888
7889   S (mp);
7890   W (ret);
7891   return ret;
7892 }
7893
7894 static void vl_api_bd_ip_mac_details_t_handler
7895   (vl_api_bd_ip_mac_details_t * mp)
7896 {
7897   vat_main_t *vam = &vat_main;
7898   u8 *ip = 0;
7899
7900   if (!mp->is_ipv6)
7901     ip =
7902       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7903   else
7904     ip =
7905       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7906
7907   print (vam->ofp,
7908          "\n%-5d %-7s %-20U %-30s",
7909          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7910          format_ethernet_address, mp->mac_address, ip);
7911
7912   vec_free (ip);
7913 }
7914
7915 static void vl_api_bd_ip_mac_details_t_handler_json
7916   (vl_api_bd_ip_mac_details_t * mp)
7917 {
7918   vat_main_t *vam = &vat_main;
7919   vat_json_node_t *node = NULL;
7920
7921   if (VAT_JSON_ARRAY != vam->json_tree.type)
7922     {
7923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7924       vat_json_init_array (&vam->json_tree);
7925     }
7926   node = vat_json_array_add (&vam->json_tree);
7927
7928   vat_json_init_object (node);
7929   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7930   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7931   vat_json_object_add_string_copy (node, "mac_address",
7932                                    format (0, "%U", format_ethernet_address,
7933                                            &mp->mac_address));
7934   u8 *ip = 0;
7935
7936   if (!mp->is_ipv6)
7937     ip =
7938       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7939   else
7940     ip =
7941       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7942   vat_json_object_add_string_copy (node, "ip_address", ip);
7943   vec_free (ip);
7944 }
7945
7946 static int
7947 api_bd_ip_mac_dump (vat_main_t * vam)
7948 {
7949   unformat_input_t *i = vam->input;
7950   vl_api_bd_ip_mac_dump_t *mp;
7951   vl_api_control_ping_t *mp_ping;
7952   int ret;
7953   u32 bd_id;
7954   u8 bd_id_set = 0;
7955
7956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7957     {
7958       if (unformat (i, "bd_id %d", &bd_id))
7959         {
7960           bd_id_set++;
7961         }
7962       else
7963         break;
7964     }
7965
7966   print (vam->ofp,
7967          "\n%-5s %-7s %-20s %-30s",
7968          "bd_id", "is_ipv6", "mac_address", "ip_address");
7969
7970   /* Dump Bridge Domain Ip to Mac entries */
7971   M (BD_IP_MAC_DUMP, mp);
7972
7973   if (bd_id_set)
7974     mp->bd_id = htonl (bd_id);
7975   else
7976     mp->bd_id = ~0;
7977
7978   S (mp);
7979
7980   /* Use a control ping for synchronization */
7981   MPING (CONTROL_PING, mp_ping);
7982   S (mp_ping);
7983
7984   W (ret);
7985   return ret;
7986 }
7987
7988 static int
7989 api_tap_connect (vat_main_t * vam)
7990 {
7991   unformat_input_t *i = vam->input;
7992   vl_api_tap_connect_t *mp;
7993   u8 mac_address[6];
7994   u8 random_mac = 1;
7995   u8 name_set = 0;
7996   u8 *tap_name;
7997   u8 *tag = 0;
7998   ip4_address_t ip4_address;
7999   u32 ip4_mask_width;
8000   int ip4_address_set = 0;
8001   ip6_address_t ip6_address;
8002   u32 ip6_mask_width;
8003   int ip6_address_set = 0;
8004   int ret;
8005
8006   clib_memset (mac_address, 0, sizeof (mac_address));
8007
8008   /* Parse args required to build the message */
8009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8010     {
8011       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8012         {
8013           random_mac = 0;
8014         }
8015       else if (unformat (i, "random-mac"))
8016         random_mac = 1;
8017       else if (unformat (i, "tapname %s", &tap_name))
8018         name_set = 1;
8019       else if (unformat (i, "tag %s", &tag))
8020         ;
8021       else if (unformat (i, "address %U/%d",
8022                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
8023         ip4_address_set = 1;
8024       else if (unformat (i, "address %U/%d",
8025                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
8026         ip6_address_set = 1;
8027       else
8028         break;
8029     }
8030
8031   if (name_set == 0)
8032     {
8033       errmsg ("missing tap name");
8034       return -99;
8035     }
8036   if (vec_len (tap_name) > 63)
8037     {
8038       errmsg ("tap name too long");
8039       return -99;
8040     }
8041   vec_add1 (tap_name, 0);
8042
8043   if (vec_len (tag) > 63)
8044     {
8045       errmsg ("tag too long");
8046       return -99;
8047     }
8048
8049   /* Construct the API message */
8050   M (TAP_CONNECT, mp);
8051
8052   mp->use_random_mac = random_mac;
8053   clib_memcpy (mp->mac_address, mac_address, 6);
8054   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8055   if (tag)
8056     clib_memcpy (mp->tag, tag, vec_len (tag));
8057
8058   if (ip4_address_set)
8059     {
8060       mp->ip4_address_set = 1;
8061       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
8062       mp->ip4_mask_width = ip4_mask_width;
8063     }
8064   if (ip6_address_set)
8065     {
8066       mp->ip6_address_set = 1;
8067       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
8068       mp->ip6_mask_width = ip6_mask_width;
8069     }
8070
8071   vec_free (tap_name);
8072   vec_free (tag);
8073
8074   /* send it... */
8075   S (mp);
8076
8077   /* Wait for a reply... */
8078   W (ret);
8079   return ret;
8080 }
8081
8082 static int
8083 api_tap_modify (vat_main_t * vam)
8084 {
8085   unformat_input_t *i = vam->input;
8086   vl_api_tap_modify_t *mp;
8087   u8 mac_address[6];
8088   u8 random_mac = 1;
8089   u8 name_set = 0;
8090   u8 *tap_name;
8091   u32 sw_if_index = ~0;
8092   u8 sw_if_index_set = 0;
8093   int ret;
8094
8095   clib_memset (mac_address, 0, sizeof (mac_address));
8096
8097   /* Parse args required to build the message */
8098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8099     {
8100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8101         sw_if_index_set = 1;
8102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8103         sw_if_index_set = 1;
8104       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8105         {
8106           random_mac = 0;
8107         }
8108       else if (unformat (i, "random-mac"))
8109         random_mac = 1;
8110       else if (unformat (i, "tapname %s", &tap_name))
8111         name_set = 1;
8112       else
8113         break;
8114     }
8115
8116   if (sw_if_index_set == 0)
8117     {
8118       errmsg ("missing vpp interface name");
8119       return -99;
8120     }
8121   if (name_set == 0)
8122     {
8123       errmsg ("missing tap name");
8124       return -99;
8125     }
8126   if (vec_len (tap_name) > 63)
8127     {
8128       errmsg ("tap name too long");
8129     }
8130   vec_add1 (tap_name, 0);
8131
8132   /* Construct the API message */
8133   M (TAP_MODIFY, mp);
8134
8135   mp->use_random_mac = random_mac;
8136   mp->sw_if_index = ntohl (sw_if_index);
8137   clib_memcpy (mp->mac_address, mac_address, 6);
8138   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8139   vec_free (tap_name);
8140
8141   /* send it... */
8142   S (mp);
8143
8144   /* Wait for a reply... */
8145   W (ret);
8146   return ret;
8147 }
8148
8149 static int
8150 api_tap_delete (vat_main_t * vam)
8151 {
8152   unformat_input_t *i = vam->input;
8153   vl_api_tap_delete_t *mp;
8154   u32 sw_if_index = ~0;
8155   u8 sw_if_index_set = 0;
8156   int ret;
8157
8158   /* Parse args required to build the message */
8159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8160     {
8161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8162         sw_if_index_set = 1;
8163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8164         sw_if_index_set = 1;
8165       else
8166         break;
8167     }
8168
8169   if (sw_if_index_set == 0)
8170     {
8171       errmsg ("missing vpp interface name");
8172       return -99;
8173     }
8174
8175   /* Construct the API message */
8176   M (TAP_DELETE, mp);
8177
8178   mp->sw_if_index = ntohl (sw_if_index);
8179
8180   /* send it... */
8181   S (mp);
8182
8183   /* Wait for a reply... */
8184   W (ret);
8185   return ret;
8186 }
8187
8188 static int
8189 api_tap_create_v2 (vat_main_t * vam)
8190 {
8191   unformat_input_t *i = vam->input;
8192   vl_api_tap_create_v2_t *mp;
8193   u8 mac_address[6];
8194   u8 random_mac = 1;
8195   u32 id = ~0;
8196   u8 *host_if_name = 0;
8197   u8 *host_ns = 0;
8198   u8 host_mac_addr[6];
8199   u8 host_mac_addr_set = 0;
8200   u8 *host_bridge = 0;
8201   ip4_address_t host_ip4_addr;
8202   ip4_address_t host_ip4_gw;
8203   u8 host_ip4_gw_set = 0;
8204   u32 host_ip4_prefix_len = 0;
8205   ip6_address_t host_ip6_addr;
8206   ip6_address_t host_ip6_gw;
8207   u8 host_ip6_gw_set = 0;
8208   u32 host_ip6_prefix_len = 0;
8209   int ret;
8210   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8211
8212   clib_memset (mac_address, 0, sizeof (mac_address));
8213
8214   /* Parse args required to build the message */
8215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8216     {
8217       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8218         {
8219           random_mac = 0;
8220         }
8221       else if (unformat (i, "id %u", &id))
8222         ;
8223       else if (unformat (i, "host-if-name %s", &host_if_name))
8224         ;
8225       else if (unformat (i, "host-ns %s", &host_ns))
8226         ;
8227       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8228                          host_mac_addr))
8229         host_mac_addr_set = 1;
8230       else if (unformat (i, "host-bridge %s", &host_bridge))
8231         ;
8232       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8233                          &host_ip4_addr, &host_ip4_prefix_len))
8234         ;
8235       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8236                          &host_ip6_addr, &host_ip6_prefix_len))
8237         ;
8238       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8239                          &host_ip4_gw))
8240         host_ip4_gw_set = 1;
8241       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8242                          &host_ip6_gw))
8243         host_ip6_gw_set = 1;
8244       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8245         ;
8246       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8247         ;
8248       else
8249         break;
8250     }
8251
8252   if (vec_len (host_if_name) > 63)
8253     {
8254       errmsg ("tap name too long. ");
8255       return -99;
8256     }
8257   if (vec_len (host_ns) > 63)
8258     {
8259       errmsg ("host name space too long. ");
8260       return -99;
8261     }
8262   if (vec_len (host_bridge) > 63)
8263     {
8264       errmsg ("host bridge name too long. ");
8265       return -99;
8266     }
8267   if (host_ip4_prefix_len > 32)
8268     {
8269       errmsg ("host ip4 prefix length not valid. ");
8270       return -99;
8271     }
8272   if (host_ip6_prefix_len > 128)
8273     {
8274       errmsg ("host ip6 prefix length not valid. ");
8275       return -99;
8276     }
8277   if (!is_pow2 (rx_ring_sz))
8278     {
8279       errmsg ("rx ring size must be power of 2. ");
8280       return -99;
8281     }
8282   if (rx_ring_sz > 32768)
8283     {
8284       errmsg ("rx ring size must be 32768 or lower. ");
8285       return -99;
8286     }
8287   if (!is_pow2 (tx_ring_sz))
8288     {
8289       errmsg ("tx ring size must be power of 2. ");
8290       return -99;
8291     }
8292   if (tx_ring_sz > 32768)
8293     {
8294       errmsg ("tx ring size must be 32768 or lower. ");
8295       return -99;
8296     }
8297
8298   /* Construct the API message */
8299   M (TAP_CREATE_V2, mp);
8300
8301   mp->use_random_mac = random_mac;
8302
8303   mp->id = ntohl (id);
8304   mp->host_namespace_set = host_ns != 0;
8305   mp->host_bridge_set = host_bridge != 0;
8306   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8307   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8308   mp->rx_ring_sz = ntohs (rx_ring_sz);
8309   mp->tx_ring_sz = ntohs (tx_ring_sz);
8310
8311   if (random_mac == 0)
8312     clib_memcpy (mp->mac_address, mac_address, 6);
8313   if (host_mac_addr_set)
8314     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8315   if (host_if_name)
8316     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8317   if (host_ns)
8318     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8319   if (host_bridge)
8320     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8321   if (host_ip4_prefix_len)
8322     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8323   if (host_ip6_prefix_len)
8324     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8325   if (host_ip4_gw_set)
8326     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8327   if (host_ip6_gw_set)
8328     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8329
8330   vec_free (host_ns);
8331   vec_free (host_if_name);
8332   vec_free (host_bridge);
8333
8334   /* send it... */
8335   S (mp);
8336
8337   /* Wait for a reply... */
8338   W (ret);
8339   return ret;
8340 }
8341
8342 static int
8343 api_tap_delete_v2 (vat_main_t * vam)
8344 {
8345   unformat_input_t *i = vam->input;
8346   vl_api_tap_delete_v2_t *mp;
8347   u32 sw_if_index = ~0;
8348   u8 sw_if_index_set = 0;
8349   int ret;
8350
8351   /* Parse args required to build the message */
8352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8353     {
8354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8355         sw_if_index_set = 1;
8356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8357         sw_if_index_set = 1;
8358       else
8359         break;
8360     }
8361
8362   if (sw_if_index_set == 0)
8363     {
8364       errmsg ("missing vpp interface name. ");
8365       return -99;
8366     }
8367
8368   /* Construct the API message */
8369   M (TAP_DELETE_V2, mp);
8370
8371   mp->sw_if_index = ntohl (sw_if_index);
8372
8373   /* send it... */
8374   S (mp);
8375
8376   /* Wait for a reply... */
8377   W (ret);
8378   return ret;
8379 }
8380
8381 static int
8382 api_bond_create (vat_main_t * vam)
8383 {
8384   unformat_input_t *i = vam->input;
8385   vl_api_bond_create_t *mp;
8386   u8 mac_address[6];
8387   u8 custom_mac = 0;
8388   int ret;
8389   u8 mode;
8390   u8 lb;
8391   u8 mode_is_set = 0;
8392
8393   clib_memset (mac_address, 0, sizeof (mac_address));
8394   lb = BOND_LB_L2;
8395
8396   /* Parse args required to build the message */
8397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8398     {
8399       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8400         mode_is_set = 1;
8401       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8402                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8403         ;
8404       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8405                          mac_address))
8406         custom_mac = 1;
8407       else
8408         break;
8409     }
8410
8411   if (mode_is_set == 0)
8412     {
8413       errmsg ("Missing bond mode. ");
8414       return -99;
8415     }
8416
8417   /* Construct the API message */
8418   M (BOND_CREATE, mp);
8419
8420   mp->use_custom_mac = custom_mac;
8421
8422   mp->mode = mode;
8423   mp->lb = lb;
8424
8425   if (custom_mac)
8426     clib_memcpy (mp->mac_address, mac_address, 6);
8427
8428   /* send it... */
8429   S (mp);
8430
8431   /* Wait for a reply... */
8432   W (ret);
8433   return ret;
8434 }
8435
8436 static int
8437 api_bond_delete (vat_main_t * vam)
8438 {
8439   unformat_input_t *i = vam->input;
8440   vl_api_bond_delete_t *mp;
8441   u32 sw_if_index = ~0;
8442   u8 sw_if_index_set = 0;
8443   int ret;
8444
8445   /* Parse args required to build the message */
8446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8447     {
8448       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8449         sw_if_index_set = 1;
8450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8451         sw_if_index_set = 1;
8452       else
8453         break;
8454     }
8455
8456   if (sw_if_index_set == 0)
8457     {
8458       errmsg ("missing vpp interface name. ");
8459       return -99;
8460     }
8461
8462   /* Construct the API message */
8463   M (BOND_DELETE, mp);
8464
8465   mp->sw_if_index = ntohl (sw_if_index);
8466
8467   /* send it... */
8468   S (mp);
8469
8470   /* Wait for a reply... */
8471   W (ret);
8472   return ret;
8473 }
8474
8475 static int
8476 api_bond_enslave (vat_main_t * vam)
8477 {
8478   unformat_input_t *i = vam->input;
8479   vl_api_bond_enslave_t *mp;
8480   u32 bond_sw_if_index;
8481   int ret;
8482   u8 is_passive;
8483   u8 is_long_timeout;
8484   u32 bond_sw_if_index_is_set = 0;
8485   u32 sw_if_index;
8486   u8 sw_if_index_is_set = 0;
8487
8488   /* Parse args required to build the message */
8489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8490     {
8491       if (unformat (i, "sw_if_index %d", &sw_if_index))
8492         sw_if_index_is_set = 1;
8493       else if (unformat (i, "bond %u", &bond_sw_if_index))
8494         bond_sw_if_index_is_set = 1;
8495       else if (unformat (i, "passive %d", &is_passive))
8496         ;
8497       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8498         ;
8499       else
8500         break;
8501     }
8502
8503   if (bond_sw_if_index_is_set == 0)
8504     {
8505       errmsg ("Missing bond sw_if_index. ");
8506       return -99;
8507     }
8508   if (sw_if_index_is_set == 0)
8509     {
8510       errmsg ("Missing slave sw_if_index. ");
8511       return -99;
8512     }
8513
8514   /* Construct the API message */
8515   M (BOND_ENSLAVE, mp);
8516
8517   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8518   mp->sw_if_index = ntohl (sw_if_index);
8519   mp->is_long_timeout = is_long_timeout;
8520   mp->is_passive = is_passive;
8521
8522   /* send it... */
8523   S (mp);
8524
8525   /* Wait for a reply... */
8526   W (ret);
8527   return ret;
8528 }
8529
8530 static int
8531 api_bond_detach_slave (vat_main_t * vam)
8532 {
8533   unformat_input_t *i = vam->input;
8534   vl_api_bond_detach_slave_t *mp;
8535   u32 sw_if_index = ~0;
8536   u8 sw_if_index_set = 0;
8537   int ret;
8538
8539   /* Parse args required to build the message */
8540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8541     {
8542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8543         sw_if_index_set = 1;
8544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8545         sw_if_index_set = 1;
8546       else
8547         break;
8548     }
8549
8550   if (sw_if_index_set == 0)
8551     {
8552       errmsg ("missing vpp interface name. ");
8553       return -99;
8554     }
8555
8556   /* Construct the API message */
8557   M (BOND_DETACH_SLAVE, mp);
8558
8559   mp->sw_if_index = ntohl (sw_if_index);
8560
8561   /* send it... */
8562   S (mp);
8563
8564   /* Wait for a reply... */
8565   W (ret);
8566   return ret;
8567 }
8568
8569 static int
8570 api_ip_table_add_del (vat_main_t * vam)
8571 {
8572   unformat_input_t *i = vam->input;
8573   vl_api_ip_table_add_del_t *mp;
8574   u32 table_id = ~0;
8575   u8 is_ipv6 = 0;
8576   u8 is_add = 1;
8577   int ret = 0;
8578
8579   /* Parse args required to build the message */
8580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8581     {
8582       if (unformat (i, "ipv6"))
8583         is_ipv6 = 1;
8584       else if (unformat (i, "del"))
8585         is_add = 0;
8586       else if (unformat (i, "add"))
8587         is_add = 1;
8588       else if (unformat (i, "table %d", &table_id))
8589         ;
8590       else
8591         {
8592           clib_warning ("parse error '%U'", format_unformat_error, i);
8593           return -99;
8594         }
8595     }
8596
8597   if (~0 == table_id)
8598     {
8599       errmsg ("missing table-ID");
8600       return -99;
8601     }
8602
8603   /* Construct the API message */
8604   M (IP_TABLE_ADD_DEL, mp);
8605
8606   mp->table_id = ntohl (table_id);
8607   mp->is_ipv6 = is_ipv6;
8608   mp->is_add = is_add;
8609
8610   /* send it... */
8611   S (mp);
8612
8613   /* Wait for a reply... */
8614   W (ret);
8615
8616   return ret;
8617 }
8618
8619 static int
8620 api_ip_add_del_route (vat_main_t * vam)
8621 {
8622   unformat_input_t *i = vam->input;
8623   vl_api_ip_add_del_route_t *mp;
8624   u32 sw_if_index = ~0, vrf_id = 0;
8625   u8 is_ipv6 = 0;
8626   u8 is_local = 0, is_drop = 0;
8627   u8 is_unreach = 0, is_prohibit = 0;
8628   u8 is_add = 1;
8629   u32 next_hop_weight = 1;
8630   u8 is_multipath = 0;
8631   u8 address_set = 0;
8632   u8 address_length_set = 0;
8633   u32 next_hop_table_id = 0;
8634   u32 resolve_attempts = 0;
8635   u32 dst_address_length = 0;
8636   u8 next_hop_set = 0;
8637   ip4_address_t v4_dst_address, v4_next_hop_address;
8638   ip6_address_t v6_dst_address, v6_next_hop_address;
8639   int count = 1;
8640   int j;
8641   f64 before = 0;
8642   u32 random_add_del = 0;
8643   u32 *random_vector = 0;
8644   uword *random_hash;
8645   u32 random_seed = 0xdeaddabe;
8646   u32 classify_table_index = ~0;
8647   u8 is_classify = 0;
8648   u8 resolve_host = 0, resolve_attached = 0;
8649   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8650   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8651   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8652
8653   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8654   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8655   /* Parse args required to build the message */
8656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8657     {
8658       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8659         ;
8660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8661         ;
8662       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8663         {
8664           address_set = 1;
8665           is_ipv6 = 0;
8666         }
8667       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8668         {
8669           address_set = 1;
8670           is_ipv6 = 1;
8671         }
8672       else if (unformat (i, "/%d", &dst_address_length))
8673         {
8674           address_length_set = 1;
8675         }
8676
8677       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8678                                          &v4_next_hop_address))
8679         {
8680           next_hop_set = 1;
8681         }
8682       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8683                                          &v6_next_hop_address))
8684         {
8685           next_hop_set = 1;
8686         }
8687       else
8688         if (unformat
8689             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8690         {
8691           next_hop_set = 1;
8692         }
8693       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8694         {
8695           next_hop_set = 1;
8696         }
8697       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8698         ;
8699       else if (unformat (i, "weight %d", &next_hop_weight))
8700         ;
8701       else if (unformat (i, "drop"))
8702         {
8703           is_drop = 1;
8704         }
8705       else if (unformat (i, "null-send-unreach"))
8706         {
8707           is_unreach = 1;
8708         }
8709       else if (unformat (i, "null-send-prohibit"))
8710         {
8711           is_prohibit = 1;
8712         }
8713       else if (unformat (i, "local"))
8714         {
8715           is_local = 1;
8716         }
8717       else if (unformat (i, "classify %d", &classify_table_index))
8718         {
8719           is_classify = 1;
8720         }
8721       else if (unformat (i, "del"))
8722         is_add = 0;
8723       else if (unformat (i, "add"))
8724         is_add = 1;
8725       else if (unformat (i, "resolve-via-host"))
8726         resolve_host = 1;
8727       else if (unformat (i, "resolve-via-attached"))
8728         resolve_attached = 1;
8729       else if (unformat (i, "multipath"))
8730         is_multipath = 1;
8731       else if (unformat (i, "vrf %d", &vrf_id))
8732         ;
8733       else if (unformat (i, "count %d", &count))
8734         ;
8735       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8736         ;
8737       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8738         ;
8739       else if (unformat (i, "out-label %d", &next_hop_out_label))
8740         {
8741           vl_api_fib_mpls_label_t fib_label = {
8742             .label = ntohl (next_hop_out_label),
8743             .ttl = 64,
8744             .exp = 0,
8745           };
8746           vec_add1 (next_hop_out_label_stack, fib_label);
8747         }
8748       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8749         ;
8750       else if (unformat (i, "random"))
8751         random_add_del = 1;
8752       else if (unformat (i, "seed %d", &random_seed))
8753         ;
8754       else
8755         {
8756           clib_warning ("parse error '%U'", format_unformat_error, i);
8757           return -99;
8758         }
8759     }
8760
8761   if (!next_hop_set && !is_drop && !is_local &&
8762       !is_classify && !is_unreach && !is_prohibit &&
8763       MPLS_LABEL_INVALID == next_hop_via_label)
8764     {
8765       errmsg
8766         ("next hop / local / drop / unreach / prohibit / classify not set");
8767       return -99;
8768     }
8769
8770   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8771     {
8772       errmsg ("next hop and next-hop via label set");
8773       return -99;
8774     }
8775   if (address_set == 0)
8776     {
8777       errmsg ("missing addresses");
8778       return -99;
8779     }
8780
8781   if (address_length_set == 0)
8782     {
8783       errmsg ("missing address length");
8784       return -99;
8785     }
8786
8787   /* Generate a pile of unique, random routes */
8788   if (random_add_del)
8789     {
8790       u32 this_random_address;
8791       random_hash = hash_create (count, sizeof (uword));
8792
8793       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8794       for (j = 0; j <= count; j++)
8795         {
8796           do
8797             {
8798               this_random_address = random_u32 (&random_seed);
8799               this_random_address =
8800                 clib_host_to_net_u32 (this_random_address);
8801             }
8802           while (hash_get (random_hash, this_random_address));
8803           vec_add1 (random_vector, this_random_address);
8804           hash_set (random_hash, this_random_address, 1);
8805         }
8806       hash_free (random_hash);
8807       v4_dst_address.as_u32 = random_vector[0];
8808     }
8809
8810   if (count > 1)
8811     {
8812       /* Turn on async mode */
8813       vam->async_mode = 1;
8814       vam->async_errors = 0;
8815       before = vat_time_now (vam);
8816     }
8817
8818   for (j = 0; j < count; j++)
8819     {
8820       /* Construct the API message */
8821       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8822           vec_len (next_hop_out_label_stack));
8823
8824       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8825       mp->table_id = ntohl (vrf_id);
8826
8827       mp->is_add = is_add;
8828       mp->is_drop = is_drop;
8829       mp->is_unreach = is_unreach;
8830       mp->is_prohibit = is_prohibit;
8831       mp->is_ipv6 = is_ipv6;
8832       mp->is_local = is_local;
8833       mp->is_classify = is_classify;
8834       mp->is_multipath = is_multipath;
8835       mp->is_resolve_host = resolve_host;
8836       mp->is_resolve_attached = resolve_attached;
8837       mp->next_hop_weight = next_hop_weight;
8838       mp->next_hop_preference = 0;
8839       mp->dst_address_length = dst_address_length;
8840       mp->next_hop_table_id = ntohl (next_hop_table_id);
8841       mp->classify_table_index = ntohl (classify_table_index);
8842       mp->next_hop_via_label = ntohl (next_hop_via_label);
8843       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8844       if (0 != mp->next_hop_n_out_labels)
8845         {
8846           memcpy (mp->next_hop_out_label_stack,
8847                   next_hop_out_label_stack,
8848                   (vec_len (next_hop_out_label_stack) *
8849                    sizeof (vl_api_fib_mpls_label_t)));
8850           vec_free (next_hop_out_label_stack);
8851         }
8852
8853       if (is_ipv6)
8854         {
8855           clib_memcpy (mp->dst_address, &v6_dst_address,
8856                        sizeof (v6_dst_address));
8857           if (next_hop_set)
8858             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8859                          sizeof (v6_next_hop_address));
8860           increment_v6_address (&v6_dst_address);
8861         }
8862       else
8863         {
8864           clib_memcpy (mp->dst_address, &v4_dst_address,
8865                        sizeof (v4_dst_address));
8866           if (next_hop_set)
8867             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8868                          sizeof (v4_next_hop_address));
8869           if (random_add_del)
8870             v4_dst_address.as_u32 = random_vector[j + 1];
8871           else
8872             increment_v4_address (&v4_dst_address);
8873         }
8874       /* send it... */
8875       S (mp);
8876       /* If we receive SIGTERM, stop now... */
8877       if (vam->do_exit)
8878         break;
8879     }
8880
8881   /* When testing multiple add/del ops, use a control-ping to sync */
8882   if (count > 1)
8883     {
8884       vl_api_control_ping_t *mp_ping;
8885       f64 after;
8886       f64 timeout;
8887
8888       /* Shut off async mode */
8889       vam->async_mode = 0;
8890
8891       MPING (CONTROL_PING, mp_ping);
8892       S (mp_ping);
8893
8894       timeout = vat_time_now (vam) + 1.0;
8895       while (vat_time_now (vam) < timeout)
8896         if (vam->result_ready == 1)
8897           goto out;
8898       vam->retval = -99;
8899
8900     out:
8901       if (vam->retval == -99)
8902         errmsg ("timeout");
8903
8904       if (vam->async_errors > 0)
8905         {
8906           errmsg ("%d asynchronous errors", vam->async_errors);
8907           vam->retval = -98;
8908         }
8909       vam->async_errors = 0;
8910       after = vat_time_now (vam);
8911
8912       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8913       if (j > 0)
8914         count = j;
8915
8916       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8917              count, after - before, count / (after - before));
8918     }
8919   else
8920     {
8921       int ret;
8922
8923       /* Wait for a reply... */
8924       W (ret);
8925       return ret;
8926     }
8927
8928   /* Return the good/bad news */
8929   return (vam->retval);
8930 }
8931
8932 static int
8933 api_ip_mroute_add_del (vat_main_t * vam)
8934 {
8935   unformat_input_t *i = vam->input;
8936   vl_api_ip_mroute_add_del_t *mp;
8937   u32 sw_if_index = ~0, vrf_id = 0;
8938   u8 is_ipv6 = 0;
8939   u8 is_local = 0;
8940   u8 is_add = 1;
8941   u8 address_set = 0;
8942   u32 grp_address_length = 0;
8943   ip4_address_t v4_grp_address, v4_src_address;
8944   ip6_address_t v6_grp_address, v6_src_address;
8945   mfib_itf_flags_t iflags = 0;
8946   mfib_entry_flags_t eflags = 0;
8947   int ret;
8948
8949   /* Parse args required to build the message */
8950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8951     {
8952       if (unformat (i, "sw_if_index %d", &sw_if_index))
8953         ;
8954       else if (unformat (i, "%U %U",
8955                          unformat_ip4_address, &v4_src_address,
8956                          unformat_ip4_address, &v4_grp_address))
8957         {
8958           grp_address_length = 64;
8959           address_set = 1;
8960           is_ipv6 = 0;
8961         }
8962       else if (unformat (i, "%U %U",
8963                          unformat_ip6_address, &v6_src_address,
8964                          unformat_ip6_address, &v6_grp_address))
8965         {
8966           grp_address_length = 256;
8967           address_set = 1;
8968           is_ipv6 = 1;
8969         }
8970       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8971         {
8972           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8973           grp_address_length = 32;
8974           address_set = 1;
8975           is_ipv6 = 0;
8976         }
8977       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8978         {
8979           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8980           grp_address_length = 128;
8981           address_set = 1;
8982           is_ipv6 = 1;
8983         }
8984       else if (unformat (i, "/%d", &grp_address_length))
8985         ;
8986       else if (unformat (i, "local"))
8987         {
8988           is_local = 1;
8989         }
8990       else if (unformat (i, "del"))
8991         is_add = 0;
8992       else if (unformat (i, "add"))
8993         is_add = 1;
8994       else if (unformat (i, "vrf %d", &vrf_id))
8995         ;
8996       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8997         ;
8998       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8999         ;
9000       else
9001         {
9002           clib_warning ("parse error '%U'", format_unformat_error, i);
9003           return -99;
9004         }
9005     }
9006
9007   if (address_set == 0)
9008     {
9009       errmsg ("missing addresses\n");
9010       return -99;
9011     }
9012
9013   /* Construct the API message */
9014   M (IP_MROUTE_ADD_DEL, mp);
9015
9016   mp->next_hop_sw_if_index = ntohl (sw_if_index);
9017   mp->table_id = ntohl (vrf_id);
9018
9019   mp->is_add = is_add;
9020   mp->is_ipv6 = is_ipv6;
9021   mp->is_local = is_local;
9022   mp->itf_flags = ntohl (iflags);
9023   mp->entry_flags = ntohl (eflags);
9024   mp->grp_address_length = grp_address_length;
9025   mp->grp_address_length = ntohs (mp->grp_address_length);
9026
9027   if (is_ipv6)
9028     {
9029       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
9030       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
9031     }
9032   else
9033     {
9034       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
9035       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
9036
9037     }
9038
9039   /* send it... */
9040   S (mp);
9041   /* Wait for a reply... */
9042   W (ret);
9043   return ret;
9044 }
9045
9046 static int
9047 api_mpls_table_add_del (vat_main_t * vam)
9048 {
9049   unformat_input_t *i = vam->input;
9050   vl_api_mpls_table_add_del_t *mp;
9051   u32 table_id = ~0;
9052   u8 is_add = 1;
9053   int ret = 0;
9054
9055   /* Parse args required to build the message */
9056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9057     {
9058       if (unformat (i, "table %d", &table_id))
9059         ;
9060       else if (unformat (i, "del"))
9061         is_add = 0;
9062       else if (unformat (i, "add"))
9063         is_add = 1;
9064       else
9065         {
9066           clib_warning ("parse error '%U'", format_unformat_error, i);
9067           return -99;
9068         }
9069     }
9070
9071   if (~0 == table_id)
9072     {
9073       errmsg ("missing table-ID");
9074       return -99;
9075     }
9076
9077   /* Construct the API message */
9078   M (MPLS_TABLE_ADD_DEL, mp);
9079
9080   mp->mt_table_id = ntohl (table_id);
9081   mp->mt_is_add = is_add;
9082
9083   /* send it... */
9084   S (mp);
9085
9086   /* Wait for a reply... */
9087   W (ret);
9088
9089   return ret;
9090 }
9091
9092 static int
9093 api_mpls_route_add_del (vat_main_t * vam)
9094 {
9095   unformat_input_t *i = vam->input;
9096   vl_api_mpls_route_add_del_t *mp;
9097   u32 sw_if_index = ~0, table_id = 0;
9098   u8 is_add = 1;
9099   u32 next_hop_weight = 1;
9100   u8 is_multipath = 0;
9101   u32 next_hop_table_id = 0;
9102   u8 next_hop_set = 0;
9103   ip4_address_t v4_next_hop_address = {
9104     .as_u32 = 0,
9105   };
9106   ip6_address_t v6_next_hop_address = { {0} };
9107   int count = 1;
9108   int j;
9109   f64 before = 0;
9110   u32 classify_table_index = ~0;
9111   u8 is_classify = 0;
9112   u8 resolve_host = 0, resolve_attached = 0;
9113   u8 is_interface_rx = 0;
9114   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9115   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9116   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9117   mpls_label_t local_label = MPLS_LABEL_INVALID;
9118   u8 is_eos = 0;
9119   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9120
9121   /* Parse args required to build the message */
9122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9123     {
9124       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9125         ;
9126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9127         ;
9128       else if (unformat (i, "%d", &local_label))
9129         ;
9130       else if (unformat (i, "eos"))
9131         is_eos = 1;
9132       else if (unformat (i, "non-eos"))
9133         is_eos = 0;
9134       else if (unformat (i, "via %U", unformat_ip4_address,
9135                          &v4_next_hop_address))
9136         {
9137           next_hop_set = 1;
9138           next_hop_proto = DPO_PROTO_IP4;
9139         }
9140       else if (unformat (i, "via %U", unformat_ip6_address,
9141                          &v6_next_hop_address))
9142         {
9143           next_hop_set = 1;
9144           next_hop_proto = DPO_PROTO_IP6;
9145         }
9146       else if (unformat (i, "weight %d", &next_hop_weight))
9147         ;
9148       else if (unformat (i, "classify %d", &classify_table_index))
9149         {
9150           is_classify = 1;
9151         }
9152       else if (unformat (i, "del"))
9153         is_add = 0;
9154       else if (unformat (i, "add"))
9155         is_add = 1;
9156       else if (unformat (i, "resolve-via-host"))
9157         resolve_host = 1;
9158       else if (unformat (i, "resolve-via-attached"))
9159         resolve_attached = 1;
9160       else if (unformat (i, "multipath"))
9161         is_multipath = 1;
9162       else if (unformat (i, "count %d", &count))
9163         ;
9164       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9165         {
9166           next_hop_set = 1;
9167           next_hop_proto = DPO_PROTO_IP4;
9168         }
9169       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9170         {
9171           next_hop_set = 1;
9172           next_hop_proto = DPO_PROTO_IP6;
9173         }
9174       else
9175         if (unformat
9176             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9177              &sw_if_index))
9178         {
9179           next_hop_set = 1;
9180           next_hop_proto = DPO_PROTO_ETHERNET;
9181           is_interface_rx = 1;
9182         }
9183       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9184         {
9185           next_hop_set = 1;
9186           next_hop_proto = DPO_PROTO_ETHERNET;
9187           is_interface_rx = 1;
9188         }
9189       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9190         next_hop_set = 1;
9191       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9192         next_hop_set = 1;
9193       else if (unformat (i, "out-label %d", &next_hop_out_label))
9194         {
9195           vl_api_fib_mpls_label_t fib_label = {
9196             .label = ntohl (next_hop_out_label),
9197             .ttl = 64,
9198             .exp = 0,
9199           };
9200           vec_add1 (next_hop_out_label_stack, fib_label);
9201         }
9202       else
9203         {
9204           clib_warning ("parse error '%U'", format_unformat_error, i);
9205           return -99;
9206         }
9207     }
9208
9209   if (!next_hop_set && !is_classify)
9210     {
9211       errmsg ("next hop / classify not set");
9212       return -99;
9213     }
9214
9215   if (MPLS_LABEL_INVALID == local_label)
9216     {
9217       errmsg ("missing label");
9218       return -99;
9219     }
9220
9221   if (count > 1)
9222     {
9223       /* Turn on async mode */
9224       vam->async_mode = 1;
9225       vam->async_errors = 0;
9226       before = vat_time_now (vam);
9227     }
9228
9229   for (j = 0; j < count; j++)
9230     {
9231       /* Construct the API message */
9232       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9233           vec_len (next_hop_out_label_stack));
9234
9235       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9236       mp->mr_table_id = ntohl (table_id);
9237
9238       mp->mr_is_add = is_add;
9239       mp->mr_next_hop_proto = next_hop_proto;
9240       mp->mr_is_classify = is_classify;
9241       mp->mr_is_multipath = is_multipath;
9242       mp->mr_is_resolve_host = resolve_host;
9243       mp->mr_is_resolve_attached = resolve_attached;
9244       mp->mr_is_interface_rx = is_interface_rx;
9245       mp->mr_next_hop_weight = next_hop_weight;
9246       mp->mr_next_hop_preference = 0;
9247       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9248       mp->mr_classify_table_index = ntohl (classify_table_index);
9249       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9250       mp->mr_label = ntohl (local_label);
9251       mp->mr_eos = is_eos;
9252
9253       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9254       if (0 != mp->mr_next_hop_n_out_labels)
9255         {
9256           memcpy (mp->mr_next_hop_out_label_stack,
9257                   next_hop_out_label_stack,
9258                   vec_len (next_hop_out_label_stack) *
9259                   sizeof (vl_api_fib_mpls_label_t));
9260           vec_free (next_hop_out_label_stack);
9261         }
9262
9263       if (next_hop_set)
9264         {
9265           if (DPO_PROTO_IP4 == next_hop_proto)
9266             {
9267               clib_memcpy (mp->mr_next_hop,
9268                            &v4_next_hop_address,
9269                            sizeof (v4_next_hop_address));
9270             }
9271           else if (DPO_PROTO_IP6 == next_hop_proto)
9272
9273             {
9274               clib_memcpy (mp->mr_next_hop,
9275                            &v6_next_hop_address,
9276                            sizeof (v6_next_hop_address));
9277             }
9278         }
9279       local_label++;
9280
9281       /* send it... */
9282       S (mp);
9283       /* If we receive SIGTERM, stop now... */
9284       if (vam->do_exit)
9285         break;
9286     }
9287
9288   /* When testing multiple add/del ops, use a control-ping to sync */
9289   if (count > 1)
9290     {
9291       vl_api_control_ping_t *mp_ping;
9292       f64 after;
9293       f64 timeout;
9294
9295       /* Shut off async mode */
9296       vam->async_mode = 0;
9297
9298       MPING (CONTROL_PING, mp_ping);
9299       S (mp_ping);
9300
9301       timeout = vat_time_now (vam) + 1.0;
9302       while (vat_time_now (vam) < timeout)
9303         if (vam->result_ready == 1)
9304           goto out;
9305       vam->retval = -99;
9306
9307     out:
9308       if (vam->retval == -99)
9309         errmsg ("timeout");
9310
9311       if (vam->async_errors > 0)
9312         {
9313           errmsg ("%d asynchronous errors", vam->async_errors);
9314           vam->retval = -98;
9315         }
9316       vam->async_errors = 0;
9317       after = vat_time_now (vam);
9318
9319       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9320       if (j > 0)
9321         count = j;
9322
9323       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9324              count, after - before, count / (after - before));
9325     }
9326   else
9327     {
9328       int ret;
9329
9330       /* Wait for a reply... */
9331       W (ret);
9332       return ret;
9333     }
9334
9335   /* Return the good/bad news */
9336   return (vam->retval);
9337 }
9338
9339 static int
9340 api_mpls_ip_bind_unbind (vat_main_t * vam)
9341 {
9342   unformat_input_t *i = vam->input;
9343   vl_api_mpls_ip_bind_unbind_t *mp;
9344   u32 ip_table_id = 0;
9345   u8 is_bind = 1;
9346   u8 is_ip4 = 1;
9347   ip4_address_t v4_address;
9348   ip6_address_t v6_address;
9349   u32 address_length;
9350   u8 address_set = 0;
9351   mpls_label_t local_label = MPLS_LABEL_INVALID;
9352   int ret;
9353
9354   /* Parse args required to build the message */
9355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9356     {
9357       if (unformat (i, "%U/%d", unformat_ip4_address,
9358                     &v4_address, &address_length))
9359         {
9360           is_ip4 = 1;
9361           address_set = 1;
9362         }
9363       else if (unformat (i, "%U/%d", unformat_ip6_address,
9364                          &v6_address, &address_length))
9365         {
9366           is_ip4 = 0;
9367           address_set = 1;
9368         }
9369       else if (unformat (i, "%d", &local_label))
9370         ;
9371       else if (unformat (i, "table-id %d", &ip_table_id))
9372         ;
9373       else if (unformat (i, "unbind"))
9374         is_bind = 0;
9375       else if (unformat (i, "bind"))
9376         is_bind = 1;
9377       else
9378         {
9379           clib_warning ("parse error '%U'", format_unformat_error, i);
9380           return -99;
9381         }
9382     }
9383
9384   if (!address_set)
9385     {
9386       errmsg ("IP address not set");
9387       return -99;
9388     }
9389
9390   if (MPLS_LABEL_INVALID == local_label)
9391     {
9392       errmsg ("missing label");
9393       return -99;
9394     }
9395
9396   /* Construct the API message */
9397   M (MPLS_IP_BIND_UNBIND, mp);
9398
9399   mp->mb_is_bind = is_bind;
9400   mp->mb_is_ip4 = is_ip4;
9401   mp->mb_ip_table_id = ntohl (ip_table_id);
9402   mp->mb_mpls_table_id = 0;
9403   mp->mb_label = ntohl (local_label);
9404   mp->mb_address_length = address_length;
9405
9406   if (is_ip4)
9407     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9408   else
9409     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9410
9411   /* send it... */
9412   S (mp);
9413
9414   /* Wait for a reply... */
9415   W (ret);
9416   return ret;
9417 }
9418
9419 static int
9420 api_sr_mpls_policy_add (vat_main_t * vam)
9421 {
9422   unformat_input_t *i = vam->input;
9423   vl_api_sr_mpls_policy_add_t *mp;
9424   u32 bsid = 0;
9425   u32 weight = 1;
9426   u8 type = 0;
9427   u8 n_segments = 0;
9428   u32 sid;
9429   u32 *segments = NULL;
9430   int ret;
9431
9432   /* Parse args required to build the message */
9433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9434     {
9435       if (unformat (i, "bsid %d", &bsid))
9436         ;
9437       else if (unformat (i, "weight %d", &weight))
9438         ;
9439       else if (unformat (i, "spray"))
9440         type = 1;
9441       else if (unformat (i, "next %d", &sid))
9442         {
9443           n_segments += 1;
9444           vec_add1 (segments, htonl (sid));
9445         }
9446       else
9447         {
9448           clib_warning ("parse error '%U'", format_unformat_error, i);
9449           return -99;
9450         }
9451     }
9452
9453   if (bsid == 0)
9454     {
9455       errmsg ("bsid not set");
9456       return -99;
9457     }
9458
9459   if (n_segments == 0)
9460     {
9461       errmsg ("no sid in segment stack");
9462       return -99;
9463     }
9464
9465   /* Construct the API message */
9466   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9467
9468   mp->bsid = htonl (bsid);
9469   mp->weight = htonl (weight);
9470   mp->type = type;
9471   mp->n_segments = n_segments;
9472   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9473   vec_free (segments);
9474
9475   /* send it... */
9476   S (mp);
9477
9478   /* Wait for a reply... */
9479   W (ret);
9480   return ret;
9481 }
9482
9483 static int
9484 api_sr_mpls_policy_del (vat_main_t * vam)
9485 {
9486   unformat_input_t *i = vam->input;
9487   vl_api_sr_mpls_policy_del_t *mp;
9488   u32 bsid = 0;
9489   int ret;
9490
9491   /* Parse args required to build the message */
9492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9493     {
9494       if (unformat (i, "bsid %d", &bsid))
9495         ;
9496       else
9497         {
9498           clib_warning ("parse error '%U'", format_unformat_error, i);
9499           return -99;
9500         }
9501     }
9502
9503   if (bsid == 0)
9504     {
9505       errmsg ("bsid not set");
9506       return -99;
9507     }
9508
9509   /* Construct the API message */
9510   M (SR_MPLS_POLICY_DEL, mp);
9511
9512   mp->bsid = htonl (bsid);
9513
9514   /* send it... */
9515   S (mp);
9516
9517   /* Wait for a reply... */
9518   W (ret);
9519   return ret;
9520 }
9521
9522 static int
9523 api_bier_table_add_del (vat_main_t * vam)
9524 {
9525   unformat_input_t *i = vam->input;
9526   vl_api_bier_table_add_del_t *mp;
9527   u8 is_add = 1;
9528   u32 set = 0, sub_domain = 0, hdr_len = 3;
9529   mpls_label_t local_label = MPLS_LABEL_INVALID;
9530   int ret;
9531
9532   /* Parse args required to build the message */
9533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9534     {
9535       if (unformat (i, "sub-domain %d", &sub_domain))
9536         ;
9537       else if (unformat (i, "set %d", &set))
9538         ;
9539       else if (unformat (i, "label %d", &local_label))
9540         ;
9541       else if (unformat (i, "hdr-len %d", &hdr_len))
9542         ;
9543       else if (unformat (i, "add"))
9544         is_add = 1;
9545       else if (unformat (i, "del"))
9546         is_add = 0;
9547       else
9548         {
9549           clib_warning ("parse error '%U'", format_unformat_error, i);
9550           return -99;
9551         }
9552     }
9553
9554   if (MPLS_LABEL_INVALID == local_label)
9555     {
9556       errmsg ("missing label\n");
9557       return -99;
9558     }
9559
9560   /* Construct the API message */
9561   M (BIER_TABLE_ADD_DEL, mp);
9562
9563   mp->bt_is_add = is_add;
9564   mp->bt_label = ntohl (local_label);
9565   mp->bt_tbl_id.bt_set = set;
9566   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9567   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9568
9569   /* send it... */
9570   S (mp);
9571
9572   /* Wait for a reply... */
9573   W (ret);
9574
9575   return (ret);
9576 }
9577
9578 static int
9579 api_bier_route_add_del (vat_main_t * vam)
9580 {
9581   unformat_input_t *i = vam->input;
9582   vl_api_bier_route_add_del_t *mp;
9583   u8 is_add = 1;
9584   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9585   ip4_address_t v4_next_hop_address;
9586   ip6_address_t v6_next_hop_address;
9587   u8 next_hop_set = 0;
9588   u8 next_hop_proto_is_ip4 = 1;
9589   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9590   int ret;
9591
9592   /* Parse args required to build the message */
9593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9594     {
9595       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9596         {
9597           next_hop_proto_is_ip4 = 1;
9598           next_hop_set = 1;
9599         }
9600       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9601         {
9602           next_hop_proto_is_ip4 = 0;
9603           next_hop_set = 1;
9604         }
9605       if (unformat (i, "sub-domain %d", &sub_domain))
9606         ;
9607       else if (unformat (i, "set %d", &set))
9608         ;
9609       else if (unformat (i, "hdr-len %d", &hdr_len))
9610         ;
9611       else if (unformat (i, "bp %d", &bp))
9612         ;
9613       else if (unformat (i, "add"))
9614         is_add = 1;
9615       else if (unformat (i, "del"))
9616         is_add = 0;
9617       else if (unformat (i, "out-label %d", &next_hop_out_label))
9618         ;
9619       else
9620         {
9621           clib_warning ("parse error '%U'", format_unformat_error, i);
9622           return -99;
9623         }
9624     }
9625
9626   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9627     {
9628       errmsg ("next hop / label set\n");
9629       return -99;
9630     }
9631   if (0 == bp)
9632     {
9633       errmsg ("bit=position not set\n");
9634       return -99;
9635     }
9636
9637   /* Construct the API message */
9638   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9639
9640   mp->br_is_add = is_add;
9641   mp->br_tbl_id.bt_set = set;
9642   mp->br_tbl_id.bt_sub_domain = sub_domain;
9643   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9644   mp->br_bp = ntohs (bp);
9645   mp->br_n_paths = 1;
9646   mp->br_paths[0].n_labels = 1;
9647   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9648   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9649
9650   if (next_hop_proto_is_ip4)
9651     {
9652       clib_memcpy (mp->br_paths[0].next_hop,
9653                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9654     }
9655   else
9656     {
9657       clib_memcpy (mp->br_paths[0].next_hop,
9658                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9659     }
9660
9661   /* send it... */
9662   S (mp);
9663
9664   /* Wait for a reply... */
9665   W (ret);
9666
9667   return (ret);
9668 }
9669
9670 static int
9671 api_proxy_arp_add_del (vat_main_t * vam)
9672 {
9673   unformat_input_t *i = vam->input;
9674   vl_api_proxy_arp_add_del_t *mp;
9675   u32 vrf_id = 0;
9676   u8 is_add = 1;
9677   ip4_address_t lo, hi;
9678   u8 range_set = 0;
9679   int ret;
9680
9681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9682     {
9683       if (unformat (i, "vrf %d", &vrf_id))
9684         ;
9685       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9686                          unformat_ip4_address, &hi))
9687         range_set = 1;
9688       else if (unformat (i, "del"))
9689         is_add = 0;
9690       else
9691         {
9692           clib_warning ("parse error '%U'", format_unformat_error, i);
9693           return -99;
9694         }
9695     }
9696
9697   if (range_set == 0)
9698     {
9699       errmsg ("address range not set");
9700       return -99;
9701     }
9702
9703   M (PROXY_ARP_ADD_DEL, mp);
9704
9705   mp->proxy.vrf_id = ntohl (vrf_id);
9706   mp->is_add = is_add;
9707   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9708   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9709
9710   S (mp);
9711   W (ret);
9712   return ret;
9713 }
9714
9715 static int
9716 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9717 {
9718   unformat_input_t *i = vam->input;
9719   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9720   u32 sw_if_index;
9721   u8 enable = 1;
9722   u8 sw_if_index_set = 0;
9723   int ret;
9724
9725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9726     {
9727       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9728         sw_if_index_set = 1;
9729       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9730         sw_if_index_set = 1;
9731       else if (unformat (i, "enable"))
9732         enable = 1;
9733       else if (unformat (i, "disable"))
9734         enable = 0;
9735       else
9736         {
9737           clib_warning ("parse error '%U'", format_unformat_error, i);
9738           return -99;
9739         }
9740     }
9741
9742   if (sw_if_index_set == 0)
9743     {
9744       errmsg ("missing interface name or sw_if_index");
9745       return -99;
9746     }
9747
9748   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9749
9750   mp->sw_if_index = ntohl (sw_if_index);
9751   mp->enable_disable = enable;
9752
9753   S (mp);
9754   W (ret);
9755   return ret;
9756 }
9757
9758 static int
9759 api_mpls_tunnel_add_del (vat_main_t * vam)
9760 {
9761   unformat_input_t *i = vam->input;
9762   vl_api_mpls_tunnel_add_del_t *mp;
9763
9764   u8 is_add = 1;
9765   u8 l2_only = 0;
9766   u32 sw_if_index = ~0;
9767   u32 next_hop_sw_if_index = ~0;
9768   u32 next_hop_proto_is_ip4 = 1;
9769
9770   u32 next_hop_table_id = 0;
9771   ip4_address_t v4_next_hop_address = {
9772     .as_u32 = 0,
9773   };
9774   ip6_address_t v6_next_hop_address = { {0} };
9775   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9776   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9777   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9778   int ret;
9779
9780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9781     {
9782       if (unformat (i, "add"))
9783         is_add = 1;
9784       else
9785         if (unformat
9786             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9787         is_add = 0;
9788       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9789         is_add = 0;
9790       else if (unformat (i, "via %U",
9791                          unformat_ip4_address, &v4_next_hop_address))
9792         {
9793           next_hop_proto_is_ip4 = 1;
9794         }
9795       else if (unformat (i, "via %U",
9796                          unformat_ip6_address, &v6_next_hop_address))
9797         {
9798           next_hop_proto_is_ip4 = 0;
9799         }
9800       else if (unformat (i, "via-label %d", &next_hop_via_label))
9801         ;
9802       else
9803         if (unformat
9804             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9805         ;
9806       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9807         ;
9808       else if (unformat (i, "l2-only"))
9809         l2_only = 1;
9810       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9811         ;
9812       else if (unformat (i, "out-label %d", &next_hop_out_label))
9813         {
9814           vl_api_fib_mpls_label_t fib_label = {
9815             .label = ntohl (next_hop_out_label),
9816             .ttl = 64,
9817             .exp = 0,
9818           };
9819           vec_add1 (next_hop_out_label_stack, fib_label);
9820         }
9821       else
9822         {
9823           clib_warning ("parse error '%U'", format_unformat_error, i);
9824           return -99;
9825         }
9826     }
9827
9828   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9829       vec_len (next_hop_out_label_stack));
9830
9831   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9832   mp->mt_sw_if_index = ntohl (sw_if_index);
9833   mp->mt_is_add = is_add;
9834   mp->mt_l2_only = l2_only;
9835   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9836   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9837   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9838   mp->mt_next_hop_weight = 1;
9839   mp->mt_next_hop_preference = 0;
9840
9841   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9842
9843   if (0 != mp->mt_next_hop_n_out_labels)
9844     {
9845       clib_memcpy (mp->mt_next_hop_out_label_stack,
9846                    next_hop_out_label_stack,
9847                    (vec_len (next_hop_out_label_stack) *
9848                     sizeof (vl_api_fib_mpls_label_t)));
9849       vec_free (next_hop_out_label_stack);
9850     }
9851
9852   if (next_hop_proto_is_ip4)
9853     {
9854       clib_memcpy (mp->mt_next_hop,
9855                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9856     }
9857   else
9858     {
9859       clib_memcpy (mp->mt_next_hop,
9860                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9861     }
9862
9863   S (mp);
9864   W (ret);
9865   return ret;
9866 }
9867
9868 static int
9869 api_sw_interface_set_unnumbered (vat_main_t * vam)
9870 {
9871   unformat_input_t *i = vam->input;
9872   vl_api_sw_interface_set_unnumbered_t *mp;
9873   u32 sw_if_index;
9874   u32 unnum_sw_index = ~0;
9875   u8 is_add = 1;
9876   u8 sw_if_index_set = 0;
9877   int ret;
9878
9879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9880     {
9881       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9882         sw_if_index_set = 1;
9883       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9884         sw_if_index_set = 1;
9885       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9886         ;
9887       else if (unformat (i, "del"))
9888         is_add = 0;
9889       else
9890         {
9891           clib_warning ("parse error '%U'", format_unformat_error, i);
9892           return -99;
9893         }
9894     }
9895
9896   if (sw_if_index_set == 0)
9897     {
9898       errmsg ("missing interface name or sw_if_index");
9899       return -99;
9900     }
9901
9902   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9903
9904   mp->sw_if_index = ntohl (sw_if_index);
9905   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9906   mp->is_add = is_add;
9907
9908   S (mp);
9909   W (ret);
9910   return ret;
9911 }
9912
9913 static int
9914 api_ip_neighbor_add_del (vat_main_t * vam)
9915 {
9916   unformat_input_t *i = vam->input;
9917   vl_api_ip_neighbor_add_del_t *mp;
9918   u32 sw_if_index;
9919   u8 sw_if_index_set = 0;
9920   u8 is_add = 1;
9921   u8 is_static = 0;
9922   u8 is_no_fib_entry = 0;
9923   u8 mac_address[6];
9924   u8 mac_set = 0;
9925   u8 v4_address_set = 0;
9926   u8 v6_address_set = 0;
9927   ip4_address_t v4address;
9928   ip6_address_t v6address;
9929   int ret;
9930
9931   clib_memset (mac_address, 0, sizeof (mac_address));
9932
9933   /* Parse args required to build the message */
9934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9935     {
9936       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9937         {
9938           mac_set = 1;
9939         }
9940       else if (unformat (i, "del"))
9941         is_add = 0;
9942       else
9943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9944         sw_if_index_set = 1;
9945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9946         sw_if_index_set = 1;
9947       else if (unformat (i, "is_static"))
9948         is_static = 1;
9949       else if (unformat (i, "no-fib-entry"))
9950         is_no_fib_entry = 1;
9951       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9952         v4_address_set = 1;
9953       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9954         v6_address_set = 1;
9955       else
9956         {
9957           clib_warning ("parse error '%U'", format_unformat_error, i);
9958           return -99;
9959         }
9960     }
9961
9962   if (sw_if_index_set == 0)
9963     {
9964       errmsg ("missing interface name or sw_if_index");
9965       return -99;
9966     }
9967   if (v4_address_set && v6_address_set)
9968     {
9969       errmsg ("both v4 and v6 addresses set");
9970       return -99;
9971     }
9972   if (!v4_address_set && !v6_address_set)
9973     {
9974       errmsg ("no address set");
9975       return -99;
9976     }
9977
9978   /* Construct the API message */
9979   M (IP_NEIGHBOR_ADD_DEL, mp);
9980
9981   mp->sw_if_index = ntohl (sw_if_index);
9982   mp->is_add = is_add;
9983   mp->is_static = is_static;
9984   mp->is_no_adj_fib = is_no_fib_entry;
9985   if (mac_set)
9986     clib_memcpy (mp->mac_address, mac_address, 6);
9987   if (v6_address_set)
9988     {
9989       mp->is_ipv6 = 1;
9990       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9991     }
9992   else
9993     {
9994       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9995       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9996     }
9997
9998   /* send it... */
9999   S (mp);
10000
10001   /* Wait for a reply, return good/bad news  */
10002   W (ret);
10003   return ret;
10004 }
10005
10006 static int
10007 api_create_vlan_subif (vat_main_t * vam)
10008 {
10009   unformat_input_t *i = vam->input;
10010   vl_api_create_vlan_subif_t *mp;
10011   u32 sw_if_index;
10012   u8 sw_if_index_set = 0;
10013   u32 vlan_id;
10014   u8 vlan_id_set = 0;
10015   int ret;
10016
10017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10018     {
10019       if (unformat (i, "sw_if_index %d", &sw_if_index))
10020         sw_if_index_set = 1;
10021       else
10022         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10023         sw_if_index_set = 1;
10024       else if (unformat (i, "vlan %d", &vlan_id))
10025         vlan_id_set = 1;
10026       else
10027         {
10028           clib_warning ("parse error '%U'", format_unformat_error, i);
10029           return -99;
10030         }
10031     }
10032
10033   if (sw_if_index_set == 0)
10034     {
10035       errmsg ("missing interface name or sw_if_index");
10036       return -99;
10037     }
10038
10039   if (vlan_id_set == 0)
10040     {
10041       errmsg ("missing vlan_id");
10042       return -99;
10043     }
10044   M (CREATE_VLAN_SUBIF, mp);
10045
10046   mp->sw_if_index = ntohl (sw_if_index);
10047   mp->vlan_id = ntohl (vlan_id);
10048
10049   S (mp);
10050   W (ret);
10051   return ret;
10052 }
10053
10054 #define foreach_create_subif_bit                \
10055 _(no_tags)                                      \
10056 _(one_tag)                                      \
10057 _(two_tags)                                     \
10058 _(dot1ad)                                       \
10059 _(exact_match)                                  \
10060 _(default_sub)                                  \
10061 _(outer_vlan_id_any)                            \
10062 _(inner_vlan_id_any)
10063
10064 static int
10065 api_create_subif (vat_main_t * vam)
10066 {
10067   unformat_input_t *i = vam->input;
10068   vl_api_create_subif_t *mp;
10069   u32 sw_if_index;
10070   u8 sw_if_index_set = 0;
10071   u32 sub_id;
10072   u8 sub_id_set = 0;
10073   u32 no_tags = 0;
10074   u32 one_tag = 0;
10075   u32 two_tags = 0;
10076   u32 dot1ad = 0;
10077   u32 exact_match = 0;
10078   u32 default_sub = 0;
10079   u32 outer_vlan_id_any = 0;
10080   u32 inner_vlan_id_any = 0;
10081   u32 tmp;
10082   u16 outer_vlan_id = 0;
10083   u16 inner_vlan_id = 0;
10084   int ret;
10085
10086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10087     {
10088       if (unformat (i, "sw_if_index %d", &sw_if_index))
10089         sw_if_index_set = 1;
10090       else
10091         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10092         sw_if_index_set = 1;
10093       else if (unformat (i, "sub_id %d", &sub_id))
10094         sub_id_set = 1;
10095       else if (unformat (i, "outer_vlan_id %d", &tmp))
10096         outer_vlan_id = tmp;
10097       else if (unformat (i, "inner_vlan_id %d", &tmp))
10098         inner_vlan_id = tmp;
10099
10100 #define _(a) else if (unformat (i, #a)) a = 1 ;
10101       foreach_create_subif_bit
10102 #undef _
10103         else
10104         {
10105           clib_warning ("parse error '%U'", format_unformat_error, i);
10106           return -99;
10107         }
10108     }
10109
10110   if (sw_if_index_set == 0)
10111     {
10112       errmsg ("missing interface name or sw_if_index");
10113       return -99;
10114     }
10115
10116   if (sub_id_set == 0)
10117     {
10118       errmsg ("missing sub_id");
10119       return -99;
10120     }
10121   M (CREATE_SUBIF, mp);
10122
10123   mp->sw_if_index = ntohl (sw_if_index);
10124   mp->sub_id = ntohl (sub_id);
10125
10126 #define _(a) mp->a = a;
10127   foreach_create_subif_bit;
10128 #undef _
10129
10130   mp->outer_vlan_id = ntohs (outer_vlan_id);
10131   mp->inner_vlan_id = ntohs (inner_vlan_id);
10132
10133   S (mp);
10134   W (ret);
10135   return ret;
10136 }
10137
10138 static int
10139 api_oam_add_del (vat_main_t * vam)
10140 {
10141   unformat_input_t *i = vam->input;
10142   vl_api_oam_add_del_t *mp;
10143   u32 vrf_id = 0;
10144   u8 is_add = 1;
10145   ip4_address_t src, dst;
10146   u8 src_set = 0;
10147   u8 dst_set = 0;
10148   int ret;
10149
10150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10151     {
10152       if (unformat (i, "vrf %d", &vrf_id))
10153         ;
10154       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10155         src_set = 1;
10156       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10157         dst_set = 1;
10158       else if (unformat (i, "del"))
10159         is_add = 0;
10160       else
10161         {
10162           clib_warning ("parse error '%U'", format_unformat_error, i);
10163           return -99;
10164         }
10165     }
10166
10167   if (src_set == 0)
10168     {
10169       errmsg ("missing src addr");
10170       return -99;
10171     }
10172
10173   if (dst_set == 0)
10174     {
10175       errmsg ("missing dst addr");
10176       return -99;
10177     }
10178
10179   M (OAM_ADD_DEL, mp);
10180
10181   mp->vrf_id = ntohl (vrf_id);
10182   mp->is_add = is_add;
10183   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10184   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10185
10186   S (mp);
10187   W (ret);
10188   return ret;
10189 }
10190
10191 static int
10192 api_reset_fib (vat_main_t * vam)
10193 {
10194   unformat_input_t *i = vam->input;
10195   vl_api_reset_fib_t *mp;
10196   u32 vrf_id = 0;
10197   u8 is_ipv6 = 0;
10198   u8 vrf_id_set = 0;
10199
10200   int ret;
10201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10202     {
10203       if (unformat (i, "vrf %d", &vrf_id))
10204         vrf_id_set = 1;
10205       else if (unformat (i, "ipv6"))
10206         is_ipv6 = 1;
10207       else
10208         {
10209           clib_warning ("parse error '%U'", format_unformat_error, i);
10210           return -99;
10211         }
10212     }
10213
10214   if (vrf_id_set == 0)
10215     {
10216       errmsg ("missing vrf id");
10217       return -99;
10218     }
10219
10220   M (RESET_FIB, mp);
10221
10222   mp->vrf_id = ntohl (vrf_id);
10223   mp->is_ipv6 = is_ipv6;
10224
10225   S (mp);
10226   W (ret);
10227   return ret;
10228 }
10229
10230 static int
10231 api_dhcp_proxy_config (vat_main_t * vam)
10232 {
10233   unformat_input_t *i = vam->input;
10234   vl_api_dhcp_proxy_config_t *mp;
10235   u32 rx_vrf_id = 0;
10236   u32 server_vrf_id = 0;
10237   u8 is_add = 1;
10238   u8 v4_address_set = 0;
10239   u8 v6_address_set = 0;
10240   ip4_address_t v4address;
10241   ip6_address_t v6address;
10242   u8 v4_src_address_set = 0;
10243   u8 v6_src_address_set = 0;
10244   ip4_address_t v4srcaddress;
10245   ip6_address_t v6srcaddress;
10246   int ret;
10247
10248   /* Parse args required to build the message */
10249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10250     {
10251       if (unformat (i, "del"))
10252         is_add = 0;
10253       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10254         ;
10255       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10256         ;
10257       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10258         v4_address_set = 1;
10259       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10260         v6_address_set = 1;
10261       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10262         v4_src_address_set = 1;
10263       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10264         v6_src_address_set = 1;
10265       else
10266         break;
10267     }
10268
10269   if (v4_address_set && v6_address_set)
10270     {
10271       errmsg ("both v4 and v6 server addresses set");
10272       return -99;
10273     }
10274   if (!v4_address_set && !v6_address_set)
10275     {
10276       errmsg ("no server addresses set");
10277       return -99;
10278     }
10279
10280   if (v4_src_address_set && v6_src_address_set)
10281     {
10282       errmsg ("both v4 and v6  src addresses set");
10283       return -99;
10284     }
10285   if (!v4_src_address_set && !v6_src_address_set)
10286     {
10287       errmsg ("no src addresses set");
10288       return -99;
10289     }
10290
10291   if (!(v4_src_address_set && v4_address_set) &&
10292       !(v6_src_address_set && v6_address_set))
10293     {
10294       errmsg ("no matching server and src addresses set");
10295       return -99;
10296     }
10297
10298   /* Construct the API message */
10299   M (DHCP_PROXY_CONFIG, mp);
10300
10301   mp->is_add = is_add;
10302   mp->rx_vrf_id = ntohl (rx_vrf_id);
10303   mp->server_vrf_id = ntohl (server_vrf_id);
10304   if (v6_address_set)
10305     {
10306       mp->is_ipv6 = 1;
10307       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10308       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10309     }
10310   else
10311     {
10312       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10313       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10314     }
10315
10316   /* send it... */
10317   S (mp);
10318
10319   /* Wait for a reply, return good/bad news  */
10320   W (ret);
10321   return ret;
10322 }
10323
10324 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10325 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10326
10327 static void
10328 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10329 {
10330   vat_main_t *vam = &vat_main;
10331   u32 i, count = mp->count;
10332   vl_api_dhcp_server_t *s;
10333
10334   if (mp->is_ipv6)
10335     print (vam->ofp,
10336            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10337            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10338            ntohl (mp->rx_vrf_id),
10339            format_ip6_address, mp->dhcp_src_address,
10340            mp->vss_type, mp->vss_vpn_ascii_id,
10341            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10342   else
10343     print (vam->ofp,
10344            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10345            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10346            ntohl (mp->rx_vrf_id),
10347            format_ip4_address, mp->dhcp_src_address,
10348            mp->vss_type, mp->vss_vpn_ascii_id,
10349            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10350
10351   for (i = 0; i < count; i++)
10352     {
10353       s = &mp->servers[i];
10354
10355       if (mp->is_ipv6)
10356         print (vam->ofp,
10357                " Server Table-ID %d, Server Address %U",
10358                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10359       else
10360         print (vam->ofp,
10361                " Server Table-ID %d, Server Address %U",
10362                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10363     }
10364 }
10365
10366 static void vl_api_dhcp_proxy_details_t_handler_json
10367   (vl_api_dhcp_proxy_details_t * mp)
10368 {
10369   vat_main_t *vam = &vat_main;
10370   vat_json_node_t *node = NULL;
10371   u32 i, count = mp->count;
10372   struct in_addr ip4;
10373   struct in6_addr ip6;
10374   vl_api_dhcp_server_t *s;
10375
10376   if (VAT_JSON_ARRAY != vam->json_tree.type)
10377     {
10378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10379       vat_json_init_array (&vam->json_tree);
10380     }
10381   node = vat_json_array_add (&vam->json_tree);
10382
10383   vat_json_init_object (node);
10384   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10385   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10386                              sizeof (mp->vss_type));
10387   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10388                                    mp->vss_vpn_ascii_id);
10389   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10390   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10391
10392   if (mp->is_ipv6)
10393     {
10394       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10395       vat_json_object_add_ip6 (node, "src_address", ip6);
10396     }
10397   else
10398     {
10399       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10400       vat_json_object_add_ip4 (node, "src_address", ip4);
10401     }
10402
10403   for (i = 0; i < count; i++)
10404     {
10405       s = &mp->servers[i];
10406
10407       vat_json_object_add_uint (node, "server-table-id",
10408                                 ntohl (s->server_vrf_id));
10409
10410       if (mp->is_ipv6)
10411         {
10412           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10413           vat_json_object_add_ip4 (node, "src_address", ip4);
10414         }
10415       else
10416         {
10417           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10418           vat_json_object_add_ip6 (node, "server_address", ip6);
10419         }
10420     }
10421 }
10422
10423 static int
10424 api_dhcp_proxy_dump (vat_main_t * vam)
10425 {
10426   unformat_input_t *i = vam->input;
10427   vl_api_control_ping_t *mp_ping;
10428   vl_api_dhcp_proxy_dump_t *mp;
10429   u8 is_ipv6 = 0;
10430   int ret;
10431
10432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10433     {
10434       if (unformat (i, "ipv6"))
10435         is_ipv6 = 1;
10436       else
10437         {
10438           clib_warning ("parse error '%U'", format_unformat_error, i);
10439           return -99;
10440         }
10441     }
10442
10443   M (DHCP_PROXY_DUMP, mp);
10444
10445   mp->is_ip6 = is_ipv6;
10446   S (mp);
10447
10448   /* Use a control ping for synchronization */
10449   MPING (CONTROL_PING, mp_ping);
10450   S (mp_ping);
10451
10452   W (ret);
10453   return ret;
10454 }
10455
10456 static int
10457 api_dhcp_proxy_set_vss (vat_main_t * vam)
10458 {
10459   unformat_input_t *i = vam->input;
10460   vl_api_dhcp_proxy_set_vss_t *mp;
10461   u8 is_ipv6 = 0;
10462   u8 is_add = 1;
10463   u32 tbl_id = ~0;
10464   u8 vss_type = VSS_TYPE_DEFAULT;
10465   u8 *vpn_ascii_id = 0;
10466   u32 oui = 0;
10467   u32 fib_id = 0;
10468   int ret;
10469
10470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10471     {
10472       if (unformat (i, "tbl_id %d", &tbl_id))
10473         ;
10474       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10475         vss_type = VSS_TYPE_ASCII;
10476       else if (unformat (i, "fib_id %d", &fib_id))
10477         vss_type = VSS_TYPE_VPN_ID;
10478       else if (unformat (i, "oui %d", &oui))
10479         vss_type = VSS_TYPE_VPN_ID;
10480       else if (unformat (i, "ipv6"))
10481         is_ipv6 = 1;
10482       else if (unformat (i, "del"))
10483         is_add = 0;
10484       else
10485         break;
10486     }
10487
10488   if (tbl_id == ~0)
10489     {
10490       errmsg ("missing tbl_id ");
10491       vec_free (vpn_ascii_id);
10492       return -99;
10493     }
10494
10495   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10496     {
10497       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10498       vec_free (vpn_ascii_id);
10499       return -99;
10500     }
10501
10502   M (DHCP_PROXY_SET_VSS, mp);
10503   mp->tbl_id = ntohl (tbl_id);
10504   mp->vss_type = vss_type;
10505   if (vpn_ascii_id)
10506     {
10507       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10508       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10509     }
10510   mp->vpn_index = ntohl (fib_id);
10511   mp->oui = ntohl (oui);
10512   mp->is_ipv6 = is_ipv6;
10513   mp->is_add = is_add;
10514
10515   S (mp);
10516   W (ret);
10517
10518   vec_free (vpn_ascii_id);
10519   return ret;
10520 }
10521
10522 static int
10523 api_dhcp_client_config (vat_main_t * vam)
10524 {
10525   unformat_input_t *i = vam->input;
10526   vl_api_dhcp_client_config_t *mp;
10527   u32 sw_if_index;
10528   u8 sw_if_index_set = 0;
10529   u8 is_add = 1;
10530   u8 *hostname = 0;
10531   u8 disable_event = 0;
10532   int ret;
10533
10534   /* Parse args required to build the message */
10535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10536     {
10537       if (unformat (i, "del"))
10538         is_add = 0;
10539       else
10540         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10541         sw_if_index_set = 1;
10542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10543         sw_if_index_set = 1;
10544       else if (unformat (i, "hostname %s", &hostname))
10545         ;
10546       else if (unformat (i, "disable_event"))
10547         disable_event = 1;
10548       else
10549         break;
10550     }
10551
10552   if (sw_if_index_set == 0)
10553     {
10554       errmsg ("missing interface name or sw_if_index");
10555       return -99;
10556     }
10557
10558   if (vec_len (hostname) > 63)
10559     {
10560       errmsg ("hostname too long");
10561     }
10562   vec_add1 (hostname, 0);
10563
10564   /* Construct the API message */
10565   M (DHCP_CLIENT_CONFIG, mp);
10566
10567   mp->is_add = is_add;
10568   mp->client.sw_if_index = htonl (sw_if_index);
10569   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10570   vec_free (hostname);
10571   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10572   mp->client.pid = htonl (getpid ());
10573
10574   /* send it... */
10575   S (mp);
10576
10577   /* Wait for a reply, return good/bad news  */
10578   W (ret);
10579   return ret;
10580 }
10581
10582 static int
10583 api_set_ip_flow_hash (vat_main_t * vam)
10584 {
10585   unformat_input_t *i = vam->input;
10586   vl_api_set_ip_flow_hash_t *mp;
10587   u32 vrf_id = 0;
10588   u8 is_ipv6 = 0;
10589   u8 vrf_id_set = 0;
10590   u8 src = 0;
10591   u8 dst = 0;
10592   u8 sport = 0;
10593   u8 dport = 0;
10594   u8 proto = 0;
10595   u8 reverse = 0;
10596   int ret;
10597
10598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10599     {
10600       if (unformat (i, "vrf %d", &vrf_id))
10601         vrf_id_set = 1;
10602       else if (unformat (i, "ipv6"))
10603         is_ipv6 = 1;
10604       else if (unformat (i, "src"))
10605         src = 1;
10606       else if (unformat (i, "dst"))
10607         dst = 1;
10608       else if (unformat (i, "sport"))
10609         sport = 1;
10610       else if (unformat (i, "dport"))
10611         dport = 1;
10612       else if (unformat (i, "proto"))
10613         proto = 1;
10614       else if (unformat (i, "reverse"))
10615         reverse = 1;
10616
10617       else
10618         {
10619           clib_warning ("parse error '%U'", format_unformat_error, i);
10620           return -99;
10621         }
10622     }
10623
10624   if (vrf_id_set == 0)
10625     {
10626       errmsg ("missing vrf id");
10627       return -99;
10628     }
10629
10630   M (SET_IP_FLOW_HASH, mp);
10631   mp->src = src;
10632   mp->dst = dst;
10633   mp->sport = sport;
10634   mp->dport = dport;
10635   mp->proto = proto;
10636   mp->reverse = reverse;
10637   mp->vrf_id = ntohl (vrf_id);
10638   mp->is_ipv6 = is_ipv6;
10639
10640   S (mp);
10641   W (ret);
10642   return ret;
10643 }
10644
10645 static int
10646 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10647 {
10648   unformat_input_t *i = vam->input;
10649   vl_api_sw_interface_ip6_enable_disable_t *mp;
10650   u32 sw_if_index;
10651   u8 sw_if_index_set = 0;
10652   u8 enable = 0;
10653   int ret;
10654
10655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10656     {
10657       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10658         sw_if_index_set = 1;
10659       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10660         sw_if_index_set = 1;
10661       else if (unformat (i, "enable"))
10662         enable = 1;
10663       else if (unformat (i, "disable"))
10664         enable = 0;
10665       else
10666         {
10667           clib_warning ("parse error '%U'", format_unformat_error, i);
10668           return -99;
10669         }
10670     }
10671
10672   if (sw_if_index_set == 0)
10673     {
10674       errmsg ("missing interface name or sw_if_index");
10675       return -99;
10676     }
10677
10678   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10679
10680   mp->sw_if_index = ntohl (sw_if_index);
10681   mp->enable = enable;
10682
10683   S (mp);
10684   W (ret);
10685   return ret;
10686 }
10687
10688 static int
10689 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10690 {
10691   unformat_input_t *i = vam->input;
10692   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10693   u32 sw_if_index;
10694   u8 sw_if_index_set = 0;
10695   u8 v6_address_set = 0;
10696   ip6_address_t v6address;
10697   int ret;
10698
10699   /* Parse args required to build the message */
10700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10701     {
10702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10703         sw_if_index_set = 1;
10704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10705         sw_if_index_set = 1;
10706       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10707         v6_address_set = 1;
10708       else
10709         break;
10710     }
10711
10712   if (sw_if_index_set == 0)
10713     {
10714       errmsg ("missing interface name or sw_if_index");
10715       return -99;
10716     }
10717   if (!v6_address_set)
10718     {
10719       errmsg ("no address set");
10720       return -99;
10721     }
10722
10723   /* Construct the API message */
10724   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10725
10726   mp->sw_if_index = ntohl (sw_if_index);
10727   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10728
10729   /* send it... */
10730   S (mp);
10731
10732   /* Wait for a reply, return good/bad news  */
10733   W (ret);
10734   return ret;
10735 }
10736
10737 static int
10738 api_ip6nd_proxy_add_del (vat_main_t * vam)
10739 {
10740   unformat_input_t *i = vam->input;
10741   vl_api_ip6nd_proxy_add_del_t *mp;
10742   u32 sw_if_index = ~0;
10743   u8 v6_address_set = 0;
10744   ip6_address_t v6address;
10745   u8 is_del = 0;
10746   int ret;
10747
10748   /* Parse args required to build the message */
10749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10750     {
10751       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10752         ;
10753       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10754         ;
10755       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10756         v6_address_set = 1;
10757       if (unformat (i, "del"))
10758         is_del = 1;
10759       else
10760         {
10761           clib_warning ("parse error '%U'", format_unformat_error, i);
10762           return -99;
10763         }
10764     }
10765
10766   if (sw_if_index == ~0)
10767     {
10768       errmsg ("missing interface name or sw_if_index");
10769       return -99;
10770     }
10771   if (!v6_address_set)
10772     {
10773       errmsg ("no address set");
10774       return -99;
10775     }
10776
10777   /* Construct the API message */
10778   M (IP6ND_PROXY_ADD_DEL, mp);
10779
10780   mp->is_del = is_del;
10781   mp->sw_if_index = ntohl (sw_if_index);
10782   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10783
10784   /* send it... */
10785   S (mp);
10786
10787   /* Wait for a reply, return good/bad news  */
10788   W (ret);
10789   return ret;
10790 }
10791
10792 static int
10793 api_ip6nd_proxy_dump (vat_main_t * vam)
10794 {
10795   vl_api_ip6nd_proxy_dump_t *mp;
10796   vl_api_control_ping_t *mp_ping;
10797   int ret;
10798
10799   M (IP6ND_PROXY_DUMP, mp);
10800
10801   S (mp);
10802
10803   /* Use a control ping for synchronization */
10804   MPING (CONTROL_PING, mp_ping);
10805   S (mp_ping);
10806
10807   W (ret);
10808   return ret;
10809 }
10810
10811 static void vl_api_ip6nd_proxy_details_t_handler
10812   (vl_api_ip6nd_proxy_details_t * mp)
10813 {
10814   vat_main_t *vam = &vat_main;
10815
10816   print (vam->ofp, "host %U sw_if_index %d",
10817          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10818 }
10819
10820 static void vl_api_ip6nd_proxy_details_t_handler_json
10821   (vl_api_ip6nd_proxy_details_t * mp)
10822 {
10823   vat_main_t *vam = &vat_main;
10824   struct in6_addr ip6;
10825   vat_json_node_t *node = NULL;
10826
10827   if (VAT_JSON_ARRAY != vam->json_tree.type)
10828     {
10829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10830       vat_json_init_array (&vam->json_tree);
10831     }
10832   node = vat_json_array_add (&vam->json_tree);
10833
10834   vat_json_init_object (node);
10835   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10836
10837   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10838   vat_json_object_add_ip6 (node, "host", ip6);
10839 }
10840
10841 static int
10842 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10843 {
10844   unformat_input_t *i = vam->input;
10845   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10846   u32 sw_if_index;
10847   u8 sw_if_index_set = 0;
10848   u32 address_length = 0;
10849   u8 v6_address_set = 0;
10850   ip6_address_t v6address;
10851   u8 use_default = 0;
10852   u8 no_advertise = 0;
10853   u8 off_link = 0;
10854   u8 no_autoconfig = 0;
10855   u8 no_onlink = 0;
10856   u8 is_no = 0;
10857   u32 val_lifetime = 0;
10858   u32 pref_lifetime = 0;
10859   int ret;
10860
10861   /* Parse args required to build the message */
10862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10863     {
10864       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10865         sw_if_index_set = 1;
10866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10867         sw_if_index_set = 1;
10868       else if (unformat (i, "%U/%d",
10869                          unformat_ip6_address, &v6address, &address_length))
10870         v6_address_set = 1;
10871       else if (unformat (i, "val_life %d", &val_lifetime))
10872         ;
10873       else if (unformat (i, "pref_life %d", &pref_lifetime))
10874         ;
10875       else if (unformat (i, "def"))
10876         use_default = 1;
10877       else if (unformat (i, "noadv"))
10878         no_advertise = 1;
10879       else if (unformat (i, "offl"))
10880         off_link = 1;
10881       else if (unformat (i, "noauto"))
10882         no_autoconfig = 1;
10883       else if (unformat (i, "nolink"))
10884         no_onlink = 1;
10885       else if (unformat (i, "isno"))
10886         is_no = 1;
10887       else
10888         {
10889           clib_warning ("parse error '%U'", format_unformat_error, i);
10890           return -99;
10891         }
10892     }
10893
10894   if (sw_if_index_set == 0)
10895     {
10896       errmsg ("missing interface name or sw_if_index");
10897       return -99;
10898     }
10899   if (!v6_address_set)
10900     {
10901       errmsg ("no address set");
10902       return -99;
10903     }
10904
10905   /* Construct the API message */
10906   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10907
10908   mp->sw_if_index = ntohl (sw_if_index);
10909   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10910   mp->address_length = address_length;
10911   mp->use_default = use_default;
10912   mp->no_advertise = no_advertise;
10913   mp->off_link = off_link;
10914   mp->no_autoconfig = no_autoconfig;
10915   mp->no_onlink = no_onlink;
10916   mp->is_no = is_no;
10917   mp->val_lifetime = ntohl (val_lifetime);
10918   mp->pref_lifetime = ntohl (pref_lifetime);
10919
10920   /* send it... */
10921   S (mp);
10922
10923   /* Wait for a reply, return good/bad news  */
10924   W (ret);
10925   return ret;
10926 }
10927
10928 static int
10929 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10930 {
10931   unformat_input_t *i = vam->input;
10932   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10933   u32 sw_if_index;
10934   u8 sw_if_index_set = 0;
10935   u8 suppress = 0;
10936   u8 managed = 0;
10937   u8 other = 0;
10938   u8 ll_option = 0;
10939   u8 send_unicast = 0;
10940   u8 cease = 0;
10941   u8 is_no = 0;
10942   u8 default_router = 0;
10943   u32 max_interval = 0;
10944   u32 min_interval = 0;
10945   u32 lifetime = 0;
10946   u32 initial_count = 0;
10947   u32 initial_interval = 0;
10948   int ret;
10949
10950
10951   /* Parse args required to build the message */
10952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10953     {
10954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10955         sw_if_index_set = 1;
10956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10957         sw_if_index_set = 1;
10958       else if (unformat (i, "maxint %d", &max_interval))
10959         ;
10960       else if (unformat (i, "minint %d", &min_interval))
10961         ;
10962       else if (unformat (i, "life %d", &lifetime))
10963         ;
10964       else if (unformat (i, "count %d", &initial_count))
10965         ;
10966       else if (unformat (i, "interval %d", &initial_interval))
10967         ;
10968       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10969         suppress = 1;
10970       else if (unformat (i, "managed"))
10971         managed = 1;
10972       else if (unformat (i, "other"))
10973         other = 1;
10974       else if (unformat (i, "ll"))
10975         ll_option = 1;
10976       else if (unformat (i, "send"))
10977         send_unicast = 1;
10978       else if (unformat (i, "cease"))
10979         cease = 1;
10980       else if (unformat (i, "isno"))
10981         is_no = 1;
10982       else if (unformat (i, "def"))
10983         default_router = 1;
10984       else
10985         {
10986           clib_warning ("parse error '%U'", format_unformat_error, i);
10987           return -99;
10988         }
10989     }
10990
10991   if (sw_if_index_set == 0)
10992     {
10993       errmsg ("missing interface name or sw_if_index");
10994       return -99;
10995     }
10996
10997   /* Construct the API message */
10998   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10999
11000   mp->sw_if_index = ntohl (sw_if_index);
11001   mp->max_interval = ntohl (max_interval);
11002   mp->min_interval = ntohl (min_interval);
11003   mp->lifetime = ntohl (lifetime);
11004   mp->initial_count = ntohl (initial_count);
11005   mp->initial_interval = ntohl (initial_interval);
11006   mp->suppress = suppress;
11007   mp->managed = managed;
11008   mp->other = other;
11009   mp->ll_option = ll_option;
11010   mp->send_unicast = send_unicast;
11011   mp->cease = cease;
11012   mp->is_no = is_no;
11013   mp->default_router = default_router;
11014
11015   /* send it... */
11016   S (mp);
11017
11018   /* Wait for a reply, return good/bad news  */
11019   W (ret);
11020   return ret;
11021 }
11022
11023 static int
11024 api_set_arp_neighbor_limit (vat_main_t * vam)
11025 {
11026   unformat_input_t *i = vam->input;
11027   vl_api_set_arp_neighbor_limit_t *mp;
11028   u32 arp_nbr_limit;
11029   u8 limit_set = 0;
11030   u8 is_ipv6 = 0;
11031   int ret;
11032
11033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11034     {
11035       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
11036         limit_set = 1;
11037       else if (unformat (i, "ipv6"))
11038         is_ipv6 = 1;
11039       else
11040         {
11041           clib_warning ("parse error '%U'", format_unformat_error, i);
11042           return -99;
11043         }
11044     }
11045
11046   if (limit_set == 0)
11047     {
11048       errmsg ("missing limit value");
11049       return -99;
11050     }
11051
11052   M (SET_ARP_NEIGHBOR_LIMIT, mp);
11053
11054   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
11055   mp->is_ipv6 = is_ipv6;
11056
11057   S (mp);
11058   W (ret);
11059   return ret;
11060 }
11061
11062 static int
11063 api_l2_patch_add_del (vat_main_t * vam)
11064 {
11065   unformat_input_t *i = vam->input;
11066   vl_api_l2_patch_add_del_t *mp;
11067   u32 rx_sw_if_index;
11068   u8 rx_sw_if_index_set = 0;
11069   u32 tx_sw_if_index;
11070   u8 tx_sw_if_index_set = 0;
11071   u8 is_add = 1;
11072   int ret;
11073
11074   /* Parse args required to build the message */
11075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11076     {
11077       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
11078         rx_sw_if_index_set = 1;
11079       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
11080         tx_sw_if_index_set = 1;
11081       else if (unformat (i, "rx"))
11082         {
11083           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11084             {
11085               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11086                             &rx_sw_if_index))
11087                 rx_sw_if_index_set = 1;
11088             }
11089           else
11090             break;
11091         }
11092       else if (unformat (i, "tx"))
11093         {
11094           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11095             {
11096               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11097                             &tx_sw_if_index))
11098                 tx_sw_if_index_set = 1;
11099             }
11100           else
11101             break;
11102         }
11103       else if (unformat (i, "del"))
11104         is_add = 0;
11105       else
11106         break;
11107     }
11108
11109   if (rx_sw_if_index_set == 0)
11110     {
11111       errmsg ("missing rx interface name or rx_sw_if_index");
11112       return -99;
11113     }
11114
11115   if (tx_sw_if_index_set == 0)
11116     {
11117       errmsg ("missing tx interface name or tx_sw_if_index");
11118       return -99;
11119     }
11120
11121   M (L2_PATCH_ADD_DEL, mp);
11122
11123   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11124   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11125   mp->is_add = is_add;
11126
11127   S (mp);
11128   W (ret);
11129   return ret;
11130 }
11131
11132 u8 is_del;
11133 u8 localsid_addr[16];
11134 u8 end_psp;
11135 u8 behavior;
11136 u32 sw_if_index;
11137 u32 vlan_index;
11138 u32 fib_table;
11139 u8 nh_addr[16];
11140
11141 static int
11142 api_sr_localsid_add_del (vat_main_t * vam)
11143 {
11144   unformat_input_t *i = vam->input;
11145   vl_api_sr_localsid_add_del_t *mp;
11146
11147   u8 is_del;
11148   ip6_address_t localsid;
11149   u8 end_psp = 0;
11150   u8 behavior = ~0;
11151   u32 sw_if_index;
11152   u32 fib_table = ~(u32) 0;
11153   ip6_address_t nh_addr6;
11154   ip4_address_t nh_addr4;
11155   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
11156   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
11157
11158   bool nexthop_set = 0;
11159
11160   int ret;
11161
11162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11163     {
11164       if (unformat (i, "del"))
11165         is_del = 1;
11166       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11167       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11168         nexthop_set = 1;
11169       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11170         nexthop_set = 1;
11171       else if (unformat (i, "behavior %u", &behavior));
11172       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11173       else if (unformat (i, "fib-table %u", &fib_table));
11174       else if (unformat (i, "end.psp %u", &behavior));
11175       else
11176         break;
11177     }
11178
11179   M (SR_LOCALSID_ADD_DEL, mp);
11180
11181   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11182   if (nexthop_set)
11183     {
11184       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11185       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11186     }
11187   mp->behavior = behavior;
11188   mp->sw_if_index = ntohl (sw_if_index);
11189   mp->fib_table = ntohl (fib_table);
11190   mp->end_psp = end_psp;
11191   mp->is_del = is_del;
11192
11193   S (mp);
11194   W (ret);
11195   return ret;
11196 }
11197
11198 static int
11199 api_ioam_enable (vat_main_t * vam)
11200 {
11201   unformat_input_t *input = vam->input;
11202   vl_api_ioam_enable_t *mp;
11203   u32 id = 0;
11204   int has_trace_option = 0;
11205   int has_pot_option = 0;
11206   int has_seqno_option = 0;
11207   int has_analyse_option = 0;
11208   int ret;
11209
11210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11211     {
11212       if (unformat (input, "trace"))
11213         has_trace_option = 1;
11214       else if (unformat (input, "pot"))
11215         has_pot_option = 1;
11216       else if (unformat (input, "seqno"))
11217         has_seqno_option = 1;
11218       else if (unformat (input, "analyse"))
11219         has_analyse_option = 1;
11220       else
11221         break;
11222     }
11223   M (IOAM_ENABLE, mp);
11224   mp->id = htons (id);
11225   mp->seqno = has_seqno_option;
11226   mp->analyse = has_analyse_option;
11227   mp->pot_enable = has_pot_option;
11228   mp->trace_enable = has_trace_option;
11229
11230   S (mp);
11231   W (ret);
11232   return ret;
11233 }
11234
11235
11236 static int
11237 api_ioam_disable (vat_main_t * vam)
11238 {
11239   vl_api_ioam_disable_t *mp;
11240   int ret;
11241
11242   M (IOAM_DISABLE, mp);
11243   S (mp);
11244   W (ret);
11245   return ret;
11246 }
11247
11248 #define foreach_tcp_proto_field                 \
11249 _(src_port)                                     \
11250 _(dst_port)
11251
11252 #define foreach_udp_proto_field                 \
11253 _(src_port)                                     \
11254 _(dst_port)
11255
11256 #define foreach_ip4_proto_field                 \
11257 _(src_address)                                  \
11258 _(dst_address)                                  \
11259 _(tos)                                          \
11260 _(length)                                       \
11261 _(fragment_id)                                  \
11262 _(ttl)                                          \
11263 _(protocol)                                     \
11264 _(checksum)
11265
11266 typedef struct
11267 {
11268   u16 src_port, dst_port;
11269 } tcpudp_header_t;
11270
11271 #if VPP_API_TEST_BUILTIN == 0
11272 uword
11273 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11274 {
11275   u8 **maskp = va_arg (*args, u8 **);
11276   u8 *mask = 0;
11277   u8 found_something = 0;
11278   tcp_header_t *tcp;
11279
11280 #define _(a) u8 a=0;
11281   foreach_tcp_proto_field;
11282 #undef _
11283
11284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11285     {
11286       if (0);
11287 #define _(a) else if (unformat (input, #a)) a=1;
11288       foreach_tcp_proto_field
11289 #undef _
11290         else
11291         break;
11292     }
11293
11294 #define _(a) found_something += a;
11295   foreach_tcp_proto_field;
11296 #undef _
11297
11298   if (found_something == 0)
11299     return 0;
11300
11301   vec_validate (mask, sizeof (*tcp) - 1);
11302
11303   tcp = (tcp_header_t *) mask;
11304
11305 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
11306   foreach_tcp_proto_field;
11307 #undef _
11308
11309   *maskp = mask;
11310   return 1;
11311 }
11312
11313 uword
11314 unformat_udp_mask (unformat_input_t * input, va_list * args)
11315 {
11316   u8 **maskp = va_arg (*args, u8 **);
11317   u8 *mask = 0;
11318   u8 found_something = 0;
11319   udp_header_t *udp;
11320
11321 #define _(a) u8 a=0;
11322   foreach_udp_proto_field;
11323 #undef _
11324
11325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11326     {
11327       if (0);
11328 #define _(a) else if (unformat (input, #a)) a=1;
11329       foreach_udp_proto_field
11330 #undef _
11331         else
11332         break;
11333     }
11334
11335 #define _(a) found_something += a;
11336   foreach_udp_proto_field;
11337 #undef _
11338
11339   if (found_something == 0)
11340     return 0;
11341
11342   vec_validate (mask, sizeof (*udp) - 1);
11343
11344   udp = (udp_header_t *) mask;
11345
11346 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
11347   foreach_udp_proto_field;
11348 #undef _
11349
11350   *maskp = mask;
11351   return 1;
11352 }
11353
11354 uword
11355 unformat_l4_mask (unformat_input_t * input, va_list * args)
11356 {
11357   u8 **maskp = va_arg (*args, u8 **);
11358   u16 src_port = 0, dst_port = 0;
11359   tcpudp_header_t *tcpudp;
11360
11361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11362     {
11363       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11364         return 1;
11365       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11366         return 1;
11367       else if (unformat (input, "src_port"))
11368         src_port = 0xFFFF;
11369       else if (unformat (input, "dst_port"))
11370         dst_port = 0xFFFF;
11371       else
11372         return 0;
11373     }
11374
11375   if (!src_port && !dst_port)
11376     return 0;
11377
11378   u8 *mask = 0;
11379   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11380
11381   tcpudp = (tcpudp_header_t *) mask;
11382   tcpudp->src_port = src_port;
11383   tcpudp->dst_port = dst_port;
11384
11385   *maskp = mask;
11386
11387   return 1;
11388 }
11389
11390 uword
11391 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11392 {
11393   u8 **maskp = va_arg (*args, u8 **);
11394   u8 *mask = 0;
11395   u8 found_something = 0;
11396   ip4_header_t *ip;
11397
11398 #define _(a) u8 a=0;
11399   foreach_ip4_proto_field;
11400 #undef _
11401   u8 version = 0;
11402   u8 hdr_length = 0;
11403
11404
11405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11406     {
11407       if (unformat (input, "version"))
11408         version = 1;
11409       else if (unformat (input, "hdr_length"))
11410         hdr_length = 1;
11411       else if (unformat (input, "src"))
11412         src_address = 1;
11413       else if (unformat (input, "dst"))
11414         dst_address = 1;
11415       else if (unformat (input, "proto"))
11416         protocol = 1;
11417
11418 #define _(a) else if (unformat (input, #a)) a=1;
11419       foreach_ip4_proto_field
11420 #undef _
11421         else
11422         break;
11423     }
11424
11425 #define _(a) found_something += a;
11426   foreach_ip4_proto_field;
11427 #undef _
11428
11429   if (found_something == 0)
11430     return 0;
11431
11432   vec_validate (mask, sizeof (*ip) - 1);
11433
11434   ip = (ip4_header_t *) mask;
11435
11436 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11437   foreach_ip4_proto_field;
11438 #undef _
11439
11440   ip->ip_version_and_header_length = 0;
11441
11442   if (version)
11443     ip->ip_version_and_header_length |= 0xF0;
11444
11445   if (hdr_length)
11446     ip->ip_version_and_header_length |= 0x0F;
11447
11448   *maskp = mask;
11449   return 1;
11450 }
11451
11452 #define foreach_ip6_proto_field                 \
11453 _(src_address)                                  \
11454 _(dst_address)                                  \
11455 _(payload_length)                               \
11456 _(hop_limit)                                    \
11457 _(protocol)
11458
11459 uword
11460 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11461 {
11462   u8 **maskp = va_arg (*args, u8 **);
11463   u8 *mask = 0;
11464   u8 found_something = 0;
11465   ip6_header_t *ip;
11466   u32 ip_version_traffic_class_and_flow_label;
11467
11468 #define _(a) u8 a=0;
11469   foreach_ip6_proto_field;
11470 #undef _
11471   u8 version = 0;
11472   u8 traffic_class = 0;
11473   u8 flow_label = 0;
11474
11475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11476     {
11477       if (unformat (input, "version"))
11478         version = 1;
11479       else if (unformat (input, "traffic-class"))
11480         traffic_class = 1;
11481       else if (unformat (input, "flow-label"))
11482         flow_label = 1;
11483       else if (unformat (input, "src"))
11484         src_address = 1;
11485       else if (unformat (input, "dst"))
11486         dst_address = 1;
11487       else if (unformat (input, "proto"))
11488         protocol = 1;
11489
11490 #define _(a) else if (unformat (input, #a)) a=1;
11491       foreach_ip6_proto_field
11492 #undef _
11493         else
11494         break;
11495     }
11496
11497 #define _(a) found_something += a;
11498   foreach_ip6_proto_field;
11499 #undef _
11500
11501   if (found_something == 0)
11502     return 0;
11503
11504   vec_validate (mask, sizeof (*ip) - 1);
11505
11506   ip = (ip6_header_t *) mask;
11507
11508 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11509   foreach_ip6_proto_field;
11510 #undef _
11511
11512   ip_version_traffic_class_and_flow_label = 0;
11513
11514   if (version)
11515     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11516
11517   if (traffic_class)
11518     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11519
11520   if (flow_label)
11521     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11522
11523   ip->ip_version_traffic_class_and_flow_label =
11524     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11525
11526   *maskp = mask;
11527   return 1;
11528 }
11529
11530 uword
11531 unformat_l3_mask (unformat_input_t * input, va_list * args)
11532 {
11533   u8 **maskp = va_arg (*args, u8 **);
11534
11535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11536     {
11537       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11538         return 1;
11539       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11540         return 1;
11541       else
11542         break;
11543     }
11544   return 0;
11545 }
11546
11547 uword
11548 unformat_l2_mask (unformat_input_t * input, va_list * args)
11549 {
11550   u8 **maskp = va_arg (*args, u8 **);
11551   u8 *mask = 0;
11552   u8 src = 0;
11553   u8 dst = 0;
11554   u8 proto = 0;
11555   u8 tag1 = 0;
11556   u8 tag2 = 0;
11557   u8 ignore_tag1 = 0;
11558   u8 ignore_tag2 = 0;
11559   u8 cos1 = 0;
11560   u8 cos2 = 0;
11561   u8 dot1q = 0;
11562   u8 dot1ad = 0;
11563   int len = 14;
11564
11565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11566     {
11567       if (unformat (input, "src"))
11568         src = 1;
11569       else if (unformat (input, "dst"))
11570         dst = 1;
11571       else if (unformat (input, "proto"))
11572         proto = 1;
11573       else if (unformat (input, "tag1"))
11574         tag1 = 1;
11575       else if (unformat (input, "tag2"))
11576         tag2 = 1;
11577       else if (unformat (input, "ignore-tag1"))
11578         ignore_tag1 = 1;
11579       else if (unformat (input, "ignore-tag2"))
11580         ignore_tag2 = 1;
11581       else if (unformat (input, "cos1"))
11582         cos1 = 1;
11583       else if (unformat (input, "cos2"))
11584         cos2 = 1;
11585       else if (unformat (input, "dot1q"))
11586         dot1q = 1;
11587       else if (unformat (input, "dot1ad"))
11588         dot1ad = 1;
11589       else
11590         break;
11591     }
11592   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11593        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11594     return 0;
11595
11596   if (tag1 || ignore_tag1 || cos1 || dot1q)
11597     len = 18;
11598   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11599     len = 22;
11600
11601   vec_validate (mask, len - 1);
11602
11603   if (dst)
11604     clib_memset (mask, 0xff, 6);
11605
11606   if (src)
11607     clib_memset (mask + 6, 0xff, 6);
11608
11609   if (tag2 || dot1ad)
11610     {
11611       /* inner vlan tag */
11612       if (tag2)
11613         {
11614           mask[19] = 0xff;
11615           mask[18] = 0x0f;
11616         }
11617       if (cos2)
11618         mask[18] |= 0xe0;
11619       if (proto)
11620         mask[21] = mask[20] = 0xff;
11621       if (tag1)
11622         {
11623           mask[15] = 0xff;
11624           mask[14] = 0x0f;
11625         }
11626       if (cos1)
11627         mask[14] |= 0xe0;
11628       *maskp = mask;
11629       return 1;
11630     }
11631   if (tag1 | dot1q)
11632     {
11633       if (tag1)
11634         {
11635           mask[15] = 0xff;
11636           mask[14] = 0x0f;
11637         }
11638       if (cos1)
11639         mask[14] |= 0xe0;
11640       if (proto)
11641         mask[16] = mask[17] = 0xff;
11642
11643       *maskp = mask;
11644       return 1;
11645     }
11646   if (cos2)
11647     mask[18] |= 0xe0;
11648   if (cos1)
11649     mask[14] |= 0xe0;
11650   if (proto)
11651     mask[12] = mask[13] = 0xff;
11652
11653   *maskp = mask;
11654   return 1;
11655 }
11656
11657 uword
11658 unformat_classify_mask (unformat_input_t * input, va_list * args)
11659 {
11660   u8 **maskp = va_arg (*args, u8 **);
11661   u32 *skipp = va_arg (*args, u32 *);
11662   u32 *matchp = va_arg (*args, u32 *);
11663   u32 match;
11664   u8 *mask = 0;
11665   u8 *l2 = 0;
11666   u8 *l3 = 0;
11667   u8 *l4 = 0;
11668   int i;
11669
11670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11671     {
11672       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11673         ;
11674       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11675         ;
11676       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11677         ;
11678       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11679         ;
11680       else
11681         break;
11682     }
11683
11684   if (l4 && !l3)
11685     {
11686       vec_free (mask);
11687       vec_free (l2);
11688       vec_free (l4);
11689       return 0;
11690     }
11691
11692   if (mask || l2 || l3 || l4)
11693     {
11694       if (l2 || l3 || l4)
11695         {
11696           /* "With a free Ethernet header in every package" */
11697           if (l2 == 0)
11698             vec_validate (l2, 13);
11699           mask = l2;
11700           if (vec_len (l3))
11701             {
11702               vec_append (mask, l3);
11703               vec_free (l3);
11704             }
11705           if (vec_len (l4))
11706             {
11707               vec_append (mask, l4);
11708               vec_free (l4);
11709             }
11710         }
11711
11712       /* Scan forward looking for the first significant mask octet */
11713       for (i = 0; i < vec_len (mask); i++)
11714         if (mask[i])
11715           break;
11716
11717       /* compute (skip, match) params */
11718       *skipp = i / sizeof (u32x4);
11719       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11720
11721       /* Pad mask to an even multiple of the vector size */
11722       while (vec_len (mask) % sizeof (u32x4))
11723         vec_add1 (mask, 0);
11724
11725       match = vec_len (mask) / sizeof (u32x4);
11726
11727       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11728         {
11729           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11730           if (*tmp || *(tmp + 1))
11731             break;
11732           match--;
11733         }
11734       if (match == 0)
11735         clib_warning ("BUG: match 0");
11736
11737       _vec_len (mask) = match * sizeof (u32x4);
11738
11739       *matchp = match;
11740       *maskp = mask;
11741
11742       return 1;
11743     }
11744
11745   return 0;
11746 }
11747 #endif /* VPP_API_TEST_BUILTIN */
11748
11749 #define foreach_l2_next                         \
11750 _(drop, DROP)                                   \
11751 _(ethernet, ETHERNET_INPUT)                     \
11752 _(ip4, IP4_INPUT)                               \
11753 _(ip6, IP6_INPUT)
11754
11755 uword
11756 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11757 {
11758   u32 *miss_next_indexp = va_arg (*args, u32 *);
11759   u32 next_index = 0;
11760   u32 tmp;
11761
11762 #define _(n,N) \
11763   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11764   foreach_l2_next;
11765 #undef _
11766
11767   if (unformat (input, "%d", &tmp))
11768     {
11769       next_index = tmp;
11770       goto out;
11771     }
11772
11773   return 0;
11774
11775 out:
11776   *miss_next_indexp = next_index;
11777   return 1;
11778 }
11779
11780 #define foreach_ip_next                         \
11781 _(drop, DROP)                                   \
11782 _(local, LOCAL)                                 \
11783 _(rewrite, REWRITE)
11784
11785 uword
11786 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11787 {
11788   u32 *miss_next_indexp = va_arg (*args, u32 *);
11789   u32 next_index = 0;
11790   u32 tmp;
11791
11792 #define _(n,N) \
11793   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11794   foreach_ip_next;
11795 #undef _
11796
11797   if (unformat (input, "%d", &tmp))
11798     {
11799       next_index = tmp;
11800       goto out;
11801     }
11802
11803   return 0;
11804
11805 out:
11806   *miss_next_indexp = next_index;
11807   return 1;
11808 }
11809
11810 #define foreach_acl_next                        \
11811 _(deny, DENY)
11812
11813 uword
11814 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11815 {
11816   u32 *miss_next_indexp = va_arg (*args, u32 *);
11817   u32 next_index = 0;
11818   u32 tmp;
11819
11820 #define _(n,N) \
11821   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11822   foreach_acl_next;
11823 #undef _
11824
11825   if (unformat (input, "permit"))
11826     {
11827       next_index = ~0;
11828       goto out;
11829     }
11830   else if (unformat (input, "%d", &tmp))
11831     {
11832       next_index = tmp;
11833       goto out;
11834     }
11835
11836   return 0;
11837
11838 out:
11839   *miss_next_indexp = next_index;
11840   return 1;
11841 }
11842
11843 uword
11844 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11845 {
11846   u32 *r = va_arg (*args, u32 *);
11847
11848   if (unformat (input, "conform-color"))
11849     *r = POLICE_CONFORM;
11850   else if (unformat (input, "exceed-color"))
11851     *r = POLICE_EXCEED;
11852   else
11853     return 0;
11854
11855   return 1;
11856 }
11857
11858 static int
11859 api_classify_add_del_table (vat_main_t * vam)
11860 {
11861   unformat_input_t *i = vam->input;
11862   vl_api_classify_add_del_table_t *mp;
11863
11864   u32 nbuckets = 2;
11865   u32 skip = ~0;
11866   u32 match = ~0;
11867   int is_add = 1;
11868   int del_chain = 0;
11869   u32 table_index = ~0;
11870   u32 next_table_index = ~0;
11871   u32 miss_next_index = ~0;
11872   u32 memory_size = 32 << 20;
11873   u8 *mask = 0;
11874   u32 current_data_flag = 0;
11875   int current_data_offset = 0;
11876   int ret;
11877
11878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11879     {
11880       if (unformat (i, "del"))
11881         is_add = 0;
11882       else if (unformat (i, "del-chain"))
11883         {
11884           is_add = 0;
11885           del_chain = 1;
11886         }
11887       else if (unformat (i, "buckets %d", &nbuckets))
11888         ;
11889       else if (unformat (i, "memory_size %d", &memory_size))
11890         ;
11891       else if (unformat (i, "skip %d", &skip))
11892         ;
11893       else if (unformat (i, "match %d", &match))
11894         ;
11895       else if (unformat (i, "table %d", &table_index))
11896         ;
11897       else if (unformat (i, "mask %U", unformat_classify_mask,
11898                          &mask, &skip, &match))
11899         ;
11900       else if (unformat (i, "next-table %d", &next_table_index))
11901         ;
11902       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11903                          &miss_next_index))
11904         ;
11905       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11906                          &miss_next_index))
11907         ;
11908       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11909                          &miss_next_index))
11910         ;
11911       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11912         ;
11913       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11914         ;
11915       else
11916         break;
11917     }
11918
11919   if (is_add && mask == 0)
11920     {
11921       errmsg ("Mask required");
11922       return -99;
11923     }
11924
11925   if (is_add && skip == ~0)
11926     {
11927       errmsg ("skip count required");
11928       return -99;
11929     }
11930
11931   if (is_add && match == ~0)
11932     {
11933       errmsg ("match count required");
11934       return -99;
11935     }
11936
11937   if (!is_add && table_index == ~0)
11938     {
11939       errmsg ("table index required for delete");
11940       return -99;
11941     }
11942
11943   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11944
11945   mp->is_add = is_add;
11946   mp->del_chain = del_chain;
11947   mp->table_index = ntohl (table_index);
11948   mp->nbuckets = ntohl (nbuckets);
11949   mp->memory_size = ntohl (memory_size);
11950   mp->skip_n_vectors = ntohl (skip);
11951   mp->match_n_vectors = ntohl (match);
11952   mp->next_table_index = ntohl (next_table_index);
11953   mp->miss_next_index = ntohl (miss_next_index);
11954   mp->current_data_flag = ntohl (current_data_flag);
11955   mp->current_data_offset = ntohl (current_data_offset);
11956   mp->mask_len = ntohl (vec_len (mask));
11957   clib_memcpy (mp->mask, mask, vec_len (mask));
11958
11959   vec_free (mask);
11960
11961   S (mp);
11962   W (ret);
11963   return ret;
11964 }
11965
11966 #if VPP_API_TEST_BUILTIN == 0
11967 uword
11968 unformat_l4_match (unformat_input_t * input, va_list * args)
11969 {
11970   u8 **matchp = va_arg (*args, u8 **);
11971
11972   u8 *proto_header = 0;
11973   int src_port = 0;
11974   int dst_port = 0;
11975
11976   tcpudp_header_t h;
11977
11978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11979     {
11980       if (unformat (input, "src_port %d", &src_port))
11981         ;
11982       else if (unformat (input, "dst_port %d", &dst_port))
11983         ;
11984       else
11985         return 0;
11986     }
11987
11988   h.src_port = clib_host_to_net_u16 (src_port);
11989   h.dst_port = clib_host_to_net_u16 (dst_port);
11990   vec_validate (proto_header, sizeof (h) - 1);
11991   memcpy (proto_header, &h, sizeof (h));
11992
11993   *matchp = proto_header;
11994
11995   return 1;
11996 }
11997
11998 uword
11999 unformat_ip4_match (unformat_input_t * input, va_list * args)
12000 {
12001   u8 **matchp = va_arg (*args, u8 **);
12002   u8 *match = 0;
12003   ip4_header_t *ip;
12004   int version = 0;
12005   u32 version_val;
12006   int hdr_length = 0;
12007   u32 hdr_length_val;
12008   int src = 0, dst = 0;
12009   ip4_address_t src_val, dst_val;
12010   int proto = 0;
12011   u32 proto_val;
12012   int tos = 0;
12013   u32 tos_val;
12014   int length = 0;
12015   u32 length_val;
12016   int fragment_id = 0;
12017   u32 fragment_id_val;
12018   int ttl = 0;
12019   int ttl_val;
12020   int checksum = 0;
12021   u32 checksum_val;
12022
12023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12024     {
12025       if (unformat (input, "version %d", &version_val))
12026         version = 1;
12027       else if (unformat (input, "hdr_length %d", &hdr_length_val))
12028         hdr_length = 1;
12029       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
12030         src = 1;
12031       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
12032         dst = 1;
12033       else if (unformat (input, "proto %d", &proto_val))
12034         proto = 1;
12035       else if (unformat (input, "tos %d", &tos_val))
12036         tos = 1;
12037       else if (unformat (input, "length %d", &length_val))
12038         length = 1;
12039       else if (unformat (input, "fragment_id %d", &fragment_id_val))
12040         fragment_id = 1;
12041       else if (unformat (input, "ttl %d", &ttl_val))
12042         ttl = 1;
12043       else if (unformat (input, "checksum %d", &checksum_val))
12044         checksum = 1;
12045       else
12046         break;
12047     }
12048
12049   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
12050       + ttl + checksum == 0)
12051     return 0;
12052
12053   /*
12054    * Aligned because we use the real comparison functions
12055    */
12056   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12057
12058   ip = (ip4_header_t *) match;
12059
12060   /* These are realistically matched in practice */
12061   if (src)
12062     ip->src_address.as_u32 = src_val.as_u32;
12063
12064   if (dst)
12065     ip->dst_address.as_u32 = dst_val.as_u32;
12066
12067   if (proto)
12068     ip->protocol = proto_val;
12069
12070
12071   /* These are not, but they're included for completeness */
12072   if (version)
12073     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
12074
12075   if (hdr_length)
12076     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
12077
12078   if (tos)
12079     ip->tos = tos_val;
12080
12081   if (length)
12082     ip->length = clib_host_to_net_u16 (length_val);
12083
12084   if (ttl)
12085     ip->ttl = ttl_val;
12086
12087   if (checksum)
12088     ip->checksum = clib_host_to_net_u16 (checksum_val);
12089
12090   *matchp = match;
12091   return 1;
12092 }
12093
12094 uword
12095 unformat_ip6_match (unformat_input_t * input, va_list * args)
12096 {
12097   u8 **matchp = va_arg (*args, u8 **);
12098   u8 *match = 0;
12099   ip6_header_t *ip;
12100   int version = 0;
12101   u32 version_val;
12102   u8 traffic_class = 0;
12103   u32 traffic_class_val = 0;
12104   u8 flow_label = 0;
12105   u8 flow_label_val;
12106   int src = 0, dst = 0;
12107   ip6_address_t src_val, dst_val;
12108   int proto = 0;
12109   u32 proto_val;
12110   int payload_length = 0;
12111   u32 payload_length_val;
12112   int hop_limit = 0;
12113   int hop_limit_val;
12114   u32 ip_version_traffic_class_and_flow_label;
12115
12116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12117     {
12118       if (unformat (input, "version %d", &version_val))
12119         version = 1;
12120       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12121         traffic_class = 1;
12122       else if (unformat (input, "flow_label %d", &flow_label_val))
12123         flow_label = 1;
12124       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12125         src = 1;
12126       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12127         dst = 1;
12128       else if (unformat (input, "proto %d", &proto_val))
12129         proto = 1;
12130       else if (unformat (input, "payload_length %d", &payload_length_val))
12131         payload_length = 1;
12132       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12133         hop_limit = 1;
12134       else
12135         break;
12136     }
12137
12138   if (version + traffic_class + flow_label + src + dst + proto +
12139       payload_length + hop_limit == 0)
12140     return 0;
12141
12142   /*
12143    * Aligned because we use the real comparison functions
12144    */
12145   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12146
12147   ip = (ip6_header_t *) match;
12148
12149   if (src)
12150     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12151
12152   if (dst)
12153     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12154
12155   if (proto)
12156     ip->protocol = proto_val;
12157
12158   ip_version_traffic_class_and_flow_label = 0;
12159
12160   if (version)
12161     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12162
12163   if (traffic_class)
12164     ip_version_traffic_class_and_flow_label |=
12165       (traffic_class_val & 0xFF) << 20;
12166
12167   if (flow_label)
12168     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12169
12170   ip->ip_version_traffic_class_and_flow_label =
12171     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12172
12173   if (payload_length)
12174     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12175
12176   if (hop_limit)
12177     ip->hop_limit = hop_limit_val;
12178
12179   *matchp = match;
12180   return 1;
12181 }
12182
12183 uword
12184 unformat_l3_match (unformat_input_t * input, va_list * args)
12185 {
12186   u8 **matchp = va_arg (*args, u8 **);
12187
12188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12189     {
12190       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12191         return 1;
12192       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12193         return 1;
12194       else
12195         break;
12196     }
12197   return 0;
12198 }
12199
12200 uword
12201 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12202 {
12203   u8 *tagp = va_arg (*args, u8 *);
12204   u32 tag;
12205
12206   if (unformat (input, "%d", &tag))
12207     {
12208       tagp[0] = (tag >> 8) & 0x0F;
12209       tagp[1] = tag & 0xFF;
12210       return 1;
12211     }
12212
12213   return 0;
12214 }
12215
12216 uword
12217 unformat_l2_match (unformat_input_t * input, va_list * args)
12218 {
12219   u8 **matchp = va_arg (*args, u8 **);
12220   u8 *match = 0;
12221   u8 src = 0;
12222   u8 src_val[6];
12223   u8 dst = 0;
12224   u8 dst_val[6];
12225   u8 proto = 0;
12226   u16 proto_val;
12227   u8 tag1 = 0;
12228   u8 tag1_val[2];
12229   u8 tag2 = 0;
12230   u8 tag2_val[2];
12231   int len = 14;
12232   u8 ignore_tag1 = 0;
12233   u8 ignore_tag2 = 0;
12234   u8 cos1 = 0;
12235   u8 cos2 = 0;
12236   u32 cos1_val = 0;
12237   u32 cos2_val = 0;
12238
12239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12240     {
12241       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12242         src = 1;
12243       else
12244         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12245         dst = 1;
12246       else if (unformat (input, "proto %U",
12247                          unformat_ethernet_type_host_byte_order, &proto_val))
12248         proto = 1;
12249       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12250         tag1 = 1;
12251       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12252         tag2 = 1;
12253       else if (unformat (input, "ignore-tag1"))
12254         ignore_tag1 = 1;
12255       else if (unformat (input, "ignore-tag2"))
12256         ignore_tag2 = 1;
12257       else if (unformat (input, "cos1 %d", &cos1_val))
12258         cos1 = 1;
12259       else if (unformat (input, "cos2 %d", &cos2_val))
12260         cos2 = 1;
12261       else
12262         break;
12263     }
12264   if ((src + dst + proto + tag1 + tag2 +
12265        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12266     return 0;
12267
12268   if (tag1 || ignore_tag1 || cos1)
12269     len = 18;
12270   if (tag2 || ignore_tag2 || cos2)
12271     len = 22;
12272
12273   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12274
12275   if (dst)
12276     clib_memcpy (match, dst_val, 6);
12277
12278   if (src)
12279     clib_memcpy (match + 6, src_val, 6);
12280
12281   if (tag2)
12282     {
12283       /* inner vlan tag */
12284       match[19] = tag2_val[1];
12285       match[18] = tag2_val[0];
12286       if (cos2)
12287         match[18] |= (cos2_val & 0x7) << 5;
12288       if (proto)
12289         {
12290           match[21] = proto_val & 0xff;
12291           match[20] = proto_val >> 8;
12292         }
12293       if (tag1)
12294         {
12295           match[15] = tag1_val[1];
12296           match[14] = tag1_val[0];
12297         }
12298       if (cos1)
12299         match[14] |= (cos1_val & 0x7) << 5;
12300       *matchp = match;
12301       return 1;
12302     }
12303   if (tag1)
12304     {
12305       match[15] = tag1_val[1];
12306       match[14] = tag1_val[0];
12307       if (proto)
12308         {
12309           match[17] = proto_val & 0xff;
12310           match[16] = proto_val >> 8;
12311         }
12312       if (cos1)
12313         match[14] |= (cos1_val & 0x7) << 5;
12314
12315       *matchp = match;
12316       return 1;
12317     }
12318   if (cos2)
12319     match[18] |= (cos2_val & 0x7) << 5;
12320   if (cos1)
12321     match[14] |= (cos1_val & 0x7) << 5;
12322   if (proto)
12323     {
12324       match[13] = proto_val & 0xff;
12325       match[12] = proto_val >> 8;
12326     }
12327
12328   *matchp = match;
12329   return 1;
12330 }
12331
12332 uword
12333 unformat_qos_source (unformat_input_t * input, va_list * args)
12334 {
12335   int *qs = va_arg (*args, int *);
12336
12337   if (unformat (input, "ip"))
12338     *qs = QOS_SOURCE_IP;
12339   else if (unformat (input, "mpls"))
12340     *qs = QOS_SOURCE_MPLS;
12341   else if (unformat (input, "ext"))
12342     *qs = QOS_SOURCE_EXT;
12343   else if (unformat (input, "vlan"))
12344     *qs = QOS_SOURCE_VLAN;
12345   else
12346     return 0;
12347
12348   return 1;
12349 }
12350 #endif
12351
12352 uword
12353 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12354 {
12355   u8 **matchp = va_arg (*args, u8 **);
12356   u32 skip_n_vectors = va_arg (*args, u32);
12357   u32 match_n_vectors = va_arg (*args, u32);
12358
12359   u8 *match = 0;
12360   u8 *l2 = 0;
12361   u8 *l3 = 0;
12362   u8 *l4 = 0;
12363
12364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12365     {
12366       if (unformat (input, "hex %U", unformat_hex_string, &match))
12367         ;
12368       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12369         ;
12370       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12371         ;
12372       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12373         ;
12374       else
12375         break;
12376     }
12377
12378   if (l4 && !l3)
12379     {
12380       vec_free (match);
12381       vec_free (l2);
12382       vec_free (l4);
12383       return 0;
12384     }
12385
12386   if (match || l2 || l3 || l4)
12387     {
12388       if (l2 || l3 || l4)
12389         {
12390           /* "Win a free Ethernet header in every packet" */
12391           if (l2 == 0)
12392             vec_validate_aligned (l2, 13, sizeof (u32x4));
12393           match = l2;
12394           if (vec_len (l3))
12395             {
12396               vec_append_aligned (match, l3, sizeof (u32x4));
12397               vec_free (l3);
12398             }
12399           if (vec_len (l4))
12400             {
12401               vec_append_aligned (match, l4, sizeof (u32x4));
12402               vec_free (l4);
12403             }
12404         }
12405
12406       /* Make sure the vector is big enough even if key is all 0's */
12407       vec_validate_aligned
12408         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12409          sizeof (u32x4));
12410
12411       /* Set size, include skipped vectors */
12412       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12413
12414       *matchp = match;
12415
12416       return 1;
12417     }
12418
12419   return 0;
12420 }
12421
12422 static int
12423 api_classify_add_del_session (vat_main_t * vam)
12424 {
12425   unformat_input_t *i = vam->input;
12426   vl_api_classify_add_del_session_t *mp;
12427   int is_add = 1;
12428   u32 table_index = ~0;
12429   u32 hit_next_index = ~0;
12430   u32 opaque_index = ~0;
12431   u8 *match = 0;
12432   i32 advance = 0;
12433   u32 skip_n_vectors = 0;
12434   u32 match_n_vectors = 0;
12435   u32 action = 0;
12436   u32 metadata = 0;
12437   int ret;
12438
12439   /*
12440    * Warning: you have to supply skip_n and match_n
12441    * because the API client cant simply look at the classify
12442    * table object.
12443    */
12444
12445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12446     {
12447       if (unformat (i, "del"))
12448         is_add = 0;
12449       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12450                          &hit_next_index))
12451         ;
12452       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12453                          &hit_next_index))
12454         ;
12455       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12456                          &hit_next_index))
12457         ;
12458       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12459         ;
12460       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12461         ;
12462       else if (unformat (i, "opaque-index %d", &opaque_index))
12463         ;
12464       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12465         ;
12466       else if (unformat (i, "match_n %d", &match_n_vectors))
12467         ;
12468       else if (unformat (i, "match %U", api_unformat_classify_match,
12469                          &match, skip_n_vectors, match_n_vectors))
12470         ;
12471       else if (unformat (i, "advance %d", &advance))
12472         ;
12473       else if (unformat (i, "table-index %d", &table_index))
12474         ;
12475       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12476         action = 1;
12477       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12478         action = 2;
12479       else if (unformat (i, "action %d", &action))
12480         ;
12481       else if (unformat (i, "metadata %d", &metadata))
12482         ;
12483       else
12484         break;
12485     }
12486
12487   if (table_index == ~0)
12488     {
12489       errmsg ("Table index required");
12490       return -99;
12491     }
12492
12493   if (is_add && match == 0)
12494     {
12495       errmsg ("Match value required");
12496       return -99;
12497     }
12498
12499   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12500
12501   mp->is_add = is_add;
12502   mp->table_index = ntohl (table_index);
12503   mp->hit_next_index = ntohl (hit_next_index);
12504   mp->opaque_index = ntohl (opaque_index);
12505   mp->advance = ntohl (advance);
12506   mp->action = action;
12507   mp->metadata = ntohl (metadata);
12508   mp->match_len = ntohl (vec_len (match));
12509   clib_memcpy (mp->match, match, vec_len (match));
12510   vec_free (match);
12511
12512   S (mp);
12513   W (ret);
12514   return ret;
12515 }
12516
12517 static int
12518 api_classify_set_interface_ip_table (vat_main_t * vam)
12519 {
12520   unformat_input_t *i = vam->input;
12521   vl_api_classify_set_interface_ip_table_t *mp;
12522   u32 sw_if_index;
12523   int sw_if_index_set;
12524   u32 table_index = ~0;
12525   u8 is_ipv6 = 0;
12526   int ret;
12527
12528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12529     {
12530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12531         sw_if_index_set = 1;
12532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12533         sw_if_index_set = 1;
12534       else if (unformat (i, "table %d", &table_index))
12535         ;
12536       else
12537         {
12538           clib_warning ("parse error '%U'", format_unformat_error, i);
12539           return -99;
12540         }
12541     }
12542
12543   if (sw_if_index_set == 0)
12544     {
12545       errmsg ("missing interface name or sw_if_index");
12546       return -99;
12547     }
12548
12549
12550   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12551
12552   mp->sw_if_index = ntohl (sw_if_index);
12553   mp->table_index = ntohl (table_index);
12554   mp->is_ipv6 = is_ipv6;
12555
12556   S (mp);
12557   W (ret);
12558   return ret;
12559 }
12560
12561 static int
12562 api_classify_set_interface_l2_tables (vat_main_t * vam)
12563 {
12564   unformat_input_t *i = vam->input;
12565   vl_api_classify_set_interface_l2_tables_t *mp;
12566   u32 sw_if_index;
12567   int sw_if_index_set;
12568   u32 ip4_table_index = ~0;
12569   u32 ip6_table_index = ~0;
12570   u32 other_table_index = ~0;
12571   u32 is_input = 1;
12572   int ret;
12573
12574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12575     {
12576       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12577         sw_if_index_set = 1;
12578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12579         sw_if_index_set = 1;
12580       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12581         ;
12582       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12583         ;
12584       else if (unformat (i, "other-table %d", &other_table_index))
12585         ;
12586       else if (unformat (i, "is-input %d", &is_input))
12587         ;
12588       else
12589         {
12590           clib_warning ("parse error '%U'", format_unformat_error, i);
12591           return -99;
12592         }
12593     }
12594
12595   if (sw_if_index_set == 0)
12596     {
12597       errmsg ("missing interface name or sw_if_index");
12598       return -99;
12599     }
12600
12601
12602   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12603
12604   mp->sw_if_index = ntohl (sw_if_index);
12605   mp->ip4_table_index = ntohl (ip4_table_index);
12606   mp->ip6_table_index = ntohl (ip6_table_index);
12607   mp->other_table_index = ntohl (other_table_index);
12608   mp->is_input = (u8) is_input;
12609
12610   S (mp);
12611   W (ret);
12612   return ret;
12613 }
12614
12615 static int
12616 api_set_ipfix_exporter (vat_main_t * vam)
12617 {
12618   unformat_input_t *i = vam->input;
12619   vl_api_set_ipfix_exporter_t *mp;
12620   ip4_address_t collector_address;
12621   u8 collector_address_set = 0;
12622   u32 collector_port = ~0;
12623   ip4_address_t src_address;
12624   u8 src_address_set = 0;
12625   u32 vrf_id = ~0;
12626   u32 path_mtu = ~0;
12627   u32 template_interval = ~0;
12628   u8 udp_checksum = 0;
12629   int ret;
12630
12631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12632     {
12633       if (unformat (i, "collector_address %U", unformat_ip4_address,
12634                     &collector_address))
12635         collector_address_set = 1;
12636       else if (unformat (i, "collector_port %d", &collector_port))
12637         ;
12638       else if (unformat (i, "src_address %U", unformat_ip4_address,
12639                          &src_address))
12640         src_address_set = 1;
12641       else if (unformat (i, "vrf_id %d", &vrf_id))
12642         ;
12643       else if (unformat (i, "path_mtu %d", &path_mtu))
12644         ;
12645       else if (unformat (i, "template_interval %d", &template_interval))
12646         ;
12647       else if (unformat (i, "udp_checksum"))
12648         udp_checksum = 1;
12649       else
12650         break;
12651     }
12652
12653   if (collector_address_set == 0)
12654     {
12655       errmsg ("collector_address required");
12656       return -99;
12657     }
12658
12659   if (src_address_set == 0)
12660     {
12661       errmsg ("src_address required");
12662       return -99;
12663     }
12664
12665   M (SET_IPFIX_EXPORTER, mp);
12666
12667   memcpy (mp->collector_address, collector_address.data,
12668           sizeof (collector_address.data));
12669   mp->collector_port = htons ((u16) collector_port);
12670   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12671   mp->vrf_id = htonl (vrf_id);
12672   mp->path_mtu = htonl (path_mtu);
12673   mp->template_interval = htonl (template_interval);
12674   mp->udp_checksum = udp_checksum;
12675
12676   S (mp);
12677   W (ret);
12678   return ret;
12679 }
12680
12681 static int
12682 api_set_ipfix_classify_stream (vat_main_t * vam)
12683 {
12684   unformat_input_t *i = vam->input;
12685   vl_api_set_ipfix_classify_stream_t *mp;
12686   u32 domain_id = 0;
12687   u32 src_port = UDP_DST_PORT_ipfix;
12688   int ret;
12689
12690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12691     {
12692       if (unformat (i, "domain %d", &domain_id))
12693         ;
12694       else if (unformat (i, "src_port %d", &src_port))
12695         ;
12696       else
12697         {
12698           errmsg ("unknown input `%U'", format_unformat_error, i);
12699           return -99;
12700         }
12701     }
12702
12703   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12704
12705   mp->domain_id = htonl (domain_id);
12706   mp->src_port = htons ((u16) src_port);
12707
12708   S (mp);
12709   W (ret);
12710   return ret;
12711 }
12712
12713 static int
12714 api_ipfix_classify_table_add_del (vat_main_t * vam)
12715 {
12716   unformat_input_t *i = vam->input;
12717   vl_api_ipfix_classify_table_add_del_t *mp;
12718   int is_add = -1;
12719   u32 classify_table_index = ~0;
12720   u8 ip_version = 0;
12721   u8 transport_protocol = 255;
12722   int ret;
12723
12724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12725     {
12726       if (unformat (i, "add"))
12727         is_add = 1;
12728       else if (unformat (i, "del"))
12729         is_add = 0;
12730       else if (unformat (i, "table %d", &classify_table_index))
12731         ;
12732       else if (unformat (i, "ip4"))
12733         ip_version = 4;
12734       else if (unformat (i, "ip6"))
12735         ip_version = 6;
12736       else if (unformat (i, "tcp"))
12737         transport_protocol = 6;
12738       else if (unformat (i, "udp"))
12739         transport_protocol = 17;
12740       else
12741         {
12742           errmsg ("unknown input `%U'", format_unformat_error, i);
12743           return -99;
12744         }
12745     }
12746
12747   if (is_add == -1)
12748     {
12749       errmsg ("expecting: add|del");
12750       return -99;
12751     }
12752   if (classify_table_index == ~0)
12753     {
12754       errmsg ("classifier table not specified");
12755       return -99;
12756     }
12757   if (ip_version == 0)
12758     {
12759       errmsg ("IP version not specified");
12760       return -99;
12761     }
12762
12763   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12764
12765   mp->is_add = is_add;
12766   mp->table_id = htonl (classify_table_index);
12767   mp->ip_version = ip_version;
12768   mp->transport_protocol = transport_protocol;
12769
12770   S (mp);
12771   W (ret);
12772   return ret;
12773 }
12774
12775 static int
12776 api_get_node_index (vat_main_t * vam)
12777 {
12778   unformat_input_t *i = vam->input;
12779   vl_api_get_node_index_t *mp;
12780   u8 *name = 0;
12781   int ret;
12782
12783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12784     {
12785       if (unformat (i, "node %s", &name))
12786         ;
12787       else
12788         break;
12789     }
12790   if (name == 0)
12791     {
12792       errmsg ("node name required");
12793       return -99;
12794     }
12795   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12796     {
12797       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12798       return -99;
12799     }
12800
12801   M (GET_NODE_INDEX, mp);
12802   clib_memcpy (mp->node_name, name, vec_len (name));
12803   vec_free (name);
12804
12805   S (mp);
12806   W (ret);
12807   return ret;
12808 }
12809
12810 static int
12811 api_get_next_index (vat_main_t * vam)
12812 {
12813   unformat_input_t *i = vam->input;
12814   vl_api_get_next_index_t *mp;
12815   u8 *node_name = 0, *next_node_name = 0;
12816   int ret;
12817
12818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12819     {
12820       if (unformat (i, "node-name %s", &node_name))
12821         ;
12822       else if (unformat (i, "next-node-name %s", &next_node_name))
12823         break;
12824     }
12825
12826   if (node_name == 0)
12827     {
12828       errmsg ("node name required");
12829       return -99;
12830     }
12831   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12832     {
12833       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12834       return -99;
12835     }
12836
12837   if (next_node_name == 0)
12838     {
12839       errmsg ("next node name required");
12840       return -99;
12841     }
12842   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12843     {
12844       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12845       return -99;
12846     }
12847
12848   M (GET_NEXT_INDEX, mp);
12849   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12850   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12851   vec_free (node_name);
12852   vec_free (next_node_name);
12853
12854   S (mp);
12855   W (ret);
12856   return ret;
12857 }
12858
12859 static int
12860 api_add_node_next (vat_main_t * vam)
12861 {
12862   unformat_input_t *i = vam->input;
12863   vl_api_add_node_next_t *mp;
12864   u8 *name = 0;
12865   u8 *next = 0;
12866   int ret;
12867
12868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12869     {
12870       if (unformat (i, "node %s", &name))
12871         ;
12872       else if (unformat (i, "next %s", &next))
12873         ;
12874       else
12875         break;
12876     }
12877   if (name == 0)
12878     {
12879       errmsg ("node name required");
12880       return -99;
12881     }
12882   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12883     {
12884       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12885       return -99;
12886     }
12887   if (next == 0)
12888     {
12889       errmsg ("next node required");
12890       return -99;
12891     }
12892   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12893     {
12894       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12895       return -99;
12896     }
12897
12898   M (ADD_NODE_NEXT, mp);
12899   clib_memcpy (mp->node_name, name, vec_len (name));
12900   clib_memcpy (mp->next_name, next, vec_len (next));
12901   vec_free (name);
12902   vec_free (next);
12903
12904   S (mp);
12905   W (ret);
12906   return ret;
12907 }
12908
12909 static int
12910 api_l2tpv3_create_tunnel (vat_main_t * vam)
12911 {
12912   unformat_input_t *i = vam->input;
12913   ip6_address_t client_address, our_address;
12914   int client_address_set = 0;
12915   int our_address_set = 0;
12916   u32 local_session_id = 0;
12917   u32 remote_session_id = 0;
12918   u64 local_cookie = 0;
12919   u64 remote_cookie = 0;
12920   u8 l2_sublayer_present = 0;
12921   vl_api_l2tpv3_create_tunnel_t *mp;
12922   int ret;
12923
12924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12925     {
12926       if (unformat (i, "client_address %U", unformat_ip6_address,
12927                     &client_address))
12928         client_address_set = 1;
12929       else if (unformat (i, "our_address %U", unformat_ip6_address,
12930                          &our_address))
12931         our_address_set = 1;
12932       else if (unformat (i, "local_session_id %d", &local_session_id))
12933         ;
12934       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12935         ;
12936       else if (unformat (i, "local_cookie %lld", &local_cookie))
12937         ;
12938       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12939         ;
12940       else if (unformat (i, "l2-sublayer-present"))
12941         l2_sublayer_present = 1;
12942       else
12943         break;
12944     }
12945
12946   if (client_address_set == 0)
12947     {
12948       errmsg ("client_address required");
12949       return -99;
12950     }
12951
12952   if (our_address_set == 0)
12953     {
12954       errmsg ("our_address required");
12955       return -99;
12956     }
12957
12958   M (L2TPV3_CREATE_TUNNEL, mp);
12959
12960   clib_memcpy (mp->client_address, client_address.as_u8,
12961                sizeof (mp->client_address));
12962
12963   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12964
12965   mp->local_session_id = ntohl (local_session_id);
12966   mp->remote_session_id = ntohl (remote_session_id);
12967   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12968   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12969   mp->l2_sublayer_present = l2_sublayer_present;
12970   mp->is_ipv6 = 1;
12971
12972   S (mp);
12973   W (ret);
12974   return ret;
12975 }
12976
12977 static int
12978 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12979 {
12980   unformat_input_t *i = vam->input;
12981   u32 sw_if_index;
12982   u8 sw_if_index_set = 0;
12983   u64 new_local_cookie = 0;
12984   u64 new_remote_cookie = 0;
12985   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12986   int ret;
12987
12988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12989     {
12990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12991         sw_if_index_set = 1;
12992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12993         sw_if_index_set = 1;
12994       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12995         ;
12996       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12997         ;
12998       else
12999         break;
13000     }
13001
13002   if (sw_if_index_set == 0)
13003     {
13004       errmsg ("missing interface name or sw_if_index");
13005       return -99;
13006     }
13007
13008   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
13009
13010   mp->sw_if_index = ntohl (sw_if_index);
13011   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
13012   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
13013
13014   S (mp);
13015   W (ret);
13016   return ret;
13017 }
13018
13019 static int
13020 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
13021 {
13022   unformat_input_t *i = vam->input;
13023   vl_api_l2tpv3_interface_enable_disable_t *mp;
13024   u32 sw_if_index;
13025   u8 sw_if_index_set = 0;
13026   u8 enable_disable = 1;
13027   int ret;
13028
13029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13030     {
13031       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13032         sw_if_index_set = 1;
13033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13034         sw_if_index_set = 1;
13035       else if (unformat (i, "enable"))
13036         enable_disable = 1;
13037       else if (unformat (i, "disable"))
13038         enable_disable = 0;
13039       else
13040         break;
13041     }
13042
13043   if (sw_if_index_set == 0)
13044     {
13045       errmsg ("missing interface name or sw_if_index");
13046       return -99;
13047     }
13048
13049   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
13050
13051   mp->sw_if_index = ntohl (sw_if_index);
13052   mp->enable_disable = enable_disable;
13053
13054   S (mp);
13055   W (ret);
13056   return ret;
13057 }
13058
13059 static int
13060 api_l2tpv3_set_lookup_key (vat_main_t * vam)
13061 {
13062   unformat_input_t *i = vam->input;
13063   vl_api_l2tpv3_set_lookup_key_t *mp;
13064   u8 key = ~0;
13065   int ret;
13066
13067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13068     {
13069       if (unformat (i, "lookup_v6_src"))
13070         key = L2T_LOOKUP_SRC_ADDRESS;
13071       else if (unformat (i, "lookup_v6_dst"))
13072         key = L2T_LOOKUP_DST_ADDRESS;
13073       else if (unformat (i, "lookup_session_id"))
13074         key = L2T_LOOKUP_SESSION_ID;
13075       else
13076         break;
13077     }
13078
13079   if (key == (u8) ~ 0)
13080     {
13081       errmsg ("l2tp session lookup key unset");
13082       return -99;
13083     }
13084
13085   M (L2TPV3_SET_LOOKUP_KEY, mp);
13086
13087   mp->key = key;
13088
13089   S (mp);
13090   W (ret);
13091   return ret;
13092 }
13093
13094 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
13095   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13096 {
13097   vat_main_t *vam = &vat_main;
13098
13099   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
13100          format_ip6_address, mp->our_address,
13101          format_ip6_address, mp->client_address,
13102          clib_net_to_host_u32 (mp->sw_if_index));
13103
13104   print (vam->ofp,
13105          "   local cookies %016llx %016llx remote cookie %016llx",
13106          clib_net_to_host_u64 (mp->local_cookie[0]),
13107          clib_net_to_host_u64 (mp->local_cookie[1]),
13108          clib_net_to_host_u64 (mp->remote_cookie));
13109
13110   print (vam->ofp, "   local session-id %d remote session-id %d",
13111          clib_net_to_host_u32 (mp->local_session_id),
13112          clib_net_to_host_u32 (mp->remote_session_id));
13113
13114   print (vam->ofp, "   l2 specific sublayer %s\n",
13115          mp->l2_sublayer_present ? "preset" : "absent");
13116
13117 }
13118
13119 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13120   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13121 {
13122   vat_main_t *vam = &vat_main;
13123   vat_json_node_t *node = NULL;
13124   struct in6_addr addr;
13125
13126   if (VAT_JSON_ARRAY != vam->json_tree.type)
13127     {
13128       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13129       vat_json_init_array (&vam->json_tree);
13130     }
13131   node = vat_json_array_add (&vam->json_tree);
13132
13133   vat_json_init_object (node);
13134
13135   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13136   vat_json_object_add_ip6 (node, "our_address", addr);
13137   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13138   vat_json_object_add_ip6 (node, "client_address", addr);
13139
13140   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13141   vat_json_init_array (lc);
13142   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13143   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13144   vat_json_object_add_uint (node, "remote_cookie",
13145                             clib_net_to_host_u64 (mp->remote_cookie));
13146
13147   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13148   vat_json_object_add_uint (node, "local_session_id",
13149                             clib_net_to_host_u32 (mp->local_session_id));
13150   vat_json_object_add_uint (node, "remote_session_id",
13151                             clib_net_to_host_u32 (mp->remote_session_id));
13152   vat_json_object_add_string_copy (node, "l2_sublayer",
13153                                    mp->l2_sublayer_present ? (u8 *) "present"
13154                                    : (u8 *) "absent");
13155 }
13156
13157 static int
13158 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13159 {
13160   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13161   vl_api_control_ping_t *mp_ping;
13162   int ret;
13163
13164   /* Get list of l2tpv3-tunnel interfaces */
13165   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13166   S (mp);
13167
13168   /* Use a control ping for synchronization */
13169   MPING (CONTROL_PING, mp_ping);
13170   S (mp_ping);
13171
13172   W (ret);
13173   return ret;
13174 }
13175
13176
13177 static void vl_api_sw_interface_tap_details_t_handler
13178   (vl_api_sw_interface_tap_details_t * mp)
13179 {
13180   vat_main_t *vam = &vat_main;
13181
13182   print (vam->ofp, "%-16s %d",
13183          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13184 }
13185
13186 static void vl_api_sw_interface_tap_details_t_handler_json
13187   (vl_api_sw_interface_tap_details_t * mp)
13188 {
13189   vat_main_t *vam = &vat_main;
13190   vat_json_node_t *node = NULL;
13191
13192   if (VAT_JSON_ARRAY != vam->json_tree.type)
13193     {
13194       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13195       vat_json_init_array (&vam->json_tree);
13196     }
13197   node = vat_json_array_add (&vam->json_tree);
13198
13199   vat_json_init_object (node);
13200   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13201   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13202 }
13203
13204 static int
13205 api_sw_interface_tap_dump (vat_main_t * vam)
13206 {
13207   vl_api_sw_interface_tap_dump_t *mp;
13208   vl_api_control_ping_t *mp_ping;
13209   int ret;
13210
13211   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13212   /* Get list of tap interfaces */
13213   M (SW_INTERFACE_TAP_DUMP, mp);
13214   S (mp);
13215
13216   /* Use a control ping for synchronization */
13217   MPING (CONTROL_PING, mp_ping);
13218   S (mp_ping);
13219
13220   W (ret);
13221   return ret;
13222 }
13223
13224 static void vl_api_sw_interface_tap_v2_details_t_handler
13225   (vl_api_sw_interface_tap_v2_details_t * mp)
13226 {
13227   vat_main_t *vam = &vat_main;
13228
13229   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13230                     mp->host_ip4_prefix_len);
13231   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13232                     mp->host_ip6_prefix_len);
13233
13234   print (vam->ofp,
13235          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13236          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13237          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13238          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13239          mp->host_bridge, ip4, ip6);
13240
13241   vec_free (ip4);
13242   vec_free (ip6);
13243 }
13244
13245 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13246   (vl_api_sw_interface_tap_v2_details_t * mp)
13247 {
13248   vat_main_t *vam = &vat_main;
13249   vat_json_node_t *node = NULL;
13250
13251   if (VAT_JSON_ARRAY != vam->json_tree.type)
13252     {
13253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13254       vat_json_init_array (&vam->json_tree);
13255     }
13256   node = vat_json_array_add (&vam->json_tree);
13257
13258   vat_json_init_object (node);
13259   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13260   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13261   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13262   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13263   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13264   vat_json_object_add_string_copy (node, "host_mac_addr",
13265                                    format (0, "%U", format_ethernet_address,
13266                                            &mp->host_mac_addr));
13267   vat_json_object_add_string_copy (node, "host_namespace",
13268                                    mp->host_namespace);
13269   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13270   vat_json_object_add_string_copy (node, "host_ip4_addr",
13271                                    format (0, "%U/%d", format_ip4_address,
13272                                            mp->host_ip4_addr,
13273                                            mp->host_ip4_prefix_len));
13274   vat_json_object_add_string_copy (node, "host_ip6_addr",
13275                                    format (0, "%U/%d", format_ip6_address,
13276                                            mp->host_ip6_addr,
13277                                            mp->host_ip6_prefix_len));
13278
13279 }
13280
13281 static int
13282 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13283 {
13284   vl_api_sw_interface_tap_v2_dump_t *mp;
13285   vl_api_control_ping_t *mp_ping;
13286   int ret;
13287
13288   print (vam->ofp,
13289          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13290          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13291          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13292          "host_ip6_addr");
13293
13294   /* Get list of tap interfaces */
13295   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13296   S (mp);
13297
13298   /* Use a control ping for synchronization */
13299   MPING (CONTROL_PING, mp_ping);
13300   S (mp_ping);
13301
13302   W (ret);
13303   return ret;
13304 }
13305
13306 static int
13307 api_vxlan_offload_rx (vat_main_t * vam)
13308 {
13309   unformat_input_t *line_input = vam->input;
13310   vl_api_vxlan_offload_rx_t *mp;
13311   u32 hw_if_index = ~0, rx_if_index = ~0;
13312   u8 is_add = 1;
13313   int ret;
13314
13315   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13316     {
13317       if (unformat (line_input, "del"))
13318         is_add = 0;
13319       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13320                          &hw_if_index))
13321         ;
13322       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13323         ;
13324       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13325                          &rx_if_index))
13326         ;
13327       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13328         ;
13329       else
13330         {
13331           errmsg ("parse error '%U'", format_unformat_error, line_input);
13332           return -99;
13333         }
13334     }
13335
13336   if (hw_if_index == ~0)
13337     {
13338       errmsg ("no hw interface");
13339       return -99;
13340     }
13341
13342   if (rx_if_index == ~0)
13343     {
13344       errmsg ("no rx tunnel");
13345       return -99;
13346     }
13347
13348   M (VXLAN_OFFLOAD_RX, mp);
13349
13350   mp->hw_if_index = ntohl (hw_if_index);
13351   mp->sw_if_index = ntohl (rx_if_index);
13352   mp->enable = is_add;
13353
13354   S (mp);
13355   W (ret);
13356   return ret;
13357 }
13358
13359 static uword unformat_vxlan_decap_next
13360   (unformat_input_t * input, va_list * args)
13361 {
13362   u32 *result = va_arg (*args, u32 *);
13363   u32 tmp;
13364
13365   if (unformat (input, "l2"))
13366     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13367   else if (unformat (input, "%d", &tmp))
13368     *result = tmp;
13369   else
13370     return 0;
13371   return 1;
13372 }
13373
13374 static int
13375 api_vxlan_add_del_tunnel (vat_main_t * vam)
13376 {
13377   unformat_input_t *line_input = vam->input;
13378   vl_api_vxlan_add_del_tunnel_t *mp;
13379   ip46_address_t src, dst;
13380   u8 is_add = 1;
13381   u8 ipv4_set = 0, ipv6_set = 0;
13382   u8 src_set = 0;
13383   u8 dst_set = 0;
13384   u8 grp_set = 0;
13385   u32 instance = ~0;
13386   u32 mcast_sw_if_index = ~0;
13387   u32 encap_vrf_id = 0;
13388   u32 decap_next_index = ~0;
13389   u32 vni = 0;
13390   int ret;
13391
13392   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13393   clib_memset (&src, 0, sizeof src);
13394   clib_memset (&dst, 0, sizeof dst);
13395
13396   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13397     {
13398       if (unformat (line_input, "del"))
13399         is_add = 0;
13400       else if (unformat (line_input, "instance %d", &instance))
13401         ;
13402       else
13403         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13404         {
13405           ipv4_set = 1;
13406           src_set = 1;
13407         }
13408       else
13409         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13410         {
13411           ipv4_set = 1;
13412           dst_set = 1;
13413         }
13414       else
13415         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13416         {
13417           ipv6_set = 1;
13418           src_set = 1;
13419         }
13420       else
13421         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13422         {
13423           ipv6_set = 1;
13424           dst_set = 1;
13425         }
13426       else if (unformat (line_input, "group %U %U",
13427                          unformat_ip4_address, &dst.ip4,
13428                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13429         {
13430           grp_set = dst_set = 1;
13431           ipv4_set = 1;
13432         }
13433       else if (unformat (line_input, "group %U",
13434                          unformat_ip4_address, &dst.ip4))
13435         {
13436           grp_set = dst_set = 1;
13437           ipv4_set = 1;
13438         }
13439       else if (unformat (line_input, "group %U %U",
13440                          unformat_ip6_address, &dst.ip6,
13441                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13442         {
13443           grp_set = dst_set = 1;
13444           ipv6_set = 1;
13445         }
13446       else if (unformat (line_input, "group %U",
13447                          unformat_ip6_address, &dst.ip6))
13448         {
13449           grp_set = dst_set = 1;
13450           ipv6_set = 1;
13451         }
13452       else
13453         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13454         ;
13455       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13456         ;
13457       else if (unformat (line_input, "decap-next %U",
13458                          unformat_vxlan_decap_next, &decap_next_index))
13459         ;
13460       else if (unformat (line_input, "vni %d", &vni))
13461         ;
13462       else
13463         {
13464           errmsg ("parse error '%U'", format_unformat_error, line_input);
13465           return -99;
13466         }
13467     }
13468
13469   if (src_set == 0)
13470     {
13471       errmsg ("tunnel src address not specified");
13472       return -99;
13473     }
13474   if (dst_set == 0)
13475     {
13476       errmsg ("tunnel dst address not specified");
13477       return -99;
13478     }
13479
13480   if (grp_set && !ip46_address_is_multicast (&dst))
13481     {
13482       errmsg ("tunnel group address not multicast");
13483       return -99;
13484     }
13485   if (grp_set && mcast_sw_if_index == ~0)
13486     {
13487       errmsg ("tunnel nonexistent multicast device");
13488       return -99;
13489     }
13490   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13491     {
13492       errmsg ("tunnel dst address must be unicast");
13493       return -99;
13494     }
13495
13496
13497   if (ipv4_set && ipv6_set)
13498     {
13499       errmsg ("both IPv4 and IPv6 addresses specified");
13500       return -99;
13501     }
13502
13503   if ((vni == 0) || (vni >> 24))
13504     {
13505       errmsg ("vni not specified or out of range");
13506       return -99;
13507     }
13508
13509   M (VXLAN_ADD_DEL_TUNNEL, mp);
13510
13511   if (ipv6_set)
13512     {
13513       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13514       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13515     }
13516   else
13517     {
13518       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13519       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13520     }
13521
13522   mp->instance = htonl (instance);
13523   mp->encap_vrf_id = ntohl (encap_vrf_id);
13524   mp->decap_next_index = ntohl (decap_next_index);
13525   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13526   mp->vni = ntohl (vni);
13527   mp->is_add = is_add;
13528   mp->is_ipv6 = ipv6_set;
13529
13530   S (mp);
13531   W (ret);
13532   return ret;
13533 }
13534
13535 static void vl_api_vxlan_tunnel_details_t_handler
13536   (vl_api_vxlan_tunnel_details_t * mp)
13537 {
13538   vat_main_t *vam = &vat_main;
13539   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13540   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13541
13542   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13543          ntohl (mp->sw_if_index),
13544          ntohl (mp->instance),
13545          format_ip46_address, &src, IP46_TYPE_ANY,
13546          format_ip46_address, &dst, IP46_TYPE_ANY,
13547          ntohl (mp->encap_vrf_id),
13548          ntohl (mp->decap_next_index), ntohl (mp->vni),
13549          ntohl (mp->mcast_sw_if_index));
13550 }
13551
13552 static void vl_api_vxlan_tunnel_details_t_handler_json
13553   (vl_api_vxlan_tunnel_details_t * mp)
13554 {
13555   vat_main_t *vam = &vat_main;
13556   vat_json_node_t *node = NULL;
13557
13558   if (VAT_JSON_ARRAY != vam->json_tree.type)
13559     {
13560       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13561       vat_json_init_array (&vam->json_tree);
13562     }
13563   node = vat_json_array_add (&vam->json_tree);
13564
13565   vat_json_init_object (node);
13566   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13567
13568   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13569
13570   if (mp->is_ipv6)
13571     {
13572       struct in6_addr ip6;
13573
13574       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13575       vat_json_object_add_ip6 (node, "src_address", ip6);
13576       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13577       vat_json_object_add_ip6 (node, "dst_address", ip6);
13578     }
13579   else
13580     {
13581       struct in_addr ip4;
13582
13583       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13584       vat_json_object_add_ip4 (node, "src_address", ip4);
13585       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13586       vat_json_object_add_ip4 (node, "dst_address", ip4);
13587     }
13588   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13589   vat_json_object_add_uint (node, "decap_next_index",
13590                             ntohl (mp->decap_next_index));
13591   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13592   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13593   vat_json_object_add_uint (node, "mcast_sw_if_index",
13594                             ntohl (mp->mcast_sw_if_index));
13595 }
13596
13597 static int
13598 api_vxlan_tunnel_dump (vat_main_t * vam)
13599 {
13600   unformat_input_t *i = vam->input;
13601   vl_api_vxlan_tunnel_dump_t *mp;
13602   vl_api_control_ping_t *mp_ping;
13603   u32 sw_if_index;
13604   u8 sw_if_index_set = 0;
13605   int ret;
13606
13607   /* Parse args required to build the message */
13608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13609     {
13610       if (unformat (i, "sw_if_index %d", &sw_if_index))
13611         sw_if_index_set = 1;
13612       else
13613         break;
13614     }
13615
13616   if (sw_if_index_set == 0)
13617     {
13618       sw_if_index = ~0;
13619     }
13620
13621   if (!vam->json_output)
13622     {
13623       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13624              "sw_if_index", "instance", "src_address", "dst_address",
13625              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13626     }
13627
13628   /* Get list of vxlan-tunnel interfaces */
13629   M (VXLAN_TUNNEL_DUMP, mp);
13630
13631   mp->sw_if_index = htonl (sw_if_index);
13632
13633   S (mp);
13634
13635   /* Use a control ping for synchronization */
13636   MPING (CONTROL_PING, mp_ping);
13637   S (mp_ping);
13638
13639   W (ret);
13640   return ret;
13641 }
13642
13643 static uword unformat_geneve_decap_next
13644   (unformat_input_t * input, va_list * args)
13645 {
13646   u32 *result = va_arg (*args, u32 *);
13647   u32 tmp;
13648
13649   if (unformat (input, "l2"))
13650     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13651   else if (unformat (input, "%d", &tmp))
13652     *result = tmp;
13653   else
13654     return 0;
13655   return 1;
13656 }
13657
13658 static int
13659 api_geneve_add_del_tunnel (vat_main_t * vam)
13660 {
13661   unformat_input_t *line_input = vam->input;
13662   vl_api_geneve_add_del_tunnel_t *mp;
13663   ip46_address_t src, dst;
13664   u8 is_add = 1;
13665   u8 ipv4_set = 0, ipv6_set = 0;
13666   u8 src_set = 0;
13667   u8 dst_set = 0;
13668   u8 grp_set = 0;
13669   u32 mcast_sw_if_index = ~0;
13670   u32 encap_vrf_id = 0;
13671   u32 decap_next_index = ~0;
13672   u32 vni = 0;
13673   int ret;
13674
13675   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13676   clib_memset (&src, 0, sizeof src);
13677   clib_memset (&dst, 0, sizeof dst);
13678
13679   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13680     {
13681       if (unformat (line_input, "del"))
13682         is_add = 0;
13683       else
13684         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13685         {
13686           ipv4_set = 1;
13687           src_set = 1;
13688         }
13689       else
13690         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13691         {
13692           ipv4_set = 1;
13693           dst_set = 1;
13694         }
13695       else
13696         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13697         {
13698           ipv6_set = 1;
13699           src_set = 1;
13700         }
13701       else
13702         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13703         {
13704           ipv6_set = 1;
13705           dst_set = 1;
13706         }
13707       else if (unformat (line_input, "group %U %U",
13708                          unformat_ip4_address, &dst.ip4,
13709                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13710         {
13711           grp_set = dst_set = 1;
13712           ipv4_set = 1;
13713         }
13714       else if (unformat (line_input, "group %U",
13715                          unformat_ip4_address, &dst.ip4))
13716         {
13717           grp_set = dst_set = 1;
13718           ipv4_set = 1;
13719         }
13720       else if (unformat (line_input, "group %U %U",
13721                          unformat_ip6_address, &dst.ip6,
13722                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13723         {
13724           grp_set = dst_set = 1;
13725           ipv6_set = 1;
13726         }
13727       else if (unformat (line_input, "group %U",
13728                          unformat_ip6_address, &dst.ip6))
13729         {
13730           grp_set = dst_set = 1;
13731           ipv6_set = 1;
13732         }
13733       else
13734         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13735         ;
13736       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13737         ;
13738       else if (unformat (line_input, "decap-next %U",
13739                          unformat_geneve_decap_next, &decap_next_index))
13740         ;
13741       else if (unformat (line_input, "vni %d", &vni))
13742         ;
13743       else
13744         {
13745           errmsg ("parse error '%U'", format_unformat_error, line_input);
13746           return -99;
13747         }
13748     }
13749
13750   if (src_set == 0)
13751     {
13752       errmsg ("tunnel src address not specified");
13753       return -99;
13754     }
13755   if (dst_set == 0)
13756     {
13757       errmsg ("tunnel dst address not specified");
13758       return -99;
13759     }
13760
13761   if (grp_set && !ip46_address_is_multicast (&dst))
13762     {
13763       errmsg ("tunnel group address not multicast");
13764       return -99;
13765     }
13766   if (grp_set && mcast_sw_if_index == ~0)
13767     {
13768       errmsg ("tunnel nonexistent multicast device");
13769       return -99;
13770     }
13771   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13772     {
13773       errmsg ("tunnel dst address must be unicast");
13774       return -99;
13775     }
13776
13777
13778   if (ipv4_set && ipv6_set)
13779     {
13780       errmsg ("both IPv4 and IPv6 addresses specified");
13781       return -99;
13782     }
13783
13784   if ((vni == 0) || (vni >> 24))
13785     {
13786       errmsg ("vni not specified or out of range");
13787       return -99;
13788     }
13789
13790   M (GENEVE_ADD_DEL_TUNNEL, mp);
13791
13792   if (ipv6_set)
13793     {
13794       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13795       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13796     }
13797   else
13798     {
13799       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13800       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13801     }
13802   mp->encap_vrf_id = ntohl (encap_vrf_id);
13803   mp->decap_next_index = ntohl (decap_next_index);
13804   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13805   mp->vni = ntohl (vni);
13806   mp->is_add = is_add;
13807   mp->is_ipv6 = ipv6_set;
13808
13809   S (mp);
13810   W (ret);
13811   return ret;
13812 }
13813
13814 static void vl_api_geneve_tunnel_details_t_handler
13815   (vl_api_geneve_tunnel_details_t * mp)
13816 {
13817   vat_main_t *vam = &vat_main;
13818   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13819   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13820
13821   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13822          ntohl (mp->sw_if_index),
13823          format_ip46_address, &src, IP46_TYPE_ANY,
13824          format_ip46_address, &dst, IP46_TYPE_ANY,
13825          ntohl (mp->encap_vrf_id),
13826          ntohl (mp->decap_next_index), ntohl (mp->vni),
13827          ntohl (mp->mcast_sw_if_index));
13828 }
13829
13830 static void vl_api_geneve_tunnel_details_t_handler_json
13831   (vl_api_geneve_tunnel_details_t * mp)
13832 {
13833   vat_main_t *vam = &vat_main;
13834   vat_json_node_t *node = NULL;
13835
13836   if (VAT_JSON_ARRAY != vam->json_tree.type)
13837     {
13838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13839       vat_json_init_array (&vam->json_tree);
13840     }
13841   node = vat_json_array_add (&vam->json_tree);
13842
13843   vat_json_init_object (node);
13844   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13845   if (mp->is_ipv6)
13846     {
13847       struct in6_addr ip6;
13848
13849       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13850       vat_json_object_add_ip6 (node, "src_address", ip6);
13851       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13852       vat_json_object_add_ip6 (node, "dst_address", ip6);
13853     }
13854   else
13855     {
13856       struct in_addr ip4;
13857
13858       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13859       vat_json_object_add_ip4 (node, "src_address", ip4);
13860       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13861       vat_json_object_add_ip4 (node, "dst_address", ip4);
13862     }
13863   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13864   vat_json_object_add_uint (node, "decap_next_index",
13865                             ntohl (mp->decap_next_index));
13866   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13867   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13868   vat_json_object_add_uint (node, "mcast_sw_if_index",
13869                             ntohl (mp->mcast_sw_if_index));
13870 }
13871
13872 static int
13873 api_geneve_tunnel_dump (vat_main_t * vam)
13874 {
13875   unformat_input_t *i = vam->input;
13876   vl_api_geneve_tunnel_dump_t *mp;
13877   vl_api_control_ping_t *mp_ping;
13878   u32 sw_if_index;
13879   u8 sw_if_index_set = 0;
13880   int ret;
13881
13882   /* Parse args required to build the message */
13883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13884     {
13885       if (unformat (i, "sw_if_index %d", &sw_if_index))
13886         sw_if_index_set = 1;
13887       else
13888         break;
13889     }
13890
13891   if (sw_if_index_set == 0)
13892     {
13893       sw_if_index = ~0;
13894     }
13895
13896   if (!vam->json_output)
13897     {
13898       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13899              "sw_if_index", "local_address", "remote_address",
13900              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13901     }
13902
13903   /* Get list of geneve-tunnel interfaces */
13904   M (GENEVE_TUNNEL_DUMP, mp);
13905
13906   mp->sw_if_index = htonl (sw_if_index);
13907
13908   S (mp);
13909
13910   /* Use a control ping for synchronization */
13911   M (CONTROL_PING, mp_ping);
13912   S (mp_ping);
13913
13914   W (ret);
13915   return ret;
13916 }
13917
13918 static int
13919 api_gre_add_del_tunnel (vat_main_t * vam)
13920 {
13921   unformat_input_t *line_input = vam->input;
13922   vl_api_gre_add_del_tunnel_t *mp;
13923   ip4_address_t src4, dst4;
13924   ip6_address_t src6, dst6;
13925   u8 is_add = 1;
13926   u8 ipv4_set = 0;
13927   u8 ipv6_set = 0;
13928   u8 t_type = GRE_TUNNEL_TYPE_L3;
13929   u8 src_set = 0;
13930   u8 dst_set = 0;
13931   u32 outer_fib_id = 0;
13932   u32 session_id = 0;
13933   u32 instance = ~0;
13934   int ret;
13935
13936   clib_memset (&src4, 0, sizeof src4);
13937   clib_memset (&dst4, 0, sizeof dst4);
13938   clib_memset (&src6, 0, sizeof src6);
13939   clib_memset (&dst6, 0, sizeof dst6);
13940
13941   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13942     {
13943       if (unformat (line_input, "del"))
13944         is_add = 0;
13945       else if (unformat (line_input, "instance %d", &instance))
13946         ;
13947       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13948         {
13949           src_set = 1;
13950           ipv4_set = 1;
13951         }
13952       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13953         {
13954           dst_set = 1;
13955           ipv4_set = 1;
13956         }
13957       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13958         {
13959           src_set = 1;
13960           ipv6_set = 1;
13961         }
13962       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13963         {
13964           dst_set = 1;
13965           ipv6_set = 1;
13966         }
13967       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13968         ;
13969       else if (unformat (line_input, "teb"))
13970         t_type = GRE_TUNNEL_TYPE_TEB;
13971       else if (unformat (line_input, "erspan %d", &session_id))
13972         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13973       else
13974         {
13975           errmsg ("parse error '%U'", format_unformat_error, line_input);
13976           return -99;
13977         }
13978     }
13979
13980   if (src_set == 0)
13981     {
13982       errmsg ("tunnel src address not specified");
13983       return -99;
13984     }
13985   if (dst_set == 0)
13986     {
13987       errmsg ("tunnel dst address not specified");
13988       return -99;
13989     }
13990   if (ipv4_set && ipv6_set)
13991     {
13992       errmsg ("both IPv4 and IPv6 addresses specified");
13993       return -99;
13994     }
13995
13996
13997   M (GRE_ADD_DEL_TUNNEL, mp);
13998
13999   if (ipv4_set)
14000     {
14001       clib_memcpy (&mp->src_address, &src4, 4);
14002       clib_memcpy (&mp->dst_address, &dst4, 4);
14003     }
14004   else
14005     {
14006       clib_memcpy (&mp->src_address, &src6, 16);
14007       clib_memcpy (&mp->dst_address, &dst6, 16);
14008     }
14009   mp->instance = htonl (instance);
14010   mp->outer_fib_id = htonl (outer_fib_id);
14011   mp->is_add = is_add;
14012   mp->session_id = htons ((u16) session_id);
14013   mp->tunnel_type = t_type;
14014   mp->is_ipv6 = ipv6_set;
14015
14016   S (mp);
14017   W (ret);
14018   return ret;
14019 }
14020
14021 static void vl_api_gre_tunnel_details_t_handler
14022   (vl_api_gre_tunnel_details_t * mp)
14023 {
14024   vat_main_t *vam = &vat_main;
14025   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
14026   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
14027
14028   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
14029          ntohl (mp->sw_if_index),
14030          ntohl (mp->instance),
14031          format_ip46_address, &src, IP46_TYPE_ANY,
14032          format_ip46_address, &dst, IP46_TYPE_ANY,
14033          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
14034 }
14035
14036 static void vl_api_gre_tunnel_details_t_handler_json
14037   (vl_api_gre_tunnel_details_t * mp)
14038 {
14039   vat_main_t *vam = &vat_main;
14040   vat_json_node_t *node = NULL;
14041   struct in_addr ip4;
14042   struct in6_addr ip6;
14043
14044   if (VAT_JSON_ARRAY != vam->json_tree.type)
14045     {
14046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14047       vat_json_init_array (&vam->json_tree);
14048     }
14049   node = vat_json_array_add (&vam->json_tree);
14050
14051   vat_json_init_object (node);
14052   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14053   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
14054   if (!mp->is_ipv6)
14055     {
14056       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14057       vat_json_object_add_ip4 (node, "src_address", ip4);
14058       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14059       vat_json_object_add_ip4 (node, "dst_address", ip4);
14060     }
14061   else
14062     {
14063       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
14064       vat_json_object_add_ip6 (node, "src_address", ip6);
14065       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
14066       vat_json_object_add_ip6 (node, "dst_address", ip6);
14067     }
14068   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
14069   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
14070   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
14071   vat_json_object_add_uint (node, "session_id", mp->session_id);
14072 }
14073
14074 static int
14075 api_gre_tunnel_dump (vat_main_t * vam)
14076 {
14077   unformat_input_t *i = vam->input;
14078   vl_api_gre_tunnel_dump_t *mp;
14079   vl_api_control_ping_t *mp_ping;
14080   u32 sw_if_index;
14081   u8 sw_if_index_set = 0;
14082   int ret;
14083
14084   /* Parse args required to build the message */
14085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14086     {
14087       if (unformat (i, "sw_if_index %d", &sw_if_index))
14088         sw_if_index_set = 1;
14089       else
14090         break;
14091     }
14092
14093   if (sw_if_index_set == 0)
14094     {
14095       sw_if_index = ~0;
14096     }
14097
14098   if (!vam->json_output)
14099     {
14100       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
14101              "sw_if_index", "instance", "src_address", "dst_address",
14102              "tunnel_type", "outer_fib_id", "session_id");
14103     }
14104
14105   /* Get list of gre-tunnel interfaces */
14106   M (GRE_TUNNEL_DUMP, mp);
14107
14108   mp->sw_if_index = htonl (sw_if_index);
14109
14110   S (mp);
14111
14112   /* Use a control ping for synchronization */
14113   MPING (CONTROL_PING, mp_ping);
14114   S (mp_ping);
14115
14116   W (ret);
14117   return ret;
14118 }
14119
14120 static int
14121 api_l2_fib_clear_table (vat_main_t * vam)
14122 {
14123 //  unformat_input_t * i = vam->input;
14124   vl_api_l2_fib_clear_table_t *mp;
14125   int ret;
14126
14127   M (L2_FIB_CLEAR_TABLE, mp);
14128
14129   S (mp);
14130   W (ret);
14131   return ret;
14132 }
14133
14134 static int
14135 api_l2_interface_efp_filter (vat_main_t * vam)
14136 {
14137   unformat_input_t *i = vam->input;
14138   vl_api_l2_interface_efp_filter_t *mp;
14139   u32 sw_if_index;
14140   u8 enable = 1;
14141   u8 sw_if_index_set = 0;
14142   int ret;
14143
14144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14145     {
14146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14147         sw_if_index_set = 1;
14148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14149         sw_if_index_set = 1;
14150       else if (unformat (i, "enable"))
14151         enable = 1;
14152       else if (unformat (i, "disable"))
14153         enable = 0;
14154       else
14155         {
14156           clib_warning ("parse error '%U'", format_unformat_error, i);
14157           return -99;
14158         }
14159     }
14160
14161   if (sw_if_index_set == 0)
14162     {
14163       errmsg ("missing sw_if_index");
14164       return -99;
14165     }
14166
14167   M (L2_INTERFACE_EFP_FILTER, mp);
14168
14169   mp->sw_if_index = ntohl (sw_if_index);
14170   mp->enable_disable = enable;
14171
14172   S (mp);
14173   W (ret);
14174   return ret;
14175 }
14176
14177 #define foreach_vtr_op                          \
14178 _("disable",  L2_VTR_DISABLED)                  \
14179 _("push-1",  L2_VTR_PUSH_1)                     \
14180 _("push-2",  L2_VTR_PUSH_2)                     \
14181 _("pop-1",  L2_VTR_POP_1)                       \
14182 _("pop-2",  L2_VTR_POP_2)                       \
14183 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14184 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14185 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14186 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14187
14188 static int
14189 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14190 {
14191   unformat_input_t *i = vam->input;
14192   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14193   u32 sw_if_index;
14194   u8 sw_if_index_set = 0;
14195   u8 vtr_op_set = 0;
14196   u32 vtr_op = 0;
14197   u32 push_dot1q = 1;
14198   u32 tag1 = ~0;
14199   u32 tag2 = ~0;
14200   int ret;
14201
14202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14203     {
14204       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14205         sw_if_index_set = 1;
14206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14207         sw_if_index_set = 1;
14208       else if (unformat (i, "vtr_op %d", &vtr_op))
14209         vtr_op_set = 1;
14210 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14211       foreach_vtr_op
14212 #undef _
14213         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14214         ;
14215       else if (unformat (i, "tag1 %d", &tag1))
14216         ;
14217       else if (unformat (i, "tag2 %d", &tag2))
14218         ;
14219       else
14220         {
14221           clib_warning ("parse error '%U'", format_unformat_error, i);
14222           return -99;
14223         }
14224     }
14225
14226   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14227     {
14228       errmsg ("missing vtr operation or sw_if_index");
14229       return -99;
14230     }
14231
14232   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14233   mp->sw_if_index = ntohl (sw_if_index);
14234   mp->vtr_op = ntohl (vtr_op);
14235   mp->push_dot1q = ntohl (push_dot1q);
14236   mp->tag1 = ntohl (tag1);
14237   mp->tag2 = ntohl (tag2);
14238
14239   S (mp);
14240   W (ret);
14241   return ret;
14242 }
14243
14244 static int
14245 api_create_vhost_user_if (vat_main_t * vam)
14246 {
14247   unformat_input_t *i = vam->input;
14248   vl_api_create_vhost_user_if_t *mp;
14249   u8 *file_name;
14250   u8 is_server = 0;
14251   u8 file_name_set = 0;
14252   u32 custom_dev_instance = ~0;
14253   u8 hwaddr[6];
14254   u8 use_custom_mac = 0;
14255   u8 disable_mrg_rxbuf = 0;
14256   u8 disable_indirect_desc = 0;
14257   u8 *tag = 0;
14258   int ret;
14259
14260   /* Shut up coverity */
14261   clib_memset (hwaddr, 0, sizeof (hwaddr));
14262
14263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14264     {
14265       if (unformat (i, "socket %s", &file_name))
14266         {
14267           file_name_set = 1;
14268         }
14269       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14270         ;
14271       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14272         use_custom_mac = 1;
14273       else if (unformat (i, "server"))
14274         is_server = 1;
14275       else if (unformat (i, "disable_mrg_rxbuf"))
14276         disable_mrg_rxbuf = 1;
14277       else if (unformat (i, "disable_indirect_desc"))
14278         disable_indirect_desc = 1;
14279       else if (unformat (i, "tag %s", &tag))
14280         ;
14281       else
14282         break;
14283     }
14284
14285   if (file_name_set == 0)
14286     {
14287       errmsg ("missing socket file name");
14288       return -99;
14289     }
14290
14291   if (vec_len (file_name) > 255)
14292     {
14293       errmsg ("socket file name too long");
14294       return -99;
14295     }
14296   vec_add1 (file_name, 0);
14297
14298   M (CREATE_VHOST_USER_IF, mp);
14299
14300   mp->is_server = is_server;
14301   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14302   mp->disable_indirect_desc = disable_indirect_desc;
14303   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14304   vec_free (file_name);
14305   if (custom_dev_instance != ~0)
14306     {
14307       mp->renumber = 1;
14308       mp->custom_dev_instance = ntohl (custom_dev_instance);
14309     }
14310
14311   mp->use_custom_mac = use_custom_mac;
14312   clib_memcpy (mp->mac_address, hwaddr, 6);
14313   if (tag)
14314     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14315   vec_free (tag);
14316
14317   S (mp);
14318   W (ret);
14319   return ret;
14320 }
14321
14322 static int
14323 api_modify_vhost_user_if (vat_main_t * vam)
14324 {
14325   unformat_input_t *i = vam->input;
14326   vl_api_modify_vhost_user_if_t *mp;
14327   u8 *file_name;
14328   u8 is_server = 0;
14329   u8 file_name_set = 0;
14330   u32 custom_dev_instance = ~0;
14331   u8 sw_if_index_set = 0;
14332   u32 sw_if_index = (u32) ~ 0;
14333   int ret;
14334
14335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14336     {
14337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14338         sw_if_index_set = 1;
14339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14340         sw_if_index_set = 1;
14341       else if (unformat (i, "socket %s", &file_name))
14342         {
14343           file_name_set = 1;
14344         }
14345       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14346         ;
14347       else if (unformat (i, "server"))
14348         is_server = 1;
14349       else
14350         break;
14351     }
14352
14353   if (sw_if_index_set == 0)
14354     {
14355       errmsg ("missing sw_if_index or interface name");
14356       return -99;
14357     }
14358
14359   if (file_name_set == 0)
14360     {
14361       errmsg ("missing socket file name");
14362       return -99;
14363     }
14364
14365   if (vec_len (file_name) > 255)
14366     {
14367       errmsg ("socket file name too long");
14368       return -99;
14369     }
14370   vec_add1 (file_name, 0);
14371
14372   M (MODIFY_VHOST_USER_IF, mp);
14373
14374   mp->sw_if_index = ntohl (sw_if_index);
14375   mp->is_server = is_server;
14376   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14377   vec_free (file_name);
14378   if (custom_dev_instance != ~0)
14379     {
14380       mp->renumber = 1;
14381       mp->custom_dev_instance = ntohl (custom_dev_instance);
14382     }
14383
14384   S (mp);
14385   W (ret);
14386   return ret;
14387 }
14388
14389 static int
14390 api_delete_vhost_user_if (vat_main_t * vam)
14391 {
14392   unformat_input_t *i = vam->input;
14393   vl_api_delete_vhost_user_if_t *mp;
14394   u32 sw_if_index = ~0;
14395   u8 sw_if_index_set = 0;
14396   int ret;
14397
14398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14399     {
14400       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14401         sw_if_index_set = 1;
14402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14403         sw_if_index_set = 1;
14404       else
14405         break;
14406     }
14407
14408   if (sw_if_index_set == 0)
14409     {
14410       errmsg ("missing sw_if_index or interface name");
14411       return -99;
14412     }
14413
14414
14415   M (DELETE_VHOST_USER_IF, mp);
14416
14417   mp->sw_if_index = ntohl (sw_if_index);
14418
14419   S (mp);
14420   W (ret);
14421   return ret;
14422 }
14423
14424 static void vl_api_sw_interface_vhost_user_details_t_handler
14425   (vl_api_sw_interface_vhost_user_details_t * mp)
14426 {
14427   vat_main_t *vam = &vat_main;
14428
14429   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14430          (char *) mp->interface_name,
14431          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14432          clib_net_to_host_u64 (mp->features), mp->is_server,
14433          ntohl (mp->num_regions), (char *) mp->sock_filename);
14434   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14435 }
14436
14437 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14438   (vl_api_sw_interface_vhost_user_details_t * mp)
14439 {
14440   vat_main_t *vam = &vat_main;
14441   vat_json_node_t *node = NULL;
14442
14443   if (VAT_JSON_ARRAY != vam->json_tree.type)
14444     {
14445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14446       vat_json_init_array (&vam->json_tree);
14447     }
14448   node = vat_json_array_add (&vam->json_tree);
14449
14450   vat_json_init_object (node);
14451   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14452   vat_json_object_add_string_copy (node, "interface_name",
14453                                    mp->interface_name);
14454   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14455                             ntohl (mp->virtio_net_hdr_sz));
14456   vat_json_object_add_uint (node, "features",
14457                             clib_net_to_host_u64 (mp->features));
14458   vat_json_object_add_uint (node, "is_server", mp->is_server);
14459   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14460   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14461   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14462 }
14463
14464 static int
14465 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14466 {
14467   vl_api_sw_interface_vhost_user_dump_t *mp;
14468   vl_api_control_ping_t *mp_ping;
14469   int ret;
14470   print (vam->ofp,
14471          "Interface name            idx hdr_sz features server regions filename");
14472
14473   /* Get list of vhost-user interfaces */
14474   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14475   S (mp);
14476
14477   /* Use a control ping for synchronization */
14478   MPING (CONTROL_PING, mp_ping);
14479   S (mp_ping);
14480
14481   W (ret);
14482   return ret;
14483 }
14484
14485 static int
14486 api_show_version (vat_main_t * vam)
14487 {
14488   vl_api_show_version_t *mp;
14489   int ret;
14490
14491   M (SHOW_VERSION, mp);
14492
14493   S (mp);
14494   W (ret);
14495   return ret;
14496 }
14497
14498
14499 static int
14500 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14501 {
14502   unformat_input_t *line_input = vam->input;
14503   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14504   ip4_address_t local4, remote4;
14505   ip6_address_t local6, remote6;
14506   u8 is_add = 1;
14507   u8 ipv4_set = 0, ipv6_set = 0;
14508   u8 local_set = 0;
14509   u8 remote_set = 0;
14510   u8 grp_set = 0;
14511   u32 mcast_sw_if_index = ~0;
14512   u32 encap_vrf_id = 0;
14513   u32 decap_vrf_id = 0;
14514   u8 protocol = ~0;
14515   u32 vni;
14516   u8 vni_set = 0;
14517   int ret;
14518
14519   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14520   clib_memset (&local4, 0, sizeof local4);
14521   clib_memset (&remote4, 0, sizeof remote4);
14522   clib_memset (&local6, 0, sizeof local6);
14523   clib_memset (&remote6, 0, sizeof remote6);
14524
14525   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14526     {
14527       if (unformat (line_input, "del"))
14528         is_add = 0;
14529       else if (unformat (line_input, "local %U",
14530                          unformat_ip4_address, &local4))
14531         {
14532           local_set = 1;
14533           ipv4_set = 1;
14534         }
14535       else if (unformat (line_input, "remote %U",
14536                          unformat_ip4_address, &remote4))
14537         {
14538           remote_set = 1;
14539           ipv4_set = 1;
14540         }
14541       else if (unformat (line_input, "local %U",
14542                          unformat_ip6_address, &local6))
14543         {
14544           local_set = 1;
14545           ipv6_set = 1;
14546         }
14547       else if (unformat (line_input, "remote %U",
14548                          unformat_ip6_address, &remote6))
14549         {
14550           remote_set = 1;
14551           ipv6_set = 1;
14552         }
14553       else if (unformat (line_input, "group %U %U",
14554                          unformat_ip4_address, &remote4,
14555                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14556         {
14557           grp_set = remote_set = 1;
14558           ipv4_set = 1;
14559         }
14560       else if (unformat (line_input, "group %U",
14561                          unformat_ip4_address, &remote4))
14562         {
14563           grp_set = remote_set = 1;
14564           ipv4_set = 1;
14565         }
14566       else if (unformat (line_input, "group %U %U",
14567                          unformat_ip6_address, &remote6,
14568                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14569         {
14570           grp_set = remote_set = 1;
14571           ipv6_set = 1;
14572         }
14573       else if (unformat (line_input, "group %U",
14574                          unformat_ip6_address, &remote6))
14575         {
14576           grp_set = remote_set = 1;
14577           ipv6_set = 1;
14578         }
14579       else
14580         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14581         ;
14582       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14583         ;
14584       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14585         ;
14586       else if (unformat (line_input, "vni %d", &vni))
14587         vni_set = 1;
14588       else if (unformat (line_input, "next-ip4"))
14589         protocol = 1;
14590       else if (unformat (line_input, "next-ip6"))
14591         protocol = 2;
14592       else if (unformat (line_input, "next-ethernet"))
14593         protocol = 3;
14594       else if (unformat (line_input, "next-nsh"))
14595         protocol = 4;
14596       else
14597         {
14598           errmsg ("parse error '%U'", format_unformat_error, line_input);
14599           return -99;
14600         }
14601     }
14602
14603   if (local_set == 0)
14604     {
14605       errmsg ("tunnel local address not specified");
14606       return -99;
14607     }
14608   if (remote_set == 0)
14609     {
14610       errmsg ("tunnel remote address not specified");
14611       return -99;
14612     }
14613   if (grp_set && mcast_sw_if_index == ~0)
14614     {
14615       errmsg ("tunnel nonexistent multicast device");
14616       return -99;
14617     }
14618   if (ipv4_set && ipv6_set)
14619     {
14620       errmsg ("both IPv4 and IPv6 addresses specified");
14621       return -99;
14622     }
14623
14624   if (vni_set == 0)
14625     {
14626       errmsg ("vni not specified");
14627       return -99;
14628     }
14629
14630   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14631
14632
14633   if (ipv6_set)
14634     {
14635       clib_memcpy (&mp->local, &local6, sizeof (local6));
14636       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14637     }
14638   else
14639     {
14640       clib_memcpy (&mp->local, &local4, sizeof (local4));
14641       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14642     }
14643
14644   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14645   mp->encap_vrf_id = ntohl (encap_vrf_id);
14646   mp->decap_vrf_id = ntohl (decap_vrf_id);
14647   mp->protocol = protocol;
14648   mp->vni = ntohl (vni);
14649   mp->is_add = is_add;
14650   mp->is_ipv6 = ipv6_set;
14651
14652   S (mp);
14653   W (ret);
14654   return ret;
14655 }
14656
14657 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14658   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14659 {
14660   vat_main_t *vam = &vat_main;
14661   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14662   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14663
14664   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14665          ntohl (mp->sw_if_index),
14666          format_ip46_address, &local, IP46_TYPE_ANY,
14667          format_ip46_address, &remote, IP46_TYPE_ANY,
14668          ntohl (mp->vni), mp->protocol,
14669          ntohl (mp->mcast_sw_if_index),
14670          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14671 }
14672
14673
14674 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14675   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14676 {
14677   vat_main_t *vam = &vat_main;
14678   vat_json_node_t *node = NULL;
14679   struct in_addr ip4;
14680   struct in6_addr ip6;
14681
14682   if (VAT_JSON_ARRAY != vam->json_tree.type)
14683     {
14684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14685       vat_json_init_array (&vam->json_tree);
14686     }
14687   node = vat_json_array_add (&vam->json_tree);
14688
14689   vat_json_init_object (node);
14690   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14691   if (mp->is_ipv6)
14692     {
14693       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14694       vat_json_object_add_ip6 (node, "local", ip6);
14695       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14696       vat_json_object_add_ip6 (node, "remote", ip6);
14697     }
14698   else
14699     {
14700       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14701       vat_json_object_add_ip4 (node, "local", ip4);
14702       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14703       vat_json_object_add_ip4 (node, "remote", ip4);
14704     }
14705   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14706   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14707   vat_json_object_add_uint (node, "mcast_sw_if_index",
14708                             ntohl (mp->mcast_sw_if_index));
14709   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14710   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14711   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14712 }
14713
14714 static int
14715 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14716 {
14717   unformat_input_t *i = vam->input;
14718   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14719   vl_api_control_ping_t *mp_ping;
14720   u32 sw_if_index;
14721   u8 sw_if_index_set = 0;
14722   int ret;
14723
14724   /* Parse args required to build the message */
14725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14726     {
14727       if (unformat (i, "sw_if_index %d", &sw_if_index))
14728         sw_if_index_set = 1;
14729       else
14730         break;
14731     }
14732
14733   if (sw_if_index_set == 0)
14734     {
14735       sw_if_index = ~0;
14736     }
14737
14738   if (!vam->json_output)
14739     {
14740       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14741              "sw_if_index", "local", "remote", "vni",
14742              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14743     }
14744
14745   /* Get list of vxlan-tunnel interfaces */
14746   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14747
14748   mp->sw_if_index = htonl (sw_if_index);
14749
14750   S (mp);
14751
14752   /* Use a control ping for synchronization */
14753   MPING (CONTROL_PING, mp_ping);
14754   S (mp_ping);
14755
14756   W (ret);
14757   return ret;
14758 }
14759
14760 static void vl_api_l2_fib_table_details_t_handler
14761   (vl_api_l2_fib_table_details_t * mp)
14762 {
14763   vat_main_t *vam = &vat_main;
14764
14765   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14766          "       %d       %d     %d",
14767          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14768          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14769          mp->bvi_mac);
14770 }
14771
14772 static void vl_api_l2_fib_table_details_t_handler_json
14773   (vl_api_l2_fib_table_details_t * mp)
14774 {
14775   vat_main_t *vam = &vat_main;
14776   vat_json_node_t *node = NULL;
14777
14778   if (VAT_JSON_ARRAY != vam->json_tree.type)
14779     {
14780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14781       vat_json_init_array (&vam->json_tree);
14782     }
14783   node = vat_json_array_add (&vam->json_tree);
14784
14785   vat_json_init_object (node);
14786   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14787   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14788   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14789   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14790   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14791   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14792 }
14793
14794 static int
14795 api_l2_fib_table_dump (vat_main_t * vam)
14796 {
14797   unformat_input_t *i = vam->input;
14798   vl_api_l2_fib_table_dump_t *mp;
14799   vl_api_control_ping_t *mp_ping;
14800   u32 bd_id;
14801   u8 bd_id_set = 0;
14802   int ret;
14803
14804   /* Parse args required to build the message */
14805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14806     {
14807       if (unformat (i, "bd_id %d", &bd_id))
14808         bd_id_set = 1;
14809       else
14810         break;
14811     }
14812
14813   if (bd_id_set == 0)
14814     {
14815       errmsg ("missing bridge domain");
14816       return -99;
14817     }
14818
14819   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14820
14821   /* Get list of l2 fib entries */
14822   M (L2_FIB_TABLE_DUMP, mp);
14823
14824   mp->bd_id = ntohl (bd_id);
14825   S (mp);
14826
14827   /* Use a control ping for synchronization */
14828   MPING (CONTROL_PING, mp_ping);
14829   S (mp_ping);
14830
14831   W (ret);
14832   return ret;
14833 }
14834
14835
14836 static int
14837 api_interface_name_renumber (vat_main_t * vam)
14838 {
14839   unformat_input_t *line_input = vam->input;
14840   vl_api_interface_name_renumber_t *mp;
14841   u32 sw_if_index = ~0;
14842   u32 new_show_dev_instance = ~0;
14843   int ret;
14844
14845   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14846     {
14847       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14848                     &sw_if_index))
14849         ;
14850       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14851         ;
14852       else if (unformat (line_input, "new_show_dev_instance %d",
14853                          &new_show_dev_instance))
14854         ;
14855       else
14856         break;
14857     }
14858
14859   if (sw_if_index == ~0)
14860     {
14861       errmsg ("missing interface name or sw_if_index");
14862       return -99;
14863     }
14864
14865   if (new_show_dev_instance == ~0)
14866     {
14867       errmsg ("missing new_show_dev_instance");
14868       return -99;
14869     }
14870
14871   M (INTERFACE_NAME_RENUMBER, mp);
14872
14873   mp->sw_if_index = ntohl (sw_if_index);
14874   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14875
14876   S (mp);
14877   W (ret);
14878   return ret;
14879 }
14880
14881 static int
14882 api_ip_probe_neighbor (vat_main_t * vam)
14883 {
14884   unformat_input_t *i = vam->input;
14885   vl_api_ip_probe_neighbor_t *mp;
14886   u8 int_set = 0;
14887   u8 adr_set = 0;
14888   u8 is_ipv6 = 0;
14889   u8 dst_adr[16];
14890   u32 sw_if_index;
14891   int ret;
14892
14893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14894     {
14895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14896         int_set = 1;
14897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14898         int_set = 1;
14899       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14900         adr_set = 1;
14901       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14902         {
14903           adr_set = 1;
14904           is_ipv6 = 1;
14905         }
14906       else
14907         break;
14908     }
14909
14910   if (int_set == 0)
14911     {
14912       errmsg ("missing interface");
14913       return -99;
14914     }
14915
14916   if (adr_set == 0)
14917     {
14918       errmsg ("missing addresses");
14919       return -99;
14920     }
14921
14922   M (IP_PROBE_NEIGHBOR, mp);
14923
14924   mp->sw_if_index = ntohl (sw_if_index);
14925   mp->is_ipv6 = is_ipv6;
14926   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14927
14928   S (mp);
14929   W (ret);
14930   return ret;
14931 }
14932
14933 static int
14934 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14935 {
14936   unformat_input_t *i = vam->input;
14937   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14938   u8 mode = IP_SCAN_V46_NEIGHBORS;
14939   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14940   int ret;
14941
14942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14943     {
14944       if (unformat (i, "ip4"))
14945         mode = IP_SCAN_V4_NEIGHBORS;
14946       else if (unformat (i, "ip6"))
14947         mode = IP_SCAN_V6_NEIGHBORS;
14948       if (unformat (i, "both"))
14949         mode = IP_SCAN_V46_NEIGHBORS;
14950       else if (unformat (i, "disable"))
14951         mode = IP_SCAN_DISABLED;
14952       else if (unformat (i, "interval %d", &interval))
14953         ;
14954       else if (unformat (i, "max-time %d", &time))
14955         ;
14956       else if (unformat (i, "max-update %d", &update))
14957         ;
14958       else if (unformat (i, "delay %d", &delay))
14959         ;
14960       else if (unformat (i, "stale %d", &stale))
14961         ;
14962       else
14963         break;
14964     }
14965
14966   if (interval > 255)
14967     {
14968       errmsg ("interval cannot exceed 255 minutes.");
14969       return -99;
14970     }
14971   if (time > 255)
14972     {
14973       errmsg ("max-time cannot exceed 255 usec.");
14974       return -99;
14975     }
14976   if (update > 255)
14977     {
14978       errmsg ("max-update cannot exceed 255.");
14979       return -99;
14980     }
14981   if (delay > 255)
14982     {
14983       errmsg ("delay cannot exceed 255 msec.");
14984       return -99;
14985     }
14986   if (stale > 255)
14987     {
14988       errmsg ("stale cannot exceed 255 minutes.");
14989       return -99;
14990     }
14991
14992   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14993   mp->mode = mode;
14994   mp->scan_interval = interval;
14995   mp->max_proc_time = time;
14996   mp->max_update = update;
14997   mp->scan_int_delay = delay;
14998   mp->stale_threshold = stale;
14999
15000   S (mp);
15001   W (ret);
15002   return ret;
15003 }
15004
15005 static int
15006 api_want_ip4_arp_events (vat_main_t * vam)
15007 {
15008   unformat_input_t *line_input = vam->input;
15009   vl_api_want_ip4_arp_events_t *mp;
15010   ip4_address_t address;
15011   int address_set = 0;
15012   u32 enable_disable = 1;
15013   int ret;
15014
15015   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15016     {
15017       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
15018         address_set = 1;
15019       else if (unformat (line_input, "del"))
15020         enable_disable = 0;
15021       else
15022         break;
15023     }
15024
15025   if (address_set == 0)
15026     {
15027       errmsg ("missing addresses");
15028       return -99;
15029     }
15030
15031   M (WANT_IP4_ARP_EVENTS, mp);
15032   mp->enable_disable = enable_disable;
15033   mp->pid = htonl (getpid ());
15034   mp->address = address.as_u32;
15035
15036   S (mp);
15037   W (ret);
15038   return ret;
15039 }
15040
15041 static int
15042 api_want_ip6_nd_events (vat_main_t * vam)
15043 {
15044   unformat_input_t *line_input = vam->input;
15045   vl_api_want_ip6_nd_events_t *mp;
15046   ip6_address_t address;
15047   int address_set = 0;
15048   u32 enable_disable = 1;
15049   int ret;
15050
15051   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15052     {
15053       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
15054         address_set = 1;
15055       else if (unformat (line_input, "del"))
15056         enable_disable = 0;
15057       else
15058         break;
15059     }
15060
15061   if (address_set == 0)
15062     {
15063       errmsg ("missing addresses");
15064       return -99;
15065     }
15066
15067   M (WANT_IP6_ND_EVENTS, mp);
15068   mp->enable_disable = enable_disable;
15069   mp->pid = htonl (getpid ());
15070   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
15071
15072   S (mp);
15073   W (ret);
15074   return ret;
15075 }
15076
15077 static int
15078 api_want_l2_macs_events (vat_main_t * vam)
15079 {
15080   unformat_input_t *line_input = vam->input;
15081   vl_api_want_l2_macs_events_t *mp;
15082   u8 enable_disable = 1;
15083   u32 scan_delay = 0;
15084   u32 max_macs_in_event = 0;
15085   u32 learn_limit = 0;
15086   int ret;
15087
15088   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15089     {
15090       if (unformat (line_input, "learn-limit %d", &learn_limit))
15091         ;
15092       else if (unformat (line_input, "scan-delay %d", &scan_delay))
15093         ;
15094       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
15095         ;
15096       else if (unformat (line_input, "disable"))
15097         enable_disable = 0;
15098       else
15099         break;
15100     }
15101
15102   M (WANT_L2_MACS_EVENTS, mp);
15103   mp->enable_disable = enable_disable;
15104   mp->pid = htonl (getpid ());
15105   mp->learn_limit = htonl (learn_limit);
15106   mp->scan_delay = (u8) scan_delay;
15107   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15108   S (mp);
15109   W (ret);
15110   return ret;
15111 }
15112
15113 static int
15114 api_input_acl_set_interface (vat_main_t * vam)
15115 {
15116   unformat_input_t *i = vam->input;
15117   vl_api_input_acl_set_interface_t *mp;
15118   u32 sw_if_index;
15119   int sw_if_index_set;
15120   u32 ip4_table_index = ~0;
15121   u32 ip6_table_index = ~0;
15122   u32 l2_table_index = ~0;
15123   u8 is_add = 1;
15124   int ret;
15125
15126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15127     {
15128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15129         sw_if_index_set = 1;
15130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15131         sw_if_index_set = 1;
15132       else if (unformat (i, "del"))
15133         is_add = 0;
15134       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15135         ;
15136       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15137         ;
15138       else if (unformat (i, "l2-table %d", &l2_table_index))
15139         ;
15140       else
15141         {
15142           clib_warning ("parse error '%U'", format_unformat_error, i);
15143           return -99;
15144         }
15145     }
15146
15147   if (sw_if_index_set == 0)
15148     {
15149       errmsg ("missing interface name or sw_if_index");
15150       return -99;
15151     }
15152
15153   M (INPUT_ACL_SET_INTERFACE, mp);
15154
15155   mp->sw_if_index = ntohl (sw_if_index);
15156   mp->ip4_table_index = ntohl (ip4_table_index);
15157   mp->ip6_table_index = ntohl (ip6_table_index);
15158   mp->l2_table_index = ntohl (l2_table_index);
15159   mp->is_add = is_add;
15160
15161   S (mp);
15162   W (ret);
15163   return ret;
15164 }
15165
15166 static int
15167 api_output_acl_set_interface (vat_main_t * vam)
15168 {
15169   unformat_input_t *i = vam->input;
15170   vl_api_output_acl_set_interface_t *mp;
15171   u32 sw_if_index;
15172   int sw_if_index_set;
15173   u32 ip4_table_index = ~0;
15174   u32 ip6_table_index = ~0;
15175   u32 l2_table_index = ~0;
15176   u8 is_add = 1;
15177   int ret;
15178
15179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15180     {
15181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15182         sw_if_index_set = 1;
15183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15184         sw_if_index_set = 1;
15185       else if (unformat (i, "del"))
15186         is_add = 0;
15187       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15188         ;
15189       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15190         ;
15191       else if (unformat (i, "l2-table %d", &l2_table_index))
15192         ;
15193       else
15194         {
15195           clib_warning ("parse error '%U'", format_unformat_error, i);
15196           return -99;
15197         }
15198     }
15199
15200   if (sw_if_index_set == 0)
15201     {
15202       errmsg ("missing interface name or sw_if_index");
15203       return -99;
15204     }
15205
15206   M (OUTPUT_ACL_SET_INTERFACE, mp);
15207
15208   mp->sw_if_index = ntohl (sw_if_index);
15209   mp->ip4_table_index = ntohl (ip4_table_index);
15210   mp->ip6_table_index = ntohl (ip6_table_index);
15211   mp->l2_table_index = ntohl (l2_table_index);
15212   mp->is_add = is_add;
15213
15214   S (mp);
15215   W (ret);
15216   return ret;
15217 }
15218
15219 static int
15220 api_ip_address_dump (vat_main_t * vam)
15221 {
15222   unformat_input_t *i = vam->input;
15223   vl_api_ip_address_dump_t *mp;
15224   vl_api_control_ping_t *mp_ping;
15225   u32 sw_if_index = ~0;
15226   u8 sw_if_index_set = 0;
15227   u8 ipv4_set = 0;
15228   u8 ipv6_set = 0;
15229   int ret;
15230
15231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15232     {
15233       if (unformat (i, "sw_if_index %d", &sw_if_index))
15234         sw_if_index_set = 1;
15235       else
15236         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15237         sw_if_index_set = 1;
15238       else if (unformat (i, "ipv4"))
15239         ipv4_set = 1;
15240       else if (unformat (i, "ipv6"))
15241         ipv6_set = 1;
15242       else
15243         break;
15244     }
15245
15246   if (ipv4_set && ipv6_set)
15247     {
15248       errmsg ("ipv4 and ipv6 flags cannot be both set");
15249       return -99;
15250     }
15251
15252   if ((!ipv4_set) && (!ipv6_set))
15253     {
15254       errmsg ("no ipv4 nor ipv6 flag set");
15255       return -99;
15256     }
15257
15258   if (sw_if_index_set == 0)
15259     {
15260       errmsg ("missing interface name or sw_if_index");
15261       return -99;
15262     }
15263
15264   vam->current_sw_if_index = sw_if_index;
15265   vam->is_ipv6 = ipv6_set;
15266
15267   M (IP_ADDRESS_DUMP, mp);
15268   mp->sw_if_index = ntohl (sw_if_index);
15269   mp->is_ipv6 = ipv6_set;
15270   S (mp);
15271
15272   /* Use a control ping for synchronization */
15273   MPING (CONTROL_PING, mp_ping);
15274   S (mp_ping);
15275
15276   W (ret);
15277   return ret;
15278 }
15279
15280 static int
15281 api_ip_dump (vat_main_t * vam)
15282 {
15283   vl_api_ip_dump_t *mp;
15284   vl_api_control_ping_t *mp_ping;
15285   unformat_input_t *in = vam->input;
15286   int ipv4_set = 0;
15287   int ipv6_set = 0;
15288   int is_ipv6;
15289   int i;
15290   int ret;
15291
15292   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15293     {
15294       if (unformat (in, "ipv4"))
15295         ipv4_set = 1;
15296       else if (unformat (in, "ipv6"))
15297         ipv6_set = 1;
15298       else
15299         break;
15300     }
15301
15302   if (ipv4_set && ipv6_set)
15303     {
15304       errmsg ("ipv4 and ipv6 flags cannot be both set");
15305       return -99;
15306     }
15307
15308   if ((!ipv4_set) && (!ipv6_set))
15309     {
15310       errmsg ("no ipv4 nor ipv6 flag set");
15311       return -99;
15312     }
15313
15314   is_ipv6 = ipv6_set;
15315   vam->is_ipv6 = is_ipv6;
15316
15317   /* free old data */
15318   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15319     {
15320       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15321     }
15322   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15323
15324   M (IP_DUMP, mp);
15325   mp->is_ipv6 = ipv6_set;
15326   S (mp);
15327
15328   /* Use a control ping for synchronization */
15329   MPING (CONTROL_PING, mp_ping);
15330   S (mp_ping);
15331
15332   W (ret);
15333   return ret;
15334 }
15335
15336 static int
15337 api_ipsec_spd_add_del (vat_main_t * vam)
15338 {
15339   unformat_input_t *i = vam->input;
15340   vl_api_ipsec_spd_add_del_t *mp;
15341   u32 spd_id = ~0;
15342   u8 is_add = 1;
15343   int ret;
15344
15345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15346     {
15347       if (unformat (i, "spd_id %d", &spd_id))
15348         ;
15349       else if (unformat (i, "del"))
15350         is_add = 0;
15351       else
15352         {
15353           clib_warning ("parse error '%U'", format_unformat_error, i);
15354           return -99;
15355         }
15356     }
15357   if (spd_id == ~0)
15358     {
15359       errmsg ("spd_id must be set");
15360       return -99;
15361     }
15362
15363   M (IPSEC_SPD_ADD_DEL, mp);
15364
15365   mp->spd_id = ntohl (spd_id);
15366   mp->is_add = is_add;
15367
15368   S (mp);
15369   W (ret);
15370   return ret;
15371 }
15372
15373 static int
15374 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15375 {
15376   unformat_input_t *i = vam->input;
15377   vl_api_ipsec_interface_add_del_spd_t *mp;
15378   u32 sw_if_index;
15379   u8 sw_if_index_set = 0;
15380   u32 spd_id = (u32) ~ 0;
15381   u8 is_add = 1;
15382   int ret;
15383
15384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15385     {
15386       if (unformat (i, "del"))
15387         is_add = 0;
15388       else if (unformat (i, "spd_id %d", &spd_id))
15389         ;
15390       else
15391         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15392         sw_if_index_set = 1;
15393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15394         sw_if_index_set = 1;
15395       else
15396         {
15397           clib_warning ("parse error '%U'", format_unformat_error, i);
15398           return -99;
15399         }
15400
15401     }
15402
15403   if (spd_id == (u32) ~ 0)
15404     {
15405       errmsg ("spd_id must be set");
15406       return -99;
15407     }
15408
15409   if (sw_if_index_set == 0)
15410     {
15411       errmsg ("missing interface name or sw_if_index");
15412       return -99;
15413     }
15414
15415   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15416
15417   mp->spd_id = ntohl (spd_id);
15418   mp->sw_if_index = ntohl (sw_if_index);
15419   mp->is_add = is_add;
15420
15421   S (mp);
15422   W (ret);
15423   return ret;
15424 }
15425
15426 static int
15427 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15428 {
15429   unformat_input_t *i = vam->input;
15430   vl_api_ipsec_spd_add_del_entry_t *mp;
15431   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15432   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15433   i32 priority = 0;
15434   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15435   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15436   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15437   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15438   int ret;
15439
15440   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15441   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15442   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15443   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15444   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15445   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15446
15447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15448     {
15449       if (unformat (i, "del"))
15450         is_add = 0;
15451       if (unformat (i, "outbound"))
15452         is_outbound = 1;
15453       if (unformat (i, "inbound"))
15454         is_outbound = 0;
15455       else if (unformat (i, "spd_id %d", &spd_id))
15456         ;
15457       else if (unformat (i, "sa_id %d", &sa_id))
15458         ;
15459       else if (unformat (i, "priority %d", &priority))
15460         ;
15461       else if (unformat (i, "protocol %d", &protocol))
15462         ;
15463       else if (unformat (i, "lport_start %d", &lport_start))
15464         ;
15465       else if (unformat (i, "lport_stop %d", &lport_stop))
15466         ;
15467       else if (unformat (i, "rport_start %d", &rport_start))
15468         ;
15469       else if (unformat (i, "rport_stop %d", &rport_stop))
15470         ;
15471       else
15472         if (unformat
15473             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15474         {
15475           is_ipv6 = 0;
15476           is_ip_any = 0;
15477         }
15478       else
15479         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15480         {
15481           is_ipv6 = 0;
15482           is_ip_any = 0;
15483         }
15484       else
15485         if (unformat
15486             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15487         {
15488           is_ipv6 = 0;
15489           is_ip_any = 0;
15490         }
15491       else
15492         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15493         {
15494           is_ipv6 = 0;
15495           is_ip_any = 0;
15496         }
15497       else
15498         if (unformat
15499             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15500         {
15501           is_ipv6 = 1;
15502           is_ip_any = 0;
15503         }
15504       else
15505         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15506         {
15507           is_ipv6 = 1;
15508           is_ip_any = 0;
15509         }
15510       else
15511         if (unformat
15512             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15513         {
15514           is_ipv6 = 1;
15515           is_ip_any = 0;
15516         }
15517       else
15518         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15519         {
15520           is_ipv6 = 1;
15521           is_ip_any = 0;
15522         }
15523       else
15524         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15525         {
15526           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15527             {
15528               clib_warning ("unsupported action: 'resolve'");
15529               return -99;
15530             }
15531         }
15532       else
15533         {
15534           clib_warning ("parse error '%U'", format_unformat_error, i);
15535           return -99;
15536         }
15537
15538     }
15539
15540   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15541
15542   mp->spd_id = ntohl (spd_id);
15543   mp->priority = ntohl (priority);
15544   mp->is_outbound = is_outbound;
15545
15546   mp->is_ipv6 = is_ipv6;
15547   if (is_ipv6 || is_ip_any)
15548     {
15549       clib_memcpy (mp->remote_address_start, &raddr6_start,
15550                    sizeof (ip6_address_t));
15551       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15552                    sizeof (ip6_address_t));
15553       clib_memcpy (mp->local_address_start, &laddr6_start,
15554                    sizeof (ip6_address_t));
15555       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15556                    sizeof (ip6_address_t));
15557     }
15558   else
15559     {
15560       clib_memcpy (mp->remote_address_start, &raddr4_start,
15561                    sizeof (ip4_address_t));
15562       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15563                    sizeof (ip4_address_t));
15564       clib_memcpy (mp->local_address_start, &laddr4_start,
15565                    sizeof (ip4_address_t));
15566       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15567                    sizeof (ip4_address_t));
15568     }
15569   mp->protocol = (u8) protocol;
15570   mp->local_port_start = ntohs ((u16) lport_start);
15571   mp->local_port_stop = ntohs ((u16) lport_stop);
15572   mp->remote_port_start = ntohs ((u16) rport_start);
15573   mp->remote_port_stop = ntohs ((u16) rport_stop);
15574   mp->policy = (u8) policy;
15575   mp->sa_id = ntohl (sa_id);
15576   mp->is_add = is_add;
15577   mp->is_ip_any = is_ip_any;
15578   S (mp);
15579   W (ret);
15580   return ret;
15581 }
15582
15583 static int
15584 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15585 {
15586   unformat_input_t *i = vam->input;
15587   vl_api_ipsec_sad_add_del_entry_t *mp;
15588   u32 sad_id = 0, spi = 0;
15589   u8 *ck = 0, *ik = 0;
15590   u8 is_add = 1;
15591
15592   u8 protocol = IPSEC_PROTOCOL_AH;
15593   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15594   u32 crypto_alg = 0, integ_alg = 0;
15595   ip4_address_t tun_src4;
15596   ip4_address_t tun_dst4;
15597   ip6_address_t tun_src6;
15598   ip6_address_t tun_dst6;
15599   int ret;
15600
15601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15602     {
15603       if (unformat (i, "del"))
15604         is_add = 0;
15605       else if (unformat (i, "sad_id %d", &sad_id))
15606         ;
15607       else if (unformat (i, "spi %d", &spi))
15608         ;
15609       else if (unformat (i, "esp"))
15610         protocol = IPSEC_PROTOCOL_ESP;
15611       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15612         {
15613           is_tunnel = 1;
15614           is_tunnel_ipv6 = 0;
15615         }
15616       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15617         {
15618           is_tunnel = 1;
15619           is_tunnel_ipv6 = 0;
15620         }
15621       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15622         {
15623           is_tunnel = 1;
15624           is_tunnel_ipv6 = 1;
15625         }
15626       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15627         {
15628           is_tunnel = 1;
15629           is_tunnel_ipv6 = 1;
15630         }
15631       else
15632         if (unformat
15633             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15634         {
15635           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15636             {
15637               clib_warning ("unsupported crypto-alg: '%U'",
15638                             format_ipsec_crypto_alg, crypto_alg);
15639               return -99;
15640             }
15641         }
15642       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15643         ;
15644       else
15645         if (unformat
15646             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15647         {
15648           if (integ_alg >= IPSEC_INTEG_N_ALG)
15649             {
15650               clib_warning ("unsupported integ-alg: '%U'",
15651                             format_ipsec_integ_alg, integ_alg);
15652               return -99;
15653             }
15654         }
15655       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15656         ;
15657       else
15658         {
15659           clib_warning ("parse error '%U'", format_unformat_error, i);
15660           return -99;
15661         }
15662
15663     }
15664
15665   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15666
15667   mp->sad_id = ntohl (sad_id);
15668   mp->is_add = is_add;
15669   mp->protocol = protocol;
15670   mp->spi = ntohl (spi);
15671   mp->is_tunnel = is_tunnel;
15672   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15673   mp->crypto_algorithm = crypto_alg;
15674   mp->integrity_algorithm = integ_alg;
15675   mp->crypto_key_length = vec_len (ck);
15676   mp->integrity_key_length = vec_len (ik);
15677
15678   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15679     mp->crypto_key_length = sizeof (mp->crypto_key);
15680
15681   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15682     mp->integrity_key_length = sizeof (mp->integrity_key);
15683
15684   if (ck)
15685     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15686   if (ik)
15687     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15688
15689   if (is_tunnel)
15690     {
15691       if (is_tunnel_ipv6)
15692         {
15693           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15694                        sizeof (ip6_address_t));
15695           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15696                        sizeof (ip6_address_t));
15697         }
15698       else
15699         {
15700           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15701                        sizeof (ip4_address_t));
15702           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15703                        sizeof (ip4_address_t));
15704         }
15705     }
15706
15707   S (mp);
15708   W (ret);
15709   return ret;
15710 }
15711
15712 static int
15713 api_ipsec_sa_set_key (vat_main_t * vam)
15714 {
15715   unformat_input_t *i = vam->input;
15716   vl_api_ipsec_sa_set_key_t *mp;
15717   u32 sa_id;
15718   u8 *ck = 0, *ik = 0;
15719   int ret;
15720
15721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15722     {
15723       if (unformat (i, "sa_id %d", &sa_id))
15724         ;
15725       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15726         ;
15727       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15728         ;
15729       else
15730         {
15731           clib_warning ("parse error '%U'", format_unformat_error, i);
15732           return -99;
15733         }
15734     }
15735
15736   M (IPSEC_SA_SET_KEY, mp);
15737
15738   mp->sa_id = ntohl (sa_id);
15739   mp->crypto_key_length = vec_len (ck);
15740   mp->integrity_key_length = vec_len (ik);
15741
15742   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15743     mp->crypto_key_length = sizeof (mp->crypto_key);
15744
15745   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15746     mp->integrity_key_length = sizeof (mp->integrity_key);
15747
15748   if (ck)
15749     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15750   if (ik)
15751     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15752
15753   S (mp);
15754   W (ret);
15755   return ret;
15756 }
15757
15758 static int
15759 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15760 {
15761   unformat_input_t *i = vam->input;
15762   vl_api_ipsec_tunnel_if_add_del_t *mp;
15763   u32 local_spi = 0, remote_spi = 0;
15764   u32 crypto_alg = 0, integ_alg = 0;
15765   u8 *lck = NULL, *rck = NULL;
15766   u8 *lik = NULL, *rik = NULL;
15767   ip4_address_t local_ip = { {0} };
15768   ip4_address_t remote_ip = { {0} };
15769   u8 is_add = 1;
15770   u8 esn = 0;
15771   u8 anti_replay = 0;
15772   u8 renumber = 0;
15773   u32 instance = ~0;
15774   int ret;
15775
15776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15777     {
15778       if (unformat (i, "del"))
15779         is_add = 0;
15780       else if (unformat (i, "esn"))
15781         esn = 1;
15782       else if (unformat (i, "anti_replay"))
15783         anti_replay = 1;
15784       else if (unformat (i, "local_spi %d", &local_spi))
15785         ;
15786       else if (unformat (i, "remote_spi %d", &remote_spi))
15787         ;
15788       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15789         ;
15790       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15791         ;
15792       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15793         ;
15794       else
15795         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15796         ;
15797       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15798         ;
15799       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15800         ;
15801       else
15802         if (unformat
15803             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15804         {
15805           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15806             {
15807               errmsg ("unsupported crypto-alg: '%U'\n",
15808                       format_ipsec_crypto_alg, crypto_alg);
15809               return -99;
15810             }
15811         }
15812       else
15813         if (unformat
15814             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15815         {
15816           if (integ_alg >= IPSEC_INTEG_N_ALG)
15817             {
15818               errmsg ("unsupported integ-alg: '%U'\n",
15819                       format_ipsec_integ_alg, integ_alg);
15820               return -99;
15821             }
15822         }
15823       else if (unformat (i, "instance %u", &instance))
15824         renumber = 1;
15825       else
15826         {
15827           errmsg ("parse error '%U'\n", format_unformat_error, i);
15828           return -99;
15829         }
15830     }
15831
15832   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15833
15834   mp->is_add = is_add;
15835   mp->esn = esn;
15836   mp->anti_replay = anti_replay;
15837
15838   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15839   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15840
15841   mp->local_spi = htonl (local_spi);
15842   mp->remote_spi = htonl (remote_spi);
15843   mp->crypto_alg = (u8) crypto_alg;
15844
15845   mp->local_crypto_key_len = 0;
15846   if (lck)
15847     {
15848       mp->local_crypto_key_len = vec_len (lck);
15849       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15850         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15851       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15852     }
15853
15854   mp->remote_crypto_key_len = 0;
15855   if (rck)
15856     {
15857       mp->remote_crypto_key_len = vec_len (rck);
15858       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15859         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15860       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15861     }
15862
15863   mp->integ_alg = (u8) integ_alg;
15864
15865   mp->local_integ_key_len = 0;
15866   if (lik)
15867     {
15868       mp->local_integ_key_len = vec_len (lik);
15869       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15870         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15871       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15872     }
15873
15874   mp->remote_integ_key_len = 0;
15875   if (rik)
15876     {
15877       mp->remote_integ_key_len = vec_len (rik);
15878       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15879         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15880       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15881     }
15882
15883   if (renumber)
15884     {
15885       mp->renumber = renumber;
15886       mp->show_instance = ntohl (instance);
15887     }
15888
15889   S (mp);
15890   W (ret);
15891   return ret;
15892 }
15893
15894 static void
15895 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15896 {
15897   vat_main_t *vam = &vat_main;
15898
15899   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15900          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15901          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15902          "tunnel_src_addr %U tunnel_dst_addr %U "
15903          "salt %u seq_outbound %lu last_seq_inbound %lu "
15904          "replay_window %lu total_data_size %lu\n",
15905          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15906          mp->protocol,
15907          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15908          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15909          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15910          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15911          mp->tunnel_src_addr,
15912          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15913          mp->tunnel_dst_addr,
15914          ntohl (mp->salt),
15915          clib_net_to_host_u64 (mp->seq_outbound),
15916          clib_net_to_host_u64 (mp->last_seq_inbound),
15917          clib_net_to_host_u64 (mp->replay_window),
15918          clib_net_to_host_u64 (mp->total_data_size));
15919 }
15920
15921 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15922 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15923
15924 static void vl_api_ipsec_sa_details_t_handler_json
15925   (vl_api_ipsec_sa_details_t * mp)
15926 {
15927   vat_main_t *vam = &vat_main;
15928   vat_json_node_t *node = NULL;
15929   struct in_addr src_ip4, dst_ip4;
15930   struct in6_addr src_ip6, dst_ip6;
15931
15932   if (VAT_JSON_ARRAY != vam->json_tree.type)
15933     {
15934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15935       vat_json_init_array (&vam->json_tree);
15936     }
15937   node = vat_json_array_add (&vam->json_tree);
15938
15939   vat_json_init_object (node);
15940   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15941   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15942   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15943   vat_json_object_add_uint (node, "proto", mp->protocol);
15944   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15945   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15946   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15947   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15948   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15949   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15950   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15951                              mp->crypto_key_len);
15952   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15953                              mp->integ_key_len);
15954   if (mp->is_tunnel_ip6)
15955     {
15956       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15957       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15958       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15959       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15960     }
15961   else
15962     {
15963       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15964       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15965       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15966       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15967     }
15968   vat_json_object_add_uint (node, "replay_window",
15969                             clib_net_to_host_u64 (mp->replay_window));
15970   vat_json_object_add_uint (node, "total_data_size",
15971                             clib_net_to_host_u64 (mp->total_data_size));
15972
15973 }
15974
15975 static int
15976 api_ipsec_sa_dump (vat_main_t * vam)
15977 {
15978   unformat_input_t *i = vam->input;
15979   vl_api_ipsec_sa_dump_t *mp;
15980   vl_api_control_ping_t *mp_ping;
15981   u32 sa_id = ~0;
15982   int ret;
15983
15984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15985     {
15986       if (unformat (i, "sa_id %d", &sa_id))
15987         ;
15988       else
15989         {
15990           clib_warning ("parse error '%U'", format_unformat_error, i);
15991           return -99;
15992         }
15993     }
15994
15995   M (IPSEC_SA_DUMP, mp);
15996
15997   mp->sa_id = ntohl (sa_id);
15998
15999   S (mp);
16000
16001   /* Use a control ping for synchronization */
16002   M (CONTROL_PING, mp_ping);
16003   S (mp_ping);
16004
16005   W (ret);
16006   return ret;
16007 }
16008
16009 static int
16010 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
16011 {
16012   unformat_input_t *i = vam->input;
16013   vl_api_ipsec_tunnel_if_set_key_t *mp;
16014   u32 sw_if_index = ~0;
16015   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
16016   u8 *key = 0;
16017   u32 alg = ~0;
16018   int ret;
16019
16020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16021     {
16022       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16023         ;
16024       else
16025         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
16026         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
16027       else
16028         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
16029         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
16030       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
16031         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
16032       else
16033         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
16034         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
16035       else if (unformat (i, "%U", unformat_hex_string, &key))
16036         ;
16037       else
16038         {
16039           clib_warning ("parse error '%U'", format_unformat_error, i);
16040           return -99;
16041         }
16042     }
16043
16044   if (sw_if_index == ~0)
16045     {
16046       errmsg ("interface must be specified");
16047       return -99;
16048     }
16049
16050   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
16051     {
16052       errmsg ("key type must be specified");
16053       return -99;
16054     }
16055
16056   if (alg == ~0)
16057     {
16058       errmsg ("algorithm must be specified");
16059       return -99;
16060     }
16061
16062   if (vec_len (key) == 0)
16063     {
16064       errmsg ("key must be specified");
16065       return -99;
16066     }
16067
16068   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
16069
16070   mp->sw_if_index = htonl (sw_if_index);
16071   mp->alg = alg;
16072   mp->key_type = key_type;
16073   mp->key_len = vec_len (key);
16074   clib_memcpy (mp->key, key, vec_len (key));
16075
16076   S (mp);
16077   W (ret);
16078
16079   return ret;
16080 }
16081
16082 static int
16083 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
16084 {
16085   unformat_input_t *i = vam->input;
16086   vl_api_ipsec_tunnel_if_set_sa_t *mp;
16087   u32 sw_if_index = ~0;
16088   u32 sa_id = ~0;
16089   u8 is_outbound = (u8) ~ 0;
16090   int ret;
16091
16092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16093     {
16094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16095         ;
16096       else if (unformat (i, "sa_id %d", &sa_id))
16097         ;
16098       else if (unformat (i, "outbound"))
16099         is_outbound = 1;
16100       else if (unformat (i, "inbound"))
16101         is_outbound = 0;
16102       else
16103         {
16104           clib_warning ("parse error '%U'", format_unformat_error, i);
16105           return -99;
16106         }
16107     }
16108
16109   if (sw_if_index == ~0)
16110     {
16111       errmsg ("interface must be specified");
16112       return -99;
16113     }
16114
16115   if (sa_id == ~0)
16116     {
16117       errmsg ("SA ID must be specified");
16118       return -99;
16119     }
16120
16121   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16122
16123   mp->sw_if_index = htonl (sw_if_index);
16124   mp->sa_id = htonl (sa_id);
16125   mp->is_outbound = is_outbound;
16126
16127   S (mp);
16128   W (ret);
16129
16130   return ret;
16131 }
16132
16133 static int
16134 api_ikev2_profile_add_del (vat_main_t * vam)
16135 {
16136   unformat_input_t *i = vam->input;
16137   vl_api_ikev2_profile_add_del_t *mp;
16138   u8 is_add = 1;
16139   u8 *name = 0;
16140   int ret;
16141
16142   const char *valid_chars = "a-zA-Z0-9_";
16143
16144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (i, "del"))
16147         is_add = 0;
16148       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16149         vec_add1 (name, 0);
16150       else
16151         {
16152           errmsg ("parse error '%U'", format_unformat_error, i);
16153           return -99;
16154         }
16155     }
16156
16157   if (!vec_len (name))
16158     {
16159       errmsg ("profile name must be specified");
16160       return -99;
16161     }
16162
16163   if (vec_len (name) > 64)
16164     {
16165       errmsg ("profile name too long");
16166       return -99;
16167     }
16168
16169   M (IKEV2_PROFILE_ADD_DEL, mp);
16170
16171   clib_memcpy (mp->name, name, vec_len (name));
16172   mp->is_add = is_add;
16173   vec_free (name);
16174
16175   S (mp);
16176   W (ret);
16177   return ret;
16178 }
16179
16180 static int
16181 api_ikev2_profile_set_auth (vat_main_t * vam)
16182 {
16183   unformat_input_t *i = vam->input;
16184   vl_api_ikev2_profile_set_auth_t *mp;
16185   u8 *name = 0;
16186   u8 *data = 0;
16187   u32 auth_method = 0;
16188   u8 is_hex = 0;
16189   int ret;
16190
16191   const char *valid_chars = "a-zA-Z0-9_";
16192
16193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16194     {
16195       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16196         vec_add1 (name, 0);
16197       else if (unformat (i, "auth_method %U",
16198                          unformat_ikev2_auth_method, &auth_method))
16199         ;
16200       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16201         is_hex = 1;
16202       else if (unformat (i, "auth_data %v", &data))
16203         ;
16204       else
16205         {
16206           errmsg ("parse error '%U'", format_unformat_error, i);
16207           return -99;
16208         }
16209     }
16210
16211   if (!vec_len (name))
16212     {
16213       errmsg ("profile name must be specified");
16214       return -99;
16215     }
16216
16217   if (vec_len (name) > 64)
16218     {
16219       errmsg ("profile name too long");
16220       return -99;
16221     }
16222
16223   if (!vec_len (data))
16224     {
16225       errmsg ("auth_data must be specified");
16226       return -99;
16227     }
16228
16229   if (!auth_method)
16230     {
16231       errmsg ("auth_method must be specified");
16232       return -99;
16233     }
16234
16235   M (IKEV2_PROFILE_SET_AUTH, mp);
16236
16237   mp->is_hex = is_hex;
16238   mp->auth_method = (u8) auth_method;
16239   mp->data_len = vec_len (data);
16240   clib_memcpy (mp->name, name, vec_len (name));
16241   clib_memcpy (mp->data, data, vec_len (data));
16242   vec_free (name);
16243   vec_free (data);
16244
16245   S (mp);
16246   W (ret);
16247   return ret;
16248 }
16249
16250 static int
16251 api_ikev2_profile_set_id (vat_main_t * vam)
16252 {
16253   unformat_input_t *i = vam->input;
16254   vl_api_ikev2_profile_set_id_t *mp;
16255   u8 *name = 0;
16256   u8 *data = 0;
16257   u8 is_local = 0;
16258   u32 id_type = 0;
16259   ip4_address_t ip4;
16260   int ret;
16261
16262   const char *valid_chars = "a-zA-Z0-9_";
16263
16264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16265     {
16266       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16267         vec_add1 (name, 0);
16268       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16269         ;
16270       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16271         {
16272           data = vec_new (u8, 4);
16273           clib_memcpy (data, ip4.as_u8, 4);
16274         }
16275       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16276         ;
16277       else if (unformat (i, "id_data %v", &data))
16278         ;
16279       else if (unformat (i, "local"))
16280         is_local = 1;
16281       else if (unformat (i, "remote"))
16282         is_local = 0;
16283       else
16284         {
16285           errmsg ("parse error '%U'", format_unformat_error, i);
16286           return -99;
16287         }
16288     }
16289
16290   if (!vec_len (name))
16291     {
16292       errmsg ("profile name must be specified");
16293       return -99;
16294     }
16295
16296   if (vec_len (name) > 64)
16297     {
16298       errmsg ("profile name too long");
16299       return -99;
16300     }
16301
16302   if (!vec_len (data))
16303     {
16304       errmsg ("id_data must be specified");
16305       return -99;
16306     }
16307
16308   if (!id_type)
16309     {
16310       errmsg ("id_type must be specified");
16311       return -99;
16312     }
16313
16314   M (IKEV2_PROFILE_SET_ID, mp);
16315
16316   mp->is_local = is_local;
16317   mp->id_type = (u8) id_type;
16318   mp->data_len = vec_len (data);
16319   clib_memcpy (mp->name, name, vec_len (name));
16320   clib_memcpy (mp->data, data, vec_len (data));
16321   vec_free (name);
16322   vec_free (data);
16323
16324   S (mp);
16325   W (ret);
16326   return ret;
16327 }
16328
16329 static int
16330 api_ikev2_profile_set_ts (vat_main_t * vam)
16331 {
16332   unformat_input_t *i = vam->input;
16333   vl_api_ikev2_profile_set_ts_t *mp;
16334   u8 *name = 0;
16335   u8 is_local = 0;
16336   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16337   ip4_address_t start_addr, end_addr;
16338
16339   const char *valid_chars = "a-zA-Z0-9_";
16340   int ret;
16341
16342   start_addr.as_u32 = 0;
16343   end_addr.as_u32 = (u32) ~ 0;
16344
16345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16346     {
16347       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16348         vec_add1 (name, 0);
16349       else if (unformat (i, "protocol %d", &proto))
16350         ;
16351       else if (unformat (i, "start_port %d", &start_port))
16352         ;
16353       else if (unformat (i, "end_port %d", &end_port))
16354         ;
16355       else
16356         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16357         ;
16358       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16359         ;
16360       else if (unformat (i, "local"))
16361         is_local = 1;
16362       else if (unformat (i, "remote"))
16363         is_local = 0;
16364       else
16365         {
16366           errmsg ("parse error '%U'", format_unformat_error, i);
16367           return -99;
16368         }
16369     }
16370
16371   if (!vec_len (name))
16372     {
16373       errmsg ("profile name must be specified");
16374       return -99;
16375     }
16376
16377   if (vec_len (name) > 64)
16378     {
16379       errmsg ("profile name too long");
16380       return -99;
16381     }
16382
16383   M (IKEV2_PROFILE_SET_TS, mp);
16384
16385   mp->is_local = is_local;
16386   mp->proto = (u8) proto;
16387   mp->start_port = (u16) start_port;
16388   mp->end_port = (u16) end_port;
16389   mp->start_addr = start_addr.as_u32;
16390   mp->end_addr = end_addr.as_u32;
16391   clib_memcpy (mp->name, name, vec_len (name));
16392   vec_free (name);
16393
16394   S (mp);
16395   W (ret);
16396   return ret;
16397 }
16398
16399 static int
16400 api_ikev2_set_local_key (vat_main_t * vam)
16401 {
16402   unformat_input_t *i = vam->input;
16403   vl_api_ikev2_set_local_key_t *mp;
16404   u8 *file = 0;
16405   int ret;
16406
16407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16408     {
16409       if (unformat (i, "file %v", &file))
16410         vec_add1 (file, 0);
16411       else
16412         {
16413           errmsg ("parse error '%U'", format_unformat_error, i);
16414           return -99;
16415         }
16416     }
16417
16418   if (!vec_len (file))
16419     {
16420       errmsg ("RSA key file must be specified");
16421       return -99;
16422     }
16423
16424   if (vec_len (file) > 256)
16425     {
16426       errmsg ("file name too long");
16427       return -99;
16428     }
16429
16430   M (IKEV2_SET_LOCAL_KEY, mp);
16431
16432   clib_memcpy (mp->key_file, file, vec_len (file));
16433   vec_free (file);
16434
16435   S (mp);
16436   W (ret);
16437   return ret;
16438 }
16439
16440 static int
16441 api_ikev2_set_responder (vat_main_t * vam)
16442 {
16443   unformat_input_t *i = vam->input;
16444   vl_api_ikev2_set_responder_t *mp;
16445   int ret;
16446   u8 *name = 0;
16447   u32 sw_if_index = ~0;
16448   ip4_address_t address;
16449
16450   const char *valid_chars = "a-zA-Z0-9_";
16451
16452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16453     {
16454       if (unformat
16455           (i, "%U interface %d address %U", unformat_token, valid_chars,
16456            &name, &sw_if_index, unformat_ip4_address, &address))
16457         vec_add1 (name, 0);
16458       else
16459         {
16460           errmsg ("parse error '%U'", format_unformat_error, i);
16461           return -99;
16462         }
16463     }
16464
16465   if (!vec_len (name))
16466     {
16467       errmsg ("profile name must be specified");
16468       return -99;
16469     }
16470
16471   if (vec_len (name) > 64)
16472     {
16473       errmsg ("profile name too long");
16474       return -99;
16475     }
16476
16477   M (IKEV2_SET_RESPONDER, mp);
16478
16479   clib_memcpy (mp->name, name, vec_len (name));
16480   vec_free (name);
16481
16482   mp->sw_if_index = sw_if_index;
16483   clib_memcpy (mp->address, &address, sizeof (address));
16484
16485   S (mp);
16486   W (ret);
16487   return ret;
16488 }
16489
16490 static int
16491 api_ikev2_set_ike_transforms (vat_main_t * vam)
16492 {
16493   unformat_input_t *i = vam->input;
16494   vl_api_ikev2_set_ike_transforms_t *mp;
16495   int ret;
16496   u8 *name = 0;
16497   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16498
16499   const char *valid_chars = "a-zA-Z0-9_";
16500
16501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16502     {
16503       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16504                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16505         vec_add1 (name, 0);
16506       else
16507         {
16508           errmsg ("parse error '%U'", format_unformat_error, i);
16509           return -99;
16510         }
16511     }
16512
16513   if (!vec_len (name))
16514     {
16515       errmsg ("profile name must be specified");
16516       return -99;
16517     }
16518
16519   if (vec_len (name) > 64)
16520     {
16521       errmsg ("profile name too long");
16522       return -99;
16523     }
16524
16525   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16526
16527   clib_memcpy (mp->name, name, vec_len (name));
16528   vec_free (name);
16529   mp->crypto_alg = crypto_alg;
16530   mp->crypto_key_size = crypto_key_size;
16531   mp->integ_alg = integ_alg;
16532   mp->dh_group = dh_group;
16533
16534   S (mp);
16535   W (ret);
16536   return ret;
16537 }
16538
16539
16540 static int
16541 api_ikev2_set_esp_transforms (vat_main_t * vam)
16542 {
16543   unformat_input_t *i = vam->input;
16544   vl_api_ikev2_set_esp_transforms_t *mp;
16545   int ret;
16546   u8 *name = 0;
16547   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16548
16549   const char *valid_chars = "a-zA-Z0-9_";
16550
16551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16552     {
16553       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16554                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16555         vec_add1 (name, 0);
16556       else
16557         {
16558           errmsg ("parse error '%U'", format_unformat_error, i);
16559           return -99;
16560         }
16561     }
16562
16563   if (!vec_len (name))
16564     {
16565       errmsg ("profile name must be specified");
16566       return -99;
16567     }
16568
16569   if (vec_len (name) > 64)
16570     {
16571       errmsg ("profile name too long");
16572       return -99;
16573     }
16574
16575   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16576
16577   clib_memcpy (mp->name, name, vec_len (name));
16578   vec_free (name);
16579   mp->crypto_alg = crypto_alg;
16580   mp->crypto_key_size = crypto_key_size;
16581   mp->integ_alg = integ_alg;
16582   mp->dh_group = dh_group;
16583
16584   S (mp);
16585   W (ret);
16586   return ret;
16587 }
16588
16589 static int
16590 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16591 {
16592   unformat_input_t *i = vam->input;
16593   vl_api_ikev2_set_sa_lifetime_t *mp;
16594   int ret;
16595   u8 *name = 0;
16596   u64 lifetime, lifetime_maxdata;
16597   u32 lifetime_jitter, handover;
16598
16599   const char *valid_chars = "a-zA-Z0-9_";
16600
16601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16602     {
16603       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16604                     &lifetime, &lifetime_jitter, &handover,
16605                     &lifetime_maxdata))
16606         vec_add1 (name, 0);
16607       else
16608         {
16609           errmsg ("parse error '%U'", format_unformat_error, i);
16610           return -99;
16611         }
16612     }
16613
16614   if (!vec_len (name))
16615     {
16616       errmsg ("profile name must be specified");
16617       return -99;
16618     }
16619
16620   if (vec_len (name) > 64)
16621     {
16622       errmsg ("profile name too long");
16623       return -99;
16624     }
16625
16626   M (IKEV2_SET_SA_LIFETIME, mp);
16627
16628   clib_memcpy (mp->name, name, vec_len (name));
16629   vec_free (name);
16630   mp->lifetime = lifetime;
16631   mp->lifetime_jitter = lifetime_jitter;
16632   mp->handover = handover;
16633   mp->lifetime_maxdata = lifetime_maxdata;
16634
16635   S (mp);
16636   W (ret);
16637   return ret;
16638 }
16639
16640 static int
16641 api_ikev2_initiate_sa_init (vat_main_t * vam)
16642 {
16643   unformat_input_t *i = vam->input;
16644   vl_api_ikev2_initiate_sa_init_t *mp;
16645   int ret;
16646   u8 *name = 0;
16647
16648   const char *valid_chars = "a-zA-Z0-9_";
16649
16650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16651     {
16652       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16653         vec_add1 (name, 0);
16654       else
16655         {
16656           errmsg ("parse error '%U'", format_unformat_error, i);
16657           return -99;
16658         }
16659     }
16660
16661   if (!vec_len (name))
16662     {
16663       errmsg ("profile name must be specified");
16664       return -99;
16665     }
16666
16667   if (vec_len (name) > 64)
16668     {
16669       errmsg ("profile name too long");
16670       return -99;
16671     }
16672
16673   M (IKEV2_INITIATE_SA_INIT, mp);
16674
16675   clib_memcpy (mp->name, name, vec_len (name));
16676   vec_free (name);
16677
16678   S (mp);
16679   W (ret);
16680   return ret;
16681 }
16682
16683 static int
16684 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16685 {
16686   unformat_input_t *i = vam->input;
16687   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16688   int ret;
16689   u64 ispi;
16690
16691
16692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16693     {
16694       if (unformat (i, "%lx", &ispi))
16695         ;
16696       else
16697         {
16698           errmsg ("parse error '%U'", format_unformat_error, i);
16699           return -99;
16700         }
16701     }
16702
16703   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16704
16705   mp->ispi = ispi;
16706
16707   S (mp);
16708   W (ret);
16709   return ret;
16710 }
16711
16712 static int
16713 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16714 {
16715   unformat_input_t *i = vam->input;
16716   vl_api_ikev2_initiate_del_child_sa_t *mp;
16717   int ret;
16718   u32 ispi;
16719
16720
16721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16722     {
16723       if (unformat (i, "%x", &ispi))
16724         ;
16725       else
16726         {
16727           errmsg ("parse error '%U'", format_unformat_error, i);
16728           return -99;
16729         }
16730     }
16731
16732   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16733
16734   mp->ispi = ispi;
16735
16736   S (mp);
16737   W (ret);
16738   return ret;
16739 }
16740
16741 static int
16742 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16743 {
16744   unformat_input_t *i = vam->input;
16745   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16746   int ret;
16747   u32 ispi;
16748
16749
16750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16751     {
16752       if (unformat (i, "%x", &ispi))
16753         ;
16754       else
16755         {
16756           errmsg ("parse error '%U'", format_unformat_error, i);
16757           return -99;
16758         }
16759     }
16760
16761   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16762
16763   mp->ispi = ispi;
16764
16765   S (mp);
16766   W (ret);
16767   return ret;
16768 }
16769
16770 static int
16771 api_get_first_msg_id (vat_main_t * vam)
16772 {
16773   vl_api_get_first_msg_id_t *mp;
16774   unformat_input_t *i = vam->input;
16775   u8 *name;
16776   u8 name_set = 0;
16777   int ret;
16778
16779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16780     {
16781       if (unformat (i, "client %s", &name))
16782         name_set = 1;
16783       else
16784         break;
16785     }
16786
16787   if (name_set == 0)
16788     {
16789       errmsg ("missing client name");
16790       return -99;
16791     }
16792   vec_add1 (name, 0);
16793
16794   if (vec_len (name) > 63)
16795     {
16796       errmsg ("client name too long");
16797       return -99;
16798     }
16799
16800   M (GET_FIRST_MSG_ID, mp);
16801   clib_memcpy (mp->name, name, vec_len (name));
16802   S (mp);
16803   W (ret);
16804   return ret;
16805 }
16806
16807 static int
16808 api_cop_interface_enable_disable (vat_main_t * vam)
16809 {
16810   unformat_input_t *line_input = vam->input;
16811   vl_api_cop_interface_enable_disable_t *mp;
16812   u32 sw_if_index = ~0;
16813   u8 enable_disable = 1;
16814   int ret;
16815
16816   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16817     {
16818       if (unformat (line_input, "disable"))
16819         enable_disable = 0;
16820       if (unformat (line_input, "enable"))
16821         enable_disable = 1;
16822       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16823                          vam, &sw_if_index))
16824         ;
16825       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16826         ;
16827       else
16828         break;
16829     }
16830
16831   if (sw_if_index == ~0)
16832     {
16833       errmsg ("missing interface name or sw_if_index");
16834       return -99;
16835     }
16836
16837   /* Construct the API message */
16838   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16839   mp->sw_if_index = ntohl (sw_if_index);
16840   mp->enable_disable = enable_disable;
16841
16842   /* send it... */
16843   S (mp);
16844   /* Wait for the reply */
16845   W (ret);
16846   return ret;
16847 }
16848
16849 static int
16850 api_cop_whitelist_enable_disable (vat_main_t * vam)
16851 {
16852   unformat_input_t *line_input = vam->input;
16853   vl_api_cop_whitelist_enable_disable_t *mp;
16854   u32 sw_if_index = ~0;
16855   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16856   u32 fib_id = 0;
16857   int ret;
16858
16859   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16860     {
16861       if (unformat (line_input, "ip4"))
16862         ip4 = 1;
16863       else if (unformat (line_input, "ip6"))
16864         ip6 = 1;
16865       else if (unformat (line_input, "default"))
16866         default_cop = 1;
16867       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16868                          vam, &sw_if_index))
16869         ;
16870       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16871         ;
16872       else if (unformat (line_input, "fib-id %d", &fib_id))
16873         ;
16874       else
16875         break;
16876     }
16877
16878   if (sw_if_index == ~0)
16879     {
16880       errmsg ("missing interface name or sw_if_index");
16881       return -99;
16882     }
16883
16884   /* Construct the API message */
16885   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16886   mp->sw_if_index = ntohl (sw_if_index);
16887   mp->fib_id = ntohl (fib_id);
16888   mp->ip4 = ip4;
16889   mp->ip6 = ip6;
16890   mp->default_cop = default_cop;
16891
16892   /* send it... */
16893   S (mp);
16894   /* Wait for the reply */
16895   W (ret);
16896   return ret;
16897 }
16898
16899 static int
16900 api_get_node_graph (vat_main_t * vam)
16901 {
16902   vl_api_get_node_graph_t *mp;
16903   int ret;
16904
16905   M (GET_NODE_GRAPH, mp);
16906
16907   /* send it... */
16908   S (mp);
16909   /* Wait for the reply */
16910   W (ret);
16911   return ret;
16912 }
16913
16914 /* *INDENT-OFF* */
16915 /** Used for parsing LISP eids */
16916 typedef CLIB_PACKED(struct{
16917   u8 addr[16];   /**< eid address */
16918   u32 len;       /**< prefix length if IP */
16919   u8 type;      /**< type of eid */
16920 }) lisp_eid_vat_t;
16921 /* *INDENT-ON* */
16922
16923 static uword
16924 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16925 {
16926   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16927
16928   clib_memset (a, 0, sizeof (a[0]));
16929
16930   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16931     {
16932       a->type = 0;              /* ipv4 type */
16933     }
16934   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16935     {
16936       a->type = 1;              /* ipv6 type */
16937     }
16938   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16939     {
16940       a->type = 2;              /* mac type */
16941     }
16942   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16943     {
16944       a->type = 3;              /* NSH type */
16945       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16946       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16947     }
16948   else
16949     {
16950       return 0;
16951     }
16952
16953   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16954     {
16955       return 0;
16956     }
16957
16958   return 1;
16959 }
16960
16961 static int
16962 lisp_eid_size_vat (u8 type)
16963 {
16964   switch (type)
16965     {
16966     case 0:
16967       return 4;
16968     case 1:
16969       return 16;
16970     case 2:
16971       return 6;
16972     case 3:
16973       return 5;
16974     }
16975   return 0;
16976 }
16977
16978 static void
16979 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16980 {
16981   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16982 }
16983
16984 static int
16985 api_one_add_del_locator_set (vat_main_t * vam)
16986 {
16987   unformat_input_t *input = vam->input;
16988   vl_api_one_add_del_locator_set_t *mp;
16989   u8 is_add = 1;
16990   u8 *locator_set_name = NULL;
16991   u8 locator_set_name_set = 0;
16992   vl_api_local_locator_t locator, *locators = 0;
16993   u32 sw_if_index, priority, weight;
16994   u32 data_len = 0;
16995
16996   int ret;
16997   /* Parse args required to build the message */
16998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16999     {
17000       if (unformat (input, "del"))
17001         {
17002           is_add = 0;
17003         }
17004       else if (unformat (input, "locator-set %s", &locator_set_name))
17005         {
17006           locator_set_name_set = 1;
17007         }
17008       else if (unformat (input, "sw_if_index %u p %u w %u",
17009                          &sw_if_index, &priority, &weight))
17010         {
17011           locator.sw_if_index = htonl (sw_if_index);
17012           locator.priority = priority;
17013           locator.weight = weight;
17014           vec_add1 (locators, locator);
17015         }
17016       else
17017         if (unformat
17018             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
17019              &sw_if_index, &priority, &weight))
17020         {
17021           locator.sw_if_index = htonl (sw_if_index);
17022           locator.priority = priority;
17023           locator.weight = weight;
17024           vec_add1 (locators, locator);
17025         }
17026       else
17027         break;
17028     }
17029
17030   if (locator_set_name_set == 0)
17031     {
17032       errmsg ("missing locator-set name");
17033       vec_free (locators);
17034       return -99;
17035     }
17036
17037   if (vec_len (locator_set_name) > 64)
17038     {
17039       errmsg ("locator-set name too long");
17040       vec_free (locator_set_name);
17041       vec_free (locators);
17042       return -99;
17043     }
17044   vec_add1 (locator_set_name, 0);
17045
17046   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
17047
17048   /* Construct the API message */
17049   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
17050
17051   mp->is_add = is_add;
17052   clib_memcpy (mp->locator_set_name, locator_set_name,
17053                vec_len (locator_set_name));
17054   vec_free (locator_set_name);
17055
17056   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
17057   if (locators)
17058     clib_memcpy (mp->locators, locators, data_len);
17059   vec_free (locators);
17060
17061   /* send it... */
17062   S (mp);
17063
17064   /* Wait for a reply... */
17065   W (ret);
17066   return ret;
17067 }
17068
17069 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
17070
17071 static int
17072 api_one_add_del_locator (vat_main_t * vam)
17073 {
17074   unformat_input_t *input = vam->input;
17075   vl_api_one_add_del_locator_t *mp;
17076   u32 tmp_if_index = ~0;
17077   u32 sw_if_index = ~0;
17078   u8 sw_if_index_set = 0;
17079   u8 sw_if_index_if_name_set = 0;
17080   u32 priority = ~0;
17081   u8 priority_set = 0;
17082   u32 weight = ~0;
17083   u8 weight_set = 0;
17084   u8 is_add = 1;
17085   u8 *locator_set_name = NULL;
17086   u8 locator_set_name_set = 0;
17087   int ret;
17088
17089   /* Parse args required to build the message */
17090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17091     {
17092       if (unformat (input, "del"))
17093         {
17094           is_add = 0;
17095         }
17096       else if (unformat (input, "locator-set %s", &locator_set_name))
17097         {
17098           locator_set_name_set = 1;
17099         }
17100       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
17101                          &tmp_if_index))
17102         {
17103           sw_if_index_if_name_set = 1;
17104           sw_if_index = tmp_if_index;
17105         }
17106       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17107         {
17108           sw_if_index_set = 1;
17109           sw_if_index = tmp_if_index;
17110         }
17111       else if (unformat (input, "p %d", &priority))
17112         {
17113           priority_set = 1;
17114         }
17115       else if (unformat (input, "w %d", &weight))
17116         {
17117           weight_set = 1;
17118         }
17119       else
17120         break;
17121     }
17122
17123   if (locator_set_name_set == 0)
17124     {
17125       errmsg ("missing locator-set name");
17126       return -99;
17127     }
17128
17129   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17130     {
17131       errmsg ("missing sw_if_index");
17132       vec_free (locator_set_name);
17133       return -99;
17134     }
17135
17136   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17137     {
17138       errmsg ("cannot use both params interface name and sw_if_index");
17139       vec_free (locator_set_name);
17140       return -99;
17141     }
17142
17143   if (priority_set == 0)
17144     {
17145       errmsg ("missing locator-set priority");
17146       vec_free (locator_set_name);
17147       return -99;
17148     }
17149
17150   if (weight_set == 0)
17151     {
17152       errmsg ("missing locator-set weight");
17153       vec_free (locator_set_name);
17154       return -99;
17155     }
17156
17157   if (vec_len (locator_set_name) > 64)
17158     {
17159       errmsg ("locator-set name too long");
17160       vec_free (locator_set_name);
17161       return -99;
17162     }
17163   vec_add1 (locator_set_name, 0);
17164
17165   /* Construct the API message */
17166   M (ONE_ADD_DEL_LOCATOR, mp);
17167
17168   mp->is_add = is_add;
17169   mp->sw_if_index = ntohl (sw_if_index);
17170   mp->priority = priority;
17171   mp->weight = weight;
17172   clib_memcpy (mp->locator_set_name, locator_set_name,
17173                vec_len (locator_set_name));
17174   vec_free (locator_set_name);
17175
17176   /* send it... */
17177   S (mp);
17178
17179   /* Wait for a reply... */
17180   W (ret);
17181   return ret;
17182 }
17183
17184 #define api_lisp_add_del_locator api_one_add_del_locator
17185
17186 uword
17187 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17188 {
17189   u32 *key_id = va_arg (*args, u32 *);
17190   u8 *s = 0;
17191
17192   if (unformat (input, "%s", &s))
17193     {
17194       if (!strcmp ((char *) s, "sha1"))
17195         key_id[0] = HMAC_SHA_1_96;
17196       else if (!strcmp ((char *) s, "sha256"))
17197         key_id[0] = HMAC_SHA_256_128;
17198       else
17199         {
17200           clib_warning ("invalid key_id: '%s'", s);
17201           key_id[0] = HMAC_NO_KEY;
17202         }
17203     }
17204   else
17205     return 0;
17206
17207   vec_free (s);
17208   return 1;
17209 }
17210
17211 static int
17212 api_one_add_del_local_eid (vat_main_t * vam)
17213 {
17214   unformat_input_t *input = vam->input;
17215   vl_api_one_add_del_local_eid_t *mp;
17216   u8 is_add = 1;
17217   u8 eid_set = 0;
17218   lisp_eid_vat_t _eid, *eid = &_eid;
17219   u8 *locator_set_name = 0;
17220   u8 locator_set_name_set = 0;
17221   u32 vni = 0;
17222   u16 key_id = 0;
17223   u8 *key = 0;
17224   int ret;
17225
17226   /* Parse args required to build the message */
17227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17228     {
17229       if (unformat (input, "del"))
17230         {
17231           is_add = 0;
17232         }
17233       else if (unformat (input, "vni %d", &vni))
17234         {
17235           ;
17236         }
17237       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17238         {
17239           eid_set = 1;
17240         }
17241       else if (unformat (input, "locator-set %s", &locator_set_name))
17242         {
17243           locator_set_name_set = 1;
17244         }
17245       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17246         ;
17247       else if (unformat (input, "secret-key %_%v%_", &key))
17248         ;
17249       else
17250         break;
17251     }
17252
17253   if (locator_set_name_set == 0)
17254     {
17255       errmsg ("missing locator-set name");
17256       return -99;
17257     }
17258
17259   if (0 == eid_set)
17260     {
17261       errmsg ("EID address not set!");
17262       vec_free (locator_set_name);
17263       return -99;
17264     }
17265
17266   if (key && (0 == key_id))
17267     {
17268       errmsg ("invalid key_id!");
17269       return -99;
17270     }
17271
17272   if (vec_len (key) > 64)
17273     {
17274       errmsg ("key too long");
17275       vec_free (key);
17276       return -99;
17277     }
17278
17279   if (vec_len (locator_set_name) > 64)
17280     {
17281       errmsg ("locator-set name too long");
17282       vec_free (locator_set_name);
17283       return -99;
17284     }
17285   vec_add1 (locator_set_name, 0);
17286
17287   /* Construct the API message */
17288   M (ONE_ADD_DEL_LOCAL_EID, mp);
17289
17290   mp->is_add = is_add;
17291   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17292   mp->eid_type = eid->type;
17293   mp->prefix_len = eid->len;
17294   mp->vni = clib_host_to_net_u32 (vni);
17295   mp->key_id = clib_host_to_net_u16 (key_id);
17296   clib_memcpy (mp->locator_set_name, locator_set_name,
17297                vec_len (locator_set_name));
17298   clib_memcpy (mp->key, key, vec_len (key));
17299
17300   vec_free (locator_set_name);
17301   vec_free (key);
17302
17303   /* send it... */
17304   S (mp);
17305
17306   /* Wait for a reply... */
17307   W (ret);
17308   return ret;
17309 }
17310
17311 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17312
17313 static int
17314 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17315 {
17316   u32 dp_table = 0, vni = 0;;
17317   unformat_input_t *input = vam->input;
17318   vl_api_gpe_add_del_fwd_entry_t *mp;
17319   u8 is_add = 1;
17320   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17321   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17322   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17323   u32 action = ~0, w;
17324   ip4_address_t rmt_rloc4, lcl_rloc4;
17325   ip6_address_t rmt_rloc6, lcl_rloc6;
17326   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17327   int ret;
17328
17329   clib_memset (&rloc, 0, sizeof (rloc));
17330
17331   /* Parse args required to build the message */
17332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17333     {
17334       if (unformat (input, "del"))
17335         is_add = 0;
17336       else if (unformat (input, "add"))
17337         is_add = 1;
17338       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17339         {
17340           rmt_eid_set = 1;
17341         }
17342       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17343         {
17344           lcl_eid_set = 1;
17345         }
17346       else if (unformat (input, "vrf %d", &dp_table))
17347         ;
17348       else if (unformat (input, "bd %d", &dp_table))
17349         ;
17350       else if (unformat (input, "vni %d", &vni))
17351         ;
17352       else if (unformat (input, "w %d", &w))
17353         {
17354           if (!curr_rloc)
17355             {
17356               errmsg ("No RLOC configured for setting priority/weight!");
17357               return -99;
17358             }
17359           curr_rloc->weight = w;
17360         }
17361       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17362                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17363         {
17364           rloc.is_ip4 = 1;
17365
17366           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17367           rloc.weight = 0;
17368           vec_add1 (lcl_locs, rloc);
17369
17370           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17371           vec_add1 (rmt_locs, rloc);
17372           /* weight saved in rmt loc */
17373           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17374         }
17375       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17376                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17377         {
17378           rloc.is_ip4 = 0;
17379           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17380           rloc.weight = 0;
17381           vec_add1 (lcl_locs, rloc);
17382
17383           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17384           vec_add1 (rmt_locs, rloc);
17385           /* weight saved in rmt loc */
17386           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17387         }
17388       else if (unformat (input, "action %d", &action))
17389         {
17390           ;
17391         }
17392       else
17393         {
17394           clib_warning ("parse error '%U'", format_unformat_error, input);
17395           return -99;
17396         }
17397     }
17398
17399   if (!rmt_eid_set)
17400     {
17401       errmsg ("remote eid addresses not set");
17402       return -99;
17403     }
17404
17405   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17406     {
17407       errmsg ("eid types don't match");
17408       return -99;
17409     }
17410
17411   if (0 == rmt_locs && (u32) ~ 0 == action)
17412     {
17413       errmsg ("action not set for negative mapping");
17414       return -99;
17415     }
17416
17417   /* Construct the API message */
17418   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17419       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17420
17421   mp->is_add = is_add;
17422   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17423   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17424   mp->eid_type = rmt_eid->type;
17425   mp->dp_table = clib_host_to_net_u32 (dp_table);
17426   mp->vni = clib_host_to_net_u32 (vni);
17427   mp->rmt_len = rmt_eid->len;
17428   mp->lcl_len = lcl_eid->len;
17429   mp->action = action;
17430
17431   if (0 != rmt_locs && 0 != lcl_locs)
17432     {
17433       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17434       clib_memcpy (mp->locs, lcl_locs,
17435                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17436
17437       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17438       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17439                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17440     }
17441   vec_free (lcl_locs);
17442   vec_free (rmt_locs);
17443
17444   /* send it... */
17445   S (mp);
17446
17447   /* Wait for a reply... */
17448   W (ret);
17449   return ret;
17450 }
17451
17452 static int
17453 api_one_add_del_map_server (vat_main_t * vam)
17454 {
17455   unformat_input_t *input = vam->input;
17456   vl_api_one_add_del_map_server_t *mp;
17457   u8 is_add = 1;
17458   u8 ipv4_set = 0;
17459   u8 ipv6_set = 0;
17460   ip4_address_t ipv4;
17461   ip6_address_t ipv6;
17462   int ret;
17463
17464   /* Parse args required to build the message */
17465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17466     {
17467       if (unformat (input, "del"))
17468         {
17469           is_add = 0;
17470         }
17471       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17472         {
17473           ipv4_set = 1;
17474         }
17475       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17476         {
17477           ipv6_set = 1;
17478         }
17479       else
17480         break;
17481     }
17482
17483   if (ipv4_set && ipv6_set)
17484     {
17485       errmsg ("both eid v4 and v6 addresses set");
17486       return -99;
17487     }
17488
17489   if (!ipv4_set && !ipv6_set)
17490     {
17491       errmsg ("eid addresses not set");
17492       return -99;
17493     }
17494
17495   /* Construct the API message */
17496   M (ONE_ADD_DEL_MAP_SERVER, mp);
17497
17498   mp->is_add = is_add;
17499   if (ipv6_set)
17500     {
17501       mp->is_ipv6 = 1;
17502       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17503     }
17504   else
17505     {
17506       mp->is_ipv6 = 0;
17507       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17508     }
17509
17510   /* send it... */
17511   S (mp);
17512
17513   /* Wait for a reply... */
17514   W (ret);
17515   return ret;
17516 }
17517
17518 #define api_lisp_add_del_map_server api_one_add_del_map_server
17519
17520 static int
17521 api_one_add_del_map_resolver (vat_main_t * vam)
17522 {
17523   unformat_input_t *input = vam->input;
17524   vl_api_one_add_del_map_resolver_t *mp;
17525   u8 is_add = 1;
17526   u8 ipv4_set = 0;
17527   u8 ipv6_set = 0;
17528   ip4_address_t ipv4;
17529   ip6_address_t ipv6;
17530   int ret;
17531
17532   /* Parse args required to build the message */
17533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17534     {
17535       if (unformat (input, "del"))
17536         {
17537           is_add = 0;
17538         }
17539       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17540         {
17541           ipv4_set = 1;
17542         }
17543       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17544         {
17545           ipv6_set = 1;
17546         }
17547       else
17548         break;
17549     }
17550
17551   if (ipv4_set && ipv6_set)
17552     {
17553       errmsg ("both eid v4 and v6 addresses set");
17554       return -99;
17555     }
17556
17557   if (!ipv4_set && !ipv6_set)
17558     {
17559       errmsg ("eid addresses not set");
17560       return -99;
17561     }
17562
17563   /* Construct the API message */
17564   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17565
17566   mp->is_add = is_add;
17567   if (ipv6_set)
17568     {
17569       mp->is_ipv6 = 1;
17570       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17571     }
17572   else
17573     {
17574       mp->is_ipv6 = 0;
17575       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17576     }
17577
17578   /* send it... */
17579   S (mp);
17580
17581   /* Wait for a reply... */
17582   W (ret);
17583   return ret;
17584 }
17585
17586 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17587
17588 static int
17589 api_lisp_gpe_enable_disable (vat_main_t * vam)
17590 {
17591   unformat_input_t *input = vam->input;
17592   vl_api_gpe_enable_disable_t *mp;
17593   u8 is_set = 0;
17594   u8 is_en = 1;
17595   int ret;
17596
17597   /* Parse args required to build the message */
17598   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17599     {
17600       if (unformat (input, "enable"))
17601         {
17602           is_set = 1;
17603           is_en = 1;
17604         }
17605       else if (unformat (input, "disable"))
17606         {
17607           is_set = 1;
17608           is_en = 0;
17609         }
17610       else
17611         break;
17612     }
17613
17614   if (is_set == 0)
17615     {
17616       errmsg ("Value not set");
17617       return -99;
17618     }
17619
17620   /* Construct the API message */
17621   M (GPE_ENABLE_DISABLE, mp);
17622
17623   mp->is_en = is_en;
17624
17625   /* send it... */
17626   S (mp);
17627
17628   /* Wait for a reply... */
17629   W (ret);
17630   return ret;
17631 }
17632
17633 static int
17634 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17635 {
17636   unformat_input_t *input = vam->input;
17637   vl_api_one_rloc_probe_enable_disable_t *mp;
17638   u8 is_set = 0;
17639   u8 is_en = 0;
17640   int ret;
17641
17642   /* Parse args required to build the message */
17643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17644     {
17645       if (unformat (input, "enable"))
17646         {
17647           is_set = 1;
17648           is_en = 1;
17649         }
17650       else if (unformat (input, "disable"))
17651         is_set = 1;
17652       else
17653         break;
17654     }
17655
17656   if (!is_set)
17657     {
17658       errmsg ("Value not set");
17659       return -99;
17660     }
17661
17662   /* Construct the API message */
17663   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17664
17665   mp->is_enabled = is_en;
17666
17667   /* send it... */
17668   S (mp);
17669
17670   /* Wait for a reply... */
17671   W (ret);
17672   return ret;
17673 }
17674
17675 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17676
17677 static int
17678 api_one_map_register_enable_disable (vat_main_t * vam)
17679 {
17680   unformat_input_t *input = vam->input;
17681   vl_api_one_map_register_enable_disable_t *mp;
17682   u8 is_set = 0;
17683   u8 is_en = 0;
17684   int ret;
17685
17686   /* Parse args required to build the message */
17687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17688     {
17689       if (unformat (input, "enable"))
17690         {
17691           is_set = 1;
17692           is_en = 1;
17693         }
17694       else if (unformat (input, "disable"))
17695         is_set = 1;
17696       else
17697         break;
17698     }
17699
17700   if (!is_set)
17701     {
17702       errmsg ("Value not set");
17703       return -99;
17704     }
17705
17706   /* Construct the API message */
17707   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17708
17709   mp->is_enabled = is_en;
17710
17711   /* send it... */
17712   S (mp);
17713
17714   /* Wait for a reply... */
17715   W (ret);
17716   return ret;
17717 }
17718
17719 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17720
17721 static int
17722 api_one_enable_disable (vat_main_t * vam)
17723 {
17724   unformat_input_t *input = vam->input;
17725   vl_api_one_enable_disable_t *mp;
17726   u8 is_set = 0;
17727   u8 is_en = 0;
17728   int ret;
17729
17730   /* Parse args required to build the message */
17731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17732     {
17733       if (unformat (input, "enable"))
17734         {
17735           is_set = 1;
17736           is_en = 1;
17737         }
17738       else if (unformat (input, "disable"))
17739         {
17740           is_set = 1;
17741         }
17742       else
17743         break;
17744     }
17745
17746   if (!is_set)
17747     {
17748       errmsg ("Value not set");
17749       return -99;
17750     }
17751
17752   /* Construct the API message */
17753   M (ONE_ENABLE_DISABLE, mp);
17754
17755   mp->is_en = is_en;
17756
17757   /* send it... */
17758   S (mp);
17759
17760   /* Wait for a reply... */
17761   W (ret);
17762   return ret;
17763 }
17764
17765 #define api_lisp_enable_disable api_one_enable_disable
17766
17767 static int
17768 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17769 {
17770   unformat_input_t *input = vam->input;
17771   vl_api_one_enable_disable_xtr_mode_t *mp;
17772   u8 is_set = 0;
17773   u8 is_en = 0;
17774   int ret;
17775
17776   /* Parse args required to build the message */
17777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17778     {
17779       if (unformat (input, "enable"))
17780         {
17781           is_set = 1;
17782           is_en = 1;
17783         }
17784       else if (unformat (input, "disable"))
17785         {
17786           is_set = 1;
17787         }
17788       else
17789         break;
17790     }
17791
17792   if (!is_set)
17793     {
17794       errmsg ("Value not set");
17795       return -99;
17796     }
17797
17798   /* Construct the API message */
17799   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17800
17801   mp->is_en = is_en;
17802
17803   /* send it... */
17804   S (mp);
17805
17806   /* Wait for a reply... */
17807   W (ret);
17808   return ret;
17809 }
17810
17811 static int
17812 api_one_show_xtr_mode (vat_main_t * vam)
17813 {
17814   vl_api_one_show_xtr_mode_t *mp;
17815   int ret;
17816
17817   /* Construct the API message */
17818   M (ONE_SHOW_XTR_MODE, mp);
17819
17820   /* send it... */
17821   S (mp);
17822
17823   /* Wait for a reply... */
17824   W (ret);
17825   return ret;
17826 }
17827
17828 static int
17829 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17830 {
17831   unformat_input_t *input = vam->input;
17832   vl_api_one_enable_disable_pitr_mode_t *mp;
17833   u8 is_set = 0;
17834   u8 is_en = 0;
17835   int ret;
17836
17837   /* Parse args required to build the message */
17838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17839     {
17840       if (unformat (input, "enable"))
17841         {
17842           is_set = 1;
17843           is_en = 1;
17844         }
17845       else if (unformat (input, "disable"))
17846         {
17847           is_set = 1;
17848         }
17849       else
17850         break;
17851     }
17852
17853   if (!is_set)
17854     {
17855       errmsg ("Value not set");
17856       return -99;
17857     }
17858
17859   /* Construct the API message */
17860   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17861
17862   mp->is_en = is_en;
17863
17864   /* send it... */
17865   S (mp);
17866
17867   /* Wait for a reply... */
17868   W (ret);
17869   return ret;
17870 }
17871
17872 static int
17873 api_one_show_pitr_mode (vat_main_t * vam)
17874 {
17875   vl_api_one_show_pitr_mode_t *mp;
17876   int ret;
17877
17878   /* Construct the API message */
17879   M (ONE_SHOW_PITR_MODE, mp);
17880
17881   /* send it... */
17882   S (mp);
17883
17884   /* Wait for a reply... */
17885   W (ret);
17886   return ret;
17887 }
17888
17889 static int
17890 api_one_enable_disable_petr_mode (vat_main_t * vam)
17891 {
17892   unformat_input_t *input = vam->input;
17893   vl_api_one_enable_disable_petr_mode_t *mp;
17894   u8 is_set = 0;
17895   u8 is_en = 0;
17896   int ret;
17897
17898   /* Parse args required to build the message */
17899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17900     {
17901       if (unformat (input, "enable"))
17902         {
17903           is_set = 1;
17904           is_en = 1;
17905         }
17906       else if (unformat (input, "disable"))
17907         {
17908           is_set = 1;
17909         }
17910       else
17911         break;
17912     }
17913
17914   if (!is_set)
17915     {
17916       errmsg ("Value not set");
17917       return -99;
17918     }
17919
17920   /* Construct the API message */
17921   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17922
17923   mp->is_en = is_en;
17924
17925   /* send it... */
17926   S (mp);
17927
17928   /* Wait for a reply... */
17929   W (ret);
17930   return ret;
17931 }
17932
17933 static int
17934 api_one_show_petr_mode (vat_main_t * vam)
17935 {
17936   vl_api_one_show_petr_mode_t *mp;
17937   int ret;
17938
17939   /* Construct the API message */
17940   M (ONE_SHOW_PETR_MODE, mp);
17941
17942   /* send it... */
17943   S (mp);
17944
17945   /* Wait for a reply... */
17946   W (ret);
17947   return ret;
17948 }
17949
17950 static int
17951 api_show_one_map_register_state (vat_main_t * vam)
17952 {
17953   vl_api_show_one_map_register_state_t *mp;
17954   int ret;
17955
17956   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17957
17958   /* send */
17959   S (mp);
17960
17961   /* wait for reply */
17962   W (ret);
17963   return ret;
17964 }
17965
17966 #define api_show_lisp_map_register_state api_show_one_map_register_state
17967
17968 static int
17969 api_show_one_rloc_probe_state (vat_main_t * vam)
17970 {
17971   vl_api_show_one_rloc_probe_state_t *mp;
17972   int ret;
17973
17974   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17975
17976   /* send */
17977   S (mp);
17978
17979   /* wait for reply */
17980   W (ret);
17981   return ret;
17982 }
17983
17984 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17985
17986 static int
17987 api_one_add_del_ndp_entry (vat_main_t * vam)
17988 {
17989   vl_api_one_add_del_ndp_entry_t *mp;
17990   unformat_input_t *input = vam->input;
17991   u8 is_add = 1;
17992   u8 mac_set = 0;
17993   u8 bd_set = 0;
17994   u8 ip_set = 0;
17995   u8 mac[6] = { 0, };
17996   u8 ip6[16] = { 0, };
17997   u32 bd = ~0;
17998   int ret;
17999
18000   /* Parse args required to build the message */
18001   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18002     {
18003       if (unformat (input, "del"))
18004         is_add = 0;
18005       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18006         mac_set = 1;
18007       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
18008         ip_set = 1;
18009       else if (unformat (input, "bd %d", &bd))
18010         bd_set = 1;
18011       else
18012         {
18013           errmsg ("parse error '%U'", format_unformat_error, input);
18014           return -99;
18015         }
18016     }
18017
18018   if (!bd_set || !ip_set || (!mac_set && is_add))
18019     {
18020       errmsg ("Missing BD, IP or MAC!");
18021       return -99;
18022     }
18023
18024   M (ONE_ADD_DEL_NDP_ENTRY, mp);
18025   mp->is_add = is_add;
18026   clib_memcpy (mp->mac, mac, 6);
18027   mp->bd = clib_host_to_net_u32 (bd);
18028   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
18029
18030   /* send */
18031   S (mp);
18032
18033   /* wait for reply */
18034   W (ret);
18035   return ret;
18036 }
18037
18038 static int
18039 api_one_add_del_l2_arp_entry (vat_main_t * vam)
18040 {
18041   vl_api_one_add_del_l2_arp_entry_t *mp;
18042   unformat_input_t *input = vam->input;
18043   u8 is_add = 1;
18044   u8 mac_set = 0;
18045   u8 bd_set = 0;
18046   u8 ip_set = 0;
18047   u8 mac[6] = { 0, };
18048   u32 ip4 = 0, bd = ~0;
18049   int ret;
18050
18051   /* Parse args required to build the message */
18052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18053     {
18054       if (unformat (input, "del"))
18055         is_add = 0;
18056       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18057         mac_set = 1;
18058       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
18059         ip_set = 1;
18060       else if (unformat (input, "bd %d", &bd))
18061         bd_set = 1;
18062       else
18063         {
18064           errmsg ("parse error '%U'", format_unformat_error, input);
18065           return -99;
18066         }
18067     }
18068
18069   if (!bd_set || !ip_set || (!mac_set && is_add))
18070     {
18071       errmsg ("Missing BD, IP or MAC!");
18072       return -99;
18073     }
18074
18075   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
18076   mp->is_add = is_add;
18077   clib_memcpy (mp->mac, mac, 6);
18078   mp->bd = clib_host_to_net_u32 (bd);
18079   mp->ip4 = ip4;
18080
18081   /* send */
18082   S (mp);
18083
18084   /* wait for reply */
18085   W (ret);
18086   return ret;
18087 }
18088
18089 static int
18090 api_one_ndp_bd_get (vat_main_t * vam)
18091 {
18092   vl_api_one_ndp_bd_get_t *mp;
18093   int ret;
18094
18095   M (ONE_NDP_BD_GET, mp);
18096
18097   /* send */
18098   S (mp);
18099
18100   /* wait for reply */
18101   W (ret);
18102   return ret;
18103 }
18104
18105 static int
18106 api_one_ndp_entries_get (vat_main_t * vam)
18107 {
18108   vl_api_one_ndp_entries_get_t *mp;
18109   unformat_input_t *input = vam->input;
18110   u8 bd_set = 0;
18111   u32 bd = ~0;
18112   int ret;
18113
18114   /* Parse args required to build the message */
18115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18116     {
18117       if (unformat (input, "bd %d", &bd))
18118         bd_set = 1;
18119       else
18120         {
18121           errmsg ("parse error '%U'", format_unformat_error, input);
18122           return -99;
18123         }
18124     }
18125
18126   if (!bd_set)
18127     {
18128       errmsg ("Expected bridge domain!");
18129       return -99;
18130     }
18131
18132   M (ONE_NDP_ENTRIES_GET, mp);
18133   mp->bd = clib_host_to_net_u32 (bd);
18134
18135   /* send */
18136   S (mp);
18137
18138   /* wait for reply */
18139   W (ret);
18140   return ret;
18141 }
18142
18143 static int
18144 api_one_l2_arp_bd_get (vat_main_t * vam)
18145 {
18146   vl_api_one_l2_arp_bd_get_t *mp;
18147   int ret;
18148
18149   M (ONE_L2_ARP_BD_GET, mp);
18150
18151   /* send */
18152   S (mp);
18153
18154   /* wait for reply */
18155   W (ret);
18156   return ret;
18157 }
18158
18159 static int
18160 api_one_l2_arp_entries_get (vat_main_t * vam)
18161 {
18162   vl_api_one_l2_arp_entries_get_t *mp;
18163   unformat_input_t *input = vam->input;
18164   u8 bd_set = 0;
18165   u32 bd = ~0;
18166   int ret;
18167
18168   /* Parse args required to build the message */
18169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18170     {
18171       if (unformat (input, "bd %d", &bd))
18172         bd_set = 1;
18173       else
18174         {
18175           errmsg ("parse error '%U'", format_unformat_error, input);
18176           return -99;
18177         }
18178     }
18179
18180   if (!bd_set)
18181     {
18182       errmsg ("Expected bridge domain!");
18183       return -99;
18184     }
18185
18186   M (ONE_L2_ARP_ENTRIES_GET, mp);
18187   mp->bd = clib_host_to_net_u32 (bd);
18188
18189   /* send */
18190   S (mp);
18191
18192   /* wait for reply */
18193   W (ret);
18194   return ret;
18195 }
18196
18197 static int
18198 api_one_stats_enable_disable (vat_main_t * vam)
18199 {
18200   vl_api_one_stats_enable_disable_t *mp;
18201   unformat_input_t *input = vam->input;
18202   u8 is_set = 0;
18203   u8 is_en = 0;
18204   int ret;
18205
18206   /* Parse args required to build the message */
18207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18208     {
18209       if (unformat (input, "enable"))
18210         {
18211           is_set = 1;
18212           is_en = 1;
18213         }
18214       else if (unformat (input, "disable"))
18215         {
18216           is_set = 1;
18217         }
18218       else
18219         break;
18220     }
18221
18222   if (!is_set)
18223     {
18224       errmsg ("Value not set");
18225       return -99;
18226     }
18227
18228   M (ONE_STATS_ENABLE_DISABLE, mp);
18229   mp->is_en = is_en;
18230
18231   /* send */
18232   S (mp);
18233
18234   /* wait for reply */
18235   W (ret);
18236   return ret;
18237 }
18238
18239 static int
18240 api_show_one_stats_enable_disable (vat_main_t * vam)
18241 {
18242   vl_api_show_one_stats_enable_disable_t *mp;
18243   int ret;
18244
18245   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18246
18247   /* send */
18248   S (mp);
18249
18250   /* wait for reply */
18251   W (ret);
18252   return ret;
18253 }
18254
18255 static int
18256 api_show_one_map_request_mode (vat_main_t * vam)
18257 {
18258   vl_api_show_one_map_request_mode_t *mp;
18259   int ret;
18260
18261   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18262
18263   /* send */
18264   S (mp);
18265
18266   /* wait for reply */
18267   W (ret);
18268   return ret;
18269 }
18270
18271 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18272
18273 static int
18274 api_one_map_request_mode (vat_main_t * vam)
18275 {
18276   unformat_input_t *input = vam->input;
18277   vl_api_one_map_request_mode_t *mp;
18278   u8 mode = 0;
18279   int ret;
18280
18281   /* Parse args required to build the message */
18282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18283     {
18284       if (unformat (input, "dst-only"))
18285         mode = 0;
18286       else if (unformat (input, "src-dst"))
18287         mode = 1;
18288       else
18289         {
18290           errmsg ("parse error '%U'", format_unformat_error, input);
18291           return -99;
18292         }
18293     }
18294
18295   M (ONE_MAP_REQUEST_MODE, mp);
18296
18297   mp->mode = mode;
18298
18299   /* send */
18300   S (mp);
18301
18302   /* wait for reply */
18303   W (ret);
18304   return ret;
18305 }
18306
18307 #define api_lisp_map_request_mode api_one_map_request_mode
18308
18309 /**
18310  * Enable/disable ONE proxy ITR.
18311  *
18312  * @param vam vpp API test context
18313  * @return return code
18314  */
18315 static int
18316 api_one_pitr_set_locator_set (vat_main_t * vam)
18317 {
18318   u8 ls_name_set = 0;
18319   unformat_input_t *input = vam->input;
18320   vl_api_one_pitr_set_locator_set_t *mp;
18321   u8 is_add = 1;
18322   u8 *ls_name = 0;
18323   int ret;
18324
18325   /* Parse args required to build the message */
18326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18327     {
18328       if (unformat (input, "del"))
18329         is_add = 0;
18330       else if (unformat (input, "locator-set %s", &ls_name))
18331         ls_name_set = 1;
18332       else
18333         {
18334           errmsg ("parse error '%U'", format_unformat_error, input);
18335           return -99;
18336         }
18337     }
18338
18339   if (!ls_name_set)
18340     {
18341       errmsg ("locator-set name not set!");
18342       return -99;
18343     }
18344
18345   M (ONE_PITR_SET_LOCATOR_SET, mp);
18346
18347   mp->is_add = is_add;
18348   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18349   vec_free (ls_name);
18350
18351   /* send */
18352   S (mp);
18353
18354   /* wait for reply */
18355   W (ret);
18356   return ret;
18357 }
18358
18359 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18360
18361 static int
18362 api_one_nsh_set_locator_set (vat_main_t * vam)
18363 {
18364   u8 ls_name_set = 0;
18365   unformat_input_t *input = vam->input;
18366   vl_api_one_nsh_set_locator_set_t *mp;
18367   u8 is_add = 1;
18368   u8 *ls_name = 0;
18369   int ret;
18370
18371   /* Parse args required to build the message */
18372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18373     {
18374       if (unformat (input, "del"))
18375         is_add = 0;
18376       else if (unformat (input, "ls %s", &ls_name))
18377         ls_name_set = 1;
18378       else
18379         {
18380           errmsg ("parse error '%U'", format_unformat_error, input);
18381           return -99;
18382         }
18383     }
18384
18385   if (!ls_name_set && is_add)
18386     {
18387       errmsg ("locator-set name not set!");
18388       return -99;
18389     }
18390
18391   M (ONE_NSH_SET_LOCATOR_SET, mp);
18392
18393   mp->is_add = is_add;
18394   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18395   vec_free (ls_name);
18396
18397   /* send */
18398   S (mp);
18399
18400   /* wait for reply */
18401   W (ret);
18402   return ret;
18403 }
18404
18405 static int
18406 api_show_one_pitr (vat_main_t * vam)
18407 {
18408   vl_api_show_one_pitr_t *mp;
18409   int ret;
18410
18411   if (!vam->json_output)
18412     {
18413       print (vam->ofp, "%=20s", "lisp status:");
18414     }
18415
18416   M (SHOW_ONE_PITR, mp);
18417   /* send it... */
18418   S (mp);
18419
18420   /* Wait for a reply... */
18421   W (ret);
18422   return ret;
18423 }
18424
18425 #define api_show_lisp_pitr api_show_one_pitr
18426
18427 static int
18428 api_one_use_petr (vat_main_t * vam)
18429 {
18430   unformat_input_t *input = vam->input;
18431   vl_api_one_use_petr_t *mp;
18432   u8 is_add = 0;
18433   ip_address_t ip;
18434   int ret;
18435
18436   clib_memset (&ip, 0, sizeof (ip));
18437
18438   /* Parse args required to build the message */
18439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18440     {
18441       if (unformat (input, "disable"))
18442         is_add = 0;
18443       else
18444         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18445         {
18446           is_add = 1;
18447           ip_addr_version (&ip) = IP4;
18448         }
18449       else
18450         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18451         {
18452           is_add = 1;
18453           ip_addr_version (&ip) = IP6;
18454         }
18455       else
18456         {
18457           errmsg ("parse error '%U'", format_unformat_error, input);
18458           return -99;
18459         }
18460     }
18461
18462   M (ONE_USE_PETR, mp);
18463
18464   mp->is_add = is_add;
18465   if (is_add)
18466     {
18467       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18468       if (mp->is_ip4)
18469         clib_memcpy (mp->address, &ip, 4);
18470       else
18471         clib_memcpy (mp->address, &ip, 16);
18472     }
18473
18474   /* send */
18475   S (mp);
18476
18477   /* wait for reply */
18478   W (ret);
18479   return ret;
18480 }
18481
18482 #define api_lisp_use_petr api_one_use_petr
18483
18484 static int
18485 api_show_one_nsh_mapping (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", "local ONE NSH mapping:");
18493     }
18494
18495   M (SHOW_ONE_NSH_MAPPING, mp);
18496   /* send it... */
18497   S (mp);
18498
18499   /* Wait for a reply... */
18500   W (ret);
18501   return ret;
18502 }
18503
18504 static int
18505 api_show_one_use_petr (vat_main_t * vam)
18506 {
18507   vl_api_show_one_use_petr_t *mp;
18508   int ret;
18509
18510   if (!vam->json_output)
18511     {
18512       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18513     }
18514
18515   M (SHOW_ONE_USE_PETR, mp);
18516   /* send it... */
18517   S (mp);
18518
18519   /* Wait for a reply... */
18520   W (ret);
18521   return ret;
18522 }
18523
18524 #define api_show_lisp_use_petr api_show_one_use_petr
18525
18526 /**
18527  * Add/delete mapping between vni and vrf
18528  */
18529 static int
18530 api_one_eid_table_add_del_map (vat_main_t * vam)
18531 {
18532   unformat_input_t *input = vam->input;
18533   vl_api_one_eid_table_add_del_map_t *mp;
18534   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18535   u32 vni, vrf, bd_index;
18536   int ret;
18537
18538   /* Parse args required to build the message */
18539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18540     {
18541       if (unformat (input, "del"))
18542         is_add = 0;
18543       else if (unformat (input, "vrf %d", &vrf))
18544         vrf_set = 1;
18545       else if (unformat (input, "bd_index %d", &bd_index))
18546         bd_index_set = 1;
18547       else if (unformat (input, "vni %d", &vni))
18548         vni_set = 1;
18549       else
18550         break;
18551     }
18552
18553   if (!vni_set || (!vrf_set && !bd_index_set))
18554     {
18555       errmsg ("missing arguments!");
18556       return -99;
18557     }
18558
18559   if (vrf_set && bd_index_set)
18560     {
18561       errmsg ("error: both vrf and bd entered!");
18562       return -99;
18563     }
18564
18565   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18566
18567   mp->is_add = is_add;
18568   mp->vni = htonl (vni);
18569   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18570   mp->is_l2 = bd_index_set;
18571
18572   /* send */
18573   S (mp);
18574
18575   /* wait for reply */
18576   W (ret);
18577   return ret;
18578 }
18579
18580 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18581
18582 uword
18583 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18584 {
18585   u32 *action = va_arg (*args, u32 *);
18586   u8 *s = 0;
18587
18588   if (unformat (input, "%s", &s))
18589     {
18590       if (!strcmp ((char *) s, "no-action"))
18591         action[0] = 0;
18592       else if (!strcmp ((char *) s, "natively-forward"))
18593         action[0] = 1;
18594       else if (!strcmp ((char *) s, "send-map-request"))
18595         action[0] = 2;
18596       else if (!strcmp ((char *) s, "drop"))
18597         action[0] = 3;
18598       else
18599         {
18600           clib_warning ("invalid action: '%s'", s);
18601           action[0] = 3;
18602         }
18603     }
18604   else
18605     return 0;
18606
18607   vec_free (s);
18608   return 1;
18609 }
18610
18611 /**
18612  * Add/del remote mapping to/from ONE control plane
18613  *
18614  * @param vam vpp API test context
18615  * @return return code
18616  */
18617 static int
18618 api_one_add_del_remote_mapping (vat_main_t * vam)
18619 {
18620   unformat_input_t *input = vam->input;
18621   vl_api_one_add_del_remote_mapping_t *mp;
18622   u32 vni = 0;
18623   lisp_eid_vat_t _eid, *eid = &_eid;
18624   lisp_eid_vat_t _seid, *seid = &_seid;
18625   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18626   u32 action = ~0, p, w, data_len;
18627   ip4_address_t rloc4;
18628   ip6_address_t rloc6;
18629   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18630   int ret;
18631
18632   clib_memset (&rloc, 0, sizeof (rloc));
18633
18634   /* Parse args required to build the message */
18635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18636     {
18637       if (unformat (input, "del-all"))
18638         {
18639           del_all = 1;
18640         }
18641       else if (unformat (input, "del"))
18642         {
18643           is_add = 0;
18644         }
18645       else if (unformat (input, "add"))
18646         {
18647           is_add = 1;
18648         }
18649       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18650         {
18651           eid_set = 1;
18652         }
18653       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18654         {
18655           seid_set = 1;
18656         }
18657       else if (unformat (input, "vni %d", &vni))
18658         {
18659           ;
18660         }
18661       else if (unformat (input, "p %d w %d", &p, &w))
18662         {
18663           if (!curr_rloc)
18664             {
18665               errmsg ("No RLOC configured for setting priority/weight!");
18666               return -99;
18667             }
18668           curr_rloc->priority = p;
18669           curr_rloc->weight = w;
18670         }
18671       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18672         {
18673           rloc.is_ip4 = 1;
18674           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18675           vec_add1 (rlocs, rloc);
18676           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18677         }
18678       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18679         {
18680           rloc.is_ip4 = 0;
18681           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18682           vec_add1 (rlocs, rloc);
18683           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18684         }
18685       else if (unformat (input, "action %U",
18686                          unformat_negative_mapping_action, &action))
18687         {
18688           ;
18689         }
18690       else
18691         {
18692           clib_warning ("parse error '%U'", format_unformat_error, input);
18693           return -99;
18694         }
18695     }
18696
18697   if (0 == eid_set)
18698     {
18699       errmsg ("missing params!");
18700       return -99;
18701     }
18702
18703   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18704     {
18705       errmsg ("no action set for negative map-reply!");
18706       return -99;
18707     }
18708
18709   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18710
18711   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18712   mp->is_add = is_add;
18713   mp->vni = htonl (vni);
18714   mp->action = (u8) action;
18715   mp->is_src_dst = seid_set;
18716   mp->eid_len = eid->len;
18717   mp->seid_len = seid->len;
18718   mp->del_all = del_all;
18719   mp->eid_type = eid->type;
18720   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18721   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18722
18723   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18724   clib_memcpy (mp->rlocs, rlocs, data_len);
18725   vec_free (rlocs);
18726
18727   /* send it... */
18728   S (mp);
18729
18730   /* Wait for a reply... */
18731   W (ret);
18732   return ret;
18733 }
18734
18735 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18736
18737 /**
18738  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18739  * forwarding entries in data-plane accordingly.
18740  *
18741  * @param vam vpp API test context
18742  * @return return code
18743  */
18744 static int
18745 api_one_add_del_adjacency (vat_main_t * vam)
18746 {
18747   unformat_input_t *input = vam->input;
18748   vl_api_one_add_del_adjacency_t *mp;
18749   u32 vni = 0;
18750   ip4_address_t leid4, reid4;
18751   ip6_address_t leid6, reid6;
18752   u8 reid_mac[6] = { 0 };
18753   u8 leid_mac[6] = { 0 };
18754   u8 reid_type, leid_type;
18755   u32 leid_len = 0, reid_len = 0, len;
18756   u8 is_add = 1;
18757   int ret;
18758
18759   leid_type = reid_type = (u8) ~ 0;
18760
18761   /* Parse args required to build the message */
18762   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18763     {
18764       if (unformat (input, "del"))
18765         {
18766           is_add = 0;
18767         }
18768       else if (unformat (input, "add"))
18769         {
18770           is_add = 1;
18771         }
18772       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18773                          &reid4, &len))
18774         {
18775           reid_type = 0;        /* ipv4 */
18776           reid_len = len;
18777         }
18778       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18779                          &reid6, &len))
18780         {
18781           reid_type = 1;        /* ipv6 */
18782           reid_len = len;
18783         }
18784       else if (unformat (input, "reid %U", unformat_ethernet_address,
18785                          reid_mac))
18786         {
18787           reid_type = 2;        /* mac */
18788         }
18789       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18790                          &leid4, &len))
18791         {
18792           leid_type = 0;        /* ipv4 */
18793           leid_len = len;
18794         }
18795       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18796                          &leid6, &len))
18797         {
18798           leid_type = 1;        /* ipv6 */
18799           leid_len = len;
18800         }
18801       else if (unformat (input, "leid %U", unformat_ethernet_address,
18802                          leid_mac))
18803         {
18804           leid_type = 2;        /* mac */
18805         }
18806       else if (unformat (input, "vni %d", &vni))
18807         {
18808           ;
18809         }
18810       else
18811         {
18812           errmsg ("parse error '%U'", format_unformat_error, input);
18813           return -99;
18814         }
18815     }
18816
18817   if ((u8) ~ 0 == reid_type)
18818     {
18819       errmsg ("missing params!");
18820       return -99;
18821     }
18822
18823   if (leid_type != reid_type)
18824     {
18825       errmsg ("remote and local EIDs are of different types!");
18826       return -99;
18827     }
18828
18829   M (ONE_ADD_DEL_ADJACENCY, mp);
18830   mp->is_add = is_add;
18831   mp->vni = htonl (vni);
18832   mp->leid_len = leid_len;
18833   mp->reid_len = reid_len;
18834   mp->eid_type = reid_type;
18835
18836   switch (mp->eid_type)
18837     {
18838     case 0:
18839       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18840       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18841       break;
18842     case 1:
18843       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18844       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18845       break;
18846     case 2:
18847       clib_memcpy (mp->leid, leid_mac, 6);
18848       clib_memcpy (mp->reid, reid_mac, 6);
18849       break;
18850     default:
18851       errmsg ("unknown EID type %d!", mp->eid_type);
18852       return 0;
18853     }
18854
18855   /* send it... */
18856   S (mp);
18857
18858   /* Wait for a reply... */
18859   W (ret);
18860   return ret;
18861 }
18862
18863 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18864
18865 uword
18866 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18867 {
18868   u32 *mode = va_arg (*args, u32 *);
18869
18870   if (unformat (input, "lisp"))
18871     *mode = 0;
18872   else if (unformat (input, "vxlan"))
18873     *mode = 1;
18874   else
18875     return 0;
18876
18877   return 1;
18878 }
18879
18880 static int
18881 api_gpe_get_encap_mode (vat_main_t * vam)
18882 {
18883   vl_api_gpe_get_encap_mode_t *mp;
18884   int ret;
18885
18886   /* Construct the API message */
18887   M (GPE_GET_ENCAP_MODE, mp);
18888
18889   /* send it... */
18890   S (mp);
18891
18892   /* Wait for a reply... */
18893   W (ret);
18894   return ret;
18895 }
18896
18897 static int
18898 api_gpe_set_encap_mode (vat_main_t * vam)
18899 {
18900   unformat_input_t *input = vam->input;
18901   vl_api_gpe_set_encap_mode_t *mp;
18902   int ret;
18903   u32 mode = 0;
18904
18905   /* Parse args required to build the message */
18906   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18907     {
18908       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18909         ;
18910       else
18911         break;
18912     }
18913
18914   /* Construct the API message */
18915   M (GPE_SET_ENCAP_MODE, mp);
18916
18917   mp->mode = mode;
18918
18919   /* send it... */
18920   S (mp);
18921
18922   /* Wait for a reply... */
18923   W (ret);
18924   return ret;
18925 }
18926
18927 static int
18928 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18929 {
18930   unformat_input_t *input = vam->input;
18931   vl_api_gpe_add_del_iface_t *mp;
18932   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18933   u32 dp_table = 0, vni = 0;
18934   int ret;
18935
18936   /* Parse args required to build the message */
18937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18938     {
18939       if (unformat (input, "up"))
18940         {
18941           action_set = 1;
18942           is_add = 1;
18943         }
18944       else if (unformat (input, "down"))
18945         {
18946           action_set = 1;
18947           is_add = 0;
18948         }
18949       else if (unformat (input, "table_id %d", &dp_table))
18950         {
18951           dp_table_set = 1;
18952         }
18953       else if (unformat (input, "bd_id %d", &dp_table))
18954         {
18955           dp_table_set = 1;
18956           is_l2 = 1;
18957         }
18958       else if (unformat (input, "vni %d", &vni))
18959         {
18960           vni_set = 1;
18961         }
18962       else
18963         break;
18964     }
18965
18966   if (action_set == 0)
18967     {
18968       errmsg ("Action not set");
18969       return -99;
18970     }
18971   if (dp_table_set == 0 || vni_set == 0)
18972     {
18973       errmsg ("vni and dp_table must be set");
18974       return -99;
18975     }
18976
18977   /* Construct the API message */
18978   M (GPE_ADD_DEL_IFACE, mp);
18979
18980   mp->is_add = is_add;
18981   mp->dp_table = clib_host_to_net_u32 (dp_table);
18982   mp->is_l2 = is_l2;
18983   mp->vni = clib_host_to_net_u32 (vni);
18984
18985   /* send it... */
18986   S (mp);
18987
18988   /* Wait for a reply... */
18989   W (ret);
18990   return ret;
18991 }
18992
18993 static int
18994 api_one_map_register_fallback_threshold (vat_main_t * vam)
18995 {
18996   unformat_input_t *input = vam->input;
18997   vl_api_one_map_register_fallback_threshold_t *mp;
18998   u32 value = 0;
18999   u8 is_set = 0;
19000   int ret;
19001
19002   /* Parse args required to build the message */
19003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19004     {
19005       if (unformat (input, "%u", &value))
19006         is_set = 1;
19007       else
19008         {
19009           clib_warning ("parse error '%U'", format_unformat_error, input);
19010           return -99;
19011         }
19012     }
19013
19014   if (!is_set)
19015     {
19016       errmsg ("fallback threshold value is missing!");
19017       return -99;
19018     }
19019
19020   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19021   mp->value = clib_host_to_net_u32 (value);
19022
19023   /* send it... */
19024   S (mp);
19025
19026   /* Wait for a reply... */
19027   W (ret);
19028   return ret;
19029 }
19030
19031 static int
19032 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
19033 {
19034   vl_api_show_one_map_register_fallback_threshold_t *mp;
19035   int ret;
19036
19037   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19038
19039   /* send it... */
19040   S (mp);
19041
19042   /* Wait for a reply... */
19043   W (ret);
19044   return ret;
19045 }
19046
19047 uword
19048 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
19049 {
19050   u32 *proto = va_arg (*args, u32 *);
19051
19052   if (unformat (input, "udp"))
19053     *proto = 1;
19054   else if (unformat (input, "api"))
19055     *proto = 2;
19056   else
19057     return 0;
19058
19059   return 1;
19060 }
19061
19062 static int
19063 api_one_set_transport_protocol (vat_main_t * vam)
19064 {
19065   unformat_input_t *input = vam->input;
19066   vl_api_one_set_transport_protocol_t *mp;
19067   u8 is_set = 0;
19068   u32 protocol = 0;
19069   int ret;
19070
19071   /* Parse args required to build the message */
19072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19073     {
19074       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
19075         is_set = 1;
19076       else
19077         {
19078           clib_warning ("parse error '%U'", format_unformat_error, input);
19079           return -99;
19080         }
19081     }
19082
19083   if (!is_set)
19084     {
19085       errmsg ("Transport protocol missing!");
19086       return -99;
19087     }
19088
19089   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
19090   mp->protocol = (u8) protocol;
19091
19092   /* send it... */
19093   S (mp);
19094
19095   /* Wait for a reply... */
19096   W (ret);
19097   return ret;
19098 }
19099
19100 static int
19101 api_one_get_transport_protocol (vat_main_t * vam)
19102 {
19103   vl_api_one_get_transport_protocol_t *mp;
19104   int ret;
19105
19106   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19107
19108   /* send it... */
19109   S (mp);
19110
19111   /* Wait for a reply... */
19112   W (ret);
19113   return ret;
19114 }
19115
19116 static int
19117 api_one_map_register_set_ttl (vat_main_t * vam)
19118 {
19119   unformat_input_t *input = vam->input;
19120   vl_api_one_map_register_set_ttl_t *mp;
19121   u32 ttl = 0;
19122   u8 is_set = 0;
19123   int ret;
19124
19125   /* Parse args required to build the message */
19126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19127     {
19128       if (unformat (input, "%u", &ttl))
19129         is_set = 1;
19130       else
19131         {
19132           clib_warning ("parse error '%U'", format_unformat_error, input);
19133           return -99;
19134         }
19135     }
19136
19137   if (!is_set)
19138     {
19139       errmsg ("TTL value missing!");
19140       return -99;
19141     }
19142
19143   M (ONE_MAP_REGISTER_SET_TTL, mp);
19144   mp->ttl = clib_host_to_net_u32 (ttl);
19145
19146   /* send it... */
19147   S (mp);
19148
19149   /* Wait for a reply... */
19150   W (ret);
19151   return ret;
19152 }
19153
19154 static int
19155 api_show_one_map_register_ttl (vat_main_t * vam)
19156 {
19157   vl_api_show_one_map_register_ttl_t *mp;
19158   int ret;
19159
19160   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19161
19162   /* send it... */
19163   S (mp);
19164
19165   /* Wait for a reply... */
19166   W (ret);
19167   return ret;
19168 }
19169
19170 /**
19171  * Add/del map request itr rlocs from ONE control plane and updates
19172  *
19173  * @param vam vpp API test context
19174  * @return return code
19175  */
19176 static int
19177 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19178 {
19179   unformat_input_t *input = vam->input;
19180   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19181   u8 *locator_set_name = 0;
19182   u8 locator_set_name_set = 0;
19183   u8 is_add = 1;
19184   int ret;
19185
19186   /* Parse args required to build the message */
19187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19188     {
19189       if (unformat (input, "del"))
19190         {
19191           is_add = 0;
19192         }
19193       else if (unformat (input, "%_%v%_", &locator_set_name))
19194         {
19195           locator_set_name_set = 1;
19196         }
19197       else
19198         {
19199           clib_warning ("parse error '%U'", format_unformat_error, input);
19200           return -99;
19201         }
19202     }
19203
19204   if (is_add && !locator_set_name_set)
19205     {
19206       errmsg ("itr-rloc is not set!");
19207       return -99;
19208     }
19209
19210   if (is_add && vec_len (locator_set_name) > 64)
19211     {
19212       errmsg ("itr-rloc locator-set name too long");
19213       vec_free (locator_set_name);
19214       return -99;
19215     }
19216
19217   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19218   mp->is_add = is_add;
19219   if (is_add)
19220     {
19221       clib_memcpy (mp->locator_set_name, locator_set_name,
19222                    vec_len (locator_set_name));
19223     }
19224   else
19225     {
19226       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19227     }
19228   vec_free (locator_set_name);
19229
19230   /* send it... */
19231   S (mp);
19232
19233   /* Wait for a reply... */
19234   W (ret);
19235   return ret;
19236 }
19237
19238 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19239
19240 static int
19241 api_one_locator_dump (vat_main_t * vam)
19242 {
19243   unformat_input_t *input = vam->input;
19244   vl_api_one_locator_dump_t *mp;
19245   vl_api_control_ping_t *mp_ping;
19246   u8 is_index_set = 0, is_name_set = 0;
19247   u8 *ls_name = 0;
19248   u32 ls_index = ~0;
19249   int ret;
19250
19251   /* Parse args required to build the message */
19252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19253     {
19254       if (unformat (input, "ls_name %_%v%_", &ls_name))
19255         {
19256           is_name_set = 1;
19257         }
19258       else if (unformat (input, "ls_index %d", &ls_index))
19259         {
19260           is_index_set = 1;
19261         }
19262       else
19263         {
19264           errmsg ("parse error '%U'", format_unformat_error, input);
19265           return -99;
19266         }
19267     }
19268
19269   if (!is_index_set && !is_name_set)
19270     {
19271       errmsg ("error: expected one of index or name!");
19272       return -99;
19273     }
19274
19275   if (is_index_set && is_name_set)
19276     {
19277       errmsg ("error: only one param expected!");
19278       return -99;
19279     }
19280
19281   if (vec_len (ls_name) > 62)
19282     {
19283       errmsg ("error: locator set name too long!");
19284       return -99;
19285     }
19286
19287   if (!vam->json_output)
19288     {
19289       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19290     }
19291
19292   M (ONE_LOCATOR_DUMP, mp);
19293   mp->is_index_set = is_index_set;
19294
19295   if (is_index_set)
19296     mp->ls_index = clib_host_to_net_u32 (ls_index);
19297   else
19298     {
19299       vec_add1 (ls_name, 0);
19300       strncpy ((char *) mp->ls_name, (char *) ls_name,
19301                sizeof (mp->ls_name) - 1);
19302     }
19303
19304   /* send it... */
19305   S (mp);
19306
19307   /* Use a control ping for synchronization */
19308   MPING (CONTROL_PING, mp_ping);
19309   S (mp_ping);
19310
19311   /* Wait for a reply... */
19312   W (ret);
19313   return ret;
19314 }
19315
19316 #define api_lisp_locator_dump api_one_locator_dump
19317
19318 static int
19319 api_one_locator_set_dump (vat_main_t * vam)
19320 {
19321   vl_api_one_locator_set_dump_t *mp;
19322   vl_api_control_ping_t *mp_ping;
19323   unformat_input_t *input = vam->input;
19324   u8 filter = 0;
19325   int ret;
19326
19327   /* Parse args required to build the message */
19328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19329     {
19330       if (unformat (input, "local"))
19331         {
19332           filter = 1;
19333         }
19334       else if (unformat (input, "remote"))
19335         {
19336           filter = 2;
19337         }
19338       else
19339         {
19340           errmsg ("parse error '%U'", format_unformat_error, input);
19341           return -99;
19342         }
19343     }
19344
19345   if (!vam->json_output)
19346     {
19347       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19348     }
19349
19350   M (ONE_LOCATOR_SET_DUMP, mp);
19351
19352   mp->filter = filter;
19353
19354   /* send it... */
19355   S (mp);
19356
19357   /* Use a control ping for synchronization */
19358   MPING (CONTROL_PING, mp_ping);
19359   S (mp_ping);
19360
19361   /* Wait for a reply... */
19362   W (ret);
19363   return ret;
19364 }
19365
19366 #define api_lisp_locator_set_dump api_one_locator_set_dump
19367
19368 static int
19369 api_one_eid_table_map_dump (vat_main_t * vam)
19370 {
19371   u8 is_l2 = 0;
19372   u8 mode_set = 0;
19373   unformat_input_t *input = vam->input;
19374   vl_api_one_eid_table_map_dump_t *mp;
19375   vl_api_control_ping_t *mp_ping;
19376   int ret;
19377
19378   /* Parse args required to build the message */
19379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19380     {
19381       if (unformat (input, "l2"))
19382         {
19383           is_l2 = 1;
19384           mode_set = 1;
19385         }
19386       else if (unformat (input, "l3"))
19387         {
19388           is_l2 = 0;
19389           mode_set = 1;
19390         }
19391       else
19392         {
19393           errmsg ("parse error '%U'", format_unformat_error, input);
19394           return -99;
19395         }
19396     }
19397
19398   if (!mode_set)
19399     {
19400       errmsg ("expected one of 'l2' or 'l3' parameter!");
19401       return -99;
19402     }
19403
19404   if (!vam->json_output)
19405     {
19406       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19407     }
19408
19409   M (ONE_EID_TABLE_MAP_DUMP, mp);
19410   mp->is_l2 = is_l2;
19411
19412   /* send it... */
19413   S (mp);
19414
19415   /* Use a control ping for synchronization */
19416   MPING (CONTROL_PING, mp_ping);
19417   S (mp_ping);
19418
19419   /* Wait for a reply... */
19420   W (ret);
19421   return ret;
19422 }
19423
19424 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19425
19426 static int
19427 api_one_eid_table_vni_dump (vat_main_t * vam)
19428 {
19429   vl_api_one_eid_table_vni_dump_t *mp;
19430   vl_api_control_ping_t *mp_ping;
19431   int ret;
19432
19433   if (!vam->json_output)
19434     {
19435       print (vam->ofp, "VNI");
19436     }
19437
19438   M (ONE_EID_TABLE_VNI_DUMP, mp);
19439
19440   /* send it... */
19441   S (mp);
19442
19443   /* Use a control ping for synchronization */
19444   MPING (CONTROL_PING, mp_ping);
19445   S (mp_ping);
19446
19447   /* Wait for a reply... */
19448   W (ret);
19449   return ret;
19450 }
19451
19452 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19453
19454 static int
19455 api_one_eid_table_dump (vat_main_t * vam)
19456 {
19457   unformat_input_t *i = vam->input;
19458   vl_api_one_eid_table_dump_t *mp;
19459   vl_api_control_ping_t *mp_ping;
19460   struct in_addr ip4;
19461   struct in6_addr ip6;
19462   u8 mac[6];
19463   u8 eid_type = ~0, eid_set = 0;
19464   u32 prefix_length = ~0, t, vni = 0;
19465   u8 filter = 0;
19466   int ret;
19467   lisp_nsh_api_t nsh;
19468
19469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19470     {
19471       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19472         {
19473           eid_set = 1;
19474           eid_type = 0;
19475           prefix_length = t;
19476         }
19477       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19478         {
19479           eid_set = 1;
19480           eid_type = 1;
19481           prefix_length = t;
19482         }
19483       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19484         {
19485           eid_set = 1;
19486           eid_type = 2;
19487         }
19488       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19489         {
19490           eid_set = 1;
19491           eid_type = 3;
19492         }
19493       else if (unformat (i, "vni %d", &t))
19494         {
19495           vni = t;
19496         }
19497       else if (unformat (i, "local"))
19498         {
19499           filter = 1;
19500         }
19501       else if (unformat (i, "remote"))
19502         {
19503           filter = 2;
19504         }
19505       else
19506         {
19507           errmsg ("parse error '%U'", format_unformat_error, i);
19508           return -99;
19509         }
19510     }
19511
19512   if (!vam->json_output)
19513     {
19514       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19515              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19516     }
19517
19518   M (ONE_EID_TABLE_DUMP, mp);
19519
19520   mp->filter = filter;
19521   if (eid_set)
19522     {
19523       mp->eid_set = 1;
19524       mp->vni = htonl (vni);
19525       mp->eid_type = eid_type;
19526       switch (eid_type)
19527         {
19528         case 0:
19529           mp->prefix_length = prefix_length;
19530           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19531           break;
19532         case 1:
19533           mp->prefix_length = prefix_length;
19534           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19535           break;
19536         case 2:
19537           clib_memcpy (mp->eid, mac, sizeof (mac));
19538           break;
19539         case 3:
19540           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19541           break;
19542         default:
19543           errmsg ("unknown EID type %d!", eid_type);
19544           return -99;
19545         }
19546     }
19547
19548   /* send it... */
19549   S (mp);
19550
19551   /* Use a control ping for synchronization */
19552   MPING (CONTROL_PING, mp_ping);
19553   S (mp_ping);
19554
19555   /* Wait for a reply... */
19556   W (ret);
19557   return ret;
19558 }
19559
19560 #define api_lisp_eid_table_dump api_one_eid_table_dump
19561
19562 static int
19563 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19564 {
19565   unformat_input_t *i = vam->input;
19566   vl_api_gpe_fwd_entries_get_t *mp;
19567   u8 vni_set = 0;
19568   u32 vni = ~0;
19569   int ret;
19570
19571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19572     {
19573       if (unformat (i, "vni %d", &vni))
19574         {
19575           vni_set = 1;
19576         }
19577       else
19578         {
19579           errmsg ("parse error '%U'", format_unformat_error, i);
19580           return -99;
19581         }
19582     }
19583
19584   if (!vni_set)
19585     {
19586       errmsg ("vni not set!");
19587       return -99;
19588     }
19589
19590   if (!vam->json_output)
19591     {
19592       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19593              "leid", "reid");
19594     }
19595
19596   M (GPE_FWD_ENTRIES_GET, mp);
19597   mp->vni = clib_host_to_net_u32 (vni);
19598
19599   /* send it... */
19600   S (mp);
19601
19602   /* Wait for a reply... */
19603   W (ret);
19604   return ret;
19605 }
19606
19607 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19608 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19609 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19610 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19611 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19612 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19613 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19614 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19615
19616 static int
19617 api_one_adjacencies_get (vat_main_t * vam)
19618 {
19619   unformat_input_t *i = vam->input;
19620   vl_api_one_adjacencies_get_t *mp;
19621   u8 vni_set = 0;
19622   u32 vni = ~0;
19623   int ret;
19624
19625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19626     {
19627       if (unformat (i, "vni %d", &vni))
19628         {
19629           vni_set = 1;
19630         }
19631       else
19632         {
19633           errmsg ("parse error '%U'", format_unformat_error, i);
19634           return -99;
19635         }
19636     }
19637
19638   if (!vni_set)
19639     {
19640       errmsg ("vni not set!");
19641       return -99;
19642     }
19643
19644   if (!vam->json_output)
19645     {
19646       print (vam->ofp, "%s %40s", "leid", "reid");
19647     }
19648
19649   M (ONE_ADJACENCIES_GET, mp);
19650   mp->vni = clib_host_to_net_u32 (vni);
19651
19652   /* send it... */
19653   S (mp);
19654
19655   /* Wait for a reply... */
19656   W (ret);
19657   return ret;
19658 }
19659
19660 #define api_lisp_adjacencies_get api_one_adjacencies_get
19661
19662 static int
19663 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19664 {
19665   unformat_input_t *i = vam->input;
19666   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19667   int ret;
19668   u8 ip_family_set = 0, is_ip4 = 1;
19669
19670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19671     {
19672       if (unformat (i, "ip4"))
19673         {
19674           ip_family_set = 1;
19675           is_ip4 = 1;
19676         }
19677       else if (unformat (i, "ip6"))
19678         {
19679           ip_family_set = 1;
19680           is_ip4 = 0;
19681         }
19682       else
19683         {
19684           errmsg ("parse error '%U'", format_unformat_error, i);
19685           return -99;
19686         }
19687     }
19688
19689   if (!ip_family_set)
19690     {
19691       errmsg ("ip family not set!");
19692       return -99;
19693     }
19694
19695   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19696   mp->is_ip4 = is_ip4;
19697
19698   /* send it... */
19699   S (mp);
19700
19701   /* Wait for a reply... */
19702   W (ret);
19703   return ret;
19704 }
19705
19706 static int
19707 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19708 {
19709   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19710   int ret;
19711
19712   if (!vam->json_output)
19713     {
19714       print (vam->ofp, "VNIs");
19715     }
19716
19717   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19718
19719   /* send it... */
19720   S (mp);
19721
19722   /* Wait for a reply... */
19723   W (ret);
19724   return ret;
19725 }
19726
19727 static int
19728 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19729 {
19730   unformat_input_t *i = vam->input;
19731   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19732   int ret = 0;
19733   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19734   struct in_addr ip4;
19735   struct in6_addr ip6;
19736   u32 table_id = 0, nh_sw_if_index = ~0;
19737
19738   clib_memset (&ip4, 0, sizeof (ip4));
19739   clib_memset (&ip6, 0, sizeof (ip6));
19740
19741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19742     {
19743       if (unformat (i, "del"))
19744         is_add = 0;
19745       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19746                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19747         {
19748           ip_set = 1;
19749           is_ip4 = 1;
19750         }
19751       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19752                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19753         {
19754           ip_set = 1;
19755           is_ip4 = 0;
19756         }
19757       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19758         {
19759           ip_set = 1;
19760           is_ip4 = 1;
19761           nh_sw_if_index = ~0;
19762         }
19763       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19764         {
19765           ip_set = 1;
19766           is_ip4 = 0;
19767           nh_sw_if_index = ~0;
19768         }
19769       else if (unformat (i, "table %d", &table_id))
19770         ;
19771       else
19772         {
19773           errmsg ("parse error '%U'", format_unformat_error, i);
19774           return -99;
19775         }
19776     }
19777
19778   if (!ip_set)
19779     {
19780       errmsg ("nh addr not set!");
19781       return -99;
19782     }
19783
19784   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19785   mp->is_add = is_add;
19786   mp->table_id = clib_host_to_net_u32 (table_id);
19787   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19788   mp->is_ip4 = is_ip4;
19789   if (is_ip4)
19790     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19791   else
19792     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19793
19794   /* send it... */
19795   S (mp);
19796
19797   /* Wait for a reply... */
19798   W (ret);
19799   return ret;
19800 }
19801
19802 static int
19803 api_one_map_server_dump (vat_main_t * vam)
19804 {
19805   vl_api_one_map_server_dump_t *mp;
19806   vl_api_control_ping_t *mp_ping;
19807   int ret;
19808
19809   if (!vam->json_output)
19810     {
19811       print (vam->ofp, "%=20s", "Map server");
19812     }
19813
19814   M (ONE_MAP_SERVER_DUMP, mp);
19815   /* send it... */
19816   S (mp);
19817
19818   /* Use a control ping for synchronization */
19819   MPING (CONTROL_PING, mp_ping);
19820   S (mp_ping);
19821
19822   /* Wait for a reply... */
19823   W (ret);
19824   return ret;
19825 }
19826
19827 #define api_lisp_map_server_dump api_one_map_server_dump
19828
19829 static int
19830 api_one_map_resolver_dump (vat_main_t * vam)
19831 {
19832   vl_api_one_map_resolver_dump_t *mp;
19833   vl_api_control_ping_t *mp_ping;
19834   int ret;
19835
19836   if (!vam->json_output)
19837     {
19838       print (vam->ofp, "%=20s", "Map resolver");
19839     }
19840
19841   M (ONE_MAP_RESOLVER_DUMP, mp);
19842   /* send it... */
19843   S (mp);
19844
19845   /* Use a control ping for synchronization */
19846   MPING (CONTROL_PING, mp_ping);
19847   S (mp_ping);
19848
19849   /* Wait for a reply... */
19850   W (ret);
19851   return ret;
19852 }
19853
19854 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19855
19856 static int
19857 api_one_stats_flush (vat_main_t * vam)
19858 {
19859   vl_api_one_stats_flush_t *mp;
19860   int ret = 0;
19861
19862   M (ONE_STATS_FLUSH, mp);
19863   S (mp);
19864   W (ret);
19865   return ret;
19866 }
19867
19868 static int
19869 api_one_stats_dump (vat_main_t * vam)
19870 {
19871   vl_api_one_stats_dump_t *mp;
19872   vl_api_control_ping_t *mp_ping;
19873   int ret;
19874
19875   M (ONE_STATS_DUMP, mp);
19876   /* send it... */
19877   S (mp);
19878
19879   /* Use a control ping for synchronization */
19880   MPING (CONTROL_PING, mp_ping);
19881   S (mp_ping);
19882
19883   /* Wait for a reply... */
19884   W (ret);
19885   return ret;
19886 }
19887
19888 static int
19889 api_show_one_status (vat_main_t * vam)
19890 {
19891   vl_api_show_one_status_t *mp;
19892   int ret;
19893
19894   if (!vam->json_output)
19895     {
19896       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19897     }
19898
19899   M (SHOW_ONE_STATUS, mp);
19900   /* send it... */
19901   S (mp);
19902   /* Wait for a reply... */
19903   W (ret);
19904   return ret;
19905 }
19906
19907 #define api_show_lisp_status api_show_one_status
19908
19909 static int
19910 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19911 {
19912   vl_api_gpe_fwd_entry_path_dump_t *mp;
19913   vl_api_control_ping_t *mp_ping;
19914   unformat_input_t *i = vam->input;
19915   u32 fwd_entry_index = ~0;
19916   int ret;
19917
19918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19919     {
19920       if (unformat (i, "index %d", &fwd_entry_index))
19921         ;
19922       else
19923         break;
19924     }
19925
19926   if (~0 == fwd_entry_index)
19927     {
19928       errmsg ("no index specified!");
19929       return -99;
19930     }
19931
19932   if (!vam->json_output)
19933     {
19934       print (vam->ofp, "first line");
19935     }
19936
19937   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19938
19939   /* send it... */
19940   S (mp);
19941   /* Use a control ping for synchronization */
19942   MPING (CONTROL_PING, mp_ping);
19943   S (mp_ping);
19944
19945   /* Wait for a reply... */
19946   W (ret);
19947   return ret;
19948 }
19949
19950 static int
19951 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19952 {
19953   vl_api_one_get_map_request_itr_rlocs_t *mp;
19954   int ret;
19955
19956   if (!vam->json_output)
19957     {
19958       print (vam->ofp, "%=20s", "itr-rlocs:");
19959     }
19960
19961   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19962   /* send it... */
19963   S (mp);
19964   /* Wait for a reply... */
19965   W (ret);
19966   return ret;
19967 }
19968
19969 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19970
19971 static int
19972 api_af_packet_create (vat_main_t * vam)
19973 {
19974   unformat_input_t *i = vam->input;
19975   vl_api_af_packet_create_t *mp;
19976   u8 *host_if_name = 0;
19977   u8 hw_addr[6];
19978   u8 random_hw_addr = 1;
19979   int ret;
19980
19981   clib_memset (hw_addr, 0, sizeof (hw_addr));
19982
19983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19984     {
19985       if (unformat (i, "name %s", &host_if_name))
19986         vec_add1 (host_if_name, 0);
19987       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19988         random_hw_addr = 0;
19989       else
19990         break;
19991     }
19992
19993   if (!vec_len (host_if_name))
19994     {
19995       errmsg ("host-interface name must be specified");
19996       return -99;
19997     }
19998
19999   if (vec_len (host_if_name) > 64)
20000     {
20001       errmsg ("host-interface name too long");
20002       return -99;
20003     }
20004
20005   M (AF_PACKET_CREATE, mp);
20006
20007   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20008   clib_memcpy (mp->hw_addr, hw_addr, 6);
20009   mp->use_random_hw_addr = random_hw_addr;
20010   vec_free (host_if_name);
20011
20012   S (mp);
20013
20014   /* *INDENT-OFF* */
20015   W2 (ret,
20016       ({
20017         if (ret == 0)
20018           fprintf (vam->ofp ? vam->ofp : stderr,
20019                    " new sw_if_index = %d\n", vam->sw_if_index);
20020       }));
20021   /* *INDENT-ON* */
20022   return ret;
20023 }
20024
20025 static int
20026 api_af_packet_delete (vat_main_t * vam)
20027 {
20028   unformat_input_t *i = vam->input;
20029   vl_api_af_packet_delete_t *mp;
20030   u8 *host_if_name = 0;
20031   int ret;
20032
20033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20034     {
20035       if (unformat (i, "name %s", &host_if_name))
20036         vec_add1 (host_if_name, 0);
20037       else
20038         break;
20039     }
20040
20041   if (!vec_len (host_if_name))
20042     {
20043       errmsg ("host-interface name must be specified");
20044       return -99;
20045     }
20046
20047   if (vec_len (host_if_name) > 64)
20048     {
20049       errmsg ("host-interface name too long");
20050       return -99;
20051     }
20052
20053   M (AF_PACKET_DELETE, mp);
20054
20055   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20056   vec_free (host_if_name);
20057
20058   S (mp);
20059   W (ret);
20060   return ret;
20061 }
20062
20063 static void vl_api_af_packet_details_t_handler
20064   (vl_api_af_packet_details_t * mp)
20065 {
20066   vat_main_t *vam = &vat_main;
20067
20068   print (vam->ofp, "%-16s %d",
20069          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
20070 }
20071
20072 static void vl_api_af_packet_details_t_handler_json
20073   (vl_api_af_packet_details_t * mp)
20074 {
20075   vat_main_t *vam = &vat_main;
20076   vat_json_node_t *node = NULL;
20077
20078   if (VAT_JSON_ARRAY != vam->json_tree.type)
20079     {
20080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20081       vat_json_init_array (&vam->json_tree);
20082     }
20083   node = vat_json_array_add (&vam->json_tree);
20084
20085   vat_json_init_object (node);
20086   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20087   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
20088 }
20089
20090 static int
20091 api_af_packet_dump (vat_main_t * vam)
20092 {
20093   vl_api_af_packet_dump_t *mp;
20094   vl_api_control_ping_t *mp_ping;
20095   int ret;
20096
20097   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
20098   /* Get list of tap interfaces */
20099   M (AF_PACKET_DUMP, mp);
20100   S (mp);
20101
20102   /* Use a control ping for synchronization */
20103   MPING (CONTROL_PING, mp_ping);
20104   S (mp_ping);
20105
20106   W (ret);
20107   return ret;
20108 }
20109
20110 static int
20111 api_policer_add_del (vat_main_t * vam)
20112 {
20113   unformat_input_t *i = vam->input;
20114   vl_api_policer_add_del_t *mp;
20115   u8 is_add = 1;
20116   u8 *name = 0;
20117   u32 cir = 0;
20118   u32 eir = 0;
20119   u64 cb = 0;
20120   u64 eb = 0;
20121   u8 rate_type = 0;
20122   u8 round_type = 0;
20123   u8 type = 0;
20124   u8 color_aware = 0;
20125   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20126   int ret;
20127
20128   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20129   conform_action.dscp = 0;
20130   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20131   exceed_action.dscp = 0;
20132   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20133   violate_action.dscp = 0;
20134
20135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20136     {
20137       if (unformat (i, "del"))
20138         is_add = 0;
20139       else if (unformat (i, "name %s", &name))
20140         vec_add1 (name, 0);
20141       else if (unformat (i, "cir %u", &cir))
20142         ;
20143       else if (unformat (i, "eir %u", &eir))
20144         ;
20145       else if (unformat (i, "cb %u", &cb))
20146         ;
20147       else if (unformat (i, "eb %u", &eb))
20148         ;
20149       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20150                          &rate_type))
20151         ;
20152       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20153                          &round_type))
20154         ;
20155       else if (unformat (i, "type %U", unformat_policer_type, &type))
20156         ;
20157       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20158                          &conform_action))
20159         ;
20160       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20161                          &exceed_action))
20162         ;
20163       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20164                          &violate_action))
20165         ;
20166       else if (unformat (i, "color-aware"))
20167         color_aware = 1;
20168       else
20169         break;
20170     }
20171
20172   if (!vec_len (name))
20173     {
20174       errmsg ("policer name must be specified");
20175       return -99;
20176     }
20177
20178   if (vec_len (name) > 64)
20179     {
20180       errmsg ("policer name too long");
20181       return -99;
20182     }
20183
20184   M (POLICER_ADD_DEL, mp);
20185
20186   clib_memcpy (mp->name, name, vec_len (name));
20187   vec_free (name);
20188   mp->is_add = is_add;
20189   mp->cir = ntohl (cir);
20190   mp->eir = ntohl (eir);
20191   mp->cb = clib_net_to_host_u64 (cb);
20192   mp->eb = clib_net_to_host_u64 (eb);
20193   mp->rate_type = rate_type;
20194   mp->round_type = round_type;
20195   mp->type = type;
20196   mp->conform_action_type = conform_action.action_type;
20197   mp->conform_dscp = conform_action.dscp;
20198   mp->exceed_action_type = exceed_action.action_type;
20199   mp->exceed_dscp = exceed_action.dscp;
20200   mp->violate_action_type = violate_action.action_type;
20201   mp->violate_dscp = violate_action.dscp;
20202   mp->color_aware = color_aware;
20203
20204   S (mp);
20205   W (ret);
20206   return ret;
20207 }
20208
20209 static int
20210 api_policer_dump (vat_main_t * vam)
20211 {
20212   unformat_input_t *i = vam->input;
20213   vl_api_policer_dump_t *mp;
20214   vl_api_control_ping_t *mp_ping;
20215   u8 *match_name = 0;
20216   u8 match_name_valid = 0;
20217   int ret;
20218
20219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20220     {
20221       if (unformat (i, "name %s", &match_name))
20222         {
20223           vec_add1 (match_name, 0);
20224           match_name_valid = 1;
20225         }
20226       else
20227         break;
20228     }
20229
20230   M (POLICER_DUMP, mp);
20231   mp->match_name_valid = match_name_valid;
20232   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20233   vec_free (match_name);
20234   /* send it... */
20235   S (mp);
20236
20237   /* Use a control ping for synchronization */
20238   MPING (CONTROL_PING, mp_ping);
20239   S (mp_ping);
20240
20241   /* Wait for a reply... */
20242   W (ret);
20243   return ret;
20244 }
20245
20246 static int
20247 api_policer_classify_set_interface (vat_main_t * vam)
20248 {
20249   unformat_input_t *i = vam->input;
20250   vl_api_policer_classify_set_interface_t *mp;
20251   u32 sw_if_index;
20252   int sw_if_index_set;
20253   u32 ip4_table_index = ~0;
20254   u32 ip6_table_index = ~0;
20255   u32 l2_table_index = ~0;
20256   u8 is_add = 1;
20257   int ret;
20258
20259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20260     {
20261       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20262         sw_if_index_set = 1;
20263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20264         sw_if_index_set = 1;
20265       else if (unformat (i, "del"))
20266         is_add = 0;
20267       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20268         ;
20269       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20270         ;
20271       else if (unformat (i, "l2-table %d", &l2_table_index))
20272         ;
20273       else
20274         {
20275           clib_warning ("parse error '%U'", format_unformat_error, i);
20276           return -99;
20277         }
20278     }
20279
20280   if (sw_if_index_set == 0)
20281     {
20282       errmsg ("missing interface name or sw_if_index");
20283       return -99;
20284     }
20285
20286   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20287
20288   mp->sw_if_index = ntohl (sw_if_index);
20289   mp->ip4_table_index = ntohl (ip4_table_index);
20290   mp->ip6_table_index = ntohl (ip6_table_index);
20291   mp->l2_table_index = ntohl (l2_table_index);
20292   mp->is_add = is_add;
20293
20294   S (mp);
20295   W (ret);
20296   return ret;
20297 }
20298
20299 static int
20300 api_policer_classify_dump (vat_main_t * vam)
20301 {
20302   unformat_input_t *i = vam->input;
20303   vl_api_policer_classify_dump_t *mp;
20304   vl_api_control_ping_t *mp_ping;
20305   u8 type = POLICER_CLASSIFY_N_TABLES;
20306   int ret;
20307
20308   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20309     ;
20310   else
20311     {
20312       errmsg ("classify table type must be specified");
20313       return -99;
20314     }
20315
20316   if (!vam->json_output)
20317     {
20318       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20319     }
20320
20321   M (POLICER_CLASSIFY_DUMP, mp);
20322   mp->type = type;
20323   /* send it... */
20324   S (mp);
20325
20326   /* Use a control ping for synchronization */
20327   MPING (CONTROL_PING, mp_ping);
20328   S (mp_ping);
20329
20330   /* Wait for a reply... */
20331   W (ret);
20332   return ret;
20333 }
20334
20335 static int
20336 api_netmap_create (vat_main_t * vam)
20337 {
20338   unformat_input_t *i = vam->input;
20339   vl_api_netmap_create_t *mp;
20340   u8 *if_name = 0;
20341   u8 hw_addr[6];
20342   u8 random_hw_addr = 1;
20343   u8 is_pipe = 0;
20344   u8 is_master = 0;
20345   int ret;
20346
20347   clib_memset (hw_addr, 0, sizeof (hw_addr));
20348
20349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20350     {
20351       if (unformat (i, "name %s", &if_name))
20352         vec_add1 (if_name, 0);
20353       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20354         random_hw_addr = 0;
20355       else if (unformat (i, "pipe"))
20356         is_pipe = 1;
20357       else if (unformat (i, "master"))
20358         is_master = 1;
20359       else if (unformat (i, "slave"))
20360         is_master = 0;
20361       else
20362         break;
20363     }
20364
20365   if (!vec_len (if_name))
20366     {
20367       errmsg ("interface name must be specified");
20368       return -99;
20369     }
20370
20371   if (vec_len (if_name) > 64)
20372     {
20373       errmsg ("interface name too long");
20374       return -99;
20375     }
20376
20377   M (NETMAP_CREATE, mp);
20378
20379   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20380   clib_memcpy (mp->hw_addr, hw_addr, 6);
20381   mp->use_random_hw_addr = random_hw_addr;
20382   mp->is_pipe = is_pipe;
20383   mp->is_master = is_master;
20384   vec_free (if_name);
20385
20386   S (mp);
20387   W (ret);
20388   return ret;
20389 }
20390
20391 static int
20392 api_netmap_delete (vat_main_t * vam)
20393 {
20394   unformat_input_t *i = vam->input;
20395   vl_api_netmap_delete_t *mp;
20396   u8 *if_name = 0;
20397   int ret;
20398
20399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20400     {
20401       if (unformat (i, "name %s", &if_name))
20402         vec_add1 (if_name, 0);
20403       else
20404         break;
20405     }
20406
20407   if (!vec_len (if_name))
20408     {
20409       errmsg ("interface name must be specified");
20410       return -99;
20411     }
20412
20413   if (vec_len (if_name) > 64)
20414     {
20415       errmsg ("interface name too long");
20416       return -99;
20417     }
20418
20419   M (NETMAP_DELETE, mp);
20420
20421   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20422   vec_free (if_name);
20423
20424   S (mp);
20425   W (ret);
20426   return ret;
20427 }
20428
20429 static void
20430 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20431 {
20432   if (fp->afi == IP46_TYPE_IP6)
20433     print (vam->ofp,
20434            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20435            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20436            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20437            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20438            format_ip6_address, fp->next_hop);
20439   else if (fp->afi == IP46_TYPE_IP4)
20440     print (vam->ofp,
20441            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20442            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20443            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20444            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20445            format_ip4_address, fp->next_hop);
20446 }
20447
20448 static void
20449 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20450                                  vl_api_fib_path_t * fp)
20451 {
20452   struct in_addr ip4;
20453   struct in6_addr ip6;
20454
20455   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20456   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20457   vat_json_object_add_uint (node, "is_local", fp->is_local);
20458   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20459   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20460   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20461   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20462   if (fp->afi == IP46_TYPE_IP4)
20463     {
20464       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20465       vat_json_object_add_ip4 (node, "next_hop", ip4);
20466     }
20467   else if (fp->afi == IP46_TYPE_IP6)
20468     {
20469       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20470       vat_json_object_add_ip6 (node, "next_hop", ip6);
20471     }
20472 }
20473
20474 static void
20475 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20476 {
20477   vat_main_t *vam = &vat_main;
20478   int count = ntohl (mp->mt_count);
20479   vl_api_fib_path_t *fp;
20480   i32 i;
20481
20482   print (vam->ofp, "[%d]: sw_if_index %d via:",
20483          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20484   fp = mp->mt_paths;
20485   for (i = 0; i < count; i++)
20486     {
20487       vl_api_mpls_fib_path_print (vam, fp);
20488       fp++;
20489     }
20490
20491   print (vam->ofp, "");
20492 }
20493
20494 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20495 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20496
20497 static void
20498 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20499 {
20500   vat_main_t *vam = &vat_main;
20501   vat_json_node_t *node = NULL;
20502   int count = ntohl (mp->mt_count);
20503   vl_api_fib_path_t *fp;
20504   i32 i;
20505
20506   if (VAT_JSON_ARRAY != vam->json_tree.type)
20507     {
20508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20509       vat_json_init_array (&vam->json_tree);
20510     }
20511   node = vat_json_array_add (&vam->json_tree);
20512
20513   vat_json_init_object (node);
20514   vat_json_object_add_uint (node, "tunnel_index",
20515                             ntohl (mp->mt_tunnel_index));
20516   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20517
20518   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20519
20520   fp = mp->mt_paths;
20521   for (i = 0; i < count; i++)
20522     {
20523       vl_api_mpls_fib_path_json_print (node, fp);
20524       fp++;
20525     }
20526 }
20527
20528 static int
20529 api_mpls_tunnel_dump (vat_main_t * vam)
20530 {
20531   vl_api_mpls_tunnel_dump_t *mp;
20532   vl_api_control_ping_t *mp_ping;
20533   u32 sw_if_index = ~0;
20534   int ret;
20535
20536   /* Parse args required to build the message */
20537   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20538     {
20539       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20540         ;
20541     }
20542
20543   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20544
20545   M (MPLS_TUNNEL_DUMP, mp);
20546   mp->sw_if_index = htonl (sw_if_index);
20547   S (mp);
20548
20549   /* Use a control ping for synchronization */
20550   MPING (CONTROL_PING, mp_ping);
20551   S (mp_ping);
20552
20553   W (ret);
20554   return ret;
20555 }
20556
20557 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20558 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20559
20560
20561 static void
20562 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20563 {
20564   vat_main_t *vam = &vat_main;
20565   int count = ntohl (mp->count);
20566   vl_api_fib_path_t *fp;
20567   int i;
20568
20569   print (vam->ofp,
20570          "table-id %d, label %u, ess_bit %u",
20571          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20572   fp = mp->path;
20573   for (i = 0; i < count; i++)
20574     {
20575       vl_api_mpls_fib_path_print (vam, fp);
20576       fp++;
20577     }
20578 }
20579
20580 static void vl_api_mpls_fib_details_t_handler_json
20581   (vl_api_mpls_fib_details_t * mp)
20582 {
20583   vat_main_t *vam = &vat_main;
20584   int count = ntohl (mp->count);
20585   vat_json_node_t *node = NULL;
20586   vl_api_fib_path_t *fp;
20587   int i;
20588
20589   if (VAT_JSON_ARRAY != vam->json_tree.type)
20590     {
20591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20592       vat_json_init_array (&vam->json_tree);
20593     }
20594   node = vat_json_array_add (&vam->json_tree);
20595
20596   vat_json_init_object (node);
20597   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20598   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20599   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20600   vat_json_object_add_uint (node, "path_count", count);
20601   fp = mp->path;
20602   for (i = 0; i < count; i++)
20603     {
20604       vl_api_mpls_fib_path_json_print (node, fp);
20605       fp++;
20606     }
20607 }
20608
20609 static int
20610 api_mpls_fib_dump (vat_main_t * vam)
20611 {
20612   vl_api_mpls_fib_dump_t *mp;
20613   vl_api_control_ping_t *mp_ping;
20614   int ret;
20615
20616   M (MPLS_FIB_DUMP, mp);
20617   S (mp);
20618
20619   /* Use a control ping for synchronization */
20620   MPING (CONTROL_PING, mp_ping);
20621   S (mp_ping);
20622
20623   W (ret);
20624   return ret;
20625 }
20626
20627 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20628 #define vl_api_ip_fib_details_t_print vl_noop_handler
20629
20630 static void
20631 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20632 {
20633   vat_main_t *vam = &vat_main;
20634   int count = ntohl (mp->count);
20635   vl_api_fib_path_t *fp;
20636   int i;
20637
20638   print (vam->ofp,
20639          "table-id %d, prefix %U/%d stats-index %d",
20640          ntohl (mp->table_id), format_ip4_address, mp->address,
20641          mp->address_length, ntohl (mp->stats_index));
20642   fp = mp->path;
20643   for (i = 0; i < count; i++)
20644     {
20645       if (fp->afi == IP46_TYPE_IP6)
20646         print (vam->ofp,
20647                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20648                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20649                "next_hop_table %d",
20650                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20651                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20652                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20653       else if (fp->afi == IP46_TYPE_IP4)
20654         print (vam->ofp,
20655                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20656                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20657                "next_hop_table %d",
20658                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20659                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20660                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20661       fp++;
20662     }
20663 }
20664
20665 static void vl_api_ip_fib_details_t_handler_json
20666   (vl_api_ip_fib_details_t * mp)
20667 {
20668   vat_main_t *vam = &vat_main;
20669   int count = ntohl (mp->count);
20670   vat_json_node_t *node = NULL;
20671   struct in_addr ip4;
20672   struct in6_addr ip6;
20673   vl_api_fib_path_t *fp;
20674   int i;
20675
20676   if (VAT_JSON_ARRAY != vam->json_tree.type)
20677     {
20678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20679       vat_json_init_array (&vam->json_tree);
20680     }
20681   node = vat_json_array_add (&vam->json_tree);
20682
20683   vat_json_init_object (node);
20684   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20685   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20686   vat_json_object_add_ip4 (node, "prefix", ip4);
20687   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20688   vat_json_object_add_uint (node, "path_count", count);
20689   fp = mp->path;
20690   for (i = 0; i < count; i++)
20691     {
20692       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20693       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20694       vat_json_object_add_uint (node, "is_local", fp->is_local);
20695       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20696       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20697       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20698       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20699       if (fp->afi == IP46_TYPE_IP4)
20700         {
20701           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20702           vat_json_object_add_ip4 (node, "next_hop", ip4);
20703         }
20704       else if (fp->afi == IP46_TYPE_IP6)
20705         {
20706           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20707           vat_json_object_add_ip6 (node, "next_hop", ip6);
20708         }
20709     }
20710 }
20711
20712 static int
20713 api_ip_fib_dump (vat_main_t * vam)
20714 {
20715   vl_api_ip_fib_dump_t *mp;
20716   vl_api_control_ping_t *mp_ping;
20717   int ret;
20718
20719   M (IP_FIB_DUMP, mp);
20720   S (mp);
20721
20722   /* Use a control ping for synchronization */
20723   MPING (CONTROL_PING, mp_ping);
20724   S (mp_ping);
20725
20726   W (ret);
20727   return ret;
20728 }
20729
20730 static int
20731 api_ip_mfib_dump (vat_main_t * vam)
20732 {
20733   vl_api_ip_mfib_dump_t *mp;
20734   vl_api_control_ping_t *mp_ping;
20735   int ret;
20736
20737   M (IP_MFIB_DUMP, mp);
20738   S (mp);
20739
20740   /* Use a control ping for synchronization */
20741   MPING (CONTROL_PING, mp_ping);
20742   S (mp_ping);
20743
20744   W (ret);
20745   return ret;
20746 }
20747
20748 static void vl_api_ip_neighbor_details_t_handler
20749   (vl_api_ip_neighbor_details_t * mp)
20750 {
20751   vat_main_t *vam = &vat_main;
20752
20753   print (vam->ofp, "%c %U %U",
20754          (mp->is_static) ? 'S' : 'D',
20755          format_ethernet_address, &mp->mac_address,
20756          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20757          &mp->ip_address);
20758 }
20759
20760 static void vl_api_ip_neighbor_details_t_handler_json
20761   (vl_api_ip_neighbor_details_t * mp)
20762 {
20763
20764   vat_main_t *vam = &vat_main;
20765   vat_json_node_t *node;
20766   struct in_addr ip4;
20767   struct in6_addr ip6;
20768
20769   if (VAT_JSON_ARRAY != vam->json_tree.type)
20770     {
20771       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20772       vat_json_init_array (&vam->json_tree);
20773     }
20774   node = vat_json_array_add (&vam->json_tree);
20775
20776   vat_json_init_object (node);
20777   vat_json_object_add_string_copy (node, "flag",
20778                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20779                                    "dynamic");
20780
20781   vat_json_object_add_string_copy (node, "link_layer",
20782                                    format (0, "%U", format_ethernet_address,
20783                                            &mp->mac_address));
20784
20785   if (mp->is_ipv6)
20786     {
20787       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20788       vat_json_object_add_ip6 (node, "ip_address", ip6);
20789     }
20790   else
20791     {
20792       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20793       vat_json_object_add_ip4 (node, "ip_address", ip4);
20794     }
20795 }
20796
20797 static int
20798 api_ip_neighbor_dump (vat_main_t * vam)
20799 {
20800   unformat_input_t *i = vam->input;
20801   vl_api_ip_neighbor_dump_t *mp;
20802   vl_api_control_ping_t *mp_ping;
20803   u8 is_ipv6 = 0;
20804   u32 sw_if_index = ~0;
20805   int ret;
20806
20807   /* Parse args required to build the message */
20808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20809     {
20810       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20811         ;
20812       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20813         ;
20814       else if (unformat (i, "ip6"))
20815         is_ipv6 = 1;
20816       else
20817         break;
20818     }
20819
20820   if (sw_if_index == ~0)
20821     {
20822       errmsg ("missing interface name or sw_if_index");
20823       return -99;
20824     }
20825
20826   M (IP_NEIGHBOR_DUMP, mp);
20827   mp->is_ipv6 = (u8) is_ipv6;
20828   mp->sw_if_index = ntohl (sw_if_index);
20829   S (mp);
20830
20831   /* Use a control ping for synchronization */
20832   MPING (CONTROL_PING, mp_ping);
20833   S (mp_ping);
20834
20835   W (ret);
20836   return ret;
20837 }
20838
20839 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20840 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20841
20842 static void
20843 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20844 {
20845   vat_main_t *vam = &vat_main;
20846   int count = ntohl (mp->count);
20847   vl_api_fib_path_t *fp;
20848   int i;
20849
20850   print (vam->ofp,
20851          "table-id %d, prefix %U/%d stats-index %d",
20852          ntohl (mp->table_id), format_ip6_address, mp->address,
20853          mp->address_length, ntohl (mp->stats_index));
20854   fp = mp->path;
20855   for (i = 0; i < count; i++)
20856     {
20857       if (fp->afi == IP46_TYPE_IP6)
20858         print (vam->ofp,
20859                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20860                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20861                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20862                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20863                format_ip6_address, fp->next_hop);
20864       else if (fp->afi == IP46_TYPE_IP4)
20865         print (vam->ofp,
20866                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20867                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20868                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20869                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20870                format_ip4_address, fp->next_hop);
20871       fp++;
20872     }
20873 }
20874
20875 static void vl_api_ip6_fib_details_t_handler_json
20876   (vl_api_ip6_fib_details_t * mp)
20877 {
20878   vat_main_t *vam = &vat_main;
20879   int count = ntohl (mp->count);
20880   vat_json_node_t *node = NULL;
20881   struct in_addr ip4;
20882   struct in6_addr ip6;
20883   vl_api_fib_path_t *fp;
20884   int i;
20885
20886   if (VAT_JSON_ARRAY != vam->json_tree.type)
20887     {
20888       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20889       vat_json_init_array (&vam->json_tree);
20890     }
20891   node = vat_json_array_add (&vam->json_tree);
20892
20893   vat_json_init_object (node);
20894   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20895   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20896   vat_json_object_add_ip6 (node, "prefix", ip6);
20897   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20898   vat_json_object_add_uint (node, "path_count", count);
20899   fp = mp->path;
20900   for (i = 0; i < count; i++)
20901     {
20902       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20903       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20904       vat_json_object_add_uint (node, "is_local", fp->is_local);
20905       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20906       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20907       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20908       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20909       if (fp->afi == IP46_TYPE_IP4)
20910         {
20911           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20912           vat_json_object_add_ip4 (node, "next_hop", ip4);
20913         }
20914       else if (fp->afi == IP46_TYPE_IP6)
20915         {
20916           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20917           vat_json_object_add_ip6 (node, "next_hop", ip6);
20918         }
20919     }
20920 }
20921
20922 static int
20923 api_ip6_fib_dump (vat_main_t * vam)
20924 {
20925   vl_api_ip6_fib_dump_t *mp;
20926   vl_api_control_ping_t *mp_ping;
20927   int ret;
20928
20929   M (IP6_FIB_DUMP, mp);
20930   S (mp);
20931
20932   /* Use a control ping for synchronization */
20933   MPING (CONTROL_PING, mp_ping);
20934   S (mp_ping);
20935
20936   W (ret);
20937   return ret;
20938 }
20939
20940 static int
20941 api_ip6_mfib_dump (vat_main_t * vam)
20942 {
20943   vl_api_ip6_mfib_dump_t *mp;
20944   vl_api_control_ping_t *mp_ping;
20945   int ret;
20946
20947   M (IP6_MFIB_DUMP, mp);
20948   S (mp);
20949
20950   /* Use a control ping for synchronization */
20951   MPING (CONTROL_PING, mp_ping);
20952   S (mp_ping);
20953
20954   W (ret);
20955   return ret;
20956 }
20957
20958 int
20959 api_classify_table_ids (vat_main_t * vam)
20960 {
20961   vl_api_classify_table_ids_t *mp;
20962   int ret;
20963
20964   /* Construct the API message */
20965   M (CLASSIFY_TABLE_IDS, mp);
20966   mp->context = 0;
20967
20968   S (mp);
20969   W (ret);
20970   return ret;
20971 }
20972
20973 int
20974 api_classify_table_by_interface (vat_main_t * vam)
20975 {
20976   unformat_input_t *input = vam->input;
20977   vl_api_classify_table_by_interface_t *mp;
20978
20979   u32 sw_if_index = ~0;
20980   int ret;
20981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20982     {
20983       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20984         ;
20985       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20986         ;
20987       else
20988         break;
20989     }
20990   if (sw_if_index == ~0)
20991     {
20992       errmsg ("missing interface name or sw_if_index");
20993       return -99;
20994     }
20995
20996   /* Construct the API message */
20997   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20998   mp->context = 0;
20999   mp->sw_if_index = ntohl (sw_if_index);
21000
21001   S (mp);
21002   W (ret);
21003   return ret;
21004 }
21005
21006 int
21007 api_classify_table_info (vat_main_t * vam)
21008 {
21009   unformat_input_t *input = vam->input;
21010   vl_api_classify_table_info_t *mp;
21011
21012   u32 table_id = ~0;
21013   int ret;
21014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21015     {
21016       if (unformat (input, "table_id %d", &table_id))
21017         ;
21018       else
21019         break;
21020     }
21021   if (table_id == ~0)
21022     {
21023       errmsg ("missing table id");
21024       return -99;
21025     }
21026
21027   /* Construct the API message */
21028   M (CLASSIFY_TABLE_INFO, mp);
21029   mp->context = 0;
21030   mp->table_id = ntohl (table_id);
21031
21032   S (mp);
21033   W (ret);
21034   return ret;
21035 }
21036
21037 int
21038 api_classify_session_dump (vat_main_t * vam)
21039 {
21040   unformat_input_t *input = vam->input;
21041   vl_api_classify_session_dump_t *mp;
21042   vl_api_control_ping_t *mp_ping;
21043
21044   u32 table_id = ~0;
21045   int ret;
21046   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21047     {
21048       if (unformat (input, "table_id %d", &table_id))
21049         ;
21050       else
21051         break;
21052     }
21053   if (table_id == ~0)
21054     {
21055       errmsg ("missing table id");
21056       return -99;
21057     }
21058
21059   /* Construct the API message */
21060   M (CLASSIFY_SESSION_DUMP, mp);
21061   mp->context = 0;
21062   mp->table_id = ntohl (table_id);
21063   S (mp);
21064
21065   /* Use a control ping for synchronization */
21066   MPING (CONTROL_PING, mp_ping);
21067   S (mp_ping);
21068
21069   W (ret);
21070   return ret;
21071 }
21072
21073 static void
21074 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
21075 {
21076   vat_main_t *vam = &vat_main;
21077
21078   print (vam->ofp, "collector_address %U, collector_port %d, "
21079          "src_address %U, vrf_id %d, path_mtu %u, "
21080          "template_interval %u, udp_checksum %d",
21081          format_ip4_address, mp->collector_address,
21082          ntohs (mp->collector_port),
21083          format_ip4_address, mp->src_address,
21084          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
21085          ntohl (mp->template_interval), mp->udp_checksum);
21086
21087   vam->retval = 0;
21088   vam->result_ready = 1;
21089 }
21090
21091 static void
21092   vl_api_ipfix_exporter_details_t_handler_json
21093   (vl_api_ipfix_exporter_details_t * mp)
21094 {
21095   vat_main_t *vam = &vat_main;
21096   vat_json_node_t node;
21097   struct in_addr collector_address;
21098   struct in_addr src_address;
21099
21100   vat_json_init_object (&node);
21101   clib_memcpy (&collector_address, &mp->collector_address,
21102                sizeof (collector_address));
21103   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
21104   vat_json_object_add_uint (&node, "collector_port",
21105                             ntohs (mp->collector_port));
21106   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21107   vat_json_object_add_ip4 (&node, "src_address", src_address);
21108   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21109   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21110   vat_json_object_add_uint (&node, "template_interval",
21111                             ntohl (mp->template_interval));
21112   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21113
21114   vat_json_print (vam->ofp, &node);
21115   vat_json_free (&node);
21116   vam->retval = 0;
21117   vam->result_ready = 1;
21118 }
21119
21120 int
21121 api_ipfix_exporter_dump (vat_main_t * vam)
21122 {
21123   vl_api_ipfix_exporter_dump_t *mp;
21124   int ret;
21125
21126   /* Construct the API message */
21127   M (IPFIX_EXPORTER_DUMP, mp);
21128   mp->context = 0;
21129
21130   S (mp);
21131   W (ret);
21132   return ret;
21133 }
21134
21135 static int
21136 api_ipfix_classify_stream_dump (vat_main_t * vam)
21137 {
21138   vl_api_ipfix_classify_stream_dump_t *mp;
21139   int ret;
21140
21141   /* Construct the API message */
21142   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21143   mp->context = 0;
21144
21145   S (mp);
21146   W (ret);
21147   return ret;
21148   /* NOTREACHED */
21149   return 0;
21150 }
21151
21152 static void
21153   vl_api_ipfix_classify_stream_details_t_handler
21154   (vl_api_ipfix_classify_stream_details_t * mp)
21155 {
21156   vat_main_t *vam = &vat_main;
21157   print (vam->ofp, "domain_id %d, src_port %d",
21158          ntohl (mp->domain_id), ntohs (mp->src_port));
21159   vam->retval = 0;
21160   vam->result_ready = 1;
21161 }
21162
21163 static void
21164   vl_api_ipfix_classify_stream_details_t_handler_json
21165   (vl_api_ipfix_classify_stream_details_t * mp)
21166 {
21167   vat_main_t *vam = &vat_main;
21168   vat_json_node_t node;
21169
21170   vat_json_init_object (&node);
21171   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21172   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21173
21174   vat_json_print (vam->ofp, &node);
21175   vat_json_free (&node);
21176   vam->retval = 0;
21177   vam->result_ready = 1;
21178 }
21179
21180 static int
21181 api_ipfix_classify_table_dump (vat_main_t * vam)
21182 {
21183   vl_api_ipfix_classify_table_dump_t *mp;
21184   vl_api_control_ping_t *mp_ping;
21185   int ret;
21186
21187   if (!vam->json_output)
21188     {
21189       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21190              "transport_protocol");
21191     }
21192
21193   /* Construct the API message */
21194   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21195
21196   /* send it... */
21197   S (mp);
21198
21199   /* Use a control ping for synchronization */
21200   MPING (CONTROL_PING, mp_ping);
21201   S (mp_ping);
21202
21203   W (ret);
21204   return ret;
21205 }
21206
21207 static void
21208   vl_api_ipfix_classify_table_details_t_handler
21209   (vl_api_ipfix_classify_table_details_t * mp)
21210 {
21211   vat_main_t *vam = &vat_main;
21212   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21213          mp->transport_protocol);
21214 }
21215
21216 static void
21217   vl_api_ipfix_classify_table_details_t_handler_json
21218   (vl_api_ipfix_classify_table_details_t * mp)
21219 {
21220   vat_json_node_t *node = NULL;
21221   vat_main_t *vam = &vat_main;
21222
21223   if (VAT_JSON_ARRAY != vam->json_tree.type)
21224     {
21225       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21226       vat_json_init_array (&vam->json_tree);
21227     }
21228
21229   node = vat_json_array_add (&vam->json_tree);
21230   vat_json_init_object (node);
21231
21232   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21233   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21234   vat_json_object_add_uint (node, "transport_protocol",
21235                             mp->transport_protocol);
21236 }
21237
21238 static int
21239 api_sw_interface_span_enable_disable (vat_main_t * vam)
21240 {
21241   unformat_input_t *i = vam->input;
21242   vl_api_sw_interface_span_enable_disable_t *mp;
21243   u32 src_sw_if_index = ~0;
21244   u32 dst_sw_if_index = ~0;
21245   u8 state = 3;
21246   int ret;
21247   u8 is_l2 = 0;
21248
21249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21250     {
21251       if (unformat
21252           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21253         ;
21254       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21255         ;
21256       else
21257         if (unformat
21258             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21259         ;
21260       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21261         ;
21262       else if (unformat (i, "disable"))
21263         state = 0;
21264       else if (unformat (i, "rx"))
21265         state = 1;
21266       else if (unformat (i, "tx"))
21267         state = 2;
21268       else if (unformat (i, "both"))
21269         state = 3;
21270       else if (unformat (i, "l2"))
21271         is_l2 = 1;
21272       else
21273         break;
21274     }
21275
21276   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21277
21278   mp->sw_if_index_from = htonl (src_sw_if_index);
21279   mp->sw_if_index_to = htonl (dst_sw_if_index);
21280   mp->state = state;
21281   mp->is_l2 = is_l2;
21282
21283   S (mp);
21284   W (ret);
21285   return ret;
21286 }
21287
21288 static void
21289 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21290                                             * mp)
21291 {
21292   vat_main_t *vam = &vat_main;
21293   u8 *sw_if_from_name = 0;
21294   u8 *sw_if_to_name = 0;
21295   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21296   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21297   char *states[] = { "none", "rx", "tx", "both" };
21298   hash_pair_t *p;
21299
21300   /* *INDENT-OFF* */
21301   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21302   ({
21303     if ((u32) p->value[0] == sw_if_index_from)
21304       {
21305         sw_if_from_name = (u8 *)(p->key);
21306         if (sw_if_to_name)
21307           break;
21308       }
21309     if ((u32) p->value[0] == sw_if_index_to)
21310       {
21311         sw_if_to_name = (u8 *)(p->key);
21312         if (sw_if_from_name)
21313           break;
21314       }
21315   }));
21316   /* *INDENT-ON* */
21317   print (vam->ofp, "%20s => %20s (%s) %s",
21318          sw_if_from_name, sw_if_to_name, states[mp->state],
21319          mp->is_l2 ? "l2" : "device");
21320 }
21321
21322 static void
21323   vl_api_sw_interface_span_details_t_handler_json
21324   (vl_api_sw_interface_span_details_t * mp)
21325 {
21326   vat_main_t *vam = &vat_main;
21327   vat_json_node_t *node = NULL;
21328   u8 *sw_if_from_name = 0;
21329   u8 *sw_if_to_name = 0;
21330   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21331   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21332   hash_pair_t *p;
21333
21334   /* *INDENT-OFF* */
21335   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21336   ({
21337     if ((u32) p->value[0] == sw_if_index_from)
21338       {
21339         sw_if_from_name = (u8 *)(p->key);
21340         if (sw_if_to_name)
21341           break;
21342       }
21343     if ((u32) p->value[0] == sw_if_index_to)
21344       {
21345         sw_if_to_name = (u8 *)(p->key);
21346         if (sw_if_from_name)
21347           break;
21348       }
21349   }));
21350   /* *INDENT-ON* */
21351
21352   if (VAT_JSON_ARRAY != vam->json_tree.type)
21353     {
21354       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21355       vat_json_init_array (&vam->json_tree);
21356     }
21357   node = vat_json_array_add (&vam->json_tree);
21358
21359   vat_json_init_object (node);
21360   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21361   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21362   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21363   if (0 != sw_if_to_name)
21364     {
21365       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21366     }
21367   vat_json_object_add_uint (node, "state", mp->state);
21368   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21369 }
21370
21371 static int
21372 api_sw_interface_span_dump (vat_main_t * vam)
21373 {
21374   unformat_input_t *input = vam->input;
21375   vl_api_sw_interface_span_dump_t *mp;
21376   vl_api_control_ping_t *mp_ping;
21377   u8 is_l2 = 0;
21378   int ret;
21379
21380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21381     {
21382       if (unformat (input, "l2"))
21383         is_l2 = 1;
21384       else
21385         break;
21386     }
21387
21388   M (SW_INTERFACE_SPAN_DUMP, mp);
21389   mp->is_l2 = is_l2;
21390   S (mp);
21391
21392   /* Use a control ping for synchronization */
21393   MPING (CONTROL_PING, mp_ping);
21394   S (mp_ping);
21395
21396   W (ret);
21397   return ret;
21398 }
21399
21400 int
21401 api_pg_create_interface (vat_main_t * vam)
21402 {
21403   unformat_input_t *input = vam->input;
21404   vl_api_pg_create_interface_t *mp;
21405
21406   u32 if_id = ~0;
21407   int ret;
21408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21409     {
21410       if (unformat (input, "if_id %d", &if_id))
21411         ;
21412       else
21413         break;
21414     }
21415   if (if_id == ~0)
21416     {
21417       errmsg ("missing pg interface index");
21418       return -99;
21419     }
21420
21421   /* Construct the API message */
21422   M (PG_CREATE_INTERFACE, mp);
21423   mp->context = 0;
21424   mp->interface_id = ntohl (if_id);
21425
21426   S (mp);
21427   W (ret);
21428   return ret;
21429 }
21430
21431 int
21432 api_pg_capture (vat_main_t * vam)
21433 {
21434   unformat_input_t *input = vam->input;
21435   vl_api_pg_capture_t *mp;
21436
21437   u32 if_id = ~0;
21438   u8 enable = 1;
21439   u32 count = 1;
21440   u8 pcap_file_set = 0;
21441   u8 *pcap_file = 0;
21442   int ret;
21443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21444     {
21445       if (unformat (input, "if_id %d", &if_id))
21446         ;
21447       else if (unformat (input, "pcap %s", &pcap_file))
21448         pcap_file_set = 1;
21449       else if (unformat (input, "count %d", &count))
21450         ;
21451       else if (unformat (input, "disable"))
21452         enable = 0;
21453       else
21454         break;
21455     }
21456   if (if_id == ~0)
21457     {
21458       errmsg ("missing pg interface index");
21459       return -99;
21460     }
21461   if (pcap_file_set > 0)
21462     {
21463       if (vec_len (pcap_file) > 255)
21464         {
21465           errmsg ("pcap file name is too long");
21466           return -99;
21467         }
21468     }
21469
21470   u32 name_len = vec_len (pcap_file);
21471   /* Construct the API message */
21472   M (PG_CAPTURE, mp);
21473   mp->context = 0;
21474   mp->interface_id = ntohl (if_id);
21475   mp->is_enabled = enable;
21476   mp->count = ntohl (count);
21477   mp->pcap_name_length = ntohl (name_len);
21478   if (pcap_file_set != 0)
21479     {
21480       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21481     }
21482   vec_free (pcap_file);
21483
21484   S (mp);
21485   W (ret);
21486   return ret;
21487 }
21488
21489 int
21490 api_pg_enable_disable (vat_main_t * vam)
21491 {
21492   unformat_input_t *input = vam->input;
21493   vl_api_pg_enable_disable_t *mp;
21494
21495   u8 enable = 1;
21496   u8 stream_name_set = 0;
21497   u8 *stream_name = 0;
21498   int ret;
21499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21500     {
21501       if (unformat (input, "stream %s", &stream_name))
21502         stream_name_set = 1;
21503       else if (unformat (input, "disable"))
21504         enable = 0;
21505       else
21506         break;
21507     }
21508
21509   if (stream_name_set > 0)
21510     {
21511       if (vec_len (stream_name) > 255)
21512         {
21513           errmsg ("stream name too long");
21514           return -99;
21515         }
21516     }
21517
21518   u32 name_len = vec_len (stream_name);
21519   /* Construct the API message */
21520   M (PG_ENABLE_DISABLE, mp);
21521   mp->context = 0;
21522   mp->is_enabled = enable;
21523   if (stream_name_set != 0)
21524     {
21525       mp->stream_name_length = ntohl (name_len);
21526       clib_memcpy (mp->stream_name, stream_name, name_len);
21527     }
21528   vec_free (stream_name);
21529
21530   S (mp);
21531   W (ret);
21532   return ret;
21533 }
21534
21535 int
21536 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21537 {
21538   unformat_input_t *input = vam->input;
21539   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21540
21541   u16 *low_ports = 0;
21542   u16 *high_ports = 0;
21543   u16 this_low;
21544   u16 this_hi;
21545   ip4_address_t ip4_addr;
21546   ip6_address_t ip6_addr;
21547   u32 length;
21548   u32 tmp, tmp2;
21549   u8 prefix_set = 0;
21550   u32 vrf_id = ~0;
21551   u8 is_add = 1;
21552   u8 is_ipv6 = 0;
21553   int ret;
21554
21555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21556     {
21557       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21558         {
21559           prefix_set = 1;
21560         }
21561       else
21562         if (unformat
21563             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21564         {
21565           prefix_set = 1;
21566           is_ipv6 = 1;
21567         }
21568       else if (unformat (input, "vrf %d", &vrf_id))
21569         ;
21570       else if (unformat (input, "del"))
21571         is_add = 0;
21572       else if (unformat (input, "port %d", &tmp))
21573         {
21574           if (tmp == 0 || tmp > 65535)
21575             {
21576               errmsg ("port %d out of range", tmp);
21577               return -99;
21578             }
21579           this_low = tmp;
21580           this_hi = this_low + 1;
21581           vec_add1 (low_ports, this_low);
21582           vec_add1 (high_ports, this_hi);
21583         }
21584       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21585         {
21586           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21587             {
21588               errmsg ("incorrect range parameters");
21589               return -99;
21590             }
21591           this_low = tmp;
21592           /* Note: in debug CLI +1 is added to high before
21593              passing to real fn that does "the work"
21594              (ip_source_and_port_range_check_add_del).
21595              This fn is a wrapper around the binary API fn a
21596              control plane will call, which expects this increment
21597              to have occurred. Hence letting the binary API control
21598              plane fn do the increment for consistency between VAT
21599              and other control planes.
21600            */
21601           this_hi = tmp2;
21602           vec_add1 (low_ports, this_low);
21603           vec_add1 (high_ports, this_hi);
21604         }
21605       else
21606         break;
21607     }
21608
21609   if (prefix_set == 0)
21610     {
21611       errmsg ("<address>/<mask> not specified");
21612       return -99;
21613     }
21614
21615   if (vrf_id == ~0)
21616     {
21617       errmsg ("VRF ID required, not specified");
21618       return -99;
21619     }
21620
21621   if (vrf_id == 0)
21622     {
21623       errmsg
21624         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21625       return -99;
21626     }
21627
21628   if (vec_len (low_ports) == 0)
21629     {
21630       errmsg ("At least one port or port range required");
21631       return -99;
21632     }
21633
21634   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21635
21636   mp->is_add = is_add;
21637
21638   if (is_ipv6)
21639     {
21640       mp->is_ipv6 = 1;
21641       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21642     }
21643   else
21644     {
21645       mp->is_ipv6 = 0;
21646       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21647     }
21648
21649   mp->mask_length = length;
21650   mp->number_of_ranges = vec_len (low_ports);
21651
21652   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21653   vec_free (low_ports);
21654
21655   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21656   vec_free (high_ports);
21657
21658   mp->vrf_id = ntohl (vrf_id);
21659
21660   S (mp);
21661   W (ret);
21662   return ret;
21663 }
21664
21665 int
21666 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21667 {
21668   unformat_input_t *input = vam->input;
21669   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21670   u32 sw_if_index = ~0;
21671   int vrf_set = 0;
21672   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21673   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21674   u8 is_add = 1;
21675   int ret;
21676
21677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21678     {
21679       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21680         ;
21681       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21682         ;
21683       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21684         vrf_set = 1;
21685       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21686         vrf_set = 1;
21687       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21688         vrf_set = 1;
21689       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21690         vrf_set = 1;
21691       else if (unformat (input, "del"))
21692         is_add = 0;
21693       else
21694         break;
21695     }
21696
21697   if (sw_if_index == ~0)
21698     {
21699       errmsg ("Interface required but not specified");
21700       return -99;
21701     }
21702
21703   if (vrf_set == 0)
21704     {
21705       errmsg ("VRF ID required but not specified");
21706       return -99;
21707     }
21708
21709   if (tcp_out_vrf_id == 0
21710       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21711     {
21712       errmsg
21713         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21714       return -99;
21715     }
21716
21717   /* Construct the API message */
21718   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21719
21720   mp->sw_if_index = ntohl (sw_if_index);
21721   mp->is_add = is_add;
21722   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21723   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21724   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21725   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21726
21727   /* send it... */
21728   S (mp);
21729
21730   /* Wait for a reply... */
21731   W (ret);
21732   return ret;
21733 }
21734
21735 static int
21736 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21737 {
21738   unformat_input_t *i = vam->input;
21739   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21740   u32 local_sa_id = 0;
21741   u32 remote_sa_id = 0;
21742   ip4_address_t src_address;
21743   ip4_address_t dst_address;
21744   u8 is_add = 1;
21745   int ret;
21746
21747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21748     {
21749       if (unformat (i, "local_sa %d", &local_sa_id))
21750         ;
21751       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21752         ;
21753       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21754         ;
21755       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21756         ;
21757       else if (unformat (i, "del"))
21758         is_add = 0;
21759       else
21760         {
21761           clib_warning ("parse error '%U'", format_unformat_error, i);
21762           return -99;
21763         }
21764     }
21765
21766   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21767
21768   mp->local_sa_id = ntohl (local_sa_id);
21769   mp->remote_sa_id = ntohl (remote_sa_id);
21770   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21771   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21772   mp->is_add = is_add;
21773
21774   S (mp);
21775   W (ret);
21776   return ret;
21777 }
21778
21779 static int
21780 api_punt (vat_main_t * vam)
21781 {
21782   unformat_input_t *i = vam->input;
21783   vl_api_punt_t *mp;
21784   u32 ipv = ~0;
21785   u32 protocol = ~0;
21786   u32 port = ~0;
21787   int is_add = 1;
21788   int ret;
21789
21790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21791     {
21792       if (unformat (i, "ip %d", &ipv))
21793         ;
21794       else if (unformat (i, "protocol %d", &protocol))
21795         ;
21796       else if (unformat (i, "port %d", &port))
21797         ;
21798       else if (unformat (i, "del"))
21799         is_add = 0;
21800       else
21801         {
21802           clib_warning ("parse error '%U'", format_unformat_error, i);
21803           return -99;
21804         }
21805     }
21806
21807   M (PUNT, mp);
21808
21809   mp->is_add = (u8) is_add;
21810   mp->ipv = (u8) ipv;
21811   mp->l4_protocol = (u8) protocol;
21812   mp->l4_port = htons ((u16) port);
21813
21814   S (mp);
21815   W (ret);
21816   return ret;
21817 }
21818
21819 static void vl_api_ipsec_gre_tunnel_details_t_handler
21820   (vl_api_ipsec_gre_tunnel_details_t * mp)
21821 {
21822   vat_main_t *vam = &vat_main;
21823
21824   print (vam->ofp, "%11d%15U%15U%14d%14d",
21825          ntohl (mp->sw_if_index),
21826          format_ip4_address, &mp->src_address,
21827          format_ip4_address, &mp->dst_address,
21828          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21829 }
21830
21831 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21832   (vl_api_ipsec_gre_tunnel_details_t * mp)
21833 {
21834   vat_main_t *vam = &vat_main;
21835   vat_json_node_t *node = NULL;
21836   struct in_addr ip4;
21837
21838   if (VAT_JSON_ARRAY != vam->json_tree.type)
21839     {
21840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21841       vat_json_init_array (&vam->json_tree);
21842     }
21843   node = vat_json_array_add (&vam->json_tree);
21844
21845   vat_json_init_object (node);
21846   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21847   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21848   vat_json_object_add_ip4 (node, "src_address", ip4);
21849   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21850   vat_json_object_add_ip4 (node, "dst_address", ip4);
21851   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21852   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21853 }
21854
21855 static int
21856 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21857 {
21858   unformat_input_t *i = vam->input;
21859   vl_api_ipsec_gre_tunnel_dump_t *mp;
21860   vl_api_control_ping_t *mp_ping;
21861   u32 sw_if_index;
21862   u8 sw_if_index_set = 0;
21863   int ret;
21864
21865   /* Parse args required to build the message */
21866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21867     {
21868       if (unformat (i, "sw_if_index %d", &sw_if_index))
21869         sw_if_index_set = 1;
21870       else
21871         break;
21872     }
21873
21874   if (sw_if_index_set == 0)
21875     {
21876       sw_if_index = ~0;
21877     }
21878
21879   if (!vam->json_output)
21880     {
21881       print (vam->ofp, "%11s%15s%15s%14s%14s",
21882              "sw_if_index", "src_address", "dst_address",
21883              "local_sa_id", "remote_sa_id");
21884     }
21885
21886   /* Get list of gre-tunnel interfaces */
21887   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21888
21889   mp->sw_if_index = htonl (sw_if_index);
21890
21891   S (mp);
21892
21893   /* Use a control ping for synchronization */
21894   MPING (CONTROL_PING, mp_ping);
21895   S (mp_ping);
21896
21897   W (ret);
21898   return ret;
21899 }
21900
21901 static int
21902 api_delete_subif (vat_main_t * vam)
21903 {
21904   unformat_input_t *i = vam->input;
21905   vl_api_delete_subif_t *mp;
21906   u32 sw_if_index = ~0;
21907   int ret;
21908
21909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21910     {
21911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21912         ;
21913       if (unformat (i, "sw_if_index %d", &sw_if_index))
21914         ;
21915       else
21916         break;
21917     }
21918
21919   if (sw_if_index == ~0)
21920     {
21921       errmsg ("missing sw_if_index");
21922       return -99;
21923     }
21924
21925   /* Construct the API message */
21926   M (DELETE_SUBIF, mp);
21927   mp->sw_if_index = ntohl (sw_if_index);
21928
21929   S (mp);
21930   W (ret);
21931   return ret;
21932 }
21933
21934 #define foreach_pbb_vtr_op      \
21935 _("disable",  L2_VTR_DISABLED)  \
21936 _("pop",  L2_VTR_POP_2)         \
21937 _("push",  L2_VTR_PUSH_2)
21938
21939 static int
21940 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21941 {
21942   unformat_input_t *i = vam->input;
21943   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21944   u32 sw_if_index = ~0, vtr_op = ~0;
21945   u16 outer_tag = ~0;
21946   u8 dmac[6], smac[6];
21947   u8 dmac_set = 0, smac_set = 0;
21948   u16 vlanid = 0;
21949   u32 sid = ~0;
21950   u32 tmp;
21951   int ret;
21952
21953   /* Shut up coverity */
21954   clib_memset (dmac, 0, sizeof (dmac));
21955   clib_memset (smac, 0, sizeof (smac));
21956
21957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21958     {
21959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21960         ;
21961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21962         ;
21963       else if (unformat (i, "vtr_op %d", &vtr_op))
21964         ;
21965 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21966       foreach_pbb_vtr_op
21967 #undef _
21968         else if (unformat (i, "translate_pbb_stag"))
21969         {
21970           if (unformat (i, "%d", &tmp))
21971             {
21972               vtr_op = L2_VTR_TRANSLATE_2_1;
21973               outer_tag = tmp;
21974             }
21975           else
21976             {
21977               errmsg
21978                 ("translate_pbb_stag operation requires outer tag definition");
21979               return -99;
21980             }
21981         }
21982       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21983         dmac_set++;
21984       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21985         smac_set++;
21986       else if (unformat (i, "sid %d", &sid))
21987         ;
21988       else if (unformat (i, "vlanid %d", &tmp))
21989         vlanid = tmp;
21990       else
21991         {
21992           clib_warning ("parse error '%U'", format_unformat_error, i);
21993           return -99;
21994         }
21995     }
21996
21997   if ((sw_if_index == ~0) || (vtr_op == ~0))
21998     {
21999       errmsg ("missing sw_if_index or vtr operation");
22000       return -99;
22001     }
22002   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
22003       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
22004     {
22005       errmsg
22006         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
22007       return -99;
22008     }
22009
22010   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
22011   mp->sw_if_index = ntohl (sw_if_index);
22012   mp->vtr_op = ntohl (vtr_op);
22013   mp->outer_tag = ntohs (outer_tag);
22014   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
22015   clib_memcpy (mp->b_smac, smac, sizeof (smac));
22016   mp->b_vlanid = ntohs (vlanid);
22017   mp->i_sid = ntohl (sid);
22018
22019   S (mp);
22020   W (ret);
22021   return ret;
22022 }
22023
22024 static int
22025 api_flow_classify_set_interface (vat_main_t * vam)
22026 {
22027   unformat_input_t *i = vam->input;
22028   vl_api_flow_classify_set_interface_t *mp;
22029   u32 sw_if_index;
22030   int sw_if_index_set;
22031   u32 ip4_table_index = ~0;
22032   u32 ip6_table_index = ~0;
22033   u8 is_add = 1;
22034   int ret;
22035
22036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22037     {
22038       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22039         sw_if_index_set = 1;
22040       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22041         sw_if_index_set = 1;
22042       else if (unformat (i, "del"))
22043         is_add = 0;
22044       else if (unformat (i, "ip4-table %d", &ip4_table_index))
22045         ;
22046       else if (unformat (i, "ip6-table %d", &ip6_table_index))
22047         ;
22048       else
22049         {
22050           clib_warning ("parse error '%U'", format_unformat_error, i);
22051           return -99;
22052         }
22053     }
22054
22055   if (sw_if_index_set == 0)
22056     {
22057       errmsg ("missing interface name or sw_if_index");
22058       return -99;
22059     }
22060
22061   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
22062
22063   mp->sw_if_index = ntohl (sw_if_index);
22064   mp->ip4_table_index = ntohl (ip4_table_index);
22065   mp->ip6_table_index = ntohl (ip6_table_index);
22066   mp->is_add = is_add;
22067
22068   S (mp);
22069   W (ret);
22070   return ret;
22071 }
22072
22073 static int
22074 api_flow_classify_dump (vat_main_t * vam)
22075 {
22076   unformat_input_t *i = vam->input;
22077   vl_api_flow_classify_dump_t *mp;
22078   vl_api_control_ping_t *mp_ping;
22079   u8 type = FLOW_CLASSIFY_N_TABLES;
22080   int ret;
22081
22082   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
22083     ;
22084   else
22085     {
22086       errmsg ("classify table type must be specified");
22087       return -99;
22088     }
22089
22090   if (!vam->json_output)
22091     {
22092       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
22093     }
22094
22095   M (FLOW_CLASSIFY_DUMP, mp);
22096   mp->type = type;
22097   /* send it... */
22098   S (mp);
22099
22100   /* Use a control ping for synchronization */
22101   MPING (CONTROL_PING, mp_ping);
22102   S (mp_ping);
22103
22104   /* Wait for a reply... */
22105   W (ret);
22106   return ret;
22107 }
22108
22109 static int
22110 api_feature_enable_disable (vat_main_t * vam)
22111 {
22112   unformat_input_t *i = vam->input;
22113   vl_api_feature_enable_disable_t *mp;
22114   u8 *arc_name = 0;
22115   u8 *feature_name = 0;
22116   u32 sw_if_index = ~0;
22117   u8 enable = 1;
22118   int ret;
22119
22120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22121     {
22122       if (unformat (i, "arc_name %s", &arc_name))
22123         ;
22124       else if (unformat (i, "feature_name %s", &feature_name))
22125         ;
22126       else
22127         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22128         ;
22129       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22130         ;
22131       else if (unformat (i, "disable"))
22132         enable = 0;
22133       else
22134         break;
22135     }
22136
22137   if (arc_name == 0)
22138     {
22139       errmsg ("missing arc name");
22140       return -99;
22141     }
22142   if (vec_len (arc_name) > 63)
22143     {
22144       errmsg ("arc name too long");
22145     }
22146
22147   if (feature_name == 0)
22148     {
22149       errmsg ("missing feature name");
22150       return -99;
22151     }
22152   if (vec_len (feature_name) > 63)
22153     {
22154       errmsg ("feature name too long");
22155     }
22156
22157   if (sw_if_index == ~0)
22158     {
22159       errmsg ("missing interface name or sw_if_index");
22160       return -99;
22161     }
22162
22163   /* Construct the API message */
22164   M (FEATURE_ENABLE_DISABLE, mp);
22165   mp->sw_if_index = ntohl (sw_if_index);
22166   mp->enable = enable;
22167   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22168   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22169   vec_free (arc_name);
22170   vec_free (feature_name);
22171
22172   S (mp);
22173   W (ret);
22174   return ret;
22175 }
22176
22177 static int
22178 api_sw_interface_tag_add_del (vat_main_t * vam)
22179 {
22180   unformat_input_t *i = vam->input;
22181   vl_api_sw_interface_tag_add_del_t *mp;
22182   u32 sw_if_index = ~0;
22183   u8 *tag = 0;
22184   u8 enable = 1;
22185   int ret;
22186
22187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22188     {
22189       if (unformat (i, "tag %s", &tag))
22190         ;
22191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22192         ;
22193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22194         ;
22195       else if (unformat (i, "del"))
22196         enable = 0;
22197       else
22198         break;
22199     }
22200
22201   if (sw_if_index == ~0)
22202     {
22203       errmsg ("missing interface name or sw_if_index");
22204       return -99;
22205     }
22206
22207   if (enable && (tag == 0))
22208     {
22209       errmsg ("no tag specified");
22210       return -99;
22211     }
22212
22213   /* Construct the API message */
22214   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22215   mp->sw_if_index = ntohl (sw_if_index);
22216   mp->is_add = enable;
22217   if (enable)
22218     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22219   vec_free (tag);
22220
22221   S (mp);
22222   W (ret);
22223   return ret;
22224 }
22225
22226 static void vl_api_l2_xconnect_details_t_handler
22227   (vl_api_l2_xconnect_details_t * mp)
22228 {
22229   vat_main_t *vam = &vat_main;
22230
22231   print (vam->ofp, "%15d%15d",
22232          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22233 }
22234
22235 static void vl_api_l2_xconnect_details_t_handler_json
22236   (vl_api_l2_xconnect_details_t * mp)
22237 {
22238   vat_main_t *vam = &vat_main;
22239   vat_json_node_t *node = NULL;
22240
22241   if (VAT_JSON_ARRAY != vam->json_tree.type)
22242     {
22243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22244       vat_json_init_array (&vam->json_tree);
22245     }
22246   node = vat_json_array_add (&vam->json_tree);
22247
22248   vat_json_init_object (node);
22249   vat_json_object_add_uint (node, "rx_sw_if_index",
22250                             ntohl (mp->rx_sw_if_index));
22251   vat_json_object_add_uint (node, "tx_sw_if_index",
22252                             ntohl (mp->tx_sw_if_index));
22253 }
22254
22255 static int
22256 api_l2_xconnect_dump (vat_main_t * vam)
22257 {
22258   vl_api_l2_xconnect_dump_t *mp;
22259   vl_api_control_ping_t *mp_ping;
22260   int ret;
22261
22262   if (!vam->json_output)
22263     {
22264       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22265     }
22266
22267   M (L2_XCONNECT_DUMP, mp);
22268
22269   S (mp);
22270
22271   /* Use a control ping for synchronization */
22272   MPING (CONTROL_PING, mp_ping);
22273   S (mp_ping);
22274
22275   W (ret);
22276   return ret;
22277 }
22278
22279 static int
22280 api_hw_interface_set_mtu (vat_main_t * vam)
22281 {
22282   unformat_input_t *i = vam->input;
22283   vl_api_hw_interface_set_mtu_t *mp;
22284   u32 sw_if_index = ~0;
22285   u32 mtu = 0;
22286   int ret;
22287
22288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22289     {
22290       if (unformat (i, "mtu %d", &mtu))
22291         ;
22292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22293         ;
22294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22295         ;
22296       else
22297         break;
22298     }
22299
22300   if (sw_if_index == ~0)
22301     {
22302       errmsg ("missing interface name or sw_if_index");
22303       return -99;
22304     }
22305
22306   if (mtu == 0)
22307     {
22308       errmsg ("no mtu specified");
22309       return -99;
22310     }
22311
22312   /* Construct the API message */
22313   M (HW_INTERFACE_SET_MTU, mp);
22314   mp->sw_if_index = ntohl (sw_if_index);
22315   mp->mtu = ntohs ((u16) mtu);
22316
22317   S (mp);
22318   W (ret);
22319   return ret;
22320 }
22321
22322 static int
22323 api_p2p_ethernet_add (vat_main_t * vam)
22324 {
22325   unformat_input_t *i = vam->input;
22326   vl_api_p2p_ethernet_add_t *mp;
22327   u32 parent_if_index = ~0;
22328   u32 sub_id = ~0;
22329   u8 remote_mac[6];
22330   u8 mac_set = 0;
22331   int ret;
22332
22333   clib_memset (remote_mac, 0, sizeof (remote_mac));
22334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22335     {
22336       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22337         ;
22338       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22339         ;
22340       else
22341         if (unformat
22342             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22343         mac_set++;
22344       else if (unformat (i, "sub_id %d", &sub_id))
22345         ;
22346       else
22347         {
22348           clib_warning ("parse error '%U'", format_unformat_error, i);
22349           return -99;
22350         }
22351     }
22352
22353   if (parent_if_index == ~0)
22354     {
22355       errmsg ("missing interface name or sw_if_index");
22356       return -99;
22357     }
22358   if (mac_set == 0)
22359     {
22360       errmsg ("missing remote mac address");
22361       return -99;
22362     }
22363   if (sub_id == ~0)
22364     {
22365       errmsg ("missing sub-interface id");
22366       return -99;
22367     }
22368
22369   M (P2P_ETHERNET_ADD, mp);
22370   mp->parent_if_index = ntohl (parent_if_index);
22371   mp->subif_id = ntohl (sub_id);
22372   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22373
22374   S (mp);
22375   W (ret);
22376   return ret;
22377 }
22378
22379 static int
22380 api_p2p_ethernet_del (vat_main_t * vam)
22381 {
22382   unformat_input_t *i = vam->input;
22383   vl_api_p2p_ethernet_del_t *mp;
22384   u32 parent_if_index = ~0;
22385   u8 remote_mac[6];
22386   u8 mac_set = 0;
22387   int ret;
22388
22389   clib_memset (remote_mac, 0, sizeof (remote_mac));
22390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22391     {
22392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22393         ;
22394       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22395         ;
22396       else
22397         if (unformat
22398             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22399         mac_set++;
22400       else
22401         {
22402           clib_warning ("parse error '%U'", format_unformat_error, i);
22403           return -99;
22404         }
22405     }
22406
22407   if (parent_if_index == ~0)
22408     {
22409       errmsg ("missing interface name or sw_if_index");
22410       return -99;
22411     }
22412   if (mac_set == 0)
22413     {
22414       errmsg ("missing remote mac address");
22415       return -99;
22416     }
22417
22418   M (P2P_ETHERNET_DEL, mp);
22419   mp->parent_if_index = ntohl (parent_if_index);
22420   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22421
22422   S (mp);
22423   W (ret);
22424   return ret;
22425 }
22426
22427 static int
22428 api_lldp_config (vat_main_t * vam)
22429 {
22430   unformat_input_t *i = vam->input;
22431   vl_api_lldp_config_t *mp;
22432   int tx_hold = 0;
22433   int tx_interval = 0;
22434   u8 *sys_name = NULL;
22435   int ret;
22436
22437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22438     {
22439       if (unformat (i, "system-name %s", &sys_name))
22440         ;
22441       else if (unformat (i, "tx-hold %d", &tx_hold))
22442         ;
22443       else if (unformat (i, "tx-interval %d", &tx_interval))
22444         ;
22445       else
22446         {
22447           clib_warning ("parse error '%U'", format_unformat_error, i);
22448           return -99;
22449         }
22450     }
22451
22452   vec_add1 (sys_name, 0);
22453
22454   M (LLDP_CONFIG, mp);
22455   mp->tx_hold = htonl (tx_hold);
22456   mp->tx_interval = htonl (tx_interval);
22457   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22458   vec_free (sys_name);
22459
22460   S (mp);
22461   W (ret);
22462   return ret;
22463 }
22464
22465 static int
22466 api_sw_interface_set_lldp (vat_main_t * vam)
22467 {
22468   unformat_input_t *i = vam->input;
22469   vl_api_sw_interface_set_lldp_t *mp;
22470   u32 sw_if_index = ~0;
22471   u32 enable = 1;
22472   u8 *port_desc = NULL, *mgmt_oid = NULL;
22473   ip4_address_t ip4_addr;
22474   ip6_address_t ip6_addr;
22475   int ret;
22476
22477   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
22478   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
22479
22480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22481     {
22482       if (unformat (i, "disable"))
22483         enable = 0;
22484       else
22485         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22486         ;
22487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22488         ;
22489       else if (unformat (i, "port-desc %s", &port_desc))
22490         ;
22491       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22492         ;
22493       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22494         ;
22495       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22496         ;
22497       else
22498         break;
22499     }
22500
22501   if (sw_if_index == ~0)
22502     {
22503       errmsg ("missing interface name or sw_if_index");
22504       return -99;
22505     }
22506
22507   /* Construct the API message */
22508   vec_add1 (port_desc, 0);
22509   vec_add1 (mgmt_oid, 0);
22510   M (SW_INTERFACE_SET_LLDP, mp);
22511   mp->sw_if_index = ntohl (sw_if_index);
22512   mp->enable = enable;
22513   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22514   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22515   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22516   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22517   vec_free (port_desc);
22518   vec_free (mgmt_oid);
22519
22520   S (mp);
22521   W (ret);
22522   return ret;
22523 }
22524
22525 static int
22526 api_tcp_configure_src_addresses (vat_main_t * vam)
22527 {
22528   vl_api_tcp_configure_src_addresses_t *mp;
22529   unformat_input_t *i = vam->input;
22530   ip4_address_t v4first, v4last;
22531   ip6_address_t v6first, v6last;
22532   u8 range_set = 0;
22533   u32 vrf_id = 0;
22534   int ret;
22535
22536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22537     {
22538       if (unformat (i, "%U - %U",
22539                     unformat_ip4_address, &v4first,
22540                     unformat_ip4_address, &v4last))
22541         {
22542           if (range_set)
22543             {
22544               errmsg ("one range per message (range already set)");
22545               return -99;
22546             }
22547           range_set = 1;
22548         }
22549       else if (unformat (i, "%U - %U",
22550                          unformat_ip6_address, &v6first,
22551                          unformat_ip6_address, &v6last))
22552         {
22553           if (range_set)
22554             {
22555               errmsg ("one range per message (range already set)");
22556               return -99;
22557             }
22558           range_set = 2;
22559         }
22560       else if (unformat (i, "vrf %d", &vrf_id))
22561         ;
22562       else
22563         break;
22564     }
22565
22566   if (range_set == 0)
22567     {
22568       errmsg ("address range not set");
22569       return -99;
22570     }
22571
22572   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22573   mp->vrf_id = ntohl (vrf_id);
22574   /* ipv6? */
22575   if (range_set == 2)
22576     {
22577       mp->is_ipv6 = 1;
22578       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22579       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22580     }
22581   else
22582     {
22583       mp->is_ipv6 = 0;
22584       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22585       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22586     }
22587   S (mp);
22588   W (ret);
22589   return ret;
22590 }
22591
22592 static void vl_api_app_namespace_add_del_reply_t_handler
22593   (vl_api_app_namespace_add_del_reply_t * mp)
22594 {
22595   vat_main_t *vam = &vat_main;
22596   i32 retval = ntohl (mp->retval);
22597   if (vam->async_mode)
22598     {
22599       vam->async_errors += (retval < 0);
22600     }
22601   else
22602     {
22603       vam->retval = retval;
22604       if (retval == 0)
22605         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22606       vam->result_ready = 1;
22607     }
22608 }
22609
22610 static void vl_api_app_namespace_add_del_reply_t_handler_json
22611   (vl_api_app_namespace_add_del_reply_t * mp)
22612 {
22613   vat_main_t *vam = &vat_main;
22614   vat_json_node_t node;
22615
22616   vat_json_init_object (&node);
22617   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22618   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22619
22620   vat_json_print (vam->ofp, &node);
22621   vat_json_free (&node);
22622
22623   vam->retval = ntohl (mp->retval);
22624   vam->result_ready = 1;
22625 }
22626
22627 static int
22628 api_app_namespace_add_del (vat_main_t * vam)
22629 {
22630   vl_api_app_namespace_add_del_t *mp;
22631   unformat_input_t *i = vam->input;
22632   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22633   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22634   u64 secret;
22635   int ret;
22636
22637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22638     {
22639       if (unformat (i, "id %_%v%_", &ns_id))
22640         ;
22641       else if (unformat (i, "secret %lu", &secret))
22642         secret_set = 1;
22643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22644         sw_if_index_set = 1;
22645       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22646         ;
22647       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22648         ;
22649       else
22650         break;
22651     }
22652   if (!ns_id || !secret_set || !sw_if_index_set)
22653     {
22654       errmsg ("namespace id, secret and sw_if_index must be set");
22655       return -99;
22656     }
22657   if (vec_len (ns_id) > 64)
22658     {
22659       errmsg ("namespace id too long");
22660       return -99;
22661     }
22662   M (APP_NAMESPACE_ADD_DEL, mp);
22663
22664   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22665   mp->namespace_id_len = vec_len (ns_id);
22666   mp->secret = clib_host_to_net_u64 (secret);
22667   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22668   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22669   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22670   vec_free (ns_id);
22671   S (mp);
22672   W (ret);
22673   return ret;
22674 }
22675
22676 static int
22677 api_sock_init_shm (vat_main_t * vam)
22678 {
22679 #if VPP_API_TEST_BUILTIN == 0
22680   unformat_input_t *i = vam->input;
22681   vl_api_shm_elem_config_t *config = 0;
22682   u64 size = 64 << 20;
22683   int rv;
22684
22685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22686     {
22687       if (unformat (i, "size %U", unformat_memory_size, &size))
22688         ;
22689       else
22690         break;
22691     }
22692
22693   /*
22694    * Canned custom ring allocator config.
22695    * Should probably parse all of this
22696    */
22697   vec_validate (config, 6);
22698   config[0].type = VL_API_VLIB_RING;
22699   config[0].size = 256;
22700   config[0].count = 32;
22701
22702   config[1].type = VL_API_VLIB_RING;
22703   config[1].size = 1024;
22704   config[1].count = 16;
22705
22706   config[2].type = VL_API_VLIB_RING;
22707   config[2].size = 4096;
22708   config[2].count = 2;
22709
22710   config[3].type = VL_API_CLIENT_RING;
22711   config[3].size = 256;
22712   config[3].count = 32;
22713
22714   config[4].type = VL_API_CLIENT_RING;
22715   config[4].size = 1024;
22716   config[4].count = 16;
22717
22718   config[5].type = VL_API_CLIENT_RING;
22719   config[5].size = 4096;
22720   config[5].count = 2;
22721
22722   config[6].type = VL_API_QUEUE;
22723   config[6].count = 128;
22724   config[6].size = sizeof (uword);
22725
22726   rv = vl_socket_client_init_shm (config);
22727   if (!rv)
22728     vam->client_index_invalid = 1;
22729   return rv;
22730 #else
22731   return -99;
22732 #endif
22733 }
22734
22735 static int
22736 api_dns_enable_disable (vat_main_t * vam)
22737 {
22738   unformat_input_t *line_input = vam->input;
22739   vl_api_dns_enable_disable_t *mp;
22740   u8 enable_disable = 1;
22741   int ret;
22742
22743   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22744     {
22745       if (unformat (line_input, "disable"))
22746         enable_disable = 0;
22747       if (unformat (line_input, "enable"))
22748         enable_disable = 1;
22749       else
22750         break;
22751     }
22752
22753   /* Construct the API message */
22754   M (DNS_ENABLE_DISABLE, mp);
22755   mp->enable = enable_disable;
22756
22757   /* send it... */
22758   S (mp);
22759   /* Wait for the reply */
22760   W (ret);
22761   return ret;
22762 }
22763
22764 static int
22765 api_dns_resolve_name (vat_main_t * vam)
22766 {
22767   unformat_input_t *line_input = vam->input;
22768   vl_api_dns_resolve_name_t *mp;
22769   u8 *name = 0;
22770   int ret;
22771
22772   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22773     {
22774       if (unformat (line_input, "%s", &name))
22775         ;
22776       else
22777         break;
22778     }
22779
22780   if (vec_len (name) > 127)
22781     {
22782       errmsg ("name too long");
22783       return -99;
22784     }
22785
22786   /* Construct the API message */
22787   M (DNS_RESOLVE_NAME, mp);
22788   memcpy (mp->name, name, vec_len (name));
22789   vec_free (name);
22790
22791   /* send it... */
22792   S (mp);
22793   /* Wait for the reply */
22794   W (ret);
22795   return ret;
22796 }
22797
22798 static int
22799 api_dns_resolve_ip (vat_main_t * vam)
22800 {
22801   unformat_input_t *line_input = vam->input;
22802   vl_api_dns_resolve_ip_t *mp;
22803   int is_ip6 = -1;
22804   ip4_address_t addr4;
22805   ip6_address_t addr6;
22806   int ret;
22807
22808   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22809     {
22810       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22811         is_ip6 = 1;
22812       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22813         is_ip6 = 0;
22814       else
22815         break;
22816     }
22817
22818   if (is_ip6 == -1)
22819     {
22820       errmsg ("missing address");
22821       return -99;
22822     }
22823
22824   /* Construct the API message */
22825   M (DNS_RESOLVE_IP, mp);
22826   mp->is_ip6 = is_ip6;
22827   if (is_ip6)
22828     memcpy (mp->address, &addr6, sizeof (addr6));
22829   else
22830     memcpy (mp->address, &addr4, sizeof (addr4));
22831
22832   /* send it... */
22833   S (mp);
22834   /* Wait for the reply */
22835   W (ret);
22836   return ret;
22837 }
22838
22839 static int
22840 api_dns_name_server_add_del (vat_main_t * vam)
22841 {
22842   unformat_input_t *i = vam->input;
22843   vl_api_dns_name_server_add_del_t *mp;
22844   u8 is_add = 1;
22845   ip6_address_t ip6_server;
22846   ip4_address_t ip4_server;
22847   int ip6_set = 0;
22848   int ip4_set = 0;
22849   int ret = 0;
22850
22851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22852     {
22853       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22854         ip6_set = 1;
22855       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22856         ip4_set = 1;
22857       else if (unformat (i, "del"))
22858         is_add = 0;
22859       else
22860         {
22861           clib_warning ("parse error '%U'", format_unformat_error, i);
22862           return -99;
22863         }
22864     }
22865
22866   if (ip4_set && ip6_set)
22867     {
22868       errmsg ("Only one server address allowed per message");
22869       return -99;
22870     }
22871   if ((ip4_set + ip6_set) == 0)
22872     {
22873       errmsg ("Server address required");
22874       return -99;
22875     }
22876
22877   /* Construct the API message */
22878   M (DNS_NAME_SERVER_ADD_DEL, mp);
22879
22880   if (ip6_set)
22881     {
22882       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22883       mp->is_ip6 = 1;
22884     }
22885   else
22886     {
22887       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22888       mp->is_ip6 = 0;
22889     }
22890
22891   mp->is_add = is_add;
22892
22893   /* send it... */
22894   S (mp);
22895
22896   /* Wait for a reply, return good/bad news  */
22897   W (ret);
22898   return ret;
22899 }
22900
22901 static void
22902 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22903 {
22904   vat_main_t *vam = &vat_main;
22905
22906   if (mp->is_ip4)
22907     {
22908       print (vam->ofp,
22909              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22910              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22911              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22912              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22913              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22914              clib_net_to_host_u32 (mp->action_index), mp->tag);
22915     }
22916   else
22917     {
22918       print (vam->ofp,
22919              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22920              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22921              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22922              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22923              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22924              clib_net_to_host_u32 (mp->action_index), mp->tag);
22925     }
22926 }
22927
22928 static void
22929 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22930                                              mp)
22931 {
22932   vat_main_t *vam = &vat_main;
22933   vat_json_node_t *node = NULL;
22934   struct in6_addr ip6;
22935   struct in_addr ip4;
22936
22937   if (VAT_JSON_ARRAY != vam->json_tree.type)
22938     {
22939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22940       vat_json_init_array (&vam->json_tree);
22941     }
22942   node = vat_json_array_add (&vam->json_tree);
22943   vat_json_init_object (node);
22944
22945   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22946   vat_json_object_add_uint (node, "appns_index",
22947                             clib_net_to_host_u32 (mp->appns_index));
22948   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22949   vat_json_object_add_uint (node, "scope", mp->scope);
22950   vat_json_object_add_uint (node, "action_index",
22951                             clib_net_to_host_u32 (mp->action_index));
22952   vat_json_object_add_uint (node, "lcl_port",
22953                             clib_net_to_host_u16 (mp->lcl_port));
22954   vat_json_object_add_uint (node, "rmt_port",
22955                             clib_net_to_host_u16 (mp->rmt_port));
22956   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22957   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22958   vat_json_object_add_string_copy (node, "tag", mp->tag);
22959   if (mp->is_ip4)
22960     {
22961       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22962       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22963       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22964       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22965     }
22966   else
22967     {
22968       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22969       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22970       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22971       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22972     }
22973 }
22974
22975 static int
22976 api_session_rule_add_del (vat_main_t * vam)
22977 {
22978   vl_api_session_rule_add_del_t *mp;
22979   unformat_input_t *i = vam->input;
22980   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22981   u32 appns_index = 0, scope = 0;
22982   ip4_address_t lcl_ip4, rmt_ip4;
22983   ip6_address_t lcl_ip6, rmt_ip6;
22984   u8 is_ip4 = 1, conn_set = 0;
22985   u8 is_add = 1, *tag = 0;
22986   int ret;
22987
22988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22989     {
22990       if (unformat (i, "del"))
22991         is_add = 0;
22992       else if (unformat (i, "add"))
22993         ;
22994       else if (unformat (i, "proto tcp"))
22995         proto = 0;
22996       else if (unformat (i, "proto udp"))
22997         proto = 1;
22998       else if (unformat (i, "appns %d", &appns_index))
22999         ;
23000       else if (unformat (i, "scope %d", &scope))
23001         ;
23002       else if (unformat (i, "tag %_%v%_", &tag))
23003         ;
23004       else
23005         if (unformat
23006             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
23007              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
23008              &rmt_port))
23009         {
23010           is_ip4 = 1;
23011           conn_set = 1;
23012         }
23013       else
23014         if (unformat
23015             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
23016              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
23017              &rmt_port))
23018         {
23019           is_ip4 = 0;
23020           conn_set = 1;
23021         }
23022       else if (unformat (i, "action %d", &action))
23023         ;
23024       else
23025         break;
23026     }
23027   if (proto == ~0 || !conn_set || action == ~0)
23028     {
23029       errmsg ("transport proto, connection and action must be set");
23030       return -99;
23031     }
23032
23033   if (scope > 3)
23034     {
23035       errmsg ("scope should be 0-3");
23036       return -99;
23037     }
23038
23039   M (SESSION_RULE_ADD_DEL, mp);
23040
23041   mp->is_ip4 = is_ip4;
23042   mp->transport_proto = proto;
23043   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
23044   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
23045   mp->lcl_plen = lcl_plen;
23046   mp->rmt_plen = rmt_plen;
23047   mp->action_index = clib_host_to_net_u32 (action);
23048   mp->appns_index = clib_host_to_net_u32 (appns_index);
23049   mp->scope = scope;
23050   mp->is_add = is_add;
23051   if (is_ip4)
23052     {
23053       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
23054       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
23055     }
23056   else
23057     {
23058       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23059       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23060     }
23061   if (tag)
23062     {
23063       clib_memcpy (mp->tag, tag, vec_len (tag));
23064       vec_free (tag);
23065     }
23066
23067   S (mp);
23068   W (ret);
23069   return ret;
23070 }
23071
23072 static int
23073 api_session_rules_dump (vat_main_t * vam)
23074 {
23075   vl_api_session_rules_dump_t *mp;
23076   vl_api_control_ping_t *mp_ping;
23077   int ret;
23078
23079   if (!vam->json_output)
23080     {
23081       print (vam->ofp, "%=20s", "Session Rules");
23082     }
23083
23084   M (SESSION_RULES_DUMP, mp);
23085   /* send it... */
23086   S (mp);
23087
23088   /* Use a control ping for synchronization */
23089   MPING (CONTROL_PING, mp_ping);
23090   S (mp_ping);
23091
23092   /* Wait for a reply... */
23093   W (ret);
23094   return ret;
23095 }
23096
23097 static int
23098 api_ip_container_proxy_add_del (vat_main_t * vam)
23099 {
23100   vl_api_ip_container_proxy_add_del_t *mp;
23101   unformat_input_t *i = vam->input;
23102   u32 plen = ~0, sw_if_index = ~0;
23103   ip4_address_t ip4;
23104   ip6_address_t ip6;
23105   u8 is_ip4 = 1;
23106   u8 is_add = 1;
23107   int ret;
23108
23109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23110     {
23111       if (unformat (i, "del"))
23112         is_add = 0;
23113       else if (unformat (i, "add"))
23114         ;
23115       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23116         {
23117           is_ip4 = 1;
23118           plen = 32;
23119         }
23120       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23121         {
23122           is_ip4 = 0;
23123           plen = 128;
23124         }
23125       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23126         ;
23127       else
23128         break;
23129     }
23130   if (sw_if_index == ~0 || plen == ~0)
23131     {
23132       errmsg ("address and sw_if_index must be set");
23133       return -99;
23134     }
23135
23136   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23137
23138   mp->is_ip4 = is_ip4;
23139   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23140   mp->plen = plen;
23141   mp->is_add = is_add;
23142   if (is_ip4)
23143     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23144   else
23145     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23146
23147   S (mp);
23148   W (ret);
23149   return ret;
23150 }
23151
23152 static int
23153 api_qos_record_enable_disable (vat_main_t * vam)
23154 {
23155   unformat_input_t *i = vam->input;
23156   vl_api_qos_record_enable_disable_t *mp;
23157   u32 sw_if_index, qs = 0xff;
23158   u8 sw_if_index_set = 0;
23159   u8 enable = 1;
23160   int ret;
23161
23162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23163     {
23164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23165         sw_if_index_set = 1;
23166       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23167         sw_if_index_set = 1;
23168       else if (unformat (i, "%U", unformat_qos_source, &qs))
23169         ;
23170       else if (unformat (i, "disable"))
23171         enable = 0;
23172       else
23173         {
23174           clib_warning ("parse error '%U'", format_unformat_error, i);
23175           return -99;
23176         }
23177     }
23178
23179   if (sw_if_index_set == 0)
23180     {
23181       errmsg ("missing interface name or sw_if_index");
23182       return -99;
23183     }
23184   if (qs == 0xff)
23185     {
23186       errmsg ("input location must be specified");
23187       return -99;
23188     }
23189
23190   M (QOS_RECORD_ENABLE_DISABLE, mp);
23191
23192   mp->sw_if_index = ntohl (sw_if_index);
23193   mp->input_source = qs;
23194   mp->enable = enable;
23195
23196   S (mp);
23197   W (ret);
23198   return ret;
23199 }
23200
23201
23202 static int
23203 q_or_quit (vat_main_t * vam)
23204 {
23205 #if VPP_API_TEST_BUILTIN == 0
23206   longjmp (vam->jump_buf, 1);
23207 #endif
23208   return 0;                     /* not so much */
23209 }
23210
23211 static int
23212 q (vat_main_t * vam)
23213 {
23214   return q_or_quit (vam);
23215 }
23216
23217 static int
23218 quit (vat_main_t * vam)
23219 {
23220   return q_or_quit (vam);
23221 }
23222
23223 static int
23224 comment (vat_main_t * vam)
23225 {
23226   return 0;
23227 }
23228
23229 static int
23230 statseg (vat_main_t * vam)
23231 {
23232   ssvm_private_t *ssvmp = &vam->stat_segment;
23233   ssvm_shared_header_t *shared_header = ssvmp->sh;
23234   vlib_counter_t **counters;
23235   u64 thread0_index1_packets;
23236   u64 thread0_index1_bytes;
23237   f64 vector_rate, input_rate;
23238   uword *p;
23239
23240   uword *counter_vector_by_name;
23241   if (vam->stat_segment_lockp == 0)
23242     {
23243       errmsg ("Stat segment not mapped...");
23244       return -99;
23245     }
23246
23247   /* look up "/if/rx for sw_if_index 1 as a test */
23248
23249   clib_spinlock_lock (vam->stat_segment_lockp);
23250
23251   counter_vector_by_name = (uword *) shared_header->opaque[1];
23252
23253   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23254   if (p == 0)
23255     {
23256       clib_spinlock_unlock (vam->stat_segment_lockp);
23257       errmsg ("/if/tx not found?");
23258       return -99;
23259     }
23260
23261   /* Fish per-thread vector of combined counters from shared memory */
23262   counters = (vlib_counter_t **) p[0];
23263
23264   if (vec_len (counters[0]) < 2)
23265     {
23266       clib_spinlock_unlock (vam->stat_segment_lockp);
23267       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23268       return -99;
23269     }
23270
23271   /* Read thread 0 sw_if_index 1 counter */
23272   thread0_index1_packets = counters[0][1].packets;
23273   thread0_index1_bytes = counters[0][1].bytes;
23274
23275   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23276   if (p == 0)
23277     {
23278       clib_spinlock_unlock (vam->stat_segment_lockp);
23279       errmsg ("vector_rate not found?");
23280       return -99;
23281     }
23282
23283   vector_rate = *(f64 *) (p[0]);
23284   p = hash_get_mem (counter_vector_by_name, "input_rate");
23285   if (p == 0)
23286     {
23287       clib_spinlock_unlock (vam->stat_segment_lockp);
23288       errmsg ("input_rate not found?");
23289       return -99;
23290     }
23291   input_rate = *(f64 *) (p[0]);
23292
23293   clib_spinlock_unlock (vam->stat_segment_lockp);
23294
23295   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23296          vector_rate, input_rate);
23297   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23298          thread0_index1_packets, thread0_index1_bytes);
23299
23300   return 0;
23301 }
23302
23303 static int
23304 cmd_cmp (void *a1, void *a2)
23305 {
23306   u8 **c1 = a1;
23307   u8 **c2 = a2;
23308
23309   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23310 }
23311
23312 static int
23313 help (vat_main_t * vam)
23314 {
23315   u8 **cmds = 0;
23316   u8 *name = 0;
23317   hash_pair_t *p;
23318   unformat_input_t *i = vam->input;
23319   int j;
23320
23321   if (unformat (i, "%s", &name))
23322     {
23323       uword *hs;
23324
23325       vec_add1 (name, 0);
23326
23327       hs = hash_get_mem (vam->help_by_name, name);
23328       if (hs)
23329         print (vam->ofp, "usage: %s %s", name, hs[0]);
23330       else
23331         print (vam->ofp, "No such msg / command '%s'", name);
23332       vec_free (name);
23333       return 0;
23334     }
23335
23336   print (vam->ofp, "Help is available for the following:");
23337
23338     /* *INDENT-OFF* */
23339     hash_foreach_pair (p, vam->function_by_name,
23340     ({
23341       vec_add1 (cmds, (u8 *)(p->key));
23342     }));
23343     /* *INDENT-ON* */
23344
23345   vec_sort_with_function (cmds, cmd_cmp);
23346
23347   for (j = 0; j < vec_len (cmds); j++)
23348     print (vam->ofp, "%s", cmds[j]);
23349
23350   vec_free (cmds);
23351   return 0;
23352 }
23353
23354 static int
23355 set (vat_main_t * vam)
23356 {
23357   u8 *name = 0, *value = 0;
23358   unformat_input_t *i = vam->input;
23359
23360   if (unformat (i, "%s", &name))
23361     {
23362       /* The input buffer is a vector, not a string. */
23363       value = vec_dup (i->buffer);
23364       vec_delete (value, i->index, 0);
23365       /* Almost certainly has a trailing newline */
23366       if (value[vec_len (value) - 1] == '\n')
23367         value[vec_len (value) - 1] = 0;
23368       /* Make sure it's a proper string, one way or the other */
23369       vec_add1 (value, 0);
23370       (void) clib_macro_set_value (&vam->macro_main,
23371                                    (char *) name, (char *) value);
23372     }
23373   else
23374     errmsg ("usage: set <name> <value>");
23375
23376   vec_free (name);
23377   vec_free (value);
23378   return 0;
23379 }
23380
23381 static int
23382 unset (vat_main_t * vam)
23383 {
23384   u8 *name = 0;
23385
23386   if (unformat (vam->input, "%s", &name))
23387     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23388       errmsg ("unset: %s wasn't set", name);
23389   vec_free (name);
23390   return 0;
23391 }
23392
23393 typedef struct
23394 {
23395   u8 *name;
23396   u8 *value;
23397 } macro_sort_t;
23398
23399
23400 static int
23401 macro_sort_cmp (void *a1, void *a2)
23402 {
23403   macro_sort_t *s1 = a1;
23404   macro_sort_t *s2 = a2;
23405
23406   return strcmp ((char *) (s1->name), (char *) (s2->name));
23407 }
23408
23409 static int
23410 dump_macro_table (vat_main_t * vam)
23411 {
23412   macro_sort_t *sort_me = 0, *sm;
23413   int i;
23414   hash_pair_t *p;
23415
23416     /* *INDENT-OFF* */
23417     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23418     ({
23419       vec_add2 (sort_me, sm, 1);
23420       sm->name = (u8 *)(p->key);
23421       sm->value = (u8 *) (p->value[0]);
23422     }));
23423     /* *INDENT-ON* */
23424
23425   vec_sort_with_function (sort_me, macro_sort_cmp);
23426
23427   if (vec_len (sort_me))
23428     print (vam->ofp, "%-15s%s", "Name", "Value");
23429   else
23430     print (vam->ofp, "The macro table is empty...");
23431
23432   for (i = 0; i < vec_len (sort_me); i++)
23433     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23434   return 0;
23435 }
23436
23437 static int
23438 dump_node_table (vat_main_t * vam)
23439 {
23440   int i, j;
23441   vlib_node_t *node, *next_node;
23442
23443   if (vec_len (vam->graph_nodes) == 0)
23444     {
23445       print (vam->ofp, "Node table empty, issue get_node_graph...");
23446       return 0;
23447     }
23448
23449   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23450     {
23451       node = vam->graph_nodes[0][i];
23452       print (vam->ofp, "[%d] %s", i, node->name);
23453       for (j = 0; j < vec_len (node->next_nodes); j++)
23454         {
23455           if (node->next_nodes[j] != ~0)
23456             {
23457               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23458               print (vam->ofp, "  [%d] %s", j, next_node->name);
23459             }
23460         }
23461     }
23462   return 0;
23463 }
23464
23465 static int
23466 value_sort_cmp (void *a1, void *a2)
23467 {
23468   name_sort_t *n1 = a1;
23469   name_sort_t *n2 = a2;
23470
23471   if (n1->value < n2->value)
23472     return -1;
23473   if (n1->value > n2->value)
23474     return 1;
23475   return 0;
23476 }
23477
23478
23479 static int
23480 dump_msg_api_table (vat_main_t * vam)
23481 {
23482   api_main_t *am = &api_main;
23483   name_sort_t *nses = 0, *ns;
23484   hash_pair_t *hp;
23485   int i;
23486
23487   /* *INDENT-OFF* */
23488   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23489   ({
23490     vec_add2 (nses, ns, 1);
23491     ns->name = (u8 *)(hp->key);
23492     ns->value = (u32) hp->value[0];
23493   }));
23494   /* *INDENT-ON* */
23495
23496   vec_sort_with_function (nses, value_sort_cmp);
23497
23498   for (i = 0; i < vec_len (nses); i++)
23499     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23500   vec_free (nses);
23501   return 0;
23502 }
23503
23504 static int
23505 get_msg_id (vat_main_t * vam)
23506 {
23507   u8 *name_and_crc;
23508   u32 message_index;
23509
23510   if (unformat (vam->input, "%s", &name_and_crc))
23511     {
23512       message_index = vl_msg_api_get_msg_index (name_and_crc);
23513       if (message_index == ~0)
23514         {
23515           print (vam->ofp, " '%s' not found", name_and_crc);
23516           return 0;
23517         }
23518       print (vam->ofp, " '%s' has message index %d",
23519              name_and_crc, message_index);
23520       return 0;
23521     }
23522   errmsg ("name_and_crc required...");
23523   return 0;
23524 }
23525
23526 static int
23527 search_node_table (vat_main_t * vam)
23528 {
23529   unformat_input_t *line_input = vam->input;
23530   u8 *node_to_find;
23531   int j;
23532   vlib_node_t *node, *next_node;
23533   uword *p;
23534
23535   if (vam->graph_node_index_by_name == 0)
23536     {
23537       print (vam->ofp, "Node table empty, issue get_node_graph...");
23538       return 0;
23539     }
23540
23541   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23542     {
23543       if (unformat (line_input, "%s", &node_to_find))
23544         {
23545           vec_add1 (node_to_find, 0);
23546           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23547           if (p == 0)
23548             {
23549               print (vam->ofp, "%s not found...", node_to_find);
23550               goto out;
23551             }
23552           node = vam->graph_nodes[0][p[0]];
23553           print (vam->ofp, "[%d] %s", p[0], node->name);
23554           for (j = 0; j < vec_len (node->next_nodes); j++)
23555             {
23556               if (node->next_nodes[j] != ~0)
23557                 {
23558                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23559                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23560                 }
23561             }
23562         }
23563
23564       else
23565         {
23566           clib_warning ("parse error '%U'", format_unformat_error,
23567                         line_input);
23568           return -99;
23569         }
23570
23571     out:
23572       vec_free (node_to_find);
23573
23574     }
23575
23576   return 0;
23577 }
23578
23579
23580 static int
23581 script (vat_main_t * vam)
23582 {
23583 #if (VPP_API_TEST_BUILTIN==0)
23584   u8 *s = 0;
23585   char *save_current_file;
23586   unformat_input_t save_input;
23587   jmp_buf save_jump_buf;
23588   u32 save_line_number;
23589
23590   FILE *new_fp, *save_ifp;
23591
23592   if (unformat (vam->input, "%s", &s))
23593     {
23594       new_fp = fopen ((char *) s, "r");
23595       if (new_fp == 0)
23596         {
23597           errmsg ("Couldn't open script file %s", s);
23598           vec_free (s);
23599           return -99;
23600         }
23601     }
23602   else
23603     {
23604       errmsg ("Missing script name");
23605       return -99;
23606     }
23607
23608   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23609   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23610   save_ifp = vam->ifp;
23611   save_line_number = vam->input_line_number;
23612   save_current_file = (char *) vam->current_file;
23613
23614   vam->input_line_number = 0;
23615   vam->ifp = new_fp;
23616   vam->current_file = s;
23617   do_one_file (vam);
23618
23619   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23620   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23621   vam->ifp = save_ifp;
23622   vam->input_line_number = save_line_number;
23623   vam->current_file = (u8 *) save_current_file;
23624   vec_free (s);
23625
23626   return 0;
23627 #else
23628   clib_warning ("use the exec command...");
23629   return -99;
23630 #endif
23631 }
23632
23633 static int
23634 echo (vat_main_t * vam)
23635 {
23636   print (vam->ofp, "%v", vam->input->buffer);
23637   return 0;
23638 }
23639
23640 /* List of API message constructors, CLI names map to api_xxx */
23641 #define foreach_vpe_api_msg                                             \
23642 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23643 _(sw_interface_dump,"")                                                 \
23644 _(sw_interface_set_flags,                                               \
23645   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23646 _(sw_interface_add_del_address,                                         \
23647   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23648 _(sw_interface_set_rx_mode,                                             \
23649   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23650 _(sw_interface_set_rx_placement,                                        \
23651   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23652 _(sw_interface_rx_placement_dump,                                       \
23653   "[<intfc> | sw_if_index <id>]")                                         \
23654 _(sw_interface_set_table,                                               \
23655   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23656 _(sw_interface_set_mpls_enable,                                         \
23657   "<intfc> | sw_if_index [disable | dis]")                              \
23658 _(sw_interface_set_vpath,                                               \
23659   "<intfc> | sw_if_index <id> enable | disable")                        \
23660 _(sw_interface_set_vxlan_bypass,                                        \
23661   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23662 _(sw_interface_set_geneve_bypass,                                       \
23663   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23664 _(sw_interface_set_l2_xconnect,                                         \
23665   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23666   "enable | disable")                                                   \
23667 _(sw_interface_set_l2_bridge,                                           \
23668   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23669   "[shg <split-horizon-group>] [bvi]\n"                                 \
23670   "enable | disable")                                                   \
23671 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23672 _(bridge_domain_add_del,                                                \
23673   "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") \
23674 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23675 _(l2fib_add_del,                                                        \
23676   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23677 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23678 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23679 _(l2_flags,                                                             \
23680   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23681 _(bridge_flags,                                                         \
23682   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23683 _(tap_connect,                                                          \
23684   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23685 _(tap_modify,                                                           \
23686   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23687 _(tap_delete,                                                           \
23688   "<vpp-if-name> | sw_if_index <id>")                                   \
23689 _(sw_interface_tap_dump, "")                                            \
23690 _(tap_create_v2,                                                        \
23691   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23692 _(tap_delete_v2,                                                        \
23693   "<vpp-if-name> | sw_if_index <id>")                                   \
23694 _(sw_interface_tap_v2_dump, "")                                         \
23695 _(bond_create,                                                          \
23696   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23697   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23698 _(bond_delete,                                                          \
23699   "<vpp-if-name> | sw_if_index <id>")                                   \
23700 _(bond_enslave,                                                         \
23701   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23702 _(bond_detach_slave,                                                    \
23703   "sw_if_index <n>")                                                    \
23704 _(sw_interface_bond_dump, "")                                           \
23705 _(sw_interface_slave_dump,                                              \
23706   "<vpp-if-name> | sw_if_index <id>")                                   \
23707 _(ip_table_add_del,                                                     \
23708   "table <n> [ipv6] [add | del]\n")                                     \
23709 _(ip_add_del_route,                                                     \
23710   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23711   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23712   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23713   "[multipath] [count <n>] [del]")                                      \
23714 _(ip_mroute_add_del,                                                    \
23715   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23716   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23717 _(mpls_table_add_del,                                                   \
23718   "table <n> [add | del]\n")                                            \
23719 _(mpls_route_add_del,                                                   \
23720   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23721   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23722   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23723   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23724   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23725   "[count <n>] [del]")                                                  \
23726 _(mpls_ip_bind_unbind,                                                  \
23727   "<label> <addr/len>")                                                 \
23728 _(mpls_tunnel_add_del,                                                  \
23729   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23730   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23731   "[l2-only]  [out-label <n>]")                                         \
23732 _(sr_mpls_policy_add,                                                   \
23733   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23734 _(sr_mpls_policy_del,                                                   \
23735   "bsid <id>")                                                          \
23736 _(bier_table_add_del,                                                   \
23737   "<label> <sub-domain> <set> <bsl> [del]")                             \
23738 _(bier_route_add_del,                                                   \
23739   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23740   "[<intfc> | sw_if_index <id>]"                                        \
23741   "[weight <n>] [del] [multipath]")                                     \
23742 _(proxy_arp_add_del,                                                    \
23743   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23744 _(proxy_arp_intfc_enable_disable,                                       \
23745   "<intfc> | sw_if_index <id> enable | disable")                        \
23746 _(sw_interface_set_unnumbered,                                          \
23747   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23748 _(ip_neighbor_add_del,                                                  \
23749   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23750   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23751 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23752 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23753   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23754   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23755   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23756 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23757 _(reset_fib, "vrf <n> [ipv6]")                                          \
23758 _(dhcp_proxy_config,                                                    \
23759   "svr <v46-address> src <v46-address>\n"                               \
23760    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23761 _(dhcp_proxy_set_vss,                                                   \
23762   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23763 _(dhcp_proxy_dump, "ip6")                                               \
23764 _(dhcp_client_config,                                                   \
23765   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23766 _(set_ip_flow_hash,                                                     \
23767   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23768 _(sw_interface_ip6_enable_disable,                                      \
23769   "<intfc> | sw_if_index <id> enable | disable")                        \
23770 _(sw_interface_ip6_set_link_local_address,                              \
23771   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23772 _(ip6nd_proxy_add_del,                                                  \
23773   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23774 _(ip6nd_proxy_dump, "")                                                 \
23775 _(sw_interface_ip6nd_ra_prefix,                                         \
23776   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23777   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23778   "[nolink] [isno]")                                                    \
23779 _(sw_interface_ip6nd_ra_config,                                         \
23780   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23781   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23782   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23783 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23784 _(l2_patch_add_del,                                                     \
23785   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23786   "enable | disable")                                                   \
23787 _(sr_localsid_add_del,                                                  \
23788   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23789   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23790 _(classify_add_del_table,                                               \
23791   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23792   " [del] [del-chain] mask <mask-value>\n"                              \
23793   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23794   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23795 _(classify_add_del_session,                                             \
23796   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23797   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23798   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23799   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23800 _(classify_set_interface_ip_table,                                      \
23801   "<intfc> | sw_if_index <nn> table <nn>")                              \
23802 _(classify_set_interface_l2_tables,                                     \
23803   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23804   "  [other-table <nn>]")                                               \
23805 _(get_node_index, "node <node-name")                                    \
23806 _(add_node_next, "node <node-name> next <next-node-name>")              \
23807 _(l2tpv3_create_tunnel,                                                 \
23808   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23809   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23810   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23811 _(l2tpv3_set_tunnel_cookies,                                            \
23812   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23813   "[new_remote_cookie <nn>]\n")                                         \
23814 _(l2tpv3_interface_enable_disable,                                      \
23815   "<intfc> | sw_if_index <nn> enable | disable")                        \
23816 _(l2tpv3_set_lookup_key,                                                \
23817   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23818 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23819 _(vxlan_offload_rx,                                                     \
23820   "hw { <interface name> | hw_if_index <nn>} "                          \
23821   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23822 _(vxlan_add_del_tunnel,                                                 \
23823   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23824   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23825   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23826 _(geneve_add_del_tunnel,                                                \
23827   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23828   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23829   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23830 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23831 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23832 _(gre_add_del_tunnel,                                                   \
23833   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23834   "[teb | erspan <session-id>] [del]")                                  \
23835 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23836 _(l2_fib_clear_table, "")                                               \
23837 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23838 _(l2_interface_vlan_tag_rewrite,                                        \
23839   "<intfc> | sw_if_index <nn> \n"                                       \
23840   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23841   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23842 _(create_vhost_user_if,                                                 \
23843         "socket <filename> [server] [renumber <dev_instance>] "         \
23844         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23845         "[mac <mac_address>]")                                          \
23846 _(modify_vhost_user_if,                                                 \
23847         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23848         "[server] [renumber <dev_instance>]")                           \
23849 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23850 _(sw_interface_vhost_user_dump, "")                                     \
23851 _(show_version, "")                                                     \
23852 _(show_threads, "")                                                     \
23853 _(vxlan_gpe_add_del_tunnel,                                             \
23854   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23855   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23856   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23857   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23858 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23859 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23860 _(interface_name_renumber,                                              \
23861   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23862 _(input_acl_set_interface,                                              \
23863   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23864   "  [l2-table <nn>] [del]")                                            \
23865 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23866 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23867   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23868 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23869 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23870 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23871 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23872 _(ip_dump, "ipv4 | ipv6")                                               \
23873 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23874 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23875   "  spid_id <n> ")                                                     \
23876 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23877   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23878   "  integ_alg <alg> integ_key <hex>")                                  \
23879 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23880   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23881   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23882   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23883 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23884 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23885   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23886   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23887   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23888   "  [instance <n>]")     \
23889 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23890 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23891   "  <alg> <hex>\n")                                                    \
23892 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23893 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23894 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23895   "(auth_data 0x<data> | auth_data <data>)")                            \
23896 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23897   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23898 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23899   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23900   "(local|remote)")                                                     \
23901 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23902 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23903 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23904 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23905 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23906 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23907 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23908 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23909 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23910 _(delete_loopback,"sw_if_index <nn>")                                   \
23911 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23912 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23913 _(want_interface_events,  "enable|disable")                             \
23914 _(want_stats,"enable|disable")                                          \
23915 _(get_first_msg_id, "client <name>")                                    \
23916 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23917 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23918   "fib-id <nn> [ip4][ip6][default]")                                    \
23919 _(get_node_graph, " ")                                                  \
23920 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23921 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23922 _(ioam_disable, "")                                                     \
23923 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23924                             " sw_if_index <sw_if_index> p <priority> "  \
23925                             "w <weight>] [del]")                        \
23926 _(one_add_del_locator, "locator-set <locator_name> "                    \
23927                         "iface <intf> | sw_if_index <sw_if_index> "     \
23928                         "p <priority> w <weight> [del]")                \
23929 _(one_add_del_local_eid,"vni <vni> eid "                                \
23930                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23931                          "locator-set <locator_name> [del]"             \
23932                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23933 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23934 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23935 _(one_enable_disable, "enable|disable")                                 \
23936 _(one_map_register_enable_disable, "enable|disable")                    \
23937 _(one_map_register_fallback_threshold, "<value>")                       \
23938 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23939 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23940                                "[seid <seid>] "                         \
23941                                "rloc <locator> p <prio> "               \
23942                                "w <weight> [rloc <loc> ... ] "          \
23943                                "action <action> [del-all]")             \
23944 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23945                           "<local-eid>")                                \
23946 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23947 _(one_use_petr, "ip-address> | disable")                                \
23948 _(one_map_request_mode, "src-dst|dst-only")                             \
23949 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23950 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23951 _(one_locator_set_dump, "[local | remote]")                             \
23952 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23953 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23954                        "[local] | [remote]")                            \
23955 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23956 _(one_ndp_bd_get, "")                                                   \
23957 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23958 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23959 _(one_l2_arp_bd_get, "")                                                \
23960 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23961 _(one_stats_enable_disable, "enable|disable")                           \
23962 _(show_one_stats_enable_disable, "")                                    \
23963 _(one_eid_table_vni_dump, "")                                           \
23964 _(one_eid_table_map_dump, "l2|l3")                                      \
23965 _(one_map_resolver_dump, "")                                            \
23966 _(one_map_server_dump, "")                                              \
23967 _(one_adjacencies_get, "vni <vni>")                                     \
23968 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23969 _(show_one_rloc_probe_state, "")                                        \
23970 _(show_one_map_register_state, "")                                      \
23971 _(show_one_status, "")                                                  \
23972 _(one_stats_dump, "")                                                   \
23973 _(one_stats_flush, "")                                                  \
23974 _(one_get_map_request_itr_rlocs, "")                                    \
23975 _(one_map_register_set_ttl, "<ttl>")                                    \
23976 _(one_set_transport_protocol, "udp|api")                                \
23977 _(one_get_transport_protocol, "")                                       \
23978 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23979 _(one_show_xtr_mode, "")                                                \
23980 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23981 _(one_show_pitr_mode, "")                                               \
23982 _(one_enable_disable_petr_mode, "enable|disable")                       \
23983 _(one_show_petr_mode, "")                                               \
23984 _(show_one_nsh_mapping, "")                                             \
23985 _(show_one_pitr, "")                                                    \
23986 _(show_one_use_petr, "")                                                \
23987 _(show_one_map_request_mode, "")                                        \
23988 _(show_one_map_register_ttl, "")                                        \
23989 _(show_one_map_register_fallback_threshold, "")                         \
23990 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23991                             " sw_if_index <sw_if_index> p <priority> "  \
23992                             "w <weight>] [del]")                        \
23993 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23994                         "iface <intf> | sw_if_index <sw_if_index> "     \
23995                         "p <priority> w <weight> [del]")                \
23996 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23997                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23998                          "locator-set <locator_name> [del]"             \
23999                          "[key-id sha1|sha256 secret-key <secret-key>]") \
24000 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
24001 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
24002 _(lisp_enable_disable, "enable|disable")                                \
24003 _(lisp_map_register_enable_disable, "enable|disable")                   \
24004 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
24005 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
24006                                "[seid <seid>] "                         \
24007                                "rloc <locator> p <prio> "               \
24008                                "w <weight> [rloc <loc> ... ] "          \
24009                                "action <action> [del-all]")             \
24010 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
24011                           "<local-eid>")                                \
24012 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
24013 _(lisp_use_petr, "<ip-address> | disable")                              \
24014 _(lisp_map_request_mode, "src-dst|dst-only")                            \
24015 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
24016 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
24017 _(lisp_locator_set_dump, "[local | remote]")                            \
24018 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
24019 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
24020                        "[local] | [remote]")                            \
24021 _(lisp_eid_table_vni_dump, "")                                          \
24022 _(lisp_eid_table_map_dump, "l2|l3")                                     \
24023 _(lisp_map_resolver_dump, "")                                           \
24024 _(lisp_map_server_dump, "")                                             \
24025 _(lisp_adjacencies_get, "vni <vni>")                                    \
24026 _(gpe_fwd_entry_vnis_get, "")                                           \
24027 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
24028 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
24029                                 "[table <table-id>]")                   \
24030 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
24031 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
24032 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
24033 _(gpe_get_encap_mode, "")                                               \
24034 _(lisp_gpe_add_del_iface, "up|down")                                    \
24035 _(lisp_gpe_enable_disable, "enable|disable")                            \
24036 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
24037   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
24038 _(show_lisp_rloc_probe_state, "")                                       \
24039 _(show_lisp_map_register_state, "")                                     \
24040 _(show_lisp_status, "")                                                 \
24041 _(lisp_get_map_request_itr_rlocs, "")                                   \
24042 _(show_lisp_pitr, "")                                                   \
24043 _(show_lisp_use_petr, "")                                               \
24044 _(show_lisp_map_request_mode, "")                                       \
24045 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
24046 _(af_packet_delete, "name <host interface name>")                       \
24047 _(af_packet_dump, "")                                                   \
24048 _(policer_add_del, "name <policer name> <params> [del]")                \
24049 _(policer_dump, "[name <policer name>]")                                \
24050 _(policer_classify_set_interface,                                       \
24051   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24052   "  [l2-table <nn>] [del]")                                            \
24053 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
24054 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
24055     "[master|slave]")                                                   \
24056 _(netmap_delete, "name <interface name>")                               \
24057 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
24058 _(mpls_fib_dump, "")                                                    \
24059 _(classify_table_ids, "")                                               \
24060 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24061 _(classify_table_info, "table_id <nn>")                                 \
24062 _(classify_session_dump, "table_id <nn>")                               \
24063 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24064     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24065     "[template_interval <nn>] [udp_checksum]")                          \
24066 _(ipfix_exporter_dump, "")                                              \
24067 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24068 _(ipfix_classify_stream_dump, "")                                       \
24069 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24070 _(ipfix_classify_table_dump, "")                                        \
24071 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24072 _(sw_interface_span_dump, "[l2]")                                           \
24073 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24074 _(pg_create_interface, "if_id <nn>")                                    \
24075 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24076 _(pg_enable_disable, "[stream <id>] disable")                           \
24077 _(ip_source_and_port_range_check_add_del,                               \
24078   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24079 _(ip_source_and_port_range_check_interface_add_del,                     \
24080   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24081   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24082 _(ipsec_gre_add_del_tunnel,                                             \
24083   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24084 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24085 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24086 _(l2_interface_pbb_tag_rewrite,                                         \
24087   "<intfc> | sw_if_index <nn> \n"                                       \
24088   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24089   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24090 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24091 _(flow_classify_set_interface,                                          \
24092   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24093 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24094 _(ip_fib_dump, "")                                                      \
24095 _(ip_mfib_dump, "")                                                     \
24096 _(ip6_fib_dump, "")                                                     \
24097 _(ip6_mfib_dump, "")                                                    \
24098 _(feature_enable_disable, "arc_name <arc_name> "                        \
24099   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24100 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24101 "[disable]")                                                            \
24102 _(l2_xconnect_dump, "")                                                 \
24103 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24104 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24105 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24106 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24107 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24108 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24109 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24110   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24111 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24112 _(sock_init_shm, "size <nnn>")                                          \
24113 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24114 _(dns_enable_disable, "[enable][disable]")                              \
24115 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24116 _(dns_resolve_name, "<hostname>")                                       \
24117 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24118 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24119 _(dns_resolve_name, "<hostname>")                                       \
24120 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24121   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24122 _(session_rules_dump, "")                                               \
24123 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24124 _(output_acl_set_interface,                                             \
24125   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24126   "  [l2-table <nn>] [del]")                                            \
24127 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24128
24129 /* List of command functions, CLI names map directly to functions */
24130 #define foreach_cli_function                                    \
24131 _(comment, "usage: comment <ignore-rest-of-line>")              \
24132 _(dump_interface_table, "usage: dump_interface_table")          \
24133 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24134 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24135 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24136 _(dump_stats_table, "usage: dump_stats_table")                  \
24137 _(dump_macro_table, "usage: dump_macro_table ")                 \
24138 _(dump_node_table, "usage: dump_node_table")                    \
24139 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24140 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24141 _(echo, "usage: echo <message>")                                \
24142 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24143 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24144 _(help, "usage: help")                                          \
24145 _(q, "usage: quit")                                             \
24146 _(quit, "usage: quit")                                          \
24147 _(search_node_table, "usage: search_node_table <name>...")      \
24148 _(set, "usage: set <variable-name> <value>")                    \
24149 _(script, "usage: script <file-name>")                          \
24150 _(statseg, "usage: statseg");                                   \
24151 _(unset, "usage: unset <variable-name>")
24152
24153 #define _(N,n)                                  \
24154     static void vl_api_##n##_t_handler_uni      \
24155     (vl_api_##n##_t * mp)                       \
24156     {                                           \
24157         vat_main_t * vam = &vat_main;           \
24158         if (vam->json_output) {                 \
24159             vl_api_##n##_t_handler_json(mp);    \
24160         } else {                                \
24161             vl_api_##n##_t_handler(mp);         \
24162         }                                       \
24163     }
24164 foreach_vpe_api_reply_msg;
24165 #if VPP_API_TEST_BUILTIN == 0
24166 foreach_standalone_reply_msg;
24167 #endif
24168 #undef _
24169
24170 void
24171 vat_api_hookup (vat_main_t * vam)
24172 {
24173 #define _(N,n)                                                  \
24174     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24175                            vl_api_##n##_t_handler_uni,          \
24176                            vl_noop_handler,                     \
24177                            vl_api_##n##_t_endian,               \
24178                            vl_api_##n##_t_print,                \
24179                            sizeof(vl_api_##n##_t), 1);
24180   foreach_vpe_api_reply_msg;
24181 #if VPP_API_TEST_BUILTIN == 0
24182   foreach_standalone_reply_msg;
24183 #endif
24184 #undef _
24185
24186 #if (VPP_API_TEST_BUILTIN==0)
24187   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24188
24189   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24190
24191   vam->function_by_name = hash_create_string (0, sizeof (uword));
24192
24193   vam->help_by_name = hash_create_string (0, sizeof (uword));
24194 #endif
24195
24196   /* API messages we can send */
24197 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24198   foreach_vpe_api_msg;
24199 #undef _
24200
24201   /* Help strings */
24202 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24203   foreach_vpe_api_msg;
24204 #undef _
24205
24206   /* CLI functions */
24207 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24208   foreach_cli_function;
24209 #undef _
24210
24211   /* Help strings */
24212 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24213   foreach_cli_function;
24214 #undef _
24215 }
24216
24217 #if VPP_API_TEST_BUILTIN
24218 static clib_error_t *
24219 vat_api_hookup_shim (vlib_main_t * vm)
24220 {
24221   vat_api_hookup (&vat_main);
24222   return 0;
24223 }
24224
24225 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24226 #endif
24227
24228 /*
24229  * fd.io coding-style-patch-verification: ON
24230  *
24231  * Local Variables:
24232  * eval: (c-set-style "gnu")
24233  * End:
24234  */