Genric API types format/unformat support for VAT and custom dump
[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   unformat_input_t *i = vam->input;
7830   vl_api_bd_ip_mac_add_del_t *mp;
7831   u32 bd_id;
7832   u8 is_ipv6 = 0;
7833   u8 is_add = 1;
7834   u8 bd_id_set = 0;
7835   u8 ip_set = 0;
7836   u8 mac_set = 0;
7837   ip4_address_t v4addr;
7838   ip6_address_t v6addr;
7839   u8 macaddr[6];
7840   int ret;
7841
7842
7843   /* Parse args required to build the message */
7844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7845     {
7846       if (unformat (i, "bd_id %d", &bd_id))
7847         {
7848           bd_id_set++;
7849         }
7850       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7851         {
7852           ip_set++;
7853         }
7854       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7855         {
7856           ip_set++;
7857           is_ipv6++;
7858         }
7859       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7860         {
7861           mac_set++;
7862         }
7863       else if (unformat (i, "del"))
7864         is_add = 0;
7865       else
7866         break;
7867     }
7868
7869   if (bd_id_set == 0)
7870     {
7871       errmsg ("missing bridge domain");
7872       return -99;
7873     }
7874   else if (ip_set == 0)
7875     {
7876       errmsg ("missing IP address");
7877       return -99;
7878     }
7879   else if (mac_set == 0)
7880     {
7881       errmsg ("missing MAC address");
7882       return -99;
7883     }
7884
7885   M (BD_IP_MAC_ADD_DEL, mp);
7886
7887   mp->bd_id = ntohl (bd_id);
7888   mp->is_ipv6 = is_ipv6;
7889   mp->is_add = is_add;
7890   if (is_ipv6)
7891     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7892   else
7893     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7894   clib_memcpy (mp->mac_address, macaddr, 6);
7895   S (mp);
7896   W (ret);
7897   return ret;
7898 }
7899
7900 static void vl_api_bd_ip_mac_details_t_handler
7901   (vl_api_bd_ip_mac_details_t * mp)
7902 {
7903   vat_main_t *vam = &vat_main;
7904   u8 *ip = 0;
7905
7906   if (!mp->is_ipv6)
7907     ip =
7908       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7909   else
7910     ip =
7911       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7912
7913   print (vam->ofp,
7914          "\n%-5d %-7s %-20U %-30s",
7915          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7916          format_ethernet_address, mp->mac_address, ip);
7917
7918   vec_free (ip);
7919 }
7920
7921 static void vl_api_bd_ip_mac_details_t_handler_json
7922   (vl_api_bd_ip_mac_details_t * mp)
7923 {
7924   vat_main_t *vam = &vat_main;
7925   vat_json_node_t *node = NULL;
7926
7927   if (VAT_JSON_ARRAY != vam->json_tree.type)
7928     {
7929       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7930       vat_json_init_array (&vam->json_tree);
7931     }
7932   node = vat_json_array_add (&vam->json_tree);
7933
7934   vat_json_init_object (node);
7935   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7936   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7937   vat_json_object_add_string_copy (node, "mac_address",
7938                                    format (0, "%U", format_ethernet_address,
7939                                            &mp->mac_address));
7940   u8 *ip = 0;
7941
7942   if (!mp->is_ipv6)
7943     ip =
7944       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7945   else
7946     ip =
7947       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7948   vat_json_object_add_string_copy (node, "ip_address", ip);
7949   vec_free (ip);
7950 }
7951
7952 static int
7953 api_bd_ip_mac_dump (vat_main_t * vam)
7954 {
7955   unformat_input_t *i = vam->input;
7956   vl_api_bd_ip_mac_dump_t *mp;
7957   vl_api_control_ping_t *mp_ping;
7958   int ret;
7959   u32 bd_id;
7960   u8 bd_id_set = 0;
7961
7962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7963     {
7964       if (unformat (i, "bd_id %d", &bd_id))
7965         {
7966           bd_id_set++;
7967         }
7968       else
7969         break;
7970     }
7971
7972   print (vam->ofp,
7973          "\n%-5s %-7s %-20s %-30s",
7974          "bd_id", "is_ipv6", "mac_address", "ip_address");
7975
7976   /* Dump Bridge Domain Ip to Mac entries */
7977   M (BD_IP_MAC_DUMP, mp);
7978
7979   if (bd_id_set)
7980     mp->bd_id = htonl (bd_id);
7981   else
7982     mp->bd_id = ~0;
7983
7984   S (mp);
7985
7986   /* Use a control ping for synchronization */
7987   MPING (CONTROL_PING, mp_ping);
7988   S (mp_ping);
7989
7990   W (ret);
7991   return ret;
7992 }
7993
7994 static int
7995 api_tap_connect (vat_main_t * vam)
7996 {
7997   unformat_input_t *i = vam->input;
7998   vl_api_tap_connect_t *mp;
7999   u8 mac_address[6];
8000   u8 random_mac = 1;
8001   u8 name_set = 0;
8002   u8 *tap_name;
8003   u8 *tag = 0;
8004   ip4_address_t ip4_address;
8005   u32 ip4_mask_width;
8006   int ip4_address_set = 0;
8007   ip6_address_t ip6_address;
8008   u32 ip6_mask_width;
8009   int ip6_address_set = 0;
8010   int ret;
8011
8012   clib_memset (mac_address, 0, sizeof (mac_address));
8013
8014   /* Parse args required to build the message */
8015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8016     {
8017       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8018         {
8019           random_mac = 0;
8020         }
8021       else if (unformat (i, "random-mac"))
8022         random_mac = 1;
8023       else if (unformat (i, "tapname %s", &tap_name))
8024         name_set = 1;
8025       else if (unformat (i, "tag %s", &tag))
8026         ;
8027       else if (unformat (i, "address %U/%d",
8028                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
8029         ip4_address_set = 1;
8030       else if (unformat (i, "address %U/%d",
8031                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
8032         ip6_address_set = 1;
8033       else
8034         break;
8035     }
8036
8037   if (name_set == 0)
8038     {
8039       errmsg ("missing tap name");
8040       return -99;
8041     }
8042   if (vec_len (tap_name) > 63)
8043     {
8044       errmsg ("tap name too long");
8045       return -99;
8046     }
8047   vec_add1 (tap_name, 0);
8048
8049   if (vec_len (tag) > 63)
8050     {
8051       errmsg ("tag too long");
8052       return -99;
8053     }
8054
8055   /* Construct the API message */
8056   M (TAP_CONNECT, mp);
8057
8058   mp->use_random_mac = random_mac;
8059   clib_memcpy (mp->mac_address, mac_address, 6);
8060   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8061   if (tag)
8062     clib_memcpy (mp->tag, tag, vec_len (tag));
8063
8064   if (ip4_address_set)
8065     {
8066       mp->ip4_address_set = 1;
8067       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
8068       mp->ip4_mask_width = ip4_mask_width;
8069     }
8070   if (ip6_address_set)
8071     {
8072       mp->ip6_address_set = 1;
8073       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
8074       mp->ip6_mask_width = ip6_mask_width;
8075     }
8076
8077   vec_free (tap_name);
8078   vec_free (tag);
8079
8080   /* send it... */
8081   S (mp);
8082
8083   /* Wait for a reply... */
8084   W (ret);
8085   return ret;
8086 }
8087
8088 static int
8089 api_tap_modify (vat_main_t * vam)
8090 {
8091   unformat_input_t *i = vam->input;
8092   vl_api_tap_modify_t *mp;
8093   u8 mac_address[6];
8094   u8 random_mac = 1;
8095   u8 name_set = 0;
8096   u8 *tap_name;
8097   u32 sw_if_index = ~0;
8098   u8 sw_if_index_set = 0;
8099   int ret;
8100
8101   clib_memset (mac_address, 0, sizeof (mac_address));
8102
8103   /* Parse args required to build the message */
8104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8105     {
8106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8107         sw_if_index_set = 1;
8108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8109         sw_if_index_set = 1;
8110       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8111         {
8112           random_mac = 0;
8113         }
8114       else if (unformat (i, "random-mac"))
8115         random_mac = 1;
8116       else if (unformat (i, "tapname %s", &tap_name))
8117         name_set = 1;
8118       else
8119         break;
8120     }
8121
8122   if (sw_if_index_set == 0)
8123     {
8124       errmsg ("missing vpp interface name");
8125       return -99;
8126     }
8127   if (name_set == 0)
8128     {
8129       errmsg ("missing tap name");
8130       return -99;
8131     }
8132   if (vec_len (tap_name) > 63)
8133     {
8134       errmsg ("tap name too long");
8135     }
8136   vec_add1 (tap_name, 0);
8137
8138   /* Construct the API message */
8139   M (TAP_MODIFY, mp);
8140
8141   mp->use_random_mac = random_mac;
8142   mp->sw_if_index = ntohl (sw_if_index);
8143   clib_memcpy (mp->mac_address, mac_address, 6);
8144   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8145   vec_free (tap_name);
8146
8147   /* send it... */
8148   S (mp);
8149
8150   /* Wait for a reply... */
8151   W (ret);
8152   return ret;
8153 }
8154
8155 static int
8156 api_tap_delete (vat_main_t * vam)
8157 {
8158   unformat_input_t *i = vam->input;
8159   vl_api_tap_delete_t *mp;
8160   u32 sw_if_index = ~0;
8161   u8 sw_if_index_set = 0;
8162   int ret;
8163
8164   /* Parse args required to build the message */
8165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8166     {
8167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8168         sw_if_index_set = 1;
8169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8170         sw_if_index_set = 1;
8171       else
8172         break;
8173     }
8174
8175   if (sw_if_index_set == 0)
8176     {
8177       errmsg ("missing vpp interface name");
8178       return -99;
8179     }
8180
8181   /* Construct the API message */
8182   M (TAP_DELETE, mp);
8183
8184   mp->sw_if_index = ntohl (sw_if_index);
8185
8186   /* send it... */
8187   S (mp);
8188
8189   /* Wait for a reply... */
8190   W (ret);
8191   return ret;
8192 }
8193
8194 static int
8195 api_tap_create_v2 (vat_main_t * vam)
8196 {
8197   unformat_input_t *i = vam->input;
8198   vl_api_tap_create_v2_t *mp;
8199   u8 mac_address[6];
8200   u8 random_mac = 1;
8201   u32 id = ~0;
8202   u8 *host_if_name = 0;
8203   u8 *host_ns = 0;
8204   u8 host_mac_addr[6];
8205   u8 host_mac_addr_set = 0;
8206   u8 *host_bridge = 0;
8207   ip4_address_t host_ip4_addr;
8208   ip4_address_t host_ip4_gw;
8209   u8 host_ip4_gw_set = 0;
8210   u32 host_ip4_prefix_len = 0;
8211   ip6_address_t host_ip6_addr;
8212   ip6_address_t host_ip6_gw;
8213   u8 host_ip6_gw_set = 0;
8214   u32 host_ip6_prefix_len = 0;
8215   int ret;
8216   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8217
8218   clib_memset (mac_address, 0, sizeof (mac_address));
8219
8220   /* Parse args required to build the message */
8221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8222     {
8223       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8224         {
8225           random_mac = 0;
8226         }
8227       else if (unformat (i, "id %u", &id))
8228         ;
8229       else if (unformat (i, "host-if-name %s", &host_if_name))
8230         ;
8231       else if (unformat (i, "host-ns %s", &host_ns))
8232         ;
8233       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8234                          host_mac_addr))
8235         host_mac_addr_set = 1;
8236       else if (unformat (i, "host-bridge %s", &host_bridge))
8237         ;
8238       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8239                          &host_ip4_addr, &host_ip4_prefix_len))
8240         ;
8241       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8242                          &host_ip6_addr, &host_ip6_prefix_len))
8243         ;
8244       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8245                          &host_ip4_gw))
8246         host_ip4_gw_set = 1;
8247       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8248                          &host_ip6_gw))
8249         host_ip6_gw_set = 1;
8250       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8251         ;
8252       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8253         ;
8254       else
8255         break;
8256     }
8257
8258   if (vec_len (host_if_name) > 63)
8259     {
8260       errmsg ("tap name too long. ");
8261       return -99;
8262     }
8263   if (vec_len (host_ns) > 63)
8264     {
8265       errmsg ("host name space too long. ");
8266       return -99;
8267     }
8268   if (vec_len (host_bridge) > 63)
8269     {
8270       errmsg ("host bridge name too long. ");
8271       return -99;
8272     }
8273   if (host_ip4_prefix_len > 32)
8274     {
8275       errmsg ("host ip4 prefix length not valid. ");
8276       return -99;
8277     }
8278   if (host_ip6_prefix_len > 128)
8279     {
8280       errmsg ("host ip6 prefix length not valid. ");
8281       return -99;
8282     }
8283   if (!is_pow2 (rx_ring_sz))
8284     {
8285       errmsg ("rx ring size must be power of 2. ");
8286       return -99;
8287     }
8288   if (rx_ring_sz > 32768)
8289     {
8290       errmsg ("rx ring size must be 32768 or lower. ");
8291       return -99;
8292     }
8293   if (!is_pow2 (tx_ring_sz))
8294     {
8295       errmsg ("tx ring size must be power of 2. ");
8296       return -99;
8297     }
8298   if (tx_ring_sz > 32768)
8299     {
8300       errmsg ("tx ring size must be 32768 or lower. ");
8301       return -99;
8302     }
8303
8304   /* Construct the API message */
8305   M (TAP_CREATE_V2, mp);
8306
8307   mp->use_random_mac = random_mac;
8308
8309   mp->id = ntohl (id);
8310   mp->host_namespace_set = host_ns != 0;
8311   mp->host_bridge_set = host_bridge != 0;
8312   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8313   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8314   mp->rx_ring_sz = ntohs (rx_ring_sz);
8315   mp->tx_ring_sz = ntohs (tx_ring_sz);
8316
8317   if (random_mac == 0)
8318     clib_memcpy (mp->mac_address, mac_address, 6);
8319   if (host_mac_addr_set)
8320     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8321   if (host_if_name)
8322     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8323   if (host_ns)
8324     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8325   if (host_bridge)
8326     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8327   if (host_ip4_prefix_len)
8328     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8329   if (host_ip6_prefix_len)
8330     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8331   if (host_ip4_gw_set)
8332     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8333   if (host_ip6_gw_set)
8334     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8335
8336   vec_free (host_ns);
8337   vec_free (host_if_name);
8338   vec_free (host_bridge);
8339
8340   /* send it... */
8341   S (mp);
8342
8343   /* Wait for a reply... */
8344   W (ret);
8345   return ret;
8346 }
8347
8348 static int
8349 api_tap_delete_v2 (vat_main_t * vam)
8350 {
8351   unformat_input_t *i = vam->input;
8352   vl_api_tap_delete_v2_t *mp;
8353   u32 sw_if_index = ~0;
8354   u8 sw_if_index_set = 0;
8355   int ret;
8356
8357   /* Parse args required to build the message */
8358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8359     {
8360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8361         sw_if_index_set = 1;
8362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8363         sw_if_index_set = 1;
8364       else
8365         break;
8366     }
8367
8368   if (sw_if_index_set == 0)
8369     {
8370       errmsg ("missing vpp interface name. ");
8371       return -99;
8372     }
8373
8374   /* Construct the API message */
8375   M (TAP_DELETE_V2, mp);
8376
8377   mp->sw_if_index = ntohl (sw_if_index);
8378
8379   /* send it... */
8380   S (mp);
8381
8382   /* Wait for a reply... */
8383   W (ret);
8384   return ret;
8385 }
8386
8387 static int
8388 api_bond_create (vat_main_t * vam)
8389 {
8390   unformat_input_t *i = vam->input;
8391   vl_api_bond_create_t *mp;
8392   u8 mac_address[6];
8393   u8 custom_mac = 0;
8394   int ret;
8395   u8 mode;
8396   u8 lb;
8397   u8 mode_is_set = 0;
8398
8399   clib_memset (mac_address, 0, sizeof (mac_address));
8400   lb = BOND_LB_L2;
8401
8402   /* Parse args required to build the message */
8403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8404     {
8405       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8406         mode_is_set = 1;
8407       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8408                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8409         ;
8410       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8411                          mac_address))
8412         custom_mac = 1;
8413       else
8414         break;
8415     }
8416
8417   if (mode_is_set == 0)
8418     {
8419       errmsg ("Missing bond mode. ");
8420       return -99;
8421     }
8422
8423   /* Construct the API message */
8424   M (BOND_CREATE, mp);
8425
8426   mp->use_custom_mac = custom_mac;
8427
8428   mp->mode = mode;
8429   mp->lb = lb;
8430
8431   if (custom_mac)
8432     clib_memcpy (mp->mac_address, mac_address, 6);
8433
8434   /* send it... */
8435   S (mp);
8436
8437   /* Wait for a reply... */
8438   W (ret);
8439   return ret;
8440 }
8441
8442 static int
8443 api_bond_delete (vat_main_t * vam)
8444 {
8445   unformat_input_t *i = vam->input;
8446   vl_api_bond_delete_t *mp;
8447   u32 sw_if_index = ~0;
8448   u8 sw_if_index_set = 0;
8449   int ret;
8450
8451   /* Parse args required to build the message */
8452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8453     {
8454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8455         sw_if_index_set = 1;
8456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8457         sw_if_index_set = 1;
8458       else
8459         break;
8460     }
8461
8462   if (sw_if_index_set == 0)
8463     {
8464       errmsg ("missing vpp interface name. ");
8465       return -99;
8466     }
8467
8468   /* Construct the API message */
8469   M (BOND_DELETE, mp);
8470
8471   mp->sw_if_index = ntohl (sw_if_index);
8472
8473   /* send it... */
8474   S (mp);
8475
8476   /* Wait for a reply... */
8477   W (ret);
8478   return ret;
8479 }
8480
8481 static int
8482 api_bond_enslave (vat_main_t * vam)
8483 {
8484   unformat_input_t *i = vam->input;
8485   vl_api_bond_enslave_t *mp;
8486   u32 bond_sw_if_index;
8487   int ret;
8488   u8 is_passive;
8489   u8 is_long_timeout;
8490   u32 bond_sw_if_index_is_set = 0;
8491   u32 sw_if_index;
8492   u8 sw_if_index_is_set = 0;
8493
8494   /* Parse args required to build the message */
8495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8496     {
8497       if (unformat (i, "sw_if_index %d", &sw_if_index))
8498         sw_if_index_is_set = 1;
8499       else if (unformat (i, "bond %u", &bond_sw_if_index))
8500         bond_sw_if_index_is_set = 1;
8501       else if (unformat (i, "passive %d", &is_passive))
8502         ;
8503       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8504         ;
8505       else
8506         break;
8507     }
8508
8509   if (bond_sw_if_index_is_set == 0)
8510     {
8511       errmsg ("Missing bond sw_if_index. ");
8512       return -99;
8513     }
8514   if (sw_if_index_is_set == 0)
8515     {
8516       errmsg ("Missing slave sw_if_index. ");
8517       return -99;
8518     }
8519
8520   /* Construct the API message */
8521   M (BOND_ENSLAVE, mp);
8522
8523   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8524   mp->sw_if_index = ntohl (sw_if_index);
8525   mp->is_long_timeout = is_long_timeout;
8526   mp->is_passive = is_passive;
8527
8528   /* send it... */
8529   S (mp);
8530
8531   /* Wait for a reply... */
8532   W (ret);
8533   return ret;
8534 }
8535
8536 static int
8537 api_bond_detach_slave (vat_main_t * vam)
8538 {
8539   unformat_input_t *i = vam->input;
8540   vl_api_bond_detach_slave_t *mp;
8541   u32 sw_if_index = ~0;
8542   u8 sw_if_index_set = 0;
8543   int ret;
8544
8545   /* Parse args required to build the message */
8546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8547     {
8548       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8549         sw_if_index_set = 1;
8550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8551         sw_if_index_set = 1;
8552       else
8553         break;
8554     }
8555
8556   if (sw_if_index_set == 0)
8557     {
8558       errmsg ("missing vpp interface name. ");
8559       return -99;
8560     }
8561
8562   /* Construct the API message */
8563   M (BOND_DETACH_SLAVE, mp);
8564
8565   mp->sw_if_index = ntohl (sw_if_index);
8566
8567   /* send it... */
8568   S (mp);
8569
8570   /* Wait for a reply... */
8571   W (ret);
8572   return ret;
8573 }
8574
8575 static int
8576 api_ip_table_add_del (vat_main_t * vam)
8577 {
8578   unformat_input_t *i = vam->input;
8579   vl_api_ip_table_add_del_t *mp;
8580   u32 table_id = ~0;
8581   u8 is_ipv6 = 0;
8582   u8 is_add = 1;
8583   int ret = 0;
8584
8585   /* Parse args required to build the message */
8586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8587     {
8588       if (unformat (i, "ipv6"))
8589         is_ipv6 = 1;
8590       else if (unformat (i, "del"))
8591         is_add = 0;
8592       else if (unformat (i, "add"))
8593         is_add = 1;
8594       else if (unformat (i, "table %d", &table_id))
8595         ;
8596       else
8597         {
8598           clib_warning ("parse error '%U'", format_unformat_error, i);
8599           return -99;
8600         }
8601     }
8602
8603   if (~0 == table_id)
8604     {
8605       errmsg ("missing table-ID");
8606       return -99;
8607     }
8608
8609   /* Construct the API message */
8610   M (IP_TABLE_ADD_DEL, mp);
8611
8612   mp->table_id = ntohl (table_id);
8613   mp->is_ipv6 = is_ipv6;
8614   mp->is_add = is_add;
8615
8616   /* send it... */
8617   S (mp);
8618
8619   /* Wait for a reply... */
8620   W (ret);
8621
8622   return ret;
8623 }
8624
8625 static int
8626 api_ip_add_del_route (vat_main_t * vam)
8627 {
8628   unformat_input_t *i = vam->input;
8629   vl_api_ip_add_del_route_t *mp;
8630   u32 sw_if_index = ~0, vrf_id = 0;
8631   u8 is_ipv6 = 0;
8632   u8 is_local = 0, is_drop = 0;
8633   u8 is_unreach = 0, is_prohibit = 0;
8634   u8 is_add = 1;
8635   u32 next_hop_weight = 1;
8636   u8 is_multipath = 0;
8637   u8 address_set = 0;
8638   u8 address_length_set = 0;
8639   u32 next_hop_table_id = 0;
8640   u32 resolve_attempts = 0;
8641   u32 dst_address_length = 0;
8642   u8 next_hop_set = 0;
8643   ip4_address_t v4_dst_address, v4_next_hop_address;
8644   ip6_address_t v6_dst_address, v6_next_hop_address;
8645   int count = 1;
8646   int j;
8647   f64 before = 0;
8648   u32 random_add_del = 0;
8649   u32 *random_vector = 0;
8650   uword *random_hash;
8651   u32 random_seed = 0xdeaddabe;
8652   u32 classify_table_index = ~0;
8653   u8 is_classify = 0;
8654   u8 resolve_host = 0, resolve_attached = 0;
8655   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8656   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8657   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8658
8659   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8660   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8661   /* Parse args required to build the message */
8662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8663     {
8664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8665         ;
8666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8667         ;
8668       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8669         {
8670           address_set = 1;
8671           is_ipv6 = 0;
8672         }
8673       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8674         {
8675           address_set = 1;
8676           is_ipv6 = 1;
8677         }
8678       else if (unformat (i, "/%d", &dst_address_length))
8679         {
8680           address_length_set = 1;
8681         }
8682
8683       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8684                                          &v4_next_hop_address))
8685         {
8686           next_hop_set = 1;
8687         }
8688       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8689                                          &v6_next_hop_address))
8690         {
8691           next_hop_set = 1;
8692         }
8693       else
8694         if (unformat
8695             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8696         {
8697           next_hop_set = 1;
8698         }
8699       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8700         {
8701           next_hop_set = 1;
8702         }
8703       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8704         ;
8705       else if (unformat (i, "weight %d", &next_hop_weight))
8706         ;
8707       else if (unformat (i, "drop"))
8708         {
8709           is_drop = 1;
8710         }
8711       else if (unformat (i, "null-send-unreach"))
8712         {
8713           is_unreach = 1;
8714         }
8715       else if (unformat (i, "null-send-prohibit"))
8716         {
8717           is_prohibit = 1;
8718         }
8719       else if (unformat (i, "local"))
8720         {
8721           is_local = 1;
8722         }
8723       else if (unformat (i, "classify %d", &classify_table_index))
8724         {
8725           is_classify = 1;
8726         }
8727       else if (unformat (i, "del"))
8728         is_add = 0;
8729       else if (unformat (i, "add"))
8730         is_add = 1;
8731       else if (unformat (i, "resolve-via-host"))
8732         resolve_host = 1;
8733       else if (unformat (i, "resolve-via-attached"))
8734         resolve_attached = 1;
8735       else if (unformat (i, "multipath"))
8736         is_multipath = 1;
8737       else if (unformat (i, "vrf %d", &vrf_id))
8738         ;
8739       else if (unformat (i, "count %d", &count))
8740         ;
8741       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8742         ;
8743       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8744         ;
8745       else if (unformat (i, "out-label %d", &next_hop_out_label))
8746         {
8747           vl_api_fib_mpls_label_t fib_label = {
8748             .label = ntohl (next_hop_out_label),
8749             .ttl = 64,
8750             .exp = 0,
8751           };
8752           vec_add1 (next_hop_out_label_stack, fib_label);
8753         }
8754       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8755         ;
8756       else if (unformat (i, "random"))
8757         random_add_del = 1;
8758       else if (unformat (i, "seed %d", &random_seed))
8759         ;
8760       else
8761         {
8762           clib_warning ("parse error '%U'", format_unformat_error, i);
8763           return -99;
8764         }
8765     }
8766
8767   if (!next_hop_set && !is_drop && !is_local &&
8768       !is_classify && !is_unreach && !is_prohibit &&
8769       MPLS_LABEL_INVALID == next_hop_via_label)
8770     {
8771       errmsg
8772         ("next hop / local / drop / unreach / prohibit / classify not set");
8773       return -99;
8774     }
8775
8776   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8777     {
8778       errmsg ("next hop and next-hop via label set");
8779       return -99;
8780     }
8781   if (address_set == 0)
8782     {
8783       errmsg ("missing addresses");
8784       return -99;
8785     }
8786
8787   if (address_length_set == 0)
8788     {
8789       errmsg ("missing address length");
8790       return -99;
8791     }
8792
8793   /* Generate a pile of unique, random routes */
8794   if (random_add_del)
8795     {
8796       u32 this_random_address;
8797       random_hash = hash_create (count, sizeof (uword));
8798
8799       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8800       for (j = 0; j <= count; j++)
8801         {
8802           do
8803             {
8804               this_random_address = random_u32 (&random_seed);
8805               this_random_address =
8806                 clib_host_to_net_u32 (this_random_address);
8807             }
8808           while (hash_get (random_hash, this_random_address));
8809           vec_add1 (random_vector, this_random_address);
8810           hash_set (random_hash, this_random_address, 1);
8811         }
8812       hash_free (random_hash);
8813       v4_dst_address.as_u32 = random_vector[0];
8814     }
8815
8816   if (count > 1)
8817     {
8818       /* Turn on async mode */
8819       vam->async_mode = 1;
8820       vam->async_errors = 0;
8821       before = vat_time_now (vam);
8822     }
8823
8824   for (j = 0; j < count; j++)
8825     {
8826       /* Construct the API message */
8827       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8828           vec_len (next_hop_out_label_stack));
8829
8830       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8831       mp->table_id = ntohl (vrf_id);
8832
8833       mp->is_add = is_add;
8834       mp->is_drop = is_drop;
8835       mp->is_unreach = is_unreach;
8836       mp->is_prohibit = is_prohibit;
8837       mp->is_ipv6 = is_ipv6;
8838       mp->is_local = is_local;
8839       mp->is_classify = is_classify;
8840       mp->is_multipath = is_multipath;
8841       mp->is_resolve_host = resolve_host;
8842       mp->is_resolve_attached = resolve_attached;
8843       mp->next_hop_weight = next_hop_weight;
8844       mp->next_hop_preference = 0;
8845       mp->dst_address_length = dst_address_length;
8846       mp->next_hop_table_id = ntohl (next_hop_table_id);
8847       mp->classify_table_index = ntohl (classify_table_index);
8848       mp->next_hop_via_label = ntohl (next_hop_via_label);
8849       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8850       if (0 != mp->next_hop_n_out_labels)
8851         {
8852           memcpy (mp->next_hop_out_label_stack,
8853                   next_hop_out_label_stack,
8854                   (vec_len (next_hop_out_label_stack) *
8855                    sizeof (vl_api_fib_mpls_label_t)));
8856           vec_free (next_hop_out_label_stack);
8857         }
8858
8859       if (is_ipv6)
8860         {
8861           clib_memcpy (mp->dst_address, &v6_dst_address,
8862                        sizeof (v6_dst_address));
8863           if (next_hop_set)
8864             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8865                          sizeof (v6_next_hop_address));
8866           increment_v6_address (&v6_dst_address);
8867         }
8868       else
8869         {
8870           clib_memcpy (mp->dst_address, &v4_dst_address,
8871                        sizeof (v4_dst_address));
8872           if (next_hop_set)
8873             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8874                          sizeof (v4_next_hop_address));
8875           if (random_add_del)
8876             v4_dst_address.as_u32 = random_vector[j + 1];
8877           else
8878             increment_v4_address (&v4_dst_address);
8879         }
8880       /* send it... */
8881       S (mp);
8882       /* If we receive SIGTERM, stop now... */
8883       if (vam->do_exit)
8884         break;
8885     }
8886
8887   /* When testing multiple add/del ops, use a control-ping to sync */
8888   if (count > 1)
8889     {
8890       vl_api_control_ping_t *mp_ping;
8891       f64 after;
8892       f64 timeout;
8893
8894       /* Shut off async mode */
8895       vam->async_mode = 0;
8896
8897       MPING (CONTROL_PING, mp_ping);
8898       S (mp_ping);
8899
8900       timeout = vat_time_now (vam) + 1.0;
8901       while (vat_time_now (vam) < timeout)
8902         if (vam->result_ready == 1)
8903           goto out;
8904       vam->retval = -99;
8905
8906     out:
8907       if (vam->retval == -99)
8908         errmsg ("timeout");
8909
8910       if (vam->async_errors > 0)
8911         {
8912           errmsg ("%d asynchronous errors", vam->async_errors);
8913           vam->retval = -98;
8914         }
8915       vam->async_errors = 0;
8916       after = vat_time_now (vam);
8917
8918       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8919       if (j > 0)
8920         count = j;
8921
8922       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8923              count, after - before, count / (after - before));
8924     }
8925   else
8926     {
8927       int ret;
8928
8929       /* Wait for a reply... */
8930       W (ret);
8931       return ret;
8932     }
8933
8934   /* Return the good/bad news */
8935   return (vam->retval);
8936 }
8937
8938 static int
8939 api_ip_mroute_add_del (vat_main_t * vam)
8940 {
8941   unformat_input_t *i = vam->input;
8942   vl_api_ip_mroute_add_del_t *mp;
8943   u32 sw_if_index = ~0, vrf_id = 0;
8944   u8 is_ipv6 = 0;
8945   u8 is_local = 0;
8946   u8 is_add = 1;
8947   u8 address_set = 0;
8948   u32 grp_address_length = 0;
8949   ip4_address_t v4_grp_address, v4_src_address;
8950   ip6_address_t v6_grp_address, v6_src_address;
8951   mfib_itf_flags_t iflags = 0;
8952   mfib_entry_flags_t eflags = 0;
8953   int ret;
8954
8955   /* Parse args required to build the message */
8956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8957     {
8958       if (unformat (i, "sw_if_index %d", &sw_if_index))
8959         ;
8960       else if (unformat (i, "%U %U",
8961                          unformat_ip4_address, &v4_src_address,
8962                          unformat_ip4_address, &v4_grp_address))
8963         {
8964           grp_address_length = 64;
8965           address_set = 1;
8966           is_ipv6 = 0;
8967         }
8968       else if (unformat (i, "%U %U",
8969                          unformat_ip6_address, &v6_src_address,
8970                          unformat_ip6_address, &v6_grp_address))
8971         {
8972           grp_address_length = 256;
8973           address_set = 1;
8974           is_ipv6 = 1;
8975         }
8976       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8977         {
8978           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8979           grp_address_length = 32;
8980           address_set = 1;
8981           is_ipv6 = 0;
8982         }
8983       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8984         {
8985           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8986           grp_address_length = 128;
8987           address_set = 1;
8988           is_ipv6 = 1;
8989         }
8990       else if (unformat (i, "/%d", &grp_address_length))
8991         ;
8992       else if (unformat (i, "local"))
8993         {
8994           is_local = 1;
8995         }
8996       else if (unformat (i, "del"))
8997         is_add = 0;
8998       else if (unformat (i, "add"))
8999         is_add = 1;
9000       else if (unformat (i, "vrf %d", &vrf_id))
9001         ;
9002       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
9003         ;
9004       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
9005         ;
9006       else
9007         {
9008           clib_warning ("parse error '%U'", format_unformat_error, i);
9009           return -99;
9010         }
9011     }
9012
9013   if (address_set == 0)
9014     {
9015       errmsg ("missing addresses\n");
9016       return -99;
9017     }
9018
9019   /* Construct the API message */
9020   M (IP_MROUTE_ADD_DEL, mp);
9021
9022   mp->next_hop_sw_if_index = ntohl (sw_if_index);
9023   mp->table_id = ntohl (vrf_id);
9024
9025   mp->is_add = is_add;
9026   mp->is_ipv6 = is_ipv6;
9027   mp->is_local = is_local;
9028   mp->itf_flags = ntohl (iflags);
9029   mp->entry_flags = ntohl (eflags);
9030   mp->grp_address_length = grp_address_length;
9031   mp->grp_address_length = ntohs (mp->grp_address_length);
9032
9033   if (is_ipv6)
9034     {
9035       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
9036       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
9037     }
9038   else
9039     {
9040       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
9041       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
9042
9043     }
9044
9045   /* send it... */
9046   S (mp);
9047   /* Wait for a reply... */
9048   W (ret);
9049   return ret;
9050 }
9051
9052 static int
9053 api_mpls_table_add_del (vat_main_t * vam)
9054 {
9055   unformat_input_t *i = vam->input;
9056   vl_api_mpls_table_add_del_t *mp;
9057   u32 table_id = ~0;
9058   u8 is_add = 1;
9059   int ret = 0;
9060
9061   /* Parse args required to build the message */
9062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9063     {
9064       if (unformat (i, "table %d", &table_id))
9065         ;
9066       else if (unformat (i, "del"))
9067         is_add = 0;
9068       else if (unformat (i, "add"))
9069         is_add = 1;
9070       else
9071         {
9072           clib_warning ("parse error '%U'", format_unformat_error, i);
9073           return -99;
9074         }
9075     }
9076
9077   if (~0 == table_id)
9078     {
9079       errmsg ("missing table-ID");
9080       return -99;
9081     }
9082
9083   /* Construct the API message */
9084   M (MPLS_TABLE_ADD_DEL, mp);
9085
9086   mp->mt_table_id = ntohl (table_id);
9087   mp->mt_is_add = is_add;
9088
9089   /* send it... */
9090   S (mp);
9091
9092   /* Wait for a reply... */
9093   W (ret);
9094
9095   return ret;
9096 }
9097
9098 static int
9099 api_mpls_route_add_del (vat_main_t * vam)
9100 {
9101   unformat_input_t *i = vam->input;
9102   vl_api_mpls_route_add_del_t *mp;
9103   u32 sw_if_index = ~0, table_id = 0;
9104   u8 is_add = 1;
9105   u32 next_hop_weight = 1;
9106   u8 is_multipath = 0;
9107   u32 next_hop_table_id = 0;
9108   u8 next_hop_set = 0;
9109   ip4_address_t v4_next_hop_address = {
9110     .as_u32 = 0,
9111   };
9112   ip6_address_t v6_next_hop_address = { {0} };
9113   int count = 1;
9114   int j;
9115   f64 before = 0;
9116   u32 classify_table_index = ~0;
9117   u8 is_classify = 0;
9118   u8 resolve_host = 0, resolve_attached = 0;
9119   u8 is_interface_rx = 0;
9120   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9121   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9122   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9123   mpls_label_t local_label = MPLS_LABEL_INVALID;
9124   u8 is_eos = 0;
9125   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9126
9127   /* Parse args required to build the message */
9128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9129     {
9130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9131         ;
9132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9133         ;
9134       else if (unformat (i, "%d", &local_label))
9135         ;
9136       else if (unformat (i, "eos"))
9137         is_eos = 1;
9138       else if (unformat (i, "non-eos"))
9139         is_eos = 0;
9140       else if (unformat (i, "via %U", unformat_ip4_address,
9141                          &v4_next_hop_address))
9142         {
9143           next_hop_set = 1;
9144           next_hop_proto = DPO_PROTO_IP4;
9145         }
9146       else if (unformat (i, "via %U", unformat_ip6_address,
9147                          &v6_next_hop_address))
9148         {
9149           next_hop_set = 1;
9150           next_hop_proto = DPO_PROTO_IP6;
9151         }
9152       else if (unformat (i, "weight %d", &next_hop_weight))
9153         ;
9154       else if (unformat (i, "classify %d", &classify_table_index))
9155         {
9156           is_classify = 1;
9157         }
9158       else if (unformat (i, "del"))
9159         is_add = 0;
9160       else if (unformat (i, "add"))
9161         is_add = 1;
9162       else if (unformat (i, "resolve-via-host"))
9163         resolve_host = 1;
9164       else if (unformat (i, "resolve-via-attached"))
9165         resolve_attached = 1;
9166       else if (unformat (i, "multipath"))
9167         is_multipath = 1;
9168       else if (unformat (i, "count %d", &count))
9169         ;
9170       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9171         {
9172           next_hop_set = 1;
9173           next_hop_proto = DPO_PROTO_IP4;
9174         }
9175       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9176         {
9177           next_hop_set = 1;
9178           next_hop_proto = DPO_PROTO_IP6;
9179         }
9180       else
9181         if (unformat
9182             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9183              &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 l2-input-on sw_if_index %d", &sw_if_index))
9190         {
9191           next_hop_set = 1;
9192           next_hop_proto = DPO_PROTO_ETHERNET;
9193           is_interface_rx = 1;
9194         }
9195       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9196         next_hop_set = 1;
9197       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9198         next_hop_set = 1;
9199       else if (unformat (i, "out-label %d", &next_hop_out_label))
9200         {
9201           vl_api_fib_mpls_label_t fib_label = {
9202             .label = ntohl (next_hop_out_label),
9203             .ttl = 64,
9204             .exp = 0,
9205           };
9206           vec_add1 (next_hop_out_label_stack, fib_label);
9207         }
9208       else
9209         {
9210           clib_warning ("parse error '%U'", format_unformat_error, i);
9211           return -99;
9212         }
9213     }
9214
9215   if (!next_hop_set && !is_classify)
9216     {
9217       errmsg ("next hop / classify not set");
9218       return -99;
9219     }
9220
9221   if (MPLS_LABEL_INVALID == local_label)
9222     {
9223       errmsg ("missing label");
9224       return -99;
9225     }
9226
9227   if (count > 1)
9228     {
9229       /* Turn on async mode */
9230       vam->async_mode = 1;
9231       vam->async_errors = 0;
9232       before = vat_time_now (vam);
9233     }
9234
9235   for (j = 0; j < count; j++)
9236     {
9237       /* Construct the API message */
9238       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9239           vec_len (next_hop_out_label_stack));
9240
9241       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9242       mp->mr_table_id = ntohl (table_id);
9243
9244       mp->mr_is_add = is_add;
9245       mp->mr_next_hop_proto = next_hop_proto;
9246       mp->mr_is_classify = is_classify;
9247       mp->mr_is_multipath = is_multipath;
9248       mp->mr_is_resolve_host = resolve_host;
9249       mp->mr_is_resolve_attached = resolve_attached;
9250       mp->mr_is_interface_rx = is_interface_rx;
9251       mp->mr_next_hop_weight = next_hop_weight;
9252       mp->mr_next_hop_preference = 0;
9253       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9254       mp->mr_classify_table_index = ntohl (classify_table_index);
9255       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9256       mp->mr_label = ntohl (local_label);
9257       mp->mr_eos = is_eos;
9258
9259       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9260       if (0 != mp->mr_next_hop_n_out_labels)
9261         {
9262           memcpy (mp->mr_next_hop_out_label_stack,
9263                   next_hop_out_label_stack,
9264                   vec_len (next_hop_out_label_stack) *
9265                   sizeof (vl_api_fib_mpls_label_t));
9266           vec_free (next_hop_out_label_stack);
9267         }
9268
9269       if (next_hop_set)
9270         {
9271           if (DPO_PROTO_IP4 == next_hop_proto)
9272             {
9273               clib_memcpy (mp->mr_next_hop,
9274                            &v4_next_hop_address,
9275                            sizeof (v4_next_hop_address));
9276             }
9277           else if (DPO_PROTO_IP6 == next_hop_proto)
9278
9279             {
9280               clib_memcpy (mp->mr_next_hop,
9281                            &v6_next_hop_address,
9282                            sizeof (v6_next_hop_address));
9283             }
9284         }
9285       local_label++;
9286
9287       /* send it... */
9288       S (mp);
9289       /* If we receive SIGTERM, stop now... */
9290       if (vam->do_exit)
9291         break;
9292     }
9293
9294   /* When testing multiple add/del ops, use a control-ping to sync */
9295   if (count > 1)
9296     {
9297       vl_api_control_ping_t *mp_ping;
9298       f64 after;
9299       f64 timeout;
9300
9301       /* Shut off async mode */
9302       vam->async_mode = 0;
9303
9304       MPING (CONTROL_PING, mp_ping);
9305       S (mp_ping);
9306
9307       timeout = vat_time_now (vam) + 1.0;
9308       while (vat_time_now (vam) < timeout)
9309         if (vam->result_ready == 1)
9310           goto out;
9311       vam->retval = -99;
9312
9313     out:
9314       if (vam->retval == -99)
9315         errmsg ("timeout");
9316
9317       if (vam->async_errors > 0)
9318         {
9319           errmsg ("%d asynchronous errors", vam->async_errors);
9320           vam->retval = -98;
9321         }
9322       vam->async_errors = 0;
9323       after = vat_time_now (vam);
9324
9325       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9326       if (j > 0)
9327         count = j;
9328
9329       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9330              count, after - before, count / (after - before));
9331     }
9332   else
9333     {
9334       int ret;
9335
9336       /* Wait for a reply... */
9337       W (ret);
9338       return ret;
9339     }
9340
9341   /* Return the good/bad news */
9342   return (vam->retval);
9343 }
9344
9345 static int
9346 api_mpls_ip_bind_unbind (vat_main_t * vam)
9347 {
9348   unformat_input_t *i = vam->input;
9349   vl_api_mpls_ip_bind_unbind_t *mp;
9350   u32 ip_table_id = 0;
9351   u8 is_bind = 1;
9352   u8 is_ip4 = 1;
9353   ip4_address_t v4_address;
9354   ip6_address_t v6_address;
9355   u32 address_length;
9356   u8 address_set = 0;
9357   mpls_label_t local_label = MPLS_LABEL_INVALID;
9358   int ret;
9359
9360   /* Parse args required to build the message */
9361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9362     {
9363       if (unformat (i, "%U/%d", unformat_ip4_address,
9364                     &v4_address, &address_length))
9365         {
9366           is_ip4 = 1;
9367           address_set = 1;
9368         }
9369       else if (unformat (i, "%U/%d", unformat_ip6_address,
9370                          &v6_address, &address_length))
9371         {
9372           is_ip4 = 0;
9373           address_set = 1;
9374         }
9375       else if (unformat (i, "%d", &local_label))
9376         ;
9377       else if (unformat (i, "table-id %d", &ip_table_id))
9378         ;
9379       else if (unformat (i, "unbind"))
9380         is_bind = 0;
9381       else if (unformat (i, "bind"))
9382         is_bind = 1;
9383       else
9384         {
9385           clib_warning ("parse error '%U'", format_unformat_error, i);
9386           return -99;
9387         }
9388     }
9389
9390   if (!address_set)
9391     {
9392       errmsg ("IP address not set");
9393       return -99;
9394     }
9395
9396   if (MPLS_LABEL_INVALID == local_label)
9397     {
9398       errmsg ("missing label");
9399       return -99;
9400     }
9401
9402   /* Construct the API message */
9403   M (MPLS_IP_BIND_UNBIND, mp);
9404
9405   mp->mb_is_bind = is_bind;
9406   mp->mb_is_ip4 = is_ip4;
9407   mp->mb_ip_table_id = ntohl (ip_table_id);
9408   mp->mb_mpls_table_id = 0;
9409   mp->mb_label = ntohl (local_label);
9410   mp->mb_address_length = address_length;
9411
9412   if (is_ip4)
9413     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9414   else
9415     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9416
9417   /* send it... */
9418   S (mp);
9419
9420   /* Wait for a reply... */
9421   W (ret);
9422   return ret;
9423 }
9424
9425 static int
9426 api_sr_mpls_policy_add (vat_main_t * vam)
9427 {
9428   unformat_input_t *i = vam->input;
9429   vl_api_sr_mpls_policy_add_t *mp;
9430   u32 bsid = 0;
9431   u32 weight = 1;
9432   u8 type = 0;
9433   u8 n_segments = 0;
9434   u32 sid;
9435   u32 *segments = NULL;
9436   int ret;
9437
9438   /* Parse args required to build the message */
9439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (i, "bsid %d", &bsid))
9442         ;
9443       else if (unformat (i, "weight %d", &weight))
9444         ;
9445       else if (unformat (i, "spray"))
9446         type = 1;
9447       else if (unformat (i, "next %d", &sid))
9448         {
9449           n_segments += 1;
9450           vec_add1 (segments, htonl (sid));
9451         }
9452       else
9453         {
9454           clib_warning ("parse error '%U'", format_unformat_error, i);
9455           return -99;
9456         }
9457     }
9458
9459   if (bsid == 0)
9460     {
9461       errmsg ("bsid not set");
9462       return -99;
9463     }
9464
9465   if (n_segments == 0)
9466     {
9467       errmsg ("no sid in segment stack");
9468       return -99;
9469     }
9470
9471   /* Construct the API message */
9472   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9473
9474   mp->bsid = htonl (bsid);
9475   mp->weight = htonl (weight);
9476   mp->type = type;
9477   mp->n_segments = n_segments;
9478   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9479   vec_free (segments);
9480
9481   /* send it... */
9482   S (mp);
9483
9484   /* Wait for a reply... */
9485   W (ret);
9486   return ret;
9487 }
9488
9489 static int
9490 api_sr_mpls_policy_del (vat_main_t * vam)
9491 {
9492   unformat_input_t *i = vam->input;
9493   vl_api_sr_mpls_policy_del_t *mp;
9494   u32 bsid = 0;
9495   int ret;
9496
9497   /* Parse args required to build the message */
9498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9499     {
9500       if (unformat (i, "bsid %d", &bsid))
9501         ;
9502       else
9503         {
9504           clib_warning ("parse error '%U'", format_unformat_error, i);
9505           return -99;
9506         }
9507     }
9508
9509   if (bsid == 0)
9510     {
9511       errmsg ("bsid not set");
9512       return -99;
9513     }
9514
9515   /* Construct the API message */
9516   M (SR_MPLS_POLICY_DEL, mp);
9517
9518   mp->bsid = htonl (bsid);
9519
9520   /* send it... */
9521   S (mp);
9522
9523   /* Wait for a reply... */
9524   W (ret);
9525   return ret;
9526 }
9527
9528 static int
9529 api_bier_table_add_del (vat_main_t * vam)
9530 {
9531   unformat_input_t *i = vam->input;
9532   vl_api_bier_table_add_del_t *mp;
9533   u8 is_add = 1;
9534   u32 set = 0, sub_domain = 0, hdr_len = 3;
9535   mpls_label_t local_label = MPLS_LABEL_INVALID;
9536   int ret;
9537
9538   /* Parse args required to build the message */
9539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9540     {
9541       if (unformat (i, "sub-domain %d", &sub_domain))
9542         ;
9543       else if (unformat (i, "set %d", &set))
9544         ;
9545       else if (unformat (i, "label %d", &local_label))
9546         ;
9547       else if (unformat (i, "hdr-len %d", &hdr_len))
9548         ;
9549       else if (unformat (i, "add"))
9550         is_add = 1;
9551       else if (unformat (i, "del"))
9552         is_add = 0;
9553       else
9554         {
9555           clib_warning ("parse error '%U'", format_unformat_error, i);
9556           return -99;
9557         }
9558     }
9559
9560   if (MPLS_LABEL_INVALID == local_label)
9561     {
9562       errmsg ("missing label\n");
9563       return -99;
9564     }
9565
9566   /* Construct the API message */
9567   M (BIER_TABLE_ADD_DEL, mp);
9568
9569   mp->bt_is_add = is_add;
9570   mp->bt_label = ntohl (local_label);
9571   mp->bt_tbl_id.bt_set = set;
9572   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9573   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9574
9575   /* send it... */
9576   S (mp);
9577
9578   /* Wait for a reply... */
9579   W (ret);
9580
9581   return (ret);
9582 }
9583
9584 static int
9585 api_bier_route_add_del (vat_main_t * vam)
9586 {
9587   unformat_input_t *i = vam->input;
9588   vl_api_bier_route_add_del_t *mp;
9589   u8 is_add = 1;
9590   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9591   ip4_address_t v4_next_hop_address;
9592   ip6_address_t v6_next_hop_address;
9593   u8 next_hop_set = 0;
9594   u8 next_hop_proto_is_ip4 = 1;
9595   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9596   int ret;
9597
9598   /* Parse args required to build the message */
9599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9600     {
9601       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9602         {
9603           next_hop_proto_is_ip4 = 1;
9604           next_hop_set = 1;
9605         }
9606       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9607         {
9608           next_hop_proto_is_ip4 = 0;
9609           next_hop_set = 1;
9610         }
9611       if (unformat (i, "sub-domain %d", &sub_domain))
9612         ;
9613       else if (unformat (i, "set %d", &set))
9614         ;
9615       else if (unformat (i, "hdr-len %d", &hdr_len))
9616         ;
9617       else if (unformat (i, "bp %d", &bp))
9618         ;
9619       else if (unformat (i, "add"))
9620         is_add = 1;
9621       else if (unformat (i, "del"))
9622         is_add = 0;
9623       else if (unformat (i, "out-label %d", &next_hop_out_label))
9624         ;
9625       else
9626         {
9627           clib_warning ("parse error '%U'", format_unformat_error, i);
9628           return -99;
9629         }
9630     }
9631
9632   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9633     {
9634       errmsg ("next hop / label set\n");
9635       return -99;
9636     }
9637   if (0 == bp)
9638     {
9639       errmsg ("bit=position not set\n");
9640       return -99;
9641     }
9642
9643   /* Construct the API message */
9644   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9645
9646   mp->br_is_add = is_add;
9647   mp->br_tbl_id.bt_set = set;
9648   mp->br_tbl_id.bt_sub_domain = sub_domain;
9649   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9650   mp->br_bp = ntohs (bp);
9651   mp->br_n_paths = 1;
9652   mp->br_paths[0].n_labels = 1;
9653   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9654   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9655
9656   if (next_hop_proto_is_ip4)
9657     {
9658       clib_memcpy (mp->br_paths[0].next_hop,
9659                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9660     }
9661   else
9662     {
9663       clib_memcpy (mp->br_paths[0].next_hop,
9664                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9665     }
9666
9667   /* send it... */
9668   S (mp);
9669
9670   /* Wait for a reply... */
9671   W (ret);
9672
9673   return (ret);
9674 }
9675
9676 static int
9677 api_proxy_arp_add_del (vat_main_t * vam)
9678 {
9679   unformat_input_t *i = vam->input;
9680   vl_api_proxy_arp_add_del_t *mp;
9681   u32 vrf_id = 0;
9682   u8 is_add = 1;
9683   ip4_address_t lo, hi;
9684   u8 range_set = 0;
9685   int ret;
9686
9687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9688     {
9689       if (unformat (i, "vrf %d", &vrf_id))
9690         ;
9691       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9692                          unformat_ip4_address, &hi))
9693         range_set = 1;
9694       else if (unformat (i, "del"))
9695         is_add = 0;
9696       else
9697         {
9698           clib_warning ("parse error '%U'", format_unformat_error, i);
9699           return -99;
9700         }
9701     }
9702
9703   if (range_set == 0)
9704     {
9705       errmsg ("address range not set");
9706       return -99;
9707     }
9708
9709   M (PROXY_ARP_ADD_DEL, mp);
9710
9711   mp->proxy.vrf_id = ntohl (vrf_id);
9712   mp->is_add = is_add;
9713   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9714   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9715
9716   S (mp);
9717   W (ret);
9718   return ret;
9719 }
9720
9721 static int
9722 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9723 {
9724   unformat_input_t *i = vam->input;
9725   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9726   u32 sw_if_index;
9727   u8 enable = 1;
9728   u8 sw_if_index_set = 0;
9729   int ret;
9730
9731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9732     {
9733       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9734         sw_if_index_set = 1;
9735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9736         sw_if_index_set = 1;
9737       else if (unformat (i, "enable"))
9738         enable = 1;
9739       else if (unformat (i, "disable"))
9740         enable = 0;
9741       else
9742         {
9743           clib_warning ("parse error '%U'", format_unformat_error, i);
9744           return -99;
9745         }
9746     }
9747
9748   if (sw_if_index_set == 0)
9749     {
9750       errmsg ("missing interface name or sw_if_index");
9751       return -99;
9752     }
9753
9754   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9755
9756   mp->sw_if_index = ntohl (sw_if_index);
9757   mp->enable_disable = enable;
9758
9759   S (mp);
9760   W (ret);
9761   return ret;
9762 }
9763
9764 static int
9765 api_mpls_tunnel_add_del (vat_main_t * vam)
9766 {
9767   unformat_input_t *i = vam->input;
9768   vl_api_mpls_tunnel_add_del_t *mp;
9769
9770   u8 is_add = 1;
9771   u8 l2_only = 0;
9772   u32 sw_if_index = ~0;
9773   u32 next_hop_sw_if_index = ~0;
9774   u32 next_hop_proto_is_ip4 = 1;
9775
9776   u32 next_hop_table_id = 0;
9777   ip4_address_t v4_next_hop_address = {
9778     .as_u32 = 0,
9779   };
9780   ip6_address_t v6_next_hop_address = { {0} };
9781   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9782   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9783   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9784   int ret;
9785
9786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9787     {
9788       if (unformat (i, "add"))
9789         is_add = 1;
9790       else
9791         if (unformat
9792             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9793         is_add = 0;
9794       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9795         is_add = 0;
9796       else if (unformat (i, "via %U",
9797                          unformat_ip4_address, &v4_next_hop_address))
9798         {
9799           next_hop_proto_is_ip4 = 1;
9800         }
9801       else if (unformat (i, "via %U",
9802                          unformat_ip6_address, &v6_next_hop_address))
9803         {
9804           next_hop_proto_is_ip4 = 0;
9805         }
9806       else if (unformat (i, "via-label %d", &next_hop_via_label))
9807         ;
9808       else
9809         if (unformat
9810             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9811         ;
9812       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9813         ;
9814       else if (unformat (i, "l2-only"))
9815         l2_only = 1;
9816       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9817         ;
9818       else if (unformat (i, "out-label %d", &next_hop_out_label))
9819         {
9820           vl_api_fib_mpls_label_t fib_label = {
9821             .label = ntohl (next_hop_out_label),
9822             .ttl = 64,
9823             .exp = 0,
9824           };
9825           vec_add1 (next_hop_out_label_stack, fib_label);
9826         }
9827       else
9828         {
9829           clib_warning ("parse error '%U'", format_unformat_error, i);
9830           return -99;
9831         }
9832     }
9833
9834   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9835       vec_len (next_hop_out_label_stack));
9836
9837   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9838   mp->mt_sw_if_index = ntohl (sw_if_index);
9839   mp->mt_is_add = is_add;
9840   mp->mt_l2_only = l2_only;
9841   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9842   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9843   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9844   mp->mt_next_hop_weight = 1;
9845   mp->mt_next_hop_preference = 0;
9846
9847   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9848
9849   if (0 != mp->mt_next_hop_n_out_labels)
9850     {
9851       clib_memcpy (mp->mt_next_hop_out_label_stack,
9852                    next_hop_out_label_stack,
9853                    (vec_len (next_hop_out_label_stack) *
9854                     sizeof (vl_api_fib_mpls_label_t)));
9855       vec_free (next_hop_out_label_stack);
9856     }
9857
9858   if (next_hop_proto_is_ip4)
9859     {
9860       clib_memcpy (mp->mt_next_hop,
9861                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9862     }
9863   else
9864     {
9865       clib_memcpy (mp->mt_next_hop,
9866                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9867     }
9868
9869   S (mp);
9870   W (ret);
9871   return ret;
9872 }
9873
9874 static int
9875 api_sw_interface_set_unnumbered (vat_main_t * vam)
9876 {
9877   unformat_input_t *i = vam->input;
9878   vl_api_sw_interface_set_unnumbered_t *mp;
9879   u32 sw_if_index;
9880   u32 unnum_sw_index = ~0;
9881   u8 is_add = 1;
9882   u8 sw_if_index_set = 0;
9883   int ret;
9884
9885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9886     {
9887       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9888         sw_if_index_set = 1;
9889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9890         sw_if_index_set = 1;
9891       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9892         ;
9893       else if (unformat (i, "del"))
9894         is_add = 0;
9895       else
9896         {
9897           clib_warning ("parse error '%U'", format_unformat_error, i);
9898           return -99;
9899         }
9900     }
9901
9902   if (sw_if_index_set == 0)
9903     {
9904       errmsg ("missing interface name or sw_if_index");
9905       return -99;
9906     }
9907
9908   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9909
9910   mp->sw_if_index = ntohl (sw_if_index);
9911   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9912   mp->is_add = is_add;
9913
9914   S (mp);
9915   W (ret);
9916   return ret;
9917 }
9918
9919 static int
9920 api_ip_neighbor_add_del (vat_main_t * vam)
9921 {
9922   unformat_input_t *i = vam->input;
9923   vl_api_ip_neighbor_add_del_t *mp;
9924   u32 sw_if_index;
9925   u8 sw_if_index_set = 0;
9926   u8 is_add = 1;
9927   u8 is_static = 0;
9928   u8 is_no_fib_entry = 0;
9929   u8 mac_address[6];
9930   u8 mac_set = 0;
9931   u8 v4_address_set = 0;
9932   u8 v6_address_set = 0;
9933   ip4_address_t v4address;
9934   ip6_address_t v6address;
9935   int ret;
9936
9937   clib_memset (mac_address, 0, sizeof (mac_address));
9938
9939   /* Parse args required to build the message */
9940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9941     {
9942       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9943         {
9944           mac_set = 1;
9945         }
9946       else if (unformat (i, "del"))
9947         is_add = 0;
9948       else
9949         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9950         sw_if_index_set = 1;
9951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9952         sw_if_index_set = 1;
9953       else if (unformat (i, "is_static"))
9954         is_static = 1;
9955       else if (unformat (i, "no-fib-entry"))
9956         is_no_fib_entry = 1;
9957       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9958         v4_address_set = 1;
9959       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9960         v6_address_set = 1;
9961       else
9962         {
9963           clib_warning ("parse error '%U'", format_unformat_error, i);
9964           return -99;
9965         }
9966     }
9967
9968   if (sw_if_index_set == 0)
9969     {
9970       errmsg ("missing interface name or sw_if_index");
9971       return -99;
9972     }
9973   if (v4_address_set && v6_address_set)
9974     {
9975       errmsg ("both v4 and v6 addresses set");
9976       return -99;
9977     }
9978   if (!v4_address_set && !v6_address_set)
9979     {
9980       errmsg ("no address set");
9981       return -99;
9982     }
9983
9984   /* Construct the API message */
9985   M (IP_NEIGHBOR_ADD_DEL, mp);
9986
9987   mp->sw_if_index = ntohl (sw_if_index);
9988   mp->is_add = is_add;
9989   mp->is_static = is_static;
9990   mp->is_no_adj_fib = is_no_fib_entry;
9991   if (mac_set)
9992     clib_memcpy (mp->mac_address, mac_address, 6);
9993   if (v6_address_set)
9994     {
9995       mp->is_ipv6 = 1;
9996       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9997     }
9998   else
9999     {
10000       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
10001       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
10002     }
10003
10004   /* send it... */
10005   S (mp);
10006
10007   /* Wait for a reply, return good/bad news  */
10008   W (ret);
10009   return ret;
10010 }
10011
10012 static int
10013 api_create_vlan_subif (vat_main_t * vam)
10014 {
10015   unformat_input_t *i = vam->input;
10016   vl_api_create_vlan_subif_t *mp;
10017   u32 sw_if_index;
10018   u8 sw_if_index_set = 0;
10019   u32 vlan_id;
10020   u8 vlan_id_set = 0;
10021   int ret;
10022
10023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10024     {
10025       if (unformat (i, "sw_if_index %d", &sw_if_index))
10026         sw_if_index_set = 1;
10027       else
10028         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10029         sw_if_index_set = 1;
10030       else if (unformat (i, "vlan %d", &vlan_id))
10031         vlan_id_set = 1;
10032       else
10033         {
10034           clib_warning ("parse error '%U'", format_unformat_error, i);
10035           return -99;
10036         }
10037     }
10038
10039   if (sw_if_index_set == 0)
10040     {
10041       errmsg ("missing interface name or sw_if_index");
10042       return -99;
10043     }
10044
10045   if (vlan_id_set == 0)
10046     {
10047       errmsg ("missing vlan_id");
10048       return -99;
10049     }
10050   M (CREATE_VLAN_SUBIF, mp);
10051
10052   mp->sw_if_index = ntohl (sw_if_index);
10053   mp->vlan_id = ntohl (vlan_id);
10054
10055   S (mp);
10056   W (ret);
10057   return ret;
10058 }
10059
10060 #define foreach_create_subif_bit                \
10061 _(no_tags)                                      \
10062 _(one_tag)                                      \
10063 _(two_tags)                                     \
10064 _(dot1ad)                                       \
10065 _(exact_match)                                  \
10066 _(default_sub)                                  \
10067 _(outer_vlan_id_any)                            \
10068 _(inner_vlan_id_any)
10069
10070 static int
10071 api_create_subif (vat_main_t * vam)
10072 {
10073   unformat_input_t *i = vam->input;
10074   vl_api_create_subif_t *mp;
10075   u32 sw_if_index;
10076   u8 sw_if_index_set = 0;
10077   u32 sub_id;
10078   u8 sub_id_set = 0;
10079   u32 no_tags = 0;
10080   u32 one_tag = 0;
10081   u32 two_tags = 0;
10082   u32 dot1ad = 0;
10083   u32 exact_match = 0;
10084   u32 default_sub = 0;
10085   u32 outer_vlan_id_any = 0;
10086   u32 inner_vlan_id_any = 0;
10087   u32 tmp;
10088   u16 outer_vlan_id = 0;
10089   u16 inner_vlan_id = 0;
10090   int ret;
10091
10092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10093     {
10094       if (unformat (i, "sw_if_index %d", &sw_if_index))
10095         sw_if_index_set = 1;
10096       else
10097         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10098         sw_if_index_set = 1;
10099       else if (unformat (i, "sub_id %d", &sub_id))
10100         sub_id_set = 1;
10101       else if (unformat (i, "outer_vlan_id %d", &tmp))
10102         outer_vlan_id = tmp;
10103       else if (unformat (i, "inner_vlan_id %d", &tmp))
10104         inner_vlan_id = tmp;
10105
10106 #define _(a) else if (unformat (i, #a)) a = 1 ;
10107       foreach_create_subif_bit
10108 #undef _
10109         else
10110         {
10111           clib_warning ("parse error '%U'", format_unformat_error, i);
10112           return -99;
10113         }
10114     }
10115
10116   if (sw_if_index_set == 0)
10117     {
10118       errmsg ("missing interface name or sw_if_index");
10119       return -99;
10120     }
10121
10122   if (sub_id_set == 0)
10123     {
10124       errmsg ("missing sub_id");
10125       return -99;
10126     }
10127   M (CREATE_SUBIF, mp);
10128
10129   mp->sw_if_index = ntohl (sw_if_index);
10130   mp->sub_id = ntohl (sub_id);
10131
10132 #define _(a) mp->a = a;
10133   foreach_create_subif_bit;
10134 #undef _
10135
10136   mp->outer_vlan_id = ntohs (outer_vlan_id);
10137   mp->inner_vlan_id = ntohs (inner_vlan_id);
10138
10139   S (mp);
10140   W (ret);
10141   return ret;
10142 }
10143
10144 static int
10145 api_oam_add_del (vat_main_t * vam)
10146 {
10147   unformat_input_t *i = vam->input;
10148   vl_api_oam_add_del_t *mp;
10149   u32 vrf_id = 0;
10150   u8 is_add = 1;
10151   ip4_address_t src, dst;
10152   u8 src_set = 0;
10153   u8 dst_set = 0;
10154   int ret;
10155
10156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10157     {
10158       if (unformat (i, "vrf %d", &vrf_id))
10159         ;
10160       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10161         src_set = 1;
10162       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10163         dst_set = 1;
10164       else if (unformat (i, "del"))
10165         is_add = 0;
10166       else
10167         {
10168           clib_warning ("parse error '%U'", format_unformat_error, i);
10169           return -99;
10170         }
10171     }
10172
10173   if (src_set == 0)
10174     {
10175       errmsg ("missing src addr");
10176       return -99;
10177     }
10178
10179   if (dst_set == 0)
10180     {
10181       errmsg ("missing dst addr");
10182       return -99;
10183     }
10184
10185   M (OAM_ADD_DEL, mp);
10186
10187   mp->vrf_id = ntohl (vrf_id);
10188   mp->is_add = is_add;
10189   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10190   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10191
10192   S (mp);
10193   W (ret);
10194   return ret;
10195 }
10196
10197 static int
10198 api_reset_fib (vat_main_t * vam)
10199 {
10200   unformat_input_t *i = vam->input;
10201   vl_api_reset_fib_t *mp;
10202   u32 vrf_id = 0;
10203   u8 is_ipv6 = 0;
10204   u8 vrf_id_set = 0;
10205
10206   int ret;
10207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10208     {
10209       if (unformat (i, "vrf %d", &vrf_id))
10210         vrf_id_set = 1;
10211       else if (unformat (i, "ipv6"))
10212         is_ipv6 = 1;
10213       else
10214         {
10215           clib_warning ("parse error '%U'", format_unformat_error, i);
10216           return -99;
10217         }
10218     }
10219
10220   if (vrf_id_set == 0)
10221     {
10222       errmsg ("missing vrf id");
10223       return -99;
10224     }
10225
10226   M (RESET_FIB, mp);
10227
10228   mp->vrf_id = ntohl (vrf_id);
10229   mp->is_ipv6 = is_ipv6;
10230
10231   S (mp);
10232   W (ret);
10233   return ret;
10234 }
10235
10236 static int
10237 api_dhcp_proxy_config (vat_main_t * vam)
10238 {
10239   unformat_input_t *i = vam->input;
10240   vl_api_dhcp_proxy_config_t *mp;
10241   u32 rx_vrf_id = 0;
10242   u32 server_vrf_id = 0;
10243   u8 is_add = 1;
10244   u8 v4_address_set = 0;
10245   u8 v6_address_set = 0;
10246   ip4_address_t v4address;
10247   ip6_address_t v6address;
10248   u8 v4_src_address_set = 0;
10249   u8 v6_src_address_set = 0;
10250   ip4_address_t v4srcaddress;
10251   ip6_address_t v6srcaddress;
10252   int ret;
10253
10254   /* Parse args required to build the message */
10255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10256     {
10257       if (unformat (i, "del"))
10258         is_add = 0;
10259       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10260         ;
10261       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10262         ;
10263       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10264         v4_address_set = 1;
10265       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10266         v6_address_set = 1;
10267       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10268         v4_src_address_set = 1;
10269       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10270         v6_src_address_set = 1;
10271       else
10272         break;
10273     }
10274
10275   if (v4_address_set && v6_address_set)
10276     {
10277       errmsg ("both v4 and v6 server addresses set");
10278       return -99;
10279     }
10280   if (!v4_address_set && !v6_address_set)
10281     {
10282       errmsg ("no server addresses set");
10283       return -99;
10284     }
10285
10286   if (v4_src_address_set && v6_src_address_set)
10287     {
10288       errmsg ("both v4 and v6  src addresses set");
10289       return -99;
10290     }
10291   if (!v4_src_address_set && !v6_src_address_set)
10292     {
10293       errmsg ("no src addresses set");
10294       return -99;
10295     }
10296
10297   if (!(v4_src_address_set && v4_address_set) &&
10298       !(v6_src_address_set && v6_address_set))
10299     {
10300       errmsg ("no matching server and src addresses set");
10301       return -99;
10302     }
10303
10304   /* Construct the API message */
10305   M (DHCP_PROXY_CONFIG, mp);
10306
10307   mp->is_add = is_add;
10308   mp->rx_vrf_id = ntohl (rx_vrf_id);
10309   mp->server_vrf_id = ntohl (server_vrf_id);
10310   if (v6_address_set)
10311     {
10312       mp->is_ipv6 = 1;
10313       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10314       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10315     }
10316   else
10317     {
10318       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10319       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10320     }
10321
10322   /* send it... */
10323   S (mp);
10324
10325   /* Wait for a reply, return good/bad news  */
10326   W (ret);
10327   return ret;
10328 }
10329
10330 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10331 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10332
10333 static void
10334 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10335 {
10336   vat_main_t *vam = &vat_main;
10337   u32 i, count = mp->count;
10338   vl_api_dhcp_server_t *s;
10339
10340   if (mp->is_ipv6)
10341     print (vam->ofp,
10342            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10343            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10344            ntohl (mp->rx_vrf_id),
10345            format_ip6_address, mp->dhcp_src_address,
10346            mp->vss_type, mp->vss_vpn_ascii_id,
10347            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10348   else
10349     print (vam->ofp,
10350            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10351            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10352            ntohl (mp->rx_vrf_id),
10353            format_ip4_address, mp->dhcp_src_address,
10354            mp->vss_type, mp->vss_vpn_ascii_id,
10355            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10356
10357   for (i = 0; i < count; i++)
10358     {
10359       s = &mp->servers[i];
10360
10361       if (mp->is_ipv6)
10362         print (vam->ofp,
10363                " Server Table-ID %d, Server Address %U",
10364                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10365       else
10366         print (vam->ofp,
10367                " Server Table-ID %d, Server Address %U",
10368                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10369     }
10370 }
10371
10372 static void vl_api_dhcp_proxy_details_t_handler_json
10373   (vl_api_dhcp_proxy_details_t * mp)
10374 {
10375   vat_main_t *vam = &vat_main;
10376   vat_json_node_t *node = NULL;
10377   u32 i, count = mp->count;
10378   struct in_addr ip4;
10379   struct in6_addr ip6;
10380   vl_api_dhcp_server_t *s;
10381
10382   if (VAT_JSON_ARRAY != vam->json_tree.type)
10383     {
10384       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10385       vat_json_init_array (&vam->json_tree);
10386     }
10387   node = vat_json_array_add (&vam->json_tree);
10388
10389   vat_json_init_object (node);
10390   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10391   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10392                              sizeof (mp->vss_type));
10393   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10394                                    mp->vss_vpn_ascii_id);
10395   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10396   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10397
10398   if (mp->is_ipv6)
10399     {
10400       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10401       vat_json_object_add_ip6 (node, "src_address", ip6);
10402     }
10403   else
10404     {
10405       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10406       vat_json_object_add_ip4 (node, "src_address", ip4);
10407     }
10408
10409   for (i = 0; i < count; i++)
10410     {
10411       s = &mp->servers[i];
10412
10413       vat_json_object_add_uint (node, "server-table-id",
10414                                 ntohl (s->server_vrf_id));
10415
10416       if (mp->is_ipv6)
10417         {
10418           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10419           vat_json_object_add_ip4 (node, "src_address", ip4);
10420         }
10421       else
10422         {
10423           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10424           vat_json_object_add_ip6 (node, "server_address", ip6);
10425         }
10426     }
10427 }
10428
10429 static int
10430 api_dhcp_proxy_dump (vat_main_t * vam)
10431 {
10432   unformat_input_t *i = vam->input;
10433   vl_api_control_ping_t *mp_ping;
10434   vl_api_dhcp_proxy_dump_t *mp;
10435   u8 is_ipv6 = 0;
10436   int ret;
10437
10438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10439     {
10440       if (unformat (i, "ipv6"))
10441         is_ipv6 = 1;
10442       else
10443         {
10444           clib_warning ("parse error '%U'", format_unformat_error, i);
10445           return -99;
10446         }
10447     }
10448
10449   M (DHCP_PROXY_DUMP, mp);
10450
10451   mp->is_ip6 = is_ipv6;
10452   S (mp);
10453
10454   /* Use a control ping for synchronization */
10455   MPING (CONTROL_PING, mp_ping);
10456   S (mp_ping);
10457
10458   W (ret);
10459   return ret;
10460 }
10461
10462 static int
10463 api_dhcp_proxy_set_vss (vat_main_t * vam)
10464 {
10465   unformat_input_t *i = vam->input;
10466   vl_api_dhcp_proxy_set_vss_t *mp;
10467   u8 is_ipv6 = 0;
10468   u8 is_add = 1;
10469   u32 tbl_id = ~0;
10470   u8 vss_type = VSS_TYPE_DEFAULT;
10471   u8 *vpn_ascii_id = 0;
10472   u32 oui = 0;
10473   u32 fib_id = 0;
10474   int ret;
10475
10476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10477     {
10478       if (unformat (i, "tbl_id %d", &tbl_id))
10479         ;
10480       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10481         vss_type = VSS_TYPE_ASCII;
10482       else if (unformat (i, "fib_id %d", &fib_id))
10483         vss_type = VSS_TYPE_VPN_ID;
10484       else if (unformat (i, "oui %d", &oui))
10485         vss_type = VSS_TYPE_VPN_ID;
10486       else if (unformat (i, "ipv6"))
10487         is_ipv6 = 1;
10488       else if (unformat (i, "del"))
10489         is_add = 0;
10490       else
10491         break;
10492     }
10493
10494   if (tbl_id == ~0)
10495     {
10496       errmsg ("missing tbl_id ");
10497       vec_free (vpn_ascii_id);
10498       return -99;
10499     }
10500
10501   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10502     {
10503       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10504       vec_free (vpn_ascii_id);
10505       return -99;
10506     }
10507
10508   M (DHCP_PROXY_SET_VSS, mp);
10509   mp->tbl_id = ntohl (tbl_id);
10510   mp->vss_type = vss_type;
10511   if (vpn_ascii_id)
10512     {
10513       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10514       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10515     }
10516   mp->vpn_index = ntohl (fib_id);
10517   mp->oui = ntohl (oui);
10518   mp->is_ipv6 = is_ipv6;
10519   mp->is_add = is_add;
10520
10521   S (mp);
10522   W (ret);
10523
10524   vec_free (vpn_ascii_id);
10525   return ret;
10526 }
10527
10528 static int
10529 api_dhcp_client_config (vat_main_t * vam)
10530 {
10531   unformat_input_t *i = vam->input;
10532   vl_api_dhcp_client_config_t *mp;
10533   u32 sw_if_index;
10534   u8 sw_if_index_set = 0;
10535   u8 is_add = 1;
10536   u8 *hostname = 0;
10537   u8 disable_event = 0;
10538   int ret;
10539
10540   /* Parse args required to build the message */
10541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10542     {
10543       if (unformat (i, "del"))
10544         is_add = 0;
10545       else
10546         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10547         sw_if_index_set = 1;
10548       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10549         sw_if_index_set = 1;
10550       else if (unformat (i, "hostname %s", &hostname))
10551         ;
10552       else if (unformat (i, "disable_event"))
10553         disable_event = 1;
10554       else
10555         break;
10556     }
10557
10558   if (sw_if_index_set == 0)
10559     {
10560       errmsg ("missing interface name or sw_if_index");
10561       return -99;
10562     }
10563
10564   if (vec_len (hostname) > 63)
10565     {
10566       errmsg ("hostname too long");
10567     }
10568   vec_add1 (hostname, 0);
10569
10570   /* Construct the API message */
10571   M (DHCP_CLIENT_CONFIG, mp);
10572
10573   mp->is_add = is_add;
10574   mp->client.sw_if_index = htonl (sw_if_index);
10575   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10576   vec_free (hostname);
10577   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10578   mp->client.pid = htonl (getpid ());
10579
10580   /* send it... */
10581   S (mp);
10582
10583   /* Wait for a reply, return good/bad news  */
10584   W (ret);
10585   return ret;
10586 }
10587
10588 static int
10589 api_set_ip_flow_hash (vat_main_t * vam)
10590 {
10591   unformat_input_t *i = vam->input;
10592   vl_api_set_ip_flow_hash_t *mp;
10593   u32 vrf_id = 0;
10594   u8 is_ipv6 = 0;
10595   u8 vrf_id_set = 0;
10596   u8 src = 0;
10597   u8 dst = 0;
10598   u8 sport = 0;
10599   u8 dport = 0;
10600   u8 proto = 0;
10601   u8 reverse = 0;
10602   int ret;
10603
10604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10605     {
10606       if (unformat (i, "vrf %d", &vrf_id))
10607         vrf_id_set = 1;
10608       else if (unformat (i, "ipv6"))
10609         is_ipv6 = 1;
10610       else if (unformat (i, "src"))
10611         src = 1;
10612       else if (unformat (i, "dst"))
10613         dst = 1;
10614       else if (unformat (i, "sport"))
10615         sport = 1;
10616       else if (unformat (i, "dport"))
10617         dport = 1;
10618       else if (unformat (i, "proto"))
10619         proto = 1;
10620       else if (unformat (i, "reverse"))
10621         reverse = 1;
10622
10623       else
10624         {
10625           clib_warning ("parse error '%U'", format_unformat_error, i);
10626           return -99;
10627         }
10628     }
10629
10630   if (vrf_id_set == 0)
10631     {
10632       errmsg ("missing vrf id");
10633       return -99;
10634     }
10635
10636   M (SET_IP_FLOW_HASH, mp);
10637   mp->src = src;
10638   mp->dst = dst;
10639   mp->sport = sport;
10640   mp->dport = dport;
10641   mp->proto = proto;
10642   mp->reverse = reverse;
10643   mp->vrf_id = ntohl (vrf_id);
10644   mp->is_ipv6 = is_ipv6;
10645
10646   S (mp);
10647   W (ret);
10648   return ret;
10649 }
10650
10651 static int
10652 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10653 {
10654   unformat_input_t *i = vam->input;
10655   vl_api_sw_interface_ip6_enable_disable_t *mp;
10656   u32 sw_if_index;
10657   u8 sw_if_index_set = 0;
10658   u8 enable = 0;
10659   int ret;
10660
10661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10662     {
10663       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10664         sw_if_index_set = 1;
10665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10666         sw_if_index_set = 1;
10667       else if (unformat (i, "enable"))
10668         enable = 1;
10669       else if (unformat (i, "disable"))
10670         enable = 0;
10671       else
10672         {
10673           clib_warning ("parse error '%U'", format_unformat_error, i);
10674           return -99;
10675         }
10676     }
10677
10678   if (sw_if_index_set == 0)
10679     {
10680       errmsg ("missing interface name or sw_if_index");
10681       return -99;
10682     }
10683
10684   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10685
10686   mp->sw_if_index = ntohl (sw_if_index);
10687   mp->enable = enable;
10688
10689   S (mp);
10690   W (ret);
10691   return ret;
10692 }
10693
10694 static int
10695 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10696 {
10697   unformat_input_t *i = vam->input;
10698   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10699   u32 sw_if_index;
10700   u8 sw_if_index_set = 0;
10701   u8 v6_address_set = 0;
10702   ip6_address_t v6address;
10703   int ret;
10704
10705   /* Parse args required to build the message */
10706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10707     {
10708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10709         sw_if_index_set = 1;
10710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10711         sw_if_index_set = 1;
10712       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10713         v6_address_set = 1;
10714       else
10715         break;
10716     }
10717
10718   if (sw_if_index_set == 0)
10719     {
10720       errmsg ("missing interface name or sw_if_index");
10721       return -99;
10722     }
10723   if (!v6_address_set)
10724     {
10725       errmsg ("no address set");
10726       return -99;
10727     }
10728
10729   /* Construct the API message */
10730   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10731
10732   mp->sw_if_index = ntohl (sw_if_index);
10733   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10734
10735   /* send it... */
10736   S (mp);
10737
10738   /* Wait for a reply, return good/bad news  */
10739   W (ret);
10740   return ret;
10741 }
10742
10743 static int
10744 api_ip6nd_proxy_add_del (vat_main_t * vam)
10745 {
10746   unformat_input_t *i = vam->input;
10747   vl_api_ip6nd_proxy_add_del_t *mp;
10748   u32 sw_if_index = ~0;
10749   u8 v6_address_set = 0;
10750   ip6_address_t v6address;
10751   u8 is_del = 0;
10752   int ret;
10753
10754   /* Parse args required to build the message */
10755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10758         ;
10759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10760         ;
10761       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10762         v6_address_set = 1;
10763       if (unformat (i, "del"))
10764         is_del = 1;
10765       else
10766         {
10767           clib_warning ("parse error '%U'", format_unformat_error, i);
10768           return -99;
10769         }
10770     }
10771
10772   if (sw_if_index == ~0)
10773     {
10774       errmsg ("missing interface name or sw_if_index");
10775       return -99;
10776     }
10777   if (!v6_address_set)
10778     {
10779       errmsg ("no address set");
10780       return -99;
10781     }
10782
10783   /* Construct the API message */
10784   M (IP6ND_PROXY_ADD_DEL, mp);
10785
10786   mp->is_del = is_del;
10787   mp->sw_if_index = ntohl (sw_if_index);
10788   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10789
10790   /* send it... */
10791   S (mp);
10792
10793   /* Wait for a reply, return good/bad news  */
10794   W (ret);
10795   return ret;
10796 }
10797
10798 static int
10799 api_ip6nd_proxy_dump (vat_main_t * vam)
10800 {
10801   vl_api_ip6nd_proxy_dump_t *mp;
10802   vl_api_control_ping_t *mp_ping;
10803   int ret;
10804
10805   M (IP6ND_PROXY_DUMP, mp);
10806
10807   S (mp);
10808
10809   /* Use a control ping for synchronization */
10810   MPING (CONTROL_PING, mp_ping);
10811   S (mp_ping);
10812
10813   W (ret);
10814   return ret;
10815 }
10816
10817 static void vl_api_ip6nd_proxy_details_t_handler
10818   (vl_api_ip6nd_proxy_details_t * mp)
10819 {
10820   vat_main_t *vam = &vat_main;
10821
10822   print (vam->ofp, "host %U sw_if_index %d",
10823          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10824 }
10825
10826 static void vl_api_ip6nd_proxy_details_t_handler_json
10827   (vl_api_ip6nd_proxy_details_t * mp)
10828 {
10829   vat_main_t *vam = &vat_main;
10830   struct in6_addr ip6;
10831   vat_json_node_t *node = NULL;
10832
10833   if (VAT_JSON_ARRAY != vam->json_tree.type)
10834     {
10835       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10836       vat_json_init_array (&vam->json_tree);
10837     }
10838   node = vat_json_array_add (&vam->json_tree);
10839
10840   vat_json_init_object (node);
10841   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10842
10843   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10844   vat_json_object_add_ip6 (node, "host", ip6);
10845 }
10846
10847 static int
10848 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10849 {
10850   unformat_input_t *i = vam->input;
10851   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10852   u32 sw_if_index;
10853   u8 sw_if_index_set = 0;
10854   u32 address_length = 0;
10855   u8 v6_address_set = 0;
10856   ip6_address_t v6address;
10857   u8 use_default = 0;
10858   u8 no_advertise = 0;
10859   u8 off_link = 0;
10860   u8 no_autoconfig = 0;
10861   u8 no_onlink = 0;
10862   u8 is_no = 0;
10863   u32 val_lifetime = 0;
10864   u32 pref_lifetime = 0;
10865   int ret;
10866
10867   /* Parse args required to build the message */
10868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10869     {
10870       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10871         sw_if_index_set = 1;
10872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10873         sw_if_index_set = 1;
10874       else if (unformat (i, "%U/%d",
10875                          unformat_ip6_address, &v6address, &address_length))
10876         v6_address_set = 1;
10877       else if (unformat (i, "val_life %d", &val_lifetime))
10878         ;
10879       else if (unformat (i, "pref_life %d", &pref_lifetime))
10880         ;
10881       else if (unformat (i, "def"))
10882         use_default = 1;
10883       else if (unformat (i, "noadv"))
10884         no_advertise = 1;
10885       else if (unformat (i, "offl"))
10886         off_link = 1;
10887       else if (unformat (i, "noauto"))
10888         no_autoconfig = 1;
10889       else if (unformat (i, "nolink"))
10890         no_onlink = 1;
10891       else if (unformat (i, "isno"))
10892         is_no = 1;
10893       else
10894         {
10895           clib_warning ("parse error '%U'", format_unformat_error, i);
10896           return -99;
10897         }
10898     }
10899
10900   if (sw_if_index_set == 0)
10901     {
10902       errmsg ("missing interface name or sw_if_index");
10903       return -99;
10904     }
10905   if (!v6_address_set)
10906     {
10907       errmsg ("no address set");
10908       return -99;
10909     }
10910
10911   /* Construct the API message */
10912   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10913
10914   mp->sw_if_index = ntohl (sw_if_index);
10915   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10916   mp->address_length = address_length;
10917   mp->use_default = use_default;
10918   mp->no_advertise = no_advertise;
10919   mp->off_link = off_link;
10920   mp->no_autoconfig = no_autoconfig;
10921   mp->no_onlink = no_onlink;
10922   mp->is_no = is_no;
10923   mp->val_lifetime = ntohl (val_lifetime);
10924   mp->pref_lifetime = ntohl (pref_lifetime);
10925
10926   /* send it... */
10927   S (mp);
10928
10929   /* Wait for a reply, return good/bad news  */
10930   W (ret);
10931   return ret;
10932 }
10933
10934 static int
10935 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10936 {
10937   unformat_input_t *i = vam->input;
10938   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10939   u32 sw_if_index;
10940   u8 sw_if_index_set = 0;
10941   u8 suppress = 0;
10942   u8 managed = 0;
10943   u8 other = 0;
10944   u8 ll_option = 0;
10945   u8 send_unicast = 0;
10946   u8 cease = 0;
10947   u8 is_no = 0;
10948   u8 default_router = 0;
10949   u32 max_interval = 0;
10950   u32 min_interval = 0;
10951   u32 lifetime = 0;
10952   u32 initial_count = 0;
10953   u32 initial_interval = 0;
10954   int ret;
10955
10956
10957   /* Parse args required to build the message */
10958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10959     {
10960       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10961         sw_if_index_set = 1;
10962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10963         sw_if_index_set = 1;
10964       else if (unformat (i, "maxint %d", &max_interval))
10965         ;
10966       else if (unformat (i, "minint %d", &min_interval))
10967         ;
10968       else if (unformat (i, "life %d", &lifetime))
10969         ;
10970       else if (unformat (i, "count %d", &initial_count))
10971         ;
10972       else if (unformat (i, "interval %d", &initial_interval))
10973         ;
10974       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10975         suppress = 1;
10976       else if (unformat (i, "managed"))
10977         managed = 1;
10978       else if (unformat (i, "other"))
10979         other = 1;
10980       else if (unformat (i, "ll"))
10981         ll_option = 1;
10982       else if (unformat (i, "send"))
10983         send_unicast = 1;
10984       else if (unformat (i, "cease"))
10985         cease = 1;
10986       else if (unformat (i, "isno"))
10987         is_no = 1;
10988       else if (unformat (i, "def"))
10989         default_router = 1;
10990       else
10991         {
10992           clib_warning ("parse error '%U'", format_unformat_error, i);
10993           return -99;
10994         }
10995     }
10996
10997   if (sw_if_index_set == 0)
10998     {
10999       errmsg ("missing interface name or sw_if_index");
11000       return -99;
11001     }
11002
11003   /* Construct the API message */
11004   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
11005
11006   mp->sw_if_index = ntohl (sw_if_index);
11007   mp->max_interval = ntohl (max_interval);
11008   mp->min_interval = ntohl (min_interval);
11009   mp->lifetime = ntohl (lifetime);
11010   mp->initial_count = ntohl (initial_count);
11011   mp->initial_interval = ntohl (initial_interval);
11012   mp->suppress = suppress;
11013   mp->managed = managed;
11014   mp->other = other;
11015   mp->ll_option = ll_option;
11016   mp->send_unicast = send_unicast;
11017   mp->cease = cease;
11018   mp->is_no = is_no;
11019   mp->default_router = default_router;
11020
11021   /* send it... */
11022   S (mp);
11023
11024   /* Wait for a reply, return good/bad news  */
11025   W (ret);
11026   return ret;
11027 }
11028
11029 static int
11030 api_set_arp_neighbor_limit (vat_main_t * vam)
11031 {
11032   unformat_input_t *i = vam->input;
11033   vl_api_set_arp_neighbor_limit_t *mp;
11034   u32 arp_nbr_limit;
11035   u8 limit_set = 0;
11036   u8 is_ipv6 = 0;
11037   int ret;
11038
11039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11040     {
11041       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
11042         limit_set = 1;
11043       else if (unformat (i, "ipv6"))
11044         is_ipv6 = 1;
11045       else
11046         {
11047           clib_warning ("parse error '%U'", format_unformat_error, i);
11048           return -99;
11049         }
11050     }
11051
11052   if (limit_set == 0)
11053     {
11054       errmsg ("missing limit value");
11055       return -99;
11056     }
11057
11058   M (SET_ARP_NEIGHBOR_LIMIT, mp);
11059
11060   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
11061   mp->is_ipv6 = is_ipv6;
11062
11063   S (mp);
11064   W (ret);
11065   return ret;
11066 }
11067
11068 static int
11069 api_l2_patch_add_del (vat_main_t * vam)
11070 {
11071   unformat_input_t *i = vam->input;
11072   vl_api_l2_patch_add_del_t *mp;
11073   u32 rx_sw_if_index;
11074   u8 rx_sw_if_index_set = 0;
11075   u32 tx_sw_if_index;
11076   u8 tx_sw_if_index_set = 0;
11077   u8 is_add = 1;
11078   int ret;
11079
11080   /* Parse args required to build the message */
11081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11082     {
11083       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
11084         rx_sw_if_index_set = 1;
11085       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
11086         tx_sw_if_index_set = 1;
11087       else if (unformat (i, "rx"))
11088         {
11089           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11090             {
11091               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11092                             &rx_sw_if_index))
11093                 rx_sw_if_index_set = 1;
11094             }
11095           else
11096             break;
11097         }
11098       else if (unformat (i, "tx"))
11099         {
11100           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11101             {
11102               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11103                             &tx_sw_if_index))
11104                 tx_sw_if_index_set = 1;
11105             }
11106           else
11107             break;
11108         }
11109       else if (unformat (i, "del"))
11110         is_add = 0;
11111       else
11112         break;
11113     }
11114
11115   if (rx_sw_if_index_set == 0)
11116     {
11117       errmsg ("missing rx interface name or rx_sw_if_index");
11118       return -99;
11119     }
11120
11121   if (tx_sw_if_index_set == 0)
11122     {
11123       errmsg ("missing tx interface name or tx_sw_if_index");
11124       return -99;
11125     }
11126
11127   M (L2_PATCH_ADD_DEL, mp);
11128
11129   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11130   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11131   mp->is_add = is_add;
11132
11133   S (mp);
11134   W (ret);
11135   return ret;
11136 }
11137
11138 u8 is_del;
11139 u8 localsid_addr[16];
11140 u8 end_psp;
11141 u8 behavior;
11142 u32 sw_if_index;
11143 u32 vlan_index;
11144 u32 fib_table;
11145 u8 nh_addr[16];
11146
11147 static int
11148 api_sr_localsid_add_del (vat_main_t * vam)
11149 {
11150   unformat_input_t *i = vam->input;
11151   vl_api_sr_localsid_add_del_t *mp;
11152
11153   u8 is_del;
11154   ip6_address_t localsid;
11155   u8 end_psp = 0;
11156   u8 behavior = ~0;
11157   u32 sw_if_index;
11158   u32 fib_table = ~(u32) 0;
11159   ip6_address_t nh_addr6;
11160   ip4_address_t nh_addr4;
11161   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
11162   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
11163
11164   bool nexthop_set = 0;
11165
11166   int ret;
11167
11168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11169     {
11170       if (unformat (i, "del"))
11171         is_del = 1;
11172       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11173       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11174         nexthop_set = 1;
11175       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11176         nexthop_set = 1;
11177       else if (unformat (i, "behavior %u", &behavior));
11178       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11179       else if (unformat (i, "fib-table %u", &fib_table));
11180       else if (unformat (i, "end.psp %u", &behavior));
11181       else
11182         break;
11183     }
11184
11185   M (SR_LOCALSID_ADD_DEL, mp);
11186
11187   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11188   if (nexthop_set)
11189     {
11190       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11191       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11192     }
11193   mp->behavior = behavior;
11194   mp->sw_if_index = ntohl (sw_if_index);
11195   mp->fib_table = ntohl (fib_table);
11196   mp->end_psp = end_psp;
11197   mp->is_del = is_del;
11198
11199   S (mp);
11200   W (ret);
11201   return ret;
11202 }
11203
11204 static int
11205 api_ioam_enable (vat_main_t * vam)
11206 {
11207   unformat_input_t *input = vam->input;
11208   vl_api_ioam_enable_t *mp;
11209   u32 id = 0;
11210   int has_trace_option = 0;
11211   int has_pot_option = 0;
11212   int has_seqno_option = 0;
11213   int has_analyse_option = 0;
11214   int ret;
11215
11216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11217     {
11218       if (unformat (input, "trace"))
11219         has_trace_option = 1;
11220       else if (unformat (input, "pot"))
11221         has_pot_option = 1;
11222       else if (unformat (input, "seqno"))
11223         has_seqno_option = 1;
11224       else if (unformat (input, "analyse"))
11225         has_analyse_option = 1;
11226       else
11227         break;
11228     }
11229   M (IOAM_ENABLE, mp);
11230   mp->id = htons (id);
11231   mp->seqno = has_seqno_option;
11232   mp->analyse = has_analyse_option;
11233   mp->pot_enable = has_pot_option;
11234   mp->trace_enable = has_trace_option;
11235
11236   S (mp);
11237   W (ret);
11238   return ret;
11239 }
11240
11241
11242 static int
11243 api_ioam_disable (vat_main_t * vam)
11244 {
11245   vl_api_ioam_disable_t *mp;
11246   int ret;
11247
11248   M (IOAM_DISABLE, mp);
11249   S (mp);
11250   W (ret);
11251   return ret;
11252 }
11253
11254 #define foreach_tcp_proto_field                 \
11255 _(src_port)                                     \
11256 _(dst_port)
11257
11258 #define foreach_udp_proto_field                 \
11259 _(src_port)                                     \
11260 _(dst_port)
11261
11262 #define foreach_ip4_proto_field                 \
11263 _(src_address)                                  \
11264 _(dst_address)                                  \
11265 _(tos)                                          \
11266 _(length)                                       \
11267 _(fragment_id)                                  \
11268 _(ttl)                                          \
11269 _(protocol)                                     \
11270 _(checksum)
11271
11272 typedef struct
11273 {
11274   u16 src_port, dst_port;
11275 } tcpudp_header_t;
11276
11277 #if VPP_API_TEST_BUILTIN == 0
11278 uword
11279 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11280 {
11281   u8 **maskp = va_arg (*args, u8 **);
11282   u8 *mask = 0;
11283   u8 found_something = 0;
11284   tcp_header_t *tcp;
11285
11286 #define _(a) u8 a=0;
11287   foreach_tcp_proto_field;
11288 #undef _
11289
11290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11291     {
11292       if (0);
11293 #define _(a) else if (unformat (input, #a)) a=1;
11294       foreach_tcp_proto_field
11295 #undef _
11296         else
11297         break;
11298     }
11299
11300 #define _(a) found_something += a;
11301   foreach_tcp_proto_field;
11302 #undef _
11303
11304   if (found_something == 0)
11305     return 0;
11306
11307   vec_validate (mask, sizeof (*tcp) - 1);
11308
11309   tcp = (tcp_header_t *) mask;
11310
11311 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
11312   foreach_tcp_proto_field;
11313 #undef _
11314
11315   *maskp = mask;
11316   return 1;
11317 }
11318
11319 uword
11320 unformat_udp_mask (unformat_input_t * input, va_list * args)
11321 {
11322   u8 **maskp = va_arg (*args, u8 **);
11323   u8 *mask = 0;
11324   u8 found_something = 0;
11325   udp_header_t *udp;
11326
11327 #define _(a) u8 a=0;
11328   foreach_udp_proto_field;
11329 #undef _
11330
11331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11332     {
11333       if (0);
11334 #define _(a) else if (unformat (input, #a)) a=1;
11335       foreach_udp_proto_field
11336 #undef _
11337         else
11338         break;
11339     }
11340
11341 #define _(a) found_something += a;
11342   foreach_udp_proto_field;
11343 #undef _
11344
11345   if (found_something == 0)
11346     return 0;
11347
11348   vec_validate (mask, sizeof (*udp) - 1);
11349
11350   udp = (udp_header_t *) mask;
11351
11352 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
11353   foreach_udp_proto_field;
11354 #undef _
11355
11356   *maskp = mask;
11357   return 1;
11358 }
11359
11360 uword
11361 unformat_l4_mask (unformat_input_t * input, va_list * args)
11362 {
11363   u8 **maskp = va_arg (*args, u8 **);
11364   u16 src_port = 0, dst_port = 0;
11365   tcpudp_header_t *tcpudp;
11366
11367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11368     {
11369       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11370         return 1;
11371       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11372         return 1;
11373       else if (unformat (input, "src_port"))
11374         src_port = 0xFFFF;
11375       else if (unformat (input, "dst_port"))
11376         dst_port = 0xFFFF;
11377       else
11378         return 0;
11379     }
11380
11381   if (!src_port && !dst_port)
11382     return 0;
11383
11384   u8 *mask = 0;
11385   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11386
11387   tcpudp = (tcpudp_header_t *) mask;
11388   tcpudp->src_port = src_port;
11389   tcpudp->dst_port = dst_port;
11390
11391   *maskp = mask;
11392
11393   return 1;
11394 }
11395
11396 uword
11397 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11398 {
11399   u8 **maskp = va_arg (*args, u8 **);
11400   u8 *mask = 0;
11401   u8 found_something = 0;
11402   ip4_header_t *ip;
11403
11404 #define _(a) u8 a=0;
11405   foreach_ip4_proto_field;
11406 #undef _
11407   u8 version = 0;
11408   u8 hdr_length = 0;
11409
11410
11411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11412     {
11413       if (unformat (input, "version"))
11414         version = 1;
11415       else if (unformat (input, "hdr_length"))
11416         hdr_length = 1;
11417       else if (unformat (input, "src"))
11418         src_address = 1;
11419       else if (unformat (input, "dst"))
11420         dst_address = 1;
11421       else if (unformat (input, "proto"))
11422         protocol = 1;
11423
11424 #define _(a) else if (unformat (input, #a)) a=1;
11425       foreach_ip4_proto_field
11426 #undef _
11427         else
11428         break;
11429     }
11430
11431 #define _(a) found_something += a;
11432   foreach_ip4_proto_field;
11433 #undef _
11434
11435   if (found_something == 0)
11436     return 0;
11437
11438   vec_validate (mask, sizeof (*ip) - 1);
11439
11440   ip = (ip4_header_t *) mask;
11441
11442 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11443   foreach_ip4_proto_field;
11444 #undef _
11445
11446   ip->ip_version_and_header_length = 0;
11447
11448   if (version)
11449     ip->ip_version_and_header_length |= 0xF0;
11450
11451   if (hdr_length)
11452     ip->ip_version_and_header_length |= 0x0F;
11453
11454   *maskp = mask;
11455   return 1;
11456 }
11457
11458 #define foreach_ip6_proto_field                 \
11459 _(src_address)                                  \
11460 _(dst_address)                                  \
11461 _(payload_length)                               \
11462 _(hop_limit)                                    \
11463 _(protocol)
11464
11465 uword
11466 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11467 {
11468   u8 **maskp = va_arg (*args, u8 **);
11469   u8 *mask = 0;
11470   u8 found_something = 0;
11471   ip6_header_t *ip;
11472   u32 ip_version_traffic_class_and_flow_label;
11473
11474 #define _(a) u8 a=0;
11475   foreach_ip6_proto_field;
11476 #undef _
11477   u8 version = 0;
11478   u8 traffic_class = 0;
11479   u8 flow_label = 0;
11480
11481   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11482     {
11483       if (unformat (input, "version"))
11484         version = 1;
11485       else if (unformat (input, "traffic-class"))
11486         traffic_class = 1;
11487       else if (unformat (input, "flow-label"))
11488         flow_label = 1;
11489       else if (unformat (input, "src"))
11490         src_address = 1;
11491       else if (unformat (input, "dst"))
11492         dst_address = 1;
11493       else if (unformat (input, "proto"))
11494         protocol = 1;
11495
11496 #define _(a) else if (unformat (input, #a)) a=1;
11497       foreach_ip6_proto_field
11498 #undef _
11499         else
11500         break;
11501     }
11502
11503 #define _(a) found_something += a;
11504   foreach_ip6_proto_field;
11505 #undef _
11506
11507   if (found_something == 0)
11508     return 0;
11509
11510   vec_validate (mask, sizeof (*ip) - 1);
11511
11512   ip = (ip6_header_t *) mask;
11513
11514 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
11515   foreach_ip6_proto_field;
11516 #undef _
11517
11518   ip_version_traffic_class_and_flow_label = 0;
11519
11520   if (version)
11521     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11522
11523   if (traffic_class)
11524     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11525
11526   if (flow_label)
11527     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11528
11529   ip->ip_version_traffic_class_and_flow_label =
11530     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11531
11532   *maskp = mask;
11533   return 1;
11534 }
11535
11536 uword
11537 unformat_l3_mask (unformat_input_t * input, va_list * args)
11538 {
11539   u8 **maskp = va_arg (*args, u8 **);
11540
11541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11542     {
11543       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11544         return 1;
11545       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11546         return 1;
11547       else
11548         break;
11549     }
11550   return 0;
11551 }
11552
11553 uword
11554 unformat_l2_mask (unformat_input_t * input, va_list * args)
11555 {
11556   u8 **maskp = va_arg (*args, u8 **);
11557   u8 *mask = 0;
11558   u8 src = 0;
11559   u8 dst = 0;
11560   u8 proto = 0;
11561   u8 tag1 = 0;
11562   u8 tag2 = 0;
11563   u8 ignore_tag1 = 0;
11564   u8 ignore_tag2 = 0;
11565   u8 cos1 = 0;
11566   u8 cos2 = 0;
11567   u8 dot1q = 0;
11568   u8 dot1ad = 0;
11569   int len = 14;
11570
11571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11572     {
11573       if (unformat (input, "src"))
11574         src = 1;
11575       else if (unformat (input, "dst"))
11576         dst = 1;
11577       else if (unformat (input, "proto"))
11578         proto = 1;
11579       else if (unformat (input, "tag1"))
11580         tag1 = 1;
11581       else if (unformat (input, "tag2"))
11582         tag2 = 1;
11583       else if (unformat (input, "ignore-tag1"))
11584         ignore_tag1 = 1;
11585       else if (unformat (input, "ignore-tag2"))
11586         ignore_tag2 = 1;
11587       else if (unformat (input, "cos1"))
11588         cos1 = 1;
11589       else if (unformat (input, "cos2"))
11590         cos2 = 1;
11591       else if (unformat (input, "dot1q"))
11592         dot1q = 1;
11593       else if (unformat (input, "dot1ad"))
11594         dot1ad = 1;
11595       else
11596         break;
11597     }
11598   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11599        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11600     return 0;
11601
11602   if (tag1 || ignore_tag1 || cos1 || dot1q)
11603     len = 18;
11604   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11605     len = 22;
11606
11607   vec_validate (mask, len - 1);
11608
11609   if (dst)
11610     clib_memset (mask, 0xff, 6);
11611
11612   if (src)
11613     clib_memset (mask + 6, 0xff, 6);
11614
11615   if (tag2 || dot1ad)
11616     {
11617       /* inner vlan tag */
11618       if (tag2)
11619         {
11620           mask[19] = 0xff;
11621           mask[18] = 0x0f;
11622         }
11623       if (cos2)
11624         mask[18] |= 0xe0;
11625       if (proto)
11626         mask[21] = mask[20] = 0xff;
11627       if (tag1)
11628         {
11629           mask[15] = 0xff;
11630           mask[14] = 0x0f;
11631         }
11632       if (cos1)
11633         mask[14] |= 0xe0;
11634       *maskp = mask;
11635       return 1;
11636     }
11637   if (tag1 | dot1q)
11638     {
11639       if (tag1)
11640         {
11641           mask[15] = 0xff;
11642           mask[14] = 0x0f;
11643         }
11644       if (cos1)
11645         mask[14] |= 0xe0;
11646       if (proto)
11647         mask[16] = mask[17] = 0xff;
11648
11649       *maskp = mask;
11650       return 1;
11651     }
11652   if (cos2)
11653     mask[18] |= 0xe0;
11654   if (cos1)
11655     mask[14] |= 0xe0;
11656   if (proto)
11657     mask[12] = mask[13] = 0xff;
11658
11659   *maskp = mask;
11660   return 1;
11661 }
11662
11663 uword
11664 unformat_classify_mask (unformat_input_t * input, va_list * args)
11665 {
11666   u8 **maskp = va_arg (*args, u8 **);
11667   u32 *skipp = va_arg (*args, u32 *);
11668   u32 *matchp = va_arg (*args, u32 *);
11669   u32 match;
11670   u8 *mask = 0;
11671   u8 *l2 = 0;
11672   u8 *l3 = 0;
11673   u8 *l4 = 0;
11674   int i;
11675
11676   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11677     {
11678       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11679         ;
11680       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11681         ;
11682       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11683         ;
11684       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11685         ;
11686       else
11687         break;
11688     }
11689
11690   if (l4 && !l3)
11691     {
11692       vec_free (mask);
11693       vec_free (l2);
11694       vec_free (l4);
11695       return 0;
11696     }
11697
11698   if (mask || l2 || l3 || l4)
11699     {
11700       if (l2 || l3 || l4)
11701         {
11702           /* "With a free Ethernet header in every package" */
11703           if (l2 == 0)
11704             vec_validate (l2, 13);
11705           mask = l2;
11706           if (vec_len (l3))
11707             {
11708               vec_append (mask, l3);
11709               vec_free (l3);
11710             }
11711           if (vec_len (l4))
11712             {
11713               vec_append (mask, l4);
11714               vec_free (l4);
11715             }
11716         }
11717
11718       /* Scan forward looking for the first significant mask octet */
11719       for (i = 0; i < vec_len (mask); i++)
11720         if (mask[i])
11721           break;
11722
11723       /* compute (skip, match) params */
11724       *skipp = i / sizeof (u32x4);
11725       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11726
11727       /* Pad mask to an even multiple of the vector size */
11728       while (vec_len (mask) % sizeof (u32x4))
11729         vec_add1 (mask, 0);
11730
11731       match = vec_len (mask) / sizeof (u32x4);
11732
11733       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11734         {
11735           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11736           if (*tmp || *(tmp + 1))
11737             break;
11738           match--;
11739         }
11740       if (match == 0)
11741         clib_warning ("BUG: match 0");
11742
11743       _vec_len (mask) = match * sizeof (u32x4);
11744
11745       *matchp = match;
11746       *maskp = mask;
11747
11748       return 1;
11749     }
11750
11751   return 0;
11752 }
11753 #endif /* VPP_API_TEST_BUILTIN */
11754
11755 #define foreach_l2_next                         \
11756 _(drop, DROP)                                   \
11757 _(ethernet, ETHERNET_INPUT)                     \
11758 _(ip4, IP4_INPUT)                               \
11759 _(ip6, IP6_INPUT)
11760
11761 uword
11762 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11763 {
11764   u32 *miss_next_indexp = va_arg (*args, u32 *);
11765   u32 next_index = 0;
11766   u32 tmp;
11767
11768 #define _(n,N) \
11769   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11770   foreach_l2_next;
11771 #undef _
11772
11773   if (unformat (input, "%d", &tmp))
11774     {
11775       next_index = tmp;
11776       goto out;
11777     }
11778
11779   return 0;
11780
11781 out:
11782   *miss_next_indexp = next_index;
11783   return 1;
11784 }
11785
11786 #define foreach_ip_next                         \
11787 _(drop, DROP)                                   \
11788 _(local, LOCAL)                                 \
11789 _(rewrite, REWRITE)
11790
11791 uword
11792 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11793 {
11794   u32 *miss_next_indexp = va_arg (*args, u32 *);
11795   u32 next_index = 0;
11796   u32 tmp;
11797
11798 #define _(n,N) \
11799   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11800   foreach_ip_next;
11801 #undef _
11802
11803   if (unformat (input, "%d", &tmp))
11804     {
11805       next_index = tmp;
11806       goto out;
11807     }
11808
11809   return 0;
11810
11811 out:
11812   *miss_next_indexp = next_index;
11813   return 1;
11814 }
11815
11816 #define foreach_acl_next                        \
11817 _(deny, DENY)
11818
11819 uword
11820 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11821 {
11822   u32 *miss_next_indexp = va_arg (*args, u32 *);
11823   u32 next_index = 0;
11824   u32 tmp;
11825
11826 #define _(n,N) \
11827   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11828   foreach_acl_next;
11829 #undef _
11830
11831   if (unformat (input, "permit"))
11832     {
11833       next_index = ~0;
11834       goto out;
11835     }
11836   else if (unformat (input, "%d", &tmp))
11837     {
11838       next_index = tmp;
11839       goto out;
11840     }
11841
11842   return 0;
11843
11844 out:
11845   *miss_next_indexp = next_index;
11846   return 1;
11847 }
11848
11849 uword
11850 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11851 {
11852   u32 *r = va_arg (*args, u32 *);
11853
11854   if (unformat (input, "conform-color"))
11855     *r = POLICE_CONFORM;
11856   else if (unformat (input, "exceed-color"))
11857     *r = POLICE_EXCEED;
11858   else
11859     return 0;
11860
11861   return 1;
11862 }
11863
11864 static int
11865 api_classify_add_del_table (vat_main_t * vam)
11866 {
11867   unformat_input_t *i = vam->input;
11868   vl_api_classify_add_del_table_t *mp;
11869
11870   u32 nbuckets = 2;
11871   u32 skip = ~0;
11872   u32 match = ~0;
11873   int is_add = 1;
11874   int del_chain = 0;
11875   u32 table_index = ~0;
11876   u32 next_table_index = ~0;
11877   u32 miss_next_index = ~0;
11878   u32 memory_size = 32 << 20;
11879   u8 *mask = 0;
11880   u32 current_data_flag = 0;
11881   int current_data_offset = 0;
11882   int ret;
11883
11884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11885     {
11886       if (unformat (i, "del"))
11887         is_add = 0;
11888       else if (unformat (i, "del-chain"))
11889         {
11890           is_add = 0;
11891           del_chain = 1;
11892         }
11893       else if (unformat (i, "buckets %d", &nbuckets))
11894         ;
11895       else if (unformat (i, "memory_size %d", &memory_size))
11896         ;
11897       else if (unformat (i, "skip %d", &skip))
11898         ;
11899       else if (unformat (i, "match %d", &match))
11900         ;
11901       else if (unformat (i, "table %d", &table_index))
11902         ;
11903       else if (unformat (i, "mask %U", unformat_classify_mask,
11904                          &mask, &skip, &match))
11905         ;
11906       else if (unformat (i, "next-table %d", &next_table_index))
11907         ;
11908       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11909                          &miss_next_index))
11910         ;
11911       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11912                          &miss_next_index))
11913         ;
11914       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11915                          &miss_next_index))
11916         ;
11917       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11918         ;
11919       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11920         ;
11921       else
11922         break;
11923     }
11924
11925   if (is_add && mask == 0)
11926     {
11927       errmsg ("Mask required");
11928       return -99;
11929     }
11930
11931   if (is_add && skip == ~0)
11932     {
11933       errmsg ("skip count required");
11934       return -99;
11935     }
11936
11937   if (is_add && match == ~0)
11938     {
11939       errmsg ("match count required");
11940       return -99;
11941     }
11942
11943   if (!is_add && table_index == ~0)
11944     {
11945       errmsg ("table index required for delete");
11946       return -99;
11947     }
11948
11949   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11950
11951   mp->is_add = is_add;
11952   mp->del_chain = del_chain;
11953   mp->table_index = ntohl (table_index);
11954   mp->nbuckets = ntohl (nbuckets);
11955   mp->memory_size = ntohl (memory_size);
11956   mp->skip_n_vectors = ntohl (skip);
11957   mp->match_n_vectors = ntohl (match);
11958   mp->next_table_index = ntohl (next_table_index);
11959   mp->miss_next_index = ntohl (miss_next_index);
11960   mp->current_data_flag = ntohl (current_data_flag);
11961   mp->current_data_offset = ntohl (current_data_offset);
11962   mp->mask_len = ntohl (vec_len (mask));
11963   clib_memcpy (mp->mask, mask, vec_len (mask));
11964
11965   vec_free (mask);
11966
11967   S (mp);
11968   W (ret);
11969   return ret;
11970 }
11971
11972 #if VPP_API_TEST_BUILTIN == 0
11973 uword
11974 unformat_l4_match (unformat_input_t * input, va_list * args)
11975 {
11976   u8 **matchp = va_arg (*args, u8 **);
11977
11978   u8 *proto_header = 0;
11979   int src_port = 0;
11980   int dst_port = 0;
11981
11982   tcpudp_header_t h;
11983
11984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11985     {
11986       if (unformat (input, "src_port %d", &src_port))
11987         ;
11988       else if (unformat (input, "dst_port %d", &dst_port))
11989         ;
11990       else
11991         return 0;
11992     }
11993
11994   h.src_port = clib_host_to_net_u16 (src_port);
11995   h.dst_port = clib_host_to_net_u16 (dst_port);
11996   vec_validate (proto_header, sizeof (h) - 1);
11997   memcpy (proto_header, &h, sizeof (h));
11998
11999   *matchp = proto_header;
12000
12001   return 1;
12002 }
12003
12004 uword
12005 unformat_ip4_match (unformat_input_t * input, va_list * args)
12006 {
12007   u8 **matchp = va_arg (*args, u8 **);
12008   u8 *match = 0;
12009   ip4_header_t *ip;
12010   int version = 0;
12011   u32 version_val;
12012   int hdr_length = 0;
12013   u32 hdr_length_val;
12014   int src = 0, dst = 0;
12015   ip4_address_t src_val, dst_val;
12016   int proto = 0;
12017   u32 proto_val;
12018   int tos = 0;
12019   u32 tos_val;
12020   int length = 0;
12021   u32 length_val;
12022   int fragment_id = 0;
12023   u32 fragment_id_val;
12024   int ttl = 0;
12025   int ttl_val;
12026   int checksum = 0;
12027   u32 checksum_val;
12028
12029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12030     {
12031       if (unformat (input, "version %d", &version_val))
12032         version = 1;
12033       else if (unformat (input, "hdr_length %d", &hdr_length_val))
12034         hdr_length = 1;
12035       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
12036         src = 1;
12037       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
12038         dst = 1;
12039       else if (unformat (input, "proto %d", &proto_val))
12040         proto = 1;
12041       else if (unformat (input, "tos %d", &tos_val))
12042         tos = 1;
12043       else if (unformat (input, "length %d", &length_val))
12044         length = 1;
12045       else if (unformat (input, "fragment_id %d", &fragment_id_val))
12046         fragment_id = 1;
12047       else if (unformat (input, "ttl %d", &ttl_val))
12048         ttl = 1;
12049       else if (unformat (input, "checksum %d", &checksum_val))
12050         checksum = 1;
12051       else
12052         break;
12053     }
12054
12055   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
12056       + ttl + checksum == 0)
12057     return 0;
12058
12059   /*
12060    * Aligned because we use the real comparison functions
12061    */
12062   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12063
12064   ip = (ip4_header_t *) match;
12065
12066   /* These are realistically matched in practice */
12067   if (src)
12068     ip->src_address.as_u32 = src_val.as_u32;
12069
12070   if (dst)
12071     ip->dst_address.as_u32 = dst_val.as_u32;
12072
12073   if (proto)
12074     ip->protocol = proto_val;
12075
12076
12077   /* These are not, but they're included for completeness */
12078   if (version)
12079     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
12080
12081   if (hdr_length)
12082     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
12083
12084   if (tos)
12085     ip->tos = tos_val;
12086
12087   if (length)
12088     ip->length = clib_host_to_net_u16 (length_val);
12089
12090   if (ttl)
12091     ip->ttl = ttl_val;
12092
12093   if (checksum)
12094     ip->checksum = clib_host_to_net_u16 (checksum_val);
12095
12096   *matchp = match;
12097   return 1;
12098 }
12099
12100 uword
12101 unformat_ip6_match (unformat_input_t * input, va_list * args)
12102 {
12103   u8 **matchp = va_arg (*args, u8 **);
12104   u8 *match = 0;
12105   ip6_header_t *ip;
12106   int version = 0;
12107   u32 version_val;
12108   u8 traffic_class = 0;
12109   u32 traffic_class_val = 0;
12110   u8 flow_label = 0;
12111   u8 flow_label_val;
12112   int src = 0, dst = 0;
12113   ip6_address_t src_val, dst_val;
12114   int proto = 0;
12115   u32 proto_val;
12116   int payload_length = 0;
12117   u32 payload_length_val;
12118   int hop_limit = 0;
12119   int hop_limit_val;
12120   u32 ip_version_traffic_class_and_flow_label;
12121
12122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12123     {
12124       if (unformat (input, "version %d", &version_val))
12125         version = 1;
12126       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12127         traffic_class = 1;
12128       else if (unformat (input, "flow_label %d", &flow_label_val))
12129         flow_label = 1;
12130       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12131         src = 1;
12132       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12133         dst = 1;
12134       else if (unformat (input, "proto %d", &proto_val))
12135         proto = 1;
12136       else if (unformat (input, "payload_length %d", &payload_length_val))
12137         payload_length = 1;
12138       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12139         hop_limit = 1;
12140       else
12141         break;
12142     }
12143
12144   if (version + traffic_class + flow_label + src + dst + proto +
12145       payload_length + hop_limit == 0)
12146     return 0;
12147
12148   /*
12149    * Aligned because we use the real comparison functions
12150    */
12151   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12152
12153   ip = (ip6_header_t *) match;
12154
12155   if (src)
12156     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12157
12158   if (dst)
12159     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12160
12161   if (proto)
12162     ip->protocol = proto_val;
12163
12164   ip_version_traffic_class_and_flow_label = 0;
12165
12166   if (version)
12167     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12168
12169   if (traffic_class)
12170     ip_version_traffic_class_and_flow_label |=
12171       (traffic_class_val & 0xFF) << 20;
12172
12173   if (flow_label)
12174     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12175
12176   ip->ip_version_traffic_class_and_flow_label =
12177     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12178
12179   if (payload_length)
12180     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12181
12182   if (hop_limit)
12183     ip->hop_limit = hop_limit_val;
12184
12185   *matchp = match;
12186   return 1;
12187 }
12188
12189 uword
12190 unformat_l3_match (unformat_input_t * input, va_list * args)
12191 {
12192   u8 **matchp = va_arg (*args, u8 **);
12193
12194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12195     {
12196       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12197         return 1;
12198       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12199         return 1;
12200       else
12201         break;
12202     }
12203   return 0;
12204 }
12205
12206 uword
12207 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12208 {
12209   u8 *tagp = va_arg (*args, u8 *);
12210   u32 tag;
12211
12212   if (unformat (input, "%d", &tag))
12213     {
12214       tagp[0] = (tag >> 8) & 0x0F;
12215       tagp[1] = tag & 0xFF;
12216       return 1;
12217     }
12218
12219   return 0;
12220 }
12221
12222 uword
12223 unformat_l2_match (unformat_input_t * input, va_list * args)
12224 {
12225   u8 **matchp = va_arg (*args, u8 **);
12226   u8 *match = 0;
12227   u8 src = 0;
12228   u8 src_val[6];
12229   u8 dst = 0;
12230   u8 dst_val[6];
12231   u8 proto = 0;
12232   u16 proto_val;
12233   u8 tag1 = 0;
12234   u8 tag1_val[2];
12235   u8 tag2 = 0;
12236   u8 tag2_val[2];
12237   int len = 14;
12238   u8 ignore_tag1 = 0;
12239   u8 ignore_tag2 = 0;
12240   u8 cos1 = 0;
12241   u8 cos2 = 0;
12242   u32 cos1_val = 0;
12243   u32 cos2_val = 0;
12244
12245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12246     {
12247       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12248         src = 1;
12249       else
12250         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12251         dst = 1;
12252       else if (unformat (input, "proto %U",
12253                          unformat_ethernet_type_host_byte_order, &proto_val))
12254         proto = 1;
12255       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12256         tag1 = 1;
12257       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12258         tag2 = 1;
12259       else if (unformat (input, "ignore-tag1"))
12260         ignore_tag1 = 1;
12261       else if (unformat (input, "ignore-tag2"))
12262         ignore_tag2 = 1;
12263       else if (unformat (input, "cos1 %d", &cos1_val))
12264         cos1 = 1;
12265       else if (unformat (input, "cos2 %d", &cos2_val))
12266         cos2 = 1;
12267       else
12268         break;
12269     }
12270   if ((src + dst + proto + tag1 + tag2 +
12271        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12272     return 0;
12273
12274   if (tag1 || ignore_tag1 || cos1)
12275     len = 18;
12276   if (tag2 || ignore_tag2 || cos2)
12277     len = 22;
12278
12279   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12280
12281   if (dst)
12282     clib_memcpy (match, dst_val, 6);
12283
12284   if (src)
12285     clib_memcpy (match + 6, src_val, 6);
12286
12287   if (tag2)
12288     {
12289       /* inner vlan tag */
12290       match[19] = tag2_val[1];
12291       match[18] = tag2_val[0];
12292       if (cos2)
12293         match[18] |= (cos2_val & 0x7) << 5;
12294       if (proto)
12295         {
12296           match[21] = proto_val & 0xff;
12297           match[20] = proto_val >> 8;
12298         }
12299       if (tag1)
12300         {
12301           match[15] = tag1_val[1];
12302           match[14] = tag1_val[0];
12303         }
12304       if (cos1)
12305         match[14] |= (cos1_val & 0x7) << 5;
12306       *matchp = match;
12307       return 1;
12308     }
12309   if (tag1)
12310     {
12311       match[15] = tag1_val[1];
12312       match[14] = tag1_val[0];
12313       if (proto)
12314         {
12315           match[17] = proto_val & 0xff;
12316           match[16] = proto_val >> 8;
12317         }
12318       if (cos1)
12319         match[14] |= (cos1_val & 0x7) << 5;
12320
12321       *matchp = match;
12322       return 1;
12323     }
12324   if (cos2)
12325     match[18] |= (cos2_val & 0x7) << 5;
12326   if (cos1)
12327     match[14] |= (cos1_val & 0x7) << 5;
12328   if (proto)
12329     {
12330       match[13] = proto_val & 0xff;
12331       match[12] = proto_val >> 8;
12332     }
12333
12334   *matchp = match;
12335   return 1;
12336 }
12337
12338 uword
12339 unformat_qos_source (unformat_input_t * input, va_list * args)
12340 {
12341   int *qs = va_arg (*args, int *);
12342
12343   if (unformat (input, "ip"))
12344     *qs = QOS_SOURCE_IP;
12345   else if (unformat (input, "mpls"))
12346     *qs = QOS_SOURCE_MPLS;
12347   else if (unformat (input, "ext"))
12348     *qs = QOS_SOURCE_EXT;
12349   else if (unformat (input, "vlan"))
12350     *qs = QOS_SOURCE_VLAN;
12351   else
12352     return 0;
12353
12354   return 1;
12355 }
12356 #endif
12357
12358 uword
12359 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12360 {
12361   u8 **matchp = va_arg (*args, u8 **);
12362   u32 skip_n_vectors = va_arg (*args, u32);
12363   u32 match_n_vectors = va_arg (*args, u32);
12364
12365   u8 *match = 0;
12366   u8 *l2 = 0;
12367   u8 *l3 = 0;
12368   u8 *l4 = 0;
12369
12370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12371     {
12372       if (unformat (input, "hex %U", unformat_hex_string, &match))
12373         ;
12374       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12375         ;
12376       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12377         ;
12378       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12379         ;
12380       else
12381         break;
12382     }
12383
12384   if (l4 && !l3)
12385     {
12386       vec_free (match);
12387       vec_free (l2);
12388       vec_free (l4);
12389       return 0;
12390     }
12391
12392   if (match || l2 || l3 || l4)
12393     {
12394       if (l2 || l3 || l4)
12395         {
12396           /* "Win a free Ethernet header in every packet" */
12397           if (l2 == 0)
12398             vec_validate_aligned (l2, 13, sizeof (u32x4));
12399           match = l2;
12400           if (vec_len (l3))
12401             {
12402               vec_append_aligned (match, l3, sizeof (u32x4));
12403               vec_free (l3);
12404             }
12405           if (vec_len (l4))
12406             {
12407               vec_append_aligned (match, l4, sizeof (u32x4));
12408               vec_free (l4);
12409             }
12410         }
12411
12412       /* Make sure the vector is big enough even if key is all 0's */
12413       vec_validate_aligned
12414         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12415          sizeof (u32x4));
12416
12417       /* Set size, include skipped vectors */
12418       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12419
12420       *matchp = match;
12421
12422       return 1;
12423     }
12424
12425   return 0;
12426 }
12427
12428 static int
12429 api_classify_add_del_session (vat_main_t * vam)
12430 {
12431   unformat_input_t *i = vam->input;
12432   vl_api_classify_add_del_session_t *mp;
12433   int is_add = 1;
12434   u32 table_index = ~0;
12435   u32 hit_next_index = ~0;
12436   u32 opaque_index = ~0;
12437   u8 *match = 0;
12438   i32 advance = 0;
12439   u32 skip_n_vectors = 0;
12440   u32 match_n_vectors = 0;
12441   u32 action = 0;
12442   u32 metadata = 0;
12443   int ret;
12444
12445   /*
12446    * Warning: you have to supply skip_n and match_n
12447    * because the API client cant simply look at the classify
12448    * table object.
12449    */
12450
12451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12452     {
12453       if (unformat (i, "del"))
12454         is_add = 0;
12455       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12456                          &hit_next_index))
12457         ;
12458       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12459                          &hit_next_index))
12460         ;
12461       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12462                          &hit_next_index))
12463         ;
12464       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12465         ;
12466       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12467         ;
12468       else if (unformat (i, "opaque-index %d", &opaque_index))
12469         ;
12470       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12471         ;
12472       else if (unformat (i, "match_n %d", &match_n_vectors))
12473         ;
12474       else if (unformat (i, "match %U", api_unformat_classify_match,
12475                          &match, skip_n_vectors, match_n_vectors))
12476         ;
12477       else if (unformat (i, "advance %d", &advance))
12478         ;
12479       else if (unformat (i, "table-index %d", &table_index))
12480         ;
12481       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12482         action = 1;
12483       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12484         action = 2;
12485       else if (unformat (i, "action %d", &action))
12486         ;
12487       else if (unformat (i, "metadata %d", &metadata))
12488         ;
12489       else
12490         break;
12491     }
12492
12493   if (table_index == ~0)
12494     {
12495       errmsg ("Table index required");
12496       return -99;
12497     }
12498
12499   if (is_add && match == 0)
12500     {
12501       errmsg ("Match value required");
12502       return -99;
12503     }
12504
12505   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12506
12507   mp->is_add = is_add;
12508   mp->table_index = ntohl (table_index);
12509   mp->hit_next_index = ntohl (hit_next_index);
12510   mp->opaque_index = ntohl (opaque_index);
12511   mp->advance = ntohl (advance);
12512   mp->action = action;
12513   mp->metadata = ntohl (metadata);
12514   mp->match_len = ntohl (vec_len (match));
12515   clib_memcpy (mp->match, match, vec_len (match));
12516   vec_free (match);
12517
12518   S (mp);
12519   W (ret);
12520   return ret;
12521 }
12522
12523 static int
12524 api_classify_set_interface_ip_table (vat_main_t * vam)
12525 {
12526   unformat_input_t *i = vam->input;
12527   vl_api_classify_set_interface_ip_table_t *mp;
12528   u32 sw_if_index;
12529   int sw_if_index_set;
12530   u32 table_index = ~0;
12531   u8 is_ipv6 = 0;
12532   int ret;
12533
12534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12535     {
12536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12537         sw_if_index_set = 1;
12538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12539         sw_if_index_set = 1;
12540       else if (unformat (i, "table %d", &table_index))
12541         ;
12542       else
12543         {
12544           clib_warning ("parse error '%U'", format_unformat_error, i);
12545           return -99;
12546         }
12547     }
12548
12549   if (sw_if_index_set == 0)
12550     {
12551       errmsg ("missing interface name or sw_if_index");
12552       return -99;
12553     }
12554
12555
12556   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12557
12558   mp->sw_if_index = ntohl (sw_if_index);
12559   mp->table_index = ntohl (table_index);
12560   mp->is_ipv6 = is_ipv6;
12561
12562   S (mp);
12563   W (ret);
12564   return ret;
12565 }
12566
12567 static int
12568 api_classify_set_interface_l2_tables (vat_main_t * vam)
12569 {
12570   unformat_input_t *i = vam->input;
12571   vl_api_classify_set_interface_l2_tables_t *mp;
12572   u32 sw_if_index;
12573   int sw_if_index_set;
12574   u32 ip4_table_index = ~0;
12575   u32 ip6_table_index = ~0;
12576   u32 other_table_index = ~0;
12577   u32 is_input = 1;
12578   int ret;
12579
12580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12581     {
12582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12583         sw_if_index_set = 1;
12584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12585         sw_if_index_set = 1;
12586       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12587         ;
12588       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12589         ;
12590       else if (unformat (i, "other-table %d", &other_table_index))
12591         ;
12592       else if (unformat (i, "is-input %d", &is_input))
12593         ;
12594       else
12595         {
12596           clib_warning ("parse error '%U'", format_unformat_error, i);
12597           return -99;
12598         }
12599     }
12600
12601   if (sw_if_index_set == 0)
12602     {
12603       errmsg ("missing interface name or sw_if_index");
12604       return -99;
12605     }
12606
12607
12608   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12609
12610   mp->sw_if_index = ntohl (sw_if_index);
12611   mp->ip4_table_index = ntohl (ip4_table_index);
12612   mp->ip6_table_index = ntohl (ip6_table_index);
12613   mp->other_table_index = ntohl (other_table_index);
12614   mp->is_input = (u8) is_input;
12615
12616   S (mp);
12617   W (ret);
12618   return ret;
12619 }
12620
12621 static int
12622 api_set_ipfix_exporter (vat_main_t * vam)
12623 {
12624   unformat_input_t *i = vam->input;
12625   vl_api_set_ipfix_exporter_t *mp;
12626   ip4_address_t collector_address;
12627   u8 collector_address_set = 0;
12628   u32 collector_port = ~0;
12629   ip4_address_t src_address;
12630   u8 src_address_set = 0;
12631   u32 vrf_id = ~0;
12632   u32 path_mtu = ~0;
12633   u32 template_interval = ~0;
12634   u8 udp_checksum = 0;
12635   int ret;
12636
12637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12638     {
12639       if (unformat (i, "collector_address %U", unformat_ip4_address,
12640                     &collector_address))
12641         collector_address_set = 1;
12642       else if (unformat (i, "collector_port %d", &collector_port))
12643         ;
12644       else if (unformat (i, "src_address %U", unformat_ip4_address,
12645                          &src_address))
12646         src_address_set = 1;
12647       else if (unformat (i, "vrf_id %d", &vrf_id))
12648         ;
12649       else if (unformat (i, "path_mtu %d", &path_mtu))
12650         ;
12651       else if (unformat (i, "template_interval %d", &template_interval))
12652         ;
12653       else if (unformat (i, "udp_checksum"))
12654         udp_checksum = 1;
12655       else
12656         break;
12657     }
12658
12659   if (collector_address_set == 0)
12660     {
12661       errmsg ("collector_address required");
12662       return -99;
12663     }
12664
12665   if (src_address_set == 0)
12666     {
12667       errmsg ("src_address required");
12668       return -99;
12669     }
12670
12671   M (SET_IPFIX_EXPORTER, mp);
12672
12673   memcpy (mp->collector_address, collector_address.data,
12674           sizeof (collector_address.data));
12675   mp->collector_port = htons ((u16) collector_port);
12676   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12677   mp->vrf_id = htonl (vrf_id);
12678   mp->path_mtu = htonl (path_mtu);
12679   mp->template_interval = htonl (template_interval);
12680   mp->udp_checksum = udp_checksum;
12681
12682   S (mp);
12683   W (ret);
12684   return ret;
12685 }
12686
12687 static int
12688 api_set_ipfix_classify_stream (vat_main_t * vam)
12689 {
12690   unformat_input_t *i = vam->input;
12691   vl_api_set_ipfix_classify_stream_t *mp;
12692   u32 domain_id = 0;
12693   u32 src_port = UDP_DST_PORT_ipfix;
12694   int ret;
12695
12696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12697     {
12698       if (unformat (i, "domain %d", &domain_id))
12699         ;
12700       else if (unformat (i, "src_port %d", &src_port))
12701         ;
12702       else
12703         {
12704           errmsg ("unknown input `%U'", format_unformat_error, i);
12705           return -99;
12706         }
12707     }
12708
12709   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12710
12711   mp->domain_id = htonl (domain_id);
12712   mp->src_port = htons ((u16) src_port);
12713
12714   S (mp);
12715   W (ret);
12716   return ret;
12717 }
12718
12719 static int
12720 api_ipfix_classify_table_add_del (vat_main_t * vam)
12721 {
12722   unformat_input_t *i = vam->input;
12723   vl_api_ipfix_classify_table_add_del_t *mp;
12724   int is_add = -1;
12725   u32 classify_table_index = ~0;
12726   u8 ip_version = 0;
12727   u8 transport_protocol = 255;
12728   int ret;
12729
12730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12731     {
12732       if (unformat (i, "add"))
12733         is_add = 1;
12734       else if (unformat (i, "del"))
12735         is_add = 0;
12736       else if (unformat (i, "table %d", &classify_table_index))
12737         ;
12738       else if (unformat (i, "ip4"))
12739         ip_version = 4;
12740       else if (unformat (i, "ip6"))
12741         ip_version = 6;
12742       else if (unformat (i, "tcp"))
12743         transport_protocol = 6;
12744       else if (unformat (i, "udp"))
12745         transport_protocol = 17;
12746       else
12747         {
12748           errmsg ("unknown input `%U'", format_unformat_error, i);
12749           return -99;
12750         }
12751     }
12752
12753   if (is_add == -1)
12754     {
12755       errmsg ("expecting: add|del");
12756       return -99;
12757     }
12758   if (classify_table_index == ~0)
12759     {
12760       errmsg ("classifier table not specified");
12761       return -99;
12762     }
12763   if (ip_version == 0)
12764     {
12765       errmsg ("IP version not specified");
12766       return -99;
12767     }
12768
12769   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12770
12771   mp->is_add = is_add;
12772   mp->table_id = htonl (classify_table_index);
12773   mp->ip_version = ip_version;
12774   mp->transport_protocol = transport_protocol;
12775
12776   S (mp);
12777   W (ret);
12778   return ret;
12779 }
12780
12781 static int
12782 api_get_node_index (vat_main_t * vam)
12783 {
12784   unformat_input_t *i = vam->input;
12785   vl_api_get_node_index_t *mp;
12786   u8 *name = 0;
12787   int ret;
12788
12789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12790     {
12791       if (unformat (i, "node %s", &name))
12792         ;
12793       else
12794         break;
12795     }
12796   if (name == 0)
12797     {
12798       errmsg ("node name required");
12799       return -99;
12800     }
12801   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12802     {
12803       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12804       return -99;
12805     }
12806
12807   M (GET_NODE_INDEX, mp);
12808   clib_memcpy (mp->node_name, name, vec_len (name));
12809   vec_free (name);
12810
12811   S (mp);
12812   W (ret);
12813   return ret;
12814 }
12815
12816 static int
12817 api_get_next_index (vat_main_t * vam)
12818 {
12819   unformat_input_t *i = vam->input;
12820   vl_api_get_next_index_t *mp;
12821   u8 *node_name = 0, *next_node_name = 0;
12822   int ret;
12823
12824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12825     {
12826       if (unformat (i, "node-name %s", &node_name))
12827         ;
12828       else if (unformat (i, "next-node-name %s", &next_node_name))
12829         break;
12830     }
12831
12832   if (node_name == 0)
12833     {
12834       errmsg ("node name required");
12835       return -99;
12836     }
12837   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12838     {
12839       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12840       return -99;
12841     }
12842
12843   if (next_node_name == 0)
12844     {
12845       errmsg ("next node name required");
12846       return -99;
12847     }
12848   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12849     {
12850       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12851       return -99;
12852     }
12853
12854   M (GET_NEXT_INDEX, mp);
12855   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12856   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12857   vec_free (node_name);
12858   vec_free (next_node_name);
12859
12860   S (mp);
12861   W (ret);
12862   return ret;
12863 }
12864
12865 static int
12866 api_add_node_next (vat_main_t * vam)
12867 {
12868   unformat_input_t *i = vam->input;
12869   vl_api_add_node_next_t *mp;
12870   u8 *name = 0;
12871   u8 *next = 0;
12872   int ret;
12873
12874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12875     {
12876       if (unformat (i, "node %s", &name))
12877         ;
12878       else if (unformat (i, "next %s", &next))
12879         ;
12880       else
12881         break;
12882     }
12883   if (name == 0)
12884     {
12885       errmsg ("node name required");
12886       return -99;
12887     }
12888   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12889     {
12890       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12891       return -99;
12892     }
12893   if (next == 0)
12894     {
12895       errmsg ("next node required");
12896       return -99;
12897     }
12898   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12899     {
12900       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12901       return -99;
12902     }
12903
12904   M (ADD_NODE_NEXT, mp);
12905   clib_memcpy (mp->node_name, name, vec_len (name));
12906   clib_memcpy (mp->next_name, next, vec_len (next));
12907   vec_free (name);
12908   vec_free (next);
12909
12910   S (mp);
12911   W (ret);
12912   return ret;
12913 }
12914
12915 static int
12916 api_l2tpv3_create_tunnel (vat_main_t * vam)
12917 {
12918   unformat_input_t *i = vam->input;
12919   ip6_address_t client_address, our_address;
12920   int client_address_set = 0;
12921   int our_address_set = 0;
12922   u32 local_session_id = 0;
12923   u32 remote_session_id = 0;
12924   u64 local_cookie = 0;
12925   u64 remote_cookie = 0;
12926   u8 l2_sublayer_present = 0;
12927   vl_api_l2tpv3_create_tunnel_t *mp;
12928   int ret;
12929
12930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12931     {
12932       if (unformat (i, "client_address %U", unformat_ip6_address,
12933                     &client_address))
12934         client_address_set = 1;
12935       else if (unformat (i, "our_address %U", unformat_ip6_address,
12936                          &our_address))
12937         our_address_set = 1;
12938       else if (unformat (i, "local_session_id %d", &local_session_id))
12939         ;
12940       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12941         ;
12942       else if (unformat (i, "local_cookie %lld", &local_cookie))
12943         ;
12944       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12945         ;
12946       else if (unformat (i, "l2-sublayer-present"))
12947         l2_sublayer_present = 1;
12948       else
12949         break;
12950     }
12951
12952   if (client_address_set == 0)
12953     {
12954       errmsg ("client_address required");
12955       return -99;
12956     }
12957
12958   if (our_address_set == 0)
12959     {
12960       errmsg ("our_address required");
12961       return -99;
12962     }
12963
12964   M (L2TPV3_CREATE_TUNNEL, mp);
12965
12966   clib_memcpy (mp->client_address, client_address.as_u8,
12967                sizeof (mp->client_address));
12968
12969   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12970
12971   mp->local_session_id = ntohl (local_session_id);
12972   mp->remote_session_id = ntohl (remote_session_id);
12973   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12974   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12975   mp->l2_sublayer_present = l2_sublayer_present;
12976   mp->is_ipv6 = 1;
12977
12978   S (mp);
12979   W (ret);
12980   return ret;
12981 }
12982
12983 static int
12984 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12985 {
12986   unformat_input_t *i = vam->input;
12987   u32 sw_if_index;
12988   u8 sw_if_index_set = 0;
12989   u64 new_local_cookie = 0;
12990   u64 new_remote_cookie = 0;
12991   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12992   int ret;
12993
12994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12995     {
12996       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12997         sw_if_index_set = 1;
12998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12999         sw_if_index_set = 1;
13000       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
13001         ;
13002       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
13003         ;
13004       else
13005         break;
13006     }
13007
13008   if (sw_if_index_set == 0)
13009     {
13010       errmsg ("missing interface name or sw_if_index");
13011       return -99;
13012     }
13013
13014   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
13015
13016   mp->sw_if_index = ntohl (sw_if_index);
13017   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
13018   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
13019
13020   S (mp);
13021   W (ret);
13022   return ret;
13023 }
13024
13025 static int
13026 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
13027 {
13028   unformat_input_t *i = vam->input;
13029   vl_api_l2tpv3_interface_enable_disable_t *mp;
13030   u32 sw_if_index;
13031   u8 sw_if_index_set = 0;
13032   u8 enable_disable = 1;
13033   int ret;
13034
13035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13036     {
13037       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13038         sw_if_index_set = 1;
13039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13040         sw_if_index_set = 1;
13041       else if (unformat (i, "enable"))
13042         enable_disable = 1;
13043       else if (unformat (i, "disable"))
13044         enable_disable = 0;
13045       else
13046         break;
13047     }
13048
13049   if (sw_if_index_set == 0)
13050     {
13051       errmsg ("missing interface name or sw_if_index");
13052       return -99;
13053     }
13054
13055   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
13056
13057   mp->sw_if_index = ntohl (sw_if_index);
13058   mp->enable_disable = enable_disable;
13059
13060   S (mp);
13061   W (ret);
13062   return ret;
13063 }
13064
13065 static int
13066 api_l2tpv3_set_lookup_key (vat_main_t * vam)
13067 {
13068   unformat_input_t *i = vam->input;
13069   vl_api_l2tpv3_set_lookup_key_t *mp;
13070   u8 key = ~0;
13071   int ret;
13072
13073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13074     {
13075       if (unformat (i, "lookup_v6_src"))
13076         key = L2T_LOOKUP_SRC_ADDRESS;
13077       else if (unformat (i, "lookup_v6_dst"))
13078         key = L2T_LOOKUP_DST_ADDRESS;
13079       else if (unformat (i, "lookup_session_id"))
13080         key = L2T_LOOKUP_SESSION_ID;
13081       else
13082         break;
13083     }
13084
13085   if (key == (u8) ~ 0)
13086     {
13087       errmsg ("l2tp session lookup key unset");
13088       return -99;
13089     }
13090
13091   M (L2TPV3_SET_LOOKUP_KEY, mp);
13092
13093   mp->key = key;
13094
13095   S (mp);
13096   W (ret);
13097   return ret;
13098 }
13099
13100 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
13101   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13102 {
13103   vat_main_t *vam = &vat_main;
13104
13105   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
13106          format_ip6_address, mp->our_address,
13107          format_ip6_address, mp->client_address,
13108          clib_net_to_host_u32 (mp->sw_if_index));
13109
13110   print (vam->ofp,
13111          "   local cookies %016llx %016llx remote cookie %016llx",
13112          clib_net_to_host_u64 (mp->local_cookie[0]),
13113          clib_net_to_host_u64 (mp->local_cookie[1]),
13114          clib_net_to_host_u64 (mp->remote_cookie));
13115
13116   print (vam->ofp, "   local session-id %d remote session-id %d",
13117          clib_net_to_host_u32 (mp->local_session_id),
13118          clib_net_to_host_u32 (mp->remote_session_id));
13119
13120   print (vam->ofp, "   l2 specific sublayer %s\n",
13121          mp->l2_sublayer_present ? "preset" : "absent");
13122
13123 }
13124
13125 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13126   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13127 {
13128   vat_main_t *vam = &vat_main;
13129   vat_json_node_t *node = NULL;
13130   struct in6_addr addr;
13131
13132   if (VAT_JSON_ARRAY != vam->json_tree.type)
13133     {
13134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13135       vat_json_init_array (&vam->json_tree);
13136     }
13137   node = vat_json_array_add (&vam->json_tree);
13138
13139   vat_json_init_object (node);
13140
13141   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13142   vat_json_object_add_ip6 (node, "our_address", addr);
13143   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13144   vat_json_object_add_ip6 (node, "client_address", addr);
13145
13146   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13147   vat_json_init_array (lc);
13148   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13149   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13150   vat_json_object_add_uint (node, "remote_cookie",
13151                             clib_net_to_host_u64 (mp->remote_cookie));
13152
13153   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13154   vat_json_object_add_uint (node, "local_session_id",
13155                             clib_net_to_host_u32 (mp->local_session_id));
13156   vat_json_object_add_uint (node, "remote_session_id",
13157                             clib_net_to_host_u32 (mp->remote_session_id));
13158   vat_json_object_add_string_copy (node, "l2_sublayer",
13159                                    mp->l2_sublayer_present ? (u8 *) "present"
13160                                    : (u8 *) "absent");
13161 }
13162
13163 static int
13164 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13165 {
13166   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13167   vl_api_control_ping_t *mp_ping;
13168   int ret;
13169
13170   /* Get list of l2tpv3-tunnel interfaces */
13171   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13172   S (mp);
13173
13174   /* Use a control ping for synchronization */
13175   MPING (CONTROL_PING, mp_ping);
13176   S (mp_ping);
13177
13178   W (ret);
13179   return ret;
13180 }
13181
13182
13183 static void vl_api_sw_interface_tap_details_t_handler
13184   (vl_api_sw_interface_tap_details_t * mp)
13185 {
13186   vat_main_t *vam = &vat_main;
13187
13188   print (vam->ofp, "%-16s %d",
13189          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13190 }
13191
13192 static void vl_api_sw_interface_tap_details_t_handler_json
13193   (vl_api_sw_interface_tap_details_t * mp)
13194 {
13195   vat_main_t *vam = &vat_main;
13196   vat_json_node_t *node = NULL;
13197
13198   if (VAT_JSON_ARRAY != vam->json_tree.type)
13199     {
13200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13201       vat_json_init_array (&vam->json_tree);
13202     }
13203   node = vat_json_array_add (&vam->json_tree);
13204
13205   vat_json_init_object (node);
13206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13207   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13208 }
13209
13210 static int
13211 api_sw_interface_tap_dump (vat_main_t * vam)
13212 {
13213   vl_api_sw_interface_tap_dump_t *mp;
13214   vl_api_control_ping_t *mp_ping;
13215   int ret;
13216
13217   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13218   /* Get list of tap interfaces */
13219   M (SW_INTERFACE_TAP_DUMP, mp);
13220   S (mp);
13221
13222   /* Use a control ping for synchronization */
13223   MPING (CONTROL_PING, mp_ping);
13224   S (mp_ping);
13225
13226   W (ret);
13227   return ret;
13228 }
13229
13230 static void vl_api_sw_interface_tap_v2_details_t_handler
13231   (vl_api_sw_interface_tap_v2_details_t * mp)
13232 {
13233   vat_main_t *vam = &vat_main;
13234
13235   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13236                     mp->host_ip4_prefix_len);
13237   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13238                     mp->host_ip6_prefix_len);
13239
13240   print (vam->ofp,
13241          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13242          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13243          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13244          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13245          mp->host_bridge, ip4, ip6);
13246
13247   vec_free (ip4);
13248   vec_free (ip6);
13249 }
13250
13251 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13252   (vl_api_sw_interface_tap_v2_details_t * mp)
13253 {
13254   vat_main_t *vam = &vat_main;
13255   vat_json_node_t *node = NULL;
13256
13257   if (VAT_JSON_ARRAY != vam->json_tree.type)
13258     {
13259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13260       vat_json_init_array (&vam->json_tree);
13261     }
13262   node = vat_json_array_add (&vam->json_tree);
13263
13264   vat_json_init_object (node);
13265   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13266   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13267   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13268   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13269   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13270   vat_json_object_add_string_copy (node, "host_mac_addr",
13271                                    format (0, "%U", format_ethernet_address,
13272                                            &mp->host_mac_addr));
13273   vat_json_object_add_string_copy (node, "host_namespace",
13274                                    mp->host_namespace);
13275   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13276   vat_json_object_add_string_copy (node, "host_ip4_addr",
13277                                    format (0, "%U/%d", format_ip4_address,
13278                                            mp->host_ip4_addr,
13279                                            mp->host_ip4_prefix_len));
13280   vat_json_object_add_string_copy (node, "host_ip6_addr",
13281                                    format (0, "%U/%d", format_ip6_address,
13282                                            mp->host_ip6_addr,
13283                                            mp->host_ip6_prefix_len));
13284
13285 }
13286
13287 static int
13288 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13289 {
13290   vl_api_sw_interface_tap_v2_dump_t *mp;
13291   vl_api_control_ping_t *mp_ping;
13292   int ret;
13293
13294   print (vam->ofp,
13295          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13296          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13297          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13298          "host_ip6_addr");
13299
13300   /* Get list of tap interfaces */
13301   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13302   S (mp);
13303
13304   /* Use a control ping for synchronization */
13305   MPING (CONTROL_PING, mp_ping);
13306   S (mp_ping);
13307
13308   W (ret);
13309   return ret;
13310 }
13311
13312 static int
13313 api_vxlan_offload_rx (vat_main_t * vam)
13314 {
13315   unformat_input_t *line_input = vam->input;
13316   vl_api_vxlan_offload_rx_t *mp;
13317   u32 hw_if_index = ~0, rx_if_index = ~0;
13318   u8 is_add = 1;
13319   int ret;
13320
13321   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13322     {
13323       if (unformat (line_input, "del"))
13324         is_add = 0;
13325       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13326                          &hw_if_index))
13327         ;
13328       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13329         ;
13330       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13331                          &rx_if_index))
13332         ;
13333       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13334         ;
13335       else
13336         {
13337           errmsg ("parse error '%U'", format_unformat_error, line_input);
13338           return -99;
13339         }
13340     }
13341
13342   if (hw_if_index == ~0)
13343     {
13344       errmsg ("no hw interface");
13345       return -99;
13346     }
13347
13348   if (rx_if_index == ~0)
13349     {
13350       errmsg ("no rx tunnel");
13351       return -99;
13352     }
13353
13354   M (VXLAN_OFFLOAD_RX, mp);
13355
13356   mp->hw_if_index = ntohl (hw_if_index);
13357   mp->sw_if_index = ntohl (rx_if_index);
13358   mp->enable = is_add;
13359
13360   S (mp);
13361   W (ret);
13362   return ret;
13363 }
13364
13365 static uword unformat_vxlan_decap_next
13366   (unformat_input_t * input, va_list * args)
13367 {
13368   u32 *result = va_arg (*args, u32 *);
13369   u32 tmp;
13370
13371   if (unformat (input, "l2"))
13372     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13373   else if (unformat (input, "%d", &tmp))
13374     *result = tmp;
13375   else
13376     return 0;
13377   return 1;
13378 }
13379
13380 static int
13381 api_vxlan_add_del_tunnel (vat_main_t * vam)
13382 {
13383   unformat_input_t *line_input = vam->input;
13384   vl_api_vxlan_add_del_tunnel_t *mp;
13385   ip46_address_t src, dst;
13386   u8 is_add = 1;
13387   u8 ipv4_set = 0, ipv6_set = 0;
13388   u8 src_set = 0;
13389   u8 dst_set = 0;
13390   u8 grp_set = 0;
13391   u32 instance = ~0;
13392   u32 mcast_sw_if_index = ~0;
13393   u32 encap_vrf_id = 0;
13394   u32 decap_next_index = ~0;
13395   u32 vni = 0;
13396   int ret;
13397
13398   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13399   clib_memset (&src, 0, sizeof src);
13400   clib_memset (&dst, 0, sizeof dst);
13401
13402   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13403     {
13404       if (unformat (line_input, "del"))
13405         is_add = 0;
13406       else if (unformat (line_input, "instance %d", &instance))
13407         ;
13408       else
13409         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13410         {
13411           ipv4_set = 1;
13412           src_set = 1;
13413         }
13414       else
13415         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13416         {
13417           ipv4_set = 1;
13418           dst_set = 1;
13419         }
13420       else
13421         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13422         {
13423           ipv6_set = 1;
13424           src_set = 1;
13425         }
13426       else
13427         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13428         {
13429           ipv6_set = 1;
13430           dst_set = 1;
13431         }
13432       else if (unformat (line_input, "group %U %U",
13433                          unformat_ip4_address, &dst.ip4,
13434                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13435         {
13436           grp_set = dst_set = 1;
13437           ipv4_set = 1;
13438         }
13439       else if (unformat (line_input, "group %U",
13440                          unformat_ip4_address, &dst.ip4))
13441         {
13442           grp_set = dst_set = 1;
13443           ipv4_set = 1;
13444         }
13445       else if (unformat (line_input, "group %U %U",
13446                          unformat_ip6_address, &dst.ip6,
13447                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13448         {
13449           grp_set = dst_set = 1;
13450           ipv6_set = 1;
13451         }
13452       else if (unformat (line_input, "group %U",
13453                          unformat_ip6_address, &dst.ip6))
13454         {
13455           grp_set = dst_set = 1;
13456           ipv6_set = 1;
13457         }
13458       else
13459         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13460         ;
13461       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13462         ;
13463       else if (unformat (line_input, "decap-next %U",
13464                          unformat_vxlan_decap_next, &decap_next_index))
13465         ;
13466       else if (unformat (line_input, "vni %d", &vni))
13467         ;
13468       else
13469         {
13470           errmsg ("parse error '%U'", format_unformat_error, line_input);
13471           return -99;
13472         }
13473     }
13474
13475   if (src_set == 0)
13476     {
13477       errmsg ("tunnel src address not specified");
13478       return -99;
13479     }
13480   if (dst_set == 0)
13481     {
13482       errmsg ("tunnel dst address not specified");
13483       return -99;
13484     }
13485
13486   if (grp_set && !ip46_address_is_multicast (&dst))
13487     {
13488       errmsg ("tunnel group address not multicast");
13489       return -99;
13490     }
13491   if (grp_set && mcast_sw_if_index == ~0)
13492     {
13493       errmsg ("tunnel nonexistent multicast device");
13494       return -99;
13495     }
13496   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13497     {
13498       errmsg ("tunnel dst address must be unicast");
13499       return -99;
13500     }
13501
13502
13503   if (ipv4_set && ipv6_set)
13504     {
13505       errmsg ("both IPv4 and IPv6 addresses specified");
13506       return -99;
13507     }
13508
13509   if ((vni == 0) || (vni >> 24))
13510     {
13511       errmsg ("vni not specified or out of range");
13512       return -99;
13513     }
13514
13515   M (VXLAN_ADD_DEL_TUNNEL, mp);
13516
13517   if (ipv6_set)
13518     {
13519       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13520       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13521     }
13522   else
13523     {
13524       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13525       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13526     }
13527
13528   mp->instance = htonl (instance);
13529   mp->encap_vrf_id = ntohl (encap_vrf_id);
13530   mp->decap_next_index = ntohl (decap_next_index);
13531   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13532   mp->vni = ntohl (vni);
13533   mp->is_add = is_add;
13534   mp->is_ipv6 = ipv6_set;
13535
13536   S (mp);
13537   W (ret);
13538   return ret;
13539 }
13540
13541 static void vl_api_vxlan_tunnel_details_t_handler
13542   (vl_api_vxlan_tunnel_details_t * mp)
13543 {
13544   vat_main_t *vam = &vat_main;
13545   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13546   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13547
13548   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13549          ntohl (mp->sw_if_index),
13550          ntohl (mp->instance),
13551          format_ip46_address, &src, IP46_TYPE_ANY,
13552          format_ip46_address, &dst, IP46_TYPE_ANY,
13553          ntohl (mp->encap_vrf_id),
13554          ntohl (mp->decap_next_index), ntohl (mp->vni),
13555          ntohl (mp->mcast_sw_if_index));
13556 }
13557
13558 static void vl_api_vxlan_tunnel_details_t_handler_json
13559   (vl_api_vxlan_tunnel_details_t * mp)
13560 {
13561   vat_main_t *vam = &vat_main;
13562   vat_json_node_t *node = NULL;
13563
13564   if (VAT_JSON_ARRAY != vam->json_tree.type)
13565     {
13566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13567       vat_json_init_array (&vam->json_tree);
13568     }
13569   node = vat_json_array_add (&vam->json_tree);
13570
13571   vat_json_init_object (node);
13572   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13573
13574   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13575
13576   if (mp->is_ipv6)
13577     {
13578       struct in6_addr ip6;
13579
13580       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13581       vat_json_object_add_ip6 (node, "src_address", ip6);
13582       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13583       vat_json_object_add_ip6 (node, "dst_address", ip6);
13584     }
13585   else
13586     {
13587       struct in_addr ip4;
13588
13589       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13590       vat_json_object_add_ip4 (node, "src_address", ip4);
13591       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13592       vat_json_object_add_ip4 (node, "dst_address", ip4);
13593     }
13594   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13595   vat_json_object_add_uint (node, "decap_next_index",
13596                             ntohl (mp->decap_next_index));
13597   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13598   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13599   vat_json_object_add_uint (node, "mcast_sw_if_index",
13600                             ntohl (mp->mcast_sw_if_index));
13601 }
13602
13603 static int
13604 api_vxlan_tunnel_dump (vat_main_t * vam)
13605 {
13606   unformat_input_t *i = vam->input;
13607   vl_api_vxlan_tunnel_dump_t *mp;
13608   vl_api_control_ping_t *mp_ping;
13609   u32 sw_if_index;
13610   u8 sw_if_index_set = 0;
13611   int ret;
13612
13613   /* Parse args required to build the message */
13614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13615     {
13616       if (unformat (i, "sw_if_index %d", &sw_if_index))
13617         sw_if_index_set = 1;
13618       else
13619         break;
13620     }
13621
13622   if (sw_if_index_set == 0)
13623     {
13624       sw_if_index = ~0;
13625     }
13626
13627   if (!vam->json_output)
13628     {
13629       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13630              "sw_if_index", "instance", "src_address", "dst_address",
13631              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13632     }
13633
13634   /* Get list of vxlan-tunnel interfaces */
13635   M (VXLAN_TUNNEL_DUMP, mp);
13636
13637   mp->sw_if_index = htonl (sw_if_index);
13638
13639   S (mp);
13640
13641   /* Use a control ping for synchronization */
13642   MPING (CONTROL_PING, mp_ping);
13643   S (mp_ping);
13644
13645   W (ret);
13646   return ret;
13647 }
13648
13649 static uword unformat_geneve_decap_next
13650   (unformat_input_t * input, va_list * args)
13651 {
13652   u32 *result = va_arg (*args, u32 *);
13653   u32 tmp;
13654
13655   if (unformat (input, "l2"))
13656     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13657   else if (unformat (input, "%d", &tmp))
13658     *result = tmp;
13659   else
13660     return 0;
13661   return 1;
13662 }
13663
13664 static int
13665 api_geneve_add_del_tunnel (vat_main_t * vam)
13666 {
13667   unformat_input_t *line_input = vam->input;
13668   vl_api_geneve_add_del_tunnel_t *mp;
13669   ip46_address_t src, dst;
13670   u8 is_add = 1;
13671   u8 ipv4_set = 0, ipv6_set = 0;
13672   u8 src_set = 0;
13673   u8 dst_set = 0;
13674   u8 grp_set = 0;
13675   u32 mcast_sw_if_index = ~0;
13676   u32 encap_vrf_id = 0;
13677   u32 decap_next_index = ~0;
13678   u32 vni = 0;
13679   int ret;
13680
13681   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13682   clib_memset (&src, 0, sizeof src);
13683   clib_memset (&dst, 0, sizeof dst);
13684
13685   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13686     {
13687       if (unformat (line_input, "del"))
13688         is_add = 0;
13689       else
13690         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13691         {
13692           ipv4_set = 1;
13693           src_set = 1;
13694         }
13695       else
13696         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13697         {
13698           ipv4_set = 1;
13699           dst_set = 1;
13700         }
13701       else
13702         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13703         {
13704           ipv6_set = 1;
13705           src_set = 1;
13706         }
13707       else
13708         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13709         {
13710           ipv6_set = 1;
13711           dst_set = 1;
13712         }
13713       else if (unformat (line_input, "group %U %U",
13714                          unformat_ip4_address, &dst.ip4,
13715                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13716         {
13717           grp_set = dst_set = 1;
13718           ipv4_set = 1;
13719         }
13720       else if (unformat (line_input, "group %U",
13721                          unformat_ip4_address, &dst.ip4))
13722         {
13723           grp_set = dst_set = 1;
13724           ipv4_set = 1;
13725         }
13726       else if (unformat (line_input, "group %U %U",
13727                          unformat_ip6_address, &dst.ip6,
13728                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13729         {
13730           grp_set = dst_set = 1;
13731           ipv6_set = 1;
13732         }
13733       else if (unformat (line_input, "group %U",
13734                          unformat_ip6_address, &dst.ip6))
13735         {
13736           grp_set = dst_set = 1;
13737           ipv6_set = 1;
13738         }
13739       else
13740         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13741         ;
13742       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13743         ;
13744       else if (unformat (line_input, "decap-next %U",
13745                          unformat_geneve_decap_next, &decap_next_index))
13746         ;
13747       else if (unformat (line_input, "vni %d", &vni))
13748         ;
13749       else
13750         {
13751           errmsg ("parse error '%U'", format_unformat_error, line_input);
13752           return -99;
13753         }
13754     }
13755
13756   if (src_set == 0)
13757     {
13758       errmsg ("tunnel src address not specified");
13759       return -99;
13760     }
13761   if (dst_set == 0)
13762     {
13763       errmsg ("tunnel dst address not specified");
13764       return -99;
13765     }
13766
13767   if (grp_set && !ip46_address_is_multicast (&dst))
13768     {
13769       errmsg ("tunnel group address not multicast");
13770       return -99;
13771     }
13772   if (grp_set && mcast_sw_if_index == ~0)
13773     {
13774       errmsg ("tunnel nonexistent multicast device");
13775       return -99;
13776     }
13777   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13778     {
13779       errmsg ("tunnel dst address must be unicast");
13780       return -99;
13781     }
13782
13783
13784   if (ipv4_set && ipv6_set)
13785     {
13786       errmsg ("both IPv4 and IPv6 addresses specified");
13787       return -99;
13788     }
13789
13790   if ((vni == 0) || (vni >> 24))
13791     {
13792       errmsg ("vni not specified or out of range");
13793       return -99;
13794     }
13795
13796   M (GENEVE_ADD_DEL_TUNNEL, mp);
13797
13798   if (ipv6_set)
13799     {
13800       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13801       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13802     }
13803   else
13804     {
13805       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13806       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13807     }
13808   mp->encap_vrf_id = ntohl (encap_vrf_id);
13809   mp->decap_next_index = ntohl (decap_next_index);
13810   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13811   mp->vni = ntohl (vni);
13812   mp->is_add = is_add;
13813   mp->is_ipv6 = ipv6_set;
13814
13815   S (mp);
13816   W (ret);
13817   return ret;
13818 }
13819
13820 static void vl_api_geneve_tunnel_details_t_handler
13821   (vl_api_geneve_tunnel_details_t * mp)
13822 {
13823   vat_main_t *vam = &vat_main;
13824   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13825   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13826
13827   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13828          ntohl (mp->sw_if_index),
13829          format_ip46_address, &src, IP46_TYPE_ANY,
13830          format_ip46_address, &dst, IP46_TYPE_ANY,
13831          ntohl (mp->encap_vrf_id),
13832          ntohl (mp->decap_next_index), ntohl (mp->vni),
13833          ntohl (mp->mcast_sw_if_index));
13834 }
13835
13836 static void vl_api_geneve_tunnel_details_t_handler_json
13837   (vl_api_geneve_tunnel_details_t * mp)
13838 {
13839   vat_main_t *vam = &vat_main;
13840   vat_json_node_t *node = NULL;
13841
13842   if (VAT_JSON_ARRAY != vam->json_tree.type)
13843     {
13844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13845       vat_json_init_array (&vam->json_tree);
13846     }
13847   node = vat_json_array_add (&vam->json_tree);
13848
13849   vat_json_init_object (node);
13850   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13851   if (mp->is_ipv6)
13852     {
13853       struct in6_addr ip6;
13854
13855       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13856       vat_json_object_add_ip6 (node, "src_address", ip6);
13857       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13858       vat_json_object_add_ip6 (node, "dst_address", ip6);
13859     }
13860   else
13861     {
13862       struct in_addr ip4;
13863
13864       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13865       vat_json_object_add_ip4 (node, "src_address", ip4);
13866       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13867       vat_json_object_add_ip4 (node, "dst_address", ip4);
13868     }
13869   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13870   vat_json_object_add_uint (node, "decap_next_index",
13871                             ntohl (mp->decap_next_index));
13872   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13873   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13874   vat_json_object_add_uint (node, "mcast_sw_if_index",
13875                             ntohl (mp->mcast_sw_if_index));
13876 }
13877
13878 static int
13879 api_geneve_tunnel_dump (vat_main_t * vam)
13880 {
13881   unformat_input_t *i = vam->input;
13882   vl_api_geneve_tunnel_dump_t *mp;
13883   vl_api_control_ping_t *mp_ping;
13884   u32 sw_if_index;
13885   u8 sw_if_index_set = 0;
13886   int ret;
13887
13888   /* Parse args required to build the message */
13889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13890     {
13891       if (unformat (i, "sw_if_index %d", &sw_if_index))
13892         sw_if_index_set = 1;
13893       else
13894         break;
13895     }
13896
13897   if (sw_if_index_set == 0)
13898     {
13899       sw_if_index = ~0;
13900     }
13901
13902   if (!vam->json_output)
13903     {
13904       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13905              "sw_if_index", "local_address", "remote_address",
13906              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13907     }
13908
13909   /* Get list of geneve-tunnel interfaces */
13910   M (GENEVE_TUNNEL_DUMP, mp);
13911
13912   mp->sw_if_index = htonl (sw_if_index);
13913
13914   S (mp);
13915
13916   /* Use a control ping for synchronization */
13917   M (CONTROL_PING, mp_ping);
13918   S (mp_ping);
13919
13920   W (ret);
13921   return ret;
13922 }
13923
13924 static int
13925 api_gre_add_del_tunnel (vat_main_t * vam)
13926 {
13927   unformat_input_t *line_input = vam->input;
13928   vl_api_gre_add_del_tunnel_t *mp;
13929   ip4_address_t src4, dst4;
13930   ip6_address_t src6, dst6;
13931   u8 is_add = 1;
13932   u8 ipv4_set = 0;
13933   u8 ipv6_set = 0;
13934   u8 t_type = GRE_TUNNEL_TYPE_L3;
13935   u8 src_set = 0;
13936   u8 dst_set = 0;
13937   u32 outer_fib_id = 0;
13938   u32 session_id = 0;
13939   u32 instance = ~0;
13940   int ret;
13941
13942   clib_memset (&src4, 0, sizeof src4);
13943   clib_memset (&dst4, 0, sizeof dst4);
13944   clib_memset (&src6, 0, sizeof src6);
13945   clib_memset (&dst6, 0, sizeof dst6);
13946
13947   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13948     {
13949       if (unformat (line_input, "del"))
13950         is_add = 0;
13951       else if (unformat (line_input, "instance %d", &instance))
13952         ;
13953       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13954         {
13955           src_set = 1;
13956           ipv4_set = 1;
13957         }
13958       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13959         {
13960           dst_set = 1;
13961           ipv4_set = 1;
13962         }
13963       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13964         {
13965           src_set = 1;
13966           ipv6_set = 1;
13967         }
13968       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13969         {
13970           dst_set = 1;
13971           ipv6_set = 1;
13972         }
13973       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13974         ;
13975       else if (unformat (line_input, "teb"))
13976         t_type = GRE_TUNNEL_TYPE_TEB;
13977       else if (unformat (line_input, "erspan %d", &session_id))
13978         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13979       else
13980         {
13981           errmsg ("parse error '%U'", format_unformat_error, line_input);
13982           return -99;
13983         }
13984     }
13985
13986   if (src_set == 0)
13987     {
13988       errmsg ("tunnel src address not specified");
13989       return -99;
13990     }
13991   if (dst_set == 0)
13992     {
13993       errmsg ("tunnel dst address not specified");
13994       return -99;
13995     }
13996   if (ipv4_set && ipv6_set)
13997     {
13998       errmsg ("both IPv4 and IPv6 addresses specified");
13999       return -99;
14000     }
14001
14002
14003   M (GRE_ADD_DEL_TUNNEL, mp);
14004
14005   if (ipv4_set)
14006     {
14007       clib_memcpy (&mp->src_address, &src4, 4);
14008       clib_memcpy (&mp->dst_address, &dst4, 4);
14009     }
14010   else
14011     {
14012       clib_memcpy (&mp->src_address, &src6, 16);
14013       clib_memcpy (&mp->dst_address, &dst6, 16);
14014     }
14015   mp->instance = htonl (instance);
14016   mp->outer_fib_id = htonl (outer_fib_id);
14017   mp->is_add = is_add;
14018   mp->session_id = htons ((u16) session_id);
14019   mp->tunnel_type = t_type;
14020   mp->is_ipv6 = ipv6_set;
14021
14022   S (mp);
14023   W (ret);
14024   return ret;
14025 }
14026
14027 static void vl_api_gre_tunnel_details_t_handler
14028   (vl_api_gre_tunnel_details_t * mp)
14029 {
14030   vat_main_t *vam = &vat_main;
14031   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
14032   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
14033
14034   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
14035          ntohl (mp->sw_if_index),
14036          ntohl (mp->instance),
14037          format_ip46_address, &src, IP46_TYPE_ANY,
14038          format_ip46_address, &dst, IP46_TYPE_ANY,
14039          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
14040 }
14041
14042 static void vl_api_gre_tunnel_details_t_handler_json
14043   (vl_api_gre_tunnel_details_t * mp)
14044 {
14045   vat_main_t *vam = &vat_main;
14046   vat_json_node_t *node = NULL;
14047   struct in_addr ip4;
14048   struct in6_addr ip6;
14049
14050   if (VAT_JSON_ARRAY != vam->json_tree.type)
14051     {
14052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14053       vat_json_init_array (&vam->json_tree);
14054     }
14055   node = vat_json_array_add (&vam->json_tree);
14056
14057   vat_json_init_object (node);
14058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14059   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
14060   if (!mp->is_ipv6)
14061     {
14062       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14063       vat_json_object_add_ip4 (node, "src_address", ip4);
14064       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14065       vat_json_object_add_ip4 (node, "dst_address", ip4);
14066     }
14067   else
14068     {
14069       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
14070       vat_json_object_add_ip6 (node, "src_address", ip6);
14071       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
14072       vat_json_object_add_ip6 (node, "dst_address", ip6);
14073     }
14074   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
14075   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
14076   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
14077   vat_json_object_add_uint (node, "session_id", mp->session_id);
14078 }
14079
14080 static int
14081 api_gre_tunnel_dump (vat_main_t * vam)
14082 {
14083   unformat_input_t *i = vam->input;
14084   vl_api_gre_tunnel_dump_t *mp;
14085   vl_api_control_ping_t *mp_ping;
14086   u32 sw_if_index;
14087   u8 sw_if_index_set = 0;
14088   int ret;
14089
14090   /* Parse args required to build the message */
14091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14092     {
14093       if (unformat (i, "sw_if_index %d", &sw_if_index))
14094         sw_if_index_set = 1;
14095       else
14096         break;
14097     }
14098
14099   if (sw_if_index_set == 0)
14100     {
14101       sw_if_index = ~0;
14102     }
14103
14104   if (!vam->json_output)
14105     {
14106       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
14107              "sw_if_index", "instance", "src_address", "dst_address",
14108              "tunnel_type", "outer_fib_id", "session_id");
14109     }
14110
14111   /* Get list of gre-tunnel interfaces */
14112   M (GRE_TUNNEL_DUMP, mp);
14113
14114   mp->sw_if_index = htonl (sw_if_index);
14115
14116   S (mp);
14117
14118   /* Use a control ping for synchronization */
14119   MPING (CONTROL_PING, mp_ping);
14120   S (mp_ping);
14121
14122   W (ret);
14123   return ret;
14124 }
14125
14126 static int
14127 api_l2_fib_clear_table (vat_main_t * vam)
14128 {
14129 //  unformat_input_t * i = vam->input;
14130   vl_api_l2_fib_clear_table_t *mp;
14131   int ret;
14132
14133   M (L2_FIB_CLEAR_TABLE, mp);
14134
14135   S (mp);
14136   W (ret);
14137   return ret;
14138 }
14139
14140 static int
14141 api_l2_interface_efp_filter (vat_main_t * vam)
14142 {
14143   unformat_input_t *i = vam->input;
14144   vl_api_l2_interface_efp_filter_t *mp;
14145   u32 sw_if_index;
14146   u8 enable = 1;
14147   u8 sw_if_index_set = 0;
14148   int ret;
14149
14150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14151     {
14152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14153         sw_if_index_set = 1;
14154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14155         sw_if_index_set = 1;
14156       else if (unformat (i, "enable"))
14157         enable = 1;
14158       else if (unformat (i, "disable"))
14159         enable = 0;
14160       else
14161         {
14162           clib_warning ("parse error '%U'", format_unformat_error, i);
14163           return -99;
14164         }
14165     }
14166
14167   if (sw_if_index_set == 0)
14168     {
14169       errmsg ("missing sw_if_index");
14170       return -99;
14171     }
14172
14173   M (L2_INTERFACE_EFP_FILTER, mp);
14174
14175   mp->sw_if_index = ntohl (sw_if_index);
14176   mp->enable_disable = enable;
14177
14178   S (mp);
14179   W (ret);
14180   return ret;
14181 }
14182
14183 #define foreach_vtr_op                          \
14184 _("disable",  L2_VTR_DISABLED)                  \
14185 _("push-1",  L2_VTR_PUSH_1)                     \
14186 _("push-2",  L2_VTR_PUSH_2)                     \
14187 _("pop-1",  L2_VTR_POP_1)                       \
14188 _("pop-2",  L2_VTR_POP_2)                       \
14189 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14190 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14191 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14192 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14193
14194 static int
14195 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14196 {
14197   unformat_input_t *i = vam->input;
14198   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14199   u32 sw_if_index;
14200   u8 sw_if_index_set = 0;
14201   u8 vtr_op_set = 0;
14202   u32 vtr_op = 0;
14203   u32 push_dot1q = 1;
14204   u32 tag1 = ~0;
14205   u32 tag2 = ~0;
14206   int ret;
14207
14208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14209     {
14210       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14211         sw_if_index_set = 1;
14212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14213         sw_if_index_set = 1;
14214       else if (unformat (i, "vtr_op %d", &vtr_op))
14215         vtr_op_set = 1;
14216 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14217       foreach_vtr_op
14218 #undef _
14219         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14220         ;
14221       else if (unformat (i, "tag1 %d", &tag1))
14222         ;
14223       else if (unformat (i, "tag2 %d", &tag2))
14224         ;
14225       else
14226         {
14227           clib_warning ("parse error '%U'", format_unformat_error, i);
14228           return -99;
14229         }
14230     }
14231
14232   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14233     {
14234       errmsg ("missing vtr operation or sw_if_index");
14235       return -99;
14236     }
14237
14238   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14239   mp->sw_if_index = ntohl (sw_if_index);
14240   mp->vtr_op = ntohl (vtr_op);
14241   mp->push_dot1q = ntohl (push_dot1q);
14242   mp->tag1 = ntohl (tag1);
14243   mp->tag2 = ntohl (tag2);
14244
14245   S (mp);
14246   W (ret);
14247   return ret;
14248 }
14249
14250 static int
14251 api_create_vhost_user_if (vat_main_t * vam)
14252 {
14253   unformat_input_t *i = vam->input;
14254   vl_api_create_vhost_user_if_t *mp;
14255   u8 *file_name;
14256   u8 is_server = 0;
14257   u8 file_name_set = 0;
14258   u32 custom_dev_instance = ~0;
14259   u8 hwaddr[6];
14260   u8 use_custom_mac = 0;
14261   u8 disable_mrg_rxbuf = 0;
14262   u8 disable_indirect_desc = 0;
14263   u8 *tag = 0;
14264   int ret;
14265
14266   /* Shut up coverity */
14267   clib_memset (hwaddr, 0, sizeof (hwaddr));
14268
14269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14270     {
14271       if (unformat (i, "socket %s", &file_name))
14272         {
14273           file_name_set = 1;
14274         }
14275       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14276         ;
14277       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14278         use_custom_mac = 1;
14279       else if (unformat (i, "server"))
14280         is_server = 1;
14281       else if (unformat (i, "disable_mrg_rxbuf"))
14282         disable_mrg_rxbuf = 1;
14283       else if (unformat (i, "disable_indirect_desc"))
14284         disable_indirect_desc = 1;
14285       else if (unformat (i, "tag %s", &tag))
14286         ;
14287       else
14288         break;
14289     }
14290
14291   if (file_name_set == 0)
14292     {
14293       errmsg ("missing socket file name");
14294       return -99;
14295     }
14296
14297   if (vec_len (file_name) > 255)
14298     {
14299       errmsg ("socket file name too long");
14300       return -99;
14301     }
14302   vec_add1 (file_name, 0);
14303
14304   M (CREATE_VHOST_USER_IF, mp);
14305
14306   mp->is_server = is_server;
14307   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14308   mp->disable_indirect_desc = disable_indirect_desc;
14309   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14310   vec_free (file_name);
14311   if (custom_dev_instance != ~0)
14312     {
14313       mp->renumber = 1;
14314       mp->custom_dev_instance = ntohl (custom_dev_instance);
14315     }
14316
14317   mp->use_custom_mac = use_custom_mac;
14318   clib_memcpy (mp->mac_address, hwaddr, 6);
14319   if (tag)
14320     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14321   vec_free (tag);
14322
14323   S (mp);
14324   W (ret);
14325   return ret;
14326 }
14327
14328 static int
14329 api_modify_vhost_user_if (vat_main_t * vam)
14330 {
14331   unformat_input_t *i = vam->input;
14332   vl_api_modify_vhost_user_if_t *mp;
14333   u8 *file_name;
14334   u8 is_server = 0;
14335   u8 file_name_set = 0;
14336   u32 custom_dev_instance = ~0;
14337   u8 sw_if_index_set = 0;
14338   u32 sw_if_index = (u32) ~ 0;
14339   int ret;
14340
14341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14342     {
14343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14344         sw_if_index_set = 1;
14345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14346         sw_if_index_set = 1;
14347       else if (unformat (i, "socket %s", &file_name))
14348         {
14349           file_name_set = 1;
14350         }
14351       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14352         ;
14353       else if (unformat (i, "server"))
14354         is_server = 1;
14355       else
14356         break;
14357     }
14358
14359   if (sw_if_index_set == 0)
14360     {
14361       errmsg ("missing sw_if_index or interface name");
14362       return -99;
14363     }
14364
14365   if (file_name_set == 0)
14366     {
14367       errmsg ("missing socket file name");
14368       return -99;
14369     }
14370
14371   if (vec_len (file_name) > 255)
14372     {
14373       errmsg ("socket file name too long");
14374       return -99;
14375     }
14376   vec_add1 (file_name, 0);
14377
14378   M (MODIFY_VHOST_USER_IF, mp);
14379
14380   mp->sw_if_index = ntohl (sw_if_index);
14381   mp->is_server = is_server;
14382   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14383   vec_free (file_name);
14384   if (custom_dev_instance != ~0)
14385     {
14386       mp->renumber = 1;
14387       mp->custom_dev_instance = ntohl (custom_dev_instance);
14388     }
14389
14390   S (mp);
14391   W (ret);
14392   return ret;
14393 }
14394
14395 static int
14396 api_delete_vhost_user_if (vat_main_t * vam)
14397 {
14398   unformat_input_t *i = vam->input;
14399   vl_api_delete_vhost_user_if_t *mp;
14400   u32 sw_if_index = ~0;
14401   u8 sw_if_index_set = 0;
14402   int ret;
14403
14404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14405     {
14406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14407         sw_if_index_set = 1;
14408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14409         sw_if_index_set = 1;
14410       else
14411         break;
14412     }
14413
14414   if (sw_if_index_set == 0)
14415     {
14416       errmsg ("missing sw_if_index or interface name");
14417       return -99;
14418     }
14419
14420
14421   M (DELETE_VHOST_USER_IF, mp);
14422
14423   mp->sw_if_index = ntohl (sw_if_index);
14424
14425   S (mp);
14426   W (ret);
14427   return ret;
14428 }
14429
14430 static void vl_api_sw_interface_vhost_user_details_t_handler
14431   (vl_api_sw_interface_vhost_user_details_t * mp)
14432 {
14433   vat_main_t *vam = &vat_main;
14434
14435   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14436          (char *) mp->interface_name,
14437          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14438          clib_net_to_host_u64 (mp->features), mp->is_server,
14439          ntohl (mp->num_regions), (char *) mp->sock_filename);
14440   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14441 }
14442
14443 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14444   (vl_api_sw_interface_vhost_user_details_t * mp)
14445 {
14446   vat_main_t *vam = &vat_main;
14447   vat_json_node_t *node = NULL;
14448
14449   if (VAT_JSON_ARRAY != vam->json_tree.type)
14450     {
14451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14452       vat_json_init_array (&vam->json_tree);
14453     }
14454   node = vat_json_array_add (&vam->json_tree);
14455
14456   vat_json_init_object (node);
14457   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14458   vat_json_object_add_string_copy (node, "interface_name",
14459                                    mp->interface_name);
14460   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14461                             ntohl (mp->virtio_net_hdr_sz));
14462   vat_json_object_add_uint (node, "features",
14463                             clib_net_to_host_u64 (mp->features));
14464   vat_json_object_add_uint (node, "is_server", mp->is_server);
14465   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14466   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14467   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14468 }
14469
14470 static int
14471 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14472 {
14473   vl_api_sw_interface_vhost_user_dump_t *mp;
14474   vl_api_control_ping_t *mp_ping;
14475   int ret;
14476   print (vam->ofp,
14477          "Interface name            idx hdr_sz features server regions filename");
14478
14479   /* Get list of vhost-user interfaces */
14480   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14481   S (mp);
14482
14483   /* Use a control ping for synchronization */
14484   MPING (CONTROL_PING, mp_ping);
14485   S (mp_ping);
14486
14487   W (ret);
14488   return ret;
14489 }
14490
14491 static int
14492 api_show_version (vat_main_t * vam)
14493 {
14494   vl_api_show_version_t *mp;
14495   int ret;
14496
14497   M (SHOW_VERSION, mp);
14498
14499   S (mp);
14500   W (ret);
14501   return ret;
14502 }
14503
14504
14505 static int
14506 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14507 {
14508   unformat_input_t *line_input = vam->input;
14509   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14510   ip4_address_t local4, remote4;
14511   ip6_address_t local6, remote6;
14512   u8 is_add = 1;
14513   u8 ipv4_set = 0, ipv6_set = 0;
14514   u8 local_set = 0;
14515   u8 remote_set = 0;
14516   u8 grp_set = 0;
14517   u32 mcast_sw_if_index = ~0;
14518   u32 encap_vrf_id = 0;
14519   u32 decap_vrf_id = 0;
14520   u8 protocol = ~0;
14521   u32 vni;
14522   u8 vni_set = 0;
14523   int ret;
14524
14525   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14526   clib_memset (&local4, 0, sizeof local4);
14527   clib_memset (&remote4, 0, sizeof remote4);
14528   clib_memset (&local6, 0, sizeof local6);
14529   clib_memset (&remote6, 0, sizeof remote6);
14530
14531   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14532     {
14533       if (unformat (line_input, "del"))
14534         is_add = 0;
14535       else if (unformat (line_input, "local %U",
14536                          unformat_ip4_address, &local4))
14537         {
14538           local_set = 1;
14539           ipv4_set = 1;
14540         }
14541       else if (unformat (line_input, "remote %U",
14542                          unformat_ip4_address, &remote4))
14543         {
14544           remote_set = 1;
14545           ipv4_set = 1;
14546         }
14547       else if (unformat (line_input, "local %U",
14548                          unformat_ip6_address, &local6))
14549         {
14550           local_set = 1;
14551           ipv6_set = 1;
14552         }
14553       else if (unformat (line_input, "remote %U",
14554                          unformat_ip6_address, &remote6))
14555         {
14556           remote_set = 1;
14557           ipv6_set = 1;
14558         }
14559       else if (unformat (line_input, "group %U %U",
14560                          unformat_ip4_address, &remote4,
14561                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14562         {
14563           grp_set = remote_set = 1;
14564           ipv4_set = 1;
14565         }
14566       else if (unformat (line_input, "group %U",
14567                          unformat_ip4_address, &remote4))
14568         {
14569           grp_set = remote_set = 1;
14570           ipv4_set = 1;
14571         }
14572       else if (unformat (line_input, "group %U %U",
14573                          unformat_ip6_address, &remote6,
14574                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14575         {
14576           grp_set = remote_set = 1;
14577           ipv6_set = 1;
14578         }
14579       else if (unformat (line_input, "group %U",
14580                          unformat_ip6_address, &remote6))
14581         {
14582           grp_set = remote_set = 1;
14583           ipv6_set = 1;
14584         }
14585       else
14586         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14587         ;
14588       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14589         ;
14590       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14591         ;
14592       else if (unformat (line_input, "vni %d", &vni))
14593         vni_set = 1;
14594       else if (unformat (line_input, "next-ip4"))
14595         protocol = 1;
14596       else if (unformat (line_input, "next-ip6"))
14597         protocol = 2;
14598       else if (unformat (line_input, "next-ethernet"))
14599         protocol = 3;
14600       else if (unformat (line_input, "next-nsh"))
14601         protocol = 4;
14602       else
14603         {
14604           errmsg ("parse error '%U'", format_unformat_error, line_input);
14605           return -99;
14606         }
14607     }
14608
14609   if (local_set == 0)
14610     {
14611       errmsg ("tunnel local address not specified");
14612       return -99;
14613     }
14614   if (remote_set == 0)
14615     {
14616       errmsg ("tunnel remote address not specified");
14617       return -99;
14618     }
14619   if (grp_set && mcast_sw_if_index == ~0)
14620     {
14621       errmsg ("tunnel nonexistent multicast device");
14622       return -99;
14623     }
14624   if (ipv4_set && ipv6_set)
14625     {
14626       errmsg ("both IPv4 and IPv6 addresses specified");
14627       return -99;
14628     }
14629
14630   if (vni_set == 0)
14631     {
14632       errmsg ("vni not specified");
14633       return -99;
14634     }
14635
14636   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14637
14638
14639   if (ipv6_set)
14640     {
14641       clib_memcpy (&mp->local, &local6, sizeof (local6));
14642       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14643     }
14644   else
14645     {
14646       clib_memcpy (&mp->local, &local4, sizeof (local4));
14647       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14648     }
14649
14650   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14651   mp->encap_vrf_id = ntohl (encap_vrf_id);
14652   mp->decap_vrf_id = ntohl (decap_vrf_id);
14653   mp->protocol = protocol;
14654   mp->vni = ntohl (vni);
14655   mp->is_add = is_add;
14656   mp->is_ipv6 = ipv6_set;
14657
14658   S (mp);
14659   W (ret);
14660   return ret;
14661 }
14662
14663 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14664   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14665 {
14666   vat_main_t *vam = &vat_main;
14667   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14668   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14669
14670   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14671          ntohl (mp->sw_if_index),
14672          format_ip46_address, &local, IP46_TYPE_ANY,
14673          format_ip46_address, &remote, IP46_TYPE_ANY,
14674          ntohl (mp->vni), mp->protocol,
14675          ntohl (mp->mcast_sw_if_index),
14676          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14677 }
14678
14679
14680 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14681   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14682 {
14683   vat_main_t *vam = &vat_main;
14684   vat_json_node_t *node = NULL;
14685   struct in_addr ip4;
14686   struct in6_addr ip6;
14687
14688   if (VAT_JSON_ARRAY != vam->json_tree.type)
14689     {
14690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14691       vat_json_init_array (&vam->json_tree);
14692     }
14693   node = vat_json_array_add (&vam->json_tree);
14694
14695   vat_json_init_object (node);
14696   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14697   if (mp->is_ipv6)
14698     {
14699       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14700       vat_json_object_add_ip6 (node, "local", ip6);
14701       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14702       vat_json_object_add_ip6 (node, "remote", ip6);
14703     }
14704   else
14705     {
14706       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14707       vat_json_object_add_ip4 (node, "local", ip4);
14708       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14709       vat_json_object_add_ip4 (node, "remote", ip4);
14710     }
14711   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14712   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14713   vat_json_object_add_uint (node, "mcast_sw_if_index",
14714                             ntohl (mp->mcast_sw_if_index));
14715   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14716   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14717   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14718 }
14719
14720 static int
14721 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14722 {
14723   unformat_input_t *i = vam->input;
14724   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14725   vl_api_control_ping_t *mp_ping;
14726   u32 sw_if_index;
14727   u8 sw_if_index_set = 0;
14728   int ret;
14729
14730   /* Parse args required to build the message */
14731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14732     {
14733       if (unformat (i, "sw_if_index %d", &sw_if_index))
14734         sw_if_index_set = 1;
14735       else
14736         break;
14737     }
14738
14739   if (sw_if_index_set == 0)
14740     {
14741       sw_if_index = ~0;
14742     }
14743
14744   if (!vam->json_output)
14745     {
14746       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14747              "sw_if_index", "local", "remote", "vni",
14748              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14749     }
14750
14751   /* Get list of vxlan-tunnel interfaces */
14752   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14753
14754   mp->sw_if_index = htonl (sw_if_index);
14755
14756   S (mp);
14757
14758   /* Use a control ping for synchronization */
14759   MPING (CONTROL_PING, mp_ping);
14760   S (mp_ping);
14761
14762   W (ret);
14763   return ret;
14764 }
14765
14766 static void vl_api_l2_fib_table_details_t_handler
14767   (vl_api_l2_fib_table_details_t * mp)
14768 {
14769   vat_main_t *vam = &vat_main;
14770
14771   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14772          "       %d       %d     %d",
14773          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14774          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14775          mp->bvi_mac);
14776 }
14777
14778 static void vl_api_l2_fib_table_details_t_handler_json
14779   (vl_api_l2_fib_table_details_t * mp)
14780 {
14781   vat_main_t *vam = &vat_main;
14782   vat_json_node_t *node = NULL;
14783
14784   if (VAT_JSON_ARRAY != vam->json_tree.type)
14785     {
14786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14787       vat_json_init_array (&vam->json_tree);
14788     }
14789   node = vat_json_array_add (&vam->json_tree);
14790
14791   vat_json_init_object (node);
14792   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14793   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14794   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14795   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14796   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14797   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14798 }
14799
14800 static int
14801 api_l2_fib_table_dump (vat_main_t * vam)
14802 {
14803   unformat_input_t *i = vam->input;
14804   vl_api_l2_fib_table_dump_t *mp;
14805   vl_api_control_ping_t *mp_ping;
14806   u32 bd_id;
14807   u8 bd_id_set = 0;
14808   int ret;
14809
14810   /* Parse args required to build the message */
14811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14812     {
14813       if (unformat (i, "bd_id %d", &bd_id))
14814         bd_id_set = 1;
14815       else
14816         break;
14817     }
14818
14819   if (bd_id_set == 0)
14820     {
14821       errmsg ("missing bridge domain");
14822       return -99;
14823     }
14824
14825   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14826
14827   /* Get list of l2 fib entries */
14828   M (L2_FIB_TABLE_DUMP, mp);
14829
14830   mp->bd_id = ntohl (bd_id);
14831   S (mp);
14832
14833   /* Use a control ping for synchronization */
14834   MPING (CONTROL_PING, mp_ping);
14835   S (mp_ping);
14836
14837   W (ret);
14838   return ret;
14839 }
14840
14841
14842 static int
14843 api_interface_name_renumber (vat_main_t * vam)
14844 {
14845   unformat_input_t *line_input = vam->input;
14846   vl_api_interface_name_renumber_t *mp;
14847   u32 sw_if_index = ~0;
14848   u32 new_show_dev_instance = ~0;
14849   int ret;
14850
14851   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14852     {
14853       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14854                     &sw_if_index))
14855         ;
14856       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14857         ;
14858       else if (unformat (line_input, "new_show_dev_instance %d",
14859                          &new_show_dev_instance))
14860         ;
14861       else
14862         break;
14863     }
14864
14865   if (sw_if_index == ~0)
14866     {
14867       errmsg ("missing interface name or sw_if_index");
14868       return -99;
14869     }
14870
14871   if (new_show_dev_instance == ~0)
14872     {
14873       errmsg ("missing new_show_dev_instance");
14874       return -99;
14875     }
14876
14877   M (INTERFACE_NAME_RENUMBER, mp);
14878
14879   mp->sw_if_index = ntohl (sw_if_index);
14880   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14881
14882   S (mp);
14883   W (ret);
14884   return ret;
14885 }
14886
14887 static int
14888 api_ip_probe_neighbor (vat_main_t * vam)
14889 {
14890   unformat_input_t *i = vam->input;
14891   vl_api_ip_probe_neighbor_t *mp;
14892   u8 int_set = 0;
14893   u8 adr_set = 0;
14894   u8 is_ipv6 = 0;
14895   u8 dst_adr[16];
14896   u32 sw_if_index;
14897   int ret;
14898
14899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14900     {
14901       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14902         int_set = 1;
14903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14904         int_set = 1;
14905       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14906         adr_set = 1;
14907       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14908         {
14909           adr_set = 1;
14910           is_ipv6 = 1;
14911         }
14912       else
14913         break;
14914     }
14915
14916   if (int_set == 0)
14917     {
14918       errmsg ("missing interface");
14919       return -99;
14920     }
14921
14922   if (adr_set == 0)
14923     {
14924       errmsg ("missing addresses");
14925       return -99;
14926     }
14927
14928   M (IP_PROBE_NEIGHBOR, mp);
14929
14930   mp->sw_if_index = ntohl (sw_if_index);
14931   mp->is_ipv6 = is_ipv6;
14932   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14933
14934   S (mp);
14935   W (ret);
14936   return ret;
14937 }
14938
14939 static int
14940 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14941 {
14942   unformat_input_t *i = vam->input;
14943   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14944   u8 mode = IP_SCAN_V46_NEIGHBORS;
14945   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14946   int ret;
14947
14948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14949     {
14950       if (unformat (i, "ip4"))
14951         mode = IP_SCAN_V4_NEIGHBORS;
14952       else if (unformat (i, "ip6"))
14953         mode = IP_SCAN_V6_NEIGHBORS;
14954       if (unformat (i, "both"))
14955         mode = IP_SCAN_V46_NEIGHBORS;
14956       else if (unformat (i, "disable"))
14957         mode = IP_SCAN_DISABLED;
14958       else if (unformat (i, "interval %d", &interval))
14959         ;
14960       else if (unformat (i, "max-time %d", &time))
14961         ;
14962       else if (unformat (i, "max-update %d", &update))
14963         ;
14964       else if (unformat (i, "delay %d", &delay))
14965         ;
14966       else if (unformat (i, "stale %d", &stale))
14967         ;
14968       else
14969         break;
14970     }
14971
14972   if (interval > 255)
14973     {
14974       errmsg ("interval cannot exceed 255 minutes.");
14975       return -99;
14976     }
14977   if (time > 255)
14978     {
14979       errmsg ("max-time cannot exceed 255 usec.");
14980       return -99;
14981     }
14982   if (update > 255)
14983     {
14984       errmsg ("max-update cannot exceed 255.");
14985       return -99;
14986     }
14987   if (delay > 255)
14988     {
14989       errmsg ("delay cannot exceed 255 msec.");
14990       return -99;
14991     }
14992   if (stale > 255)
14993     {
14994       errmsg ("stale cannot exceed 255 minutes.");
14995       return -99;
14996     }
14997
14998   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14999   mp->mode = mode;
15000   mp->scan_interval = interval;
15001   mp->max_proc_time = time;
15002   mp->max_update = update;
15003   mp->scan_int_delay = delay;
15004   mp->stale_threshold = stale;
15005
15006   S (mp);
15007   W (ret);
15008   return ret;
15009 }
15010
15011 static int
15012 api_want_ip4_arp_events (vat_main_t * vam)
15013 {
15014   unformat_input_t *line_input = vam->input;
15015   vl_api_want_ip4_arp_events_t *mp;
15016   ip4_address_t address;
15017   int address_set = 0;
15018   u32 enable_disable = 1;
15019   int ret;
15020
15021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
15024         address_set = 1;
15025       else if (unformat (line_input, "del"))
15026         enable_disable = 0;
15027       else
15028         break;
15029     }
15030
15031   if (address_set == 0)
15032     {
15033       errmsg ("missing addresses");
15034       return -99;
15035     }
15036
15037   M (WANT_IP4_ARP_EVENTS, mp);
15038   mp->enable_disable = enable_disable;
15039   mp->pid = htonl (getpid ());
15040   mp->address = address.as_u32;
15041
15042   S (mp);
15043   W (ret);
15044   return ret;
15045 }
15046
15047 static int
15048 api_want_ip6_nd_events (vat_main_t * vam)
15049 {
15050   unformat_input_t *line_input = vam->input;
15051   vl_api_want_ip6_nd_events_t *mp;
15052   ip6_address_t address;
15053   int address_set = 0;
15054   u32 enable_disable = 1;
15055   int ret;
15056
15057   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15058     {
15059       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
15060         address_set = 1;
15061       else if (unformat (line_input, "del"))
15062         enable_disable = 0;
15063       else
15064         break;
15065     }
15066
15067   if (address_set == 0)
15068     {
15069       errmsg ("missing addresses");
15070       return -99;
15071     }
15072
15073   M (WANT_IP6_ND_EVENTS, mp);
15074   mp->enable_disable = enable_disable;
15075   mp->pid = htonl (getpid ());
15076   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
15077
15078   S (mp);
15079   W (ret);
15080   return ret;
15081 }
15082
15083 static int
15084 api_want_l2_macs_events (vat_main_t * vam)
15085 {
15086   unformat_input_t *line_input = vam->input;
15087   vl_api_want_l2_macs_events_t *mp;
15088   u8 enable_disable = 1;
15089   u32 scan_delay = 0;
15090   u32 max_macs_in_event = 0;
15091   u32 learn_limit = 0;
15092   int ret;
15093
15094   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15095     {
15096       if (unformat (line_input, "learn-limit %d", &learn_limit))
15097         ;
15098       else if (unformat (line_input, "scan-delay %d", &scan_delay))
15099         ;
15100       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
15101         ;
15102       else if (unformat (line_input, "disable"))
15103         enable_disable = 0;
15104       else
15105         break;
15106     }
15107
15108   M (WANT_L2_MACS_EVENTS, mp);
15109   mp->enable_disable = enable_disable;
15110   mp->pid = htonl (getpid ());
15111   mp->learn_limit = htonl (learn_limit);
15112   mp->scan_delay = (u8) scan_delay;
15113   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15114   S (mp);
15115   W (ret);
15116   return ret;
15117 }
15118
15119 static int
15120 api_input_acl_set_interface (vat_main_t * vam)
15121 {
15122   unformat_input_t *i = vam->input;
15123   vl_api_input_acl_set_interface_t *mp;
15124   u32 sw_if_index;
15125   int sw_if_index_set;
15126   u32 ip4_table_index = ~0;
15127   u32 ip6_table_index = ~0;
15128   u32 l2_table_index = ~0;
15129   u8 is_add = 1;
15130   int ret;
15131
15132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15133     {
15134       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15135         sw_if_index_set = 1;
15136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15137         sw_if_index_set = 1;
15138       else if (unformat (i, "del"))
15139         is_add = 0;
15140       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15141         ;
15142       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15143         ;
15144       else if (unformat (i, "l2-table %d", &l2_table_index))
15145         ;
15146       else
15147         {
15148           clib_warning ("parse error '%U'", format_unformat_error, i);
15149           return -99;
15150         }
15151     }
15152
15153   if (sw_if_index_set == 0)
15154     {
15155       errmsg ("missing interface name or sw_if_index");
15156       return -99;
15157     }
15158
15159   M (INPUT_ACL_SET_INTERFACE, mp);
15160
15161   mp->sw_if_index = ntohl (sw_if_index);
15162   mp->ip4_table_index = ntohl (ip4_table_index);
15163   mp->ip6_table_index = ntohl (ip6_table_index);
15164   mp->l2_table_index = ntohl (l2_table_index);
15165   mp->is_add = is_add;
15166
15167   S (mp);
15168   W (ret);
15169   return ret;
15170 }
15171
15172 static int
15173 api_output_acl_set_interface (vat_main_t * vam)
15174 {
15175   unformat_input_t *i = vam->input;
15176   vl_api_output_acl_set_interface_t *mp;
15177   u32 sw_if_index;
15178   int sw_if_index_set;
15179   u32 ip4_table_index = ~0;
15180   u32 ip6_table_index = ~0;
15181   u32 l2_table_index = ~0;
15182   u8 is_add = 1;
15183   int ret;
15184
15185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15186     {
15187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15188         sw_if_index_set = 1;
15189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15190         sw_if_index_set = 1;
15191       else if (unformat (i, "del"))
15192         is_add = 0;
15193       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15194         ;
15195       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15196         ;
15197       else if (unformat (i, "l2-table %d", &l2_table_index))
15198         ;
15199       else
15200         {
15201           clib_warning ("parse error '%U'", format_unformat_error, i);
15202           return -99;
15203         }
15204     }
15205
15206   if (sw_if_index_set == 0)
15207     {
15208       errmsg ("missing interface name or sw_if_index");
15209       return -99;
15210     }
15211
15212   M (OUTPUT_ACL_SET_INTERFACE, mp);
15213
15214   mp->sw_if_index = ntohl (sw_if_index);
15215   mp->ip4_table_index = ntohl (ip4_table_index);
15216   mp->ip6_table_index = ntohl (ip6_table_index);
15217   mp->l2_table_index = ntohl (l2_table_index);
15218   mp->is_add = is_add;
15219
15220   S (mp);
15221   W (ret);
15222   return ret;
15223 }
15224
15225 static int
15226 api_ip_address_dump (vat_main_t * vam)
15227 {
15228   unformat_input_t *i = vam->input;
15229   vl_api_ip_address_dump_t *mp;
15230   vl_api_control_ping_t *mp_ping;
15231   u32 sw_if_index = ~0;
15232   u8 sw_if_index_set = 0;
15233   u8 ipv4_set = 0;
15234   u8 ipv6_set = 0;
15235   int ret;
15236
15237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15238     {
15239       if (unformat (i, "sw_if_index %d", &sw_if_index))
15240         sw_if_index_set = 1;
15241       else
15242         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15243         sw_if_index_set = 1;
15244       else if (unformat (i, "ipv4"))
15245         ipv4_set = 1;
15246       else if (unformat (i, "ipv6"))
15247         ipv6_set = 1;
15248       else
15249         break;
15250     }
15251
15252   if (ipv4_set && ipv6_set)
15253     {
15254       errmsg ("ipv4 and ipv6 flags cannot be both set");
15255       return -99;
15256     }
15257
15258   if ((!ipv4_set) && (!ipv6_set))
15259     {
15260       errmsg ("no ipv4 nor ipv6 flag set");
15261       return -99;
15262     }
15263
15264   if (sw_if_index_set == 0)
15265     {
15266       errmsg ("missing interface name or sw_if_index");
15267       return -99;
15268     }
15269
15270   vam->current_sw_if_index = sw_if_index;
15271   vam->is_ipv6 = ipv6_set;
15272
15273   M (IP_ADDRESS_DUMP, mp);
15274   mp->sw_if_index = ntohl (sw_if_index);
15275   mp->is_ipv6 = ipv6_set;
15276   S (mp);
15277
15278   /* Use a control ping for synchronization */
15279   MPING (CONTROL_PING, mp_ping);
15280   S (mp_ping);
15281
15282   W (ret);
15283   return ret;
15284 }
15285
15286 static int
15287 api_ip_dump (vat_main_t * vam)
15288 {
15289   vl_api_ip_dump_t *mp;
15290   vl_api_control_ping_t *mp_ping;
15291   unformat_input_t *in = vam->input;
15292   int ipv4_set = 0;
15293   int ipv6_set = 0;
15294   int is_ipv6;
15295   int i;
15296   int ret;
15297
15298   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15299     {
15300       if (unformat (in, "ipv4"))
15301         ipv4_set = 1;
15302       else if (unformat (in, "ipv6"))
15303         ipv6_set = 1;
15304       else
15305         break;
15306     }
15307
15308   if (ipv4_set && ipv6_set)
15309     {
15310       errmsg ("ipv4 and ipv6 flags cannot be both set");
15311       return -99;
15312     }
15313
15314   if ((!ipv4_set) && (!ipv6_set))
15315     {
15316       errmsg ("no ipv4 nor ipv6 flag set");
15317       return -99;
15318     }
15319
15320   is_ipv6 = ipv6_set;
15321   vam->is_ipv6 = is_ipv6;
15322
15323   /* free old data */
15324   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15325     {
15326       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15327     }
15328   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15329
15330   M (IP_DUMP, mp);
15331   mp->is_ipv6 = ipv6_set;
15332   S (mp);
15333
15334   /* Use a control ping for synchronization */
15335   MPING (CONTROL_PING, mp_ping);
15336   S (mp_ping);
15337
15338   W (ret);
15339   return ret;
15340 }
15341
15342 static int
15343 api_ipsec_spd_add_del (vat_main_t * vam)
15344 {
15345   unformat_input_t *i = vam->input;
15346   vl_api_ipsec_spd_add_del_t *mp;
15347   u32 spd_id = ~0;
15348   u8 is_add = 1;
15349   int ret;
15350
15351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15352     {
15353       if (unformat (i, "spd_id %d", &spd_id))
15354         ;
15355       else if (unformat (i, "del"))
15356         is_add = 0;
15357       else
15358         {
15359           clib_warning ("parse error '%U'", format_unformat_error, i);
15360           return -99;
15361         }
15362     }
15363   if (spd_id == ~0)
15364     {
15365       errmsg ("spd_id must be set");
15366       return -99;
15367     }
15368
15369   M (IPSEC_SPD_ADD_DEL, mp);
15370
15371   mp->spd_id = ntohl (spd_id);
15372   mp->is_add = is_add;
15373
15374   S (mp);
15375   W (ret);
15376   return ret;
15377 }
15378
15379 static int
15380 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15381 {
15382   unformat_input_t *i = vam->input;
15383   vl_api_ipsec_interface_add_del_spd_t *mp;
15384   u32 sw_if_index;
15385   u8 sw_if_index_set = 0;
15386   u32 spd_id = (u32) ~ 0;
15387   u8 is_add = 1;
15388   int ret;
15389
15390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15391     {
15392       if (unformat (i, "del"))
15393         is_add = 0;
15394       else if (unformat (i, "spd_id %d", &spd_id))
15395         ;
15396       else
15397         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15398         sw_if_index_set = 1;
15399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15400         sw_if_index_set = 1;
15401       else
15402         {
15403           clib_warning ("parse error '%U'", format_unformat_error, i);
15404           return -99;
15405         }
15406
15407     }
15408
15409   if (spd_id == (u32) ~ 0)
15410     {
15411       errmsg ("spd_id must be set");
15412       return -99;
15413     }
15414
15415   if (sw_if_index_set == 0)
15416     {
15417       errmsg ("missing interface name or sw_if_index");
15418       return -99;
15419     }
15420
15421   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15422
15423   mp->spd_id = ntohl (spd_id);
15424   mp->sw_if_index = ntohl (sw_if_index);
15425   mp->is_add = is_add;
15426
15427   S (mp);
15428   W (ret);
15429   return ret;
15430 }
15431
15432 static int
15433 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15434 {
15435   unformat_input_t *i = vam->input;
15436   vl_api_ipsec_spd_add_del_entry_t *mp;
15437   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15438   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15439   i32 priority = 0;
15440   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15441   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15442   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15443   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15444   int ret;
15445
15446   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15447   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15448   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15449   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15450   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15451   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15452
15453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15454     {
15455       if (unformat (i, "del"))
15456         is_add = 0;
15457       if (unformat (i, "outbound"))
15458         is_outbound = 1;
15459       if (unformat (i, "inbound"))
15460         is_outbound = 0;
15461       else if (unformat (i, "spd_id %d", &spd_id))
15462         ;
15463       else if (unformat (i, "sa_id %d", &sa_id))
15464         ;
15465       else if (unformat (i, "priority %d", &priority))
15466         ;
15467       else if (unformat (i, "protocol %d", &protocol))
15468         ;
15469       else if (unformat (i, "lport_start %d", &lport_start))
15470         ;
15471       else if (unformat (i, "lport_stop %d", &lport_stop))
15472         ;
15473       else if (unformat (i, "rport_start %d", &rport_start))
15474         ;
15475       else if (unformat (i, "rport_stop %d", &rport_stop))
15476         ;
15477       else
15478         if (unformat
15479             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15480         {
15481           is_ipv6 = 0;
15482           is_ip_any = 0;
15483         }
15484       else
15485         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15486         {
15487           is_ipv6 = 0;
15488           is_ip_any = 0;
15489         }
15490       else
15491         if (unformat
15492             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15493         {
15494           is_ipv6 = 0;
15495           is_ip_any = 0;
15496         }
15497       else
15498         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15499         {
15500           is_ipv6 = 0;
15501           is_ip_any = 0;
15502         }
15503       else
15504         if (unformat
15505             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15506         {
15507           is_ipv6 = 1;
15508           is_ip_any = 0;
15509         }
15510       else
15511         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15512         {
15513           is_ipv6 = 1;
15514           is_ip_any = 0;
15515         }
15516       else
15517         if (unformat
15518             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15519         {
15520           is_ipv6 = 1;
15521           is_ip_any = 0;
15522         }
15523       else
15524         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15525         {
15526           is_ipv6 = 1;
15527           is_ip_any = 0;
15528         }
15529       else
15530         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15531         {
15532           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15533             {
15534               clib_warning ("unsupported action: 'resolve'");
15535               return -99;
15536             }
15537         }
15538       else
15539         {
15540           clib_warning ("parse error '%U'", format_unformat_error, i);
15541           return -99;
15542         }
15543
15544     }
15545
15546   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15547
15548   mp->spd_id = ntohl (spd_id);
15549   mp->priority = ntohl (priority);
15550   mp->is_outbound = is_outbound;
15551
15552   mp->is_ipv6 = is_ipv6;
15553   if (is_ipv6 || is_ip_any)
15554     {
15555       clib_memcpy (mp->remote_address_start, &raddr6_start,
15556                    sizeof (ip6_address_t));
15557       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15558                    sizeof (ip6_address_t));
15559       clib_memcpy (mp->local_address_start, &laddr6_start,
15560                    sizeof (ip6_address_t));
15561       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15562                    sizeof (ip6_address_t));
15563     }
15564   else
15565     {
15566       clib_memcpy (mp->remote_address_start, &raddr4_start,
15567                    sizeof (ip4_address_t));
15568       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15569                    sizeof (ip4_address_t));
15570       clib_memcpy (mp->local_address_start, &laddr4_start,
15571                    sizeof (ip4_address_t));
15572       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15573                    sizeof (ip4_address_t));
15574     }
15575   mp->protocol = (u8) protocol;
15576   mp->local_port_start = ntohs ((u16) lport_start);
15577   mp->local_port_stop = ntohs ((u16) lport_stop);
15578   mp->remote_port_start = ntohs ((u16) rport_start);
15579   mp->remote_port_stop = ntohs ((u16) rport_stop);
15580   mp->policy = (u8) policy;
15581   mp->sa_id = ntohl (sa_id);
15582   mp->is_add = is_add;
15583   mp->is_ip_any = is_ip_any;
15584   S (mp);
15585   W (ret);
15586   return ret;
15587 }
15588
15589 static int
15590 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15591 {
15592   unformat_input_t *i = vam->input;
15593   vl_api_ipsec_sad_add_del_entry_t *mp;
15594   u32 sad_id = 0, spi = 0;
15595   u8 *ck = 0, *ik = 0;
15596   u8 is_add = 1;
15597
15598   u8 protocol = IPSEC_PROTOCOL_AH;
15599   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15600   u32 crypto_alg = 0, integ_alg = 0;
15601   ip4_address_t tun_src4;
15602   ip4_address_t tun_dst4;
15603   ip6_address_t tun_src6;
15604   ip6_address_t tun_dst6;
15605   int ret;
15606
15607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15608     {
15609       if (unformat (i, "del"))
15610         is_add = 0;
15611       else if (unformat (i, "sad_id %d", &sad_id))
15612         ;
15613       else if (unformat (i, "spi %d", &spi))
15614         ;
15615       else if (unformat (i, "esp"))
15616         protocol = IPSEC_PROTOCOL_ESP;
15617       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15618         {
15619           is_tunnel = 1;
15620           is_tunnel_ipv6 = 0;
15621         }
15622       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15623         {
15624           is_tunnel = 1;
15625           is_tunnel_ipv6 = 0;
15626         }
15627       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15628         {
15629           is_tunnel = 1;
15630           is_tunnel_ipv6 = 1;
15631         }
15632       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15633         {
15634           is_tunnel = 1;
15635           is_tunnel_ipv6 = 1;
15636         }
15637       else
15638         if (unformat
15639             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15640         {
15641           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15642             {
15643               clib_warning ("unsupported crypto-alg: '%U'",
15644                             format_ipsec_crypto_alg, crypto_alg);
15645               return -99;
15646             }
15647         }
15648       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15649         ;
15650       else
15651         if (unformat
15652             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15653         {
15654           if (integ_alg >= IPSEC_INTEG_N_ALG)
15655             {
15656               clib_warning ("unsupported integ-alg: '%U'",
15657                             format_ipsec_integ_alg, integ_alg);
15658               return -99;
15659             }
15660         }
15661       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15662         ;
15663       else
15664         {
15665           clib_warning ("parse error '%U'", format_unformat_error, i);
15666           return -99;
15667         }
15668
15669     }
15670
15671   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15672
15673   mp->sad_id = ntohl (sad_id);
15674   mp->is_add = is_add;
15675   mp->protocol = protocol;
15676   mp->spi = ntohl (spi);
15677   mp->is_tunnel = is_tunnel;
15678   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15679   mp->crypto_algorithm = crypto_alg;
15680   mp->integrity_algorithm = integ_alg;
15681   mp->crypto_key_length = vec_len (ck);
15682   mp->integrity_key_length = vec_len (ik);
15683
15684   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15685     mp->crypto_key_length = sizeof (mp->crypto_key);
15686
15687   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15688     mp->integrity_key_length = sizeof (mp->integrity_key);
15689
15690   if (ck)
15691     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15692   if (ik)
15693     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15694
15695   if (is_tunnel)
15696     {
15697       if (is_tunnel_ipv6)
15698         {
15699           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15700                        sizeof (ip6_address_t));
15701           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15702                        sizeof (ip6_address_t));
15703         }
15704       else
15705         {
15706           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15707                        sizeof (ip4_address_t));
15708           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15709                        sizeof (ip4_address_t));
15710         }
15711     }
15712
15713   S (mp);
15714   W (ret);
15715   return ret;
15716 }
15717
15718 static int
15719 api_ipsec_sa_set_key (vat_main_t * vam)
15720 {
15721   unformat_input_t *i = vam->input;
15722   vl_api_ipsec_sa_set_key_t *mp;
15723   u32 sa_id;
15724   u8 *ck = 0, *ik = 0;
15725   int ret;
15726
15727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15728     {
15729       if (unformat (i, "sa_id %d", &sa_id))
15730         ;
15731       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15732         ;
15733       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15734         ;
15735       else
15736         {
15737           clib_warning ("parse error '%U'", format_unformat_error, i);
15738           return -99;
15739         }
15740     }
15741
15742   M (IPSEC_SA_SET_KEY, mp);
15743
15744   mp->sa_id = ntohl (sa_id);
15745   mp->crypto_key_length = vec_len (ck);
15746   mp->integrity_key_length = vec_len (ik);
15747
15748   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15749     mp->crypto_key_length = sizeof (mp->crypto_key);
15750
15751   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15752     mp->integrity_key_length = sizeof (mp->integrity_key);
15753
15754   if (ck)
15755     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15756   if (ik)
15757     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15758
15759   S (mp);
15760   W (ret);
15761   return ret;
15762 }
15763
15764 static int
15765 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15766 {
15767   unformat_input_t *i = vam->input;
15768   vl_api_ipsec_tunnel_if_add_del_t *mp;
15769   u32 local_spi = 0, remote_spi = 0;
15770   u32 crypto_alg = 0, integ_alg = 0;
15771   u8 *lck = NULL, *rck = NULL;
15772   u8 *lik = NULL, *rik = NULL;
15773   ip4_address_t local_ip = { {0} };
15774   ip4_address_t remote_ip = { {0} };
15775   u8 is_add = 1;
15776   u8 esn = 0;
15777   u8 anti_replay = 0;
15778   u8 renumber = 0;
15779   u32 instance = ~0;
15780   int ret;
15781
15782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15783     {
15784       if (unformat (i, "del"))
15785         is_add = 0;
15786       else if (unformat (i, "esn"))
15787         esn = 1;
15788       else if (unformat (i, "anti_replay"))
15789         anti_replay = 1;
15790       else if (unformat (i, "local_spi %d", &local_spi))
15791         ;
15792       else if (unformat (i, "remote_spi %d", &remote_spi))
15793         ;
15794       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15795         ;
15796       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15797         ;
15798       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15799         ;
15800       else
15801         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15802         ;
15803       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15804         ;
15805       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15806         ;
15807       else
15808         if (unformat
15809             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15810         {
15811           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15812             {
15813               errmsg ("unsupported crypto-alg: '%U'\n",
15814                       format_ipsec_crypto_alg, crypto_alg);
15815               return -99;
15816             }
15817         }
15818       else
15819         if (unformat
15820             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15821         {
15822           if (integ_alg >= IPSEC_INTEG_N_ALG)
15823             {
15824               errmsg ("unsupported integ-alg: '%U'\n",
15825                       format_ipsec_integ_alg, integ_alg);
15826               return -99;
15827             }
15828         }
15829       else if (unformat (i, "instance %u", &instance))
15830         renumber = 1;
15831       else
15832         {
15833           errmsg ("parse error '%U'\n", format_unformat_error, i);
15834           return -99;
15835         }
15836     }
15837
15838   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15839
15840   mp->is_add = is_add;
15841   mp->esn = esn;
15842   mp->anti_replay = anti_replay;
15843
15844   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15845   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15846
15847   mp->local_spi = htonl (local_spi);
15848   mp->remote_spi = htonl (remote_spi);
15849   mp->crypto_alg = (u8) crypto_alg;
15850
15851   mp->local_crypto_key_len = 0;
15852   if (lck)
15853     {
15854       mp->local_crypto_key_len = vec_len (lck);
15855       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15856         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15857       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15858     }
15859
15860   mp->remote_crypto_key_len = 0;
15861   if (rck)
15862     {
15863       mp->remote_crypto_key_len = vec_len (rck);
15864       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15865         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15866       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15867     }
15868
15869   mp->integ_alg = (u8) integ_alg;
15870
15871   mp->local_integ_key_len = 0;
15872   if (lik)
15873     {
15874       mp->local_integ_key_len = vec_len (lik);
15875       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15876         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15877       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15878     }
15879
15880   mp->remote_integ_key_len = 0;
15881   if (rik)
15882     {
15883       mp->remote_integ_key_len = vec_len (rik);
15884       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15885         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15886       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15887     }
15888
15889   if (renumber)
15890     {
15891       mp->renumber = renumber;
15892       mp->show_instance = ntohl (instance);
15893     }
15894
15895   S (mp);
15896   W (ret);
15897   return ret;
15898 }
15899
15900 static void
15901 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15902 {
15903   vat_main_t *vam = &vat_main;
15904
15905   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15906          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15907          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15908          "tunnel_src_addr %U tunnel_dst_addr %U "
15909          "salt %u seq_outbound %lu last_seq_inbound %lu "
15910          "replay_window %lu total_data_size %lu\n",
15911          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15912          mp->protocol,
15913          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15914          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15915          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15916          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15917          mp->tunnel_src_addr,
15918          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15919          mp->tunnel_dst_addr,
15920          ntohl (mp->salt),
15921          clib_net_to_host_u64 (mp->seq_outbound),
15922          clib_net_to_host_u64 (mp->last_seq_inbound),
15923          clib_net_to_host_u64 (mp->replay_window),
15924          clib_net_to_host_u64 (mp->total_data_size));
15925 }
15926
15927 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15928 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15929
15930 static void vl_api_ipsec_sa_details_t_handler_json
15931   (vl_api_ipsec_sa_details_t * mp)
15932 {
15933   vat_main_t *vam = &vat_main;
15934   vat_json_node_t *node = NULL;
15935   struct in_addr src_ip4, dst_ip4;
15936   struct in6_addr src_ip6, dst_ip6;
15937
15938   if (VAT_JSON_ARRAY != vam->json_tree.type)
15939     {
15940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15941       vat_json_init_array (&vam->json_tree);
15942     }
15943   node = vat_json_array_add (&vam->json_tree);
15944
15945   vat_json_init_object (node);
15946   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15947   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15948   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15949   vat_json_object_add_uint (node, "proto", mp->protocol);
15950   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15951   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15952   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15953   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15954   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15955   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15956   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15957                              mp->crypto_key_len);
15958   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15959                              mp->integ_key_len);
15960   if (mp->is_tunnel_ip6)
15961     {
15962       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15963       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15964       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15965       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15966     }
15967   else
15968     {
15969       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15970       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15971       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15972       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15973     }
15974   vat_json_object_add_uint (node, "replay_window",
15975                             clib_net_to_host_u64 (mp->replay_window));
15976   vat_json_object_add_uint (node, "total_data_size",
15977                             clib_net_to_host_u64 (mp->total_data_size));
15978
15979 }
15980
15981 static int
15982 api_ipsec_sa_dump (vat_main_t * vam)
15983 {
15984   unformat_input_t *i = vam->input;
15985   vl_api_ipsec_sa_dump_t *mp;
15986   vl_api_control_ping_t *mp_ping;
15987   u32 sa_id = ~0;
15988   int ret;
15989
15990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15991     {
15992       if (unformat (i, "sa_id %d", &sa_id))
15993         ;
15994       else
15995         {
15996           clib_warning ("parse error '%U'", format_unformat_error, i);
15997           return -99;
15998         }
15999     }
16000
16001   M (IPSEC_SA_DUMP, mp);
16002
16003   mp->sa_id = ntohl (sa_id);
16004
16005   S (mp);
16006
16007   /* Use a control ping for synchronization */
16008   M (CONTROL_PING, mp_ping);
16009   S (mp_ping);
16010
16011   W (ret);
16012   return ret;
16013 }
16014
16015 static int
16016 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
16017 {
16018   unformat_input_t *i = vam->input;
16019   vl_api_ipsec_tunnel_if_set_key_t *mp;
16020   u32 sw_if_index = ~0;
16021   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
16022   u8 *key = 0;
16023   u32 alg = ~0;
16024   int ret;
16025
16026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16027     {
16028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16029         ;
16030       else
16031         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
16032         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
16033       else
16034         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
16035         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
16036       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
16037         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
16038       else
16039         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
16040         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
16041       else if (unformat (i, "%U", unformat_hex_string, &key))
16042         ;
16043       else
16044         {
16045           clib_warning ("parse error '%U'", format_unformat_error, i);
16046           return -99;
16047         }
16048     }
16049
16050   if (sw_if_index == ~0)
16051     {
16052       errmsg ("interface must be specified");
16053       return -99;
16054     }
16055
16056   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
16057     {
16058       errmsg ("key type must be specified");
16059       return -99;
16060     }
16061
16062   if (alg == ~0)
16063     {
16064       errmsg ("algorithm must be specified");
16065       return -99;
16066     }
16067
16068   if (vec_len (key) == 0)
16069     {
16070       errmsg ("key must be specified");
16071       return -99;
16072     }
16073
16074   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
16075
16076   mp->sw_if_index = htonl (sw_if_index);
16077   mp->alg = alg;
16078   mp->key_type = key_type;
16079   mp->key_len = vec_len (key);
16080   clib_memcpy (mp->key, key, vec_len (key));
16081
16082   S (mp);
16083   W (ret);
16084
16085   return ret;
16086 }
16087
16088 static int
16089 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
16090 {
16091   unformat_input_t *i = vam->input;
16092   vl_api_ipsec_tunnel_if_set_sa_t *mp;
16093   u32 sw_if_index = ~0;
16094   u32 sa_id = ~0;
16095   u8 is_outbound = (u8) ~ 0;
16096   int ret;
16097
16098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16099     {
16100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16101         ;
16102       else if (unformat (i, "sa_id %d", &sa_id))
16103         ;
16104       else if (unformat (i, "outbound"))
16105         is_outbound = 1;
16106       else if (unformat (i, "inbound"))
16107         is_outbound = 0;
16108       else
16109         {
16110           clib_warning ("parse error '%U'", format_unformat_error, i);
16111           return -99;
16112         }
16113     }
16114
16115   if (sw_if_index == ~0)
16116     {
16117       errmsg ("interface must be specified");
16118       return -99;
16119     }
16120
16121   if (sa_id == ~0)
16122     {
16123       errmsg ("SA ID must be specified");
16124       return -99;
16125     }
16126
16127   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16128
16129   mp->sw_if_index = htonl (sw_if_index);
16130   mp->sa_id = htonl (sa_id);
16131   mp->is_outbound = is_outbound;
16132
16133   S (mp);
16134   W (ret);
16135
16136   return ret;
16137 }
16138
16139 static int
16140 api_ikev2_profile_add_del (vat_main_t * vam)
16141 {
16142   unformat_input_t *i = vam->input;
16143   vl_api_ikev2_profile_add_del_t *mp;
16144   u8 is_add = 1;
16145   u8 *name = 0;
16146   int ret;
16147
16148   const char *valid_chars = "a-zA-Z0-9_";
16149
16150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16151     {
16152       if (unformat (i, "del"))
16153         is_add = 0;
16154       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16155         vec_add1 (name, 0);
16156       else
16157         {
16158           errmsg ("parse error '%U'", format_unformat_error, i);
16159           return -99;
16160         }
16161     }
16162
16163   if (!vec_len (name))
16164     {
16165       errmsg ("profile name must be specified");
16166       return -99;
16167     }
16168
16169   if (vec_len (name) > 64)
16170     {
16171       errmsg ("profile name too long");
16172       return -99;
16173     }
16174
16175   M (IKEV2_PROFILE_ADD_DEL, mp);
16176
16177   clib_memcpy (mp->name, name, vec_len (name));
16178   mp->is_add = is_add;
16179   vec_free (name);
16180
16181   S (mp);
16182   W (ret);
16183   return ret;
16184 }
16185
16186 static int
16187 api_ikev2_profile_set_auth (vat_main_t * vam)
16188 {
16189   unformat_input_t *i = vam->input;
16190   vl_api_ikev2_profile_set_auth_t *mp;
16191   u8 *name = 0;
16192   u8 *data = 0;
16193   u32 auth_method = 0;
16194   u8 is_hex = 0;
16195   int ret;
16196
16197   const char *valid_chars = "a-zA-Z0-9_";
16198
16199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16200     {
16201       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16202         vec_add1 (name, 0);
16203       else if (unformat (i, "auth_method %U",
16204                          unformat_ikev2_auth_method, &auth_method))
16205         ;
16206       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16207         is_hex = 1;
16208       else if (unformat (i, "auth_data %v", &data))
16209         ;
16210       else
16211         {
16212           errmsg ("parse error '%U'", format_unformat_error, i);
16213           return -99;
16214         }
16215     }
16216
16217   if (!vec_len (name))
16218     {
16219       errmsg ("profile name must be specified");
16220       return -99;
16221     }
16222
16223   if (vec_len (name) > 64)
16224     {
16225       errmsg ("profile name too long");
16226       return -99;
16227     }
16228
16229   if (!vec_len (data))
16230     {
16231       errmsg ("auth_data must be specified");
16232       return -99;
16233     }
16234
16235   if (!auth_method)
16236     {
16237       errmsg ("auth_method must be specified");
16238       return -99;
16239     }
16240
16241   M (IKEV2_PROFILE_SET_AUTH, mp);
16242
16243   mp->is_hex = is_hex;
16244   mp->auth_method = (u8) auth_method;
16245   mp->data_len = vec_len (data);
16246   clib_memcpy (mp->name, name, vec_len (name));
16247   clib_memcpy (mp->data, data, vec_len (data));
16248   vec_free (name);
16249   vec_free (data);
16250
16251   S (mp);
16252   W (ret);
16253   return ret;
16254 }
16255
16256 static int
16257 api_ikev2_profile_set_id (vat_main_t * vam)
16258 {
16259   unformat_input_t *i = vam->input;
16260   vl_api_ikev2_profile_set_id_t *mp;
16261   u8 *name = 0;
16262   u8 *data = 0;
16263   u8 is_local = 0;
16264   u32 id_type = 0;
16265   ip4_address_t ip4;
16266   int ret;
16267
16268   const char *valid_chars = "a-zA-Z0-9_";
16269
16270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16271     {
16272       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16273         vec_add1 (name, 0);
16274       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16275         ;
16276       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16277         {
16278           data = vec_new (u8, 4);
16279           clib_memcpy (data, ip4.as_u8, 4);
16280         }
16281       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16282         ;
16283       else if (unformat (i, "id_data %v", &data))
16284         ;
16285       else if (unformat (i, "local"))
16286         is_local = 1;
16287       else if (unformat (i, "remote"))
16288         is_local = 0;
16289       else
16290         {
16291           errmsg ("parse error '%U'", format_unformat_error, i);
16292           return -99;
16293         }
16294     }
16295
16296   if (!vec_len (name))
16297     {
16298       errmsg ("profile name must be specified");
16299       return -99;
16300     }
16301
16302   if (vec_len (name) > 64)
16303     {
16304       errmsg ("profile name too long");
16305       return -99;
16306     }
16307
16308   if (!vec_len (data))
16309     {
16310       errmsg ("id_data must be specified");
16311       return -99;
16312     }
16313
16314   if (!id_type)
16315     {
16316       errmsg ("id_type must be specified");
16317       return -99;
16318     }
16319
16320   M (IKEV2_PROFILE_SET_ID, mp);
16321
16322   mp->is_local = is_local;
16323   mp->id_type = (u8) id_type;
16324   mp->data_len = vec_len (data);
16325   clib_memcpy (mp->name, name, vec_len (name));
16326   clib_memcpy (mp->data, data, vec_len (data));
16327   vec_free (name);
16328   vec_free (data);
16329
16330   S (mp);
16331   W (ret);
16332   return ret;
16333 }
16334
16335 static int
16336 api_ikev2_profile_set_ts (vat_main_t * vam)
16337 {
16338   unformat_input_t *i = vam->input;
16339   vl_api_ikev2_profile_set_ts_t *mp;
16340   u8 *name = 0;
16341   u8 is_local = 0;
16342   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16343   ip4_address_t start_addr, end_addr;
16344
16345   const char *valid_chars = "a-zA-Z0-9_";
16346   int ret;
16347
16348   start_addr.as_u32 = 0;
16349   end_addr.as_u32 = (u32) ~ 0;
16350
16351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16352     {
16353       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16354         vec_add1 (name, 0);
16355       else if (unformat (i, "protocol %d", &proto))
16356         ;
16357       else if (unformat (i, "start_port %d", &start_port))
16358         ;
16359       else if (unformat (i, "end_port %d", &end_port))
16360         ;
16361       else
16362         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16363         ;
16364       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16365         ;
16366       else if (unformat (i, "local"))
16367         is_local = 1;
16368       else if (unformat (i, "remote"))
16369         is_local = 0;
16370       else
16371         {
16372           errmsg ("parse error '%U'", format_unformat_error, i);
16373           return -99;
16374         }
16375     }
16376
16377   if (!vec_len (name))
16378     {
16379       errmsg ("profile name must be specified");
16380       return -99;
16381     }
16382
16383   if (vec_len (name) > 64)
16384     {
16385       errmsg ("profile name too long");
16386       return -99;
16387     }
16388
16389   M (IKEV2_PROFILE_SET_TS, mp);
16390
16391   mp->is_local = is_local;
16392   mp->proto = (u8) proto;
16393   mp->start_port = (u16) start_port;
16394   mp->end_port = (u16) end_port;
16395   mp->start_addr = start_addr.as_u32;
16396   mp->end_addr = end_addr.as_u32;
16397   clib_memcpy (mp->name, name, vec_len (name));
16398   vec_free (name);
16399
16400   S (mp);
16401   W (ret);
16402   return ret;
16403 }
16404
16405 static int
16406 api_ikev2_set_local_key (vat_main_t * vam)
16407 {
16408   unformat_input_t *i = vam->input;
16409   vl_api_ikev2_set_local_key_t *mp;
16410   u8 *file = 0;
16411   int ret;
16412
16413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16414     {
16415       if (unformat (i, "file %v", &file))
16416         vec_add1 (file, 0);
16417       else
16418         {
16419           errmsg ("parse error '%U'", format_unformat_error, i);
16420           return -99;
16421         }
16422     }
16423
16424   if (!vec_len (file))
16425     {
16426       errmsg ("RSA key file must be specified");
16427       return -99;
16428     }
16429
16430   if (vec_len (file) > 256)
16431     {
16432       errmsg ("file name too long");
16433       return -99;
16434     }
16435
16436   M (IKEV2_SET_LOCAL_KEY, mp);
16437
16438   clib_memcpy (mp->key_file, file, vec_len (file));
16439   vec_free (file);
16440
16441   S (mp);
16442   W (ret);
16443   return ret;
16444 }
16445
16446 static int
16447 api_ikev2_set_responder (vat_main_t * vam)
16448 {
16449   unformat_input_t *i = vam->input;
16450   vl_api_ikev2_set_responder_t *mp;
16451   int ret;
16452   u8 *name = 0;
16453   u32 sw_if_index = ~0;
16454   ip4_address_t address;
16455
16456   const char *valid_chars = "a-zA-Z0-9_";
16457
16458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16459     {
16460       if (unformat
16461           (i, "%U interface %d address %U", unformat_token, valid_chars,
16462            &name, &sw_if_index, unformat_ip4_address, &address))
16463         vec_add1 (name, 0);
16464       else
16465         {
16466           errmsg ("parse error '%U'", format_unformat_error, i);
16467           return -99;
16468         }
16469     }
16470
16471   if (!vec_len (name))
16472     {
16473       errmsg ("profile name must be specified");
16474       return -99;
16475     }
16476
16477   if (vec_len (name) > 64)
16478     {
16479       errmsg ("profile name too long");
16480       return -99;
16481     }
16482
16483   M (IKEV2_SET_RESPONDER, mp);
16484
16485   clib_memcpy (mp->name, name, vec_len (name));
16486   vec_free (name);
16487
16488   mp->sw_if_index = sw_if_index;
16489   clib_memcpy (mp->address, &address, sizeof (address));
16490
16491   S (mp);
16492   W (ret);
16493   return ret;
16494 }
16495
16496 static int
16497 api_ikev2_set_ike_transforms (vat_main_t * vam)
16498 {
16499   unformat_input_t *i = vam->input;
16500   vl_api_ikev2_set_ike_transforms_t *mp;
16501   int ret;
16502   u8 *name = 0;
16503   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16504
16505   const char *valid_chars = "a-zA-Z0-9_";
16506
16507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16508     {
16509       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16510                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16511         vec_add1 (name, 0);
16512       else
16513         {
16514           errmsg ("parse error '%U'", format_unformat_error, i);
16515           return -99;
16516         }
16517     }
16518
16519   if (!vec_len (name))
16520     {
16521       errmsg ("profile name must be specified");
16522       return -99;
16523     }
16524
16525   if (vec_len (name) > 64)
16526     {
16527       errmsg ("profile name too long");
16528       return -99;
16529     }
16530
16531   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16532
16533   clib_memcpy (mp->name, name, vec_len (name));
16534   vec_free (name);
16535   mp->crypto_alg = crypto_alg;
16536   mp->crypto_key_size = crypto_key_size;
16537   mp->integ_alg = integ_alg;
16538   mp->dh_group = dh_group;
16539
16540   S (mp);
16541   W (ret);
16542   return ret;
16543 }
16544
16545
16546 static int
16547 api_ikev2_set_esp_transforms (vat_main_t * vam)
16548 {
16549   unformat_input_t *i = vam->input;
16550   vl_api_ikev2_set_esp_transforms_t *mp;
16551   int ret;
16552   u8 *name = 0;
16553   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16554
16555   const char *valid_chars = "a-zA-Z0-9_";
16556
16557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16558     {
16559       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16560                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16561         vec_add1 (name, 0);
16562       else
16563         {
16564           errmsg ("parse error '%U'", format_unformat_error, i);
16565           return -99;
16566         }
16567     }
16568
16569   if (!vec_len (name))
16570     {
16571       errmsg ("profile name must be specified");
16572       return -99;
16573     }
16574
16575   if (vec_len (name) > 64)
16576     {
16577       errmsg ("profile name too long");
16578       return -99;
16579     }
16580
16581   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16582
16583   clib_memcpy (mp->name, name, vec_len (name));
16584   vec_free (name);
16585   mp->crypto_alg = crypto_alg;
16586   mp->crypto_key_size = crypto_key_size;
16587   mp->integ_alg = integ_alg;
16588   mp->dh_group = dh_group;
16589
16590   S (mp);
16591   W (ret);
16592   return ret;
16593 }
16594
16595 static int
16596 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16597 {
16598   unformat_input_t *i = vam->input;
16599   vl_api_ikev2_set_sa_lifetime_t *mp;
16600   int ret;
16601   u8 *name = 0;
16602   u64 lifetime, lifetime_maxdata;
16603   u32 lifetime_jitter, handover;
16604
16605   const char *valid_chars = "a-zA-Z0-9_";
16606
16607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16608     {
16609       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16610                     &lifetime, &lifetime_jitter, &handover,
16611                     &lifetime_maxdata))
16612         vec_add1 (name, 0);
16613       else
16614         {
16615           errmsg ("parse error '%U'", format_unformat_error, i);
16616           return -99;
16617         }
16618     }
16619
16620   if (!vec_len (name))
16621     {
16622       errmsg ("profile name must be specified");
16623       return -99;
16624     }
16625
16626   if (vec_len (name) > 64)
16627     {
16628       errmsg ("profile name too long");
16629       return -99;
16630     }
16631
16632   M (IKEV2_SET_SA_LIFETIME, mp);
16633
16634   clib_memcpy (mp->name, name, vec_len (name));
16635   vec_free (name);
16636   mp->lifetime = lifetime;
16637   mp->lifetime_jitter = lifetime_jitter;
16638   mp->handover = handover;
16639   mp->lifetime_maxdata = lifetime_maxdata;
16640
16641   S (mp);
16642   W (ret);
16643   return ret;
16644 }
16645
16646 static int
16647 api_ikev2_initiate_sa_init (vat_main_t * vam)
16648 {
16649   unformat_input_t *i = vam->input;
16650   vl_api_ikev2_initiate_sa_init_t *mp;
16651   int ret;
16652   u8 *name = 0;
16653
16654   const char *valid_chars = "a-zA-Z0-9_";
16655
16656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16657     {
16658       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16659         vec_add1 (name, 0);
16660       else
16661         {
16662           errmsg ("parse error '%U'", format_unformat_error, i);
16663           return -99;
16664         }
16665     }
16666
16667   if (!vec_len (name))
16668     {
16669       errmsg ("profile name must be specified");
16670       return -99;
16671     }
16672
16673   if (vec_len (name) > 64)
16674     {
16675       errmsg ("profile name too long");
16676       return -99;
16677     }
16678
16679   M (IKEV2_INITIATE_SA_INIT, mp);
16680
16681   clib_memcpy (mp->name, name, vec_len (name));
16682   vec_free (name);
16683
16684   S (mp);
16685   W (ret);
16686   return ret;
16687 }
16688
16689 static int
16690 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16691 {
16692   unformat_input_t *i = vam->input;
16693   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16694   int ret;
16695   u64 ispi;
16696
16697
16698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16699     {
16700       if (unformat (i, "%lx", &ispi))
16701         ;
16702       else
16703         {
16704           errmsg ("parse error '%U'", format_unformat_error, i);
16705           return -99;
16706         }
16707     }
16708
16709   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16710
16711   mp->ispi = ispi;
16712
16713   S (mp);
16714   W (ret);
16715   return ret;
16716 }
16717
16718 static int
16719 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16720 {
16721   unformat_input_t *i = vam->input;
16722   vl_api_ikev2_initiate_del_child_sa_t *mp;
16723   int ret;
16724   u32 ispi;
16725
16726
16727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16728     {
16729       if (unformat (i, "%x", &ispi))
16730         ;
16731       else
16732         {
16733           errmsg ("parse error '%U'", format_unformat_error, i);
16734           return -99;
16735         }
16736     }
16737
16738   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16739
16740   mp->ispi = ispi;
16741
16742   S (mp);
16743   W (ret);
16744   return ret;
16745 }
16746
16747 static int
16748 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16749 {
16750   unformat_input_t *i = vam->input;
16751   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16752   int ret;
16753   u32 ispi;
16754
16755
16756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16757     {
16758       if (unformat (i, "%x", &ispi))
16759         ;
16760       else
16761         {
16762           errmsg ("parse error '%U'", format_unformat_error, i);
16763           return -99;
16764         }
16765     }
16766
16767   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16768
16769   mp->ispi = ispi;
16770
16771   S (mp);
16772   W (ret);
16773   return ret;
16774 }
16775
16776 static int
16777 api_get_first_msg_id (vat_main_t * vam)
16778 {
16779   vl_api_get_first_msg_id_t *mp;
16780   unformat_input_t *i = vam->input;
16781   u8 *name;
16782   u8 name_set = 0;
16783   int ret;
16784
16785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16786     {
16787       if (unformat (i, "client %s", &name))
16788         name_set = 1;
16789       else
16790         break;
16791     }
16792
16793   if (name_set == 0)
16794     {
16795       errmsg ("missing client name");
16796       return -99;
16797     }
16798   vec_add1 (name, 0);
16799
16800   if (vec_len (name) > 63)
16801     {
16802       errmsg ("client name too long");
16803       return -99;
16804     }
16805
16806   M (GET_FIRST_MSG_ID, mp);
16807   clib_memcpy (mp->name, name, vec_len (name));
16808   S (mp);
16809   W (ret);
16810   return ret;
16811 }
16812
16813 static int
16814 api_cop_interface_enable_disable (vat_main_t * vam)
16815 {
16816   unformat_input_t *line_input = vam->input;
16817   vl_api_cop_interface_enable_disable_t *mp;
16818   u32 sw_if_index = ~0;
16819   u8 enable_disable = 1;
16820   int ret;
16821
16822   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16823     {
16824       if (unformat (line_input, "disable"))
16825         enable_disable = 0;
16826       if (unformat (line_input, "enable"))
16827         enable_disable = 1;
16828       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16829                          vam, &sw_if_index))
16830         ;
16831       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16832         ;
16833       else
16834         break;
16835     }
16836
16837   if (sw_if_index == ~0)
16838     {
16839       errmsg ("missing interface name or sw_if_index");
16840       return -99;
16841     }
16842
16843   /* Construct the API message */
16844   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16845   mp->sw_if_index = ntohl (sw_if_index);
16846   mp->enable_disable = enable_disable;
16847
16848   /* send it... */
16849   S (mp);
16850   /* Wait for the reply */
16851   W (ret);
16852   return ret;
16853 }
16854
16855 static int
16856 api_cop_whitelist_enable_disable (vat_main_t * vam)
16857 {
16858   unformat_input_t *line_input = vam->input;
16859   vl_api_cop_whitelist_enable_disable_t *mp;
16860   u32 sw_if_index = ~0;
16861   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16862   u32 fib_id = 0;
16863   int ret;
16864
16865   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16866     {
16867       if (unformat (line_input, "ip4"))
16868         ip4 = 1;
16869       else if (unformat (line_input, "ip6"))
16870         ip6 = 1;
16871       else if (unformat (line_input, "default"))
16872         default_cop = 1;
16873       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16874                          vam, &sw_if_index))
16875         ;
16876       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16877         ;
16878       else if (unformat (line_input, "fib-id %d", &fib_id))
16879         ;
16880       else
16881         break;
16882     }
16883
16884   if (sw_if_index == ~0)
16885     {
16886       errmsg ("missing interface name or sw_if_index");
16887       return -99;
16888     }
16889
16890   /* Construct the API message */
16891   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16892   mp->sw_if_index = ntohl (sw_if_index);
16893   mp->fib_id = ntohl (fib_id);
16894   mp->ip4 = ip4;
16895   mp->ip6 = ip6;
16896   mp->default_cop = default_cop;
16897
16898   /* send it... */
16899   S (mp);
16900   /* Wait for the reply */
16901   W (ret);
16902   return ret;
16903 }
16904
16905 static int
16906 api_get_node_graph (vat_main_t * vam)
16907 {
16908   vl_api_get_node_graph_t *mp;
16909   int ret;
16910
16911   M (GET_NODE_GRAPH, mp);
16912
16913   /* send it... */
16914   S (mp);
16915   /* Wait for the reply */
16916   W (ret);
16917   return ret;
16918 }
16919
16920 /* *INDENT-OFF* */
16921 /** Used for parsing LISP eids */
16922 typedef CLIB_PACKED(struct{
16923   u8 addr[16];   /**< eid address */
16924   u32 len;       /**< prefix length if IP */
16925   u8 type;      /**< type of eid */
16926 }) lisp_eid_vat_t;
16927 /* *INDENT-ON* */
16928
16929 static uword
16930 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16931 {
16932   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16933
16934   clib_memset (a, 0, sizeof (a[0]));
16935
16936   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16937     {
16938       a->type = 0;              /* ipv4 type */
16939     }
16940   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16941     {
16942       a->type = 1;              /* ipv6 type */
16943     }
16944   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16945     {
16946       a->type = 2;              /* mac type */
16947     }
16948   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16949     {
16950       a->type = 3;              /* NSH type */
16951       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16952       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16953     }
16954   else
16955     {
16956       return 0;
16957     }
16958
16959   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16960     {
16961       return 0;
16962     }
16963
16964   return 1;
16965 }
16966
16967 static int
16968 lisp_eid_size_vat (u8 type)
16969 {
16970   switch (type)
16971     {
16972     case 0:
16973       return 4;
16974     case 1:
16975       return 16;
16976     case 2:
16977       return 6;
16978     case 3:
16979       return 5;
16980     }
16981   return 0;
16982 }
16983
16984 static void
16985 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16986 {
16987   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16988 }
16989
16990 static int
16991 api_one_add_del_locator_set (vat_main_t * vam)
16992 {
16993   unformat_input_t *input = vam->input;
16994   vl_api_one_add_del_locator_set_t *mp;
16995   u8 is_add = 1;
16996   u8 *locator_set_name = NULL;
16997   u8 locator_set_name_set = 0;
16998   vl_api_local_locator_t locator, *locators = 0;
16999   u32 sw_if_index, priority, weight;
17000   u32 data_len = 0;
17001
17002   int ret;
17003   /* Parse args required to build the message */
17004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17005     {
17006       if (unformat (input, "del"))
17007         {
17008           is_add = 0;
17009         }
17010       else if (unformat (input, "locator-set %s", &locator_set_name))
17011         {
17012           locator_set_name_set = 1;
17013         }
17014       else if (unformat (input, "sw_if_index %u p %u w %u",
17015                          &sw_if_index, &priority, &weight))
17016         {
17017           locator.sw_if_index = htonl (sw_if_index);
17018           locator.priority = priority;
17019           locator.weight = weight;
17020           vec_add1 (locators, locator);
17021         }
17022       else
17023         if (unformat
17024             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
17025              &sw_if_index, &priority, &weight))
17026         {
17027           locator.sw_if_index = htonl (sw_if_index);
17028           locator.priority = priority;
17029           locator.weight = weight;
17030           vec_add1 (locators, locator);
17031         }
17032       else
17033         break;
17034     }
17035
17036   if (locator_set_name_set == 0)
17037     {
17038       errmsg ("missing locator-set name");
17039       vec_free (locators);
17040       return -99;
17041     }
17042
17043   if (vec_len (locator_set_name) > 64)
17044     {
17045       errmsg ("locator-set name too long");
17046       vec_free (locator_set_name);
17047       vec_free (locators);
17048       return -99;
17049     }
17050   vec_add1 (locator_set_name, 0);
17051
17052   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
17053
17054   /* Construct the API message */
17055   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
17056
17057   mp->is_add = is_add;
17058   clib_memcpy (mp->locator_set_name, locator_set_name,
17059                vec_len (locator_set_name));
17060   vec_free (locator_set_name);
17061
17062   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
17063   if (locators)
17064     clib_memcpy (mp->locators, locators, data_len);
17065   vec_free (locators);
17066
17067   /* send it... */
17068   S (mp);
17069
17070   /* Wait for a reply... */
17071   W (ret);
17072   return ret;
17073 }
17074
17075 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
17076
17077 static int
17078 api_one_add_del_locator (vat_main_t * vam)
17079 {
17080   unformat_input_t *input = vam->input;
17081   vl_api_one_add_del_locator_t *mp;
17082   u32 tmp_if_index = ~0;
17083   u32 sw_if_index = ~0;
17084   u8 sw_if_index_set = 0;
17085   u8 sw_if_index_if_name_set = 0;
17086   u32 priority = ~0;
17087   u8 priority_set = 0;
17088   u32 weight = ~0;
17089   u8 weight_set = 0;
17090   u8 is_add = 1;
17091   u8 *locator_set_name = NULL;
17092   u8 locator_set_name_set = 0;
17093   int ret;
17094
17095   /* Parse args required to build the message */
17096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17097     {
17098       if (unformat (input, "del"))
17099         {
17100           is_add = 0;
17101         }
17102       else if (unformat (input, "locator-set %s", &locator_set_name))
17103         {
17104           locator_set_name_set = 1;
17105         }
17106       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
17107                          &tmp_if_index))
17108         {
17109           sw_if_index_if_name_set = 1;
17110           sw_if_index = tmp_if_index;
17111         }
17112       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17113         {
17114           sw_if_index_set = 1;
17115           sw_if_index = tmp_if_index;
17116         }
17117       else if (unformat (input, "p %d", &priority))
17118         {
17119           priority_set = 1;
17120         }
17121       else if (unformat (input, "w %d", &weight))
17122         {
17123           weight_set = 1;
17124         }
17125       else
17126         break;
17127     }
17128
17129   if (locator_set_name_set == 0)
17130     {
17131       errmsg ("missing locator-set name");
17132       return -99;
17133     }
17134
17135   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17136     {
17137       errmsg ("missing sw_if_index");
17138       vec_free (locator_set_name);
17139       return -99;
17140     }
17141
17142   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17143     {
17144       errmsg ("cannot use both params interface name and sw_if_index");
17145       vec_free (locator_set_name);
17146       return -99;
17147     }
17148
17149   if (priority_set == 0)
17150     {
17151       errmsg ("missing locator-set priority");
17152       vec_free (locator_set_name);
17153       return -99;
17154     }
17155
17156   if (weight_set == 0)
17157     {
17158       errmsg ("missing locator-set weight");
17159       vec_free (locator_set_name);
17160       return -99;
17161     }
17162
17163   if (vec_len (locator_set_name) > 64)
17164     {
17165       errmsg ("locator-set name too long");
17166       vec_free (locator_set_name);
17167       return -99;
17168     }
17169   vec_add1 (locator_set_name, 0);
17170
17171   /* Construct the API message */
17172   M (ONE_ADD_DEL_LOCATOR, mp);
17173
17174   mp->is_add = is_add;
17175   mp->sw_if_index = ntohl (sw_if_index);
17176   mp->priority = priority;
17177   mp->weight = weight;
17178   clib_memcpy (mp->locator_set_name, locator_set_name,
17179                vec_len (locator_set_name));
17180   vec_free (locator_set_name);
17181
17182   /* send it... */
17183   S (mp);
17184
17185   /* Wait for a reply... */
17186   W (ret);
17187   return ret;
17188 }
17189
17190 #define api_lisp_add_del_locator api_one_add_del_locator
17191
17192 uword
17193 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17194 {
17195   u32 *key_id = va_arg (*args, u32 *);
17196   u8 *s = 0;
17197
17198   if (unformat (input, "%s", &s))
17199     {
17200       if (!strcmp ((char *) s, "sha1"))
17201         key_id[0] = HMAC_SHA_1_96;
17202       else if (!strcmp ((char *) s, "sha256"))
17203         key_id[0] = HMAC_SHA_256_128;
17204       else
17205         {
17206           clib_warning ("invalid key_id: '%s'", s);
17207           key_id[0] = HMAC_NO_KEY;
17208         }
17209     }
17210   else
17211     return 0;
17212
17213   vec_free (s);
17214   return 1;
17215 }
17216
17217 static int
17218 api_one_add_del_local_eid (vat_main_t * vam)
17219 {
17220   unformat_input_t *input = vam->input;
17221   vl_api_one_add_del_local_eid_t *mp;
17222   u8 is_add = 1;
17223   u8 eid_set = 0;
17224   lisp_eid_vat_t _eid, *eid = &_eid;
17225   u8 *locator_set_name = 0;
17226   u8 locator_set_name_set = 0;
17227   u32 vni = 0;
17228   u16 key_id = 0;
17229   u8 *key = 0;
17230   int ret;
17231
17232   /* Parse args required to build the message */
17233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17234     {
17235       if (unformat (input, "del"))
17236         {
17237           is_add = 0;
17238         }
17239       else if (unformat (input, "vni %d", &vni))
17240         {
17241           ;
17242         }
17243       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17244         {
17245           eid_set = 1;
17246         }
17247       else if (unformat (input, "locator-set %s", &locator_set_name))
17248         {
17249           locator_set_name_set = 1;
17250         }
17251       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17252         ;
17253       else if (unformat (input, "secret-key %_%v%_", &key))
17254         ;
17255       else
17256         break;
17257     }
17258
17259   if (locator_set_name_set == 0)
17260     {
17261       errmsg ("missing locator-set name");
17262       return -99;
17263     }
17264
17265   if (0 == eid_set)
17266     {
17267       errmsg ("EID address not set!");
17268       vec_free (locator_set_name);
17269       return -99;
17270     }
17271
17272   if (key && (0 == key_id))
17273     {
17274       errmsg ("invalid key_id!");
17275       return -99;
17276     }
17277
17278   if (vec_len (key) > 64)
17279     {
17280       errmsg ("key too long");
17281       vec_free (key);
17282       return -99;
17283     }
17284
17285   if (vec_len (locator_set_name) > 64)
17286     {
17287       errmsg ("locator-set name too long");
17288       vec_free (locator_set_name);
17289       return -99;
17290     }
17291   vec_add1 (locator_set_name, 0);
17292
17293   /* Construct the API message */
17294   M (ONE_ADD_DEL_LOCAL_EID, mp);
17295
17296   mp->is_add = is_add;
17297   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17298   mp->eid_type = eid->type;
17299   mp->prefix_len = eid->len;
17300   mp->vni = clib_host_to_net_u32 (vni);
17301   mp->key_id = clib_host_to_net_u16 (key_id);
17302   clib_memcpy (mp->locator_set_name, locator_set_name,
17303                vec_len (locator_set_name));
17304   clib_memcpy (mp->key, key, vec_len (key));
17305
17306   vec_free (locator_set_name);
17307   vec_free (key);
17308
17309   /* send it... */
17310   S (mp);
17311
17312   /* Wait for a reply... */
17313   W (ret);
17314   return ret;
17315 }
17316
17317 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17318
17319 static int
17320 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17321 {
17322   u32 dp_table = 0, vni = 0;;
17323   unformat_input_t *input = vam->input;
17324   vl_api_gpe_add_del_fwd_entry_t *mp;
17325   u8 is_add = 1;
17326   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17327   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17328   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17329   u32 action = ~0, w;
17330   ip4_address_t rmt_rloc4, lcl_rloc4;
17331   ip6_address_t rmt_rloc6, lcl_rloc6;
17332   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17333   int ret;
17334
17335   clib_memset (&rloc, 0, sizeof (rloc));
17336
17337   /* Parse args required to build the message */
17338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17339     {
17340       if (unformat (input, "del"))
17341         is_add = 0;
17342       else if (unformat (input, "add"))
17343         is_add = 1;
17344       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17345         {
17346           rmt_eid_set = 1;
17347         }
17348       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17349         {
17350           lcl_eid_set = 1;
17351         }
17352       else if (unformat (input, "vrf %d", &dp_table))
17353         ;
17354       else if (unformat (input, "bd %d", &dp_table))
17355         ;
17356       else if (unformat (input, "vni %d", &vni))
17357         ;
17358       else if (unformat (input, "w %d", &w))
17359         {
17360           if (!curr_rloc)
17361             {
17362               errmsg ("No RLOC configured for setting priority/weight!");
17363               return -99;
17364             }
17365           curr_rloc->weight = w;
17366         }
17367       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17368                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17369         {
17370           rloc.is_ip4 = 1;
17371
17372           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17373           rloc.weight = 0;
17374           vec_add1 (lcl_locs, rloc);
17375
17376           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17377           vec_add1 (rmt_locs, rloc);
17378           /* weight saved in rmt loc */
17379           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17380         }
17381       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17382                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17383         {
17384           rloc.is_ip4 = 0;
17385           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17386           rloc.weight = 0;
17387           vec_add1 (lcl_locs, rloc);
17388
17389           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17390           vec_add1 (rmt_locs, rloc);
17391           /* weight saved in rmt loc */
17392           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17393         }
17394       else if (unformat (input, "action %d", &action))
17395         {
17396           ;
17397         }
17398       else
17399         {
17400           clib_warning ("parse error '%U'", format_unformat_error, input);
17401           return -99;
17402         }
17403     }
17404
17405   if (!rmt_eid_set)
17406     {
17407       errmsg ("remote eid addresses not set");
17408       return -99;
17409     }
17410
17411   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17412     {
17413       errmsg ("eid types don't match");
17414       return -99;
17415     }
17416
17417   if (0 == rmt_locs && (u32) ~ 0 == action)
17418     {
17419       errmsg ("action not set for negative mapping");
17420       return -99;
17421     }
17422
17423   /* Construct the API message */
17424   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17425       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17426
17427   mp->is_add = is_add;
17428   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17429   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17430   mp->eid_type = rmt_eid->type;
17431   mp->dp_table = clib_host_to_net_u32 (dp_table);
17432   mp->vni = clib_host_to_net_u32 (vni);
17433   mp->rmt_len = rmt_eid->len;
17434   mp->lcl_len = lcl_eid->len;
17435   mp->action = action;
17436
17437   if (0 != rmt_locs && 0 != lcl_locs)
17438     {
17439       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17440       clib_memcpy (mp->locs, lcl_locs,
17441                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17442
17443       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17444       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17445                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17446     }
17447   vec_free (lcl_locs);
17448   vec_free (rmt_locs);
17449
17450   /* send it... */
17451   S (mp);
17452
17453   /* Wait for a reply... */
17454   W (ret);
17455   return ret;
17456 }
17457
17458 static int
17459 api_one_add_del_map_server (vat_main_t * vam)
17460 {
17461   unformat_input_t *input = vam->input;
17462   vl_api_one_add_del_map_server_t *mp;
17463   u8 is_add = 1;
17464   u8 ipv4_set = 0;
17465   u8 ipv6_set = 0;
17466   ip4_address_t ipv4;
17467   ip6_address_t ipv6;
17468   int ret;
17469
17470   /* Parse args required to build the message */
17471   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17472     {
17473       if (unformat (input, "del"))
17474         {
17475           is_add = 0;
17476         }
17477       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17478         {
17479           ipv4_set = 1;
17480         }
17481       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17482         {
17483           ipv6_set = 1;
17484         }
17485       else
17486         break;
17487     }
17488
17489   if (ipv4_set && ipv6_set)
17490     {
17491       errmsg ("both eid v4 and v6 addresses set");
17492       return -99;
17493     }
17494
17495   if (!ipv4_set && !ipv6_set)
17496     {
17497       errmsg ("eid addresses not set");
17498       return -99;
17499     }
17500
17501   /* Construct the API message */
17502   M (ONE_ADD_DEL_MAP_SERVER, mp);
17503
17504   mp->is_add = is_add;
17505   if (ipv6_set)
17506     {
17507       mp->is_ipv6 = 1;
17508       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17509     }
17510   else
17511     {
17512       mp->is_ipv6 = 0;
17513       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17514     }
17515
17516   /* send it... */
17517   S (mp);
17518
17519   /* Wait for a reply... */
17520   W (ret);
17521   return ret;
17522 }
17523
17524 #define api_lisp_add_del_map_server api_one_add_del_map_server
17525
17526 static int
17527 api_one_add_del_map_resolver (vat_main_t * vam)
17528 {
17529   unformat_input_t *input = vam->input;
17530   vl_api_one_add_del_map_resolver_t *mp;
17531   u8 is_add = 1;
17532   u8 ipv4_set = 0;
17533   u8 ipv6_set = 0;
17534   ip4_address_t ipv4;
17535   ip6_address_t ipv6;
17536   int ret;
17537
17538   /* Parse args required to build the message */
17539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17540     {
17541       if (unformat (input, "del"))
17542         {
17543           is_add = 0;
17544         }
17545       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17546         {
17547           ipv4_set = 1;
17548         }
17549       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17550         {
17551           ipv6_set = 1;
17552         }
17553       else
17554         break;
17555     }
17556
17557   if (ipv4_set && ipv6_set)
17558     {
17559       errmsg ("both eid v4 and v6 addresses set");
17560       return -99;
17561     }
17562
17563   if (!ipv4_set && !ipv6_set)
17564     {
17565       errmsg ("eid addresses not set");
17566       return -99;
17567     }
17568
17569   /* Construct the API message */
17570   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17571
17572   mp->is_add = is_add;
17573   if (ipv6_set)
17574     {
17575       mp->is_ipv6 = 1;
17576       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17577     }
17578   else
17579     {
17580       mp->is_ipv6 = 0;
17581       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17582     }
17583
17584   /* send it... */
17585   S (mp);
17586
17587   /* Wait for a reply... */
17588   W (ret);
17589   return ret;
17590 }
17591
17592 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17593
17594 static int
17595 api_lisp_gpe_enable_disable (vat_main_t * vam)
17596 {
17597   unformat_input_t *input = vam->input;
17598   vl_api_gpe_enable_disable_t *mp;
17599   u8 is_set = 0;
17600   u8 is_en = 1;
17601   int ret;
17602
17603   /* Parse args required to build the message */
17604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17605     {
17606       if (unformat (input, "enable"))
17607         {
17608           is_set = 1;
17609           is_en = 1;
17610         }
17611       else if (unformat (input, "disable"))
17612         {
17613           is_set = 1;
17614           is_en = 0;
17615         }
17616       else
17617         break;
17618     }
17619
17620   if (is_set == 0)
17621     {
17622       errmsg ("Value not set");
17623       return -99;
17624     }
17625
17626   /* Construct the API message */
17627   M (GPE_ENABLE_DISABLE, mp);
17628
17629   mp->is_en = is_en;
17630
17631   /* send it... */
17632   S (mp);
17633
17634   /* Wait for a reply... */
17635   W (ret);
17636   return ret;
17637 }
17638
17639 static int
17640 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17641 {
17642   unformat_input_t *input = vam->input;
17643   vl_api_one_rloc_probe_enable_disable_t *mp;
17644   u8 is_set = 0;
17645   u8 is_en = 0;
17646   int ret;
17647
17648   /* Parse args required to build the message */
17649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17650     {
17651       if (unformat (input, "enable"))
17652         {
17653           is_set = 1;
17654           is_en = 1;
17655         }
17656       else if (unformat (input, "disable"))
17657         is_set = 1;
17658       else
17659         break;
17660     }
17661
17662   if (!is_set)
17663     {
17664       errmsg ("Value not set");
17665       return -99;
17666     }
17667
17668   /* Construct the API message */
17669   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17670
17671   mp->is_enabled = is_en;
17672
17673   /* send it... */
17674   S (mp);
17675
17676   /* Wait for a reply... */
17677   W (ret);
17678   return ret;
17679 }
17680
17681 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17682
17683 static int
17684 api_one_map_register_enable_disable (vat_main_t * vam)
17685 {
17686   unformat_input_t *input = vam->input;
17687   vl_api_one_map_register_enable_disable_t *mp;
17688   u8 is_set = 0;
17689   u8 is_en = 0;
17690   int ret;
17691
17692   /* Parse args required to build the message */
17693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17694     {
17695       if (unformat (input, "enable"))
17696         {
17697           is_set = 1;
17698           is_en = 1;
17699         }
17700       else if (unformat (input, "disable"))
17701         is_set = 1;
17702       else
17703         break;
17704     }
17705
17706   if (!is_set)
17707     {
17708       errmsg ("Value not set");
17709       return -99;
17710     }
17711
17712   /* Construct the API message */
17713   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17714
17715   mp->is_enabled = is_en;
17716
17717   /* send it... */
17718   S (mp);
17719
17720   /* Wait for a reply... */
17721   W (ret);
17722   return ret;
17723 }
17724
17725 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17726
17727 static int
17728 api_one_enable_disable (vat_main_t * vam)
17729 {
17730   unformat_input_t *input = vam->input;
17731   vl_api_one_enable_disable_t *mp;
17732   u8 is_set = 0;
17733   u8 is_en = 0;
17734   int ret;
17735
17736   /* Parse args required to build the message */
17737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17738     {
17739       if (unformat (input, "enable"))
17740         {
17741           is_set = 1;
17742           is_en = 1;
17743         }
17744       else if (unformat (input, "disable"))
17745         {
17746           is_set = 1;
17747         }
17748       else
17749         break;
17750     }
17751
17752   if (!is_set)
17753     {
17754       errmsg ("Value not set");
17755       return -99;
17756     }
17757
17758   /* Construct the API message */
17759   M (ONE_ENABLE_DISABLE, mp);
17760
17761   mp->is_en = is_en;
17762
17763   /* send it... */
17764   S (mp);
17765
17766   /* Wait for a reply... */
17767   W (ret);
17768   return ret;
17769 }
17770
17771 #define api_lisp_enable_disable api_one_enable_disable
17772
17773 static int
17774 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17775 {
17776   unformat_input_t *input = vam->input;
17777   vl_api_one_enable_disable_xtr_mode_t *mp;
17778   u8 is_set = 0;
17779   u8 is_en = 0;
17780   int ret;
17781
17782   /* Parse args required to build the message */
17783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17784     {
17785       if (unformat (input, "enable"))
17786         {
17787           is_set = 1;
17788           is_en = 1;
17789         }
17790       else if (unformat (input, "disable"))
17791         {
17792           is_set = 1;
17793         }
17794       else
17795         break;
17796     }
17797
17798   if (!is_set)
17799     {
17800       errmsg ("Value not set");
17801       return -99;
17802     }
17803
17804   /* Construct the API message */
17805   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17806
17807   mp->is_en = is_en;
17808
17809   /* send it... */
17810   S (mp);
17811
17812   /* Wait for a reply... */
17813   W (ret);
17814   return ret;
17815 }
17816
17817 static int
17818 api_one_show_xtr_mode (vat_main_t * vam)
17819 {
17820   vl_api_one_show_xtr_mode_t *mp;
17821   int ret;
17822
17823   /* Construct the API message */
17824   M (ONE_SHOW_XTR_MODE, mp);
17825
17826   /* send it... */
17827   S (mp);
17828
17829   /* Wait for a reply... */
17830   W (ret);
17831   return ret;
17832 }
17833
17834 static int
17835 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17836 {
17837   unformat_input_t *input = vam->input;
17838   vl_api_one_enable_disable_pitr_mode_t *mp;
17839   u8 is_set = 0;
17840   u8 is_en = 0;
17841   int ret;
17842
17843   /* Parse args required to build the message */
17844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17845     {
17846       if (unformat (input, "enable"))
17847         {
17848           is_set = 1;
17849           is_en = 1;
17850         }
17851       else if (unformat (input, "disable"))
17852         {
17853           is_set = 1;
17854         }
17855       else
17856         break;
17857     }
17858
17859   if (!is_set)
17860     {
17861       errmsg ("Value not set");
17862       return -99;
17863     }
17864
17865   /* Construct the API message */
17866   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17867
17868   mp->is_en = is_en;
17869
17870   /* send it... */
17871   S (mp);
17872
17873   /* Wait for a reply... */
17874   W (ret);
17875   return ret;
17876 }
17877
17878 static int
17879 api_one_show_pitr_mode (vat_main_t * vam)
17880 {
17881   vl_api_one_show_pitr_mode_t *mp;
17882   int ret;
17883
17884   /* Construct the API message */
17885   M (ONE_SHOW_PITR_MODE, mp);
17886
17887   /* send it... */
17888   S (mp);
17889
17890   /* Wait for a reply... */
17891   W (ret);
17892   return ret;
17893 }
17894
17895 static int
17896 api_one_enable_disable_petr_mode (vat_main_t * vam)
17897 {
17898   unformat_input_t *input = vam->input;
17899   vl_api_one_enable_disable_petr_mode_t *mp;
17900   u8 is_set = 0;
17901   u8 is_en = 0;
17902   int ret;
17903
17904   /* Parse args required to build the message */
17905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17906     {
17907       if (unformat (input, "enable"))
17908         {
17909           is_set = 1;
17910           is_en = 1;
17911         }
17912       else if (unformat (input, "disable"))
17913         {
17914           is_set = 1;
17915         }
17916       else
17917         break;
17918     }
17919
17920   if (!is_set)
17921     {
17922       errmsg ("Value not set");
17923       return -99;
17924     }
17925
17926   /* Construct the API message */
17927   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17928
17929   mp->is_en = is_en;
17930
17931   /* send it... */
17932   S (mp);
17933
17934   /* Wait for a reply... */
17935   W (ret);
17936   return ret;
17937 }
17938
17939 static int
17940 api_one_show_petr_mode (vat_main_t * vam)
17941 {
17942   vl_api_one_show_petr_mode_t *mp;
17943   int ret;
17944
17945   /* Construct the API message */
17946   M (ONE_SHOW_PETR_MODE, mp);
17947
17948   /* send it... */
17949   S (mp);
17950
17951   /* Wait for a reply... */
17952   W (ret);
17953   return ret;
17954 }
17955
17956 static int
17957 api_show_one_map_register_state (vat_main_t * vam)
17958 {
17959   vl_api_show_one_map_register_state_t *mp;
17960   int ret;
17961
17962   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17963
17964   /* send */
17965   S (mp);
17966
17967   /* wait for reply */
17968   W (ret);
17969   return ret;
17970 }
17971
17972 #define api_show_lisp_map_register_state api_show_one_map_register_state
17973
17974 static int
17975 api_show_one_rloc_probe_state (vat_main_t * vam)
17976 {
17977   vl_api_show_one_rloc_probe_state_t *mp;
17978   int ret;
17979
17980   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17981
17982   /* send */
17983   S (mp);
17984
17985   /* wait for reply */
17986   W (ret);
17987   return ret;
17988 }
17989
17990 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17991
17992 static int
17993 api_one_add_del_ndp_entry (vat_main_t * vam)
17994 {
17995   vl_api_one_add_del_ndp_entry_t *mp;
17996   unformat_input_t *input = vam->input;
17997   u8 is_add = 1;
17998   u8 mac_set = 0;
17999   u8 bd_set = 0;
18000   u8 ip_set = 0;
18001   u8 mac[6] = { 0, };
18002   u8 ip6[16] = { 0, };
18003   u32 bd = ~0;
18004   int ret;
18005
18006   /* Parse args required to build the message */
18007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18008     {
18009       if (unformat (input, "del"))
18010         is_add = 0;
18011       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18012         mac_set = 1;
18013       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
18014         ip_set = 1;
18015       else if (unformat (input, "bd %d", &bd))
18016         bd_set = 1;
18017       else
18018         {
18019           errmsg ("parse error '%U'", format_unformat_error, input);
18020           return -99;
18021         }
18022     }
18023
18024   if (!bd_set || !ip_set || (!mac_set && is_add))
18025     {
18026       errmsg ("Missing BD, IP or MAC!");
18027       return -99;
18028     }
18029
18030   M (ONE_ADD_DEL_NDP_ENTRY, mp);
18031   mp->is_add = is_add;
18032   clib_memcpy (mp->mac, mac, 6);
18033   mp->bd = clib_host_to_net_u32 (bd);
18034   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
18035
18036   /* send */
18037   S (mp);
18038
18039   /* wait for reply */
18040   W (ret);
18041   return ret;
18042 }
18043
18044 static int
18045 api_one_add_del_l2_arp_entry (vat_main_t * vam)
18046 {
18047   vl_api_one_add_del_l2_arp_entry_t *mp;
18048   unformat_input_t *input = vam->input;
18049   u8 is_add = 1;
18050   u8 mac_set = 0;
18051   u8 bd_set = 0;
18052   u8 ip_set = 0;
18053   u8 mac[6] = { 0, };
18054   u32 ip4 = 0, bd = ~0;
18055   int ret;
18056
18057   /* Parse args required to build the message */
18058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18059     {
18060       if (unformat (input, "del"))
18061         is_add = 0;
18062       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18063         mac_set = 1;
18064       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
18065         ip_set = 1;
18066       else if (unformat (input, "bd %d", &bd))
18067         bd_set = 1;
18068       else
18069         {
18070           errmsg ("parse error '%U'", format_unformat_error, input);
18071           return -99;
18072         }
18073     }
18074
18075   if (!bd_set || !ip_set || (!mac_set && is_add))
18076     {
18077       errmsg ("Missing BD, IP or MAC!");
18078       return -99;
18079     }
18080
18081   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
18082   mp->is_add = is_add;
18083   clib_memcpy (mp->mac, mac, 6);
18084   mp->bd = clib_host_to_net_u32 (bd);
18085   mp->ip4 = ip4;
18086
18087   /* send */
18088   S (mp);
18089
18090   /* wait for reply */
18091   W (ret);
18092   return ret;
18093 }
18094
18095 static int
18096 api_one_ndp_bd_get (vat_main_t * vam)
18097 {
18098   vl_api_one_ndp_bd_get_t *mp;
18099   int ret;
18100
18101   M (ONE_NDP_BD_GET, mp);
18102
18103   /* send */
18104   S (mp);
18105
18106   /* wait for reply */
18107   W (ret);
18108   return ret;
18109 }
18110
18111 static int
18112 api_one_ndp_entries_get (vat_main_t * vam)
18113 {
18114   vl_api_one_ndp_entries_get_t *mp;
18115   unformat_input_t *input = vam->input;
18116   u8 bd_set = 0;
18117   u32 bd = ~0;
18118   int ret;
18119
18120   /* Parse args required to build the message */
18121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18122     {
18123       if (unformat (input, "bd %d", &bd))
18124         bd_set = 1;
18125       else
18126         {
18127           errmsg ("parse error '%U'", format_unformat_error, input);
18128           return -99;
18129         }
18130     }
18131
18132   if (!bd_set)
18133     {
18134       errmsg ("Expected bridge domain!");
18135       return -99;
18136     }
18137
18138   M (ONE_NDP_ENTRIES_GET, mp);
18139   mp->bd = clib_host_to_net_u32 (bd);
18140
18141   /* send */
18142   S (mp);
18143
18144   /* wait for reply */
18145   W (ret);
18146   return ret;
18147 }
18148
18149 static int
18150 api_one_l2_arp_bd_get (vat_main_t * vam)
18151 {
18152   vl_api_one_l2_arp_bd_get_t *mp;
18153   int ret;
18154
18155   M (ONE_L2_ARP_BD_GET, mp);
18156
18157   /* send */
18158   S (mp);
18159
18160   /* wait for reply */
18161   W (ret);
18162   return ret;
18163 }
18164
18165 static int
18166 api_one_l2_arp_entries_get (vat_main_t * vam)
18167 {
18168   vl_api_one_l2_arp_entries_get_t *mp;
18169   unformat_input_t *input = vam->input;
18170   u8 bd_set = 0;
18171   u32 bd = ~0;
18172   int ret;
18173
18174   /* Parse args required to build the message */
18175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18176     {
18177       if (unformat (input, "bd %d", &bd))
18178         bd_set = 1;
18179       else
18180         {
18181           errmsg ("parse error '%U'", format_unformat_error, input);
18182           return -99;
18183         }
18184     }
18185
18186   if (!bd_set)
18187     {
18188       errmsg ("Expected bridge domain!");
18189       return -99;
18190     }
18191
18192   M (ONE_L2_ARP_ENTRIES_GET, mp);
18193   mp->bd = clib_host_to_net_u32 (bd);
18194
18195   /* send */
18196   S (mp);
18197
18198   /* wait for reply */
18199   W (ret);
18200   return ret;
18201 }
18202
18203 static int
18204 api_one_stats_enable_disable (vat_main_t * vam)
18205 {
18206   vl_api_one_stats_enable_disable_t *mp;
18207   unformat_input_t *input = vam->input;
18208   u8 is_set = 0;
18209   u8 is_en = 0;
18210   int ret;
18211
18212   /* Parse args required to build the message */
18213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18214     {
18215       if (unformat (input, "enable"))
18216         {
18217           is_set = 1;
18218           is_en = 1;
18219         }
18220       else if (unformat (input, "disable"))
18221         {
18222           is_set = 1;
18223         }
18224       else
18225         break;
18226     }
18227
18228   if (!is_set)
18229     {
18230       errmsg ("Value not set");
18231       return -99;
18232     }
18233
18234   M (ONE_STATS_ENABLE_DISABLE, mp);
18235   mp->is_en = is_en;
18236
18237   /* send */
18238   S (mp);
18239
18240   /* wait for reply */
18241   W (ret);
18242   return ret;
18243 }
18244
18245 static int
18246 api_show_one_stats_enable_disable (vat_main_t * vam)
18247 {
18248   vl_api_show_one_stats_enable_disable_t *mp;
18249   int ret;
18250
18251   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18252
18253   /* send */
18254   S (mp);
18255
18256   /* wait for reply */
18257   W (ret);
18258   return ret;
18259 }
18260
18261 static int
18262 api_show_one_map_request_mode (vat_main_t * vam)
18263 {
18264   vl_api_show_one_map_request_mode_t *mp;
18265   int ret;
18266
18267   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18268
18269   /* send */
18270   S (mp);
18271
18272   /* wait for reply */
18273   W (ret);
18274   return ret;
18275 }
18276
18277 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18278
18279 static int
18280 api_one_map_request_mode (vat_main_t * vam)
18281 {
18282   unformat_input_t *input = vam->input;
18283   vl_api_one_map_request_mode_t *mp;
18284   u8 mode = 0;
18285   int ret;
18286
18287   /* Parse args required to build the message */
18288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18289     {
18290       if (unformat (input, "dst-only"))
18291         mode = 0;
18292       else if (unformat (input, "src-dst"))
18293         mode = 1;
18294       else
18295         {
18296           errmsg ("parse error '%U'", format_unformat_error, input);
18297           return -99;
18298         }
18299     }
18300
18301   M (ONE_MAP_REQUEST_MODE, mp);
18302
18303   mp->mode = mode;
18304
18305   /* send */
18306   S (mp);
18307
18308   /* wait for reply */
18309   W (ret);
18310   return ret;
18311 }
18312
18313 #define api_lisp_map_request_mode api_one_map_request_mode
18314
18315 /**
18316  * Enable/disable ONE proxy ITR.
18317  *
18318  * @param vam vpp API test context
18319  * @return return code
18320  */
18321 static int
18322 api_one_pitr_set_locator_set (vat_main_t * vam)
18323 {
18324   u8 ls_name_set = 0;
18325   unformat_input_t *input = vam->input;
18326   vl_api_one_pitr_set_locator_set_t *mp;
18327   u8 is_add = 1;
18328   u8 *ls_name = 0;
18329   int ret;
18330
18331   /* Parse args required to build the message */
18332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18333     {
18334       if (unformat (input, "del"))
18335         is_add = 0;
18336       else if (unformat (input, "locator-set %s", &ls_name))
18337         ls_name_set = 1;
18338       else
18339         {
18340           errmsg ("parse error '%U'", format_unformat_error, input);
18341           return -99;
18342         }
18343     }
18344
18345   if (!ls_name_set)
18346     {
18347       errmsg ("locator-set name not set!");
18348       return -99;
18349     }
18350
18351   M (ONE_PITR_SET_LOCATOR_SET, mp);
18352
18353   mp->is_add = is_add;
18354   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18355   vec_free (ls_name);
18356
18357   /* send */
18358   S (mp);
18359
18360   /* wait for reply */
18361   W (ret);
18362   return ret;
18363 }
18364
18365 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18366
18367 static int
18368 api_one_nsh_set_locator_set (vat_main_t * vam)
18369 {
18370   u8 ls_name_set = 0;
18371   unformat_input_t *input = vam->input;
18372   vl_api_one_nsh_set_locator_set_t *mp;
18373   u8 is_add = 1;
18374   u8 *ls_name = 0;
18375   int ret;
18376
18377   /* Parse args required to build the message */
18378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18379     {
18380       if (unformat (input, "del"))
18381         is_add = 0;
18382       else if (unformat (input, "ls %s", &ls_name))
18383         ls_name_set = 1;
18384       else
18385         {
18386           errmsg ("parse error '%U'", format_unformat_error, input);
18387           return -99;
18388         }
18389     }
18390
18391   if (!ls_name_set && is_add)
18392     {
18393       errmsg ("locator-set name not set!");
18394       return -99;
18395     }
18396
18397   M (ONE_NSH_SET_LOCATOR_SET, mp);
18398
18399   mp->is_add = is_add;
18400   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18401   vec_free (ls_name);
18402
18403   /* send */
18404   S (mp);
18405
18406   /* wait for reply */
18407   W (ret);
18408   return ret;
18409 }
18410
18411 static int
18412 api_show_one_pitr (vat_main_t * vam)
18413 {
18414   vl_api_show_one_pitr_t *mp;
18415   int ret;
18416
18417   if (!vam->json_output)
18418     {
18419       print (vam->ofp, "%=20s", "lisp status:");
18420     }
18421
18422   M (SHOW_ONE_PITR, mp);
18423   /* send it... */
18424   S (mp);
18425
18426   /* Wait for a reply... */
18427   W (ret);
18428   return ret;
18429 }
18430
18431 #define api_show_lisp_pitr api_show_one_pitr
18432
18433 static int
18434 api_one_use_petr (vat_main_t * vam)
18435 {
18436   unformat_input_t *input = vam->input;
18437   vl_api_one_use_petr_t *mp;
18438   u8 is_add = 0;
18439   ip_address_t ip;
18440   int ret;
18441
18442   clib_memset (&ip, 0, sizeof (ip));
18443
18444   /* Parse args required to build the message */
18445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18446     {
18447       if (unformat (input, "disable"))
18448         is_add = 0;
18449       else
18450         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18451         {
18452           is_add = 1;
18453           ip_addr_version (&ip) = IP4;
18454         }
18455       else
18456         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18457         {
18458           is_add = 1;
18459           ip_addr_version (&ip) = IP6;
18460         }
18461       else
18462         {
18463           errmsg ("parse error '%U'", format_unformat_error, input);
18464           return -99;
18465         }
18466     }
18467
18468   M (ONE_USE_PETR, mp);
18469
18470   mp->is_add = is_add;
18471   if (is_add)
18472     {
18473       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18474       if (mp->is_ip4)
18475         clib_memcpy (mp->address, &ip, 4);
18476       else
18477         clib_memcpy (mp->address, &ip, 16);
18478     }
18479
18480   /* send */
18481   S (mp);
18482
18483   /* wait for reply */
18484   W (ret);
18485   return ret;
18486 }
18487
18488 #define api_lisp_use_petr api_one_use_petr
18489
18490 static int
18491 api_show_one_nsh_mapping (vat_main_t * vam)
18492 {
18493   vl_api_show_one_use_petr_t *mp;
18494   int ret;
18495
18496   if (!vam->json_output)
18497     {
18498       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18499     }
18500
18501   M (SHOW_ONE_NSH_MAPPING, mp);
18502   /* send it... */
18503   S (mp);
18504
18505   /* Wait for a reply... */
18506   W (ret);
18507   return ret;
18508 }
18509
18510 static int
18511 api_show_one_use_petr (vat_main_t * vam)
18512 {
18513   vl_api_show_one_use_petr_t *mp;
18514   int ret;
18515
18516   if (!vam->json_output)
18517     {
18518       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18519     }
18520
18521   M (SHOW_ONE_USE_PETR, mp);
18522   /* send it... */
18523   S (mp);
18524
18525   /* Wait for a reply... */
18526   W (ret);
18527   return ret;
18528 }
18529
18530 #define api_show_lisp_use_petr api_show_one_use_petr
18531
18532 /**
18533  * Add/delete mapping between vni and vrf
18534  */
18535 static int
18536 api_one_eid_table_add_del_map (vat_main_t * vam)
18537 {
18538   unformat_input_t *input = vam->input;
18539   vl_api_one_eid_table_add_del_map_t *mp;
18540   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18541   u32 vni, vrf, bd_index;
18542   int ret;
18543
18544   /* Parse args required to build the message */
18545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18546     {
18547       if (unformat (input, "del"))
18548         is_add = 0;
18549       else if (unformat (input, "vrf %d", &vrf))
18550         vrf_set = 1;
18551       else if (unformat (input, "bd_index %d", &bd_index))
18552         bd_index_set = 1;
18553       else if (unformat (input, "vni %d", &vni))
18554         vni_set = 1;
18555       else
18556         break;
18557     }
18558
18559   if (!vni_set || (!vrf_set && !bd_index_set))
18560     {
18561       errmsg ("missing arguments!");
18562       return -99;
18563     }
18564
18565   if (vrf_set && bd_index_set)
18566     {
18567       errmsg ("error: both vrf and bd entered!");
18568       return -99;
18569     }
18570
18571   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18572
18573   mp->is_add = is_add;
18574   mp->vni = htonl (vni);
18575   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18576   mp->is_l2 = bd_index_set;
18577
18578   /* send */
18579   S (mp);
18580
18581   /* wait for reply */
18582   W (ret);
18583   return ret;
18584 }
18585
18586 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18587
18588 uword
18589 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18590 {
18591   u32 *action = va_arg (*args, u32 *);
18592   u8 *s = 0;
18593
18594   if (unformat (input, "%s", &s))
18595     {
18596       if (!strcmp ((char *) s, "no-action"))
18597         action[0] = 0;
18598       else if (!strcmp ((char *) s, "natively-forward"))
18599         action[0] = 1;
18600       else if (!strcmp ((char *) s, "send-map-request"))
18601         action[0] = 2;
18602       else if (!strcmp ((char *) s, "drop"))
18603         action[0] = 3;
18604       else
18605         {
18606           clib_warning ("invalid action: '%s'", s);
18607           action[0] = 3;
18608         }
18609     }
18610   else
18611     return 0;
18612
18613   vec_free (s);
18614   return 1;
18615 }
18616
18617 /**
18618  * Add/del remote mapping to/from ONE control plane
18619  *
18620  * @param vam vpp API test context
18621  * @return return code
18622  */
18623 static int
18624 api_one_add_del_remote_mapping (vat_main_t * vam)
18625 {
18626   unformat_input_t *input = vam->input;
18627   vl_api_one_add_del_remote_mapping_t *mp;
18628   u32 vni = 0;
18629   lisp_eid_vat_t _eid, *eid = &_eid;
18630   lisp_eid_vat_t _seid, *seid = &_seid;
18631   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18632   u32 action = ~0, p, w, data_len;
18633   ip4_address_t rloc4;
18634   ip6_address_t rloc6;
18635   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18636   int ret;
18637
18638   clib_memset (&rloc, 0, sizeof (rloc));
18639
18640   /* Parse args required to build the message */
18641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18642     {
18643       if (unformat (input, "del-all"))
18644         {
18645           del_all = 1;
18646         }
18647       else if (unformat (input, "del"))
18648         {
18649           is_add = 0;
18650         }
18651       else if (unformat (input, "add"))
18652         {
18653           is_add = 1;
18654         }
18655       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18656         {
18657           eid_set = 1;
18658         }
18659       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18660         {
18661           seid_set = 1;
18662         }
18663       else if (unformat (input, "vni %d", &vni))
18664         {
18665           ;
18666         }
18667       else if (unformat (input, "p %d w %d", &p, &w))
18668         {
18669           if (!curr_rloc)
18670             {
18671               errmsg ("No RLOC configured for setting priority/weight!");
18672               return -99;
18673             }
18674           curr_rloc->priority = p;
18675           curr_rloc->weight = w;
18676         }
18677       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18678         {
18679           rloc.is_ip4 = 1;
18680           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18681           vec_add1 (rlocs, rloc);
18682           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18683         }
18684       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18685         {
18686           rloc.is_ip4 = 0;
18687           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18688           vec_add1 (rlocs, rloc);
18689           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18690         }
18691       else if (unformat (input, "action %U",
18692                          unformat_negative_mapping_action, &action))
18693         {
18694           ;
18695         }
18696       else
18697         {
18698           clib_warning ("parse error '%U'", format_unformat_error, input);
18699           return -99;
18700         }
18701     }
18702
18703   if (0 == eid_set)
18704     {
18705       errmsg ("missing params!");
18706       return -99;
18707     }
18708
18709   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18710     {
18711       errmsg ("no action set for negative map-reply!");
18712       return -99;
18713     }
18714
18715   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18716
18717   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18718   mp->is_add = is_add;
18719   mp->vni = htonl (vni);
18720   mp->action = (u8) action;
18721   mp->is_src_dst = seid_set;
18722   mp->eid_len = eid->len;
18723   mp->seid_len = seid->len;
18724   mp->del_all = del_all;
18725   mp->eid_type = eid->type;
18726   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18727   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18728
18729   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18730   clib_memcpy (mp->rlocs, rlocs, data_len);
18731   vec_free (rlocs);
18732
18733   /* send it... */
18734   S (mp);
18735
18736   /* Wait for a reply... */
18737   W (ret);
18738   return ret;
18739 }
18740
18741 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18742
18743 /**
18744  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18745  * forwarding entries in data-plane accordingly.
18746  *
18747  * @param vam vpp API test context
18748  * @return return code
18749  */
18750 static int
18751 api_one_add_del_adjacency (vat_main_t * vam)
18752 {
18753   unformat_input_t *input = vam->input;
18754   vl_api_one_add_del_adjacency_t *mp;
18755   u32 vni = 0;
18756   ip4_address_t leid4, reid4;
18757   ip6_address_t leid6, reid6;
18758   u8 reid_mac[6] = { 0 };
18759   u8 leid_mac[6] = { 0 };
18760   u8 reid_type, leid_type;
18761   u32 leid_len = 0, reid_len = 0, len;
18762   u8 is_add = 1;
18763   int ret;
18764
18765   leid_type = reid_type = (u8) ~ 0;
18766
18767   /* Parse args required to build the message */
18768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18769     {
18770       if (unformat (input, "del"))
18771         {
18772           is_add = 0;
18773         }
18774       else if (unformat (input, "add"))
18775         {
18776           is_add = 1;
18777         }
18778       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18779                          &reid4, &len))
18780         {
18781           reid_type = 0;        /* ipv4 */
18782           reid_len = len;
18783         }
18784       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18785                          &reid6, &len))
18786         {
18787           reid_type = 1;        /* ipv6 */
18788           reid_len = len;
18789         }
18790       else if (unformat (input, "reid %U", unformat_ethernet_address,
18791                          reid_mac))
18792         {
18793           reid_type = 2;        /* mac */
18794         }
18795       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18796                          &leid4, &len))
18797         {
18798           leid_type = 0;        /* ipv4 */
18799           leid_len = len;
18800         }
18801       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18802                          &leid6, &len))
18803         {
18804           leid_type = 1;        /* ipv6 */
18805           leid_len = len;
18806         }
18807       else if (unformat (input, "leid %U", unformat_ethernet_address,
18808                          leid_mac))
18809         {
18810           leid_type = 2;        /* mac */
18811         }
18812       else if (unformat (input, "vni %d", &vni))
18813         {
18814           ;
18815         }
18816       else
18817         {
18818           errmsg ("parse error '%U'", format_unformat_error, input);
18819           return -99;
18820         }
18821     }
18822
18823   if ((u8) ~ 0 == reid_type)
18824     {
18825       errmsg ("missing params!");
18826       return -99;
18827     }
18828
18829   if (leid_type != reid_type)
18830     {
18831       errmsg ("remote and local EIDs are of different types!");
18832       return -99;
18833     }
18834
18835   M (ONE_ADD_DEL_ADJACENCY, mp);
18836   mp->is_add = is_add;
18837   mp->vni = htonl (vni);
18838   mp->leid_len = leid_len;
18839   mp->reid_len = reid_len;
18840   mp->eid_type = reid_type;
18841
18842   switch (mp->eid_type)
18843     {
18844     case 0:
18845       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18846       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18847       break;
18848     case 1:
18849       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18850       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18851       break;
18852     case 2:
18853       clib_memcpy (mp->leid, leid_mac, 6);
18854       clib_memcpy (mp->reid, reid_mac, 6);
18855       break;
18856     default:
18857       errmsg ("unknown EID type %d!", mp->eid_type);
18858       return 0;
18859     }
18860
18861   /* send it... */
18862   S (mp);
18863
18864   /* Wait for a reply... */
18865   W (ret);
18866   return ret;
18867 }
18868
18869 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18870
18871 uword
18872 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18873 {
18874   u32 *mode = va_arg (*args, u32 *);
18875
18876   if (unformat (input, "lisp"))
18877     *mode = 0;
18878   else if (unformat (input, "vxlan"))
18879     *mode = 1;
18880   else
18881     return 0;
18882
18883   return 1;
18884 }
18885
18886 static int
18887 api_gpe_get_encap_mode (vat_main_t * vam)
18888 {
18889   vl_api_gpe_get_encap_mode_t *mp;
18890   int ret;
18891
18892   /* Construct the API message */
18893   M (GPE_GET_ENCAP_MODE, mp);
18894
18895   /* send it... */
18896   S (mp);
18897
18898   /* Wait for a reply... */
18899   W (ret);
18900   return ret;
18901 }
18902
18903 static int
18904 api_gpe_set_encap_mode (vat_main_t * vam)
18905 {
18906   unformat_input_t *input = vam->input;
18907   vl_api_gpe_set_encap_mode_t *mp;
18908   int ret;
18909   u32 mode = 0;
18910
18911   /* Parse args required to build the message */
18912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18913     {
18914       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18915         ;
18916       else
18917         break;
18918     }
18919
18920   /* Construct the API message */
18921   M (GPE_SET_ENCAP_MODE, mp);
18922
18923   mp->mode = mode;
18924
18925   /* send it... */
18926   S (mp);
18927
18928   /* Wait for a reply... */
18929   W (ret);
18930   return ret;
18931 }
18932
18933 static int
18934 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18935 {
18936   unformat_input_t *input = vam->input;
18937   vl_api_gpe_add_del_iface_t *mp;
18938   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18939   u32 dp_table = 0, vni = 0;
18940   int ret;
18941
18942   /* Parse args required to build the message */
18943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18944     {
18945       if (unformat (input, "up"))
18946         {
18947           action_set = 1;
18948           is_add = 1;
18949         }
18950       else if (unformat (input, "down"))
18951         {
18952           action_set = 1;
18953           is_add = 0;
18954         }
18955       else if (unformat (input, "table_id %d", &dp_table))
18956         {
18957           dp_table_set = 1;
18958         }
18959       else if (unformat (input, "bd_id %d", &dp_table))
18960         {
18961           dp_table_set = 1;
18962           is_l2 = 1;
18963         }
18964       else if (unformat (input, "vni %d", &vni))
18965         {
18966           vni_set = 1;
18967         }
18968       else
18969         break;
18970     }
18971
18972   if (action_set == 0)
18973     {
18974       errmsg ("Action not set");
18975       return -99;
18976     }
18977   if (dp_table_set == 0 || vni_set == 0)
18978     {
18979       errmsg ("vni and dp_table must be set");
18980       return -99;
18981     }
18982
18983   /* Construct the API message */
18984   M (GPE_ADD_DEL_IFACE, mp);
18985
18986   mp->is_add = is_add;
18987   mp->dp_table = clib_host_to_net_u32 (dp_table);
18988   mp->is_l2 = is_l2;
18989   mp->vni = clib_host_to_net_u32 (vni);
18990
18991   /* send it... */
18992   S (mp);
18993
18994   /* Wait for a reply... */
18995   W (ret);
18996   return ret;
18997 }
18998
18999 static int
19000 api_one_map_register_fallback_threshold (vat_main_t * vam)
19001 {
19002   unformat_input_t *input = vam->input;
19003   vl_api_one_map_register_fallback_threshold_t *mp;
19004   u32 value = 0;
19005   u8 is_set = 0;
19006   int ret;
19007
19008   /* Parse args required to build the message */
19009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19010     {
19011       if (unformat (input, "%u", &value))
19012         is_set = 1;
19013       else
19014         {
19015           clib_warning ("parse error '%U'", format_unformat_error, input);
19016           return -99;
19017         }
19018     }
19019
19020   if (!is_set)
19021     {
19022       errmsg ("fallback threshold value is missing!");
19023       return -99;
19024     }
19025
19026   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19027   mp->value = clib_host_to_net_u32 (value);
19028
19029   /* send it... */
19030   S (mp);
19031
19032   /* Wait for a reply... */
19033   W (ret);
19034   return ret;
19035 }
19036
19037 static int
19038 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
19039 {
19040   vl_api_show_one_map_register_fallback_threshold_t *mp;
19041   int ret;
19042
19043   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19044
19045   /* send it... */
19046   S (mp);
19047
19048   /* Wait for a reply... */
19049   W (ret);
19050   return ret;
19051 }
19052
19053 uword
19054 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
19055 {
19056   u32 *proto = va_arg (*args, u32 *);
19057
19058   if (unformat (input, "udp"))
19059     *proto = 1;
19060   else if (unformat (input, "api"))
19061     *proto = 2;
19062   else
19063     return 0;
19064
19065   return 1;
19066 }
19067
19068 static int
19069 api_one_set_transport_protocol (vat_main_t * vam)
19070 {
19071   unformat_input_t *input = vam->input;
19072   vl_api_one_set_transport_protocol_t *mp;
19073   u8 is_set = 0;
19074   u32 protocol = 0;
19075   int ret;
19076
19077   /* Parse args required to build the message */
19078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19079     {
19080       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
19081         is_set = 1;
19082       else
19083         {
19084           clib_warning ("parse error '%U'", format_unformat_error, input);
19085           return -99;
19086         }
19087     }
19088
19089   if (!is_set)
19090     {
19091       errmsg ("Transport protocol missing!");
19092       return -99;
19093     }
19094
19095   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
19096   mp->protocol = (u8) protocol;
19097
19098   /* send it... */
19099   S (mp);
19100
19101   /* Wait for a reply... */
19102   W (ret);
19103   return ret;
19104 }
19105
19106 static int
19107 api_one_get_transport_protocol (vat_main_t * vam)
19108 {
19109   vl_api_one_get_transport_protocol_t *mp;
19110   int ret;
19111
19112   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19113
19114   /* send it... */
19115   S (mp);
19116
19117   /* Wait for a reply... */
19118   W (ret);
19119   return ret;
19120 }
19121
19122 static int
19123 api_one_map_register_set_ttl (vat_main_t * vam)
19124 {
19125   unformat_input_t *input = vam->input;
19126   vl_api_one_map_register_set_ttl_t *mp;
19127   u32 ttl = 0;
19128   u8 is_set = 0;
19129   int ret;
19130
19131   /* Parse args required to build the message */
19132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19133     {
19134       if (unformat (input, "%u", &ttl))
19135         is_set = 1;
19136       else
19137         {
19138           clib_warning ("parse error '%U'", format_unformat_error, input);
19139           return -99;
19140         }
19141     }
19142
19143   if (!is_set)
19144     {
19145       errmsg ("TTL value missing!");
19146       return -99;
19147     }
19148
19149   M (ONE_MAP_REGISTER_SET_TTL, mp);
19150   mp->ttl = clib_host_to_net_u32 (ttl);
19151
19152   /* send it... */
19153   S (mp);
19154
19155   /* Wait for a reply... */
19156   W (ret);
19157   return ret;
19158 }
19159
19160 static int
19161 api_show_one_map_register_ttl (vat_main_t * vam)
19162 {
19163   vl_api_show_one_map_register_ttl_t *mp;
19164   int ret;
19165
19166   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19167
19168   /* send it... */
19169   S (mp);
19170
19171   /* Wait for a reply... */
19172   W (ret);
19173   return ret;
19174 }
19175
19176 /**
19177  * Add/del map request itr rlocs from ONE control plane and updates
19178  *
19179  * @param vam vpp API test context
19180  * @return return code
19181  */
19182 static int
19183 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19184 {
19185   unformat_input_t *input = vam->input;
19186   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19187   u8 *locator_set_name = 0;
19188   u8 locator_set_name_set = 0;
19189   u8 is_add = 1;
19190   int ret;
19191
19192   /* Parse args required to build the message */
19193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19194     {
19195       if (unformat (input, "del"))
19196         {
19197           is_add = 0;
19198         }
19199       else if (unformat (input, "%_%v%_", &locator_set_name))
19200         {
19201           locator_set_name_set = 1;
19202         }
19203       else
19204         {
19205           clib_warning ("parse error '%U'", format_unformat_error, input);
19206           return -99;
19207         }
19208     }
19209
19210   if (is_add && !locator_set_name_set)
19211     {
19212       errmsg ("itr-rloc is not set!");
19213       return -99;
19214     }
19215
19216   if (is_add && vec_len (locator_set_name) > 64)
19217     {
19218       errmsg ("itr-rloc locator-set name too long");
19219       vec_free (locator_set_name);
19220       return -99;
19221     }
19222
19223   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19224   mp->is_add = is_add;
19225   if (is_add)
19226     {
19227       clib_memcpy (mp->locator_set_name, locator_set_name,
19228                    vec_len (locator_set_name));
19229     }
19230   else
19231     {
19232       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19233     }
19234   vec_free (locator_set_name);
19235
19236   /* send it... */
19237   S (mp);
19238
19239   /* Wait for a reply... */
19240   W (ret);
19241   return ret;
19242 }
19243
19244 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19245
19246 static int
19247 api_one_locator_dump (vat_main_t * vam)
19248 {
19249   unformat_input_t *input = vam->input;
19250   vl_api_one_locator_dump_t *mp;
19251   vl_api_control_ping_t *mp_ping;
19252   u8 is_index_set = 0, is_name_set = 0;
19253   u8 *ls_name = 0;
19254   u32 ls_index = ~0;
19255   int ret;
19256
19257   /* Parse args required to build the message */
19258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19259     {
19260       if (unformat (input, "ls_name %_%v%_", &ls_name))
19261         {
19262           is_name_set = 1;
19263         }
19264       else if (unformat (input, "ls_index %d", &ls_index))
19265         {
19266           is_index_set = 1;
19267         }
19268       else
19269         {
19270           errmsg ("parse error '%U'", format_unformat_error, input);
19271           return -99;
19272         }
19273     }
19274
19275   if (!is_index_set && !is_name_set)
19276     {
19277       errmsg ("error: expected one of index or name!");
19278       return -99;
19279     }
19280
19281   if (is_index_set && is_name_set)
19282     {
19283       errmsg ("error: only one param expected!");
19284       return -99;
19285     }
19286
19287   if (vec_len (ls_name) > 62)
19288     {
19289       errmsg ("error: locator set name too long!");
19290       return -99;
19291     }
19292
19293   if (!vam->json_output)
19294     {
19295       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19296     }
19297
19298   M (ONE_LOCATOR_DUMP, mp);
19299   mp->is_index_set = is_index_set;
19300
19301   if (is_index_set)
19302     mp->ls_index = clib_host_to_net_u32 (ls_index);
19303   else
19304     {
19305       vec_add1 (ls_name, 0);
19306       strncpy ((char *) mp->ls_name, (char *) ls_name,
19307                sizeof (mp->ls_name) - 1);
19308     }
19309
19310   /* send it... */
19311   S (mp);
19312
19313   /* Use a control ping for synchronization */
19314   MPING (CONTROL_PING, mp_ping);
19315   S (mp_ping);
19316
19317   /* Wait for a reply... */
19318   W (ret);
19319   return ret;
19320 }
19321
19322 #define api_lisp_locator_dump api_one_locator_dump
19323
19324 static int
19325 api_one_locator_set_dump (vat_main_t * vam)
19326 {
19327   vl_api_one_locator_set_dump_t *mp;
19328   vl_api_control_ping_t *mp_ping;
19329   unformat_input_t *input = vam->input;
19330   u8 filter = 0;
19331   int ret;
19332
19333   /* Parse args required to build the message */
19334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19335     {
19336       if (unformat (input, "local"))
19337         {
19338           filter = 1;
19339         }
19340       else if (unformat (input, "remote"))
19341         {
19342           filter = 2;
19343         }
19344       else
19345         {
19346           errmsg ("parse error '%U'", format_unformat_error, input);
19347           return -99;
19348         }
19349     }
19350
19351   if (!vam->json_output)
19352     {
19353       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19354     }
19355
19356   M (ONE_LOCATOR_SET_DUMP, mp);
19357
19358   mp->filter = filter;
19359
19360   /* send it... */
19361   S (mp);
19362
19363   /* Use a control ping for synchronization */
19364   MPING (CONTROL_PING, mp_ping);
19365   S (mp_ping);
19366
19367   /* Wait for a reply... */
19368   W (ret);
19369   return ret;
19370 }
19371
19372 #define api_lisp_locator_set_dump api_one_locator_set_dump
19373
19374 static int
19375 api_one_eid_table_map_dump (vat_main_t * vam)
19376 {
19377   u8 is_l2 = 0;
19378   u8 mode_set = 0;
19379   unformat_input_t *input = vam->input;
19380   vl_api_one_eid_table_map_dump_t *mp;
19381   vl_api_control_ping_t *mp_ping;
19382   int ret;
19383
19384   /* Parse args required to build the message */
19385   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19386     {
19387       if (unformat (input, "l2"))
19388         {
19389           is_l2 = 1;
19390           mode_set = 1;
19391         }
19392       else if (unformat (input, "l3"))
19393         {
19394           is_l2 = 0;
19395           mode_set = 1;
19396         }
19397       else
19398         {
19399           errmsg ("parse error '%U'", format_unformat_error, input);
19400           return -99;
19401         }
19402     }
19403
19404   if (!mode_set)
19405     {
19406       errmsg ("expected one of 'l2' or 'l3' parameter!");
19407       return -99;
19408     }
19409
19410   if (!vam->json_output)
19411     {
19412       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19413     }
19414
19415   M (ONE_EID_TABLE_MAP_DUMP, mp);
19416   mp->is_l2 = is_l2;
19417
19418   /* send it... */
19419   S (mp);
19420
19421   /* Use a control ping for synchronization */
19422   MPING (CONTROL_PING, mp_ping);
19423   S (mp_ping);
19424
19425   /* Wait for a reply... */
19426   W (ret);
19427   return ret;
19428 }
19429
19430 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19431
19432 static int
19433 api_one_eid_table_vni_dump (vat_main_t * vam)
19434 {
19435   vl_api_one_eid_table_vni_dump_t *mp;
19436   vl_api_control_ping_t *mp_ping;
19437   int ret;
19438
19439   if (!vam->json_output)
19440     {
19441       print (vam->ofp, "VNI");
19442     }
19443
19444   M (ONE_EID_TABLE_VNI_DUMP, mp);
19445
19446   /* send it... */
19447   S (mp);
19448
19449   /* Use a control ping for synchronization */
19450   MPING (CONTROL_PING, mp_ping);
19451   S (mp_ping);
19452
19453   /* Wait for a reply... */
19454   W (ret);
19455   return ret;
19456 }
19457
19458 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19459
19460 static int
19461 api_one_eid_table_dump (vat_main_t * vam)
19462 {
19463   unformat_input_t *i = vam->input;
19464   vl_api_one_eid_table_dump_t *mp;
19465   vl_api_control_ping_t *mp_ping;
19466   struct in_addr ip4;
19467   struct in6_addr ip6;
19468   u8 mac[6];
19469   u8 eid_type = ~0, eid_set = 0;
19470   u32 prefix_length = ~0, t, vni = 0;
19471   u8 filter = 0;
19472   int ret;
19473   lisp_nsh_api_t nsh;
19474
19475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19476     {
19477       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19478         {
19479           eid_set = 1;
19480           eid_type = 0;
19481           prefix_length = t;
19482         }
19483       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19484         {
19485           eid_set = 1;
19486           eid_type = 1;
19487           prefix_length = t;
19488         }
19489       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19490         {
19491           eid_set = 1;
19492           eid_type = 2;
19493         }
19494       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19495         {
19496           eid_set = 1;
19497           eid_type = 3;
19498         }
19499       else if (unformat (i, "vni %d", &t))
19500         {
19501           vni = t;
19502         }
19503       else if (unformat (i, "local"))
19504         {
19505           filter = 1;
19506         }
19507       else if (unformat (i, "remote"))
19508         {
19509           filter = 2;
19510         }
19511       else
19512         {
19513           errmsg ("parse error '%U'", format_unformat_error, i);
19514           return -99;
19515         }
19516     }
19517
19518   if (!vam->json_output)
19519     {
19520       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19521              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19522     }
19523
19524   M (ONE_EID_TABLE_DUMP, mp);
19525
19526   mp->filter = filter;
19527   if (eid_set)
19528     {
19529       mp->eid_set = 1;
19530       mp->vni = htonl (vni);
19531       mp->eid_type = eid_type;
19532       switch (eid_type)
19533         {
19534         case 0:
19535           mp->prefix_length = prefix_length;
19536           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19537           break;
19538         case 1:
19539           mp->prefix_length = prefix_length;
19540           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19541           break;
19542         case 2:
19543           clib_memcpy (mp->eid, mac, sizeof (mac));
19544           break;
19545         case 3:
19546           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19547           break;
19548         default:
19549           errmsg ("unknown EID type %d!", eid_type);
19550           return -99;
19551         }
19552     }
19553
19554   /* send it... */
19555   S (mp);
19556
19557   /* Use a control ping for synchronization */
19558   MPING (CONTROL_PING, mp_ping);
19559   S (mp_ping);
19560
19561   /* Wait for a reply... */
19562   W (ret);
19563   return ret;
19564 }
19565
19566 #define api_lisp_eid_table_dump api_one_eid_table_dump
19567
19568 static int
19569 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19570 {
19571   unformat_input_t *i = vam->input;
19572   vl_api_gpe_fwd_entries_get_t *mp;
19573   u8 vni_set = 0;
19574   u32 vni = ~0;
19575   int ret;
19576
19577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19578     {
19579       if (unformat (i, "vni %d", &vni))
19580         {
19581           vni_set = 1;
19582         }
19583       else
19584         {
19585           errmsg ("parse error '%U'", format_unformat_error, i);
19586           return -99;
19587         }
19588     }
19589
19590   if (!vni_set)
19591     {
19592       errmsg ("vni not set!");
19593       return -99;
19594     }
19595
19596   if (!vam->json_output)
19597     {
19598       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19599              "leid", "reid");
19600     }
19601
19602   M (GPE_FWD_ENTRIES_GET, mp);
19603   mp->vni = clib_host_to_net_u32 (vni);
19604
19605   /* send it... */
19606   S (mp);
19607
19608   /* Wait for a reply... */
19609   W (ret);
19610   return ret;
19611 }
19612
19613 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19614 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19615 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19616 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19617 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19618 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19619 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19620 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19621
19622 static int
19623 api_one_adjacencies_get (vat_main_t * vam)
19624 {
19625   unformat_input_t *i = vam->input;
19626   vl_api_one_adjacencies_get_t *mp;
19627   u8 vni_set = 0;
19628   u32 vni = ~0;
19629   int ret;
19630
19631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19632     {
19633       if (unformat (i, "vni %d", &vni))
19634         {
19635           vni_set = 1;
19636         }
19637       else
19638         {
19639           errmsg ("parse error '%U'", format_unformat_error, i);
19640           return -99;
19641         }
19642     }
19643
19644   if (!vni_set)
19645     {
19646       errmsg ("vni not set!");
19647       return -99;
19648     }
19649
19650   if (!vam->json_output)
19651     {
19652       print (vam->ofp, "%s %40s", "leid", "reid");
19653     }
19654
19655   M (ONE_ADJACENCIES_GET, mp);
19656   mp->vni = clib_host_to_net_u32 (vni);
19657
19658   /* send it... */
19659   S (mp);
19660
19661   /* Wait for a reply... */
19662   W (ret);
19663   return ret;
19664 }
19665
19666 #define api_lisp_adjacencies_get api_one_adjacencies_get
19667
19668 static int
19669 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19670 {
19671   unformat_input_t *i = vam->input;
19672   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19673   int ret;
19674   u8 ip_family_set = 0, is_ip4 = 1;
19675
19676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19677     {
19678       if (unformat (i, "ip4"))
19679         {
19680           ip_family_set = 1;
19681           is_ip4 = 1;
19682         }
19683       else if (unformat (i, "ip6"))
19684         {
19685           ip_family_set = 1;
19686           is_ip4 = 0;
19687         }
19688       else
19689         {
19690           errmsg ("parse error '%U'", format_unformat_error, i);
19691           return -99;
19692         }
19693     }
19694
19695   if (!ip_family_set)
19696     {
19697       errmsg ("ip family not set!");
19698       return -99;
19699     }
19700
19701   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19702   mp->is_ip4 = is_ip4;
19703
19704   /* send it... */
19705   S (mp);
19706
19707   /* Wait for a reply... */
19708   W (ret);
19709   return ret;
19710 }
19711
19712 static int
19713 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19714 {
19715   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19716   int ret;
19717
19718   if (!vam->json_output)
19719     {
19720       print (vam->ofp, "VNIs");
19721     }
19722
19723   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19724
19725   /* send it... */
19726   S (mp);
19727
19728   /* Wait for a reply... */
19729   W (ret);
19730   return ret;
19731 }
19732
19733 static int
19734 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19735 {
19736   unformat_input_t *i = vam->input;
19737   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19738   int ret = 0;
19739   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19740   struct in_addr ip4;
19741   struct in6_addr ip6;
19742   u32 table_id = 0, nh_sw_if_index = ~0;
19743
19744   clib_memset (&ip4, 0, sizeof (ip4));
19745   clib_memset (&ip6, 0, sizeof (ip6));
19746
19747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19748     {
19749       if (unformat (i, "del"))
19750         is_add = 0;
19751       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19752                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19753         {
19754           ip_set = 1;
19755           is_ip4 = 1;
19756         }
19757       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19758                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19759         {
19760           ip_set = 1;
19761           is_ip4 = 0;
19762         }
19763       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19764         {
19765           ip_set = 1;
19766           is_ip4 = 1;
19767           nh_sw_if_index = ~0;
19768         }
19769       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19770         {
19771           ip_set = 1;
19772           is_ip4 = 0;
19773           nh_sw_if_index = ~0;
19774         }
19775       else if (unformat (i, "table %d", &table_id))
19776         ;
19777       else
19778         {
19779           errmsg ("parse error '%U'", format_unformat_error, i);
19780           return -99;
19781         }
19782     }
19783
19784   if (!ip_set)
19785     {
19786       errmsg ("nh addr not set!");
19787       return -99;
19788     }
19789
19790   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19791   mp->is_add = is_add;
19792   mp->table_id = clib_host_to_net_u32 (table_id);
19793   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19794   mp->is_ip4 = is_ip4;
19795   if (is_ip4)
19796     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19797   else
19798     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19799
19800   /* send it... */
19801   S (mp);
19802
19803   /* Wait for a reply... */
19804   W (ret);
19805   return ret;
19806 }
19807
19808 static int
19809 api_one_map_server_dump (vat_main_t * vam)
19810 {
19811   vl_api_one_map_server_dump_t *mp;
19812   vl_api_control_ping_t *mp_ping;
19813   int ret;
19814
19815   if (!vam->json_output)
19816     {
19817       print (vam->ofp, "%=20s", "Map server");
19818     }
19819
19820   M (ONE_MAP_SERVER_DUMP, mp);
19821   /* send it... */
19822   S (mp);
19823
19824   /* Use a control ping for synchronization */
19825   MPING (CONTROL_PING, mp_ping);
19826   S (mp_ping);
19827
19828   /* Wait for a reply... */
19829   W (ret);
19830   return ret;
19831 }
19832
19833 #define api_lisp_map_server_dump api_one_map_server_dump
19834
19835 static int
19836 api_one_map_resolver_dump (vat_main_t * vam)
19837 {
19838   vl_api_one_map_resolver_dump_t *mp;
19839   vl_api_control_ping_t *mp_ping;
19840   int ret;
19841
19842   if (!vam->json_output)
19843     {
19844       print (vam->ofp, "%=20s", "Map resolver");
19845     }
19846
19847   M (ONE_MAP_RESOLVER_DUMP, mp);
19848   /* send it... */
19849   S (mp);
19850
19851   /* Use a control ping for synchronization */
19852   MPING (CONTROL_PING, mp_ping);
19853   S (mp_ping);
19854
19855   /* Wait for a reply... */
19856   W (ret);
19857   return ret;
19858 }
19859
19860 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19861
19862 static int
19863 api_one_stats_flush (vat_main_t * vam)
19864 {
19865   vl_api_one_stats_flush_t *mp;
19866   int ret = 0;
19867
19868   M (ONE_STATS_FLUSH, mp);
19869   S (mp);
19870   W (ret);
19871   return ret;
19872 }
19873
19874 static int
19875 api_one_stats_dump (vat_main_t * vam)
19876 {
19877   vl_api_one_stats_dump_t *mp;
19878   vl_api_control_ping_t *mp_ping;
19879   int ret;
19880
19881   M (ONE_STATS_DUMP, mp);
19882   /* send it... */
19883   S (mp);
19884
19885   /* Use a control ping for synchronization */
19886   MPING (CONTROL_PING, mp_ping);
19887   S (mp_ping);
19888
19889   /* Wait for a reply... */
19890   W (ret);
19891   return ret;
19892 }
19893
19894 static int
19895 api_show_one_status (vat_main_t * vam)
19896 {
19897   vl_api_show_one_status_t *mp;
19898   int ret;
19899
19900   if (!vam->json_output)
19901     {
19902       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19903     }
19904
19905   M (SHOW_ONE_STATUS, mp);
19906   /* send it... */
19907   S (mp);
19908   /* Wait for a reply... */
19909   W (ret);
19910   return ret;
19911 }
19912
19913 #define api_show_lisp_status api_show_one_status
19914
19915 static int
19916 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19917 {
19918   vl_api_gpe_fwd_entry_path_dump_t *mp;
19919   vl_api_control_ping_t *mp_ping;
19920   unformat_input_t *i = vam->input;
19921   u32 fwd_entry_index = ~0;
19922   int ret;
19923
19924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19925     {
19926       if (unformat (i, "index %d", &fwd_entry_index))
19927         ;
19928       else
19929         break;
19930     }
19931
19932   if (~0 == fwd_entry_index)
19933     {
19934       errmsg ("no index specified!");
19935       return -99;
19936     }
19937
19938   if (!vam->json_output)
19939     {
19940       print (vam->ofp, "first line");
19941     }
19942
19943   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19944
19945   /* send it... */
19946   S (mp);
19947   /* Use a control ping for synchronization */
19948   MPING (CONTROL_PING, mp_ping);
19949   S (mp_ping);
19950
19951   /* Wait for a reply... */
19952   W (ret);
19953   return ret;
19954 }
19955
19956 static int
19957 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19958 {
19959   vl_api_one_get_map_request_itr_rlocs_t *mp;
19960   int ret;
19961
19962   if (!vam->json_output)
19963     {
19964       print (vam->ofp, "%=20s", "itr-rlocs:");
19965     }
19966
19967   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19968   /* send it... */
19969   S (mp);
19970   /* Wait for a reply... */
19971   W (ret);
19972   return ret;
19973 }
19974
19975 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19976
19977 static int
19978 api_af_packet_create (vat_main_t * vam)
19979 {
19980   unformat_input_t *i = vam->input;
19981   vl_api_af_packet_create_t *mp;
19982   u8 *host_if_name = 0;
19983   u8 hw_addr[6];
19984   u8 random_hw_addr = 1;
19985   int ret;
19986
19987   clib_memset (hw_addr, 0, sizeof (hw_addr));
19988
19989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19990     {
19991       if (unformat (i, "name %s", &host_if_name))
19992         vec_add1 (host_if_name, 0);
19993       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19994         random_hw_addr = 0;
19995       else
19996         break;
19997     }
19998
19999   if (!vec_len (host_if_name))
20000     {
20001       errmsg ("host-interface name must be specified");
20002       return -99;
20003     }
20004
20005   if (vec_len (host_if_name) > 64)
20006     {
20007       errmsg ("host-interface name too long");
20008       return -99;
20009     }
20010
20011   M (AF_PACKET_CREATE, mp);
20012
20013   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20014   clib_memcpy (mp->hw_addr, hw_addr, 6);
20015   mp->use_random_hw_addr = random_hw_addr;
20016   vec_free (host_if_name);
20017
20018   S (mp);
20019
20020   /* *INDENT-OFF* */
20021   W2 (ret,
20022       ({
20023         if (ret == 0)
20024           fprintf (vam->ofp ? vam->ofp : stderr,
20025                    " new sw_if_index = %d\n", vam->sw_if_index);
20026       }));
20027   /* *INDENT-ON* */
20028   return ret;
20029 }
20030
20031 static int
20032 api_af_packet_delete (vat_main_t * vam)
20033 {
20034   unformat_input_t *i = vam->input;
20035   vl_api_af_packet_delete_t *mp;
20036   u8 *host_if_name = 0;
20037   int ret;
20038
20039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20040     {
20041       if (unformat (i, "name %s", &host_if_name))
20042         vec_add1 (host_if_name, 0);
20043       else
20044         break;
20045     }
20046
20047   if (!vec_len (host_if_name))
20048     {
20049       errmsg ("host-interface name must be specified");
20050       return -99;
20051     }
20052
20053   if (vec_len (host_if_name) > 64)
20054     {
20055       errmsg ("host-interface name too long");
20056       return -99;
20057     }
20058
20059   M (AF_PACKET_DELETE, mp);
20060
20061   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20062   vec_free (host_if_name);
20063
20064   S (mp);
20065   W (ret);
20066   return ret;
20067 }
20068
20069 static void vl_api_af_packet_details_t_handler
20070   (vl_api_af_packet_details_t * mp)
20071 {
20072   vat_main_t *vam = &vat_main;
20073
20074   print (vam->ofp, "%-16s %d",
20075          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
20076 }
20077
20078 static void vl_api_af_packet_details_t_handler_json
20079   (vl_api_af_packet_details_t * mp)
20080 {
20081   vat_main_t *vam = &vat_main;
20082   vat_json_node_t *node = NULL;
20083
20084   if (VAT_JSON_ARRAY != vam->json_tree.type)
20085     {
20086       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20087       vat_json_init_array (&vam->json_tree);
20088     }
20089   node = vat_json_array_add (&vam->json_tree);
20090
20091   vat_json_init_object (node);
20092   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20093   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
20094 }
20095
20096 static int
20097 api_af_packet_dump (vat_main_t * vam)
20098 {
20099   vl_api_af_packet_dump_t *mp;
20100   vl_api_control_ping_t *mp_ping;
20101   int ret;
20102
20103   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
20104   /* Get list of tap interfaces */
20105   M (AF_PACKET_DUMP, mp);
20106   S (mp);
20107
20108   /* Use a control ping for synchronization */
20109   MPING (CONTROL_PING, mp_ping);
20110   S (mp_ping);
20111
20112   W (ret);
20113   return ret;
20114 }
20115
20116 static int
20117 api_policer_add_del (vat_main_t * vam)
20118 {
20119   unformat_input_t *i = vam->input;
20120   vl_api_policer_add_del_t *mp;
20121   u8 is_add = 1;
20122   u8 *name = 0;
20123   u32 cir = 0;
20124   u32 eir = 0;
20125   u64 cb = 0;
20126   u64 eb = 0;
20127   u8 rate_type = 0;
20128   u8 round_type = 0;
20129   u8 type = 0;
20130   u8 color_aware = 0;
20131   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20132   int ret;
20133
20134   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20135   conform_action.dscp = 0;
20136   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20137   exceed_action.dscp = 0;
20138   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20139   violate_action.dscp = 0;
20140
20141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20142     {
20143       if (unformat (i, "del"))
20144         is_add = 0;
20145       else if (unformat (i, "name %s", &name))
20146         vec_add1 (name, 0);
20147       else if (unformat (i, "cir %u", &cir))
20148         ;
20149       else if (unformat (i, "eir %u", &eir))
20150         ;
20151       else if (unformat (i, "cb %u", &cb))
20152         ;
20153       else if (unformat (i, "eb %u", &eb))
20154         ;
20155       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20156                          &rate_type))
20157         ;
20158       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20159                          &round_type))
20160         ;
20161       else if (unformat (i, "type %U", unformat_policer_type, &type))
20162         ;
20163       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20164                          &conform_action))
20165         ;
20166       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20167                          &exceed_action))
20168         ;
20169       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20170                          &violate_action))
20171         ;
20172       else if (unformat (i, "color-aware"))
20173         color_aware = 1;
20174       else
20175         break;
20176     }
20177
20178   if (!vec_len (name))
20179     {
20180       errmsg ("policer name must be specified");
20181       return -99;
20182     }
20183
20184   if (vec_len (name) > 64)
20185     {
20186       errmsg ("policer name too long");
20187       return -99;
20188     }
20189
20190   M (POLICER_ADD_DEL, mp);
20191
20192   clib_memcpy (mp->name, name, vec_len (name));
20193   vec_free (name);
20194   mp->is_add = is_add;
20195   mp->cir = ntohl (cir);
20196   mp->eir = ntohl (eir);
20197   mp->cb = clib_net_to_host_u64 (cb);
20198   mp->eb = clib_net_to_host_u64 (eb);
20199   mp->rate_type = rate_type;
20200   mp->round_type = round_type;
20201   mp->type = type;
20202   mp->conform_action_type = conform_action.action_type;
20203   mp->conform_dscp = conform_action.dscp;
20204   mp->exceed_action_type = exceed_action.action_type;
20205   mp->exceed_dscp = exceed_action.dscp;
20206   mp->violate_action_type = violate_action.action_type;
20207   mp->violate_dscp = violate_action.dscp;
20208   mp->color_aware = color_aware;
20209
20210   S (mp);
20211   W (ret);
20212   return ret;
20213 }
20214
20215 static int
20216 api_policer_dump (vat_main_t * vam)
20217 {
20218   unformat_input_t *i = vam->input;
20219   vl_api_policer_dump_t *mp;
20220   vl_api_control_ping_t *mp_ping;
20221   u8 *match_name = 0;
20222   u8 match_name_valid = 0;
20223   int ret;
20224
20225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20226     {
20227       if (unformat (i, "name %s", &match_name))
20228         {
20229           vec_add1 (match_name, 0);
20230           match_name_valid = 1;
20231         }
20232       else
20233         break;
20234     }
20235
20236   M (POLICER_DUMP, mp);
20237   mp->match_name_valid = match_name_valid;
20238   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20239   vec_free (match_name);
20240   /* send it... */
20241   S (mp);
20242
20243   /* Use a control ping for synchronization */
20244   MPING (CONTROL_PING, mp_ping);
20245   S (mp_ping);
20246
20247   /* Wait for a reply... */
20248   W (ret);
20249   return ret;
20250 }
20251
20252 static int
20253 api_policer_classify_set_interface (vat_main_t * vam)
20254 {
20255   unformat_input_t *i = vam->input;
20256   vl_api_policer_classify_set_interface_t *mp;
20257   u32 sw_if_index;
20258   int sw_if_index_set;
20259   u32 ip4_table_index = ~0;
20260   u32 ip6_table_index = ~0;
20261   u32 l2_table_index = ~0;
20262   u8 is_add = 1;
20263   int ret;
20264
20265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20266     {
20267       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20268         sw_if_index_set = 1;
20269       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20270         sw_if_index_set = 1;
20271       else if (unformat (i, "del"))
20272         is_add = 0;
20273       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20274         ;
20275       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20276         ;
20277       else if (unformat (i, "l2-table %d", &l2_table_index))
20278         ;
20279       else
20280         {
20281           clib_warning ("parse error '%U'", format_unformat_error, i);
20282           return -99;
20283         }
20284     }
20285
20286   if (sw_if_index_set == 0)
20287     {
20288       errmsg ("missing interface name or sw_if_index");
20289       return -99;
20290     }
20291
20292   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20293
20294   mp->sw_if_index = ntohl (sw_if_index);
20295   mp->ip4_table_index = ntohl (ip4_table_index);
20296   mp->ip6_table_index = ntohl (ip6_table_index);
20297   mp->l2_table_index = ntohl (l2_table_index);
20298   mp->is_add = is_add;
20299
20300   S (mp);
20301   W (ret);
20302   return ret;
20303 }
20304
20305 static int
20306 api_policer_classify_dump (vat_main_t * vam)
20307 {
20308   unformat_input_t *i = vam->input;
20309   vl_api_policer_classify_dump_t *mp;
20310   vl_api_control_ping_t *mp_ping;
20311   u8 type = POLICER_CLASSIFY_N_TABLES;
20312   int ret;
20313
20314   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20315     ;
20316   else
20317     {
20318       errmsg ("classify table type must be specified");
20319       return -99;
20320     }
20321
20322   if (!vam->json_output)
20323     {
20324       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20325     }
20326
20327   M (POLICER_CLASSIFY_DUMP, mp);
20328   mp->type = type;
20329   /* send it... */
20330   S (mp);
20331
20332   /* Use a control ping for synchronization */
20333   MPING (CONTROL_PING, mp_ping);
20334   S (mp_ping);
20335
20336   /* Wait for a reply... */
20337   W (ret);
20338   return ret;
20339 }
20340
20341 static int
20342 api_netmap_create (vat_main_t * vam)
20343 {
20344   unformat_input_t *i = vam->input;
20345   vl_api_netmap_create_t *mp;
20346   u8 *if_name = 0;
20347   u8 hw_addr[6];
20348   u8 random_hw_addr = 1;
20349   u8 is_pipe = 0;
20350   u8 is_master = 0;
20351   int ret;
20352
20353   clib_memset (hw_addr, 0, sizeof (hw_addr));
20354
20355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20356     {
20357       if (unformat (i, "name %s", &if_name))
20358         vec_add1 (if_name, 0);
20359       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20360         random_hw_addr = 0;
20361       else if (unformat (i, "pipe"))
20362         is_pipe = 1;
20363       else if (unformat (i, "master"))
20364         is_master = 1;
20365       else if (unformat (i, "slave"))
20366         is_master = 0;
20367       else
20368         break;
20369     }
20370
20371   if (!vec_len (if_name))
20372     {
20373       errmsg ("interface name must be specified");
20374       return -99;
20375     }
20376
20377   if (vec_len (if_name) > 64)
20378     {
20379       errmsg ("interface name too long");
20380       return -99;
20381     }
20382
20383   M (NETMAP_CREATE, mp);
20384
20385   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20386   clib_memcpy (mp->hw_addr, hw_addr, 6);
20387   mp->use_random_hw_addr = random_hw_addr;
20388   mp->is_pipe = is_pipe;
20389   mp->is_master = is_master;
20390   vec_free (if_name);
20391
20392   S (mp);
20393   W (ret);
20394   return ret;
20395 }
20396
20397 static int
20398 api_netmap_delete (vat_main_t * vam)
20399 {
20400   unformat_input_t *i = vam->input;
20401   vl_api_netmap_delete_t *mp;
20402   u8 *if_name = 0;
20403   int ret;
20404
20405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20406     {
20407       if (unformat (i, "name %s", &if_name))
20408         vec_add1 (if_name, 0);
20409       else
20410         break;
20411     }
20412
20413   if (!vec_len (if_name))
20414     {
20415       errmsg ("interface name must be specified");
20416       return -99;
20417     }
20418
20419   if (vec_len (if_name) > 64)
20420     {
20421       errmsg ("interface name too long");
20422       return -99;
20423     }
20424
20425   M (NETMAP_DELETE, mp);
20426
20427   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20428   vec_free (if_name);
20429
20430   S (mp);
20431   W (ret);
20432   return ret;
20433 }
20434
20435 static void
20436 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20437 {
20438   if (fp->afi == IP46_TYPE_IP6)
20439     print (vam->ofp,
20440            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20441            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20442            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20443            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20444            format_ip6_address, fp->next_hop);
20445   else if (fp->afi == IP46_TYPE_IP4)
20446     print (vam->ofp,
20447            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20448            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20449            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20450            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20451            format_ip4_address, fp->next_hop);
20452 }
20453
20454 static void
20455 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20456                                  vl_api_fib_path_t * fp)
20457 {
20458   struct in_addr ip4;
20459   struct in6_addr ip6;
20460
20461   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20462   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20463   vat_json_object_add_uint (node, "is_local", fp->is_local);
20464   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20465   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20466   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20467   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20468   if (fp->afi == IP46_TYPE_IP4)
20469     {
20470       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20471       vat_json_object_add_ip4 (node, "next_hop", ip4);
20472     }
20473   else if (fp->afi == IP46_TYPE_IP6)
20474     {
20475       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20476       vat_json_object_add_ip6 (node, "next_hop", ip6);
20477     }
20478 }
20479
20480 static void
20481 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20482 {
20483   vat_main_t *vam = &vat_main;
20484   int count = ntohl (mp->mt_count);
20485   vl_api_fib_path_t *fp;
20486   i32 i;
20487
20488   print (vam->ofp, "[%d]: sw_if_index %d via:",
20489          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20490   fp = mp->mt_paths;
20491   for (i = 0; i < count; i++)
20492     {
20493       vl_api_mpls_fib_path_print (vam, fp);
20494       fp++;
20495     }
20496
20497   print (vam->ofp, "");
20498 }
20499
20500 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20501 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20502
20503 static void
20504 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20505 {
20506   vat_main_t *vam = &vat_main;
20507   vat_json_node_t *node = NULL;
20508   int count = ntohl (mp->mt_count);
20509   vl_api_fib_path_t *fp;
20510   i32 i;
20511
20512   if (VAT_JSON_ARRAY != vam->json_tree.type)
20513     {
20514       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20515       vat_json_init_array (&vam->json_tree);
20516     }
20517   node = vat_json_array_add (&vam->json_tree);
20518
20519   vat_json_init_object (node);
20520   vat_json_object_add_uint (node, "tunnel_index",
20521                             ntohl (mp->mt_tunnel_index));
20522   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20523
20524   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20525
20526   fp = mp->mt_paths;
20527   for (i = 0; i < count; i++)
20528     {
20529       vl_api_mpls_fib_path_json_print (node, fp);
20530       fp++;
20531     }
20532 }
20533
20534 static int
20535 api_mpls_tunnel_dump (vat_main_t * vam)
20536 {
20537   vl_api_mpls_tunnel_dump_t *mp;
20538   vl_api_control_ping_t *mp_ping;
20539   u32 sw_if_index = ~0;
20540   int ret;
20541
20542   /* Parse args required to build the message */
20543   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20544     {
20545       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20546         ;
20547     }
20548
20549   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20550
20551   M (MPLS_TUNNEL_DUMP, mp);
20552   mp->sw_if_index = htonl (sw_if_index);
20553   S (mp);
20554
20555   /* Use a control ping for synchronization */
20556   MPING (CONTROL_PING, mp_ping);
20557   S (mp_ping);
20558
20559   W (ret);
20560   return ret;
20561 }
20562
20563 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20564 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20565
20566
20567 static void
20568 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20569 {
20570   vat_main_t *vam = &vat_main;
20571   int count = ntohl (mp->count);
20572   vl_api_fib_path_t *fp;
20573   int i;
20574
20575   print (vam->ofp,
20576          "table-id %d, label %u, ess_bit %u",
20577          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20578   fp = mp->path;
20579   for (i = 0; i < count; i++)
20580     {
20581       vl_api_mpls_fib_path_print (vam, fp);
20582       fp++;
20583     }
20584 }
20585
20586 static void vl_api_mpls_fib_details_t_handler_json
20587   (vl_api_mpls_fib_details_t * mp)
20588 {
20589   vat_main_t *vam = &vat_main;
20590   int count = ntohl (mp->count);
20591   vat_json_node_t *node = NULL;
20592   vl_api_fib_path_t *fp;
20593   int i;
20594
20595   if (VAT_JSON_ARRAY != vam->json_tree.type)
20596     {
20597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20598       vat_json_init_array (&vam->json_tree);
20599     }
20600   node = vat_json_array_add (&vam->json_tree);
20601
20602   vat_json_init_object (node);
20603   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20604   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20605   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20606   vat_json_object_add_uint (node, "path_count", count);
20607   fp = mp->path;
20608   for (i = 0; i < count; i++)
20609     {
20610       vl_api_mpls_fib_path_json_print (node, fp);
20611       fp++;
20612     }
20613 }
20614
20615 static int
20616 api_mpls_fib_dump (vat_main_t * vam)
20617 {
20618   vl_api_mpls_fib_dump_t *mp;
20619   vl_api_control_ping_t *mp_ping;
20620   int ret;
20621
20622   M (MPLS_FIB_DUMP, mp);
20623   S (mp);
20624
20625   /* Use a control ping for synchronization */
20626   MPING (CONTROL_PING, mp_ping);
20627   S (mp_ping);
20628
20629   W (ret);
20630   return ret;
20631 }
20632
20633 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20634 #define vl_api_ip_fib_details_t_print vl_noop_handler
20635
20636 static void
20637 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20638 {
20639   vat_main_t *vam = &vat_main;
20640   int count = ntohl (mp->count);
20641   vl_api_fib_path_t *fp;
20642   int i;
20643
20644   print (vam->ofp,
20645          "table-id %d, prefix %U/%d stats-index %d",
20646          ntohl (mp->table_id), format_ip4_address, mp->address,
20647          mp->address_length, ntohl (mp->stats_index));
20648   fp = mp->path;
20649   for (i = 0; i < count; i++)
20650     {
20651       if (fp->afi == IP46_TYPE_IP6)
20652         print (vam->ofp,
20653                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20654                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20655                "next_hop_table %d",
20656                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20657                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20658                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20659       else if (fp->afi == IP46_TYPE_IP4)
20660         print (vam->ofp,
20661                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20662                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20663                "next_hop_table %d",
20664                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20665                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20666                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20667       fp++;
20668     }
20669 }
20670
20671 static void vl_api_ip_fib_details_t_handler_json
20672   (vl_api_ip_fib_details_t * mp)
20673 {
20674   vat_main_t *vam = &vat_main;
20675   int count = ntohl (mp->count);
20676   vat_json_node_t *node = NULL;
20677   struct in_addr ip4;
20678   struct in6_addr ip6;
20679   vl_api_fib_path_t *fp;
20680   int i;
20681
20682   if (VAT_JSON_ARRAY != vam->json_tree.type)
20683     {
20684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20685       vat_json_init_array (&vam->json_tree);
20686     }
20687   node = vat_json_array_add (&vam->json_tree);
20688
20689   vat_json_init_object (node);
20690   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20691   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20692   vat_json_object_add_ip4 (node, "prefix", ip4);
20693   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20694   vat_json_object_add_uint (node, "path_count", count);
20695   fp = mp->path;
20696   for (i = 0; i < count; i++)
20697     {
20698       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20699       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20700       vat_json_object_add_uint (node, "is_local", fp->is_local);
20701       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20702       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20703       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20704       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20705       if (fp->afi == IP46_TYPE_IP4)
20706         {
20707           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20708           vat_json_object_add_ip4 (node, "next_hop", ip4);
20709         }
20710       else if (fp->afi == IP46_TYPE_IP6)
20711         {
20712           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20713           vat_json_object_add_ip6 (node, "next_hop", ip6);
20714         }
20715     }
20716 }
20717
20718 static int
20719 api_ip_fib_dump (vat_main_t * vam)
20720 {
20721   vl_api_ip_fib_dump_t *mp;
20722   vl_api_control_ping_t *mp_ping;
20723   int ret;
20724
20725   M (IP_FIB_DUMP, mp);
20726   S (mp);
20727
20728   /* Use a control ping for synchronization */
20729   MPING (CONTROL_PING, mp_ping);
20730   S (mp_ping);
20731
20732   W (ret);
20733   return ret;
20734 }
20735
20736 static int
20737 api_ip_mfib_dump (vat_main_t * vam)
20738 {
20739   vl_api_ip_mfib_dump_t *mp;
20740   vl_api_control_ping_t *mp_ping;
20741   int ret;
20742
20743   M (IP_MFIB_DUMP, mp);
20744   S (mp);
20745
20746   /* Use a control ping for synchronization */
20747   MPING (CONTROL_PING, mp_ping);
20748   S (mp_ping);
20749
20750   W (ret);
20751   return ret;
20752 }
20753
20754 static void vl_api_ip_neighbor_details_t_handler
20755   (vl_api_ip_neighbor_details_t * mp)
20756 {
20757   vat_main_t *vam = &vat_main;
20758
20759   print (vam->ofp, "%c %U %U",
20760          (mp->is_static) ? 'S' : 'D',
20761          format_ethernet_address, &mp->mac_address,
20762          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20763          &mp->ip_address);
20764 }
20765
20766 static void vl_api_ip_neighbor_details_t_handler_json
20767   (vl_api_ip_neighbor_details_t * mp)
20768 {
20769
20770   vat_main_t *vam = &vat_main;
20771   vat_json_node_t *node;
20772   struct in_addr ip4;
20773   struct in6_addr ip6;
20774
20775   if (VAT_JSON_ARRAY != vam->json_tree.type)
20776     {
20777       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20778       vat_json_init_array (&vam->json_tree);
20779     }
20780   node = vat_json_array_add (&vam->json_tree);
20781
20782   vat_json_init_object (node);
20783   vat_json_object_add_string_copy (node, "flag",
20784                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20785                                    "dynamic");
20786
20787   vat_json_object_add_string_copy (node, "link_layer",
20788                                    format (0, "%U", format_ethernet_address,
20789                                            &mp->mac_address));
20790
20791   if (mp->is_ipv6)
20792     {
20793       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20794       vat_json_object_add_ip6 (node, "ip_address", ip6);
20795     }
20796   else
20797     {
20798       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20799       vat_json_object_add_ip4 (node, "ip_address", ip4);
20800     }
20801 }
20802
20803 static int
20804 api_ip_neighbor_dump (vat_main_t * vam)
20805 {
20806   unformat_input_t *i = vam->input;
20807   vl_api_ip_neighbor_dump_t *mp;
20808   vl_api_control_ping_t *mp_ping;
20809   u8 is_ipv6 = 0;
20810   u32 sw_if_index = ~0;
20811   int ret;
20812
20813   /* Parse args required to build the message */
20814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20815     {
20816       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20817         ;
20818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20819         ;
20820       else if (unformat (i, "ip6"))
20821         is_ipv6 = 1;
20822       else
20823         break;
20824     }
20825
20826   if (sw_if_index == ~0)
20827     {
20828       errmsg ("missing interface name or sw_if_index");
20829       return -99;
20830     }
20831
20832   M (IP_NEIGHBOR_DUMP, mp);
20833   mp->is_ipv6 = (u8) is_ipv6;
20834   mp->sw_if_index = ntohl (sw_if_index);
20835   S (mp);
20836
20837   /* Use a control ping for synchronization */
20838   MPING (CONTROL_PING, mp_ping);
20839   S (mp_ping);
20840
20841   W (ret);
20842   return ret;
20843 }
20844
20845 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20846 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20847
20848 static void
20849 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20850 {
20851   vat_main_t *vam = &vat_main;
20852   int count = ntohl (mp->count);
20853   vl_api_fib_path_t *fp;
20854   int i;
20855
20856   print (vam->ofp,
20857          "table-id %d, prefix %U/%d stats-index %d",
20858          ntohl (mp->table_id), format_ip6_address, mp->address,
20859          mp->address_length, ntohl (mp->stats_index));
20860   fp = mp->path;
20861   for (i = 0; i < count; i++)
20862     {
20863       if (fp->afi == IP46_TYPE_IP6)
20864         print (vam->ofp,
20865                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20866                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20867                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20868                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20869                format_ip6_address, fp->next_hop);
20870       else if (fp->afi == IP46_TYPE_IP4)
20871         print (vam->ofp,
20872                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20873                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20874                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20875                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20876                format_ip4_address, fp->next_hop);
20877       fp++;
20878     }
20879 }
20880
20881 static void vl_api_ip6_fib_details_t_handler_json
20882   (vl_api_ip6_fib_details_t * mp)
20883 {
20884   vat_main_t *vam = &vat_main;
20885   int count = ntohl (mp->count);
20886   vat_json_node_t *node = NULL;
20887   struct in_addr ip4;
20888   struct in6_addr ip6;
20889   vl_api_fib_path_t *fp;
20890   int i;
20891
20892   if (VAT_JSON_ARRAY != vam->json_tree.type)
20893     {
20894       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20895       vat_json_init_array (&vam->json_tree);
20896     }
20897   node = vat_json_array_add (&vam->json_tree);
20898
20899   vat_json_init_object (node);
20900   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20901   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20902   vat_json_object_add_ip6 (node, "prefix", ip6);
20903   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20904   vat_json_object_add_uint (node, "path_count", count);
20905   fp = mp->path;
20906   for (i = 0; i < count; i++)
20907     {
20908       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20909       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20910       vat_json_object_add_uint (node, "is_local", fp->is_local);
20911       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20912       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20913       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20914       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20915       if (fp->afi == IP46_TYPE_IP4)
20916         {
20917           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20918           vat_json_object_add_ip4 (node, "next_hop", ip4);
20919         }
20920       else if (fp->afi == IP46_TYPE_IP6)
20921         {
20922           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20923           vat_json_object_add_ip6 (node, "next_hop", ip6);
20924         }
20925     }
20926 }
20927
20928 static int
20929 api_ip6_fib_dump (vat_main_t * vam)
20930 {
20931   vl_api_ip6_fib_dump_t *mp;
20932   vl_api_control_ping_t *mp_ping;
20933   int ret;
20934
20935   M (IP6_FIB_DUMP, mp);
20936   S (mp);
20937
20938   /* Use a control ping for synchronization */
20939   MPING (CONTROL_PING, mp_ping);
20940   S (mp_ping);
20941
20942   W (ret);
20943   return ret;
20944 }
20945
20946 static int
20947 api_ip6_mfib_dump (vat_main_t * vam)
20948 {
20949   vl_api_ip6_mfib_dump_t *mp;
20950   vl_api_control_ping_t *mp_ping;
20951   int ret;
20952
20953   M (IP6_MFIB_DUMP, mp);
20954   S (mp);
20955
20956   /* Use a control ping for synchronization */
20957   MPING (CONTROL_PING, mp_ping);
20958   S (mp_ping);
20959
20960   W (ret);
20961   return ret;
20962 }
20963
20964 int
20965 api_classify_table_ids (vat_main_t * vam)
20966 {
20967   vl_api_classify_table_ids_t *mp;
20968   int ret;
20969
20970   /* Construct the API message */
20971   M (CLASSIFY_TABLE_IDS, mp);
20972   mp->context = 0;
20973
20974   S (mp);
20975   W (ret);
20976   return ret;
20977 }
20978
20979 int
20980 api_classify_table_by_interface (vat_main_t * vam)
20981 {
20982   unformat_input_t *input = vam->input;
20983   vl_api_classify_table_by_interface_t *mp;
20984
20985   u32 sw_if_index = ~0;
20986   int ret;
20987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20988     {
20989       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20990         ;
20991       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20992         ;
20993       else
20994         break;
20995     }
20996   if (sw_if_index == ~0)
20997     {
20998       errmsg ("missing interface name or sw_if_index");
20999       return -99;
21000     }
21001
21002   /* Construct the API message */
21003   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
21004   mp->context = 0;
21005   mp->sw_if_index = ntohl (sw_if_index);
21006
21007   S (mp);
21008   W (ret);
21009   return ret;
21010 }
21011
21012 int
21013 api_classify_table_info (vat_main_t * vam)
21014 {
21015   unformat_input_t *input = vam->input;
21016   vl_api_classify_table_info_t *mp;
21017
21018   u32 table_id = ~0;
21019   int ret;
21020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21021     {
21022       if (unformat (input, "table_id %d", &table_id))
21023         ;
21024       else
21025         break;
21026     }
21027   if (table_id == ~0)
21028     {
21029       errmsg ("missing table id");
21030       return -99;
21031     }
21032
21033   /* Construct the API message */
21034   M (CLASSIFY_TABLE_INFO, mp);
21035   mp->context = 0;
21036   mp->table_id = ntohl (table_id);
21037
21038   S (mp);
21039   W (ret);
21040   return ret;
21041 }
21042
21043 int
21044 api_classify_session_dump (vat_main_t * vam)
21045 {
21046   unformat_input_t *input = vam->input;
21047   vl_api_classify_session_dump_t *mp;
21048   vl_api_control_ping_t *mp_ping;
21049
21050   u32 table_id = ~0;
21051   int ret;
21052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21053     {
21054       if (unformat (input, "table_id %d", &table_id))
21055         ;
21056       else
21057         break;
21058     }
21059   if (table_id == ~0)
21060     {
21061       errmsg ("missing table id");
21062       return -99;
21063     }
21064
21065   /* Construct the API message */
21066   M (CLASSIFY_SESSION_DUMP, mp);
21067   mp->context = 0;
21068   mp->table_id = ntohl (table_id);
21069   S (mp);
21070
21071   /* Use a control ping for synchronization */
21072   MPING (CONTROL_PING, mp_ping);
21073   S (mp_ping);
21074
21075   W (ret);
21076   return ret;
21077 }
21078
21079 static void
21080 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
21081 {
21082   vat_main_t *vam = &vat_main;
21083
21084   print (vam->ofp, "collector_address %U, collector_port %d, "
21085          "src_address %U, vrf_id %d, path_mtu %u, "
21086          "template_interval %u, udp_checksum %d",
21087          format_ip4_address, mp->collector_address,
21088          ntohs (mp->collector_port),
21089          format_ip4_address, mp->src_address,
21090          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
21091          ntohl (mp->template_interval), mp->udp_checksum);
21092
21093   vam->retval = 0;
21094   vam->result_ready = 1;
21095 }
21096
21097 static void
21098   vl_api_ipfix_exporter_details_t_handler_json
21099   (vl_api_ipfix_exporter_details_t * mp)
21100 {
21101   vat_main_t *vam = &vat_main;
21102   vat_json_node_t node;
21103   struct in_addr collector_address;
21104   struct in_addr src_address;
21105
21106   vat_json_init_object (&node);
21107   clib_memcpy (&collector_address, &mp->collector_address,
21108                sizeof (collector_address));
21109   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
21110   vat_json_object_add_uint (&node, "collector_port",
21111                             ntohs (mp->collector_port));
21112   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21113   vat_json_object_add_ip4 (&node, "src_address", src_address);
21114   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21115   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21116   vat_json_object_add_uint (&node, "template_interval",
21117                             ntohl (mp->template_interval));
21118   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21119
21120   vat_json_print (vam->ofp, &node);
21121   vat_json_free (&node);
21122   vam->retval = 0;
21123   vam->result_ready = 1;
21124 }
21125
21126 int
21127 api_ipfix_exporter_dump (vat_main_t * vam)
21128 {
21129   vl_api_ipfix_exporter_dump_t *mp;
21130   int ret;
21131
21132   /* Construct the API message */
21133   M (IPFIX_EXPORTER_DUMP, mp);
21134   mp->context = 0;
21135
21136   S (mp);
21137   W (ret);
21138   return ret;
21139 }
21140
21141 static int
21142 api_ipfix_classify_stream_dump (vat_main_t * vam)
21143 {
21144   vl_api_ipfix_classify_stream_dump_t *mp;
21145   int ret;
21146
21147   /* Construct the API message */
21148   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21149   mp->context = 0;
21150
21151   S (mp);
21152   W (ret);
21153   return ret;
21154   /* NOTREACHED */
21155   return 0;
21156 }
21157
21158 static void
21159   vl_api_ipfix_classify_stream_details_t_handler
21160   (vl_api_ipfix_classify_stream_details_t * mp)
21161 {
21162   vat_main_t *vam = &vat_main;
21163   print (vam->ofp, "domain_id %d, src_port %d",
21164          ntohl (mp->domain_id), ntohs (mp->src_port));
21165   vam->retval = 0;
21166   vam->result_ready = 1;
21167 }
21168
21169 static void
21170   vl_api_ipfix_classify_stream_details_t_handler_json
21171   (vl_api_ipfix_classify_stream_details_t * mp)
21172 {
21173   vat_main_t *vam = &vat_main;
21174   vat_json_node_t node;
21175
21176   vat_json_init_object (&node);
21177   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21178   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21179
21180   vat_json_print (vam->ofp, &node);
21181   vat_json_free (&node);
21182   vam->retval = 0;
21183   vam->result_ready = 1;
21184 }
21185
21186 static int
21187 api_ipfix_classify_table_dump (vat_main_t * vam)
21188 {
21189   vl_api_ipfix_classify_table_dump_t *mp;
21190   vl_api_control_ping_t *mp_ping;
21191   int ret;
21192
21193   if (!vam->json_output)
21194     {
21195       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21196              "transport_protocol");
21197     }
21198
21199   /* Construct the API message */
21200   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21201
21202   /* send it... */
21203   S (mp);
21204
21205   /* Use a control ping for synchronization */
21206   MPING (CONTROL_PING, mp_ping);
21207   S (mp_ping);
21208
21209   W (ret);
21210   return ret;
21211 }
21212
21213 static void
21214   vl_api_ipfix_classify_table_details_t_handler
21215   (vl_api_ipfix_classify_table_details_t * mp)
21216 {
21217   vat_main_t *vam = &vat_main;
21218   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21219          mp->transport_protocol);
21220 }
21221
21222 static void
21223   vl_api_ipfix_classify_table_details_t_handler_json
21224   (vl_api_ipfix_classify_table_details_t * mp)
21225 {
21226   vat_json_node_t *node = NULL;
21227   vat_main_t *vam = &vat_main;
21228
21229   if (VAT_JSON_ARRAY != vam->json_tree.type)
21230     {
21231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21232       vat_json_init_array (&vam->json_tree);
21233     }
21234
21235   node = vat_json_array_add (&vam->json_tree);
21236   vat_json_init_object (node);
21237
21238   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21239   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21240   vat_json_object_add_uint (node, "transport_protocol",
21241                             mp->transport_protocol);
21242 }
21243
21244 static int
21245 api_sw_interface_span_enable_disable (vat_main_t * vam)
21246 {
21247   unformat_input_t *i = vam->input;
21248   vl_api_sw_interface_span_enable_disable_t *mp;
21249   u32 src_sw_if_index = ~0;
21250   u32 dst_sw_if_index = ~0;
21251   u8 state = 3;
21252   int ret;
21253   u8 is_l2 = 0;
21254
21255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21256     {
21257       if (unformat
21258           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21259         ;
21260       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21261         ;
21262       else
21263         if (unformat
21264             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21265         ;
21266       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21267         ;
21268       else if (unformat (i, "disable"))
21269         state = 0;
21270       else if (unformat (i, "rx"))
21271         state = 1;
21272       else if (unformat (i, "tx"))
21273         state = 2;
21274       else if (unformat (i, "both"))
21275         state = 3;
21276       else if (unformat (i, "l2"))
21277         is_l2 = 1;
21278       else
21279         break;
21280     }
21281
21282   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21283
21284   mp->sw_if_index_from = htonl (src_sw_if_index);
21285   mp->sw_if_index_to = htonl (dst_sw_if_index);
21286   mp->state = state;
21287   mp->is_l2 = is_l2;
21288
21289   S (mp);
21290   W (ret);
21291   return ret;
21292 }
21293
21294 static void
21295 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21296                                             * mp)
21297 {
21298   vat_main_t *vam = &vat_main;
21299   u8 *sw_if_from_name = 0;
21300   u8 *sw_if_to_name = 0;
21301   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21302   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21303   char *states[] = { "none", "rx", "tx", "both" };
21304   hash_pair_t *p;
21305
21306   /* *INDENT-OFF* */
21307   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21308   ({
21309     if ((u32) p->value[0] == sw_if_index_from)
21310       {
21311         sw_if_from_name = (u8 *)(p->key);
21312         if (sw_if_to_name)
21313           break;
21314       }
21315     if ((u32) p->value[0] == sw_if_index_to)
21316       {
21317         sw_if_to_name = (u8 *)(p->key);
21318         if (sw_if_from_name)
21319           break;
21320       }
21321   }));
21322   /* *INDENT-ON* */
21323   print (vam->ofp, "%20s => %20s (%s) %s",
21324          sw_if_from_name, sw_if_to_name, states[mp->state],
21325          mp->is_l2 ? "l2" : "device");
21326 }
21327
21328 static void
21329   vl_api_sw_interface_span_details_t_handler_json
21330   (vl_api_sw_interface_span_details_t * mp)
21331 {
21332   vat_main_t *vam = &vat_main;
21333   vat_json_node_t *node = NULL;
21334   u8 *sw_if_from_name = 0;
21335   u8 *sw_if_to_name = 0;
21336   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21337   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21338   hash_pair_t *p;
21339
21340   /* *INDENT-OFF* */
21341   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21342   ({
21343     if ((u32) p->value[0] == sw_if_index_from)
21344       {
21345         sw_if_from_name = (u8 *)(p->key);
21346         if (sw_if_to_name)
21347           break;
21348       }
21349     if ((u32) p->value[0] == sw_if_index_to)
21350       {
21351         sw_if_to_name = (u8 *)(p->key);
21352         if (sw_if_from_name)
21353           break;
21354       }
21355   }));
21356   /* *INDENT-ON* */
21357
21358   if (VAT_JSON_ARRAY != vam->json_tree.type)
21359     {
21360       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21361       vat_json_init_array (&vam->json_tree);
21362     }
21363   node = vat_json_array_add (&vam->json_tree);
21364
21365   vat_json_init_object (node);
21366   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21367   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21368   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21369   if (0 != sw_if_to_name)
21370     {
21371       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21372     }
21373   vat_json_object_add_uint (node, "state", mp->state);
21374   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21375 }
21376
21377 static int
21378 api_sw_interface_span_dump (vat_main_t * vam)
21379 {
21380   unformat_input_t *input = vam->input;
21381   vl_api_sw_interface_span_dump_t *mp;
21382   vl_api_control_ping_t *mp_ping;
21383   u8 is_l2 = 0;
21384   int ret;
21385
21386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21387     {
21388       if (unformat (input, "l2"))
21389         is_l2 = 1;
21390       else
21391         break;
21392     }
21393
21394   M (SW_INTERFACE_SPAN_DUMP, mp);
21395   mp->is_l2 = is_l2;
21396   S (mp);
21397
21398   /* Use a control ping for synchronization */
21399   MPING (CONTROL_PING, mp_ping);
21400   S (mp_ping);
21401
21402   W (ret);
21403   return ret;
21404 }
21405
21406 int
21407 api_pg_create_interface (vat_main_t * vam)
21408 {
21409   unformat_input_t *input = vam->input;
21410   vl_api_pg_create_interface_t *mp;
21411
21412   u32 if_id = ~0;
21413   int ret;
21414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21415     {
21416       if (unformat (input, "if_id %d", &if_id))
21417         ;
21418       else
21419         break;
21420     }
21421   if (if_id == ~0)
21422     {
21423       errmsg ("missing pg interface index");
21424       return -99;
21425     }
21426
21427   /* Construct the API message */
21428   M (PG_CREATE_INTERFACE, mp);
21429   mp->context = 0;
21430   mp->interface_id = ntohl (if_id);
21431
21432   S (mp);
21433   W (ret);
21434   return ret;
21435 }
21436
21437 int
21438 api_pg_capture (vat_main_t * vam)
21439 {
21440   unformat_input_t *input = vam->input;
21441   vl_api_pg_capture_t *mp;
21442
21443   u32 if_id = ~0;
21444   u8 enable = 1;
21445   u32 count = 1;
21446   u8 pcap_file_set = 0;
21447   u8 *pcap_file = 0;
21448   int ret;
21449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21450     {
21451       if (unformat (input, "if_id %d", &if_id))
21452         ;
21453       else if (unformat (input, "pcap %s", &pcap_file))
21454         pcap_file_set = 1;
21455       else if (unformat (input, "count %d", &count))
21456         ;
21457       else if (unformat (input, "disable"))
21458         enable = 0;
21459       else
21460         break;
21461     }
21462   if (if_id == ~0)
21463     {
21464       errmsg ("missing pg interface index");
21465       return -99;
21466     }
21467   if (pcap_file_set > 0)
21468     {
21469       if (vec_len (pcap_file) > 255)
21470         {
21471           errmsg ("pcap file name is too long");
21472           return -99;
21473         }
21474     }
21475
21476   u32 name_len = vec_len (pcap_file);
21477   /* Construct the API message */
21478   M (PG_CAPTURE, mp);
21479   mp->context = 0;
21480   mp->interface_id = ntohl (if_id);
21481   mp->is_enabled = enable;
21482   mp->count = ntohl (count);
21483   mp->pcap_name_length = ntohl (name_len);
21484   if (pcap_file_set != 0)
21485     {
21486       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21487     }
21488   vec_free (pcap_file);
21489
21490   S (mp);
21491   W (ret);
21492   return ret;
21493 }
21494
21495 int
21496 api_pg_enable_disable (vat_main_t * vam)
21497 {
21498   unformat_input_t *input = vam->input;
21499   vl_api_pg_enable_disable_t *mp;
21500
21501   u8 enable = 1;
21502   u8 stream_name_set = 0;
21503   u8 *stream_name = 0;
21504   int ret;
21505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21506     {
21507       if (unformat (input, "stream %s", &stream_name))
21508         stream_name_set = 1;
21509       else if (unformat (input, "disable"))
21510         enable = 0;
21511       else
21512         break;
21513     }
21514
21515   if (stream_name_set > 0)
21516     {
21517       if (vec_len (stream_name) > 255)
21518         {
21519           errmsg ("stream name too long");
21520           return -99;
21521         }
21522     }
21523
21524   u32 name_len = vec_len (stream_name);
21525   /* Construct the API message */
21526   M (PG_ENABLE_DISABLE, mp);
21527   mp->context = 0;
21528   mp->is_enabled = enable;
21529   if (stream_name_set != 0)
21530     {
21531       mp->stream_name_length = ntohl (name_len);
21532       clib_memcpy (mp->stream_name, stream_name, name_len);
21533     }
21534   vec_free (stream_name);
21535
21536   S (mp);
21537   W (ret);
21538   return ret;
21539 }
21540
21541 int
21542 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21543 {
21544   unformat_input_t *input = vam->input;
21545   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21546
21547   u16 *low_ports = 0;
21548   u16 *high_ports = 0;
21549   u16 this_low;
21550   u16 this_hi;
21551   ip4_address_t ip4_addr;
21552   ip6_address_t ip6_addr;
21553   u32 length;
21554   u32 tmp, tmp2;
21555   u8 prefix_set = 0;
21556   u32 vrf_id = ~0;
21557   u8 is_add = 1;
21558   u8 is_ipv6 = 0;
21559   int ret;
21560
21561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21562     {
21563       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21564         {
21565           prefix_set = 1;
21566         }
21567       else
21568         if (unformat
21569             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21570         {
21571           prefix_set = 1;
21572           is_ipv6 = 1;
21573         }
21574       else if (unformat (input, "vrf %d", &vrf_id))
21575         ;
21576       else if (unformat (input, "del"))
21577         is_add = 0;
21578       else if (unformat (input, "port %d", &tmp))
21579         {
21580           if (tmp == 0 || tmp > 65535)
21581             {
21582               errmsg ("port %d out of range", tmp);
21583               return -99;
21584             }
21585           this_low = tmp;
21586           this_hi = this_low + 1;
21587           vec_add1 (low_ports, this_low);
21588           vec_add1 (high_ports, this_hi);
21589         }
21590       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21591         {
21592           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21593             {
21594               errmsg ("incorrect range parameters");
21595               return -99;
21596             }
21597           this_low = tmp;
21598           /* Note: in debug CLI +1 is added to high before
21599              passing to real fn that does "the work"
21600              (ip_source_and_port_range_check_add_del).
21601              This fn is a wrapper around the binary API fn a
21602              control plane will call, which expects this increment
21603              to have occurred. Hence letting the binary API control
21604              plane fn do the increment for consistency between VAT
21605              and other control planes.
21606            */
21607           this_hi = tmp2;
21608           vec_add1 (low_ports, this_low);
21609           vec_add1 (high_ports, this_hi);
21610         }
21611       else
21612         break;
21613     }
21614
21615   if (prefix_set == 0)
21616     {
21617       errmsg ("<address>/<mask> not specified");
21618       return -99;
21619     }
21620
21621   if (vrf_id == ~0)
21622     {
21623       errmsg ("VRF ID required, not specified");
21624       return -99;
21625     }
21626
21627   if (vrf_id == 0)
21628     {
21629       errmsg
21630         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21631       return -99;
21632     }
21633
21634   if (vec_len (low_ports) == 0)
21635     {
21636       errmsg ("At least one port or port range required");
21637       return -99;
21638     }
21639
21640   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21641
21642   mp->is_add = is_add;
21643
21644   if (is_ipv6)
21645     {
21646       mp->is_ipv6 = 1;
21647       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21648     }
21649   else
21650     {
21651       mp->is_ipv6 = 0;
21652       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21653     }
21654
21655   mp->mask_length = length;
21656   mp->number_of_ranges = vec_len (low_ports);
21657
21658   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21659   vec_free (low_ports);
21660
21661   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21662   vec_free (high_ports);
21663
21664   mp->vrf_id = ntohl (vrf_id);
21665
21666   S (mp);
21667   W (ret);
21668   return ret;
21669 }
21670
21671 int
21672 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21673 {
21674   unformat_input_t *input = vam->input;
21675   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21676   u32 sw_if_index = ~0;
21677   int vrf_set = 0;
21678   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21679   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21680   u8 is_add = 1;
21681   int ret;
21682
21683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21684     {
21685       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21686         ;
21687       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21688         ;
21689       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21690         vrf_set = 1;
21691       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21692         vrf_set = 1;
21693       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21694         vrf_set = 1;
21695       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21696         vrf_set = 1;
21697       else if (unformat (input, "del"))
21698         is_add = 0;
21699       else
21700         break;
21701     }
21702
21703   if (sw_if_index == ~0)
21704     {
21705       errmsg ("Interface required but not specified");
21706       return -99;
21707     }
21708
21709   if (vrf_set == 0)
21710     {
21711       errmsg ("VRF ID required but not specified");
21712       return -99;
21713     }
21714
21715   if (tcp_out_vrf_id == 0
21716       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21717     {
21718       errmsg
21719         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21720       return -99;
21721     }
21722
21723   /* Construct the API message */
21724   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21725
21726   mp->sw_if_index = ntohl (sw_if_index);
21727   mp->is_add = is_add;
21728   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21729   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21730   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21731   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21732
21733   /* send it... */
21734   S (mp);
21735
21736   /* Wait for a reply... */
21737   W (ret);
21738   return ret;
21739 }
21740
21741 static int
21742 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21743 {
21744   unformat_input_t *i = vam->input;
21745   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21746   u32 local_sa_id = 0;
21747   u32 remote_sa_id = 0;
21748   ip4_address_t src_address;
21749   ip4_address_t dst_address;
21750   u8 is_add = 1;
21751   int ret;
21752
21753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21754     {
21755       if (unformat (i, "local_sa %d", &local_sa_id))
21756         ;
21757       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21758         ;
21759       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21760         ;
21761       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21762         ;
21763       else if (unformat (i, "del"))
21764         is_add = 0;
21765       else
21766         {
21767           clib_warning ("parse error '%U'", format_unformat_error, i);
21768           return -99;
21769         }
21770     }
21771
21772   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21773
21774   mp->local_sa_id = ntohl (local_sa_id);
21775   mp->remote_sa_id = ntohl (remote_sa_id);
21776   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21777   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21778   mp->is_add = is_add;
21779
21780   S (mp);
21781   W (ret);
21782   return ret;
21783 }
21784
21785 static int
21786 api_punt (vat_main_t * vam)
21787 {
21788   unformat_input_t *i = vam->input;
21789   vl_api_punt_t *mp;
21790   u32 ipv = ~0;
21791   u32 protocol = ~0;
21792   u32 port = ~0;
21793   int is_add = 1;
21794   int ret;
21795
21796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21797     {
21798       if (unformat (i, "ip %d", &ipv))
21799         ;
21800       else if (unformat (i, "protocol %d", &protocol))
21801         ;
21802       else if (unformat (i, "port %d", &port))
21803         ;
21804       else if (unformat (i, "del"))
21805         is_add = 0;
21806       else
21807         {
21808           clib_warning ("parse error '%U'", format_unformat_error, i);
21809           return -99;
21810         }
21811     }
21812
21813   M (PUNT, mp);
21814
21815   mp->is_add = (u8) is_add;
21816   mp->ipv = (u8) ipv;
21817   mp->l4_protocol = (u8) protocol;
21818   mp->l4_port = htons ((u16) port);
21819
21820   S (mp);
21821   W (ret);
21822   return ret;
21823 }
21824
21825 static void vl_api_ipsec_gre_tunnel_details_t_handler
21826   (vl_api_ipsec_gre_tunnel_details_t * mp)
21827 {
21828   vat_main_t *vam = &vat_main;
21829
21830   print (vam->ofp, "%11d%15U%15U%14d%14d",
21831          ntohl (mp->sw_if_index),
21832          format_ip4_address, &mp->src_address,
21833          format_ip4_address, &mp->dst_address,
21834          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21835 }
21836
21837 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21838   (vl_api_ipsec_gre_tunnel_details_t * mp)
21839 {
21840   vat_main_t *vam = &vat_main;
21841   vat_json_node_t *node = NULL;
21842   struct in_addr ip4;
21843
21844   if (VAT_JSON_ARRAY != vam->json_tree.type)
21845     {
21846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21847       vat_json_init_array (&vam->json_tree);
21848     }
21849   node = vat_json_array_add (&vam->json_tree);
21850
21851   vat_json_init_object (node);
21852   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21853   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21854   vat_json_object_add_ip4 (node, "src_address", ip4);
21855   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21856   vat_json_object_add_ip4 (node, "dst_address", ip4);
21857   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21858   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21859 }
21860
21861 static int
21862 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21863 {
21864   unformat_input_t *i = vam->input;
21865   vl_api_ipsec_gre_tunnel_dump_t *mp;
21866   vl_api_control_ping_t *mp_ping;
21867   u32 sw_if_index;
21868   u8 sw_if_index_set = 0;
21869   int ret;
21870
21871   /* Parse args required to build the message */
21872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21873     {
21874       if (unformat (i, "sw_if_index %d", &sw_if_index))
21875         sw_if_index_set = 1;
21876       else
21877         break;
21878     }
21879
21880   if (sw_if_index_set == 0)
21881     {
21882       sw_if_index = ~0;
21883     }
21884
21885   if (!vam->json_output)
21886     {
21887       print (vam->ofp, "%11s%15s%15s%14s%14s",
21888              "sw_if_index", "src_address", "dst_address",
21889              "local_sa_id", "remote_sa_id");
21890     }
21891
21892   /* Get list of gre-tunnel interfaces */
21893   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21894
21895   mp->sw_if_index = htonl (sw_if_index);
21896
21897   S (mp);
21898
21899   /* Use a control ping for synchronization */
21900   MPING (CONTROL_PING, mp_ping);
21901   S (mp_ping);
21902
21903   W (ret);
21904   return ret;
21905 }
21906
21907 static int
21908 api_delete_subif (vat_main_t * vam)
21909 {
21910   unformat_input_t *i = vam->input;
21911   vl_api_delete_subif_t *mp;
21912   u32 sw_if_index = ~0;
21913   int ret;
21914
21915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21916     {
21917       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21918         ;
21919       if (unformat (i, "sw_if_index %d", &sw_if_index))
21920         ;
21921       else
21922         break;
21923     }
21924
21925   if (sw_if_index == ~0)
21926     {
21927       errmsg ("missing sw_if_index");
21928       return -99;
21929     }
21930
21931   /* Construct the API message */
21932   M (DELETE_SUBIF, mp);
21933   mp->sw_if_index = ntohl (sw_if_index);
21934
21935   S (mp);
21936   W (ret);
21937   return ret;
21938 }
21939
21940 #define foreach_pbb_vtr_op      \
21941 _("disable",  L2_VTR_DISABLED)  \
21942 _("pop",  L2_VTR_POP_2)         \
21943 _("push",  L2_VTR_PUSH_2)
21944
21945 static int
21946 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21947 {
21948   unformat_input_t *i = vam->input;
21949   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21950   u32 sw_if_index = ~0, vtr_op = ~0;
21951   u16 outer_tag = ~0;
21952   u8 dmac[6], smac[6];
21953   u8 dmac_set = 0, smac_set = 0;
21954   u16 vlanid = 0;
21955   u32 sid = ~0;
21956   u32 tmp;
21957   int ret;
21958
21959   /* Shut up coverity */
21960   clib_memset (dmac, 0, sizeof (dmac));
21961   clib_memset (smac, 0, sizeof (smac));
21962
21963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21964     {
21965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21966         ;
21967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21968         ;
21969       else if (unformat (i, "vtr_op %d", &vtr_op))
21970         ;
21971 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21972       foreach_pbb_vtr_op
21973 #undef _
21974         else if (unformat (i, "translate_pbb_stag"))
21975         {
21976           if (unformat (i, "%d", &tmp))
21977             {
21978               vtr_op = L2_VTR_TRANSLATE_2_1;
21979               outer_tag = tmp;
21980             }
21981           else
21982             {
21983               errmsg
21984                 ("translate_pbb_stag operation requires outer tag definition");
21985               return -99;
21986             }
21987         }
21988       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21989         dmac_set++;
21990       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21991         smac_set++;
21992       else if (unformat (i, "sid %d", &sid))
21993         ;
21994       else if (unformat (i, "vlanid %d", &tmp))
21995         vlanid = tmp;
21996       else
21997         {
21998           clib_warning ("parse error '%U'", format_unformat_error, i);
21999           return -99;
22000         }
22001     }
22002
22003   if ((sw_if_index == ~0) || (vtr_op == ~0))
22004     {
22005       errmsg ("missing sw_if_index or vtr operation");
22006       return -99;
22007     }
22008   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
22009       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
22010     {
22011       errmsg
22012         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
22013       return -99;
22014     }
22015
22016   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
22017   mp->sw_if_index = ntohl (sw_if_index);
22018   mp->vtr_op = ntohl (vtr_op);
22019   mp->outer_tag = ntohs (outer_tag);
22020   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
22021   clib_memcpy (mp->b_smac, smac, sizeof (smac));
22022   mp->b_vlanid = ntohs (vlanid);
22023   mp->i_sid = ntohl (sid);
22024
22025   S (mp);
22026   W (ret);
22027   return ret;
22028 }
22029
22030 static int
22031 api_flow_classify_set_interface (vat_main_t * vam)
22032 {
22033   unformat_input_t *i = vam->input;
22034   vl_api_flow_classify_set_interface_t *mp;
22035   u32 sw_if_index;
22036   int sw_if_index_set;
22037   u32 ip4_table_index = ~0;
22038   u32 ip6_table_index = ~0;
22039   u8 is_add = 1;
22040   int ret;
22041
22042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22043     {
22044       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22045         sw_if_index_set = 1;
22046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22047         sw_if_index_set = 1;
22048       else if (unformat (i, "del"))
22049         is_add = 0;
22050       else if (unformat (i, "ip4-table %d", &ip4_table_index))
22051         ;
22052       else if (unformat (i, "ip6-table %d", &ip6_table_index))
22053         ;
22054       else
22055         {
22056           clib_warning ("parse error '%U'", format_unformat_error, i);
22057           return -99;
22058         }
22059     }
22060
22061   if (sw_if_index_set == 0)
22062     {
22063       errmsg ("missing interface name or sw_if_index");
22064       return -99;
22065     }
22066
22067   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
22068
22069   mp->sw_if_index = ntohl (sw_if_index);
22070   mp->ip4_table_index = ntohl (ip4_table_index);
22071   mp->ip6_table_index = ntohl (ip6_table_index);
22072   mp->is_add = is_add;
22073
22074   S (mp);
22075   W (ret);
22076   return ret;
22077 }
22078
22079 static int
22080 api_flow_classify_dump (vat_main_t * vam)
22081 {
22082   unformat_input_t *i = vam->input;
22083   vl_api_flow_classify_dump_t *mp;
22084   vl_api_control_ping_t *mp_ping;
22085   u8 type = FLOW_CLASSIFY_N_TABLES;
22086   int ret;
22087
22088   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
22089     ;
22090   else
22091     {
22092       errmsg ("classify table type must be specified");
22093       return -99;
22094     }
22095
22096   if (!vam->json_output)
22097     {
22098       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
22099     }
22100
22101   M (FLOW_CLASSIFY_DUMP, mp);
22102   mp->type = type;
22103   /* send it... */
22104   S (mp);
22105
22106   /* Use a control ping for synchronization */
22107   MPING (CONTROL_PING, mp_ping);
22108   S (mp_ping);
22109
22110   /* Wait for a reply... */
22111   W (ret);
22112   return ret;
22113 }
22114
22115 static int
22116 api_feature_enable_disable (vat_main_t * vam)
22117 {
22118   unformat_input_t *i = vam->input;
22119   vl_api_feature_enable_disable_t *mp;
22120   u8 *arc_name = 0;
22121   u8 *feature_name = 0;
22122   u32 sw_if_index = ~0;
22123   u8 enable = 1;
22124   int ret;
22125
22126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22127     {
22128       if (unformat (i, "arc_name %s", &arc_name))
22129         ;
22130       else if (unformat (i, "feature_name %s", &feature_name))
22131         ;
22132       else
22133         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22134         ;
22135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22136         ;
22137       else if (unformat (i, "disable"))
22138         enable = 0;
22139       else
22140         break;
22141     }
22142
22143   if (arc_name == 0)
22144     {
22145       errmsg ("missing arc name");
22146       return -99;
22147     }
22148   if (vec_len (arc_name) > 63)
22149     {
22150       errmsg ("arc name too long");
22151     }
22152
22153   if (feature_name == 0)
22154     {
22155       errmsg ("missing feature name");
22156       return -99;
22157     }
22158   if (vec_len (feature_name) > 63)
22159     {
22160       errmsg ("feature name too long");
22161     }
22162
22163   if (sw_if_index == ~0)
22164     {
22165       errmsg ("missing interface name or sw_if_index");
22166       return -99;
22167     }
22168
22169   /* Construct the API message */
22170   M (FEATURE_ENABLE_DISABLE, mp);
22171   mp->sw_if_index = ntohl (sw_if_index);
22172   mp->enable = enable;
22173   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22174   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22175   vec_free (arc_name);
22176   vec_free (feature_name);
22177
22178   S (mp);
22179   W (ret);
22180   return ret;
22181 }
22182
22183 static int
22184 api_sw_interface_tag_add_del (vat_main_t * vam)
22185 {
22186   unformat_input_t *i = vam->input;
22187   vl_api_sw_interface_tag_add_del_t *mp;
22188   u32 sw_if_index = ~0;
22189   u8 *tag = 0;
22190   u8 enable = 1;
22191   int ret;
22192
22193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22194     {
22195       if (unformat (i, "tag %s", &tag))
22196         ;
22197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22198         ;
22199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22200         ;
22201       else if (unformat (i, "del"))
22202         enable = 0;
22203       else
22204         break;
22205     }
22206
22207   if (sw_if_index == ~0)
22208     {
22209       errmsg ("missing interface name or sw_if_index");
22210       return -99;
22211     }
22212
22213   if (enable && (tag == 0))
22214     {
22215       errmsg ("no tag specified");
22216       return -99;
22217     }
22218
22219   /* Construct the API message */
22220   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22221   mp->sw_if_index = ntohl (sw_if_index);
22222   mp->is_add = enable;
22223   if (enable)
22224     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22225   vec_free (tag);
22226
22227   S (mp);
22228   W (ret);
22229   return ret;
22230 }
22231
22232 static void vl_api_l2_xconnect_details_t_handler
22233   (vl_api_l2_xconnect_details_t * mp)
22234 {
22235   vat_main_t *vam = &vat_main;
22236
22237   print (vam->ofp, "%15d%15d",
22238          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22239 }
22240
22241 static void vl_api_l2_xconnect_details_t_handler_json
22242   (vl_api_l2_xconnect_details_t * mp)
22243 {
22244   vat_main_t *vam = &vat_main;
22245   vat_json_node_t *node = NULL;
22246
22247   if (VAT_JSON_ARRAY != vam->json_tree.type)
22248     {
22249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22250       vat_json_init_array (&vam->json_tree);
22251     }
22252   node = vat_json_array_add (&vam->json_tree);
22253
22254   vat_json_init_object (node);
22255   vat_json_object_add_uint (node, "rx_sw_if_index",
22256                             ntohl (mp->rx_sw_if_index));
22257   vat_json_object_add_uint (node, "tx_sw_if_index",
22258                             ntohl (mp->tx_sw_if_index));
22259 }
22260
22261 static int
22262 api_l2_xconnect_dump (vat_main_t * vam)
22263 {
22264   vl_api_l2_xconnect_dump_t *mp;
22265   vl_api_control_ping_t *mp_ping;
22266   int ret;
22267
22268   if (!vam->json_output)
22269     {
22270       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22271     }
22272
22273   M (L2_XCONNECT_DUMP, mp);
22274
22275   S (mp);
22276
22277   /* Use a control ping for synchronization */
22278   MPING (CONTROL_PING, mp_ping);
22279   S (mp_ping);
22280
22281   W (ret);
22282   return ret;
22283 }
22284
22285 static int
22286 api_hw_interface_set_mtu (vat_main_t * vam)
22287 {
22288   unformat_input_t *i = vam->input;
22289   vl_api_hw_interface_set_mtu_t *mp;
22290   u32 sw_if_index = ~0;
22291   u32 mtu = 0;
22292   int ret;
22293
22294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22295     {
22296       if (unformat (i, "mtu %d", &mtu))
22297         ;
22298       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22299         ;
22300       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22301         ;
22302       else
22303         break;
22304     }
22305
22306   if (sw_if_index == ~0)
22307     {
22308       errmsg ("missing interface name or sw_if_index");
22309       return -99;
22310     }
22311
22312   if (mtu == 0)
22313     {
22314       errmsg ("no mtu specified");
22315       return -99;
22316     }
22317
22318   /* Construct the API message */
22319   M (HW_INTERFACE_SET_MTU, mp);
22320   mp->sw_if_index = ntohl (sw_if_index);
22321   mp->mtu = ntohs ((u16) mtu);
22322
22323   S (mp);
22324   W (ret);
22325   return ret;
22326 }
22327
22328 static int
22329 api_p2p_ethernet_add (vat_main_t * vam)
22330 {
22331   unformat_input_t *i = vam->input;
22332   vl_api_p2p_ethernet_add_t *mp;
22333   u32 parent_if_index = ~0;
22334   u32 sub_id = ~0;
22335   u8 remote_mac[6];
22336   u8 mac_set = 0;
22337   int ret;
22338
22339   clib_memset (remote_mac, 0, sizeof (remote_mac));
22340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22341     {
22342       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22343         ;
22344       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22345         ;
22346       else
22347         if (unformat
22348             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22349         mac_set++;
22350       else if (unformat (i, "sub_id %d", &sub_id))
22351         ;
22352       else
22353         {
22354           clib_warning ("parse error '%U'", format_unformat_error, i);
22355           return -99;
22356         }
22357     }
22358
22359   if (parent_if_index == ~0)
22360     {
22361       errmsg ("missing interface name or sw_if_index");
22362       return -99;
22363     }
22364   if (mac_set == 0)
22365     {
22366       errmsg ("missing remote mac address");
22367       return -99;
22368     }
22369   if (sub_id == ~0)
22370     {
22371       errmsg ("missing sub-interface id");
22372       return -99;
22373     }
22374
22375   M (P2P_ETHERNET_ADD, mp);
22376   mp->parent_if_index = ntohl (parent_if_index);
22377   mp->subif_id = ntohl (sub_id);
22378   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22379
22380   S (mp);
22381   W (ret);
22382   return ret;
22383 }
22384
22385 static int
22386 api_p2p_ethernet_del (vat_main_t * vam)
22387 {
22388   unformat_input_t *i = vam->input;
22389   vl_api_p2p_ethernet_del_t *mp;
22390   u32 parent_if_index = ~0;
22391   u8 remote_mac[6];
22392   u8 mac_set = 0;
22393   int ret;
22394
22395   clib_memset (remote_mac, 0, sizeof (remote_mac));
22396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22397     {
22398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22399         ;
22400       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22401         ;
22402       else
22403         if (unformat
22404             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22405         mac_set++;
22406       else
22407         {
22408           clib_warning ("parse error '%U'", format_unformat_error, i);
22409           return -99;
22410         }
22411     }
22412
22413   if (parent_if_index == ~0)
22414     {
22415       errmsg ("missing interface name or sw_if_index");
22416       return -99;
22417     }
22418   if (mac_set == 0)
22419     {
22420       errmsg ("missing remote mac address");
22421       return -99;
22422     }
22423
22424   M (P2P_ETHERNET_DEL, mp);
22425   mp->parent_if_index = ntohl (parent_if_index);
22426   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22427
22428   S (mp);
22429   W (ret);
22430   return ret;
22431 }
22432
22433 static int
22434 api_lldp_config (vat_main_t * vam)
22435 {
22436   unformat_input_t *i = vam->input;
22437   vl_api_lldp_config_t *mp;
22438   int tx_hold = 0;
22439   int tx_interval = 0;
22440   u8 *sys_name = NULL;
22441   int ret;
22442
22443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22444     {
22445       if (unformat (i, "system-name %s", &sys_name))
22446         ;
22447       else if (unformat (i, "tx-hold %d", &tx_hold))
22448         ;
22449       else if (unformat (i, "tx-interval %d", &tx_interval))
22450         ;
22451       else
22452         {
22453           clib_warning ("parse error '%U'", format_unformat_error, i);
22454           return -99;
22455         }
22456     }
22457
22458   vec_add1 (sys_name, 0);
22459
22460   M (LLDP_CONFIG, mp);
22461   mp->tx_hold = htonl (tx_hold);
22462   mp->tx_interval = htonl (tx_interval);
22463   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22464   vec_free (sys_name);
22465
22466   S (mp);
22467   W (ret);
22468   return ret;
22469 }
22470
22471 static int
22472 api_sw_interface_set_lldp (vat_main_t * vam)
22473 {
22474   unformat_input_t *i = vam->input;
22475   vl_api_sw_interface_set_lldp_t *mp;
22476   u32 sw_if_index = ~0;
22477   u32 enable = 1;
22478   u8 *port_desc = NULL, *mgmt_oid = NULL;
22479   ip4_address_t ip4_addr;
22480   ip6_address_t ip6_addr;
22481   int ret;
22482
22483   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
22484   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
22485
22486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22487     {
22488       if (unformat (i, "disable"))
22489         enable = 0;
22490       else
22491         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22492         ;
22493       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22494         ;
22495       else if (unformat (i, "port-desc %s", &port_desc))
22496         ;
22497       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22498         ;
22499       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22500         ;
22501       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22502         ;
22503       else
22504         break;
22505     }
22506
22507   if (sw_if_index == ~0)
22508     {
22509       errmsg ("missing interface name or sw_if_index");
22510       return -99;
22511     }
22512
22513   /* Construct the API message */
22514   vec_add1 (port_desc, 0);
22515   vec_add1 (mgmt_oid, 0);
22516   M (SW_INTERFACE_SET_LLDP, mp);
22517   mp->sw_if_index = ntohl (sw_if_index);
22518   mp->enable = enable;
22519   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22520   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22521   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22522   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22523   vec_free (port_desc);
22524   vec_free (mgmt_oid);
22525
22526   S (mp);
22527   W (ret);
22528   return ret;
22529 }
22530
22531 static int
22532 api_tcp_configure_src_addresses (vat_main_t * vam)
22533 {
22534   vl_api_tcp_configure_src_addresses_t *mp;
22535   unformat_input_t *i = vam->input;
22536   ip4_address_t v4first, v4last;
22537   ip6_address_t v6first, v6last;
22538   u8 range_set = 0;
22539   u32 vrf_id = 0;
22540   int ret;
22541
22542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22543     {
22544       if (unformat (i, "%U - %U",
22545                     unformat_ip4_address, &v4first,
22546                     unformat_ip4_address, &v4last))
22547         {
22548           if (range_set)
22549             {
22550               errmsg ("one range per message (range already set)");
22551               return -99;
22552             }
22553           range_set = 1;
22554         }
22555       else if (unformat (i, "%U - %U",
22556                          unformat_ip6_address, &v6first,
22557                          unformat_ip6_address, &v6last))
22558         {
22559           if (range_set)
22560             {
22561               errmsg ("one range per message (range already set)");
22562               return -99;
22563             }
22564           range_set = 2;
22565         }
22566       else if (unformat (i, "vrf %d", &vrf_id))
22567         ;
22568       else
22569         break;
22570     }
22571
22572   if (range_set == 0)
22573     {
22574       errmsg ("address range not set");
22575       return -99;
22576     }
22577
22578   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22579   mp->vrf_id = ntohl (vrf_id);
22580   /* ipv6? */
22581   if (range_set == 2)
22582     {
22583       mp->is_ipv6 = 1;
22584       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22585       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22586     }
22587   else
22588     {
22589       mp->is_ipv6 = 0;
22590       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22591       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22592     }
22593   S (mp);
22594   W (ret);
22595   return ret;
22596 }
22597
22598 static void vl_api_app_namespace_add_del_reply_t_handler
22599   (vl_api_app_namespace_add_del_reply_t * mp)
22600 {
22601   vat_main_t *vam = &vat_main;
22602   i32 retval = ntohl (mp->retval);
22603   if (vam->async_mode)
22604     {
22605       vam->async_errors += (retval < 0);
22606     }
22607   else
22608     {
22609       vam->retval = retval;
22610       if (retval == 0)
22611         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22612       vam->result_ready = 1;
22613     }
22614 }
22615
22616 static void vl_api_app_namespace_add_del_reply_t_handler_json
22617   (vl_api_app_namespace_add_del_reply_t * mp)
22618 {
22619   vat_main_t *vam = &vat_main;
22620   vat_json_node_t node;
22621
22622   vat_json_init_object (&node);
22623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22624   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22625
22626   vat_json_print (vam->ofp, &node);
22627   vat_json_free (&node);
22628
22629   vam->retval = ntohl (mp->retval);
22630   vam->result_ready = 1;
22631 }
22632
22633 static int
22634 api_app_namespace_add_del (vat_main_t * vam)
22635 {
22636   vl_api_app_namespace_add_del_t *mp;
22637   unformat_input_t *i = vam->input;
22638   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22639   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22640   u64 secret;
22641   int ret;
22642
22643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22644     {
22645       if (unformat (i, "id %_%v%_", &ns_id))
22646         ;
22647       else if (unformat (i, "secret %lu", &secret))
22648         secret_set = 1;
22649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22650         sw_if_index_set = 1;
22651       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22652         ;
22653       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22654         ;
22655       else
22656         break;
22657     }
22658   if (!ns_id || !secret_set || !sw_if_index_set)
22659     {
22660       errmsg ("namespace id, secret and sw_if_index must be set");
22661       return -99;
22662     }
22663   if (vec_len (ns_id) > 64)
22664     {
22665       errmsg ("namespace id too long");
22666       return -99;
22667     }
22668   M (APP_NAMESPACE_ADD_DEL, mp);
22669
22670   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22671   mp->namespace_id_len = vec_len (ns_id);
22672   mp->secret = clib_host_to_net_u64 (secret);
22673   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22674   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22675   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22676   vec_free (ns_id);
22677   S (mp);
22678   W (ret);
22679   return ret;
22680 }
22681
22682 static int
22683 api_sock_init_shm (vat_main_t * vam)
22684 {
22685 #if VPP_API_TEST_BUILTIN == 0
22686   unformat_input_t *i = vam->input;
22687   vl_api_shm_elem_config_t *config = 0;
22688   u64 size = 64 << 20;
22689   int rv;
22690
22691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22692     {
22693       if (unformat (i, "size %U", unformat_memory_size, &size))
22694         ;
22695       else
22696         break;
22697     }
22698
22699   /*
22700    * Canned custom ring allocator config.
22701    * Should probably parse all of this
22702    */
22703   vec_validate (config, 6);
22704   config[0].type = VL_API_VLIB_RING;
22705   config[0].size = 256;
22706   config[0].count = 32;
22707
22708   config[1].type = VL_API_VLIB_RING;
22709   config[1].size = 1024;
22710   config[1].count = 16;
22711
22712   config[2].type = VL_API_VLIB_RING;
22713   config[2].size = 4096;
22714   config[2].count = 2;
22715
22716   config[3].type = VL_API_CLIENT_RING;
22717   config[3].size = 256;
22718   config[3].count = 32;
22719
22720   config[4].type = VL_API_CLIENT_RING;
22721   config[4].size = 1024;
22722   config[4].count = 16;
22723
22724   config[5].type = VL_API_CLIENT_RING;
22725   config[5].size = 4096;
22726   config[5].count = 2;
22727
22728   config[6].type = VL_API_QUEUE;
22729   config[6].count = 128;
22730   config[6].size = sizeof (uword);
22731
22732   rv = vl_socket_client_init_shm (config);
22733   if (!rv)
22734     vam->client_index_invalid = 1;
22735   return rv;
22736 #else
22737   return -99;
22738 #endif
22739 }
22740
22741 static int
22742 api_dns_enable_disable (vat_main_t * vam)
22743 {
22744   unformat_input_t *line_input = vam->input;
22745   vl_api_dns_enable_disable_t *mp;
22746   u8 enable_disable = 1;
22747   int ret;
22748
22749   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22750     {
22751       if (unformat (line_input, "disable"))
22752         enable_disable = 0;
22753       if (unformat (line_input, "enable"))
22754         enable_disable = 1;
22755       else
22756         break;
22757     }
22758
22759   /* Construct the API message */
22760   M (DNS_ENABLE_DISABLE, mp);
22761   mp->enable = enable_disable;
22762
22763   /* send it... */
22764   S (mp);
22765   /* Wait for the reply */
22766   W (ret);
22767   return ret;
22768 }
22769
22770 static int
22771 api_dns_resolve_name (vat_main_t * vam)
22772 {
22773   unformat_input_t *line_input = vam->input;
22774   vl_api_dns_resolve_name_t *mp;
22775   u8 *name = 0;
22776   int ret;
22777
22778   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22779     {
22780       if (unformat (line_input, "%s", &name))
22781         ;
22782       else
22783         break;
22784     }
22785
22786   if (vec_len (name) > 127)
22787     {
22788       errmsg ("name too long");
22789       return -99;
22790     }
22791
22792   /* Construct the API message */
22793   M (DNS_RESOLVE_NAME, mp);
22794   memcpy (mp->name, name, vec_len (name));
22795   vec_free (name);
22796
22797   /* send it... */
22798   S (mp);
22799   /* Wait for the reply */
22800   W (ret);
22801   return ret;
22802 }
22803
22804 static int
22805 api_dns_resolve_ip (vat_main_t * vam)
22806 {
22807   unformat_input_t *line_input = vam->input;
22808   vl_api_dns_resolve_ip_t *mp;
22809   int is_ip6 = -1;
22810   ip4_address_t addr4;
22811   ip6_address_t addr6;
22812   int ret;
22813
22814   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22815     {
22816       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22817         is_ip6 = 1;
22818       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22819         is_ip6 = 0;
22820       else
22821         break;
22822     }
22823
22824   if (is_ip6 == -1)
22825     {
22826       errmsg ("missing address");
22827       return -99;
22828     }
22829
22830   /* Construct the API message */
22831   M (DNS_RESOLVE_IP, mp);
22832   mp->is_ip6 = is_ip6;
22833   if (is_ip6)
22834     memcpy (mp->address, &addr6, sizeof (addr6));
22835   else
22836     memcpy (mp->address, &addr4, sizeof (addr4));
22837
22838   /* send it... */
22839   S (mp);
22840   /* Wait for the reply */
22841   W (ret);
22842   return ret;
22843 }
22844
22845 static int
22846 api_dns_name_server_add_del (vat_main_t * vam)
22847 {
22848   unformat_input_t *i = vam->input;
22849   vl_api_dns_name_server_add_del_t *mp;
22850   u8 is_add = 1;
22851   ip6_address_t ip6_server;
22852   ip4_address_t ip4_server;
22853   int ip6_set = 0;
22854   int ip4_set = 0;
22855   int ret = 0;
22856
22857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22858     {
22859       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22860         ip6_set = 1;
22861       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22862         ip4_set = 1;
22863       else if (unformat (i, "del"))
22864         is_add = 0;
22865       else
22866         {
22867           clib_warning ("parse error '%U'", format_unformat_error, i);
22868           return -99;
22869         }
22870     }
22871
22872   if (ip4_set && ip6_set)
22873     {
22874       errmsg ("Only one server address allowed per message");
22875       return -99;
22876     }
22877   if ((ip4_set + ip6_set) == 0)
22878     {
22879       errmsg ("Server address required");
22880       return -99;
22881     }
22882
22883   /* Construct the API message */
22884   M (DNS_NAME_SERVER_ADD_DEL, mp);
22885
22886   if (ip6_set)
22887     {
22888       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22889       mp->is_ip6 = 1;
22890     }
22891   else
22892     {
22893       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22894       mp->is_ip6 = 0;
22895     }
22896
22897   mp->is_add = is_add;
22898
22899   /* send it... */
22900   S (mp);
22901
22902   /* Wait for a reply, return good/bad news  */
22903   W (ret);
22904   return ret;
22905 }
22906
22907 static void
22908 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22909 {
22910   vat_main_t *vam = &vat_main;
22911
22912   if (mp->is_ip4)
22913     {
22914       print (vam->ofp,
22915              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22916              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22917              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22918              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22919              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22920              clib_net_to_host_u32 (mp->action_index), mp->tag);
22921     }
22922   else
22923     {
22924       print (vam->ofp,
22925              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22926              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22927              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22928              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22929              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22930              clib_net_to_host_u32 (mp->action_index), mp->tag);
22931     }
22932 }
22933
22934 static void
22935 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22936                                              mp)
22937 {
22938   vat_main_t *vam = &vat_main;
22939   vat_json_node_t *node = NULL;
22940   struct in6_addr ip6;
22941   struct in_addr ip4;
22942
22943   if (VAT_JSON_ARRAY != vam->json_tree.type)
22944     {
22945       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22946       vat_json_init_array (&vam->json_tree);
22947     }
22948   node = vat_json_array_add (&vam->json_tree);
22949   vat_json_init_object (node);
22950
22951   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22952   vat_json_object_add_uint (node, "appns_index",
22953                             clib_net_to_host_u32 (mp->appns_index));
22954   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22955   vat_json_object_add_uint (node, "scope", mp->scope);
22956   vat_json_object_add_uint (node, "action_index",
22957                             clib_net_to_host_u32 (mp->action_index));
22958   vat_json_object_add_uint (node, "lcl_port",
22959                             clib_net_to_host_u16 (mp->lcl_port));
22960   vat_json_object_add_uint (node, "rmt_port",
22961                             clib_net_to_host_u16 (mp->rmt_port));
22962   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22963   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22964   vat_json_object_add_string_copy (node, "tag", mp->tag);
22965   if (mp->is_ip4)
22966     {
22967       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22968       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22969       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22970       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22971     }
22972   else
22973     {
22974       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22975       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22976       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22977       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22978     }
22979 }
22980
22981 static int
22982 api_session_rule_add_del (vat_main_t * vam)
22983 {
22984   vl_api_session_rule_add_del_t *mp;
22985   unformat_input_t *i = vam->input;
22986   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22987   u32 appns_index = 0, scope = 0;
22988   ip4_address_t lcl_ip4, rmt_ip4;
22989   ip6_address_t lcl_ip6, rmt_ip6;
22990   u8 is_ip4 = 1, conn_set = 0;
22991   u8 is_add = 1, *tag = 0;
22992   int ret;
22993
22994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22995     {
22996       if (unformat (i, "del"))
22997         is_add = 0;
22998       else if (unformat (i, "add"))
22999         ;
23000       else if (unformat (i, "proto tcp"))
23001         proto = 0;
23002       else if (unformat (i, "proto udp"))
23003         proto = 1;
23004       else if (unformat (i, "appns %d", &appns_index))
23005         ;
23006       else if (unformat (i, "scope %d", &scope))
23007         ;
23008       else if (unformat (i, "tag %_%v%_", &tag))
23009         ;
23010       else
23011         if (unformat
23012             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
23013              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
23014              &rmt_port))
23015         {
23016           is_ip4 = 1;
23017           conn_set = 1;
23018         }
23019       else
23020         if (unformat
23021             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
23022              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
23023              &rmt_port))
23024         {
23025           is_ip4 = 0;
23026           conn_set = 1;
23027         }
23028       else if (unformat (i, "action %d", &action))
23029         ;
23030       else
23031         break;
23032     }
23033   if (proto == ~0 || !conn_set || action == ~0)
23034     {
23035       errmsg ("transport proto, connection and action must be set");
23036       return -99;
23037     }
23038
23039   if (scope > 3)
23040     {
23041       errmsg ("scope should be 0-3");
23042       return -99;
23043     }
23044
23045   M (SESSION_RULE_ADD_DEL, mp);
23046
23047   mp->is_ip4 = is_ip4;
23048   mp->transport_proto = proto;
23049   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
23050   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
23051   mp->lcl_plen = lcl_plen;
23052   mp->rmt_plen = rmt_plen;
23053   mp->action_index = clib_host_to_net_u32 (action);
23054   mp->appns_index = clib_host_to_net_u32 (appns_index);
23055   mp->scope = scope;
23056   mp->is_add = is_add;
23057   if (is_ip4)
23058     {
23059       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
23060       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
23061     }
23062   else
23063     {
23064       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23065       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23066     }
23067   if (tag)
23068     {
23069       clib_memcpy (mp->tag, tag, vec_len (tag));
23070       vec_free (tag);
23071     }
23072
23073   S (mp);
23074   W (ret);
23075   return ret;
23076 }
23077
23078 static int
23079 api_session_rules_dump (vat_main_t * vam)
23080 {
23081   vl_api_session_rules_dump_t *mp;
23082   vl_api_control_ping_t *mp_ping;
23083   int ret;
23084
23085   if (!vam->json_output)
23086     {
23087       print (vam->ofp, "%=20s", "Session Rules");
23088     }
23089
23090   M (SESSION_RULES_DUMP, mp);
23091   /* send it... */
23092   S (mp);
23093
23094   /* Use a control ping for synchronization */
23095   MPING (CONTROL_PING, mp_ping);
23096   S (mp_ping);
23097
23098   /* Wait for a reply... */
23099   W (ret);
23100   return ret;
23101 }
23102
23103 static int
23104 api_ip_container_proxy_add_del (vat_main_t * vam)
23105 {
23106   vl_api_ip_container_proxy_add_del_t *mp;
23107   unformat_input_t *i = vam->input;
23108   u32 plen = ~0, sw_if_index = ~0;
23109   ip4_address_t ip4;
23110   ip6_address_t ip6;
23111   u8 is_ip4 = 1;
23112   u8 is_add = 1;
23113   int ret;
23114
23115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23116     {
23117       if (unformat (i, "del"))
23118         is_add = 0;
23119       else if (unformat (i, "add"))
23120         ;
23121       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23122         {
23123           is_ip4 = 1;
23124           plen = 32;
23125         }
23126       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23127         {
23128           is_ip4 = 0;
23129           plen = 128;
23130         }
23131       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23132         ;
23133       else
23134         break;
23135     }
23136   if (sw_if_index == ~0 || plen == ~0)
23137     {
23138       errmsg ("address and sw_if_index must be set");
23139       return -99;
23140     }
23141
23142   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23143
23144   mp->is_ip4 = is_ip4;
23145   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23146   mp->plen = plen;
23147   mp->is_add = is_add;
23148   if (is_ip4)
23149     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23150   else
23151     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23152
23153   S (mp);
23154   W (ret);
23155   return ret;
23156 }
23157
23158 static int
23159 api_qos_record_enable_disable (vat_main_t * vam)
23160 {
23161   unformat_input_t *i = vam->input;
23162   vl_api_qos_record_enable_disable_t *mp;
23163   u32 sw_if_index, qs = 0xff;
23164   u8 sw_if_index_set = 0;
23165   u8 enable = 1;
23166   int ret;
23167
23168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23169     {
23170       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23171         sw_if_index_set = 1;
23172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23173         sw_if_index_set = 1;
23174       else if (unformat (i, "%U", unformat_qos_source, &qs))
23175         ;
23176       else if (unformat (i, "disable"))
23177         enable = 0;
23178       else
23179         {
23180           clib_warning ("parse error '%U'", format_unformat_error, i);
23181           return -99;
23182         }
23183     }
23184
23185   if (sw_if_index_set == 0)
23186     {
23187       errmsg ("missing interface name or sw_if_index");
23188       return -99;
23189     }
23190   if (qs == 0xff)
23191     {
23192       errmsg ("input location must be specified");
23193       return -99;
23194     }
23195
23196   M (QOS_RECORD_ENABLE_DISABLE, mp);
23197
23198   mp->sw_if_index = ntohl (sw_if_index);
23199   mp->input_source = qs;
23200   mp->enable = enable;
23201
23202   S (mp);
23203   W (ret);
23204   return ret;
23205 }
23206
23207
23208 static int
23209 q_or_quit (vat_main_t * vam)
23210 {
23211 #if VPP_API_TEST_BUILTIN == 0
23212   longjmp (vam->jump_buf, 1);
23213 #endif
23214   return 0;                     /* not so much */
23215 }
23216
23217 static int
23218 q (vat_main_t * vam)
23219 {
23220   return q_or_quit (vam);
23221 }
23222
23223 static int
23224 quit (vat_main_t * vam)
23225 {
23226   return q_or_quit (vam);
23227 }
23228
23229 static int
23230 comment (vat_main_t * vam)
23231 {
23232   return 0;
23233 }
23234
23235 static int
23236 statseg (vat_main_t * vam)
23237 {
23238   ssvm_private_t *ssvmp = &vam->stat_segment;
23239   ssvm_shared_header_t *shared_header = ssvmp->sh;
23240   vlib_counter_t **counters;
23241   u64 thread0_index1_packets;
23242   u64 thread0_index1_bytes;
23243   f64 vector_rate, input_rate;
23244   uword *p;
23245
23246   uword *counter_vector_by_name;
23247   if (vam->stat_segment_lockp == 0)
23248     {
23249       errmsg ("Stat segment not mapped...");
23250       return -99;
23251     }
23252
23253   /* look up "/if/rx for sw_if_index 1 as a test */
23254
23255   clib_spinlock_lock (vam->stat_segment_lockp);
23256
23257   counter_vector_by_name = (uword *) shared_header->opaque[1];
23258
23259   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23260   if (p == 0)
23261     {
23262       clib_spinlock_unlock (vam->stat_segment_lockp);
23263       errmsg ("/if/tx not found?");
23264       return -99;
23265     }
23266
23267   /* Fish per-thread vector of combined counters from shared memory */
23268   counters = (vlib_counter_t **) p[0];
23269
23270   if (vec_len (counters[0]) < 2)
23271     {
23272       clib_spinlock_unlock (vam->stat_segment_lockp);
23273       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23274       return -99;
23275     }
23276
23277   /* Read thread 0 sw_if_index 1 counter */
23278   thread0_index1_packets = counters[0][1].packets;
23279   thread0_index1_bytes = counters[0][1].bytes;
23280
23281   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23282   if (p == 0)
23283     {
23284       clib_spinlock_unlock (vam->stat_segment_lockp);
23285       errmsg ("vector_rate not found?");
23286       return -99;
23287     }
23288
23289   vector_rate = *(f64 *) (p[0]);
23290   p = hash_get_mem (counter_vector_by_name, "input_rate");
23291   if (p == 0)
23292     {
23293       clib_spinlock_unlock (vam->stat_segment_lockp);
23294       errmsg ("input_rate not found?");
23295       return -99;
23296     }
23297   input_rate = *(f64 *) (p[0]);
23298
23299   clib_spinlock_unlock (vam->stat_segment_lockp);
23300
23301   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23302          vector_rate, input_rate);
23303   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23304          thread0_index1_packets, thread0_index1_bytes);
23305
23306   return 0;
23307 }
23308
23309 static int
23310 cmd_cmp (void *a1, void *a2)
23311 {
23312   u8 **c1 = a1;
23313   u8 **c2 = a2;
23314
23315   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23316 }
23317
23318 static int
23319 help (vat_main_t * vam)
23320 {
23321   u8 **cmds = 0;
23322   u8 *name = 0;
23323   hash_pair_t *p;
23324   unformat_input_t *i = vam->input;
23325   int j;
23326
23327   if (unformat (i, "%s", &name))
23328     {
23329       uword *hs;
23330
23331       vec_add1 (name, 0);
23332
23333       hs = hash_get_mem (vam->help_by_name, name);
23334       if (hs)
23335         print (vam->ofp, "usage: %s %s", name, hs[0]);
23336       else
23337         print (vam->ofp, "No such msg / command '%s'", name);
23338       vec_free (name);
23339       return 0;
23340     }
23341
23342   print (vam->ofp, "Help is available for the following:");
23343
23344     /* *INDENT-OFF* */
23345     hash_foreach_pair (p, vam->function_by_name,
23346     ({
23347       vec_add1 (cmds, (u8 *)(p->key));
23348     }));
23349     /* *INDENT-ON* */
23350
23351   vec_sort_with_function (cmds, cmd_cmp);
23352
23353   for (j = 0; j < vec_len (cmds); j++)
23354     print (vam->ofp, "%s", cmds[j]);
23355
23356   vec_free (cmds);
23357   return 0;
23358 }
23359
23360 static int
23361 set (vat_main_t * vam)
23362 {
23363   u8 *name = 0, *value = 0;
23364   unformat_input_t *i = vam->input;
23365
23366   if (unformat (i, "%s", &name))
23367     {
23368       /* The input buffer is a vector, not a string. */
23369       value = vec_dup (i->buffer);
23370       vec_delete (value, i->index, 0);
23371       /* Almost certainly has a trailing newline */
23372       if (value[vec_len (value) - 1] == '\n')
23373         value[vec_len (value) - 1] = 0;
23374       /* Make sure it's a proper string, one way or the other */
23375       vec_add1 (value, 0);
23376       (void) clib_macro_set_value (&vam->macro_main,
23377                                    (char *) name, (char *) value);
23378     }
23379   else
23380     errmsg ("usage: set <name> <value>");
23381
23382   vec_free (name);
23383   vec_free (value);
23384   return 0;
23385 }
23386
23387 static int
23388 unset (vat_main_t * vam)
23389 {
23390   u8 *name = 0;
23391
23392   if (unformat (vam->input, "%s", &name))
23393     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23394       errmsg ("unset: %s wasn't set", name);
23395   vec_free (name);
23396   return 0;
23397 }
23398
23399 typedef struct
23400 {
23401   u8 *name;
23402   u8 *value;
23403 } macro_sort_t;
23404
23405
23406 static int
23407 macro_sort_cmp (void *a1, void *a2)
23408 {
23409   macro_sort_t *s1 = a1;
23410   macro_sort_t *s2 = a2;
23411
23412   return strcmp ((char *) (s1->name), (char *) (s2->name));
23413 }
23414
23415 static int
23416 dump_macro_table (vat_main_t * vam)
23417 {
23418   macro_sort_t *sort_me = 0, *sm;
23419   int i;
23420   hash_pair_t *p;
23421
23422     /* *INDENT-OFF* */
23423     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23424     ({
23425       vec_add2 (sort_me, sm, 1);
23426       sm->name = (u8 *)(p->key);
23427       sm->value = (u8 *) (p->value[0]);
23428     }));
23429     /* *INDENT-ON* */
23430
23431   vec_sort_with_function (sort_me, macro_sort_cmp);
23432
23433   if (vec_len (sort_me))
23434     print (vam->ofp, "%-15s%s", "Name", "Value");
23435   else
23436     print (vam->ofp, "The macro table is empty...");
23437
23438   for (i = 0; i < vec_len (sort_me); i++)
23439     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23440   return 0;
23441 }
23442
23443 static int
23444 dump_node_table (vat_main_t * vam)
23445 {
23446   int i, j;
23447   vlib_node_t *node, *next_node;
23448
23449   if (vec_len (vam->graph_nodes) == 0)
23450     {
23451       print (vam->ofp, "Node table empty, issue get_node_graph...");
23452       return 0;
23453     }
23454
23455   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23456     {
23457       node = vam->graph_nodes[0][i];
23458       print (vam->ofp, "[%d] %s", i, node->name);
23459       for (j = 0; j < vec_len (node->next_nodes); j++)
23460         {
23461           if (node->next_nodes[j] != ~0)
23462             {
23463               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23464               print (vam->ofp, "  [%d] %s", j, next_node->name);
23465             }
23466         }
23467     }
23468   return 0;
23469 }
23470
23471 static int
23472 value_sort_cmp (void *a1, void *a2)
23473 {
23474   name_sort_t *n1 = a1;
23475   name_sort_t *n2 = a2;
23476
23477   if (n1->value < n2->value)
23478     return -1;
23479   if (n1->value > n2->value)
23480     return 1;
23481   return 0;
23482 }
23483
23484
23485 static int
23486 dump_msg_api_table (vat_main_t * vam)
23487 {
23488   api_main_t *am = &api_main;
23489   name_sort_t *nses = 0, *ns;
23490   hash_pair_t *hp;
23491   int i;
23492
23493   /* *INDENT-OFF* */
23494   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23495   ({
23496     vec_add2 (nses, ns, 1);
23497     ns->name = (u8 *)(hp->key);
23498     ns->value = (u32) hp->value[0];
23499   }));
23500   /* *INDENT-ON* */
23501
23502   vec_sort_with_function (nses, value_sort_cmp);
23503
23504   for (i = 0; i < vec_len (nses); i++)
23505     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23506   vec_free (nses);
23507   return 0;
23508 }
23509
23510 static int
23511 get_msg_id (vat_main_t * vam)
23512 {
23513   u8 *name_and_crc;
23514   u32 message_index;
23515
23516   if (unformat (vam->input, "%s", &name_and_crc))
23517     {
23518       message_index = vl_msg_api_get_msg_index (name_and_crc);
23519       if (message_index == ~0)
23520         {
23521           print (vam->ofp, " '%s' not found", name_and_crc);
23522           return 0;
23523         }
23524       print (vam->ofp, " '%s' has message index %d",
23525              name_and_crc, message_index);
23526       return 0;
23527     }
23528   errmsg ("name_and_crc required...");
23529   return 0;
23530 }
23531
23532 static int
23533 search_node_table (vat_main_t * vam)
23534 {
23535   unformat_input_t *line_input = vam->input;
23536   u8 *node_to_find;
23537   int j;
23538   vlib_node_t *node, *next_node;
23539   uword *p;
23540
23541   if (vam->graph_node_index_by_name == 0)
23542     {
23543       print (vam->ofp, "Node table empty, issue get_node_graph...");
23544       return 0;
23545     }
23546
23547   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23548     {
23549       if (unformat (line_input, "%s", &node_to_find))
23550         {
23551           vec_add1 (node_to_find, 0);
23552           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23553           if (p == 0)
23554             {
23555               print (vam->ofp, "%s not found...", node_to_find);
23556               goto out;
23557             }
23558           node = vam->graph_nodes[0][p[0]];
23559           print (vam->ofp, "[%d] %s", p[0], node->name);
23560           for (j = 0; j < vec_len (node->next_nodes); j++)
23561             {
23562               if (node->next_nodes[j] != ~0)
23563                 {
23564                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23565                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23566                 }
23567             }
23568         }
23569
23570       else
23571         {
23572           clib_warning ("parse error '%U'", format_unformat_error,
23573                         line_input);
23574           return -99;
23575         }
23576
23577     out:
23578       vec_free (node_to_find);
23579
23580     }
23581
23582   return 0;
23583 }
23584
23585
23586 static int
23587 script (vat_main_t * vam)
23588 {
23589 #if (VPP_API_TEST_BUILTIN==0)
23590   u8 *s = 0;
23591   char *save_current_file;
23592   unformat_input_t save_input;
23593   jmp_buf save_jump_buf;
23594   u32 save_line_number;
23595
23596   FILE *new_fp, *save_ifp;
23597
23598   if (unformat (vam->input, "%s", &s))
23599     {
23600       new_fp = fopen ((char *) s, "r");
23601       if (new_fp == 0)
23602         {
23603           errmsg ("Couldn't open script file %s", s);
23604           vec_free (s);
23605           return -99;
23606         }
23607     }
23608   else
23609     {
23610       errmsg ("Missing script name");
23611       return -99;
23612     }
23613
23614   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23615   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23616   save_ifp = vam->ifp;
23617   save_line_number = vam->input_line_number;
23618   save_current_file = (char *) vam->current_file;
23619
23620   vam->input_line_number = 0;
23621   vam->ifp = new_fp;
23622   vam->current_file = s;
23623   do_one_file (vam);
23624
23625   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23626   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23627   vam->ifp = save_ifp;
23628   vam->input_line_number = save_line_number;
23629   vam->current_file = (u8 *) save_current_file;
23630   vec_free (s);
23631
23632   return 0;
23633 #else
23634   clib_warning ("use the exec command...");
23635   return -99;
23636 #endif
23637 }
23638
23639 static int
23640 echo (vat_main_t * vam)
23641 {
23642   print (vam->ofp, "%v", vam->input->buffer);
23643   return 0;
23644 }
23645
23646 /* List of API message constructors, CLI names map to api_xxx */
23647 #define foreach_vpe_api_msg                                             \
23648 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23649 _(sw_interface_dump,"")                                                 \
23650 _(sw_interface_set_flags,                                               \
23651   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23652 _(sw_interface_add_del_address,                                         \
23653   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23654 _(sw_interface_set_rx_mode,                                             \
23655   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23656 _(sw_interface_set_rx_placement,                                        \
23657   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23658 _(sw_interface_rx_placement_dump,                                       \
23659   "[<intfc> | sw_if_index <id>]")                                         \
23660 _(sw_interface_set_table,                                               \
23661   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23662 _(sw_interface_set_mpls_enable,                                         \
23663   "<intfc> | sw_if_index [disable | dis]")                              \
23664 _(sw_interface_set_vpath,                                               \
23665   "<intfc> | sw_if_index <id> enable | disable")                        \
23666 _(sw_interface_set_vxlan_bypass,                                        \
23667   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23668 _(sw_interface_set_geneve_bypass,                                       \
23669   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23670 _(sw_interface_set_l2_xconnect,                                         \
23671   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23672   "enable | disable")                                                   \
23673 _(sw_interface_set_l2_bridge,                                           \
23674   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23675   "[shg <split-horizon-group>] [bvi]\n"                                 \
23676   "enable | disable")                                                   \
23677 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23678 _(bridge_domain_add_del,                                                \
23679   "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") \
23680 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23681 _(l2fib_add_del,                                                        \
23682   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23683 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23684 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23685 _(l2_flags,                                                             \
23686   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23687 _(bridge_flags,                                                         \
23688   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23689 _(tap_connect,                                                          \
23690   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23691 _(tap_modify,                                                           \
23692   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23693 _(tap_delete,                                                           \
23694   "<vpp-if-name> | sw_if_index <id>")                                   \
23695 _(sw_interface_tap_dump, "")                                            \
23696 _(tap_create_v2,                                                        \
23697   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23698 _(tap_delete_v2,                                                        \
23699   "<vpp-if-name> | sw_if_index <id>")                                   \
23700 _(sw_interface_tap_v2_dump, "")                                         \
23701 _(bond_create,                                                          \
23702   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23703   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23704 _(bond_delete,                                                          \
23705   "<vpp-if-name> | sw_if_index <id>")                                   \
23706 _(bond_enslave,                                                         \
23707   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23708 _(bond_detach_slave,                                                    \
23709   "sw_if_index <n>")                                                    \
23710 _(sw_interface_bond_dump, "")                                           \
23711 _(sw_interface_slave_dump,                                              \
23712   "<vpp-if-name> | sw_if_index <id>")                                   \
23713 _(ip_table_add_del,                                                     \
23714   "table <n> [ipv6] [add | del]\n")                                     \
23715 _(ip_add_del_route,                                                     \
23716   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23717   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23718   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23719   "[multipath] [count <n>] [del]")                                      \
23720 _(ip_mroute_add_del,                                                    \
23721   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23722   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23723 _(mpls_table_add_del,                                                   \
23724   "table <n> [add | del]\n")                                            \
23725 _(mpls_route_add_del,                                                   \
23726   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23727   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23728   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23729   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23730   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23731   "[count <n>] [del]")                                                  \
23732 _(mpls_ip_bind_unbind,                                                  \
23733   "<label> <addr/len>")                                                 \
23734 _(mpls_tunnel_add_del,                                                  \
23735   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23736   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23737   "[l2-only]  [out-label <n>]")                                         \
23738 _(sr_mpls_policy_add,                                                   \
23739   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23740 _(sr_mpls_policy_del,                                                   \
23741   "bsid <id>")                                                          \
23742 _(bier_table_add_del,                                                   \
23743   "<label> <sub-domain> <set> <bsl> [del]")                             \
23744 _(bier_route_add_del,                                                   \
23745   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23746   "[<intfc> | sw_if_index <id>]"                                        \
23747   "[weight <n>] [del] [multipath]")                                     \
23748 _(proxy_arp_add_del,                                                    \
23749   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23750 _(proxy_arp_intfc_enable_disable,                                       \
23751   "<intfc> | sw_if_index <id> enable | disable")                        \
23752 _(sw_interface_set_unnumbered,                                          \
23753   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23754 _(ip_neighbor_add_del,                                                  \
23755   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23756   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23757 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23758 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23759   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23760   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23761   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23762 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23763 _(reset_fib, "vrf <n> [ipv6]")                                          \
23764 _(dhcp_proxy_config,                                                    \
23765   "svr <v46-address> src <v46-address>\n"                               \
23766    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23767 _(dhcp_proxy_set_vss,                                                   \
23768   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23769 _(dhcp_proxy_dump, "ip6")                                               \
23770 _(dhcp_client_config,                                                   \
23771   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23772 _(set_ip_flow_hash,                                                     \
23773   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23774 _(sw_interface_ip6_enable_disable,                                      \
23775   "<intfc> | sw_if_index <id> enable | disable")                        \
23776 _(sw_interface_ip6_set_link_local_address,                              \
23777   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23778 _(ip6nd_proxy_add_del,                                                  \
23779   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23780 _(ip6nd_proxy_dump, "")                                                 \
23781 _(sw_interface_ip6nd_ra_prefix,                                         \
23782   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23783   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23784   "[nolink] [isno]")                                                    \
23785 _(sw_interface_ip6nd_ra_config,                                         \
23786   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23787   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23788   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23789 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23790 _(l2_patch_add_del,                                                     \
23791   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23792   "enable | disable")                                                   \
23793 _(sr_localsid_add_del,                                                  \
23794   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23795   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23796 _(classify_add_del_table,                                               \
23797   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23798   " [del] [del-chain] mask <mask-value>\n"                              \
23799   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23800   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23801 _(classify_add_del_session,                                             \
23802   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23803   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23804   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23805   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23806 _(classify_set_interface_ip_table,                                      \
23807   "<intfc> | sw_if_index <nn> table <nn>")                              \
23808 _(classify_set_interface_l2_tables,                                     \
23809   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23810   "  [other-table <nn>]")                                               \
23811 _(get_node_index, "node <node-name")                                    \
23812 _(add_node_next, "node <node-name> next <next-node-name>")              \
23813 _(l2tpv3_create_tunnel,                                                 \
23814   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23815   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23816   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23817 _(l2tpv3_set_tunnel_cookies,                                            \
23818   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23819   "[new_remote_cookie <nn>]\n")                                         \
23820 _(l2tpv3_interface_enable_disable,                                      \
23821   "<intfc> | sw_if_index <nn> enable | disable")                        \
23822 _(l2tpv3_set_lookup_key,                                                \
23823   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23824 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23825 _(vxlan_offload_rx,                                                     \
23826   "hw { <interface name> | hw_if_index <nn>} "                          \
23827   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23828 _(vxlan_add_del_tunnel,                                                 \
23829   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23830   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23831   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23832 _(geneve_add_del_tunnel,                                                \
23833   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23834   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23835   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23836 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23837 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23838 _(gre_add_del_tunnel,                                                   \
23839   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23840   "[teb | erspan <session-id>] [del]")                                  \
23841 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23842 _(l2_fib_clear_table, "")                                               \
23843 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23844 _(l2_interface_vlan_tag_rewrite,                                        \
23845   "<intfc> | sw_if_index <nn> \n"                                       \
23846   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23847   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23848 _(create_vhost_user_if,                                                 \
23849         "socket <filename> [server] [renumber <dev_instance>] "         \
23850         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23851         "[mac <mac_address>]")                                          \
23852 _(modify_vhost_user_if,                                                 \
23853         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23854         "[server] [renumber <dev_instance>]")                           \
23855 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23856 _(sw_interface_vhost_user_dump, "")                                     \
23857 _(show_version, "")                                                     \
23858 _(show_threads, "")                                                     \
23859 _(vxlan_gpe_add_del_tunnel,                                             \
23860   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23861   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23862   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23863   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23864 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23865 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23866 _(interface_name_renumber,                                              \
23867   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23868 _(input_acl_set_interface,                                              \
23869   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23870   "  [l2-table <nn>] [del]")                                            \
23871 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23872 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23873   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23874 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23875 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23876 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23877 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23878 _(ip_dump, "ipv4 | ipv6")                                               \
23879 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23880 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23881   "  spid_id <n> ")                                                     \
23882 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23883   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23884   "  integ_alg <alg> integ_key <hex>")                                  \
23885 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23886   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23887   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23888   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23889 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23890 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23891   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23892   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23893   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23894   "  [instance <n>]")     \
23895 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23896 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23897   "  <alg> <hex>\n")                                                    \
23898 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23899 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23900 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23901   "(auth_data 0x<data> | auth_data <data>)")                            \
23902 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23903   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23904 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23905   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23906   "(local|remote)")                                                     \
23907 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23908 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23909 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23910 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23911 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23912 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23913 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23914 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23915 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23916 _(delete_loopback,"sw_if_index <nn>")                                   \
23917 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23918 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23919 _(want_interface_events,  "enable|disable")                             \
23920 _(want_stats,"enable|disable")                                          \
23921 _(get_first_msg_id, "client <name>")                                    \
23922 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23923 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23924   "fib-id <nn> [ip4][ip6][default]")                                    \
23925 _(get_node_graph, " ")                                                  \
23926 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23927 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23928 _(ioam_disable, "")                                                     \
23929 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23930                             " sw_if_index <sw_if_index> p <priority> "  \
23931                             "w <weight>] [del]")                        \
23932 _(one_add_del_locator, "locator-set <locator_name> "                    \
23933                         "iface <intf> | sw_if_index <sw_if_index> "     \
23934                         "p <priority> w <weight> [del]")                \
23935 _(one_add_del_local_eid,"vni <vni> eid "                                \
23936                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23937                          "locator-set <locator_name> [del]"             \
23938                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23939 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23940 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23941 _(one_enable_disable, "enable|disable")                                 \
23942 _(one_map_register_enable_disable, "enable|disable")                    \
23943 _(one_map_register_fallback_threshold, "<value>")                       \
23944 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23945 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23946                                "[seid <seid>] "                         \
23947                                "rloc <locator> p <prio> "               \
23948                                "w <weight> [rloc <loc> ... ] "          \
23949                                "action <action> [del-all]")             \
23950 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23951                           "<local-eid>")                                \
23952 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23953 _(one_use_petr, "ip-address> | disable")                                \
23954 _(one_map_request_mode, "src-dst|dst-only")                             \
23955 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23956 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23957 _(one_locator_set_dump, "[local | remote]")                             \
23958 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23959 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23960                        "[local] | [remote]")                            \
23961 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23962 _(one_ndp_bd_get, "")                                                   \
23963 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23964 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23965 _(one_l2_arp_bd_get, "")                                                \
23966 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23967 _(one_stats_enable_disable, "enable|disable")                           \
23968 _(show_one_stats_enable_disable, "")                                    \
23969 _(one_eid_table_vni_dump, "")                                           \
23970 _(one_eid_table_map_dump, "l2|l3")                                      \
23971 _(one_map_resolver_dump, "")                                            \
23972 _(one_map_server_dump, "")                                              \
23973 _(one_adjacencies_get, "vni <vni>")                                     \
23974 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23975 _(show_one_rloc_probe_state, "")                                        \
23976 _(show_one_map_register_state, "")                                      \
23977 _(show_one_status, "")                                                  \
23978 _(one_stats_dump, "")                                                   \
23979 _(one_stats_flush, "")                                                  \
23980 _(one_get_map_request_itr_rlocs, "")                                    \
23981 _(one_map_register_set_ttl, "<ttl>")                                    \
23982 _(one_set_transport_protocol, "udp|api")                                \
23983 _(one_get_transport_protocol, "")                                       \
23984 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23985 _(one_show_xtr_mode, "")                                                \
23986 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23987 _(one_show_pitr_mode, "")                                               \
23988 _(one_enable_disable_petr_mode, "enable|disable")                       \
23989 _(one_show_petr_mode, "")                                               \
23990 _(show_one_nsh_mapping, "")                                             \
23991 _(show_one_pitr, "")                                                    \
23992 _(show_one_use_petr, "")                                                \
23993 _(show_one_map_request_mode, "")                                        \
23994 _(show_one_map_register_ttl, "")                                        \
23995 _(show_one_map_register_fallback_threshold, "")                         \
23996 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23997                             " sw_if_index <sw_if_index> p <priority> "  \
23998                             "w <weight>] [del]")                        \
23999 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
24000                         "iface <intf> | sw_if_index <sw_if_index> "     \
24001                         "p <priority> w <weight> [del]")                \
24002 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
24003                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
24004                          "locator-set <locator_name> [del]"             \
24005                          "[key-id sha1|sha256 secret-key <secret-key>]") \
24006 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
24007 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
24008 _(lisp_enable_disable, "enable|disable")                                \
24009 _(lisp_map_register_enable_disable, "enable|disable")                   \
24010 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
24011 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
24012                                "[seid <seid>] "                         \
24013                                "rloc <locator> p <prio> "               \
24014                                "w <weight> [rloc <loc> ... ] "          \
24015                                "action <action> [del-all]")             \
24016 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
24017                           "<local-eid>")                                \
24018 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
24019 _(lisp_use_petr, "<ip-address> | disable")                              \
24020 _(lisp_map_request_mode, "src-dst|dst-only")                            \
24021 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
24022 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
24023 _(lisp_locator_set_dump, "[local | remote]")                            \
24024 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
24025 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
24026                        "[local] | [remote]")                            \
24027 _(lisp_eid_table_vni_dump, "")                                          \
24028 _(lisp_eid_table_map_dump, "l2|l3")                                     \
24029 _(lisp_map_resolver_dump, "")                                           \
24030 _(lisp_map_server_dump, "")                                             \
24031 _(lisp_adjacencies_get, "vni <vni>")                                    \
24032 _(gpe_fwd_entry_vnis_get, "")                                           \
24033 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
24034 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
24035                                 "[table <table-id>]")                   \
24036 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
24037 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
24038 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
24039 _(gpe_get_encap_mode, "")                                               \
24040 _(lisp_gpe_add_del_iface, "up|down")                                    \
24041 _(lisp_gpe_enable_disable, "enable|disable")                            \
24042 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
24043   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
24044 _(show_lisp_rloc_probe_state, "")                                       \
24045 _(show_lisp_map_register_state, "")                                     \
24046 _(show_lisp_status, "")                                                 \
24047 _(lisp_get_map_request_itr_rlocs, "")                                   \
24048 _(show_lisp_pitr, "")                                                   \
24049 _(show_lisp_use_petr, "")                                               \
24050 _(show_lisp_map_request_mode, "")                                       \
24051 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
24052 _(af_packet_delete, "name <host interface name>")                       \
24053 _(af_packet_dump, "")                                                   \
24054 _(policer_add_del, "name <policer name> <params> [del]")                \
24055 _(policer_dump, "[name <policer name>]")                                \
24056 _(policer_classify_set_interface,                                       \
24057   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24058   "  [l2-table <nn>] [del]")                                            \
24059 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
24060 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
24061     "[master|slave]")                                                   \
24062 _(netmap_delete, "name <interface name>")                               \
24063 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
24064 _(mpls_fib_dump, "")                                                    \
24065 _(classify_table_ids, "")                                               \
24066 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24067 _(classify_table_info, "table_id <nn>")                                 \
24068 _(classify_session_dump, "table_id <nn>")                               \
24069 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24070     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24071     "[template_interval <nn>] [udp_checksum]")                          \
24072 _(ipfix_exporter_dump, "")                                              \
24073 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24074 _(ipfix_classify_stream_dump, "")                                       \
24075 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24076 _(ipfix_classify_table_dump, "")                                        \
24077 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24078 _(sw_interface_span_dump, "[l2]")                                           \
24079 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24080 _(pg_create_interface, "if_id <nn>")                                    \
24081 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24082 _(pg_enable_disable, "[stream <id>] disable")                           \
24083 _(ip_source_and_port_range_check_add_del,                               \
24084   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24085 _(ip_source_and_port_range_check_interface_add_del,                     \
24086   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24087   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24088 _(ipsec_gre_add_del_tunnel,                                             \
24089   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24090 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24091 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24092 _(l2_interface_pbb_tag_rewrite,                                         \
24093   "<intfc> | sw_if_index <nn> \n"                                       \
24094   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24095   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24096 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24097 _(flow_classify_set_interface,                                          \
24098   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24099 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24100 _(ip_fib_dump, "")                                                      \
24101 _(ip_mfib_dump, "")                                                     \
24102 _(ip6_fib_dump, "")                                                     \
24103 _(ip6_mfib_dump, "")                                                    \
24104 _(feature_enable_disable, "arc_name <arc_name> "                        \
24105   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24106 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24107 "[disable]")                                                            \
24108 _(l2_xconnect_dump, "")                                                 \
24109 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24110 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24111 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24112 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24113 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24114 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24115 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24116   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24117 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24118 _(sock_init_shm, "size <nnn>")                                          \
24119 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24120 _(dns_enable_disable, "[enable][disable]")                              \
24121 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24122 _(dns_resolve_name, "<hostname>")                                       \
24123 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24124 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24125 _(dns_resolve_name, "<hostname>")                                       \
24126 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24127   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24128 _(session_rules_dump, "")                                               \
24129 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24130 _(output_acl_set_interface,                                             \
24131   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24132   "  [l2-table <nn>] [del]")                                            \
24133 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24134
24135 /* List of command functions, CLI names map directly to functions */
24136 #define foreach_cli_function                                    \
24137 _(comment, "usage: comment <ignore-rest-of-line>")              \
24138 _(dump_interface_table, "usage: dump_interface_table")          \
24139 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24140 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24141 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24142 _(dump_stats_table, "usage: dump_stats_table")                  \
24143 _(dump_macro_table, "usage: dump_macro_table ")                 \
24144 _(dump_node_table, "usage: dump_node_table")                    \
24145 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24146 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24147 _(echo, "usage: echo <message>")                                \
24148 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24149 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24150 _(help, "usage: help")                                          \
24151 _(q, "usage: quit")                                             \
24152 _(quit, "usage: quit")                                          \
24153 _(search_node_table, "usage: search_node_table <name>...")      \
24154 _(set, "usage: set <variable-name> <value>")                    \
24155 _(script, "usage: script <file-name>")                          \
24156 _(statseg, "usage: statseg");                                   \
24157 _(unset, "usage: unset <variable-name>")
24158
24159 #define _(N,n)                                  \
24160     static void vl_api_##n##_t_handler_uni      \
24161     (vl_api_##n##_t * mp)                       \
24162     {                                           \
24163         vat_main_t * vam = &vat_main;           \
24164         if (vam->json_output) {                 \
24165             vl_api_##n##_t_handler_json(mp);    \
24166         } else {                                \
24167             vl_api_##n##_t_handler(mp);         \
24168         }                                       \
24169     }
24170 foreach_vpe_api_reply_msg;
24171 #if VPP_API_TEST_BUILTIN == 0
24172 foreach_standalone_reply_msg;
24173 #endif
24174 #undef _
24175
24176 void
24177 vat_api_hookup (vat_main_t * vam)
24178 {
24179 #define _(N,n)                                                  \
24180     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24181                            vl_api_##n##_t_handler_uni,          \
24182                            vl_noop_handler,                     \
24183                            vl_api_##n##_t_endian,               \
24184                            vl_api_##n##_t_print,                \
24185                            sizeof(vl_api_##n##_t), 1);
24186   foreach_vpe_api_reply_msg;
24187 #if VPP_API_TEST_BUILTIN == 0
24188   foreach_standalone_reply_msg;
24189 #endif
24190 #undef _
24191
24192 #if (VPP_API_TEST_BUILTIN==0)
24193   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24194
24195   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24196
24197   vam->function_by_name = hash_create_string (0, sizeof (uword));
24198
24199   vam->help_by_name = hash_create_string (0, sizeof (uword));
24200 #endif
24201
24202   /* API messages we can send */
24203 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24204   foreach_vpe_api_msg;
24205 #undef _
24206
24207   /* Help strings */
24208 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24209   foreach_vpe_api_msg;
24210 #undef _
24211
24212   /* CLI functions */
24213 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24214   foreach_cli_function;
24215 #undef _
24216
24217   /* Help strings */
24218 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24219   foreach_cli_function;
24220 #undef _
24221 }
24222
24223 #if VPP_API_TEST_BUILTIN
24224 static clib_error_t *
24225 vat_api_hookup_shim (vlib_main_t * vm)
24226 {
24227   vat_api_hookup (&vat_main);
24228   return 0;
24229 }
24230
24231 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24232 #endif
24233
24234 /*
24235  * fd.io coding-style-patch-verification: ON
24236  *
24237  * Local Variables:
24238  * eval: (c-set-style "gnu")
24239  * End:
24240  */