stats: Deprecate old stats framework
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/l2/l2_input.h>
28 #include <vnet/l2tp/l2tp.h>
29 #include <vnet/vxlan/vxlan.h>
30 #include <vnet/geneve/geneve.h>
31 #include <vnet/gre/gre.h>
32 #include <vnet/vxlan-gpe/vxlan_gpe.h>
33 #include <vnet/lisp-gpe/lisp_gpe.h>
34
35 #include <vpp/api/vpe_msg_enum.h>
36 #include <vnet/l2/l2_classify.h>
37 #include <vnet/l2/l2_vtr.h>
38 #include <vnet/classify/in_out_acl.h>
39 #include <vnet/classify/policer_classify.h>
40 #include <vnet/classify/flow_classify.h>
41 #include <vnet/mpls/mpls.h>
42 #include <vnet/ipsec/ipsec.h>
43 #include <vnet/ipsec/ikev2.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #define vl_print(handle, ...)
75 #define vl_printfun
76 #include <vpp/api/vpe_all_api_h.h>
77 #undef vl_printfun
78
79 #define __plugin_msg_base 0
80 #include <vlibapi/vat_helper_macros.h>
81
82 #if VPP_API_TEST_BUILTIN == 0
83 #include <netdb.h>
84
85 /* *INDENT-OFF* */
86 const mac_address_t ZERO_MAC_ADDRESS = {
87   .bytes = {
88     0, 0, 0, 0, 0, 0,
89   },
90 };
91 /* *INDENT-ON* */
92
93 u32
94 vl (void *p)
95 {
96   return vec_len (p);
97 }
98
99 int
100 vat_socket_connect (vat_main_t * vam)
101 {
102   vam->socket_client_main = &socket_client_main;
103   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
104                                    0 /* default socket rx, tx buffer */ );
105 }
106 #else /* vpp built-in case, we don't do sockets... */
107 int
108 vat_socket_connect (vat_main_t * vam)
109 {
110   return 0;
111 }
112
113 int
114 vl_socket_client_read (int wait)
115 {
116   return -1;
117 };
118
119 int
120 vl_socket_client_write ()
121 {
122   return -1;
123 };
124
125 void *
126 vl_socket_client_msg_alloc (int nbytes)
127 {
128   return 0;
129 }
130 #endif
131
132
133 f64
134 vat_time_now (vat_main_t * vam)
135 {
136 #if VPP_API_TEST_BUILTIN
137   return vlib_time_now (vam->vlib_main);
138 #else
139   return clib_time_now (&vam->clib_time);
140 #endif
141 }
142
143 void
144 errmsg (char *fmt, ...)
145 {
146   vat_main_t *vam = &vat_main;
147   va_list va;
148   u8 *s;
149
150   va_start (va, fmt);
151   s = va_format (0, fmt, &va);
152   va_end (va);
153
154   vec_add1 (s, 0);
155
156 #if VPP_API_TEST_BUILTIN
157   vlib_cli_output (vam->vlib_main, (char *) s);
158 #else
159   {
160     if (vam->ifp != stdin)
161       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
162                vam->input_line_number);
163     fformat (vam->ofp, (char *) s);
164     fflush (vam->ofp);
165   }
166 #endif
167
168   vec_free (s);
169 }
170
171 #if VPP_API_TEST_BUILTIN == 0
172 static uword
173 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
174 {
175   vat_main_t *vam = va_arg (*args, vat_main_t *);
176   u32 *result = va_arg (*args, u32 *);
177   u8 *if_name;
178   uword *p;
179
180   if (!unformat (input, "%s", &if_name))
181     return 0;
182
183   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
184   if (p == 0)
185     return 0;
186   *result = p[0];
187   return 1;
188 }
189
190 static uword
191 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
192 {
193   return 0;
194 }
195
196 /* Parse an IP4 address %d.%d.%d.%d. */
197 uword
198 unformat_ip4_address (unformat_input_t * input, va_list * args)
199 {
200   u8 *result = va_arg (*args, u8 *);
201   unsigned a[4];
202
203   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
204     return 0;
205
206   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
207     return 0;
208
209   result[0] = a[0];
210   result[1] = a[1];
211   result[2] = a[2];
212   result[3] = a[3];
213
214   return 1;
215 }
216
217 uword
218 unformat_ethernet_address (unformat_input_t * input, va_list * args)
219 {
220   u8 *result = va_arg (*args, u8 *);
221   u32 i, a[6];
222
223   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
224                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
225     return 0;
226
227   /* Check range. */
228   for (i = 0; i < 6; i++)
229     if (a[i] >= (1 << 8))
230       return 0;
231
232   for (i = 0; i < 6; i++)
233     result[i] = a[i];
234
235   return 1;
236 }
237
238 /* Returns ethernet type as an int in host byte order. */
239 uword
240 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
241                                         va_list * args)
242 {
243   u16 *result = va_arg (*args, u16 *);
244   int type;
245
246   /* Numeric type. */
247   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
248     {
249       if (type >= (1 << 16))
250         return 0;
251       *result = type;
252       return 1;
253     }
254   return 0;
255 }
256
257 /* Parse an IP6 address. */
258 uword
259 unformat_ip6_address (unformat_input_t * input, va_list * args)
260 {
261   ip6_address_t *result = va_arg (*args, ip6_address_t *);
262   u16 hex_quads[8];
263   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
264   uword c, n_colon, double_colon_index;
265
266   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
267   double_colon_index = ARRAY_LEN (hex_quads);
268   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
269     {
270       hex_digit = 16;
271       if (c >= '0' && c <= '9')
272         hex_digit = c - '0';
273       else if (c >= 'a' && c <= 'f')
274         hex_digit = c + 10 - 'a';
275       else if (c >= 'A' && c <= 'F')
276         hex_digit = c + 10 - 'A';
277       else if (c == ':' && n_colon < 2)
278         n_colon++;
279       else
280         {
281           unformat_put_input (input);
282           break;
283         }
284
285       /* Too many hex quads. */
286       if (n_hex_quads >= ARRAY_LEN (hex_quads))
287         return 0;
288
289       if (hex_digit < 16)
290         {
291           hex_quad = (hex_quad << 4) | hex_digit;
292
293           /* Hex quad must fit in 16 bits. */
294           if (n_hex_digits >= 4)
295             return 0;
296
297           n_colon = 0;
298           n_hex_digits++;
299         }
300
301       /* Save position of :: */
302       if (n_colon == 2)
303         {
304           /* More than one :: ? */
305           if (double_colon_index < ARRAY_LEN (hex_quads))
306             return 0;
307           double_colon_index = n_hex_quads;
308         }
309
310       if (n_colon > 0 && n_hex_digits > 0)
311         {
312           hex_quads[n_hex_quads++] = hex_quad;
313           hex_quad = 0;
314           n_hex_digits = 0;
315         }
316     }
317
318   if (n_hex_digits > 0)
319     hex_quads[n_hex_quads++] = hex_quad;
320
321   {
322     word i;
323
324     /* Expand :: to appropriate number of zero hex quads. */
325     if (double_colon_index < ARRAY_LEN (hex_quads))
326       {
327         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
328
329         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
330           hex_quads[n_zero + i] = hex_quads[i];
331
332         for (i = 0; i < n_zero; i++)
333           hex_quads[double_colon_index + i] = 0;
334
335         n_hex_quads = ARRAY_LEN (hex_quads);
336       }
337
338     /* Too few hex quads given. */
339     if (n_hex_quads < ARRAY_LEN (hex_quads))
340       return 0;
341
342     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
343       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
344
345     return 1;
346   }
347 }
348
349 uword
350 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
351 {
352   u32 *r = va_arg (*args, u32 *);
353
354   if (0);
355 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
356   foreach_ipsec_policy_action
357 #undef _
358     else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
370   foreach_ipsec_crypto_alg
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 u8 *
378 format_ipsec_crypto_alg (u8 * s, va_list * args)
379 {
380   u32 i = va_arg (*args, u32);
381   u8 *t = 0;
382
383   switch (i)
384     {
385 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
386       foreach_ipsec_crypto_alg
387 #undef _
388     default:
389       return format (s, "unknown");
390     }
391   return format (s, "%s", t);
392 }
393
394 uword
395 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
396 {
397   u32 *r = va_arg (*args, u32 *);
398
399   if (0);
400 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
401   foreach_ipsec_integ_alg
402 #undef _
403     else
404     return 0;
405   return 1;
406 }
407
408 u8 *
409 format_ipsec_integ_alg (u8 * s, va_list * args)
410 {
411   u32 i = va_arg (*args, u32);
412   u8 *t = 0;
413
414   switch (i)
415     {
416 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
417       foreach_ipsec_integ_alg
418 #undef _
419     default:
420       return format (s, "unknown");
421     }
422   return format (s, "%s", t);
423 }
424
425 uword
426 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
427 {
428   u32 *r = va_arg (*args, u32 *);
429
430   if (0);
431 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
432   foreach_ikev2_auth_method
433 #undef _
434     else
435     return 0;
436   return 1;
437 }
438
439 uword
440 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
441 {
442   u32 *r = va_arg (*args, u32 *);
443
444   if (0);
445 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
446   foreach_ikev2_id_type
447 #undef _
448     else
449     return 0;
450   return 1;
451 }
452 #else /* VPP_API_TEST_BUILTIN == 1 */
453 static uword
454 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
455 {
456   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
457   vnet_main_t *vnm = vnet_get_main ();
458   u32 *result = va_arg (*args, u32 *);
459
460   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
461 }
462
463 static uword
464 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
465 {
466   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
467   vnet_main_t *vnm = vnet_get_main ();
468   u32 *result = va_arg (*args, u32 *);
469
470   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
471 }
472
473 #endif /* VPP_API_TEST_BUILTIN */
474
475 static uword
476 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
477 {
478   u8 *r = va_arg (*args, u8 *);
479
480   if (unformat (input, "kbps"))
481     *r = SSE2_QOS_RATE_KBPS;
482   else if (unformat (input, "pps"))
483     *r = SSE2_QOS_RATE_PPS;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_policer_round_type (unformat_input_t * input, va_list * args)
491 {
492   u8 *r = va_arg (*args, u8 *);
493
494   if (unformat (input, "closest"))
495     *r = SSE2_QOS_ROUND_TO_CLOSEST;
496   else if (unformat (input, "up"))
497     *r = SSE2_QOS_ROUND_TO_UP;
498   else if (unformat (input, "down"))
499     *r = SSE2_QOS_ROUND_TO_DOWN;
500   else
501     return 0;
502   return 1;
503 }
504
505 static uword
506 unformat_policer_type (unformat_input_t * input, va_list * args)
507 {
508   u8 *r = va_arg (*args, u8 *);
509
510   if (unformat (input, "1r2c"))
511     *r = SSE2_QOS_POLICER_TYPE_1R2C;
512   else if (unformat (input, "1r3c"))
513     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
514   else if (unformat (input, "2r3c-2698"))
515     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
516   else if (unformat (input, "2r3c-4115"))
517     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
518   else if (unformat (input, "2r3c-mef5cf1"))
519     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
520   else
521     return 0;
522   return 1;
523 }
524
525 static uword
526 unformat_dscp (unformat_input_t * input, va_list * va)
527 {
528   u8 *r = va_arg (*va, u8 *);
529
530   if (0);
531 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
532   foreach_vnet_dscp
533 #undef _
534     else
535     return 0;
536   return 1;
537 }
538
539 static uword
540 unformat_policer_action_type (unformat_input_t * input, va_list * va)
541 {
542   sse2_qos_pol_action_params_st *a
543     = va_arg (*va, sse2_qos_pol_action_params_st *);
544
545   if (unformat (input, "drop"))
546     a->action_type = SSE2_QOS_ACTION_DROP;
547   else if (unformat (input, "transmit"))
548     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
549   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
550     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
551   else
552     return 0;
553   return 1;
554 }
555
556 static uword
557 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
558 {
559   u32 *r = va_arg (*va, u32 *);
560   u32 tid;
561
562   if (unformat (input, "ip4"))
563     tid = POLICER_CLASSIFY_TABLE_IP4;
564   else if (unformat (input, "ip6"))
565     tid = POLICER_CLASSIFY_TABLE_IP6;
566   else if (unformat (input, "l2"))
567     tid = POLICER_CLASSIFY_TABLE_L2;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 static uword
576 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
577 {
578   u32 *r = va_arg (*va, u32 *);
579   u32 tid;
580
581   if (unformat (input, "ip4"))
582     tid = FLOW_CLASSIFY_TABLE_IP4;
583   else if (unformat (input, "ip6"))
584     tid = FLOW_CLASSIFY_TABLE_IP6;
585   else
586     return 0;
587
588   *r = tid;
589   return 1;
590 }
591
592 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
593 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
594 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
595 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
596
597 #if (VPP_API_TEST_BUILTIN==0)
598 uword
599 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
600 {
601   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
602   mfib_itf_attribute_t attr;
603
604   old = *iflags;
605   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
606   {
607     if (unformat (input, mfib_itf_flag_long_names[attr]))
608       *iflags |= (1 << attr);
609   }
610   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_itf_flag_names[attr]))
613       *iflags |= (1 << attr);
614   }
615
616   return (old == *iflags ? 0 : 1);
617 }
618
619 uword
620 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
621 {
622   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
623   mfib_entry_attribute_t attr;
624
625   old = *eflags;
626   FOR_EACH_MFIB_ATTRIBUTE (attr)
627   {
628     if (unformat (input, mfib_flag_long_names[attr]))
629       *eflags |= (1 << attr);
630   }
631   FOR_EACH_MFIB_ATTRIBUTE (attr)
632   {
633     if (unformat (input, mfib_flag_names[attr]))
634       *eflags |= (1 << attr);
635   }
636
637   return (old == *eflags ? 0 : 1);
638 }
639
640 u8 *
641 format_ip4_address (u8 * s, va_list * args)
642 {
643   u8 *a = va_arg (*args, u8 *);
644   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
645 }
646
647 u8 *
648 format_ip6_address (u8 * s, va_list * args)
649 {
650   ip6_address_t *a = va_arg (*args, ip6_address_t *);
651   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
652
653   i_max_n_zero = ARRAY_LEN (a->as_u16);
654   max_n_zeros = 0;
655   i_first_zero = i_max_n_zero;
656   n_zeros = 0;
657   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
658     {
659       u32 is_zero = a->as_u16[i] == 0;
660       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
661         {
662           i_first_zero = i;
663           n_zeros = 0;
664         }
665       n_zeros += is_zero;
666       if ((!is_zero && n_zeros > max_n_zeros)
667           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
668         {
669           i_max_n_zero = i_first_zero;
670           max_n_zeros = n_zeros;
671           i_first_zero = ARRAY_LEN (a->as_u16);
672           n_zeros = 0;
673         }
674     }
675
676   last_double_colon = 0;
677   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
678     {
679       if (i == i_max_n_zero && max_n_zeros > 1)
680         {
681           s = format (s, "::");
682           i += max_n_zeros - 1;
683           last_double_colon = 1;
684         }
685       else
686         {
687           s = format (s, "%s%x",
688                       (last_double_colon || i == 0) ? "" : ":",
689                       clib_net_to_host_u16 (a->as_u16[i]));
690           last_double_colon = 0;
691         }
692     }
693
694   return s;
695 }
696
697 /* Format an IP46 address. */
698 u8 *
699 format_ip46_address (u8 * s, va_list * args)
700 {
701   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
702   ip46_type_t type = va_arg (*args, ip46_type_t);
703   int is_ip4 = 1;
704
705   switch (type)
706     {
707     case IP46_TYPE_ANY:
708       is_ip4 = ip46_address_is_ip4 (ip46);
709       break;
710     case IP46_TYPE_IP4:
711       is_ip4 = 1;
712       break;
713     case IP46_TYPE_IP6:
714       is_ip4 = 0;
715       break;
716     }
717
718   return is_ip4 ?
719     format (s, "%U", format_ip4_address, &ip46->ip4) :
720     format (s, "%U", format_ip6_address, &ip46->ip6);
721 }
722
723 u8 *
724 format_ethernet_address (u8 * s, va_list * args)
725 {
726   u8 *a = va_arg (*args, u8 *);
727
728   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
729                  a[0], a[1], a[2], a[3], a[4], a[5]);
730 }
731 #endif
732
733 static void
734 increment_v4_address (ip4_address_t * a)
735 {
736   u32 v;
737
738   v = ntohl (a->as_u32) + 1;
739   a->as_u32 = ntohl (v);
740 }
741
742 static void
743 increment_v6_address (ip6_address_t * a)
744 {
745   u64 v0, v1;
746
747   v0 = clib_net_to_host_u64 (a->as_u64[0]);
748   v1 = clib_net_to_host_u64 (a->as_u64[1]);
749
750   v1 += 1;
751   if (v1 == 0)
752     v0 += 1;
753   a->as_u64[0] = clib_net_to_host_u64 (v0);
754   a->as_u64[1] = clib_net_to_host_u64 (v1);
755 }
756
757 static void
758 increment_mac_address (u8 * mac)
759 {
760   u64 tmp = *((u64 *) mac);
761   tmp = clib_net_to_host_u64 (tmp);
762   tmp += 1 << 16;               /* skip unused (least significant) octets */
763   tmp = clib_host_to_net_u64 (tmp);
764
765   clib_memcpy (mac, &tmp, 6);
766 }
767
768 static void vl_api_create_loopback_reply_t_handler
769   (vl_api_create_loopback_reply_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   i32 retval = ntohl (mp->retval);
773
774   vam->retval = retval;
775   vam->regenerate_interface_table = 1;
776   vam->sw_if_index = ntohl (mp->sw_if_index);
777   vam->result_ready = 1;
778 }
779
780 static void vl_api_create_loopback_reply_t_handler_json
781   (vl_api_create_loopback_reply_t * mp)
782 {
783   vat_main_t *vam = &vat_main;
784   vat_json_node_t node;
785
786   vat_json_init_object (&node);
787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
788   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
789
790   vat_json_print (vam->ofp, &node);
791   vat_json_free (&node);
792   vam->retval = ntohl (mp->retval);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_loopback_instance_reply_t_handler
797   (vl_api_create_loopback_instance_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   i32 retval = ntohl (mp->retval);
801
802   vam->retval = retval;
803   vam->regenerate_interface_table = 1;
804   vam->sw_if_index = ntohl (mp->sw_if_index);
805   vam->result_ready = 1;
806 }
807
808 static void vl_api_create_loopback_instance_reply_t_handler_json
809   (vl_api_create_loopback_instance_reply_t * mp)
810 {
811   vat_main_t *vam = &vat_main;
812   vat_json_node_t node;
813
814   vat_json_init_object (&node);
815   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
816   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
817
818   vat_json_print (vam->ofp, &node);
819   vat_json_free (&node);
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_af_packet_create_reply_t_handler
825   (vl_api_af_packet_create_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_af_packet_create_reply_t_handler_json
837   (vl_api_af_packet_create_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848
849   vam->retval = ntohl (mp->retval);
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_create_vlan_subif_reply_t_handler
854   (vl_api_create_vlan_subif_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   i32 retval = ntohl (mp->retval);
858
859   vam->retval = retval;
860   vam->regenerate_interface_table = 1;
861   vam->sw_if_index = ntohl (mp->sw_if_index);
862   vam->result_ready = 1;
863 }
864
865 static void vl_api_create_vlan_subif_reply_t_handler_json
866   (vl_api_create_vlan_subif_reply_t * mp)
867 {
868   vat_main_t *vam = &vat_main;
869   vat_json_node_t node;
870
871   vat_json_init_object (&node);
872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875   vat_json_print (vam->ofp, &node);
876   vat_json_free (&node);
877
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_create_subif_reply_t_handler
883   (vl_api_create_subif_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->sw_if_index = ntohl (mp->sw_if_index);
891   vam->result_ready = 1;
892 }
893
894 static void vl_api_create_subif_reply_t_handler_json
895   (vl_api_create_subif_reply_t * mp)
896 {
897   vat_main_t *vam = &vat_main;
898   vat_json_node_t node;
899
900   vat_json_init_object (&node);
901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
902   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
903
904   vat_json_print (vam->ofp, &node);
905   vat_json_free (&node);
906
907   vam->retval = ntohl (mp->retval);
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_interface_name_renumber_reply_t_handler
912   (vl_api_interface_name_renumber_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   i32 retval = ntohl (mp->retval);
916
917   vam->retval = retval;
918   vam->regenerate_interface_table = 1;
919   vam->result_ready = 1;
920 }
921
922 static void vl_api_interface_name_renumber_reply_t_handler_json
923   (vl_api_interface_name_renumber_reply_t * mp)
924 {
925   vat_main_t *vam = &vat_main;
926   vat_json_node_t node;
927
928   vat_json_init_object (&node);
929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
930
931   vat_json_print (vam->ofp, &node);
932   vat_json_free (&node);
933
934   vam->retval = ntohl (mp->retval);
935   vam->result_ready = 1;
936 }
937
938 /*
939  * Special-case: build the interface table, maintain
940  * the next loopback sw_if_index vbl.
941  */
942 static void vl_api_sw_interface_details_t_handler
943   (vl_api_sw_interface_details_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   u8 *s = format (0, "%s%c", mp->interface_name, 0);
947
948   hash_set_mem (vam->sw_if_index_by_interface_name, s,
949                 ntohl (mp->sw_if_index));
950
951   /* In sub interface case, fill the sub interface table entry */
952   if (mp->sw_if_index != mp->sup_sw_if_index)
953     {
954       sw_interface_subif_t *sub = NULL;
955
956       vec_add2 (vam->sw_if_subif_table, sub, 1);
957
958       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
959       strncpy ((char *) sub->interface_name, (char *) s,
960                vec_len (sub->interface_name));
961       sub->sw_if_index = ntohl (mp->sw_if_index);
962       sub->sub_id = ntohl (mp->sub_id);
963
964       sub->sub_dot1ad = mp->sub_dot1ad;
965       sub->sub_number_of_tags = mp->sub_number_of_tags;
966       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
967       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
968       sub->sub_exact_match = mp->sub_exact_match;
969       sub->sub_default = mp->sub_default;
970       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
971       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
972
973       /* vlan tag rewrite */
974       sub->vtr_op = ntohl (mp->vtr_op);
975       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
976       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
977       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
978     }
979 }
980
981 static void vl_api_sw_interface_details_t_handler_json
982   (vl_api_sw_interface_details_t * mp)
983 {
984   vat_main_t *vam = &vat_main;
985   vat_json_node_t *node = NULL;
986
987   if (VAT_JSON_ARRAY != vam->json_tree.type)
988     {
989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
990       vat_json_init_array (&vam->json_tree);
991     }
992   node = vat_json_array_add (&vam->json_tree);
993
994   vat_json_init_object (node);
995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
996   vat_json_object_add_uint (node, "sup_sw_if_index",
997                             ntohl (mp->sup_sw_if_index));
998   vat_json_object_add_uint (node, "l2_address_length",
999                             ntohl (mp->l2_address_length));
1000   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1001                              sizeof (mp->l2_address));
1002   vat_json_object_add_string_copy (node, "interface_name",
1003                                    mp->interface_name);
1004   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1005   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1006   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1007   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1008   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1009   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1010   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1011   vat_json_object_add_uint (node, "sub_number_of_tags",
1012                             mp->sub_number_of_tags);
1013   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1014                             ntohs (mp->sub_outer_vlan_id));
1015   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1016                             ntohs (mp->sub_inner_vlan_id));
1017   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1018   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1019   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1020                             mp->sub_outer_vlan_id_any);
1021   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1022                             mp->sub_inner_vlan_id_any);
1023   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1024   vat_json_object_add_uint (node, "vtr_push_dot1q",
1025                             ntohl (mp->vtr_push_dot1q));
1026   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1027   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1028   if (mp->sub_dot1ah)
1029     {
1030       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1031                                        format (0, "%U",
1032                                                format_ethernet_address,
1033                                                &mp->b_dmac));
1034       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1035                                        format (0, "%U",
1036                                                format_ethernet_address,
1037                                                &mp->b_smac));
1038       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1039       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1040     }
1041 }
1042
1043 #if VPP_API_TEST_BUILTIN == 0
1044 static void vl_api_sw_interface_event_t_handler
1045   (vl_api_sw_interface_event_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   if (vam->interface_event_display)
1049     errmsg ("interface flags: sw_if_index %d %s %s",
1050             ntohl (mp->sw_if_index),
1051             mp->admin_up_down ? "admin-up" : "admin-down",
1052             mp->link_up_down ? "link-up" : "link-down");
1053 }
1054 #endif
1055
1056 static void vl_api_sw_interface_event_t_handler_json
1057   (vl_api_sw_interface_event_t * mp)
1058 {
1059   /* JSON output not supported */
1060 }
1061
1062 static void
1063 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067
1068   vam->retval = retval;
1069   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1070   vam->result_ready = 1;
1071 }
1072
1073 static void
1074 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1075 {
1076   vat_main_t *vam = &vat_main;
1077   vat_json_node_t node;
1078   api_main_t *am = &api_main;
1079   void *oldheap;
1080   u8 *reply;
1081
1082   vat_json_init_object (&node);
1083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1084   vat_json_object_add_uint (&node, "reply_in_shmem",
1085                             ntohl (mp->reply_in_shmem));
1086   /* Toss the shared-memory original... */
1087   pthread_mutex_lock (&am->vlib_rp->mutex);
1088   oldheap = svm_push_data_heap (am->vlib_rp);
1089
1090   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1091   vec_free (reply);
1092
1093   svm_pop_heap (oldheap);
1094   pthread_mutex_unlock (&am->vlib_rp->mutex);
1095
1096   vat_json_print (vam->ofp, &node);
1097   vat_json_free (&node);
1098
1099   vam->retval = ntohl (mp->retval);
1100   vam->result_ready = 1;
1101 }
1102
1103 static void
1104 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1105 {
1106   vat_main_t *vam = &vat_main;
1107   i32 retval = ntohl (mp->retval);
1108   u32 length = vl_api_string_len (&mp->reply);
1109
1110   vec_reset_length (vam->cmd_reply);
1111
1112   vam->retval = retval;
1113   if (retval == 0)
1114     {
1115       vec_validate (vam->cmd_reply, length);
1116       clib_memcpy ((char *) (vam->cmd_reply),
1117                    vl_api_from_api_string (&mp->reply), length);
1118       vam->cmd_reply[length] = 0;
1119     }
1120   vam->result_ready = 1;
1121 }
1122
1123 static void
1124 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1125 {
1126   vat_main_t *vam = &vat_main;
1127   vat_json_node_t node;
1128
1129   vec_reset_length (vam->cmd_reply);
1130
1131   vat_json_init_object (&node);
1132   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1133   vat_json_object_add_string_copy (&node, "reply",
1134                                    vl_api_from_api_string (&mp->reply));
1135
1136   vat_json_print (vam->ofp, &node);
1137   vat_json_free (&node);
1138
1139   vam->retval = ntohl (mp->retval);
1140   vam->result_ready = 1;
1141 }
1142
1143 static void vl_api_classify_add_del_table_reply_t_handler
1144   (vl_api_classify_add_del_table_reply_t * mp)
1145 {
1146   vat_main_t *vam = &vat_main;
1147   i32 retval = ntohl (mp->retval);
1148   if (vam->async_mode)
1149     {
1150       vam->async_errors += (retval < 0);
1151     }
1152   else
1153     {
1154       vam->retval = retval;
1155       if (retval == 0 &&
1156           ((mp->new_table_index != 0xFFFFFFFF) ||
1157            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1158            (mp->match_n_vectors != 0xFFFFFFFF)))
1159         /*
1160          * Note: this is just barely thread-safe, depends on
1161          * the main thread spinning waiting for an answer...
1162          */
1163         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1164                 ntohl (mp->new_table_index),
1165                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1166       vam->result_ready = 1;
1167     }
1168 }
1169
1170 static void vl_api_classify_add_del_table_reply_t_handler_json
1171   (vl_api_classify_add_del_table_reply_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   vat_json_node_t node;
1175
1176   vat_json_init_object (&node);
1177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1178   vat_json_object_add_uint (&node, "new_table_index",
1179                             ntohl (mp->new_table_index));
1180   vat_json_object_add_uint (&node, "skip_n_vectors",
1181                             ntohl (mp->skip_n_vectors));
1182   vat_json_object_add_uint (&node, "match_n_vectors",
1183                             ntohl (mp->match_n_vectors));
1184
1185   vat_json_print (vam->ofp, &node);
1186   vat_json_free (&node);
1187
1188   vam->retval = ntohl (mp->retval);
1189   vam->result_ready = 1;
1190 }
1191
1192 static void vl_api_get_node_index_reply_t_handler
1193   (vl_api_get_node_index_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   i32 retval = ntohl (mp->retval);
1197   if (vam->async_mode)
1198     {
1199       vam->async_errors += (retval < 0);
1200     }
1201   else
1202     {
1203       vam->retval = retval;
1204       if (retval == 0)
1205         errmsg ("node index %d", ntohl (mp->node_index));
1206       vam->result_ready = 1;
1207     }
1208 }
1209
1210 static void vl_api_get_node_index_reply_t_handler_json
1211   (vl_api_get_node_index_reply_t * mp)
1212 {
1213   vat_main_t *vam = &vat_main;
1214   vat_json_node_t node;
1215
1216   vat_json_init_object (&node);
1217   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1218   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1219
1220   vat_json_print (vam->ofp, &node);
1221   vat_json_free (&node);
1222
1223   vam->retval = ntohl (mp->retval);
1224   vam->result_ready = 1;
1225 }
1226
1227 static void vl_api_get_next_index_reply_t_handler
1228   (vl_api_get_next_index_reply_t * mp)
1229 {
1230   vat_main_t *vam = &vat_main;
1231   i32 retval = ntohl (mp->retval);
1232   if (vam->async_mode)
1233     {
1234       vam->async_errors += (retval < 0);
1235     }
1236   else
1237     {
1238       vam->retval = retval;
1239       if (retval == 0)
1240         errmsg ("next node index %d", ntohl (mp->next_index));
1241       vam->result_ready = 1;
1242     }
1243 }
1244
1245 static void vl_api_get_next_index_reply_t_handler_json
1246   (vl_api_get_next_index_reply_t * mp)
1247 {
1248   vat_main_t *vam = &vat_main;
1249   vat_json_node_t node;
1250
1251   vat_json_init_object (&node);
1252   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1253   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1254
1255   vat_json_print (vam->ofp, &node);
1256   vat_json_free (&node);
1257
1258   vam->retval = ntohl (mp->retval);
1259   vam->result_ready = 1;
1260 }
1261
1262 static void vl_api_add_node_next_reply_t_handler
1263   (vl_api_add_node_next_reply_t * mp)
1264 {
1265   vat_main_t *vam = &vat_main;
1266   i32 retval = ntohl (mp->retval);
1267   if (vam->async_mode)
1268     {
1269       vam->async_errors += (retval < 0);
1270     }
1271   else
1272     {
1273       vam->retval = retval;
1274       if (retval == 0)
1275         errmsg ("next index %d", ntohl (mp->next_index));
1276       vam->result_ready = 1;
1277     }
1278 }
1279
1280 static void vl_api_add_node_next_reply_t_handler_json
1281   (vl_api_add_node_next_reply_t * mp)
1282 {
1283   vat_main_t *vam = &vat_main;
1284   vat_json_node_t node;
1285
1286   vat_json_init_object (&node);
1287   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1288   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1289
1290   vat_json_print (vam->ofp, &node);
1291   vat_json_free (&node);
1292
1293   vam->retval = ntohl (mp->retval);
1294   vam->result_ready = 1;
1295 }
1296
1297 static void vl_api_show_version_reply_t_handler
1298   (vl_api_show_version_reply_t * mp)
1299 {
1300   vat_main_t *vam = &vat_main;
1301   i32 retval = ntohl (mp->retval);
1302
1303   if (retval >= 0)
1304     {
1305       char *s;
1306       char *p = (char *) &mp->program;
1307
1308       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1309       errmsg ("        program: %s\n", s);
1310       free (s);
1311
1312       p +=
1313         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1314       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1315       errmsg ("        version: %s\n", s);
1316       free (s);
1317
1318       p +=
1319         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1320       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1321       errmsg ("     build date: %s\n", s);
1322       free (s);
1323
1324       p +=
1325         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1326       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1327       errmsg ("build directory: %s\n", s);
1328       free (s);
1329     }
1330   vam->retval = retval;
1331   vam->result_ready = 1;
1332 }
1333
1334 static void vl_api_show_version_reply_t_handler_json
1335   (vl_api_show_version_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   vat_json_node_t node;
1339
1340   vat_json_init_object (&node);
1341   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1342   char *p = (char *) &mp->program;
1343   vat_json_object_add_string_copy (&node, "program",
1344                                    vl_api_from_api_string ((vl_api_string_t *)
1345                                                            p));
1346   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1347   vat_json_object_add_string_copy (&node, "version",
1348                                    vl_api_from_api_string ((vl_api_string_t *)
1349                                                            p));
1350   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1351   vat_json_object_add_string_copy (&node, "build_date",
1352                                    vl_api_from_api_string ((vl_api_string_t *)
1353                                                            p));
1354   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1355   vat_json_object_add_string_copy (&node, "build_directory",
1356                                    vl_api_from_api_string ((vl_api_string_t *)
1357                                                            p));
1358
1359   vat_json_print (vam->ofp, &node);
1360   vat_json_free (&node);
1361
1362   vam->retval = ntohl (mp->retval);
1363   vam->result_ready = 1;
1364 }
1365
1366 static void vl_api_show_threads_reply_t_handler
1367   (vl_api_show_threads_reply_t * mp)
1368 {
1369   vat_main_t *vam = &vat_main;
1370   i32 retval = ntohl (mp->retval);
1371   int i, count = 0;
1372
1373   if (retval >= 0)
1374     count = ntohl (mp->count);
1375
1376   for (i = 0; i < count; i++)
1377     print (vam->ofp,
1378            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1379            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1380            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1381            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1382            ntohl (mp->thread_data[i].cpu_socket));
1383
1384   vam->retval = retval;
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_show_threads_reply_t_handler_json
1389   (vl_api_show_threads_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   vat_json_node_t node;
1393   vl_api_thread_data_t *td;
1394   i32 retval = ntohl (mp->retval);
1395   int i, count = 0;
1396
1397   if (retval >= 0)
1398     count = ntohl (mp->count);
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", retval);
1402   vat_json_object_add_uint (&node, "count", count);
1403
1404   for (i = 0; i < count; i++)
1405     {
1406       td = &mp->thread_data[i];
1407       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1408       vat_json_object_add_string_copy (&node, "name", td->name);
1409       vat_json_object_add_string_copy (&node, "type", td->type);
1410       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1411       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1412       vat_json_object_add_int (&node, "core", ntohl (td->id));
1413       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1414     }
1415
1416   vat_json_print (vam->ofp, &node);
1417   vat_json_free (&node);
1418
1419   vam->retval = retval;
1420   vam->result_ready = 1;
1421 }
1422
1423 static int
1424 api_show_threads (vat_main_t * vam)
1425 {
1426   vl_api_show_threads_t *mp;
1427   int ret;
1428
1429   print (vam->ofp,
1430          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1431          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1432
1433   M (SHOW_THREADS, mp);
1434
1435   S (mp);
1436   W (ret);
1437   return ret;
1438 }
1439
1440 static void
1441 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1442 {
1443   u32 sw_if_index = ntohl (mp->sw_if_index);
1444   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1445           mp->mac_ip ? "mac/ip binding" : "address resolution",
1446           ntohl (mp->pid), format_ip4_address, &mp->address,
1447           format_ethernet_address, mp->new_mac, sw_if_index);
1448 }
1449
1450 static void
1451 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1452 {
1453   /* JSON output not supported */
1454 }
1455
1456 static void
1457 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1458 {
1459   u32 sw_if_index = ntohl (mp->sw_if_index);
1460   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1461           mp->mac_ip ? "mac/ip binding" : "address resolution",
1462           ntohl (mp->pid), format_ip6_address, mp->address,
1463           format_ethernet_address, mp->new_mac, sw_if_index);
1464 }
1465
1466 static void
1467 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1468 {
1469   /* JSON output not supported */
1470 }
1471
1472 static void
1473 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1474 {
1475   u32 n_macs = ntohl (mp->n_macs);
1476   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1477           ntohl (mp->pid), mp->client_index, n_macs);
1478   int i;
1479   for (i = 0; i < n_macs; i++)
1480     {
1481       vl_api_mac_entry_t *mac = &mp->mac[i];
1482       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1483               i + 1, ntohl (mac->sw_if_index),
1484               format_ethernet_address, mac->mac_addr, mac->action);
1485       if (i == 1000)
1486         break;
1487     }
1488 }
1489
1490 static void
1491 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1492 {
1493   /* JSON output not supported */
1494 }
1495
1496 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1497 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1498
1499 /*
1500  * Special-case: build the bridge domain table, maintain
1501  * the next bd id vbl.
1502  */
1503 static void vl_api_bridge_domain_details_t_handler
1504   (vl_api_bridge_domain_details_t * mp)
1505 {
1506   vat_main_t *vam = &vat_main;
1507   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1508   int i;
1509
1510   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1511          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1512
1513   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1514          ntohl (mp->bd_id), mp->learn, mp->forward,
1515          mp->flood, ntohl (mp->bvi_sw_if_index),
1516          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1517
1518   if (n_sw_ifs)
1519     {
1520       vl_api_bridge_domain_sw_if_t *sw_ifs;
1521       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1522              "Interface Name");
1523
1524       sw_ifs = mp->sw_if_details;
1525       for (i = 0; i < n_sw_ifs; i++)
1526         {
1527           u8 *sw_if_name = 0;
1528           u32 sw_if_index;
1529           hash_pair_t *p;
1530
1531           sw_if_index = ntohl (sw_ifs->sw_if_index);
1532
1533           /* *INDENT-OFF* */
1534           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1535                              ({
1536                                if ((u32) p->value[0] == sw_if_index)
1537                                  {
1538                                    sw_if_name = (u8 *)(p->key);
1539                                    break;
1540                                  }
1541                              }));
1542           /* *INDENT-ON* */
1543           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1544                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1545                  "sw_if_index not found!");
1546
1547           sw_ifs++;
1548         }
1549     }
1550 }
1551
1552 static void vl_api_bridge_domain_details_t_handler_json
1553   (vl_api_bridge_domain_details_t * mp)
1554 {
1555   vat_main_t *vam = &vat_main;
1556   vat_json_node_t *node, *array = NULL;
1557   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1558
1559   if (VAT_JSON_ARRAY != vam->json_tree.type)
1560     {
1561       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1562       vat_json_init_array (&vam->json_tree);
1563     }
1564   node = vat_json_array_add (&vam->json_tree);
1565
1566   vat_json_init_object (node);
1567   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1568   vat_json_object_add_uint (node, "flood", mp->flood);
1569   vat_json_object_add_uint (node, "forward", mp->forward);
1570   vat_json_object_add_uint (node, "learn", mp->learn);
1571   vat_json_object_add_uint (node, "bvi_sw_if_index",
1572                             ntohl (mp->bvi_sw_if_index));
1573   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1574   array = vat_json_object_add (node, "sw_if");
1575   vat_json_init_array (array);
1576
1577
1578
1579   if (n_sw_ifs)
1580     {
1581       vl_api_bridge_domain_sw_if_t *sw_ifs;
1582       int i;
1583
1584       sw_ifs = mp->sw_if_details;
1585       for (i = 0; i < n_sw_ifs; i++)
1586         {
1587           node = vat_json_array_add (array);
1588           vat_json_init_object (node);
1589           vat_json_object_add_uint (node, "sw_if_index",
1590                                     ntohl (sw_ifs->sw_if_index));
1591           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1592           sw_ifs++;
1593         }
1594     }
1595 }
1596
1597 static void vl_api_control_ping_reply_t_handler
1598   (vl_api_control_ping_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611   if (vam->socket_client_main)
1612     vam->socket_client_main->control_pings_outstanding--;
1613 }
1614
1615 static void vl_api_control_ping_reply_t_handler_json
1616   (vl_api_control_ping_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   i32 retval = ntohl (mp->retval);
1620
1621   if (VAT_JSON_NONE != vam->json_tree.type)
1622     {
1623       vat_json_print (vam->ofp, &vam->json_tree);
1624       vat_json_free (&vam->json_tree);
1625       vam->json_tree.type = VAT_JSON_NONE;
1626     }
1627   else
1628     {
1629       /* just print [] */
1630       vat_json_init_array (&vam->json_tree);
1631       vat_json_print (vam->ofp, &vam->json_tree);
1632       vam->json_tree.type = VAT_JSON_NONE;
1633     }
1634
1635   vam->retval = retval;
1636   vam->result_ready = 1;
1637 }
1638
1639 static void
1640   vl_api_bridge_domain_set_mac_age_reply_t_handler
1641   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1642 {
1643   vat_main_t *vam = &vat_main;
1644   i32 retval = ntohl (mp->retval);
1645   if (vam->async_mode)
1646     {
1647       vam->async_errors += (retval < 0);
1648     }
1649   else
1650     {
1651       vam->retval = retval;
1652       vam->result_ready = 1;
1653     }
1654 }
1655
1656 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1657   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1658 {
1659   vat_main_t *vam = &vat_main;
1660   vat_json_node_t node;
1661
1662   vat_json_init_object (&node);
1663   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1664
1665   vat_json_print (vam->ofp, &node);
1666   vat_json_free (&node);
1667
1668   vam->retval = ntohl (mp->retval);
1669   vam->result_ready = 1;
1670 }
1671
1672 static void
1673 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1674 {
1675   vat_main_t *vam = &vat_main;
1676   i32 retval = ntohl (mp->retval);
1677   if (vam->async_mode)
1678     {
1679       vam->async_errors += (retval < 0);
1680     }
1681   else
1682     {
1683       vam->retval = retval;
1684       vam->result_ready = 1;
1685     }
1686 }
1687
1688 static void vl_api_l2_flags_reply_t_handler_json
1689   (vl_api_l2_flags_reply_t * mp)
1690 {
1691   vat_main_t *vam = &vat_main;
1692   vat_json_node_t node;
1693
1694   vat_json_init_object (&node);
1695   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1696   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1697                             ntohl (mp->resulting_feature_bitmap));
1698
1699   vat_json_print (vam->ofp, &node);
1700   vat_json_free (&node);
1701
1702   vam->retval = ntohl (mp->retval);
1703   vam->result_ready = 1;
1704 }
1705
1706 static void vl_api_bridge_flags_reply_t_handler
1707   (vl_api_bridge_flags_reply_t * mp)
1708 {
1709   vat_main_t *vam = &vat_main;
1710   i32 retval = ntohl (mp->retval);
1711   if (vam->async_mode)
1712     {
1713       vam->async_errors += (retval < 0);
1714     }
1715   else
1716     {
1717       vam->retval = retval;
1718       vam->result_ready = 1;
1719     }
1720 }
1721
1722 static void vl_api_bridge_flags_reply_t_handler_json
1723   (vl_api_bridge_flags_reply_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   vat_json_node_t node;
1727
1728   vat_json_init_object (&node);
1729   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1730   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1731                             ntohl (mp->resulting_feature_bitmap));
1732
1733   vat_json_print (vam->ofp, &node);
1734   vat_json_free (&node);
1735
1736   vam->retval = ntohl (mp->retval);
1737   vam->result_ready = 1;
1738 }
1739
1740 static void vl_api_tap_connect_reply_t_handler
1741   (vl_api_tap_connect_reply_t * mp)
1742 {
1743   vat_main_t *vam = &vat_main;
1744   i32 retval = ntohl (mp->retval);
1745   if (vam->async_mode)
1746     {
1747       vam->async_errors += (retval < 0);
1748     }
1749   else
1750     {
1751       vam->retval = retval;
1752       vam->sw_if_index = ntohl (mp->sw_if_index);
1753       vam->result_ready = 1;
1754     }
1755
1756 }
1757
1758 static void vl_api_tap_connect_reply_t_handler_json
1759   (vl_api_tap_connect_reply_t * mp)
1760 {
1761   vat_main_t *vam = &vat_main;
1762   vat_json_node_t node;
1763
1764   vat_json_init_object (&node);
1765   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1766   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1767
1768   vat_json_print (vam->ofp, &node);
1769   vat_json_free (&node);
1770
1771   vam->retval = ntohl (mp->retval);
1772   vam->result_ready = 1;
1773
1774 }
1775
1776 static void
1777 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1778 {
1779   vat_main_t *vam = &vat_main;
1780   i32 retval = ntohl (mp->retval);
1781   if (vam->async_mode)
1782     {
1783       vam->async_errors += (retval < 0);
1784     }
1785   else
1786     {
1787       vam->retval = retval;
1788       vam->sw_if_index = ntohl (mp->sw_if_index);
1789       vam->result_ready = 1;
1790     }
1791 }
1792
1793 static void vl_api_tap_modify_reply_t_handler_json
1794   (vl_api_tap_modify_reply_t * mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   vat_json_node_t node;
1798
1799   vat_json_init_object (&node);
1800   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1801   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1802
1803   vat_json_print (vam->ofp, &node);
1804   vat_json_free (&node);
1805
1806   vam->retval = ntohl (mp->retval);
1807   vam->result_ready = 1;
1808 }
1809
1810 static void
1811 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1812 {
1813   vat_main_t *vam = &vat_main;
1814   i32 retval = ntohl (mp->retval);
1815   if (vam->async_mode)
1816     {
1817       vam->async_errors += (retval < 0);
1818     }
1819   else
1820     {
1821       vam->retval = retval;
1822       vam->result_ready = 1;
1823     }
1824 }
1825
1826 static void vl_api_tap_delete_reply_t_handler_json
1827   (vl_api_tap_delete_reply_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   vat_json_node_t node;
1831
1832   vat_json_init_object (&node);
1833   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1834
1835   vat_json_print (vam->ofp, &node);
1836   vat_json_free (&node);
1837
1838   vam->retval = ntohl (mp->retval);
1839   vam->result_ready = 1;
1840 }
1841
1842 static void
1843 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1844 {
1845   vat_main_t *vam = &vat_main;
1846   i32 retval = ntohl (mp->retval);
1847   if (vam->async_mode)
1848     {
1849       vam->async_errors += (retval < 0);
1850     }
1851   else
1852     {
1853       vam->retval = retval;
1854       vam->sw_if_index = ntohl (mp->sw_if_index);
1855       vam->result_ready = 1;
1856     }
1857
1858 }
1859
1860 static void vl_api_tap_create_v2_reply_t_handler_json
1861   (vl_api_tap_create_v2_reply_t * mp)
1862 {
1863   vat_main_t *vam = &vat_main;
1864   vat_json_node_t node;
1865
1866   vat_json_init_object (&node);
1867   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1868   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1869
1870   vat_json_print (vam->ofp, &node);
1871   vat_json_free (&node);
1872
1873   vam->retval = ntohl (mp->retval);
1874   vam->result_ready = 1;
1875
1876 }
1877
1878 static void
1879 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1880 {
1881   vat_main_t *vam = &vat_main;
1882   i32 retval = ntohl (mp->retval);
1883   if (vam->async_mode)
1884     {
1885       vam->async_errors += (retval < 0);
1886     }
1887   else
1888     {
1889       vam->retval = retval;
1890       vam->result_ready = 1;
1891     }
1892 }
1893
1894 static void vl_api_tap_delete_v2_reply_t_handler_json
1895   (vl_api_tap_delete_v2_reply_t * mp)
1896 {
1897   vat_main_t *vam = &vat_main;
1898   vat_json_node_t node;
1899
1900   vat_json_init_object (&node);
1901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1902
1903   vat_json_print (vam->ofp, &node);
1904   vat_json_free (&node);
1905
1906   vam->retval = ntohl (mp->retval);
1907   vam->result_ready = 1;
1908 }
1909
1910 static void
1911 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   i32 retval = ntohl (mp->retval);
1915
1916   if (vam->async_mode)
1917     {
1918       vam->async_errors += (retval < 0);
1919     }
1920   else
1921     {
1922       vam->retval = retval;
1923       vam->sw_if_index = ntohl (mp->sw_if_index);
1924       vam->result_ready = 1;
1925     }
1926 }
1927
1928 static void vl_api_bond_create_reply_t_handler_json
1929   (vl_api_bond_create_reply_t * mp)
1930 {
1931   vat_main_t *vam = &vat_main;
1932   vat_json_node_t node;
1933
1934   vat_json_init_object (&node);
1935   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1936   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1937
1938   vat_json_print (vam->ofp, &node);
1939   vat_json_free (&node);
1940
1941   vam->retval = ntohl (mp->retval);
1942   vam->result_ready = 1;
1943 }
1944
1945 static void
1946 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   i32 retval = ntohl (mp->retval);
1950
1951   if (vam->async_mode)
1952     {
1953       vam->async_errors += (retval < 0);
1954     }
1955   else
1956     {
1957       vam->retval = retval;
1958       vam->result_ready = 1;
1959     }
1960 }
1961
1962 static void vl_api_bond_delete_reply_t_handler_json
1963   (vl_api_bond_delete_reply_t * mp)
1964 {
1965   vat_main_t *vam = &vat_main;
1966   vat_json_node_t node;
1967
1968   vat_json_init_object (&node);
1969   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1970
1971   vat_json_print (vam->ofp, &node);
1972   vat_json_free (&node);
1973
1974   vam->retval = ntohl (mp->retval);
1975   vam->result_ready = 1;
1976 }
1977
1978 static void
1979 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1980 {
1981   vat_main_t *vam = &vat_main;
1982   i32 retval = ntohl (mp->retval);
1983
1984   if (vam->async_mode)
1985     {
1986       vam->async_errors += (retval < 0);
1987     }
1988   else
1989     {
1990       vam->retval = retval;
1991       vam->result_ready = 1;
1992     }
1993 }
1994
1995 static void vl_api_bond_enslave_reply_t_handler_json
1996   (vl_api_bond_enslave_reply_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t node;
2000
2001   vat_json_init_object (&node);
2002   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2003
2004   vat_json_print (vam->ofp, &node);
2005   vat_json_free (&node);
2006
2007   vam->retval = ntohl (mp->retval);
2008   vam->result_ready = 1;
2009 }
2010
2011 static void
2012 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2013                                           mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   i32 retval = ntohl (mp->retval);
2017
2018   if (vam->async_mode)
2019     {
2020       vam->async_errors += (retval < 0);
2021     }
2022   else
2023     {
2024       vam->retval = retval;
2025       vam->result_ready = 1;
2026     }
2027 }
2028
2029 static void vl_api_bond_detach_slave_reply_t_handler_json
2030   (vl_api_bond_detach_slave_reply_t * mp)
2031 {
2032   vat_main_t *vam = &vat_main;
2033   vat_json_node_t node;
2034
2035   vat_json_init_object (&node);
2036   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2037
2038   vat_json_print (vam->ofp, &node);
2039   vat_json_free (&node);
2040
2041   vam->retval = ntohl (mp->retval);
2042   vam->result_ready = 1;
2043 }
2044
2045 static void vl_api_sw_interface_bond_details_t_handler
2046   (vl_api_sw_interface_bond_details_t * mp)
2047 {
2048   vat_main_t *vam = &vat_main;
2049
2050   print (vam->ofp,
2051          "%-16s %-12d %-12U %-13U %-14u %-14u",
2052          mp->interface_name, ntohl (mp->sw_if_index),
2053          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2054          ntohl (mp->active_slaves), ntohl (mp->slaves));
2055 }
2056
2057 static void vl_api_sw_interface_bond_details_t_handler_json
2058   (vl_api_sw_interface_bond_details_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vat_json_node_t *node = NULL;
2062
2063   if (VAT_JSON_ARRAY != vam->json_tree.type)
2064     {
2065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2066       vat_json_init_array (&vam->json_tree);
2067     }
2068   node = vat_json_array_add (&vam->json_tree);
2069
2070   vat_json_init_object (node);
2071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2072   vat_json_object_add_string_copy (node, "interface_name",
2073                                    mp->interface_name);
2074   vat_json_object_add_uint (node, "mode", mp->mode);
2075   vat_json_object_add_uint (node, "load_balance", mp->lb);
2076   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2077   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2078 }
2079
2080 static int
2081 api_sw_interface_bond_dump (vat_main_t * vam)
2082 {
2083   vl_api_sw_interface_bond_dump_t *mp;
2084   vl_api_control_ping_t *mp_ping;
2085   int ret;
2086
2087   print (vam->ofp,
2088          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2089          "interface name", "sw_if_index", "mode", "load balance",
2090          "active slaves", "slaves");
2091
2092   /* Get list of bond interfaces */
2093   M (SW_INTERFACE_BOND_DUMP, mp);
2094   S (mp);
2095
2096   /* Use a control ping for synchronization */
2097   MPING (CONTROL_PING, mp_ping);
2098   S (mp_ping);
2099
2100   W (ret);
2101   return ret;
2102 }
2103
2104 static void vl_api_sw_interface_slave_details_t_handler
2105   (vl_api_sw_interface_slave_details_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108
2109   print (vam->ofp,
2110          "%-25s %-12d %-12d %d", mp->interface_name,
2111          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2112 }
2113
2114 static void vl_api_sw_interface_slave_details_t_handler_json
2115   (vl_api_sw_interface_slave_details_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   vat_json_node_t *node = NULL;
2119
2120   if (VAT_JSON_ARRAY != vam->json_tree.type)
2121     {
2122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2123       vat_json_init_array (&vam->json_tree);
2124     }
2125   node = vat_json_array_add (&vam->json_tree);
2126
2127   vat_json_init_object (node);
2128   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2129   vat_json_object_add_string_copy (node, "interface_name",
2130                                    mp->interface_name);
2131   vat_json_object_add_uint (node, "passive", mp->is_passive);
2132   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2133 }
2134
2135 static int
2136 api_sw_interface_slave_dump (vat_main_t * vam)
2137 {
2138   unformat_input_t *i = vam->input;
2139   vl_api_sw_interface_slave_dump_t *mp;
2140   vl_api_control_ping_t *mp_ping;
2141   u32 sw_if_index = ~0;
2142   u8 sw_if_index_set = 0;
2143   int ret;
2144
2145   /* Parse args required to build the message */
2146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2147     {
2148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2149         sw_if_index_set = 1;
2150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2151         sw_if_index_set = 1;
2152       else
2153         break;
2154     }
2155
2156   if (sw_if_index_set == 0)
2157     {
2158       errmsg ("missing vpp interface name. ");
2159       return -99;
2160     }
2161
2162   print (vam->ofp,
2163          "\n%-25s %-12s %-12s %s",
2164          "slave interface name", "sw_if_index", "passive", "long_timeout");
2165
2166   /* Get list of bond interfaces */
2167   M (SW_INTERFACE_SLAVE_DUMP, mp);
2168   mp->sw_if_index = ntohl (sw_if_index);
2169   S (mp);
2170
2171   /* Use a control ping for synchronization */
2172   MPING (CONTROL_PING, mp_ping);
2173   S (mp_ping);
2174
2175   W (ret);
2176   return ret;
2177 }
2178
2179 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2180   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       vam->retval = retval;
2191       vam->sw_if_index = ntohl (mp->sw_if_index);
2192       vam->result_ready = 1;
2193     }
2194   vam->regenerate_interface_table = 1;
2195 }
2196
2197 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2198   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   vat_json_node_t node;
2202
2203   vat_json_init_object (&node);
2204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2205   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2206                             ntohl (mp->sw_if_index));
2207
2208   vat_json_print (vam->ofp, &node);
2209   vat_json_free (&node);
2210
2211   vam->retval = ntohl (mp->retval);
2212   vam->result_ready = 1;
2213 }
2214
2215 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2216   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   i32 retval = ntohl (mp->retval);
2220   if (vam->async_mode)
2221     {
2222       vam->async_errors += (retval < 0);
2223     }
2224   else
2225     {
2226       vam->retval = retval;
2227       vam->sw_if_index = ntohl (mp->sw_if_index);
2228       vam->result_ready = 1;
2229     }
2230 }
2231
2232 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2233   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   vat_json_node_t node;
2237
2238   vat_json_init_object (&node);
2239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2240   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2241
2242   vat_json_print (vam->ofp, &node);
2243   vat_json_free (&node);
2244
2245   vam->retval = ntohl (mp->retval);
2246   vam->result_ready = 1;
2247 }
2248
2249 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2250   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2251 {
2252   vat_main_t *vam = &vat_main;
2253   i32 retval = ntohl (mp->retval);
2254   if (vam->async_mode)
2255     {
2256       vam->async_errors += (retval < 0);
2257     }
2258   else
2259     {
2260       vam->retval = retval;
2261       vam->result_ready = 1;
2262     }
2263 }
2264
2265 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2266   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2267 {
2268   vat_main_t *vam = &vat_main;
2269   vat_json_node_t node;
2270
2271   vat_json_init_object (&node);
2272   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2273   vat_json_object_add_uint (&node, "fwd_entry_index",
2274                             clib_net_to_host_u32 (mp->fwd_entry_index));
2275
2276   vat_json_print (vam->ofp, &node);
2277   vat_json_free (&node);
2278
2279   vam->retval = ntohl (mp->retval);
2280   vam->result_ready = 1;
2281 }
2282
2283 u8 *
2284 format_lisp_transport_protocol (u8 * s, va_list * args)
2285 {
2286   u32 proto = va_arg (*args, u32);
2287
2288   switch (proto)
2289     {
2290     case 1:
2291       return format (s, "udp");
2292     case 2:
2293       return format (s, "api");
2294     default:
2295       return 0;
2296     }
2297   return 0;
2298 }
2299
2300 static void vl_api_one_get_transport_protocol_reply_t_handler
2301   (vl_api_one_get_transport_protocol_reply_t * mp)
2302 {
2303   vat_main_t *vam = &vat_main;
2304   i32 retval = ntohl (mp->retval);
2305   if (vam->async_mode)
2306     {
2307       vam->async_errors += (retval < 0);
2308     }
2309   else
2310     {
2311       u32 proto = mp->protocol;
2312       print (vam->ofp, "Transport protocol: %U",
2313              format_lisp_transport_protocol, proto);
2314       vam->retval = retval;
2315       vam->result_ready = 1;
2316     }
2317 }
2318
2319 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2320   (vl_api_one_get_transport_protocol_reply_t * mp)
2321 {
2322   vat_main_t *vam = &vat_main;
2323   vat_json_node_t node;
2324   u8 *s;
2325
2326   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2327   vec_add1 (s, 0);
2328
2329   vat_json_init_object (&node);
2330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2331   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2332
2333   vec_free (s);
2334   vat_json_print (vam->ofp, &node);
2335   vat_json_free (&node);
2336
2337   vam->retval = ntohl (mp->retval);
2338   vam->result_ready = 1;
2339 }
2340
2341 static void vl_api_one_add_del_locator_set_reply_t_handler
2342   (vl_api_one_add_del_locator_set_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   i32 retval = ntohl (mp->retval);
2346   if (vam->async_mode)
2347     {
2348       vam->async_errors += (retval < 0);
2349     }
2350   else
2351     {
2352       vam->retval = retval;
2353       vam->result_ready = 1;
2354     }
2355 }
2356
2357 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2358   (vl_api_one_add_del_locator_set_reply_t * mp)
2359 {
2360   vat_main_t *vam = &vat_main;
2361   vat_json_node_t node;
2362
2363   vat_json_init_object (&node);
2364   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2365   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2366
2367   vat_json_print (vam->ofp, &node);
2368   vat_json_free (&node);
2369
2370   vam->retval = ntohl (mp->retval);
2371   vam->result_ready = 1;
2372 }
2373
2374 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2375   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2376 {
2377   vat_main_t *vam = &vat_main;
2378   i32 retval = ntohl (mp->retval);
2379   if (vam->async_mode)
2380     {
2381       vam->async_errors += (retval < 0);
2382     }
2383   else
2384     {
2385       vam->retval = retval;
2386       vam->sw_if_index = ntohl (mp->sw_if_index);
2387       vam->result_ready = 1;
2388     }
2389   vam->regenerate_interface_table = 1;
2390 }
2391
2392 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2393   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2394 {
2395   vat_main_t *vam = &vat_main;
2396   vat_json_node_t node;
2397
2398   vat_json_init_object (&node);
2399   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2400   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2401
2402   vat_json_print (vam->ofp, &node);
2403   vat_json_free (&node);
2404
2405   vam->retval = ntohl (mp->retval);
2406   vam->result_ready = 1;
2407 }
2408
2409 static void vl_api_vxlan_offload_rx_reply_t_handler
2410   (vl_api_vxlan_offload_rx_reply_t * mp)
2411 {
2412   vat_main_t *vam = &vat_main;
2413   i32 retval = ntohl (mp->retval);
2414   if (vam->async_mode)
2415     {
2416       vam->async_errors += (retval < 0);
2417     }
2418   else
2419     {
2420       vam->retval = retval;
2421       vam->result_ready = 1;
2422     }
2423 }
2424
2425 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2426   (vl_api_vxlan_offload_rx_reply_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   vat_json_node_t node;
2430
2431   vat_json_init_object (&node);
2432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2433
2434   vat_json_print (vam->ofp, &node);
2435   vat_json_free (&node);
2436
2437   vam->retval = ntohl (mp->retval);
2438   vam->result_ready = 1;
2439 }
2440
2441 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2442   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   i32 retval = ntohl (mp->retval);
2446   if (vam->async_mode)
2447     {
2448       vam->async_errors += (retval < 0);
2449     }
2450   else
2451     {
2452       vam->retval = retval;
2453       vam->sw_if_index = ntohl (mp->sw_if_index);
2454       vam->result_ready = 1;
2455     }
2456 }
2457
2458 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2459   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   vat_json_node_t node;
2463
2464   vat_json_init_object (&node);
2465   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2466   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2467
2468   vat_json_print (vam->ofp, &node);
2469   vat_json_free (&node);
2470
2471   vam->retval = ntohl (mp->retval);
2472   vam->result_ready = 1;
2473 }
2474
2475 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2476   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479   i32 retval = ntohl (mp->retval);
2480   if (vam->async_mode)
2481     {
2482       vam->async_errors += (retval < 0);
2483     }
2484   else
2485     {
2486       vam->retval = retval;
2487       vam->sw_if_index = ntohl (mp->sw_if_index);
2488       vam->result_ready = 1;
2489     }
2490   vam->regenerate_interface_table = 1;
2491 }
2492
2493 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2494   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   vat_json_node_t node;
2498
2499   vat_json_init_object (&node);
2500   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2501   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2502
2503   vat_json_print (vam->ofp, &node);
2504   vat_json_free (&node);
2505
2506   vam->retval = ntohl (mp->retval);
2507   vam->result_ready = 1;
2508 }
2509
2510 static void vl_api_gre_add_del_tunnel_reply_t_handler
2511   (vl_api_gre_add_del_tunnel_reply_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   i32 retval = ntohl (mp->retval);
2515   if (vam->async_mode)
2516     {
2517       vam->async_errors += (retval < 0);
2518     }
2519   else
2520     {
2521       vam->retval = retval;
2522       vam->sw_if_index = ntohl (mp->sw_if_index);
2523       vam->result_ready = 1;
2524     }
2525 }
2526
2527 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2528   (vl_api_gre_add_del_tunnel_reply_t * mp)
2529 {
2530   vat_main_t *vam = &vat_main;
2531   vat_json_node_t node;
2532
2533   vat_json_init_object (&node);
2534   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2535   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2536
2537   vat_json_print (vam->ofp, &node);
2538   vat_json_free (&node);
2539
2540   vam->retval = ntohl (mp->retval);
2541   vam->result_ready = 1;
2542 }
2543
2544 static void vl_api_create_vhost_user_if_reply_t_handler
2545   (vl_api_create_vhost_user_if_reply_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   i32 retval = ntohl (mp->retval);
2549   if (vam->async_mode)
2550     {
2551       vam->async_errors += (retval < 0);
2552     }
2553   else
2554     {
2555       vam->retval = retval;
2556       vam->sw_if_index = ntohl (mp->sw_if_index);
2557       vam->result_ready = 1;
2558     }
2559   vam->regenerate_interface_table = 1;
2560 }
2561
2562 static void vl_api_create_vhost_user_if_reply_t_handler_json
2563   (vl_api_create_vhost_user_if_reply_t * mp)
2564 {
2565   vat_main_t *vam = &vat_main;
2566   vat_json_node_t node;
2567
2568   vat_json_init_object (&node);
2569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2571
2572   vat_json_print (vam->ofp, &node);
2573   vat_json_free (&node);
2574
2575   vam->retval = ntohl (mp->retval);
2576   vam->result_ready = 1;
2577 }
2578
2579 static void vl_api_dns_resolve_name_reply_t_handler
2580   (vl_api_dns_resolve_name_reply_t * mp)
2581 {
2582   vat_main_t *vam = &vat_main;
2583   i32 retval = ntohl (mp->retval);
2584   if (vam->async_mode)
2585     {
2586       vam->async_errors += (retval < 0);
2587     }
2588   else
2589     {
2590       vam->retval = retval;
2591       vam->result_ready = 1;
2592
2593       if (retval == 0)
2594         {
2595           if (mp->ip4_set)
2596             clib_warning ("ip4 address %U", format_ip4_address,
2597                           (ip4_address_t *) mp->ip4_address);
2598           if (mp->ip6_set)
2599             clib_warning ("ip6 address %U", format_ip6_address,
2600                           (ip6_address_t *) mp->ip6_address);
2601         }
2602       else
2603         clib_warning ("retval %d", retval);
2604     }
2605 }
2606
2607 static void vl_api_dns_resolve_name_reply_t_handler_json
2608   (vl_api_dns_resolve_name_reply_t * mp)
2609 {
2610   clib_warning ("not implemented");
2611 }
2612
2613 static void vl_api_dns_resolve_ip_reply_t_handler
2614   (vl_api_dns_resolve_ip_reply_t * mp)
2615 {
2616   vat_main_t *vam = &vat_main;
2617   i32 retval = ntohl (mp->retval);
2618   if (vam->async_mode)
2619     {
2620       vam->async_errors += (retval < 0);
2621     }
2622   else
2623     {
2624       vam->retval = retval;
2625       vam->result_ready = 1;
2626
2627       if (retval == 0)
2628         {
2629           clib_warning ("canonical name %s", mp->name);
2630         }
2631       else
2632         clib_warning ("retval %d", retval);
2633     }
2634 }
2635
2636 static void vl_api_dns_resolve_ip_reply_t_handler_json
2637   (vl_api_dns_resolve_ip_reply_t * mp)
2638 {
2639   clib_warning ("not implemented");
2640 }
2641
2642
2643 static void vl_api_ip_address_details_t_handler
2644   (vl_api_ip_address_details_t * mp)
2645 {
2646   vat_main_t *vam = &vat_main;
2647   static ip_address_details_t empty_ip_address_details = { {0} };
2648   ip_address_details_t *address = NULL;
2649   ip_details_t *current_ip_details = NULL;
2650   ip_details_t *details = NULL;
2651
2652   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2653
2654   if (!details || vam->current_sw_if_index >= vec_len (details)
2655       || !details[vam->current_sw_if_index].present)
2656     {
2657       errmsg ("ip address details arrived but not stored");
2658       errmsg ("ip_dump should be called first");
2659       return;
2660     }
2661
2662   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2663
2664 #define addresses (current_ip_details->addr)
2665
2666   vec_validate_init_empty (addresses, vec_len (addresses),
2667                            empty_ip_address_details);
2668
2669   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2670
2671   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2672   address->prefix_length = mp->prefix_length;
2673 #undef addresses
2674 }
2675
2676 static void vl_api_ip_address_details_t_handler_json
2677   (vl_api_ip_address_details_t * mp)
2678 {
2679   vat_main_t *vam = &vat_main;
2680   vat_json_node_t *node = NULL;
2681   struct in6_addr ip6;
2682   struct in_addr ip4;
2683
2684   if (VAT_JSON_ARRAY != vam->json_tree.type)
2685     {
2686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2687       vat_json_init_array (&vam->json_tree);
2688     }
2689   node = vat_json_array_add (&vam->json_tree);
2690
2691   vat_json_init_object (node);
2692   if (vam->is_ipv6)
2693     {
2694       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2695       vat_json_object_add_ip6 (node, "ip", ip6);
2696     }
2697   else
2698     {
2699       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2700       vat_json_object_add_ip4 (node, "ip", ip4);
2701     }
2702   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2703 }
2704
2705 static void
2706 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2707 {
2708   vat_main_t *vam = &vat_main;
2709   static ip_details_t empty_ip_details = { 0 };
2710   ip_details_t *ip = NULL;
2711   u32 sw_if_index = ~0;
2712
2713   sw_if_index = ntohl (mp->sw_if_index);
2714
2715   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2716                            sw_if_index, empty_ip_details);
2717
2718   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2719                          sw_if_index);
2720
2721   ip->present = 1;
2722 }
2723
2724 static void
2725 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728
2729   if (VAT_JSON_ARRAY != vam->json_tree.type)
2730     {
2731       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2732       vat_json_init_array (&vam->json_tree);
2733     }
2734   vat_json_array_add_uint (&vam->json_tree,
2735                            clib_net_to_host_u32 (mp->sw_if_index));
2736 }
2737
2738 static void
2739 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2740 {
2741   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2742           "router_addr %U host_mac %U",
2743           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2744           mp->lease.hostname,
2745           format_ip4_address, &mp->lease.host_address,
2746           format_ip4_address, &mp->lease.router_address,
2747           format_ethernet_address, mp->lease.host_mac);
2748 }
2749
2750 static void vl_api_dhcp_compl_event_t_handler_json
2751   (vl_api_dhcp_compl_event_t * mp)
2752 {
2753   /* JSON output not supported */
2754 }
2755
2756 static void vl_api_get_first_msg_id_reply_t_handler
2757   (vl_api_get_first_msg_id_reply_t * mp)
2758 {
2759   vat_main_t *vam = &vat_main;
2760   i32 retval = ntohl (mp->retval);
2761
2762   if (vam->async_mode)
2763     {
2764       vam->async_errors += (retval < 0);
2765     }
2766   else
2767     {
2768       vam->retval = retval;
2769       vam->result_ready = 1;
2770     }
2771   if (retval >= 0)
2772     {
2773       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2774     }
2775 }
2776
2777 static void vl_api_get_first_msg_id_reply_t_handler_json
2778   (vl_api_get_first_msg_id_reply_t * mp)
2779 {
2780   vat_main_t *vam = &vat_main;
2781   vat_json_node_t node;
2782
2783   vat_json_init_object (&node);
2784   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2785   vat_json_object_add_uint (&node, "first_msg_id",
2786                             (uint) ntohs (mp->first_msg_id));
2787
2788   vat_json_print (vam->ofp, &node);
2789   vat_json_free (&node);
2790
2791   vam->retval = ntohl (mp->retval);
2792   vam->result_ready = 1;
2793 }
2794
2795 static void vl_api_get_node_graph_reply_t_handler
2796   (vl_api_get_node_graph_reply_t * mp)
2797 {
2798   vat_main_t *vam = &vat_main;
2799   api_main_t *am = &api_main;
2800   i32 retval = ntohl (mp->retval);
2801   u8 *pvt_copy, *reply;
2802   void *oldheap;
2803   vlib_node_t *node;
2804   int i;
2805
2806   if (vam->async_mode)
2807     {
2808       vam->async_errors += (retval < 0);
2809     }
2810   else
2811     {
2812       vam->retval = retval;
2813       vam->result_ready = 1;
2814     }
2815
2816   /* "Should never happen..." */
2817   if (retval != 0)
2818     return;
2819
2820   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2821   pvt_copy = vec_dup (reply);
2822
2823   /* Toss the shared-memory original... */
2824   pthread_mutex_lock (&am->vlib_rp->mutex);
2825   oldheap = svm_push_data_heap (am->vlib_rp);
2826
2827   vec_free (reply);
2828
2829   svm_pop_heap (oldheap);
2830   pthread_mutex_unlock (&am->vlib_rp->mutex);
2831
2832   if (vam->graph_nodes)
2833     {
2834       hash_free (vam->graph_node_index_by_name);
2835
2836       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2837         {
2838           node = vam->graph_nodes[0][i];
2839           vec_free (node->name);
2840           vec_free (node->next_nodes);
2841           vec_free (node);
2842         }
2843       vec_free (vam->graph_nodes[0]);
2844       vec_free (vam->graph_nodes);
2845     }
2846
2847   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2848   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2849   vec_free (pvt_copy);
2850
2851   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2852     {
2853       node = vam->graph_nodes[0][i];
2854       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2855     }
2856 }
2857
2858 static void vl_api_get_node_graph_reply_t_handler_json
2859   (vl_api_get_node_graph_reply_t * mp)
2860 {
2861   vat_main_t *vam = &vat_main;
2862   api_main_t *am = &api_main;
2863   void *oldheap;
2864   vat_json_node_t node;
2865   u8 *reply;
2866
2867   /* $$$$ make this real? */
2868   vat_json_init_object (&node);
2869   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2870   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2871
2872   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2873
2874   /* Toss the shared-memory original... */
2875   pthread_mutex_lock (&am->vlib_rp->mutex);
2876   oldheap = svm_push_data_heap (am->vlib_rp);
2877
2878   vec_free (reply);
2879
2880   svm_pop_heap (oldheap);
2881   pthread_mutex_unlock (&am->vlib_rp->mutex);
2882
2883   vat_json_print (vam->ofp, &node);
2884   vat_json_free (&node);
2885
2886   vam->retval = ntohl (mp->retval);
2887   vam->result_ready = 1;
2888 }
2889
2890 static void
2891 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2892 {
2893   vat_main_t *vam = &vat_main;
2894   u8 *s = 0;
2895
2896   if (mp->local)
2897     {
2898       s = format (s, "%=16d%=16d%=16d",
2899                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2900     }
2901   else
2902     {
2903       s = format (s, "%=16U%=16d%=16d",
2904                   mp->is_ipv6 ? format_ip6_address :
2905                   format_ip4_address,
2906                   mp->ip_address, mp->priority, mp->weight);
2907     }
2908
2909   print (vam->ofp, "%v", s);
2910   vec_free (s);
2911 }
2912
2913 static void
2914 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2915 {
2916   vat_main_t *vam = &vat_main;
2917   vat_json_node_t *node = NULL;
2918   struct in6_addr ip6;
2919   struct in_addr ip4;
2920
2921   if (VAT_JSON_ARRAY != vam->json_tree.type)
2922     {
2923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2924       vat_json_init_array (&vam->json_tree);
2925     }
2926   node = vat_json_array_add (&vam->json_tree);
2927   vat_json_init_object (node);
2928
2929   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2930   vat_json_object_add_uint (node, "priority", mp->priority);
2931   vat_json_object_add_uint (node, "weight", mp->weight);
2932
2933   if (mp->local)
2934     vat_json_object_add_uint (node, "sw_if_index",
2935                               clib_net_to_host_u32 (mp->sw_if_index));
2936   else
2937     {
2938       if (mp->is_ipv6)
2939         {
2940           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2941           vat_json_object_add_ip6 (node, "address", ip6);
2942         }
2943       else
2944         {
2945           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2946           vat_json_object_add_ip4 (node, "address", ip4);
2947         }
2948     }
2949 }
2950
2951 static void
2952 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2953                                           mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956   u8 *ls_name = 0;
2957
2958   ls_name = format (0, "%s", mp->ls_name);
2959
2960   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2961          ls_name);
2962   vec_free (ls_name);
2963 }
2964
2965 static void
2966   vl_api_one_locator_set_details_t_handler_json
2967   (vl_api_one_locator_set_details_t * mp)
2968 {
2969   vat_main_t *vam = &vat_main;
2970   vat_json_node_t *node = 0;
2971   u8 *ls_name = 0;
2972
2973   ls_name = format (0, "%s", mp->ls_name);
2974   vec_add1 (ls_name, 0);
2975
2976   if (VAT_JSON_ARRAY != vam->json_tree.type)
2977     {
2978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2979       vat_json_init_array (&vam->json_tree);
2980     }
2981   node = vat_json_array_add (&vam->json_tree);
2982
2983   vat_json_init_object (node);
2984   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2985   vat_json_object_add_uint (node, "ls_index",
2986                             clib_net_to_host_u32 (mp->ls_index));
2987   vec_free (ls_name);
2988 }
2989
2990 typedef struct
2991 {
2992   u32 spi;
2993   u8 si;
2994 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2995
2996 uword
2997 unformat_nsh_address (unformat_input_t * input, va_list * args)
2998 {
2999   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3000   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3001 }
3002
3003 u8 *
3004 format_nsh_address_vat (u8 * s, va_list * args)
3005 {
3006   nsh_t *a = va_arg (*args, nsh_t *);
3007   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3008 }
3009
3010 static u8 *
3011 format_lisp_flat_eid (u8 * s, va_list * args)
3012 {
3013   u32 type = va_arg (*args, u32);
3014   u8 *eid = va_arg (*args, u8 *);
3015   u32 eid_len = va_arg (*args, u32);
3016
3017   switch (type)
3018     {
3019     case 0:
3020       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3021     case 1:
3022       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3023     case 2:
3024       return format (s, "%U", format_ethernet_address, eid);
3025     case 3:
3026       return format (s, "%U", format_nsh_address_vat, eid);
3027     }
3028   return 0;
3029 }
3030
3031 static u8 *
3032 format_lisp_eid_vat (u8 * s, va_list * args)
3033 {
3034   u32 type = va_arg (*args, u32);
3035   u8 *eid = va_arg (*args, u8 *);
3036   u32 eid_len = va_arg (*args, u32);
3037   u8 *seid = va_arg (*args, u8 *);
3038   u32 seid_len = va_arg (*args, u32);
3039   u32 is_src_dst = va_arg (*args, u32);
3040
3041   if (is_src_dst)
3042     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3043
3044   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3045
3046   return s;
3047 }
3048
3049 static void
3050 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3051 {
3052   vat_main_t *vam = &vat_main;
3053   u8 *s = 0, *eid = 0;
3054
3055   if (~0 == mp->locator_set_index)
3056     s = format (0, "action: %d", mp->action);
3057   else
3058     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3059
3060   eid = format (0, "%U", format_lisp_eid_vat,
3061                 mp->eid_type,
3062                 mp->eid,
3063                 mp->eid_prefix_len,
3064                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3065   vec_add1 (eid, 0);
3066
3067   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3068          clib_net_to_host_u32 (mp->vni),
3069          eid,
3070          mp->is_local ? "local" : "remote",
3071          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3072          clib_net_to_host_u16 (mp->key_id), mp->key);
3073
3074   vec_free (s);
3075   vec_free (eid);
3076 }
3077
3078 static void
3079 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3080                                              * mp)
3081 {
3082   vat_main_t *vam = &vat_main;
3083   vat_json_node_t *node = 0;
3084   u8 *eid = 0;
3085
3086   if (VAT_JSON_ARRAY != vam->json_tree.type)
3087     {
3088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3089       vat_json_init_array (&vam->json_tree);
3090     }
3091   node = vat_json_array_add (&vam->json_tree);
3092
3093   vat_json_init_object (node);
3094   if (~0 == mp->locator_set_index)
3095     vat_json_object_add_uint (node, "action", mp->action);
3096   else
3097     vat_json_object_add_uint (node, "locator_set_index",
3098                               clib_net_to_host_u32 (mp->locator_set_index));
3099
3100   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3101   if (mp->eid_type == 3)
3102     {
3103       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3104       vat_json_init_object (nsh_json);
3105       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3106       vat_json_object_add_uint (nsh_json, "spi",
3107                                 clib_net_to_host_u32 (nsh->spi));
3108       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3109     }
3110   else
3111     {
3112       eid = format (0, "%U", format_lisp_eid_vat,
3113                     mp->eid_type,
3114                     mp->eid,
3115                     mp->eid_prefix_len,
3116                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3117       vec_add1 (eid, 0);
3118       vat_json_object_add_string_copy (node, "eid", eid);
3119       vec_free (eid);
3120     }
3121   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3122   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3123   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3124
3125   if (mp->key_id)
3126     {
3127       vat_json_object_add_uint (node, "key_id",
3128                                 clib_net_to_host_u16 (mp->key_id));
3129       vat_json_object_add_string_copy (node, "key", mp->key);
3130     }
3131 }
3132
3133 static void
3134 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137   u8 *seid = 0, *deid = 0;
3138   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3139
3140   deid = format (0, "%U", format_lisp_eid_vat,
3141                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3142
3143   seid = format (0, "%U", format_lisp_eid_vat,
3144                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3145
3146   vec_add1 (deid, 0);
3147   vec_add1 (seid, 0);
3148
3149   if (mp->is_ip4)
3150     format_ip_address_fcn = format_ip4_address;
3151   else
3152     format_ip_address_fcn = format_ip6_address;
3153
3154
3155   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3156          clib_net_to_host_u32 (mp->vni),
3157          seid, deid,
3158          format_ip_address_fcn, mp->lloc,
3159          format_ip_address_fcn, mp->rloc,
3160          clib_net_to_host_u32 (mp->pkt_count),
3161          clib_net_to_host_u32 (mp->bytes));
3162
3163   vec_free (deid);
3164   vec_free (seid);
3165 }
3166
3167 static void
3168 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3169 {
3170   struct in6_addr ip6;
3171   struct in_addr ip4;
3172   vat_main_t *vam = &vat_main;
3173   vat_json_node_t *node = 0;
3174   u8 *deid = 0, *seid = 0;
3175
3176   if (VAT_JSON_ARRAY != vam->json_tree.type)
3177     {
3178       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3179       vat_json_init_array (&vam->json_tree);
3180     }
3181   node = vat_json_array_add (&vam->json_tree);
3182
3183   vat_json_init_object (node);
3184   deid = format (0, "%U", format_lisp_eid_vat,
3185                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3186
3187   seid = format (0, "%U", format_lisp_eid_vat,
3188                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3189
3190   vec_add1 (deid, 0);
3191   vec_add1 (seid, 0);
3192
3193   vat_json_object_add_string_copy (node, "seid", seid);
3194   vat_json_object_add_string_copy (node, "deid", deid);
3195   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3196
3197   if (mp->is_ip4)
3198     {
3199       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3200       vat_json_object_add_ip4 (node, "lloc", ip4);
3201       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3202       vat_json_object_add_ip4 (node, "rloc", ip4);
3203     }
3204   else
3205     {
3206       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3207       vat_json_object_add_ip6 (node, "lloc", ip6);
3208       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3209       vat_json_object_add_ip6 (node, "rloc", ip6);
3210     }
3211   vat_json_object_add_uint (node, "pkt_count",
3212                             clib_net_to_host_u32 (mp->pkt_count));
3213   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3214
3215   vec_free (deid);
3216   vec_free (seid);
3217 }
3218
3219 static void
3220   vl_api_one_eid_table_map_details_t_handler
3221   (vl_api_one_eid_table_map_details_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224
3225   u8 *line = format (0, "%=10d%=10d",
3226                      clib_net_to_host_u32 (mp->vni),
3227                      clib_net_to_host_u32 (mp->dp_table));
3228   print (vam->ofp, "%v", line);
3229   vec_free (line);
3230 }
3231
3232 static void
3233   vl_api_one_eid_table_map_details_t_handler_json
3234   (vl_api_one_eid_table_map_details_t * mp)
3235 {
3236   vat_main_t *vam = &vat_main;
3237   vat_json_node_t *node = NULL;
3238
3239   if (VAT_JSON_ARRAY != vam->json_tree.type)
3240     {
3241       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3242       vat_json_init_array (&vam->json_tree);
3243     }
3244   node = vat_json_array_add (&vam->json_tree);
3245   vat_json_init_object (node);
3246   vat_json_object_add_uint (node, "dp_table",
3247                             clib_net_to_host_u32 (mp->dp_table));
3248   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3249 }
3250
3251 static void
3252   vl_api_one_eid_table_vni_details_t_handler
3253   (vl_api_one_eid_table_vni_details_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256
3257   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3258   print (vam->ofp, "%v", line);
3259   vec_free (line);
3260 }
3261
3262 static void
3263   vl_api_one_eid_table_vni_details_t_handler_json
3264   (vl_api_one_eid_table_vni_details_t * mp)
3265 {
3266   vat_main_t *vam = &vat_main;
3267   vat_json_node_t *node = NULL;
3268
3269   if (VAT_JSON_ARRAY != vam->json_tree.type)
3270     {
3271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3272       vat_json_init_array (&vam->json_tree);
3273     }
3274   node = vat_json_array_add (&vam->json_tree);
3275   vat_json_init_object (node);
3276   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3277 }
3278
3279 static void
3280   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3281   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3282 {
3283   vat_main_t *vam = &vat_main;
3284   int retval = clib_net_to_host_u32 (mp->retval);
3285
3286   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3287   print (vam->ofp, "fallback threshold value: %d", mp->value);
3288
3289   vam->retval = retval;
3290   vam->result_ready = 1;
3291 }
3292
3293 static void
3294   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3295   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   vat_json_node_t _node, *node = &_node;
3299   int retval = clib_net_to_host_u32 (mp->retval);
3300
3301   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3302   vat_json_init_object (node);
3303   vat_json_object_add_uint (node, "value", mp->value);
3304
3305   vat_json_print (vam->ofp, node);
3306   vat_json_free (node);
3307
3308   vam->retval = retval;
3309   vam->result_ready = 1;
3310 }
3311
3312 static void
3313   vl_api_show_one_map_register_state_reply_t_handler
3314   (vl_api_show_one_map_register_state_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   int retval = clib_net_to_host_u32 (mp->retval);
3318
3319   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3320
3321   vam->retval = retval;
3322   vam->result_ready = 1;
3323 }
3324
3325 static void
3326   vl_api_show_one_map_register_state_reply_t_handler_json
3327   (vl_api_show_one_map_register_state_reply_t * mp)
3328 {
3329   vat_main_t *vam = &vat_main;
3330   vat_json_node_t _node, *node = &_node;
3331   int retval = clib_net_to_host_u32 (mp->retval);
3332
3333   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3334
3335   vat_json_init_object (node);
3336   vat_json_object_add_string_copy (node, "state", s);
3337
3338   vat_json_print (vam->ofp, node);
3339   vat_json_free (node);
3340
3341   vam->retval = retval;
3342   vam->result_ready = 1;
3343   vec_free (s);
3344 }
3345
3346 static void
3347   vl_api_show_one_rloc_probe_state_reply_t_handler
3348   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3349 {
3350   vat_main_t *vam = &vat_main;
3351   int retval = clib_net_to_host_u32 (mp->retval);
3352
3353   if (retval)
3354     goto end;
3355
3356   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3357 end:
3358   vam->retval = retval;
3359   vam->result_ready = 1;
3360 }
3361
3362 static void
3363   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3364   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3365 {
3366   vat_main_t *vam = &vat_main;
3367   vat_json_node_t _node, *node = &_node;
3368   int retval = clib_net_to_host_u32 (mp->retval);
3369
3370   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3371   vat_json_init_object (node);
3372   vat_json_object_add_string_copy (node, "state", s);
3373
3374   vat_json_print (vam->ofp, node);
3375   vat_json_free (node);
3376
3377   vam->retval = retval;
3378   vam->result_ready = 1;
3379   vec_free (s);
3380 }
3381
3382 static void
3383   vl_api_show_one_stats_enable_disable_reply_t_handler
3384   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   int retval = clib_net_to_host_u32 (mp->retval);
3388
3389   if (retval)
3390     goto end;
3391
3392   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3393 end:
3394   vam->retval = retval;
3395   vam->result_ready = 1;
3396 }
3397
3398 static void
3399   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3400   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3401 {
3402   vat_main_t *vam = &vat_main;
3403   vat_json_node_t _node, *node = &_node;
3404   int retval = clib_net_to_host_u32 (mp->retval);
3405
3406   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3407   vat_json_init_object (node);
3408   vat_json_object_add_string_copy (node, "state", s);
3409
3410   vat_json_print (vam->ofp, node);
3411   vat_json_free (node);
3412
3413   vam->retval = retval;
3414   vam->result_ready = 1;
3415   vec_free (s);
3416 }
3417
3418 static void
3419 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3420 {
3421   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3422   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3423   e->vni = clib_net_to_host_u32 (e->vni);
3424 }
3425
3426 static void
3427   gpe_fwd_entries_get_reply_t_net_to_host
3428   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3429 {
3430   u32 i;
3431
3432   mp->count = clib_net_to_host_u32 (mp->count);
3433   for (i = 0; i < mp->count; i++)
3434     {
3435       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3436     }
3437 }
3438
3439 static u8 *
3440 format_gpe_encap_mode (u8 * s, va_list * args)
3441 {
3442   u32 mode = va_arg (*args, u32);
3443
3444   switch (mode)
3445     {
3446     case 0:
3447       return format (s, "lisp");
3448     case 1:
3449       return format (s, "vxlan");
3450     }
3451   return 0;
3452 }
3453
3454 static void
3455   vl_api_gpe_get_encap_mode_reply_t_handler
3456   (vl_api_gpe_get_encap_mode_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459
3460   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3461   vam->retval = ntohl (mp->retval);
3462   vam->result_ready = 1;
3463 }
3464
3465 static void
3466   vl_api_gpe_get_encap_mode_reply_t_handler_json
3467   (vl_api_gpe_get_encap_mode_reply_t * mp)
3468 {
3469   vat_main_t *vam = &vat_main;
3470   vat_json_node_t node;
3471
3472   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3473   vec_add1 (encap_mode, 0);
3474
3475   vat_json_init_object (&node);
3476   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3477
3478   vec_free (encap_mode);
3479   vat_json_print (vam->ofp, &node);
3480   vat_json_free (&node);
3481
3482   vam->retval = ntohl (mp->retval);
3483   vam->result_ready = 1;
3484 }
3485
3486 static void
3487   vl_api_gpe_fwd_entry_path_details_t_handler
3488   (vl_api_gpe_fwd_entry_path_details_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3492
3493   if (mp->lcl_loc.is_ip4)
3494     format_ip_address_fcn = format_ip4_address;
3495   else
3496     format_ip_address_fcn = format_ip6_address;
3497
3498   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3499          format_ip_address_fcn, &mp->lcl_loc,
3500          format_ip_address_fcn, &mp->rmt_loc);
3501 }
3502
3503 static void
3504 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3505 {
3506   struct in6_addr ip6;
3507   struct in_addr ip4;
3508
3509   if (loc->is_ip4)
3510     {
3511       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3512       vat_json_object_add_ip4 (n, "address", ip4);
3513     }
3514   else
3515     {
3516       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3517       vat_json_object_add_ip6 (n, "address", ip6);
3518     }
3519   vat_json_object_add_uint (n, "weight", loc->weight);
3520 }
3521
3522 static void
3523   vl_api_gpe_fwd_entry_path_details_t_handler_json
3524   (vl_api_gpe_fwd_entry_path_details_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   vat_json_node_t *node = NULL;
3528   vat_json_node_t *loc_node;
3529
3530   if (VAT_JSON_ARRAY != vam->json_tree.type)
3531     {
3532       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3533       vat_json_init_array (&vam->json_tree);
3534     }
3535   node = vat_json_array_add (&vam->json_tree);
3536   vat_json_init_object (node);
3537
3538   loc_node = vat_json_object_add (node, "local_locator");
3539   vat_json_init_object (loc_node);
3540   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3541
3542   loc_node = vat_json_object_add (node, "remote_locator");
3543   vat_json_init_object (loc_node);
3544   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3545 }
3546
3547 static void
3548   vl_api_gpe_fwd_entries_get_reply_t_handler
3549   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3550 {
3551   vat_main_t *vam = &vat_main;
3552   u32 i;
3553   int retval = clib_net_to_host_u32 (mp->retval);
3554   vl_api_gpe_fwd_entry_t *e;
3555
3556   if (retval)
3557     goto end;
3558
3559   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3560
3561   for (i = 0; i < mp->count; i++)
3562     {
3563       e = &mp->entries[i];
3564       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3565              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3566              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3567     }
3568
3569 end:
3570   vam->retval = retval;
3571   vam->result_ready = 1;
3572 }
3573
3574 static void
3575   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3576   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3577 {
3578   u8 *s = 0;
3579   vat_main_t *vam = &vat_main;
3580   vat_json_node_t *e = 0, root;
3581   u32 i;
3582   int retval = clib_net_to_host_u32 (mp->retval);
3583   vl_api_gpe_fwd_entry_t *fwd;
3584
3585   if (retval)
3586     goto end;
3587
3588   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3589   vat_json_init_array (&root);
3590
3591   for (i = 0; i < mp->count; i++)
3592     {
3593       e = vat_json_array_add (&root);
3594       fwd = &mp->entries[i];
3595
3596       vat_json_init_object (e);
3597       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3598       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3599       vat_json_object_add_int (e, "vni", fwd->vni);
3600       vat_json_object_add_int (e, "action", fwd->action);
3601
3602       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3603                   fwd->leid_prefix_len);
3604       vec_add1 (s, 0);
3605       vat_json_object_add_string_copy (e, "leid", s);
3606       vec_free (s);
3607
3608       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3609                   fwd->reid_prefix_len);
3610       vec_add1 (s, 0);
3611       vat_json_object_add_string_copy (e, "reid", s);
3612       vec_free (s);
3613     }
3614
3615   vat_json_print (vam->ofp, &root);
3616   vat_json_free (&root);
3617
3618 end:
3619   vam->retval = retval;
3620   vam->result_ready = 1;
3621 }
3622
3623 static void
3624   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3625   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3626 {
3627   vat_main_t *vam = &vat_main;
3628   u32 i, n;
3629   int retval = clib_net_to_host_u32 (mp->retval);
3630   vl_api_gpe_native_fwd_rpath_t *r;
3631
3632   if (retval)
3633     goto end;
3634
3635   n = clib_net_to_host_u32 (mp->count);
3636
3637   for (i = 0; i < n; i++)
3638     {
3639       r = &mp->entries[i];
3640       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3641              clib_net_to_host_u32 (r->fib_index),
3642              clib_net_to_host_u32 (r->nh_sw_if_index),
3643              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3644     }
3645
3646 end:
3647   vam->retval = retval;
3648   vam->result_ready = 1;
3649 }
3650
3651 static void
3652   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3653   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3654 {
3655   vat_main_t *vam = &vat_main;
3656   vat_json_node_t root, *e;
3657   u32 i, n;
3658   int retval = clib_net_to_host_u32 (mp->retval);
3659   vl_api_gpe_native_fwd_rpath_t *r;
3660   u8 *s;
3661
3662   if (retval)
3663     goto end;
3664
3665   n = clib_net_to_host_u32 (mp->count);
3666   vat_json_init_array (&root);
3667
3668   for (i = 0; i < n; i++)
3669     {
3670       e = vat_json_array_add (&root);
3671       vat_json_init_object (e);
3672       r = &mp->entries[i];
3673       s =
3674         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3675                 r->nh_addr);
3676       vec_add1 (s, 0);
3677       vat_json_object_add_string_copy (e, "ip4", s);
3678       vec_free (s);
3679
3680       vat_json_object_add_uint (e, "fib_index",
3681                                 clib_net_to_host_u32 (r->fib_index));
3682       vat_json_object_add_uint (e, "nh_sw_if_index",
3683                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3684     }
3685
3686   vat_json_print (vam->ofp, &root);
3687   vat_json_free (&root);
3688
3689 end:
3690   vam->retval = retval;
3691   vam->result_ready = 1;
3692 }
3693
3694 static void
3695   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3696   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3697 {
3698   vat_main_t *vam = &vat_main;
3699   u32 i, n;
3700   int retval = clib_net_to_host_u32 (mp->retval);
3701
3702   if (retval)
3703     goto end;
3704
3705   n = clib_net_to_host_u32 (mp->count);
3706
3707   for (i = 0; i < n; i++)
3708     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3709
3710 end:
3711   vam->retval = retval;
3712   vam->result_ready = 1;
3713 }
3714
3715 static void
3716   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3717   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3718 {
3719   vat_main_t *vam = &vat_main;
3720   vat_json_node_t root;
3721   u32 i, n;
3722   int retval = clib_net_to_host_u32 (mp->retval);
3723
3724   if (retval)
3725     goto end;
3726
3727   n = clib_net_to_host_u32 (mp->count);
3728   vat_json_init_array (&root);
3729
3730   for (i = 0; i < n; i++)
3731     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3732
3733   vat_json_print (vam->ofp, &root);
3734   vat_json_free (&root);
3735
3736 end:
3737   vam->retval = retval;
3738   vam->result_ready = 1;
3739 }
3740
3741 static void
3742   vl_api_one_ndp_entries_get_reply_t_handler
3743   (vl_api_one_ndp_entries_get_reply_t * mp)
3744 {
3745   vat_main_t *vam = &vat_main;
3746   u32 i, n;
3747   int retval = clib_net_to_host_u32 (mp->retval);
3748
3749   if (retval)
3750     goto end;
3751
3752   n = clib_net_to_host_u32 (mp->count);
3753
3754   for (i = 0; i < n; i++)
3755     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3756            format_ethernet_address, mp->entries[i].mac);
3757
3758 end:
3759   vam->retval = retval;
3760   vam->result_ready = 1;
3761 }
3762
3763 static void
3764   vl_api_one_ndp_entries_get_reply_t_handler_json
3765   (vl_api_one_ndp_entries_get_reply_t * mp)
3766 {
3767   u8 *s = 0;
3768   vat_main_t *vam = &vat_main;
3769   vat_json_node_t *e = 0, root;
3770   u32 i, n;
3771   int retval = clib_net_to_host_u32 (mp->retval);
3772   vl_api_one_ndp_entry_t *arp_entry;
3773
3774   if (retval)
3775     goto end;
3776
3777   n = clib_net_to_host_u32 (mp->count);
3778   vat_json_init_array (&root);
3779
3780   for (i = 0; i < n; i++)
3781     {
3782       e = vat_json_array_add (&root);
3783       arp_entry = &mp->entries[i];
3784
3785       vat_json_init_object (e);
3786       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3787       vec_add1 (s, 0);
3788
3789       vat_json_object_add_string_copy (e, "mac", s);
3790       vec_free (s);
3791
3792       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3793       vec_add1 (s, 0);
3794       vat_json_object_add_string_copy (e, "ip6", s);
3795       vec_free (s);
3796     }
3797
3798   vat_json_print (vam->ofp, &root);
3799   vat_json_free (&root);
3800
3801 end:
3802   vam->retval = retval;
3803   vam->result_ready = 1;
3804 }
3805
3806 static void
3807   vl_api_one_l2_arp_entries_get_reply_t_handler
3808   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3809 {
3810   vat_main_t *vam = &vat_main;
3811   u32 i, n;
3812   int retval = clib_net_to_host_u32 (mp->retval);
3813
3814   if (retval)
3815     goto end;
3816
3817   n = clib_net_to_host_u32 (mp->count);
3818
3819   for (i = 0; i < n; i++)
3820     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3821            format_ethernet_address, mp->entries[i].mac);
3822
3823 end:
3824   vam->retval = retval;
3825   vam->result_ready = 1;
3826 }
3827
3828 static void
3829   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3830   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3831 {
3832   u8 *s = 0;
3833   vat_main_t *vam = &vat_main;
3834   vat_json_node_t *e = 0, root;
3835   u32 i, n;
3836   int retval = clib_net_to_host_u32 (mp->retval);
3837   vl_api_one_l2_arp_entry_t *arp_entry;
3838
3839   if (retval)
3840     goto end;
3841
3842   n = clib_net_to_host_u32 (mp->count);
3843   vat_json_init_array (&root);
3844
3845   for (i = 0; i < n; i++)
3846     {
3847       e = vat_json_array_add (&root);
3848       arp_entry = &mp->entries[i];
3849
3850       vat_json_init_object (e);
3851       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3852       vec_add1 (s, 0);
3853
3854       vat_json_object_add_string_copy (e, "mac", s);
3855       vec_free (s);
3856
3857       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3858       vec_add1 (s, 0);
3859       vat_json_object_add_string_copy (e, "ip4", s);
3860       vec_free (s);
3861     }
3862
3863   vat_json_print (vam->ofp, &root);
3864   vat_json_free (&root);
3865
3866 end:
3867   vam->retval = retval;
3868   vam->result_ready = 1;
3869 }
3870
3871 static void
3872 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3873 {
3874   vat_main_t *vam = &vat_main;
3875   u32 i, n;
3876   int retval = clib_net_to_host_u32 (mp->retval);
3877
3878   if (retval)
3879     goto end;
3880
3881   n = clib_net_to_host_u32 (mp->count);
3882
3883   for (i = 0; i < n; i++)
3884     {
3885       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3886     }
3887
3888 end:
3889   vam->retval = retval;
3890   vam->result_ready = 1;
3891 }
3892
3893 static void
3894   vl_api_one_ndp_bd_get_reply_t_handler_json
3895   (vl_api_one_ndp_bd_get_reply_t * mp)
3896 {
3897   vat_main_t *vam = &vat_main;
3898   vat_json_node_t root;
3899   u32 i, n;
3900   int retval = clib_net_to_host_u32 (mp->retval);
3901
3902   if (retval)
3903     goto end;
3904
3905   n = clib_net_to_host_u32 (mp->count);
3906   vat_json_init_array (&root);
3907
3908   for (i = 0; i < n; i++)
3909     {
3910       vat_json_array_add_uint (&root,
3911                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3912     }
3913
3914   vat_json_print (vam->ofp, &root);
3915   vat_json_free (&root);
3916
3917 end:
3918   vam->retval = retval;
3919   vam->result_ready = 1;
3920 }
3921
3922 static void
3923   vl_api_one_l2_arp_bd_get_reply_t_handler
3924   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3925 {
3926   vat_main_t *vam = &vat_main;
3927   u32 i, n;
3928   int retval = clib_net_to_host_u32 (mp->retval);
3929
3930   if (retval)
3931     goto end;
3932
3933   n = clib_net_to_host_u32 (mp->count);
3934
3935   for (i = 0; i < n; i++)
3936     {
3937       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3938     }
3939
3940 end:
3941   vam->retval = retval;
3942   vam->result_ready = 1;
3943 }
3944
3945 static void
3946   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3947   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3948 {
3949   vat_main_t *vam = &vat_main;
3950   vat_json_node_t root;
3951   u32 i, n;
3952   int retval = clib_net_to_host_u32 (mp->retval);
3953
3954   if (retval)
3955     goto end;
3956
3957   n = clib_net_to_host_u32 (mp->count);
3958   vat_json_init_array (&root);
3959
3960   for (i = 0; i < n; i++)
3961     {
3962       vat_json_array_add_uint (&root,
3963                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3964     }
3965
3966   vat_json_print (vam->ofp, &root);
3967   vat_json_free (&root);
3968
3969 end:
3970   vam->retval = retval;
3971   vam->result_ready = 1;
3972 }
3973
3974 static void
3975   vl_api_one_adjacencies_get_reply_t_handler
3976   (vl_api_one_adjacencies_get_reply_t * mp)
3977 {
3978   vat_main_t *vam = &vat_main;
3979   u32 i, n;
3980   int retval = clib_net_to_host_u32 (mp->retval);
3981   vl_api_one_adjacency_t *a;
3982
3983   if (retval)
3984     goto end;
3985
3986   n = clib_net_to_host_u32 (mp->count);
3987
3988   for (i = 0; i < n; i++)
3989     {
3990       a = &mp->adjacencies[i];
3991       print (vam->ofp, "%U %40U",
3992              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3993              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3994     }
3995
3996 end:
3997   vam->retval = retval;
3998   vam->result_ready = 1;
3999 }
4000
4001 static void
4002   vl_api_one_adjacencies_get_reply_t_handler_json
4003   (vl_api_one_adjacencies_get_reply_t * mp)
4004 {
4005   u8 *s = 0;
4006   vat_main_t *vam = &vat_main;
4007   vat_json_node_t *e = 0, root;
4008   u32 i, n;
4009   int retval = clib_net_to_host_u32 (mp->retval);
4010   vl_api_one_adjacency_t *a;
4011
4012   if (retval)
4013     goto end;
4014
4015   n = clib_net_to_host_u32 (mp->count);
4016   vat_json_init_array (&root);
4017
4018   for (i = 0; i < n; i++)
4019     {
4020       e = vat_json_array_add (&root);
4021       a = &mp->adjacencies[i];
4022
4023       vat_json_init_object (e);
4024       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4025                   a->leid_prefix_len);
4026       vec_add1 (s, 0);
4027       vat_json_object_add_string_copy (e, "leid", s);
4028       vec_free (s);
4029
4030       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4031                   a->reid_prefix_len);
4032       vec_add1 (s, 0);
4033       vat_json_object_add_string_copy (e, "reid", s);
4034       vec_free (s);
4035     }
4036
4037   vat_json_print (vam->ofp, &root);
4038   vat_json_free (&root);
4039
4040 end:
4041   vam->retval = retval;
4042   vam->result_ready = 1;
4043 }
4044
4045 static void
4046 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4047 {
4048   vat_main_t *vam = &vat_main;
4049
4050   print (vam->ofp, "%=20U",
4051          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4052          mp->ip_address);
4053 }
4054
4055 static void
4056   vl_api_one_map_server_details_t_handler_json
4057   (vl_api_one_map_server_details_t * mp)
4058 {
4059   vat_main_t *vam = &vat_main;
4060   vat_json_node_t *node = NULL;
4061   struct in6_addr ip6;
4062   struct in_addr ip4;
4063
4064   if (VAT_JSON_ARRAY != vam->json_tree.type)
4065     {
4066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4067       vat_json_init_array (&vam->json_tree);
4068     }
4069   node = vat_json_array_add (&vam->json_tree);
4070
4071   vat_json_init_object (node);
4072   if (mp->is_ipv6)
4073     {
4074       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4075       vat_json_object_add_ip6 (node, "map-server", ip6);
4076     }
4077   else
4078     {
4079       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4080       vat_json_object_add_ip4 (node, "map-server", ip4);
4081     }
4082 }
4083
4084 static void
4085 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4086                                            * mp)
4087 {
4088   vat_main_t *vam = &vat_main;
4089
4090   print (vam->ofp, "%=20U",
4091          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4092          mp->ip_address);
4093 }
4094
4095 static void
4096   vl_api_one_map_resolver_details_t_handler_json
4097   (vl_api_one_map_resolver_details_t * mp)
4098 {
4099   vat_main_t *vam = &vat_main;
4100   vat_json_node_t *node = NULL;
4101   struct in6_addr ip6;
4102   struct in_addr ip4;
4103
4104   if (VAT_JSON_ARRAY != vam->json_tree.type)
4105     {
4106       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4107       vat_json_init_array (&vam->json_tree);
4108     }
4109   node = vat_json_array_add (&vam->json_tree);
4110
4111   vat_json_init_object (node);
4112   if (mp->is_ipv6)
4113     {
4114       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4115       vat_json_object_add_ip6 (node, "map resolver", ip6);
4116     }
4117   else
4118     {
4119       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4120       vat_json_object_add_ip4 (node, "map resolver", ip4);
4121     }
4122 }
4123
4124 static void
4125 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4126 {
4127   vat_main_t *vam = &vat_main;
4128   i32 retval = ntohl (mp->retval);
4129
4130   if (0 <= retval)
4131     {
4132       print (vam->ofp, "feature: %s\ngpe: %s",
4133              mp->feature_status ? "enabled" : "disabled",
4134              mp->gpe_status ? "enabled" : "disabled");
4135     }
4136
4137   vam->retval = retval;
4138   vam->result_ready = 1;
4139 }
4140
4141 static void
4142   vl_api_show_one_status_reply_t_handler_json
4143   (vl_api_show_one_status_reply_t * mp)
4144 {
4145   vat_main_t *vam = &vat_main;
4146   vat_json_node_t node;
4147   u8 *gpe_status = NULL;
4148   u8 *feature_status = NULL;
4149
4150   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4151   feature_status = format (0, "%s",
4152                            mp->feature_status ? "enabled" : "disabled");
4153   vec_add1 (gpe_status, 0);
4154   vec_add1 (feature_status, 0);
4155
4156   vat_json_init_object (&node);
4157   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4158   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4159
4160   vec_free (gpe_status);
4161   vec_free (feature_status);
4162
4163   vat_json_print (vam->ofp, &node);
4164   vat_json_free (&node);
4165
4166   vam->retval = ntohl (mp->retval);
4167   vam->result_ready = 1;
4168 }
4169
4170 static void
4171   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4172   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4173 {
4174   vat_main_t *vam = &vat_main;
4175   i32 retval = ntohl (mp->retval);
4176
4177   if (retval >= 0)
4178     {
4179       print (vam->ofp, "%=20s", mp->locator_set_name);
4180     }
4181
4182   vam->retval = retval;
4183   vam->result_ready = 1;
4184 }
4185
4186 static void
4187   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4188   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4189 {
4190   vat_main_t *vam = &vat_main;
4191   vat_json_node_t *node = NULL;
4192
4193   if (VAT_JSON_ARRAY != vam->json_tree.type)
4194     {
4195       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4196       vat_json_init_array (&vam->json_tree);
4197     }
4198   node = vat_json_array_add (&vam->json_tree);
4199
4200   vat_json_init_object (node);
4201   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4202
4203   vat_json_print (vam->ofp, node);
4204   vat_json_free (node);
4205
4206   vam->retval = ntohl (mp->retval);
4207   vam->result_ready = 1;
4208 }
4209
4210 static u8 *
4211 format_lisp_map_request_mode (u8 * s, va_list * args)
4212 {
4213   u32 mode = va_arg (*args, u32);
4214
4215   switch (mode)
4216     {
4217     case 0:
4218       return format (0, "dst-only");
4219     case 1:
4220       return format (0, "src-dst");
4221     }
4222   return 0;
4223 }
4224
4225 static void
4226   vl_api_show_one_map_request_mode_reply_t_handler
4227   (vl_api_show_one_map_request_mode_reply_t * mp)
4228 {
4229   vat_main_t *vam = &vat_main;
4230   i32 retval = ntohl (mp->retval);
4231
4232   if (0 <= retval)
4233     {
4234       u32 mode = mp->mode;
4235       print (vam->ofp, "map_request_mode: %U",
4236              format_lisp_map_request_mode, mode);
4237     }
4238
4239   vam->retval = retval;
4240   vam->result_ready = 1;
4241 }
4242
4243 static void
4244   vl_api_show_one_map_request_mode_reply_t_handler_json
4245   (vl_api_show_one_map_request_mode_reply_t * mp)
4246 {
4247   vat_main_t *vam = &vat_main;
4248   vat_json_node_t node;
4249   u8 *s = 0;
4250   u32 mode;
4251
4252   mode = mp->mode;
4253   s = format (0, "%U", format_lisp_map_request_mode, mode);
4254   vec_add1 (s, 0);
4255
4256   vat_json_init_object (&node);
4257   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4258   vat_json_print (vam->ofp, &node);
4259   vat_json_free (&node);
4260
4261   vec_free (s);
4262   vam->retval = ntohl (mp->retval);
4263   vam->result_ready = 1;
4264 }
4265
4266 static void
4267   vl_api_one_show_xtr_mode_reply_t_handler
4268   (vl_api_one_show_xtr_mode_reply_t * mp)
4269 {
4270   vat_main_t *vam = &vat_main;
4271   i32 retval = ntohl (mp->retval);
4272
4273   if (0 <= retval)
4274     {
4275       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4276     }
4277
4278   vam->retval = retval;
4279   vam->result_ready = 1;
4280 }
4281
4282 static void
4283   vl_api_one_show_xtr_mode_reply_t_handler_json
4284   (vl_api_one_show_xtr_mode_reply_t * mp)
4285 {
4286   vat_main_t *vam = &vat_main;
4287   vat_json_node_t node;
4288   u8 *status = 0;
4289
4290   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4291   vec_add1 (status, 0);
4292
4293   vat_json_init_object (&node);
4294   vat_json_object_add_string_copy (&node, "status", status);
4295
4296   vec_free (status);
4297
4298   vat_json_print (vam->ofp, &node);
4299   vat_json_free (&node);
4300
4301   vam->retval = ntohl (mp->retval);
4302   vam->result_ready = 1;
4303 }
4304
4305 static void
4306   vl_api_one_show_pitr_mode_reply_t_handler
4307   (vl_api_one_show_pitr_mode_reply_t * mp)
4308 {
4309   vat_main_t *vam = &vat_main;
4310   i32 retval = ntohl (mp->retval);
4311
4312   if (0 <= retval)
4313     {
4314       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4315     }
4316
4317   vam->retval = retval;
4318   vam->result_ready = 1;
4319 }
4320
4321 static void
4322   vl_api_one_show_pitr_mode_reply_t_handler_json
4323   (vl_api_one_show_pitr_mode_reply_t * mp)
4324 {
4325   vat_main_t *vam = &vat_main;
4326   vat_json_node_t node;
4327   u8 *status = 0;
4328
4329   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4330   vec_add1 (status, 0);
4331
4332   vat_json_init_object (&node);
4333   vat_json_object_add_string_copy (&node, "status", status);
4334
4335   vec_free (status);
4336
4337   vat_json_print (vam->ofp, &node);
4338   vat_json_free (&node);
4339
4340   vam->retval = ntohl (mp->retval);
4341   vam->result_ready = 1;
4342 }
4343
4344 static void
4345   vl_api_one_show_petr_mode_reply_t_handler
4346   (vl_api_one_show_petr_mode_reply_t * mp)
4347 {
4348   vat_main_t *vam = &vat_main;
4349   i32 retval = ntohl (mp->retval);
4350
4351   if (0 <= retval)
4352     {
4353       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4354     }
4355
4356   vam->retval = retval;
4357   vam->result_ready = 1;
4358 }
4359
4360 static void
4361   vl_api_one_show_petr_mode_reply_t_handler_json
4362   (vl_api_one_show_petr_mode_reply_t * mp)
4363 {
4364   vat_main_t *vam = &vat_main;
4365   vat_json_node_t node;
4366   u8 *status = 0;
4367
4368   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4369   vec_add1 (status, 0);
4370
4371   vat_json_init_object (&node);
4372   vat_json_object_add_string_copy (&node, "status", status);
4373
4374   vec_free (status);
4375
4376   vat_json_print (vam->ofp, &node);
4377   vat_json_free (&node);
4378
4379   vam->retval = ntohl (mp->retval);
4380   vam->result_ready = 1;
4381 }
4382
4383 static void
4384   vl_api_show_one_use_petr_reply_t_handler
4385   (vl_api_show_one_use_petr_reply_t * mp)
4386 {
4387   vat_main_t *vam = &vat_main;
4388   i32 retval = ntohl (mp->retval);
4389
4390   if (0 <= retval)
4391     {
4392       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4393       if (mp->status)
4394         {
4395           print (vam->ofp, "Proxy-ETR address; %U",
4396                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4397                  mp->address);
4398         }
4399     }
4400
4401   vam->retval = retval;
4402   vam->result_ready = 1;
4403 }
4404
4405 static void
4406   vl_api_show_one_use_petr_reply_t_handler_json
4407   (vl_api_show_one_use_petr_reply_t * mp)
4408 {
4409   vat_main_t *vam = &vat_main;
4410   vat_json_node_t node;
4411   u8 *status = 0;
4412   struct in_addr ip4;
4413   struct in6_addr ip6;
4414
4415   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4416   vec_add1 (status, 0);
4417
4418   vat_json_init_object (&node);
4419   vat_json_object_add_string_copy (&node, "status", status);
4420   if (mp->status)
4421     {
4422       if (mp->is_ip4)
4423         {
4424           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4425           vat_json_object_add_ip6 (&node, "address", ip6);
4426         }
4427       else
4428         {
4429           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4430           vat_json_object_add_ip4 (&node, "address", ip4);
4431         }
4432     }
4433
4434   vec_free (status);
4435
4436   vat_json_print (vam->ofp, &node);
4437   vat_json_free (&node);
4438
4439   vam->retval = ntohl (mp->retval);
4440   vam->result_ready = 1;
4441 }
4442
4443 static void
4444   vl_api_show_one_nsh_mapping_reply_t_handler
4445   (vl_api_show_one_nsh_mapping_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   i32 retval = ntohl (mp->retval);
4449
4450   if (0 <= retval)
4451     {
4452       print (vam->ofp, "%-20s%-16s",
4453              mp->is_set ? "set" : "not-set",
4454              mp->is_set ? (char *) mp->locator_set_name : "");
4455     }
4456
4457   vam->retval = retval;
4458   vam->result_ready = 1;
4459 }
4460
4461 static void
4462   vl_api_show_one_nsh_mapping_reply_t_handler_json
4463   (vl_api_show_one_nsh_mapping_reply_t * mp)
4464 {
4465   vat_main_t *vam = &vat_main;
4466   vat_json_node_t node;
4467   u8 *status = 0;
4468
4469   status = format (0, "%s", mp->is_set ? "yes" : "no");
4470   vec_add1 (status, 0);
4471
4472   vat_json_init_object (&node);
4473   vat_json_object_add_string_copy (&node, "is_set", status);
4474   if (mp->is_set)
4475     {
4476       vat_json_object_add_string_copy (&node, "locator_set",
4477                                        mp->locator_set_name);
4478     }
4479
4480   vec_free (status);
4481
4482   vat_json_print (vam->ofp, &node);
4483   vat_json_free (&node);
4484
4485   vam->retval = ntohl (mp->retval);
4486   vam->result_ready = 1;
4487 }
4488
4489 static void
4490   vl_api_show_one_map_register_ttl_reply_t_handler
4491   (vl_api_show_one_map_register_ttl_reply_t * mp)
4492 {
4493   vat_main_t *vam = &vat_main;
4494   i32 retval = ntohl (mp->retval);
4495
4496   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4497
4498   if (0 <= retval)
4499     {
4500       print (vam->ofp, "ttl: %u", mp->ttl);
4501     }
4502
4503   vam->retval = retval;
4504   vam->result_ready = 1;
4505 }
4506
4507 static void
4508   vl_api_show_one_map_register_ttl_reply_t_handler_json
4509   (vl_api_show_one_map_register_ttl_reply_t * mp)
4510 {
4511   vat_main_t *vam = &vat_main;
4512   vat_json_node_t node;
4513
4514   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4515   vat_json_init_object (&node);
4516   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4517
4518   vat_json_print (vam->ofp, &node);
4519   vat_json_free (&node);
4520
4521   vam->retval = ntohl (mp->retval);
4522   vam->result_ready = 1;
4523 }
4524
4525 static void
4526 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4527 {
4528   vat_main_t *vam = &vat_main;
4529   i32 retval = ntohl (mp->retval);
4530
4531   if (0 <= retval)
4532     {
4533       print (vam->ofp, "%-20s%-16s",
4534              mp->status ? "enabled" : "disabled",
4535              mp->status ? (char *) mp->locator_set_name : "");
4536     }
4537
4538   vam->retval = retval;
4539   vam->result_ready = 1;
4540 }
4541
4542 static void
4543 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4544 {
4545   vat_main_t *vam = &vat_main;
4546   vat_json_node_t node;
4547   u8 *status = 0;
4548
4549   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4550   vec_add1 (status, 0);
4551
4552   vat_json_init_object (&node);
4553   vat_json_object_add_string_copy (&node, "status", status);
4554   if (mp->status)
4555     {
4556       vat_json_object_add_string_copy (&node, "locator_set",
4557                                        mp->locator_set_name);
4558     }
4559
4560   vec_free (status);
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   vam->retval = ntohl (mp->retval);
4566   vam->result_ready = 1;
4567 }
4568
4569 static u8 *
4570 format_policer_type (u8 * s, va_list * va)
4571 {
4572   u32 i = va_arg (*va, u32);
4573
4574   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4575     s = format (s, "1r2c");
4576   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4577     s = format (s, "1r3c");
4578   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4579     s = format (s, "2r3c-2698");
4580   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4581     s = format (s, "2r3c-4115");
4582   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4583     s = format (s, "2r3c-mef5cf1");
4584   else
4585     s = format (s, "ILLEGAL");
4586   return s;
4587 }
4588
4589 static u8 *
4590 format_policer_rate_type (u8 * s, va_list * va)
4591 {
4592   u32 i = va_arg (*va, u32);
4593
4594   if (i == SSE2_QOS_RATE_KBPS)
4595     s = format (s, "kbps");
4596   else if (i == SSE2_QOS_RATE_PPS)
4597     s = format (s, "pps");
4598   else
4599     s = format (s, "ILLEGAL");
4600   return s;
4601 }
4602
4603 static u8 *
4604 format_policer_round_type (u8 * s, va_list * va)
4605 {
4606   u32 i = va_arg (*va, u32);
4607
4608   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4609     s = format (s, "closest");
4610   else if (i == SSE2_QOS_ROUND_TO_UP)
4611     s = format (s, "up");
4612   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4613     s = format (s, "down");
4614   else
4615     s = format (s, "ILLEGAL");
4616   return s;
4617 }
4618
4619 static u8 *
4620 format_policer_action_type (u8 * s, va_list * va)
4621 {
4622   u32 i = va_arg (*va, u32);
4623
4624   if (i == SSE2_QOS_ACTION_DROP)
4625     s = format (s, "drop");
4626   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4627     s = format (s, "transmit");
4628   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4629     s = format (s, "mark-and-transmit");
4630   else
4631     s = format (s, "ILLEGAL");
4632   return s;
4633 }
4634
4635 static u8 *
4636 format_dscp (u8 * s, va_list * va)
4637 {
4638   u32 i = va_arg (*va, u32);
4639   char *t = 0;
4640
4641   switch (i)
4642     {
4643 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4644       foreach_vnet_dscp
4645 #undef _
4646     default:
4647       return format (s, "ILLEGAL");
4648     }
4649   s = format (s, "%s", t);
4650   return s;
4651 }
4652
4653 static void
4654 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4655 {
4656   vat_main_t *vam = &vat_main;
4657   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4658
4659   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4660     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4661   else
4662     conform_dscp_str = format (0, "");
4663
4664   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4665     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4666   else
4667     exceed_dscp_str = format (0, "");
4668
4669   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4670     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4671   else
4672     violate_dscp_str = format (0, "");
4673
4674   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4675          "rate type %U, round type %U, %s rate, %s color-aware, "
4676          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4677          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4678          "conform action %U%s, exceed action %U%s, violate action %U%s",
4679          mp->name,
4680          format_policer_type, mp->type,
4681          ntohl (mp->cir),
4682          ntohl (mp->eir),
4683          clib_net_to_host_u64 (mp->cb),
4684          clib_net_to_host_u64 (mp->eb),
4685          format_policer_rate_type, mp->rate_type,
4686          format_policer_round_type, mp->round_type,
4687          mp->single_rate ? "single" : "dual",
4688          mp->color_aware ? "is" : "not",
4689          ntohl (mp->cir_tokens_per_period),
4690          ntohl (mp->pir_tokens_per_period),
4691          ntohl (mp->scale),
4692          ntohl (mp->current_limit),
4693          ntohl (mp->current_bucket),
4694          ntohl (mp->extended_limit),
4695          ntohl (mp->extended_bucket),
4696          clib_net_to_host_u64 (mp->last_update_time),
4697          format_policer_action_type, mp->conform_action_type,
4698          conform_dscp_str,
4699          format_policer_action_type, mp->exceed_action_type,
4700          exceed_dscp_str,
4701          format_policer_action_type, mp->violate_action_type,
4702          violate_dscp_str);
4703
4704   vec_free (conform_dscp_str);
4705   vec_free (exceed_dscp_str);
4706   vec_free (violate_dscp_str);
4707 }
4708
4709 static void vl_api_policer_details_t_handler_json
4710   (vl_api_policer_details_t * mp)
4711 {
4712   vat_main_t *vam = &vat_main;
4713   vat_json_node_t *node;
4714   u8 *rate_type_str, *round_type_str, *type_str;
4715   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4716
4717   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4718   round_type_str =
4719     format (0, "%U", format_policer_round_type, mp->round_type);
4720   type_str = format (0, "%U", format_policer_type, mp->type);
4721   conform_action_str = format (0, "%U", format_policer_action_type,
4722                                mp->conform_action_type);
4723   exceed_action_str = format (0, "%U", format_policer_action_type,
4724                               mp->exceed_action_type);
4725   violate_action_str = format (0, "%U", format_policer_action_type,
4726                                mp->violate_action_type);
4727
4728   if (VAT_JSON_ARRAY != vam->json_tree.type)
4729     {
4730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4731       vat_json_init_array (&vam->json_tree);
4732     }
4733   node = vat_json_array_add (&vam->json_tree);
4734
4735   vat_json_init_object (node);
4736   vat_json_object_add_string_copy (node, "name", mp->name);
4737   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4738   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4739   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4740   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4741   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4742   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4743   vat_json_object_add_string_copy (node, "type", type_str);
4744   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4745   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4746   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4747   vat_json_object_add_uint (node, "cir_tokens_per_period",
4748                             ntohl (mp->cir_tokens_per_period));
4749   vat_json_object_add_uint (node, "eir_tokens_per_period",
4750                             ntohl (mp->pir_tokens_per_period));
4751   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4752   vat_json_object_add_uint (node, "current_bucket",
4753                             ntohl (mp->current_bucket));
4754   vat_json_object_add_uint (node, "extended_limit",
4755                             ntohl (mp->extended_limit));
4756   vat_json_object_add_uint (node, "extended_bucket",
4757                             ntohl (mp->extended_bucket));
4758   vat_json_object_add_uint (node, "last_update_time",
4759                             ntohl (mp->last_update_time));
4760   vat_json_object_add_string_copy (node, "conform_action",
4761                                    conform_action_str);
4762   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4763     {
4764       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4765       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4766       vec_free (dscp_str);
4767     }
4768   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4769   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4770     {
4771       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4772       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4773       vec_free (dscp_str);
4774     }
4775   vat_json_object_add_string_copy (node, "violate_action",
4776                                    violate_action_str);
4777   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4778     {
4779       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4780       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4781       vec_free (dscp_str);
4782     }
4783
4784   vec_free (rate_type_str);
4785   vec_free (round_type_str);
4786   vec_free (type_str);
4787   vec_free (conform_action_str);
4788   vec_free (exceed_action_str);
4789   vec_free (violate_action_str);
4790 }
4791
4792 static void
4793 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4794                                            mp)
4795 {
4796   vat_main_t *vam = &vat_main;
4797   int i, count = ntohl (mp->count);
4798
4799   if (count > 0)
4800     print (vam->ofp, "classify table ids (%d) : ", count);
4801   for (i = 0; i < count; i++)
4802     {
4803       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4804       print (vam->ofp, (i < count - 1) ? "," : "");
4805     }
4806   vam->retval = ntohl (mp->retval);
4807   vam->result_ready = 1;
4808 }
4809
4810 static void
4811   vl_api_classify_table_ids_reply_t_handler_json
4812   (vl_api_classify_table_ids_reply_t * mp)
4813 {
4814   vat_main_t *vam = &vat_main;
4815   int i, count = ntohl (mp->count);
4816
4817   if (count > 0)
4818     {
4819       vat_json_node_t node;
4820
4821       vat_json_init_object (&node);
4822       for (i = 0; i < count; i++)
4823         {
4824           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4825         }
4826       vat_json_print (vam->ofp, &node);
4827       vat_json_free (&node);
4828     }
4829   vam->retval = ntohl (mp->retval);
4830   vam->result_ready = 1;
4831 }
4832
4833 static void
4834   vl_api_classify_table_by_interface_reply_t_handler
4835   (vl_api_classify_table_by_interface_reply_t * mp)
4836 {
4837   vat_main_t *vam = &vat_main;
4838   u32 table_id;
4839
4840   table_id = ntohl (mp->l2_table_id);
4841   if (table_id != ~0)
4842     print (vam->ofp, "l2 table id : %d", table_id);
4843   else
4844     print (vam->ofp, "l2 table id : No input ACL tables configured");
4845   table_id = ntohl (mp->ip4_table_id);
4846   if (table_id != ~0)
4847     print (vam->ofp, "ip4 table id : %d", table_id);
4848   else
4849     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4850   table_id = ntohl (mp->ip6_table_id);
4851   if (table_id != ~0)
4852     print (vam->ofp, "ip6 table id : %d", table_id);
4853   else
4854     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4855   vam->retval = ntohl (mp->retval);
4856   vam->result_ready = 1;
4857 }
4858
4859 static void
4860   vl_api_classify_table_by_interface_reply_t_handler_json
4861   (vl_api_classify_table_by_interface_reply_t * mp)
4862 {
4863   vat_main_t *vam = &vat_main;
4864   vat_json_node_t node;
4865
4866   vat_json_init_object (&node);
4867
4868   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4869   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4870   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4871
4872   vat_json_print (vam->ofp, &node);
4873   vat_json_free (&node);
4874
4875   vam->retval = ntohl (mp->retval);
4876   vam->result_ready = 1;
4877 }
4878
4879 static void vl_api_policer_add_del_reply_t_handler
4880   (vl_api_policer_add_del_reply_t * mp)
4881 {
4882   vat_main_t *vam = &vat_main;
4883   i32 retval = ntohl (mp->retval);
4884   if (vam->async_mode)
4885     {
4886       vam->async_errors += (retval < 0);
4887     }
4888   else
4889     {
4890       vam->retval = retval;
4891       vam->result_ready = 1;
4892       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4893         /*
4894          * Note: this is just barely thread-safe, depends on
4895          * the main thread spinning waiting for an answer...
4896          */
4897         errmsg ("policer index %d", ntohl (mp->policer_index));
4898     }
4899 }
4900
4901 static void vl_api_policer_add_del_reply_t_handler_json
4902   (vl_api_policer_add_del_reply_t * mp)
4903 {
4904   vat_main_t *vam = &vat_main;
4905   vat_json_node_t node;
4906
4907   vat_json_init_object (&node);
4908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4909   vat_json_object_add_uint (&node, "policer_index",
4910                             ntohl (mp->policer_index));
4911
4912   vat_json_print (vam->ofp, &node);
4913   vat_json_free (&node);
4914
4915   vam->retval = ntohl (mp->retval);
4916   vam->result_ready = 1;
4917 }
4918
4919 /* Format hex dump. */
4920 u8 *
4921 format_hex_bytes (u8 * s, va_list * va)
4922 {
4923   u8 *bytes = va_arg (*va, u8 *);
4924   int n_bytes = va_arg (*va, int);
4925   uword i;
4926
4927   /* Print short or long form depending on byte count. */
4928   uword short_form = n_bytes <= 32;
4929   u32 indent = format_get_indent (s);
4930
4931   if (n_bytes == 0)
4932     return s;
4933
4934   for (i = 0; i < n_bytes; i++)
4935     {
4936       if (!short_form && (i % 32) == 0)
4937         s = format (s, "%08x: ", i);
4938       s = format (s, "%02x", bytes[i]);
4939       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4940         s = format (s, "\n%U", format_white_space, indent);
4941     }
4942
4943   return s;
4944 }
4945
4946 static void
4947 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4948                                             * mp)
4949 {
4950   vat_main_t *vam = &vat_main;
4951   i32 retval = ntohl (mp->retval);
4952   if (retval == 0)
4953     {
4954       print (vam->ofp, "classify table info :");
4955       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4956              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4957              ntohl (mp->miss_next_index));
4958       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4959              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4960              ntohl (mp->match_n_vectors));
4961       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4962              ntohl (mp->mask_length));
4963     }
4964   vam->retval = retval;
4965   vam->result_ready = 1;
4966 }
4967
4968 static void
4969   vl_api_classify_table_info_reply_t_handler_json
4970   (vl_api_classify_table_info_reply_t * mp)
4971 {
4972   vat_main_t *vam = &vat_main;
4973   vat_json_node_t node;
4974
4975   i32 retval = ntohl (mp->retval);
4976   if (retval == 0)
4977     {
4978       vat_json_init_object (&node);
4979
4980       vat_json_object_add_int (&node, "sessions",
4981                                ntohl (mp->active_sessions));
4982       vat_json_object_add_int (&node, "nexttbl",
4983                                ntohl (mp->next_table_index));
4984       vat_json_object_add_int (&node, "nextnode",
4985                                ntohl (mp->miss_next_index));
4986       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4987       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4988       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4989       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4990                       ntohl (mp->mask_length), 0);
4991       vat_json_object_add_string_copy (&node, "mask", s);
4992
4993       vat_json_print (vam->ofp, &node);
4994       vat_json_free (&node);
4995     }
4996   vam->retval = ntohl (mp->retval);
4997   vam->result_ready = 1;
4998 }
4999
5000 static void
5001 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5002                                            mp)
5003 {
5004   vat_main_t *vam = &vat_main;
5005
5006   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5007          ntohl (mp->hit_next_index), ntohl (mp->advance),
5008          ntohl (mp->opaque_index));
5009   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5010          ntohl (mp->match_length));
5011 }
5012
5013 static void
5014   vl_api_classify_session_details_t_handler_json
5015   (vl_api_classify_session_details_t * mp)
5016 {
5017   vat_main_t *vam = &vat_main;
5018   vat_json_node_t *node = NULL;
5019
5020   if (VAT_JSON_ARRAY != vam->json_tree.type)
5021     {
5022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5023       vat_json_init_array (&vam->json_tree);
5024     }
5025   node = vat_json_array_add (&vam->json_tree);
5026
5027   vat_json_init_object (node);
5028   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5029   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5030   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5031   u8 *s =
5032     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5033             0);
5034   vat_json_object_add_string_copy (node, "match", s);
5035 }
5036
5037 static void vl_api_pg_create_interface_reply_t_handler
5038   (vl_api_pg_create_interface_reply_t * mp)
5039 {
5040   vat_main_t *vam = &vat_main;
5041
5042   vam->retval = ntohl (mp->retval);
5043   vam->result_ready = 1;
5044 }
5045
5046 static void vl_api_pg_create_interface_reply_t_handler_json
5047   (vl_api_pg_create_interface_reply_t * mp)
5048 {
5049   vat_main_t *vam = &vat_main;
5050   vat_json_node_t node;
5051
5052   i32 retval = ntohl (mp->retval);
5053   if (retval == 0)
5054     {
5055       vat_json_init_object (&node);
5056
5057       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5058
5059       vat_json_print (vam->ofp, &node);
5060       vat_json_free (&node);
5061     }
5062   vam->retval = ntohl (mp->retval);
5063   vam->result_ready = 1;
5064 }
5065
5066 static void vl_api_policer_classify_details_t_handler
5067   (vl_api_policer_classify_details_t * mp)
5068 {
5069   vat_main_t *vam = &vat_main;
5070
5071   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5072          ntohl (mp->table_index));
5073 }
5074
5075 static void vl_api_policer_classify_details_t_handler_json
5076   (vl_api_policer_classify_details_t * mp)
5077 {
5078   vat_main_t *vam = &vat_main;
5079   vat_json_node_t *node;
5080
5081   if (VAT_JSON_ARRAY != vam->json_tree.type)
5082     {
5083       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5084       vat_json_init_array (&vam->json_tree);
5085     }
5086   node = vat_json_array_add (&vam->json_tree);
5087
5088   vat_json_init_object (node);
5089   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5090   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5091 }
5092
5093 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5094   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5095 {
5096   vat_main_t *vam = &vat_main;
5097   i32 retval = ntohl (mp->retval);
5098   if (vam->async_mode)
5099     {
5100       vam->async_errors += (retval < 0);
5101     }
5102   else
5103     {
5104       vam->retval = retval;
5105       vam->sw_if_index = ntohl (mp->sw_if_index);
5106       vam->result_ready = 1;
5107     }
5108   vam->regenerate_interface_table = 1;
5109 }
5110
5111 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5112   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5113 {
5114   vat_main_t *vam = &vat_main;
5115   vat_json_node_t node;
5116
5117   vat_json_init_object (&node);
5118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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_flow_classify_details_t_handler
5129   (vl_api_flow_classify_details_t * mp)
5130 {
5131   vat_main_t *vam = &vat_main;
5132
5133   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5134          ntohl (mp->table_index));
5135 }
5136
5137 static void vl_api_flow_classify_details_t_handler_json
5138   (vl_api_flow_classify_details_t * mp)
5139 {
5140   vat_main_t *vam = &vat_main;
5141   vat_json_node_t *node;
5142
5143   if (VAT_JSON_ARRAY != vam->json_tree.type)
5144     {
5145       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5146       vat_json_init_array (&vam->json_tree);
5147     }
5148   node = vat_json_array_add (&vam->json_tree);
5149
5150   vat_json_init_object (node);
5151   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5152   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5153 }
5154
5155 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5156 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5157 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5158 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5159 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5160 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5161 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5162 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5163 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5164 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5165
5166 /*
5167  * Generate boilerplate reply handlers, which
5168  * dig the return value out of the xxx_reply_t API message,
5169  * stick it into vam->retval, and set vam->result_ready
5170  *
5171  * Could also do this by pointing N message decode slots at
5172  * a single function, but that could break in subtle ways.
5173  */
5174
5175 #define foreach_standard_reply_retval_handler           \
5176 _(sw_interface_set_flags_reply)                         \
5177 _(sw_interface_add_del_address_reply)                   \
5178 _(sw_interface_set_rx_mode_reply)                       \
5179 _(sw_interface_set_rx_placement_reply)                  \
5180 _(sw_interface_set_table_reply)                         \
5181 _(sw_interface_set_mpls_enable_reply)                   \
5182 _(sw_interface_set_vpath_reply)                         \
5183 _(sw_interface_set_vxlan_bypass_reply)                  \
5184 _(sw_interface_set_geneve_bypass_reply)                 \
5185 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5186 _(sw_interface_set_l2_bridge_reply)                     \
5187 _(bridge_domain_add_del_reply)                          \
5188 _(sw_interface_set_l2_xconnect_reply)                   \
5189 _(l2fib_add_del_reply)                                  \
5190 _(l2fib_flush_int_reply)                                \
5191 _(l2fib_flush_bd_reply)                                 \
5192 _(ip_add_del_route_reply)                               \
5193 _(ip_table_add_del_reply)                               \
5194 _(ip_mroute_add_del_reply)                              \
5195 _(mpls_route_add_del_reply)                             \
5196 _(mpls_table_add_del_reply)                             \
5197 _(mpls_ip_bind_unbind_reply)                            \
5198 _(bier_route_add_del_reply)                             \
5199 _(bier_table_add_del_reply)                             \
5200 _(proxy_arp_add_del_reply)                              \
5201 _(proxy_arp_intfc_enable_disable_reply)                 \
5202 _(sw_interface_set_unnumbered_reply)                    \
5203 _(ip_neighbor_add_del_reply)                            \
5204 _(oam_add_del_reply)                                    \
5205 _(reset_fib_reply)                                      \
5206 _(dhcp_proxy_config_reply)                              \
5207 _(dhcp_proxy_set_vss_reply)                             \
5208 _(dhcp_client_config_reply)                             \
5209 _(set_ip_flow_hash_reply)                               \
5210 _(sw_interface_ip6_enable_disable_reply)                \
5211 _(ip6nd_proxy_add_del_reply)                            \
5212 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5213 _(sw_interface_ip6nd_ra_config_reply)                   \
5214 _(set_arp_neighbor_limit_reply)                         \
5215 _(l2_patch_add_del_reply)                               \
5216 _(sr_mpls_policy_add_reply)                             \
5217 _(sr_mpls_policy_mod_reply)                             \
5218 _(sr_mpls_policy_del_reply)                             \
5219 _(sr_policy_add_reply)                                  \
5220 _(sr_policy_mod_reply)                                  \
5221 _(sr_policy_del_reply)                                  \
5222 _(sr_localsid_add_del_reply)                            \
5223 _(sr_steering_add_del_reply)                            \
5224 _(classify_add_del_session_reply)                       \
5225 _(classify_set_interface_ip_table_reply)                \
5226 _(classify_set_interface_l2_tables_reply)               \
5227 _(l2tpv3_set_tunnel_cookies_reply)                      \
5228 _(l2tpv3_interface_enable_disable_reply)                \
5229 _(l2tpv3_set_lookup_key_reply)                          \
5230 _(l2_fib_clear_table_reply)                             \
5231 _(l2_interface_efp_filter_reply)                        \
5232 _(l2_interface_vlan_tag_rewrite_reply)                  \
5233 _(modify_vhost_user_if_reply)                           \
5234 _(delete_vhost_user_if_reply)                           \
5235 _(ip_probe_neighbor_reply)                              \
5236 _(ip_scan_neighbor_enable_disable_reply)                \
5237 _(want_ip4_arp_events_reply)                            \
5238 _(want_ip6_nd_events_reply)                             \
5239 _(want_l2_macs_events_reply)                            \
5240 _(input_acl_set_interface_reply)                        \
5241 _(ipsec_spd_add_del_reply)                              \
5242 _(ipsec_interface_add_del_spd_reply)                    \
5243 _(ipsec_spd_add_del_entry_reply)                        \
5244 _(ipsec_sad_add_del_entry_reply)                        \
5245 _(ipsec_sa_set_key_reply)                               \
5246 _(ipsec_tunnel_if_add_del_reply)                        \
5247 _(ipsec_tunnel_if_set_key_reply)                        \
5248 _(ipsec_tunnel_if_set_sa_reply)                         \
5249 _(ikev2_profile_add_del_reply)                          \
5250 _(ikev2_profile_set_auth_reply)                         \
5251 _(ikev2_profile_set_id_reply)                           \
5252 _(ikev2_profile_set_ts_reply)                           \
5253 _(ikev2_set_local_key_reply)                            \
5254 _(ikev2_set_responder_reply)                            \
5255 _(ikev2_set_ike_transforms_reply)                       \
5256 _(ikev2_set_esp_transforms_reply)                       \
5257 _(ikev2_set_sa_lifetime_reply)                          \
5258 _(ikev2_initiate_sa_init_reply)                         \
5259 _(ikev2_initiate_del_ike_sa_reply)                      \
5260 _(ikev2_initiate_del_child_sa_reply)                    \
5261 _(ikev2_initiate_rekey_child_sa_reply)                  \
5262 _(delete_loopback_reply)                                \
5263 _(bd_ip_mac_add_del_reply)                              \
5264 _(want_interface_events_reply)                          \
5265 _(cop_interface_enable_disable_reply)                   \
5266 _(cop_whitelist_enable_disable_reply)                   \
5267 _(sw_interface_clear_stats_reply)                       \
5268 _(ioam_enable_reply)                                    \
5269 _(ioam_disable_reply)                                   \
5270 _(one_add_del_locator_reply)                            \
5271 _(one_add_del_local_eid_reply)                          \
5272 _(one_add_del_remote_mapping_reply)                     \
5273 _(one_add_del_adjacency_reply)                          \
5274 _(one_add_del_map_resolver_reply)                       \
5275 _(one_add_del_map_server_reply)                         \
5276 _(one_enable_disable_reply)                             \
5277 _(one_rloc_probe_enable_disable_reply)                  \
5278 _(one_map_register_enable_disable_reply)                \
5279 _(one_map_register_set_ttl_reply)                       \
5280 _(one_set_transport_protocol_reply)                     \
5281 _(one_map_register_fallback_threshold_reply)            \
5282 _(one_pitr_set_locator_set_reply)                       \
5283 _(one_map_request_mode_reply)                           \
5284 _(one_add_del_map_request_itr_rlocs_reply)              \
5285 _(one_eid_table_add_del_map_reply)                      \
5286 _(one_use_petr_reply)                                   \
5287 _(one_stats_enable_disable_reply)                       \
5288 _(one_add_del_l2_arp_entry_reply)                       \
5289 _(one_add_del_ndp_entry_reply)                          \
5290 _(one_stats_flush_reply)                                \
5291 _(one_enable_disable_xtr_mode_reply)                    \
5292 _(one_enable_disable_pitr_mode_reply)                   \
5293 _(one_enable_disable_petr_mode_reply)                   \
5294 _(gpe_enable_disable_reply)                             \
5295 _(gpe_set_encap_mode_reply)                             \
5296 _(gpe_add_del_iface_reply)                              \
5297 _(gpe_add_del_native_fwd_rpath_reply)                   \
5298 _(af_packet_delete_reply)                               \
5299 _(policer_classify_set_interface_reply)                 \
5300 _(netmap_create_reply)                                  \
5301 _(netmap_delete_reply)                                  \
5302 _(set_ipfix_exporter_reply)                             \
5303 _(set_ipfix_classify_stream_reply)                      \
5304 _(ipfix_classify_table_add_del_reply)                   \
5305 _(flow_classify_set_interface_reply)                    \
5306 _(sw_interface_span_enable_disable_reply)               \
5307 _(pg_capture_reply)                                     \
5308 _(pg_enable_disable_reply)                              \
5309 _(ip_source_and_port_range_check_add_del_reply)         \
5310 _(ip_source_and_port_range_check_interface_add_del_reply)\
5311 _(delete_subif_reply)                                   \
5312 _(l2_interface_pbb_tag_rewrite_reply)                   \
5313 _(set_punt_reply)                                       \
5314 _(feature_enable_disable_reply)                         \
5315 _(sw_interface_tag_add_del_reply)                       \
5316 _(hw_interface_set_mtu_reply)                           \
5317 _(p2p_ethernet_add_reply)                               \
5318 _(p2p_ethernet_del_reply)                               \
5319 _(lldp_config_reply)                                    \
5320 _(sw_interface_set_lldp_reply)                          \
5321 _(tcp_configure_src_addresses_reply)                    \
5322 _(dns_enable_disable_reply)                             \
5323 _(dns_name_server_add_del_reply)                        \
5324 _(session_rule_add_del_reply)                           \
5325 _(ip_container_proxy_add_del_reply)                     \
5326 _(output_acl_set_interface_reply)                       \
5327 _(qos_record_enable_disable_reply)
5328
5329 #define _(n)                                    \
5330     static void vl_api_##n##_t_handler          \
5331     (vl_api_##n##_t * mp)                       \
5332     {                                           \
5333         vat_main_t * vam = &vat_main;           \
5334         i32 retval = ntohl(mp->retval);         \
5335         if (vam->async_mode) {                  \
5336             vam->async_errors += (retval < 0);  \
5337         } else {                                \
5338             vam->retval = retval;               \
5339             vam->result_ready = 1;              \
5340         }                                       \
5341     }
5342 foreach_standard_reply_retval_handler;
5343 #undef _
5344
5345 #define _(n)                                    \
5346     static void vl_api_##n##_t_handler_json     \
5347     (vl_api_##n##_t * mp)                       \
5348     {                                           \
5349         vat_main_t * vam = &vat_main;           \
5350         vat_json_node_t node;                   \
5351         vat_json_init_object(&node);            \
5352         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5353         vat_json_print(vam->ofp, &node);        \
5354         vam->retval = ntohl(mp->retval);        \
5355         vam->result_ready = 1;                  \
5356     }
5357 foreach_standard_reply_retval_handler;
5358 #undef _
5359
5360 /*
5361  * Table of message reply handlers, must include boilerplate handlers
5362  * we just generated
5363  */
5364
5365 #define foreach_vpe_api_reply_msg                                       \
5366 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5367 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5368 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5369 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5370 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5371 _(CLI_REPLY, cli_reply)                                                 \
5372 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5373 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5374   sw_interface_add_del_address_reply)                                   \
5375 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5376 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5377 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5378 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5379 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5380 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5381 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5382 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5383 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5384 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5385   sw_interface_set_l2_xconnect_reply)                                   \
5386 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5387   sw_interface_set_l2_bridge_reply)                                     \
5388 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5389 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5390 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5391 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5392 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5393 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5394 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5395 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5396 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5397 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5398 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5399 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5400 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5401 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5402 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5403 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5404 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5405 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5406 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5407 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5408 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5409 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5410 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5411 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5412 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5413 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5414 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5415 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5416 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5417 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5418 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5419   proxy_arp_intfc_enable_disable_reply)                                 \
5420 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5421 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5422   sw_interface_set_unnumbered_reply)                                    \
5423 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5424 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5425 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5426 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5427 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5428 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5429 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5430 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5431 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5432 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5433 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5434   sw_interface_ip6_enable_disable_reply)                                \
5435 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5436 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5437 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5438   sw_interface_ip6nd_ra_prefix_reply)                                   \
5439 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5440   sw_interface_ip6nd_ra_config_reply)                                   \
5441 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5442 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5443 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5444 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5445 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5446 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5447 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5448 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5449 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5450 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5451 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5452 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5453 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5454 classify_set_interface_ip_table_reply)                                  \
5455 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5456   classify_set_interface_l2_tables_reply)                               \
5457 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5458 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5459 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5460 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5461 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5462   l2tpv3_interface_enable_disable_reply)                                \
5463 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5464 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5465 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5466 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5467 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5468 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5469 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5470 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5471 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5472 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5473 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5474 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5475 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5476 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5477 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5478 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5479 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5480 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5481 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5482 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5483 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5484 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5485 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5486 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5487 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5488 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5489 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5490 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5491 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5492 _(L2_MACS_EVENT, l2_macs_event)                                         \
5493 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5494 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5495 _(IP_DETAILS, ip_details)                                               \
5496 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5497 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5498 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5499 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5500 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5501 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5502 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5503 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5504 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5505 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5506 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5507 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5508 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5509 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5510 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5511 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5512 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5513 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5514 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5515 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5516 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5517 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5518 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5519 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5520 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5521 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5522 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5523 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5524 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5525 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5526 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5527 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5528 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5529 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5530 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5531 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5532 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5533 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5534 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5535 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5536 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5537 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5538 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5539   one_map_register_enable_disable_reply)                                \
5540 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5541 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5542 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5543 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5544   one_map_register_fallback_threshold_reply)                            \
5545 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5546   one_rloc_probe_enable_disable_reply)                                  \
5547 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5548 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5549 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5550 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5551 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5552 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5553 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5554 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5555 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5556 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5557 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5558 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5559 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5560 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5561 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5562 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5563   show_one_stats_enable_disable_reply)                                  \
5564 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5565 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5566 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5567 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5568 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5569 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5570 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5571 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5572   one_enable_disable_pitr_mode_reply)                                   \
5573 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5574   one_enable_disable_petr_mode_reply)                                   \
5575 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5576 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5577 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5578 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5579 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5580 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5581 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5582 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5583 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5584 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5585 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5586 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5587   gpe_add_del_native_fwd_rpath_reply)                                   \
5588 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5589   gpe_fwd_entry_path_details)                                           \
5590 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5591 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5592   one_add_del_map_request_itr_rlocs_reply)                              \
5593 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5594   one_get_map_request_itr_rlocs_reply)                                  \
5595 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5596 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5597 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5598 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5599 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5600 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5601   show_one_map_register_state_reply)                                    \
5602 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5603 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5604   show_one_map_register_fallback_threshold_reply)                       \
5605 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5606 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5607 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5608 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5609 _(POLICER_DETAILS, policer_details)                                     \
5610 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5611 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5612 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5613 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5614 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5615 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5616 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5617 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5618 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5619 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5620 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5621 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5622 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5623 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5624 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5625 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5626 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5627 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5628 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5629 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5630 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5631 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5632 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5633 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5634 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5635  ip_source_and_port_range_check_add_del_reply)                          \
5636 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5637  ip_source_and_port_range_check_interface_add_del_reply)                \
5638 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5639 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5640 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5641 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5642 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5643 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5644 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5645 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5646 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5647 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5648 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5649 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5650 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5651 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5652 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5653 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5654 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5655 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5656 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5657 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5658 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5659 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5660 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5661 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5662 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5663 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5664 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5665 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5666
5667 #define foreach_standalone_reply_msg                                    \
5668 _(SW_INTERFACE_EVENT, sw_interface_event)
5669
5670 typedef struct
5671 {
5672   u8 *name;
5673   u32 value;
5674 } name_sort_t;
5675
5676 #define STR_VTR_OP_CASE(op)     \
5677     case L2_VTR_ ## op:         \
5678         return "" # op;
5679
5680 static const char *
5681 str_vtr_op (u32 vtr_op)
5682 {
5683   switch (vtr_op)
5684     {
5685       STR_VTR_OP_CASE (DISABLED);
5686       STR_VTR_OP_CASE (PUSH_1);
5687       STR_VTR_OP_CASE (PUSH_2);
5688       STR_VTR_OP_CASE (POP_1);
5689       STR_VTR_OP_CASE (POP_2);
5690       STR_VTR_OP_CASE (TRANSLATE_1_1);
5691       STR_VTR_OP_CASE (TRANSLATE_1_2);
5692       STR_VTR_OP_CASE (TRANSLATE_2_1);
5693       STR_VTR_OP_CASE (TRANSLATE_2_2);
5694     }
5695
5696   return "UNKNOWN";
5697 }
5698
5699 static int
5700 dump_sub_interface_table (vat_main_t * vam)
5701 {
5702   const sw_interface_subif_t *sub = NULL;
5703
5704   if (vam->json_output)
5705     {
5706       clib_warning
5707         ("JSON output supported only for VPE API calls and dump_stats_table");
5708       return -99;
5709     }
5710
5711   print (vam->ofp,
5712          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5713          "Interface", "sw_if_index",
5714          "sub id", "dot1ad", "tags", "outer id",
5715          "inner id", "exact", "default", "outer any", "inner any");
5716
5717   vec_foreach (sub, vam->sw_if_subif_table)
5718   {
5719     print (vam->ofp,
5720            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5721            sub->interface_name,
5722            sub->sw_if_index,
5723            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5724            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5725            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5726            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5727     if (sub->vtr_op != L2_VTR_DISABLED)
5728       {
5729         print (vam->ofp,
5730                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5731                "tag1: %d tag2: %d ]",
5732                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5733                sub->vtr_tag1, sub->vtr_tag2);
5734       }
5735   }
5736
5737   return 0;
5738 }
5739
5740 static int
5741 name_sort_cmp (void *a1, void *a2)
5742 {
5743   name_sort_t *n1 = a1;
5744   name_sort_t *n2 = a2;
5745
5746   return strcmp ((char *) n1->name, (char *) n2->name);
5747 }
5748
5749 static int
5750 dump_interface_table (vat_main_t * vam)
5751 {
5752   hash_pair_t *p;
5753   name_sort_t *nses = 0, *ns;
5754
5755   if (vam->json_output)
5756     {
5757       clib_warning
5758         ("JSON output supported only for VPE API calls and dump_stats_table");
5759       return -99;
5760     }
5761
5762   /* *INDENT-OFF* */
5763   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5764   ({
5765     vec_add2 (nses, ns, 1);
5766     ns->name = (u8 *)(p->key);
5767     ns->value = (u32) p->value[0];
5768   }));
5769   /* *INDENT-ON* */
5770
5771   vec_sort_with_function (nses, name_sort_cmp);
5772
5773   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5774   vec_foreach (ns, nses)
5775   {
5776     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5777   }
5778   vec_free (nses);
5779   return 0;
5780 }
5781
5782 static int
5783 dump_ip_table (vat_main_t * vam, int is_ipv6)
5784 {
5785   const ip_details_t *det = NULL;
5786   const ip_address_details_t *address = NULL;
5787   u32 i = ~0;
5788
5789   print (vam->ofp, "%-12s", "sw_if_index");
5790
5791   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5792   {
5793     i++;
5794     if (!det->present)
5795       {
5796         continue;
5797       }
5798     print (vam->ofp, "%-12d", i);
5799     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5800     if (!det->addr)
5801       {
5802         continue;
5803       }
5804     vec_foreach (address, det->addr)
5805     {
5806       print (vam->ofp,
5807              "            %-30U%-13d",
5808              is_ipv6 ? format_ip6_address : format_ip4_address,
5809              address->ip, address->prefix_length);
5810     }
5811   }
5812
5813   return 0;
5814 }
5815
5816 static int
5817 dump_ipv4_table (vat_main_t * vam)
5818 {
5819   if (vam->json_output)
5820     {
5821       clib_warning
5822         ("JSON output supported only for VPE API calls and dump_stats_table");
5823       return -99;
5824     }
5825
5826   return dump_ip_table (vam, 0);
5827 }
5828
5829 static int
5830 dump_ipv6_table (vat_main_t * vam)
5831 {
5832   if (vam->json_output)
5833     {
5834       clib_warning
5835         ("JSON output supported only for VPE API calls and dump_stats_table");
5836       return -99;
5837     }
5838
5839   return dump_ip_table (vam, 1);
5840 }
5841
5842 /*
5843  * Pass CLI buffers directly in the CLI_INBAND API message,
5844  * instead of an additional shared memory area.
5845  */
5846 static int
5847 exec_inband (vat_main_t * vam)
5848 {
5849   vl_api_cli_inband_t *mp;
5850   unformat_input_t *i = vam->input;
5851   int ret;
5852
5853   if (vec_len (i->buffer) == 0)
5854     return -1;
5855
5856   if (vam->exec_mode == 0 && unformat (i, "mode"))
5857     {
5858       vam->exec_mode = 1;
5859       return 0;
5860     }
5861   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5862     {
5863       vam->exec_mode = 0;
5864       return 0;
5865     }
5866
5867   /*
5868    * In order for the CLI command to work, it
5869    * must be a vector ending in \n, not a C-string ending
5870    * in \n\0.
5871    */
5872   u32 len = vec_len (vam->input->buffer);
5873   M2 (CLI_INBAND, mp, len);
5874   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5875
5876   S (mp);
5877   W (ret);
5878   /* json responses may or may not include a useful reply... */
5879   if (vec_len (vam->cmd_reply))
5880     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5881   return ret;
5882 }
5883
5884 int
5885 exec (vat_main_t * vam)
5886 {
5887   return exec_inband (vam);
5888 }
5889
5890 static int
5891 api_create_loopback (vat_main_t * vam)
5892 {
5893   unformat_input_t *i = vam->input;
5894   vl_api_create_loopback_t *mp;
5895   vl_api_create_loopback_instance_t *mp_lbi;
5896   u8 mac_address[6];
5897   u8 mac_set = 0;
5898   u8 is_specified = 0;
5899   u32 user_instance = 0;
5900   int ret;
5901
5902   clib_memset (mac_address, 0, sizeof (mac_address));
5903
5904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5905     {
5906       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5907         mac_set = 1;
5908       if (unformat (i, "instance %d", &user_instance))
5909         is_specified = 1;
5910       else
5911         break;
5912     }
5913
5914   if (is_specified)
5915     {
5916       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5917       mp_lbi->is_specified = is_specified;
5918       if (is_specified)
5919         mp_lbi->user_instance = htonl (user_instance);
5920       if (mac_set)
5921         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5922       S (mp_lbi);
5923     }
5924   else
5925     {
5926       /* Construct the API message */
5927       M (CREATE_LOOPBACK, mp);
5928       if (mac_set)
5929         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5930       S (mp);
5931     }
5932
5933   W (ret);
5934   return ret;
5935 }
5936
5937 static int
5938 api_delete_loopback (vat_main_t * vam)
5939 {
5940   unformat_input_t *i = vam->input;
5941   vl_api_delete_loopback_t *mp;
5942   u32 sw_if_index = ~0;
5943   int ret;
5944
5945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5946     {
5947       if (unformat (i, "sw_if_index %d", &sw_if_index))
5948         ;
5949       else
5950         break;
5951     }
5952
5953   if (sw_if_index == ~0)
5954     {
5955       errmsg ("missing sw_if_index");
5956       return -99;
5957     }
5958
5959   /* Construct the API message */
5960   M (DELETE_LOOPBACK, mp);
5961   mp->sw_if_index = ntohl (sw_if_index);
5962
5963   S (mp);
5964   W (ret);
5965   return ret;
5966 }
5967
5968 static int
5969 api_want_interface_events (vat_main_t * vam)
5970 {
5971   unformat_input_t *i = vam->input;
5972   vl_api_want_interface_events_t *mp;
5973   int enable = -1;
5974   int ret;
5975
5976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5977     {
5978       if (unformat (i, "enable"))
5979         enable = 1;
5980       else if (unformat (i, "disable"))
5981         enable = 0;
5982       else
5983         break;
5984     }
5985
5986   if (enable == -1)
5987     {
5988       errmsg ("missing enable|disable");
5989       return -99;
5990     }
5991
5992   M (WANT_INTERFACE_EVENTS, mp);
5993   mp->enable_disable = enable;
5994
5995   vam->interface_event_display = enable;
5996
5997   S (mp);
5998   W (ret);
5999   return ret;
6000 }
6001
6002
6003 /* Note: non-static, called once to set up the initial intfc table */
6004 int
6005 api_sw_interface_dump (vat_main_t * vam)
6006 {
6007   vl_api_sw_interface_dump_t *mp;
6008   vl_api_control_ping_t *mp_ping;
6009   hash_pair_t *p;
6010   name_sort_t *nses = 0, *ns;
6011   sw_interface_subif_t *sub = NULL;
6012   int ret;
6013
6014   /* Toss the old name table */
6015   /* *INDENT-OFF* */
6016   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6017   ({
6018     vec_add2 (nses, ns, 1);
6019     ns->name = (u8 *)(p->key);
6020     ns->value = (u32) p->value[0];
6021   }));
6022   /* *INDENT-ON* */
6023
6024   hash_free (vam->sw_if_index_by_interface_name);
6025
6026   vec_foreach (ns, nses) vec_free (ns->name);
6027
6028   vec_free (nses);
6029
6030   vec_foreach (sub, vam->sw_if_subif_table)
6031   {
6032     vec_free (sub->interface_name);
6033   }
6034   vec_free (vam->sw_if_subif_table);
6035
6036   /* recreate the interface name hash table */
6037   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6038
6039   /*
6040    * Ask for all interface names. Otherwise, the epic catalog of
6041    * name filters becomes ridiculously long, and vat ends up needing
6042    * to be taught about new interface types.
6043    */
6044   M (SW_INTERFACE_DUMP, mp);
6045   S (mp);
6046
6047   /* Use a control ping for synchronization */
6048   MPING (CONTROL_PING, mp_ping);
6049   S (mp_ping);
6050
6051   W (ret);
6052   return ret;
6053 }
6054
6055 static int
6056 api_sw_interface_set_flags (vat_main_t * vam)
6057 {
6058   unformat_input_t *i = vam->input;
6059   vl_api_sw_interface_set_flags_t *mp;
6060   u32 sw_if_index;
6061   u8 sw_if_index_set = 0;
6062   u8 admin_up = 0;
6063   int ret;
6064
6065   /* Parse args required to build the message */
6066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6067     {
6068       if (unformat (i, "admin-up"))
6069         admin_up = 1;
6070       else if (unformat (i, "admin-down"))
6071         admin_up = 0;
6072       else
6073         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6074         sw_if_index_set = 1;
6075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6076         sw_if_index_set = 1;
6077       else
6078         break;
6079     }
6080
6081   if (sw_if_index_set == 0)
6082     {
6083       errmsg ("missing interface name or sw_if_index");
6084       return -99;
6085     }
6086
6087   /* Construct the API message */
6088   M (SW_INTERFACE_SET_FLAGS, mp);
6089   mp->sw_if_index = ntohl (sw_if_index);
6090   mp->admin_up_down = admin_up;
6091
6092   /* send it... */
6093   S (mp);
6094
6095   /* Wait for a reply, return the good/bad news... */
6096   W (ret);
6097   return ret;
6098 }
6099
6100 static int
6101 api_sw_interface_set_rx_mode (vat_main_t * vam)
6102 {
6103   unformat_input_t *i = vam->input;
6104   vl_api_sw_interface_set_rx_mode_t *mp;
6105   u32 sw_if_index;
6106   u8 sw_if_index_set = 0;
6107   int ret;
6108   u8 queue_id_valid = 0;
6109   u32 queue_id;
6110   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6111
6112   /* Parse args required to build the message */
6113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6114     {
6115       if (unformat (i, "queue %d", &queue_id))
6116         queue_id_valid = 1;
6117       else if (unformat (i, "polling"))
6118         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6119       else if (unformat (i, "interrupt"))
6120         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6121       else if (unformat (i, "adaptive"))
6122         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6123       else
6124         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6125         sw_if_index_set = 1;
6126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6127         sw_if_index_set = 1;
6128       else
6129         break;
6130     }
6131
6132   if (sw_if_index_set == 0)
6133     {
6134       errmsg ("missing interface name or sw_if_index");
6135       return -99;
6136     }
6137   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6138     {
6139       errmsg ("missing rx-mode");
6140       return -99;
6141     }
6142
6143   /* Construct the API message */
6144   M (SW_INTERFACE_SET_RX_MODE, mp);
6145   mp->sw_if_index = ntohl (sw_if_index);
6146   mp->mode = mode;
6147   mp->queue_id_valid = queue_id_valid;
6148   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6149
6150   /* send it... */
6151   S (mp);
6152
6153   /* Wait for a reply, return the good/bad news... */
6154   W (ret);
6155   return ret;
6156 }
6157
6158 static int
6159 api_sw_interface_set_rx_placement (vat_main_t * vam)
6160 {
6161   unformat_input_t *i = vam->input;
6162   vl_api_sw_interface_set_rx_placement_t *mp;
6163   u32 sw_if_index;
6164   u8 sw_if_index_set = 0;
6165   int ret;
6166   u8 is_main = 0;
6167   u32 queue_id, thread_index;
6168
6169   /* Parse args required to build the message */
6170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6171     {
6172       if (unformat (i, "queue %d", &queue_id))
6173         ;
6174       else if (unformat (i, "main"))
6175         is_main = 1;
6176       else if (unformat (i, "worker %d", &thread_index))
6177         ;
6178       else
6179         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6180         sw_if_index_set = 1;
6181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6182         sw_if_index_set = 1;
6183       else
6184         break;
6185     }
6186
6187   if (sw_if_index_set == 0)
6188     {
6189       errmsg ("missing interface name or sw_if_index");
6190       return -99;
6191     }
6192
6193   if (is_main)
6194     thread_index = 0;
6195   /* Construct the API message */
6196   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6197   mp->sw_if_index = ntohl (sw_if_index);
6198   mp->worker_id = ntohl (thread_index);
6199   mp->queue_id = ntohl (queue_id);
6200   mp->is_main = is_main;
6201
6202   /* send it... */
6203   S (mp);
6204   /* Wait for a reply, return the good/bad news... */
6205   W (ret);
6206   return ret;
6207 }
6208
6209 static void vl_api_sw_interface_rx_placement_details_t_handler
6210   (vl_api_sw_interface_rx_placement_details_t * mp)
6211 {
6212   vat_main_t *vam = &vat_main;
6213   u32 worker_id = ntohl (mp->worker_id);
6214
6215   print (vam->ofp,
6216          "\n%-11d %-11s %-6d %-5d %-9s",
6217          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6218          worker_id, ntohl (mp->queue_id),
6219          (mp->mode ==
6220           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6221 }
6222
6223 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6224   (vl_api_sw_interface_rx_placement_details_t * mp)
6225 {
6226   vat_main_t *vam = &vat_main;
6227   vat_json_node_t *node = NULL;
6228
6229   if (VAT_JSON_ARRAY != vam->json_tree.type)
6230     {
6231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6232       vat_json_init_array (&vam->json_tree);
6233     }
6234   node = vat_json_array_add (&vam->json_tree);
6235
6236   vat_json_init_object (node);
6237   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6238   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6239   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6240   vat_json_object_add_uint (node, "mode", mp->mode);
6241 }
6242
6243 static int
6244 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6245 {
6246   unformat_input_t *i = vam->input;
6247   vl_api_sw_interface_rx_placement_dump_t *mp;
6248   vl_api_control_ping_t *mp_ping;
6249   int ret;
6250   u32 sw_if_index;
6251   u8 sw_if_index_set = 0;
6252
6253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6254     {
6255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6256         sw_if_index_set++;
6257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6258         sw_if_index_set++;
6259       else
6260         break;
6261     }
6262
6263   print (vam->ofp,
6264          "\n%-11s %-11s %-6s %-5s %-4s",
6265          "sw_if_index", "main/worker", "thread", "queue", "mode");
6266
6267   /* Dump Interface rx placement */
6268   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6269
6270   if (sw_if_index_set)
6271     mp->sw_if_index = htonl (sw_if_index);
6272   else
6273     mp->sw_if_index = ~0;
6274
6275   S (mp);
6276
6277   /* Use a control ping for synchronization */
6278   MPING (CONTROL_PING, mp_ping);
6279   S (mp_ping);
6280
6281   W (ret);
6282   return ret;
6283 }
6284
6285 static int
6286 api_sw_interface_clear_stats (vat_main_t * vam)
6287 {
6288   unformat_input_t *i = vam->input;
6289   vl_api_sw_interface_clear_stats_t *mp;
6290   u32 sw_if_index;
6291   u8 sw_if_index_set = 0;
6292   int ret;
6293
6294   /* Parse args required to build the message */
6295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6296     {
6297       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6298         sw_if_index_set = 1;
6299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6300         sw_if_index_set = 1;
6301       else
6302         break;
6303     }
6304
6305   /* Construct the API message */
6306   M (SW_INTERFACE_CLEAR_STATS, mp);
6307
6308   if (sw_if_index_set == 1)
6309     mp->sw_if_index = ntohl (sw_if_index);
6310   else
6311     mp->sw_if_index = ~0;
6312
6313   /* send it... */
6314   S (mp);
6315
6316   /* Wait for a reply, return the good/bad news... */
6317   W (ret);
6318   return ret;
6319 }
6320
6321 static int
6322 api_sw_interface_add_del_address (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   vl_api_sw_interface_add_del_address_t *mp;
6326   u32 sw_if_index;
6327   u8 sw_if_index_set = 0;
6328   u8 is_add = 1, del_all = 0;
6329   u32 address_length = 0;
6330   u8 v4_address_set = 0;
6331   u8 v6_address_set = 0;
6332   ip4_address_t v4address;
6333   ip6_address_t v6address;
6334   int ret;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "del-all"))
6340         del_all = 1;
6341       else if (unformat (i, "del"))
6342         is_add = 0;
6343       else
6344         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6345         sw_if_index_set = 1;
6346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6347         sw_if_index_set = 1;
6348       else if (unformat (i, "%U/%d",
6349                          unformat_ip4_address, &v4address, &address_length))
6350         v4_address_set = 1;
6351       else if (unformat (i, "%U/%d",
6352                          unformat_ip6_address, &v6address, &address_length))
6353         v6_address_set = 1;
6354       else
6355         break;
6356     }
6357
6358   if (sw_if_index_set == 0)
6359     {
6360       errmsg ("missing interface name or sw_if_index");
6361       return -99;
6362     }
6363   if (v4_address_set && v6_address_set)
6364     {
6365       errmsg ("both v4 and v6 addresses set");
6366       return -99;
6367     }
6368   if (!v4_address_set && !v6_address_set && !del_all)
6369     {
6370       errmsg ("no addresses set");
6371       return -99;
6372     }
6373
6374   /* Construct the API message */
6375   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6376
6377   mp->sw_if_index = ntohl (sw_if_index);
6378   mp->is_add = is_add;
6379   mp->del_all = del_all;
6380   if (v6_address_set)
6381     {
6382       mp->is_ipv6 = 1;
6383       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6384     }
6385   else
6386     {
6387       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6388     }
6389   mp->address_length = address_length;
6390
6391   /* send it... */
6392   S (mp);
6393
6394   /* Wait for a reply, return good/bad news  */
6395   W (ret);
6396   return ret;
6397 }
6398
6399 static int
6400 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6401 {
6402   unformat_input_t *i = vam->input;
6403   vl_api_sw_interface_set_mpls_enable_t *mp;
6404   u32 sw_if_index;
6405   u8 sw_if_index_set = 0;
6406   u8 enable = 1;
6407   int ret;
6408
6409   /* Parse args required to build the message */
6410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6411     {
6412       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6413         sw_if_index_set = 1;
6414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6415         sw_if_index_set = 1;
6416       else if (unformat (i, "disable"))
6417         enable = 0;
6418       else if (unformat (i, "dis"))
6419         enable = 0;
6420       else
6421         break;
6422     }
6423
6424   if (sw_if_index_set == 0)
6425     {
6426       errmsg ("missing interface name or sw_if_index");
6427       return -99;
6428     }
6429
6430   /* Construct the API message */
6431   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6432
6433   mp->sw_if_index = ntohl (sw_if_index);
6434   mp->enable = enable;
6435
6436   /* send it... */
6437   S (mp);
6438
6439   /* Wait for a reply... */
6440   W (ret);
6441   return ret;
6442 }
6443
6444 static int
6445 api_sw_interface_set_table (vat_main_t * vam)
6446 {
6447   unformat_input_t *i = vam->input;
6448   vl_api_sw_interface_set_table_t *mp;
6449   u32 sw_if_index, vrf_id = 0;
6450   u8 sw_if_index_set = 0;
6451   u8 is_ipv6 = 0;
6452   int ret;
6453
6454   /* Parse args required to build the message */
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6460         sw_if_index_set = 1;
6461       else if (unformat (i, "vrf %d", &vrf_id))
6462         ;
6463       else if (unformat (i, "ipv6"))
6464         is_ipv6 = 1;
6465       else
6466         break;
6467     }
6468
6469   if (sw_if_index_set == 0)
6470     {
6471       errmsg ("missing interface name or sw_if_index");
6472       return -99;
6473     }
6474
6475   /* Construct the API message */
6476   M (SW_INTERFACE_SET_TABLE, mp);
6477
6478   mp->sw_if_index = ntohl (sw_if_index);
6479   mp->is_ipv6 = is_ipv6;
6480   mp->vrf_id = ntohl (vrf_id);
6481
6482   /* send it... */
6483   S (mp);
6484
6485   /* Wait for a reply... */
6486   W (ret);
6487   return ret;
6488 }
6489
6490 static void vl_api_sw_interface_get_table_reply_t_handler
6491   (vl_api_sw_interface_get_table_reply_t * mp)
6492 {
6493   vat_main_t *vam = &vat_main;
6494
6495   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6496
6497   vam->retval = ntohl (mp->retval);
6498   vam->result_ready = 1;
6499
6500 }
6501
6502 static void vl_api_sw_interface_get_table_reply_t_handler_json
6503   (vl_api_sw_interface_get_table_reply_t * mp)
6504 {
6505   vat_main_t *vam = &vat_main;
6506   vat_json_node_t node;
6507
6508   vat_json_init_object (&node);
6509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6510   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6511
6512   vat_json_print (vam->ofp, &node);
6513   vat_json_free (&node);
6514
6515   vam->retval = ntohl (mp->retval);
6516   vam->result_ready = 1;
6517 }
6518
6519 static int
6520 api_sw_interface_get_table (vat_main_t * vam)
6521 {
6522   unformat_input_t *i = vam->input;
6523   vl_api_sw_interface_get_table_t *mp;
6524   u32 sw_if_index;
6525   u8 sw_if_index_set = 0;
6526   u8 is_ipv6 = 0;
6527   int ret;
6528
6529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6530     {
6531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6534         sw_if_index_set = 1;
6535       else if (unformat (i, "ipv6"))
6536         is_ipv6 = 1;
6537       else
6538         break;
6539     }
6540
6541   if (sw_if_index_set == 0)
6542     {
6543       errmsg ("missing interface name or sw_if_index");
6544       return -99;
6545     }
6546
6547   M (SW_INTERFACE_GET_TABLE, mp);
6548   mp->sw_if_index = htonl (sw_if_index);
6549   mp->is_ipv6 = is_ipv6;
6550
6551   S (mp);
6552   W (ret);
6553   return ret;
6554 }
6555
6556 static int
6557 api_sw_interface_set_vpath (vat_main_t * vam)
6558 {
6559   unformat_input_t *i = vam->input;
6560   vl_api_sw_interface_set_vpath_t *mp;
6561   u32 sw_if_index = 0;
6562   u8 sw_if_index_set = 0;
6563   u8 is_enable = 0;
6564   int ret;
6565
6566   /* Parse args required to build the message */
6567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6568     {
6569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6570         sw_if_index_set = 1;
6571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6572         sw_if_index_set = 1;
6573       else if (unformat (i, "enable"))
6574         is_enable = 1;
6575       else if (unformat (i, "disable"))
6576         is_enable = 0;
6577       else
6578         break;
6579     }
6580
6581   if (sw_if_index_set == 0)
6582     {
6583       errmsg ("missing interface name or sw_if_index");
6584       return -99;
6585     }
6586
6587   /* Construct the API message */
6588   M (SW_INTERFACE_SET_VPATH, mp);
6589
6590   mp->sw_if_index = ntohl (sw_if_index);
6591   mp->enable = is_enable;
6592
6593   /* send it... */
6594   S (mp);
6595
6596   /* Wait for a reply... */
6597   W (ret);
6598   return ret;
6599 }
6600
6601 static int
6602 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6603 {
6604   unformat_input_t *i = vam->input;
6605   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6606   u32 sw_if_index = 0;
6607   u8 sw_if_index_set = 0;
6608   u8 is_enable = 1;
6609   u8 is_ipv6 = 0;
6610   int ret;
6611
6612   /* Parse args required to build the message */
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         sw_if_index_set = 1;
6619       else if (unformat (i, "enable"))
6620         is_enable = 1;
6621       else if (unformat (i, "disable"))
6622         is_enable = 0;
6623       else if (unformat (i, "ip4"))
6624         is_ipv6 = 0;
6625       else if (unformat (i, "ip6"))
6626         is_ipv6 = 1;
6627       else
6628         break;
6629     }
6630
6631   if (sw_if_index_set == 0)
6632     {
6633       errmsg ("missing interface name or sw_if_index");
6634       return -99;
6635     }
6636
6637   /* Construct the API message */
6638   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6639
6640   mp->sw_if_index = ntohl (sw_if_index);
6641   mp->enable = is_enable;
6642   mp->is_ipv6 = is_ipv6;
6643
6644   /* send it... */
6645   S (mp);
6646
6647   /* Wait for a reply... */
6648   W (ret);
6649   return ret;
6650 }
6651
6652 static int
6653 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6654 {
6655   unformat_input_t *i = vam->input;
6656   vl_api_sw_interface_set_geneve_bypass_t *mp;
6657   u32 sw_if_index = 0;
6658   u8 sw_if_index_set = 0;
6659   u8 is_enable = 1;
6660   u8 is_ipv6 = 0;
6661   int ret;
6662
6663   /* Parse args required to build the message */
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6667         sw_if_index_set = 1;
6668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6669         sw_if_index_set = 1;
6670       else if (unformat (i, "enable"))
6671         is_enable = 1;
6672       else if (unformat (i, "disable"))
6673         is_enable = 0;
6674       else if (unformat (i, "ip4"))
6675         is_ipv6 = 0;
6676       else if (unformat (i, "ip6"))
6677         is_ipv6 = 1;
6678       else
6679         break;
6680     }
6681
6682   if (sw_if_index_set == 0)
6683     {
6684       errmsg ("missing interface name or sw_if_index");
6685       return -99;
6686     }
6687
6688   /* Construct the API message */
6689   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6690
6691   mp->sw_if_index = ntohl (sw_if_index);
6692   mp->enable = is_enable;
6693   mp->is_ipv6 = is_ipv6;
6694
6695   /* send it... */
6696   S (mp);
6697
6698   /* Wait for a reply... */
6699   W (ret);
6700   return ret;
6701 }
6702
6703 static int
6704 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6705 {
6706   unformat_input_t *i = vam->input;
6707   vl_api_sw_interface_set_l2_xconnect_t *mp;
6708   u32 rx_sw_if_index;
6709   u8 rx_sw_if_index_set = 0;
6710   u32 tx_sw_if_index;
6711   u8 tx_sw_if_index_set = 0;
6712   u8 enable = 1;
6713   int ret;
6714
6715   /* Parse args required to build the message */
6716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6717     {
6718       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6719         rx_sw_if_index_set = 1;
6720       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6721         tx_sw_if_index_set = 1;
6722       else if (unformat (i, "rx"))
6723         {
6724           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6725             {
6726               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6727                             &rx_sw_if_index))
6728                 rx_sw_if_index_set = 1;
6729             }
6730           else
6731             break;
6732         }
6733       else if (unformat (i, "tx"))
6734         {
6735           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6736             {
6737               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6738                             &tx_sw_if_index))
6739                 tx_sw_if_index_set = 1;
6740             }
6741           else
6742             break;
6743         }
6744       else if (unformat (i, "enable"))
6745         enable = 1;
6746       else if (unformat (i, "disable"))
6747         enable = 0;
6748       else
6749         break;
6750     }
6751
6752   if (rx_sw_if_index_set == 0)
6753     {
6754       errmsg ("missing rx interface name or rx_sw_if_index");
6755       return -99;
6756     }
6757
6758   if (enable && (tx_sw_if_index_set == 0))
6759     {
6760       errmsg ("missing tx interface name or tx_sw_if_index");
6761       return -99;
6762     }
6763
6764   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6765
6766   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6767   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6768   mp->enable = enable;
6769
6770   S (mp);
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_sw_interface_set_l2_bridge_t *mp;
6780   vl_api_l2_port_type_t port_type;
6781   u32 rx_sw_if_index;
6782   u8 rx_sw_if_index_set = 0;
6783   u32 bd_id;
6784   u8 bd_id_set = 0;
6785   u32 shg = 0;
6786   u8 enable = 1;
6787   int ret;
6788
6789   port_type = L2_API_PORT_TYPE_NORMAL;
6790
6791   /* Parse args required to build the message */
6792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6793     {
6794       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6795         rx_sw_if_index_set = 1;
6796       else if (unformat (i, "bd_id %d", &bd_id))
6797         bd_id_set = 1;
6798       else
6799         if (unformat
6800             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6801         rx_sw_if_index_set = 1;
6802       else if (unformat (i, "shg %d", &shg))
6803         ;
6804       else if (unformat (i, "bvi"))
6805         port_type = L2_API_PORT_TYPE_BVI;
6806       else if (unformat (i, "uu-fwd"))
6807         port_type = L2_API_PORT_TYPE_UU_FWD;
6808       else if (unformat (i, "enable"))
6809         enable = 1;
6810       else if (unformat (i, "disable"))
6811         enable = 0;
6812       else
6813         break;
6814     }
6815
6816   if (rx_sw_if_index_set == 0)
6817     {
6818       errmsg ("missing rx interface name or sw_if_index");
6819       return -99;
6820     }
6821
6822   if (enable && (bd_id_set == 0))
6823     {
6824       errmsg ("missing bridge domain");
6825       return -99;
6826     }
6827
6828   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6829
6830   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6831   mp->bd_id = ntohl (bd_id);
6832   mp->shg = (u8) shg;
6833   mp->port_type = ntohl (port_type);
6834   mp->enable = enable;
6835
6836   S (mp);
6837   W (ret);
6838   return ret;
6839 }
6840
6841 static int
6842 api_bridge_domain_dump (vat_main_t * vam)
6843 {
6844   unformat_input_t *i = vam->input;
6845   vl_api_bridge_domain_dump_t *mp;
6846   vl_api_control_ping_t *mp_ping;
6847   u32 bd_id = ~0;
6848   int ret;
6849
6850   /* Parse args required to build the message */
6851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6852     {
6853       if (unformat (i, "bd_id %d", &bd_id))
6854         ;
6855       else
6856         break;
6857     }
6858
6859   M (BRIDGE_DOMAIN_DUMP, mp);
6860   mp->bd_id = ntohl (bd_id);
6861   S (mp);
6862
6863   /* Use a control ping for synchronization */
6864   MPING (CONTROL_PING, mp_ping);
6865   S (mp_ping);
6866
6867   W (ret);
6868   return ret;
6869 }
6870
6871 static int
6872 api_bridge_domain_add_del (vat_main_t * vam)
6873 {
6874   unformat_input_t *i = vam->input;
6875   vl_api_bridge_domain_add_del_t *mp;
6876   u32 bd_id = ~0;
6877   u8 is_add = 1;
6878   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6879   u8 *bd_tag = NULL;
6880   u32 mac_age = 0;
6881   int ret;
6882
6883   /* Parse args required to build the message */
6884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6885     {
6886       if (unformat (i, "bd_id %d", &bd_id))
6887         ;
6888       else if (unformat (i, "flood %d", &flood))
6889         ;
6890       else if (unformat (i, "uu-flood %d", &uu_flood))
6891         ;
6892       else if (unformat (i, "forward %d", &forward))
6893         ;
6894       else if (unformat (i, "learn %d", &learn))
6895         ;
6896       else if (unformat (i, "arp-term %d", &arp_term))
6897         ;
6898       else if (unformat (i, "mac-age %d", &mac_age))
6899         ;
6900       else if (unformat (i, "bd-tag %s", &bd_tag))
6901         ;
6902       else if (unformat (i, "del"))
6903         {
6904           is_add = 0;
6905           flood = uu_flood = forward = learn = 0;
6906         }
6907       else
6908         break;
6909     }
6910
6911   if (bd_id == ~0)
6912     {
6913       errmsg ("missing bridge domain");
6914       ret = -99;
6915       goto done;
6916     }
6917
6918   if (mac_age > 255)
6919     {
6920       errmsg ("mac age must be less than 256 ");
6921       ret = -99;
6922       goto done;
6923     }
6924
6925   if ((bd_tag) && (vec_len (bd_tag) > 63))
6926     {
6927       errmsg ("bd-tag cannot be longer than 63");
6928       ret = -99;
6929       goto done;
6930     }
6931
6932   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6933
6934   mp->bd_id = ntohl (bd_id);
6935   mp->flood = flood;
6936   mp->uu_flood = uu_flood;
6937   mp->forward = forward;
6938   mp->learn = learn;
6939   mp->arp_term = arp_term;
6940   mp->is_add = is_add;
6941   mp->mac_age = (u8) mac_age;
6942   if (bd_tag)
6943     {
6944       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6945       mp->bd_tag[vec_len (bd_tag)] = 0;
6946     }
6947   S (mp);
6948   W (ret);
6949
6950 done:
6951   vec_free (bd_tag);
6952   return ret;
6953 }
6954
6955 static int
6956 api_l2fib_flush_bd (vat_main_t * vam)
6957 {
6958   unformat_input_t *i = vam->input;
6959   vl_api_l2fib_flush_bd_t *mp;
6960   u32 bd_id = ~0;
6961   int ret;
6962
6963   /* Parse args required to build the message */
6964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6965     {
6966       if (unformat (i, "bd_id %d", &bd_id));
6967       else
6968         break;
6969     }
6970
6971   if (bd_id == ~0)
6972     {
6973       errmsg ("missing bridge domain");
6974       return -99;
6975     }
6976
6977   M (L2FIB_FLUSH_BD, mp);
6978
6979   mp->bd_id = htonl (bd_id);
6980
6981   S (mp);
6982   W (ret);
6983   return ret;
6984 }
6985
6986 static int
6987 api_l2fib_flush_int (vat_main_t * vam)
6988 {
6989   unformat_input_t *i = vam->input;
6990   vl_api_l2fib_flush_int_t *mp;
6991   u32 sw_if_index = ~0;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "sw_if_index %d", &sw_if_index));
6998       else
6999         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7000       else
7001         break;
7002     }
7003
7004   if (sw_if_index == ~0)
7005     {
7006       errmsg ("missing interface name or sw_if_index");
7007       return -99;
7008     }
7009
7010   M (L2FIB_FLUSH_INT, mp);
7011
7012   mp->sw_if_index = ntohl (sw_if_index);
7013
7014   S (mp);
7015   W (ret);
7016   return ret;
7017 }
7018
7019 static int
7020 api_l2fib_add_del (vat_main_t * vam)
7021 {
7022   unformat_input_t *i = vam->input;
7023   vl_api_l2fib_add_del_t *mp;
7024   f64 timeout;
7025   u8 mac[6] = { 0 };
7026   u8 mac_set = 0;
7027   u32 bd_id;
7028   u8 bd_id_set = 0;
7029   u32 sw_if_index = 0;
7030   u8 sw_if_index_set = 0;
7031   u8 is_add = 1;
7032   u8 static_mac = 0;
7033   u8 filter_mac = 0;
7034   u8 bvi_mac = 0;
7035   int count = 1;
7036   f64 before = 0;
7037   int j;
7038
7039   /* Parse args required to build the message */
7040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7041     {
7042       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7043         mac_set = 1;
7044       else if (unformat (i, "bd_id %d", &bd_id))
7045         bd_id_set = 1;
7046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7047         sw_if_index_set = 1;
7048       else if (unformat (i, "sw_if"))
7049         {
7050           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7051             {
7052               if (unformat
7053                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7054                 sw_if_index_set = 1;
7055             }
7056           else
7057             break;
7058         }
7059       else if (unformat (i, "static"))
7060         static_mac = 1;
7061       else if (unformat (i, "filter"))
7062         {
7063           filter_mac = 1;
7064           static_mac = 1;
7065         }
7066       else if (unformat (i, "bvi"))
7067         {
7068           bvi_mac = 1;
7069           static_mac = 1;
7070         }
7071       else if (unformat (i, "del"))
7072         is_add = 0;
7073       else if (unformat (i, "count %d", &count))
7074         ;
7075       else
7076         break;
7077     }
7078
7079   if (mac_set == 0)
7080     {
7081       errmsg ("missing mac address");
7082       return -99;
7083     }
7084
7085   if (bd_id_set == 0)
7086     {
7087       errmsg ("missing bridge domain");
7088       return -99;
7089     }
7090
7091   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7092     {
7093       errmsg ("missing interface name or sw_if_index");
7094       return -99;
7095     }
7096
7097   if (count > 1)
7098     {
7099       /* Turn on async mode */
7100       vam->async_mode = 1;
7101       vam->async_errors = 0;
7102       before = vat_time_now (vam);
7103     }
7104
7105   for (j = 0; j < count; j++)
7106     {
7107       M (L2FIB_ADD_DEL, mp);
7108
7109       clib_memcpy (mp->mac, mac, 6);
7110       mp->bd_id = ntohl (bd_id);
7111       mp->is_add = is_add;
7112       mp->sw_if_index = ntohl (sw_if_index);
7113
7114       if (is_add)
7115         {
7116           mp->static_mac = static_mac;
7117           mp->filter_mac = filter_mac;
7118           mp->bvi_mac = bvi_mac;
7119         }
7120       increment_mac_address (mac);
7121       /* send it... */
7122       S (mp);
7123     }
7124
7125   if (count > 1)
7126     {
7127       vl_api_control_ping_t *mp_ping;
7128       f64 after;
7129
7130       /* Shut off async mode */
7131       vam->async_mode = 0;
7132
7133       MPING (CONTROL_PING, mp_ping);
7134       S (mp_ping);
7135
7136       timeout = vat_time_now (vam) + 1.0;
7137       while (vat_time_now (vam) < timeout)
7138         if (vam->result_ready == 1)
7139           goto out;
7140       vam->retval = -99;
7141
7142     out:
7143       if (vam->retval == -99)
7144         errmsg ("timeout");
7145
7146       if (vam->async_errors > 0)
7147         {
7148           errmsg ("%d asynchronous errors", vam->async_errors);
7149           vam->retval = -98;
7150         }
7151       vam->async_errors = 0;
7152       after = vat_time_now (vam);
7153
7154       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7155              count, after - before, count / (after - before));
7156     }
7157   else
7158     {
7159       int ret;
7160
7161       /* Wait for a reply... */
7162       W (ret);
7163       return ret;
7164     }
7165   /* Return the good/bad news */
7166   return (vam->retval);
7167 }
7168
7169 static int
7170 api_bridge_domain_set_mac_age (vat_main_t * vam)
7171 {
7172   unformat_input_t *i = vam->input;
7173   vl_api_bridge_domain_set_mac_age_t *mp;
7174   u32 bd_id = ~0;
7175   u32 mac_age = 0;
7176   int ret;
7177
7178   /* Parse args required to build the message */
7179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (i, "bd_id %d", &bd_id));
7182       else if (unformat (i, "mac-age %d", &mac_age));
7183       else
7184         break;
7185     }
7186
7187   if (bd_id == ~0)
7188     {
7189       errmsg ("missing bridge domain");
7190       return -99;
7191     }
7192
7193   if (mac_age > 255)
7194     {
7195       errmsg ("mac age must be less than 256 ");
7196       return -99;
7197     }
7198
7199   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7200
7201   mp->bd_id = htonl (bd_id);
7202   mp->mac_age = (u8) mac_age;
7203
7204   S (mp);
7205   W (ret);
7206   return ret;
7207 }
7208
7209 static int
7210 api_l2_flags (vat_main_t * vam)
7211 {
7212   unformat_input_t *i = vam->input;
7213   vl_api_l2_flags_t *mp;
7214   u32 sw_if_index;
7215   u32 flags = 0;
7216   u8 sw_if_index_set = 0;
7217   u8 is_set = 0;
7218   int ret;
7219
7220   /* Parse args required to build the message */
7221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7222     {
7223       if (unformat (i, "sw_if_index %d", &sw_if_index))
7224         sw_if_index_set = 1;
7225       else if (unformat (i, "sw_if"))
7226         {
7227           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228             {
7229               if (unformat
7230                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7231                 sw_if_index_set = 1;
7232             }
7233           else
7234             break;
7235         }
7236       else if (unformat (i, "learn"))
7237         flags |= L2_LEARN;
7238       else if (unformat (i, "forward"))
7239         flags |= L2_FWD;
7240       else if (unformat (i, "flood"))
7241         flags |= L2_FLOOD;
7242       else if (unformat (i, "uu-flood"))
7243         flags |= L2_UU_FLOOD;
7244       else if (unformat (i, "arp-term"))
7245         flags |= L2_ARP_TERM;
7246       else if (unformat (i, "off"))
7247         is_set = 0;
7248       else if (unformat (i, "disable"))
7249         is_set = 0;
7250       else
7251         break;
7252     }
7253
7254   if (sw_if_index_set == 0)
7255     {
7256       errmsg ("missing interface name or sw_if_index");
7257       return -99;
7258     }
7259
7260   M (L2_FLAGS, mp);
7261
7262   mp->sw_if_index = ntohl (sw_if_index);
7263   mp->feature_bitmap = ntohl (flags);
7264   mp->is_set = is_set;
7265
7266   S (mp);
7267   W (ret);
7268   return ret;
7269 }
7270
7271 static int
7272 api_bridge_flags (vat_main_t * vam)
7273 {
7274   unformat_input_t *i = vam->input;
7275   vl_api_bridge_flags_t *mp;
7276   u32 bd_id;
7277   u8 bd_id_set = 0;
7278   u8 is_set = 1;
7279   bd_flags_t flags = 0;
7280   int ret;
7281
7282   /* Parse args required to build the message */
7283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284     {
7285       if (unformat (i, "bd_id %d", &bd_id))
7286         bd_id_set = 1;
7287       else if (unformat (i, "learn"))
7288         flags |= BRIDGE_API_FLAG_LEARN;
7289       else if (unformat (i, "forward"))
7290         flags |= BRIDGE_API_FLAG_FWD;
7291       else if (unformat (i, "flood"))
7292         flags |= BRIDGE_API_FLAG_FLOOD;
7293       else if (unformat (i, "uu-flood"))
7294         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7295       else if (unformat (i, "arp-term"))
7296         flags |= BRIDGE_API_FLAG_ARP_TERM;
7297       else if (unformat (i, "off"))
7298         is_set = 0;
7299       else if (unformat (i, "disable"))
7300         is_set = 0;
7301       else
7302         break;
7303     }
7304
7305   if (bd_id_set == 0)
7306     {
7307       errmsg ("missing bridge domain");
7308       return -99;
7309     }
7310
7311   M (BRIDGE_FLAGS, mp);
7312
7313   mp->bd_id = ntohl (bd_id);
7314   mp->flags = ntohl (flags);
7315   mp->is_set = is_set;
7316
7317   S (mp);
7318   W (ret);
7319   return ret;
7320 }
7321
7322 static int
7323 api_bd_ip_mac_add_del (vat_main_t * vam)
7324 {
7325   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7326   vl_api_mac_address_t mac = VL_API_ZERO_MAC_ADDRESS;
7327   unformat_input_t *i = vam->input;
7328   vl_api_bd_ip_mac_add_del_t *mp;
7329   ip46_type_t type;
7330   u32 bd_id;
7331   u8 is_ipv6 = 0;
7332   u8 is_add = 1;
7333   u8 bd_id_set = 0;
7334   u8 ip_set = 0;
7335   u8 mac_set = 0;
7336   u8 macaddr[6];
7337   int ret;
7338
7339
7340   /* Parse args required to build the message */
7341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7342     {
7343       if (unformat (i, "bd_id %d", &bd_id))
7344         {
7345           bd_id_set++;
7346         }
7347       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7348         {
7349           ip_set++;
7350         }
7351       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7352         {
7353           mac_set++;
7354         }
7355       else if (unformat (i, "del"))
7356         is_add = 0;
7357       else
7358         break;
7359     }
7360
7361   if (bd_id_set == 0)
7362     {
7363       errmsg ("missing bridge domain");
7364       return -99;
7365     }
7366   else if (ip_set == 0)
7367     {
7368       errmsg ("missing IP address");
7369       return -99;
7370     }
7371   else if (mac_set == 0)
7372     {
7373       errmsg ("missing MAC address");
7374       return -99;
7375     }
7376
7377   M (BD_IP_MAC_ADD_DEL, mp);
7378
7379   mp->bd_id = ntohl (bd_id);
7380   mp->is_add = is_add;
7381
7382   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7383   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7384
7385   S (mp);
7386   W (ret);
7387   return ret;
7388 }
7389
7390 static void vl_api_bd_ip_mac_details_t_handler
7391   (vl_api_bd_ip_mac_details_t * mp)
7392 {
7393   vat_main_t *vam = &vat_main;
7394   u8 *ip = 0;
7395
7396   if (!mp->is_ipv6)
7397     ip =
7398       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7399   else
7400     ip =
7401       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7402
7403   print (vam->ofp,
7404          "\n%-5d %-7s %-20U %-30s",
7405          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7406          format_ethernet_address, mp->mac_address, ip);
7407
7408   vec_free (ip);
7409 }
7410
7411 static void vl_api_bd_ip_mac_details_t_handler_json
7412   (vl_api_bd_ip_mac_details_t * mp)
7413 {
7414   vat_main_t *vam = &vat_main;
7415   vat_json_node_t *node = NULL;
7416
7417   if (VAT_JSON_ARRAY != vam->json_tree.type)
7418     {
7419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7420       vat_json_init_array (&vam->json_tree);
7421     }
7422   node = vat_json_array_add (&vam->json_tree);
7423
7424   vat_json_init_object (node);
7425   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7426   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7427   vat_json_object_add_string_copy (node, "mac_address",
7428                                    format (0, "%U", format_ethernet_address,
7429                                            &mp->mac_address));
7430   u8 *ip = 0;
7431
7432   if (!mp->is_ipv6)
7433     ip =
7434       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7435   else
7436     ip =
7437       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7438   vat_json_object_add_string_copy (node, "ip_address", ip);
7439   vec_free (ip);
7440 }
7441
7442 static int
7443 api_bd_ip_mac_dump (vat_main_t * vam)
7444 {
7445   unformat_input_t *i = vam->input;
7446   vl_api_bd_ip_mac_dump_t *mp;
7447   vl_api_control_ping_t *mp_ping;
7448   int ret;
7449   u32 bd_id;
7450   u8 bd_id_set = 0;
7451
7452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7453     {
7454       if (unformat (i, "bd_id %d", &bd_id))
7455         {
7456           bd_id_set++;
7457         }
7458       else
7459         break;
7460     }
7461
7462   print (vam->ofp,
7463          "\n%-5s %-7s %-20s %-30s",
7464          "bd_id", "is_ipv6", "mac_address", "ip_address");
7465
7466   /* Dump Bridge Domain Ip to Mac entries */
7467   M (BD_IP_MAC_DUMP, mp);
7468
7469   if (bd_id_set)
7470     mp->bd_id = htonl (bd_id);
7471   else
7472     mp->bd_id = ~0;
7473
7474   S (mp);
7475
7476   /* Use a control ping for synchronization */
7477   MPING (CONTROL_PING, mp_ping);
7478   S (mp_ping);
7479
7480   W (ret);
7481   return ret;
7482 }
7483
7484 static int
7485 api_tap_connect (vat_main_t * vam)
7486 {
7487   unformat_input_t *i = vam->input;
7488   vl_api_tap_connect_t *mp;
7489   u8 mac_address[6];
7490   u8 random_mac = 1;
7491   u8 name_set = 0;
7492   u8 *tap_name;
7493   u8 *tag = 0;
7494   ip4_address_t ip4_address;
7495   u32 ip4_mask_width;
7496   int ip4_address_set = 0;
7497   ip6_address_t ip6_address;
7498   u32 ip6_mask_width;
7499   int ip6_address_set = 0;
7500   int ret;
7501
7502   clib_memset (mac_address, 0, sizeof (mac_address));
7503
7504   /* Parse args required to build the message */
7505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7506     {
7507       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7508         {
7509           random_mac = 0;
7510         }
7511       else if (unformat (i, "random-mac"))
7512         random_mac = 1;
7513       else if (unformat (i, "tapname %s", &tap_name))
7514         name_set = 1;
7515       else if (unformat (i, "tag %s", &tag))
7516         ;
7517       else if (unformat (i, "address %U/%d",
7518                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7519         ip4_address_set = 1;
7520       else if (unformat (i, "address %U/%d",
7521                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7522         ip6_address_set = 1;
7523       else
7524         break;
7525     }
7526
7527   if (name_set == 0)
7528     {
7529       errmsg ("missing tap name");
7530       return -99;
7531     }
7532   if (vec_len (tap_name) > 63)
7533     {
7534       errmsg ("tap name too long");
7535       return -99;
7536     }
7537   vec_add1 (tap_name, 0);
7538
7539   if (vec_len (tag) > 63)
7540     {
7541       errmsg ("tag too long");
7542       return -99;
7543     }
7544
7545   /* Construct the API message */
7546   M (TAP_CONNECT, mp);
7547
7548   mp->use_random_mac = random_mac;
7549   clib_memcpy (mp->mac_address, mac_address, 6);
7550   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7551   if (tag)
7552     clib_memcpy (mp->tag, tag, vec_len (tag));
7553
7554   if (ip4_address_set)
7555     {
7556       mp->ip4_address_set = 1;
7557       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7558       mp->ip4_mask_width = ip4_mask_width;
7559     }
7560   if (ip6_address_set)
7561     {
7562       mp->ip6_address_set = 1;
7563       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7564       mp->ip6_mask_width = ip6_mask_width;
7565     }
7566
7567   vec_free (tap_name);
7568   vec_free (tag);
7569
7570   /* send it... */
7571   S (mp);
7572
7573   /* Wait for a reply... */
7574   W (ret);
7575   return ret;
7576 }
7577
7578 static int
7579 api_tap_modify (vat_main_t * vam)
7580 {
7581   unformat_input_t *i = vam->input;
7582   vl_api_tap_modify_t *mp;
7583   u8 mac_address[6];
7584   u8 random_mac = 1;
7585   u8 name_set = 0;
7586   u8 *tap_name;
7587   u32 sw_if_index = ~0;
7588   u8 sw_if_index_set = 0;
7589   int ret;
7590
7591   clib_memset (mac_address, 0, sizeof (mac_address));
7592
7593   /* Parse args required to build the message */
7594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7595     {
7596       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7597         sw_if_index_set = 1;
7598       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7599         sw_if_index_set = 1;
7600       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7601         {
7602           random_mac = 0;
7603         }
7604       else if (unformat (i, "random-mac"))
7605         random_mac = 1;
7606       else if (unformat (i, "tapname %s", &tap_name))
7607         name_set = 1;
7608       else
7609         break;
7610     }
7611
7612   if (sw_if_index_set == 0)
7613     {
7614       errmsg ("missing vpp interface name");
7615       return -99;
7616     }
7617   if (name_set == 0)
7618     {
7619       errmsg ("missing tap name");
7620       return -99;
7621     }
7622   if (vec_len (tap_name) > 63)
7623     {
7624       errmsg ("tap name too long");
7625     }
7626   vec_add1 (tap_name, 0);
7627
7628   /* Construct the API message */
7629   M (TAP_MODIFY, mp);
7630
7631   mp->use_random_mac = random_mac;
7632   mp->sw_if_index = ntohl (sw_if_index);
7633   clib_memcpy (mp->mac_address, mac_address, 6);
7634   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7635   vec_free (tap_name);
7636
7637   /* send it... */
7638   S (mp);
7639
7640   /* Wait for a reply... */
7641   W (ret);
7642   return ret;
7643 }
7644
7645 static int
7646 api_tap_delete (vat_main_t * vam)
7647 {
7648   unformat_input_t *i = vam->input;
7649   vl_api_tap_delete_t *mp;
7650   u32 sw_if_index = ~0;
7651   u8 sw_if_index_set = 0;
7652   int ret;
7653
7654   /* Parse args required to build the message */
7655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7656     {
7657       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7658         sw_if_index_set = 1;
7659       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7660         sw_if_index_set = 1;
7661       else
7662         break;
7663     }
7664
7665   if (sw_if_index_set == 0)
7666     {
7667       errmsg ("missing vpp interface name");
7668       return -99;
7669     }
7670
7671   /* Construct the API message */
7672   M (TAP_DELETE, mp);
7673
7674   mp->sw_if_index = ntohl (sw_if_index);
7675
7676   /* send it... */
7677   S (mp);
7678
7679   /* Wait for a reply... */
7680   W (ret);
7681   return ret;
7682 }
7683
7684 static int
7685 api_tap_create_v2 (vat_main_t * vam)
7686 {
7687   unformat_input_t *i = vam->input;
7688   vl_api_tap_create_v2_t *mp;
7689   u8 mac_address[6];
7690   u8 random_mac = 1;
7691   u32 id = ~0;
7692   u8 *host_if_name = 0;
7693   u8 *host_ns = 0;
7694   u8 host_mac_addr[6];
7695   u8 host_mac_addr_set = 0;
7696   u8 *host_bridge = 0;
7697   ip4_address_t host_ip4_addr;
7698   ip4_address_t host_ip4_gw;
7699   u8 host_ip4_gw_set = 0;
7700   u32 host_ip4_prefix_len = 0;
7701   ip6_address_t host_ip6_addr;
7702   ip6_address_t host_ip6_gw;
7703   u8 host_ip6_gw_set = 0;
7704   u32 host_ip6_prefix_len = 0;
7705   int ret;
7706   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7707
7708   clib_memset (mac_address, 0, sizeof (mac_address));
7709
7710   /* Parse args required to build the message */
7711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712     {
7713       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7714         {
7715           random_mac = 0;
7716         }
7717       else if (unformat (i, "id %u", &id))
7718         ;
7719       else if (unformat (i, "host-if-name %s", &host_if_name))
7720         ;
7721       else if (unformat (i, "host-ns %s", &host_ns))
7722         ;
7723       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7724                          host_mac_addr))
7725         host_mac_addr_set = 1;
7726       else if (unformat (i, "host-bridge %s", &host_bridge))
7727         ;
7728       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7729                          &host_ip4_addr, &host_ip4_prefix_len))
7730         ;
7731       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7732                          &host_ip6_addr, &host_ip6_prefix_len))
7733         ;
7734       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7735                          &host_ip4_gw))
7736         host_ip4_gw_set = 1;
7737       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7738                          &host_ip6_gw))
7739         host_ip6_gw_set = 1;
7740       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7741         ;
7742       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7743         ;
7744       else
7745         break;
7746     }
7747
7748   if (vec_len (host_if_name) > 63)
7749     {
7750       errmsg ("tap name too long. ");
7751       return -99;
7752     }
7753   if (vec_len (host_ns) > 63)
7754     {
7755       errmsg ("host name space too long. ");
7756       return -99;
7757     }
7758   if (vec_len (host_bridge) > 63)
7759     {
7760       errmsg ("host bridge name too long. ");
7761       return -99;
7762     }
7763   if (host_ip4_prefix_len > 32)
7764     {
7765       errmsg ("host ip4 prefix length not valid. ");
7766       return -99;
7767     }
7768   if (host_ip6_prefix_len > 128)
7769     {
7770       errmsg ("host ip6 prefix length not valid. ");
7771       return -99;
7772     }
7773   if (!is_pow2 (rx_ring_sz))
7774     {
7775       errmsg ("rx ring size must be power of 2. ");
7776       return -99;
7777     }
7778   if (rx_ring_sz > 32768)
7779     {
7780       errmsg ("rx ring size must be 32768 or lower. ");
7781       return -99;
7782     }
7783   if (!is_pow2 (tx_ring_sz))
7784     {
7785       errmsg ("tx ring size must be power of 2. ");
7786       return -99;
7787     }
7788   if (tx_ring_sz > 32768)
7789     {
7790       errmsg ("tx ring size must be 32768 or lower. ");
7791       return -99;
7792     }
7793
7794   /* Construct the API message */
7795   M (TAP_CREATE_V2, mp);
7796
7797   mp->use_random_mac = random_mac;
7798
7799   mp->id = ntohl (id);
7800   mp->host_namespace_set = host_ns != 0;
7801   mp->host_bridge_set = host_bridge != 0;
7802   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7803   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7804   mp->rx_ring_sz = ntohs (rx_ring_sz);
7805   mp->tx_ring_sz = ntohs (tx_ring_sz);
7806
7807   if (random_mac == 0)
7808     clib_memcpy (mp->mac_address, mac_address, 6);
7809   if (host_mac_addr_set)
7810     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7811   if (host_if_name)
7812     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7813   if (host_ns)
7814     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7815   if (host_bridge)
7816     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7817   if (host_ip4_prefix_len)
7818     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7819   if (host_ip6_prefix_len)
7820     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7821   if (host_ip4_gw_set)
7822     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7823   if (host_ip6_gw_set)
7824     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7825
7826   vec_free (host_ns);
7827   vec_free (host_if_name);
7828   vec_free (host_bridge);
7829
7830   /* send it... */
7831   S (mp);
7832
7833   /* Wait for a reply... */
7834   W (ret);
7835   return ret;
7836 }
7837
7838 static int
7839 api_tap_delete_v2 (vat_main_t * vam)
7840 {
7841   unformat_input_t *i = vam->input;
7842   vl_api_tap_delete_v2_t *mp;
7843   u32 sw_if_index = ~0;
7844   u8 sw_if_index_set = 0;
7845   int ret;
7846
7847   /* Parse args required to build the message */
7848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7849     {
7850       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7851         sw_if_index_set = 1;
7852       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7853         sw_if_index_set = 1;
7854       else
7855         break;
7856     }
7857
7858   if (sw_if_index_set == 0)
7859     {
7860       errmsg ("missing vpp interface name. ");
7861       return -99;
7862     }
7863
7864   /* Construct the API message */
7865   M (TAP_DELETE_V2, mp);
7866
7867   mp->sw_if_index = ntohl (sw_if_index);
7868
7869   /* send it... */
7870   S (mp);
7871
7872   /* Wait for a reply... */
7873   W (ret);
7874   return ret;
7875 }
7876
7877 static int
7878 api_bond_create (vat_main_t * vam)
7879 {
7880   unformat_input_t *i = vam->input;
7881   vl_api_bond_create_t *mp;
7882   u8 mac_address[6];
7883   u8 custom_mac = 0;
7884   int ret;
7885   u8 mode;
7886   u8 lb;
7887   u8 mode_is_set = 0;
7888
7889   clib_memset (mac_address, 0, sizeof (mac_address));
7890   lb = BOND_LB_L2;
7891
7892   /* Parse args required to build the message */
7893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7894     {
7895       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7896         mode_is_set = 1;
7897       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7898                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7899         ;
7900       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7901                          mac_address))
7902         custom_mac = 1;
7903       else
7904         break;
7905     }
7906
7907   if (mode_is_set == 0)
7908     {
7909       errmsg ("Missing bond mode. ");
7910       return -99;
7911     }
7912
7913   /* Construct the API message */
7914   M (BOND_CREATE, mp);
7915
7916   mp->use_custom_mac = custom_mac;
7917
7918   mp->mode = mode;
7919   mp->lb = lb;
7920
7921   if (custom_mac)
7922     clib_memcpy (mp->mac_address, mac_address, 6);
7923
7924   /* send it... */
7925   S (mp);
7926
7927   /* Wait for a reply... */
7928   W (ret);
7929   return ret;
7930 }
7931
7932 static int
7933 api_bond_delete (vat_main_t * vam)
7934 {
7935   unformat_input_t *i = vam->input;
7936   vl_api_bond_delete_t *mp;
7937   u32 sw_if_index = ~0;
7938   u8 sw_if_index_set = 0;
7939   int ret;
7940
7941   /* Parse args required to build the message */
7942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7943     {
7944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7945         sw_if_index_set = 1;
7946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7947         sw_if_index_set = 1;
7948       else
7949         break;
7950     }
7951
7952   if (sw_if_index_set == 0)
7953     {
7954       errmsg ("missing vpp interface name. ");
7955       return -99;
7956     }
7957
7958   /* Construct the API message */
7959   M (BOND_DELETE, mp);
7960
7961   mp->sw_if_index = ntohl (sw_if_index);
7962
7963   /* send it... */
7964   S (mp);
7965
7966   /* Wait for a reply... */
7967   W (ret);
7968   return ret;
7969 }
7970
7971 static int
7972 api_bond_enslave (vat_main_t * vam)
7973 {
7974   unformat_input_t *i = vam->input;
7975   vl_api_bond_enslave_t *mp;
7976   u32 bond_sw_if_index;
7977   int ret;
7978   u8 is_passive;
7979   u8 is_long_timeout;
7980   u32 bond_sw_if_index_is_set = 0;
7981   u32 sw_if_index;
7982   u8 sw_if_index_is_set = 0;
7983
7984   /* Parse args required to build the message */
7985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7986     {
7987       if (unformat (i, "sw_if_index %d", &sw_if_index))
7988         sw_if_index_is_set = 1;
7989       else if (unformat (i, "bond %u", &bond_sw_if_index))
7990         bond_sw_if_index_is_set = 1;
7991       else if (unformat (i, "passive %d", &is_passive))
7992         ;
7993       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7994         ;
7995       else
7996         break;
7997     }
7998
7999   if (bond_sw_if_index_is_set == 0)
8000     {
8001       errmsg ("Missing bond sw_if_index. ");
8002       return -99;
8003     }
8004   if (sw_if_index_is_set == 0)
8005     {
8006       errmsg ("Missing slave sw_if_index. ");
8007       return -99;
8008     }
8009
8010   /* Construct the API message */
8011   M (BOND_ENSLAVE, mp);
8012
8013   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8014   mp->sw_if_index = ntohl (sw_if_index);
8015   mp->is_long_timeout = is_long_timeout;
8016   mp->is_passive = is_passive;
8017
8018   /* send it... */
8019   S (mp);
8020
8021   /* Wait for a reply... */
8022   W (ret);
8023   return ret;
8024 }
8025
8026 static int
8027 api_bond_detach_slave (vat_main_t * vam)
8028 {
8029   unformat_input_t *i = vam->input;
8030   vl_api_bond_detach_slave_t *mp;
8031   u32 sw_if_index = ~0;
8032   u8 sw_if_index_set = 0;
8033   int ret;
8034
8035   /* Parse args required to build the message */
8036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8037     {
8038       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8039         sw_if_index_set = 1;
8040       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8041         sw_if_index_set = 1;
8042       else
8043         break;
8044     }
8045
8046   if (sw_if_index_set == 0)
8047     {
8048       errmsg ("missing vpp interface name. ");
8049       return -99;
8050     }
8051
8052   /* Construct the API message */
8053   M (BOND_DETACH_SLAVE, mp);
8054
8055   mp->sw_if_index = ntohl (sw_if_index);
8056
8057   /* send it... */
8058   S (mp);
8059
8060   /* Wait for a reply... */
8061   W (ret);
8062   return ret;
8063 }
8064
8065 static int
8066 api_ip_table_add_del (vat_main_t * vam)
8067 {
8068   unformat_input_t *i = vam->input;
8069   vl_api_ip_table_add_del_t *mp;
8070   u32 table_id = ~0;
8071   u8 is_ipv6 = 0;
8072   u8 is_add = 1;
8073   int ret = 0;
8074
8075   /* Parse args required to build the message */
8076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8077     {
8078       if (unformat (i, "ipv6"))
8079         is_ipv6 = 1;
8080       else if (unformat (i, "del"))
8081         is_add = 0;
8082       else if (unformat (i, "add"))
8083         is_add = 1;
8084       else if (unformat (i, "table %d", &table_id))
8085         ;
8086       else
8087         {
8088           clib_warning ("parse error '%U'", format_unformat_error, i);
8089           return -99;
8090         }
8091     }
8092
8093   if (~0 == table_id)
8094     {
8095       errmsg ("missing table-ID");
8096       return -99;
8097     }
8098
8099   /* Construct the API message */
8100   M (IP_TABLE_ADD_DEL, mp);
8101
8102   mp->table_id = ntohl (table_id);
8103   mp->is_ipv6 = is_ipv6;
8104   mp->is_add = is_add;
8105
8106   /* send it... */
8107   S (mp);
8108
8109   /* Wait for a reply... */
8110   W (ret);
8111
8112   return ret;
8113 }
8114
8115 static int
8116 api_ip_add_del_route (vat_main_t * vam)
8117 {
8118   unformat_input_t *i = vam->input;
8119   vl_api_ip_add_del_route_t *mp;
8120   u32 sw_if_index = ~0, vrf_id = 0;
8121   u8 is_ipv6 = 0;
8122   u8 is_local = 0, is_drop = 0;
8123   u8 is_unreach = 0, is_prohibit = 0;
8124   u8 is_add = 1;
8125   u32 next_hop_weight = 1;
8126   u8 is_multipath = 0;
8127   u8 address_set = 0;
8128   u8 address_length_set = 0;
8129   u32 next_hop_table_id = 0;
8130   u32 resolve_attempts = 0;
8131   u32 dst_address_length = 0;
8132   u8 next_hop_set = 0;
8133   ip4_address_t v4_dst_address, v4_next_hop_address;
8134   ip6_address_t v6_dst_address, v6_next_hop_address;
8135   int count = 1;
8136   int j;
8137   f64 before = 0;
8138   u32 random_add_del = 0;
8139   u32 *random_vector = 0;
8140   uword *random_hash;
8141   u32 random_seed = 0xdeaddabe;
8142   u32 classify_table_index = ~0;
8143   u8 is_classify = 0;
8144   u8 resolve_host = 0, resolve_attached = 0;
8145   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8146   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8147   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8148
8149   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8150   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8151   /* Parse args required to build the message */
8152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8153     {
8154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8155         ;
8156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8157         ;
8158       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8159         {
8160           address_set = 1;
8161           is_ipv6 = 0;
8162         }
8163       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8164         {
8165           address_set = 1;
8166           is_ipv6 = 1;
8167         }
8168       else if (unformat (i, "/%d", &dst_address_length))
8169         {
8170           address_length_set = 1;
8171         }
8172
8173       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8174                                          &v4_next_hop_address))
8175         {
8176           next_hop_set = 1;
8177         }
8178       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8179                                          &v6_next_hop_address))
8180         {
8181           next_hop_set = 1;
8182         }
8183       else
8184         if (unformat
8185             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8186         {
8187           next_hop_set = 1;
8188         }
8189       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8190         {
8191           next_hop_set = 1;
8192         }
8193       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8194         ;
8195       else if (unformat (i, "weight %d", &next_hop_weight))
8196         ;
8197       else if (unformat (i, "drop"))
8198         {
8199           is_drop = 1;
8200         }
8201       else if (unformat (i, "null-send-unreach"))
8202         {
8203           is_unreach = 1;
8204         }
8205       else if (unformat (i, "null-send-prohibit"))
8206         {
8207           is_prohibit = 1;
8208         }
8209       else if (unformat (i, "local"))
8210         {
8211           is_local = 1;
8212         }
8213       else if (unformat (i, "classify %d", &classify_table_index))
8214         {
8215           is_classify = 1;
8216         }
8217       else if (unformat (i, "del"))
8218         is_add = 0;
8219       else if (unformat (i, "add"))
8220         is_add = 1;
8221       else if (unformat (i, "resolve-via-host"))
8222         resolve_host = 1;
8223       else if (unformat (i, "resolve-via-attached"))
8224         resolve_attached = 1;
8225       else if (unformat (i, "multipath"))
8226         is_multipath = 1;
8227       else if (unformat (i, "vrf %d", &vrf_id))
8228         ;
8229       else if (unformat (i, "count %d", &count))
8230         ;
8231       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8232         ;
8233       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8234         ;
8235       else if (unformat (i, "out-label %d", &next_hop_out_label))
8236         {
8237           vl_api_fib_mpls_label_t fib_label = {
8238             .label = ntohl (next_hop_out_label),
8239             .ttl = 64,
8240             .exp = 0,
8241           };
8242           vec_add1 (next_hop_out_label_stack, fib_label);
8243         }
8244       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8245         ;
8246       else if (unformat (i, "random"))
8247         random_add_del = 1;
8248       else if (unformat (i, "seed %d", &random_seed))
8249         ;
8250       else
8251         {
8252           clib_warning ("parse error '%U'", format_unformat_error, i);
8253           return -99;
8254         }
8255     }
8256
8257   if (!next_hop_set && !is_drop && !is_local &&
8258       !is_classify && !is_unreach && !is_prohibit &&
8259       MPLS_LABEL_INVALID == next_hop_via_label)
8260     {
8261       errmsg
8262         ("next hop / local / drop / unreach / prohibit / classify not set");
8263       return -99;
8264     }
8265
8266   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8267     {
8268       errmsg ("next hop and next-hop via label set");
8269       return -99;
8270     }
8271   if (address_set == 0)
8272     {
8273       errmsg ("missing addresses");
8274       return -99;
8275     }
8276
8277   if (address_length_set == 0)
8278     {
8279       errmsg ("missing address length");
8280       return -99;
8281     }
8282
8283   /* Generate a pile of unique, random routes */
8284   if (random_add_del)
8285     {
8286       u32 this_random_address;
8287       random_hash = hash_create (count, sizeof (uword));
8288
8289       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8290       for (j = 0; j <= count; j++)
8291         {
8292           do
8293             {
8294               this_random_address = random_u32 (&random_seed);
8295               this_random_address =
8296                 clib_host_to_net_u32 (this_random_address);
8297             }
8298           while (hash_get (random_hash, this_random_address));
8299           vec_add1 (random_vector, this_random_address);
8300           hash_set (random_hash, this_random_address, 1);
8301         }
8302       hash_free (random_hash);
8303       v4_dst_address.as_u32 = random_vector[0];
8304     }
8305
8306   if (count > 1)
8307     {
8308       /* Turn on async mode */
8309       vam->async_mode = 1;
8310       vam->async_errors = 0;
8311       before = vat_time_now (vam);
8312     }
8313
8314   for (j = 0; j < count; j++)
8315     {
8316       /* Construct the API message */
8317       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8318           vec_len (next_hop_out_label_stack));
8319
8320       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8321       mp->table_id = ntohl (vrf_id);
8322
8323       mp->is_add = is_add;
8324       mp->is_drop = is_drop;
8325       mp->is_unreach = is_unreach;
8326       mp->is_prohibit = is_prohibit;
8327       mp->is_ipv6 = is_ipv6;
8328       mp->is_local = is_local;
8329       mp->is_classify = is_classify;
8330       mp->is_multipath = is_multipath;
8331       mp->is_resolve_host = resolve_host;
8332       mp->is_resolve_attached = resolve_attached;
8333       mp->next_hop_weight = next_hop_weight;
8334       mp->next_hop_preference = 0;
8335       mp->dst_address_length = dst_address_length;
8336       mp->next_hop_table_id = ntohl (next_hop_table_id);
8337       mp->classify_table_index = ntohl (classify_table_index);
8338       mp->next_hop_via_label = ntohl (next_hop_via_label);
8339       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8340       if (0 != mp->next_hop_n_out_labels)
8341         {
8342           memcpy (mp->next_hop_out_label_stack,
8343                   next_hop_out_label_stack,
8344                   (vec_len (next_hop_out_label_stack) *
8345                    sizeof (vl_api_fib_mpls_label_t)));
8346           vec_free (next_hop_out_label_stack);
8347         }
8348
8349       if (is_ipv6)
8350         {
8351           clib_memcpy (mp->dst_address, &v6_dst_address,
8352                        sizeof (v6_dst_address));
8353           if (next_hop_set)
8354             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8355                          sizeof (v6_next_hop_address));
8356           increment_v6_address (&v6_dst_address);
8357         }
8358       else
8359         {
8360           clib_memcpy (mp->dst_address, &v4_dst_address,
8361                        sizeof (v4_dst_address));
8362           if (next_hop_set)
8363             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8364                          sizeof (v4_next_hop_address));
8365           if (random_add_del)
8366             v4_dst_address.as_u32 = random_vector[j + 1];
8367           else
8368             increment_v4_address (&v4_dst_address);
8369         }
8370       /* send it... */
8371       S (mp);
8372       /* If we receive SIGTERM, stop now... */
8373       if (vam->do_exit)
8374         break;
8375     }
8376
8377   /* When testing multiple add/del ops, use a control-ping to sync */
8378   if (count > 1)
8379     {
8380       vl_api_control_ping_t *mp_ping;
8381       f64 after;
8382       f64 timeout;
8383
8384       /* Shut off async mode */
8385       vam->async_mode = 0;
8386
8387       MPING (CONTROL_PING, mp_ping);
8388       S (mp_ping);
8389
8390       timeout = vat_time_now (vam) + 1.0;
8391       while (vat_time_now (vam) < timeout)
8392         if (vam->result_ready == 1)
8393           goto out;
8394       vam->retval = -99;
8395
8396     out:
8397       if (vam->retval == -99)
8398         errmsg ("timeout");
8399
8400       if (vam->async_errors > 0)
8401         {
8402           errmsg ("%d asynchronous errors", vam->async_errors);
8403           vam->retval = -98;
8404         }
8405       vam->async_errors = 0;
8406       after = vat_time_now (vam);
8407
8408       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8409       if (j > 0)
8410         count = j;
8411
8412       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8413              count, after - before, count / (after - before));
8414     }
8415   else
8416     {
8417       int ret;
8418
8419       /* Wait for a reply... */
8420       W (ret);
8421       return ret;
8422     }
8423
8424   /* Return the good/bad news */
8425   return (vam->retval);
8426 }
8427
8428 static int
8429 api_ip_mroute_add_del (vat_main_t * vam)
8430 {
8431   unformat_input_t *i = vam->input;
8432   vl_api_ip_mroute_add_del_t *mp;
8433   u32 sw_if_index = ~0, vrf_id = 0;
8434   u8 is_ipv6 = 0;
8435   u8 is_local = 0;
8436   u8 is_add = 1;
8437   u8 address_set = 0;
8438   u32 grp_address_length = 0;
8439   ip4_address_t v4_grp_address, v4_src_address;
8440   ip6_address_t v6_grp_address, v6_src_address;
8441   mfib_itf_flags_t iflags = 0;
8442   mfib_entry_flags_t eflags = 0;
8443   int ret;
8444
8445   /* Parse args required to build the message */
8446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8447     {
8448       if (unformat (i, "sw_if_index %d", &sw_if_index))
8449         ;
8450       else if (unformat (i, "%U %U",
8451                          unformat_ip4_address, &v4_src_address,
8452                          unformat_ip4_address, &v4_grp_address))
8453         {
8454           grp_address_length = 64;
8455           address_set = 1;
8456           is_ipv6 = 0;
8457         }
8458       else if (unformat (i, "%U %U",
8459                          unformat_ip6_address, &v6_src_address,
8460                          unformat_ip6_address, &v6_grp_address))
8461         {
8462           grp_address_length = 256;
8463           address_set = 1;
8464           is_ipv6 = 1;
8465         }
8466       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8467         {
8468           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8469           grp_address_length = 32;
8470           address_set = 1;
8471           is_ipv6 = 0;
8472         }
8473       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8474         {
8475           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8476           grp_address_length = 128;
8477           address_set = 1;
8478           is_ipv6 = 1;
8479         }
8480       else if (unformat (i, "/%d", &grp_address_length))
8481         ;
8482       else if (unformat (i, "local"))
8483         {
8484           is_local = 1;
8485         }
8486       else if (unformat (i, "del"))
8487         is_add = 0;
8488       else if (unformat (i, "add"))
8489         is_add = 1;
8490       else if (unformat (i, "vrf %d", &vrf_id))
8491         ;
8492       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8493         ;
8494       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8495         ;
8496       else
8497         {
8498           clib_warning ("parse error '%U'", format_unformat_error, i);
8499           return -99;
8500         }
8501     }
8502
8503   if (address_set == 0)
8504     {
8505       errmsg ("missing addresses\n");
8506       return -99;
8507     }
8508
8509   /* Construct the API message */
8510   M (IP_MROUTE_ADD_DEL, mp);
8511
8512   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8513   mp->table_id = ntohl (vrf_id);
8514
8515   mp->is_add = is_add;
8516   mp->is_ipv6 = is_ipv6;
8517   mp->is_local = is_local;
8518   mp->itf_flags = ntohl (iflags);
8519   mp->entry_flags = ntohl (eflags);
8520   mp->grp_address_length = grp_address_length;
8521   mp->grp_address_length = ntohs (mp->grp_address_length);
8522
8523   if (is_ipv6)
8524     {
8525       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8526       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8527     }
8528   else
8529     {
8530       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8531       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8532
8533     }
8534
8535   /* send it... */
8536   S (mp);
8537   /* Wait for a reply... */
8538   W (ret);
8539   return ret;
8540 }
8541
8542 static int
8543 api_mpls_table_add_del (vat_main_t * vam)
8544 {
8545   unformat_input_t *i = vam->input;
8546   vl_api_mpls_table_add_del_t *mp;
8547   u32 table_id = ~0;
8548   u8 is_add = 1;
8549   int ret = 0;
8550
8551   /* Parse args required to build the message */
8552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8553     {
8554       if (unformat (i, "table %d", &table_id))
8555         ;
8556       else if (unformat (i, "del"))
8557         is_add = 0;
8558       else if (unformat (i, "add"))
8559         is_add = 1;
8560       else
8561         {
8562           clib_warning ("parse error '%U'", format_unformat_error, i);
8563           return -99;
8564         }
8565     }
8566
8567   if (~0 == table_id)
8568     {
8569       errmsg ("missing table-ID");
8570       return -99;
8571     }
8572
8573   /* Construct the API message */
8574   M (MPLS_TABLE_ADD_DEL, mp);
8575
8576   mp->mt_table_id = ntohl (table_id);
8577   mp->mt_is_add = is_add;
8578
8579   /* send it... */
8580   S (mp);
8581
8582   /* Wait for a reply... */
8583   W (ret);
8584
8585   return ret;
8586 }
8587
8588 static int
8589 api_mpls_route_add_del (vat_main_t * vam)
8590 {
8591   unformat_input_t *i = vam->input;
8592   vl_api_mpls_route_add_del_t *mp;
8593   u32 sw_if_index = ~0, table_id = 0;
8594   u8 is_add = 1;
8595   u32 next_hop_weight = 1;
8596   u8 is_multipath = 0;
8597   u32 next_hop_table_id = 0;
8598   u8 next_hop_set = 0;
8599   ip4_address_t v4_next_hop_address = {
8600     .as_u32 = 0,
8601   };
8602   ip6_address_t v6_next_hop_address = { {0} };
8603   int count = 1;
8604   int j;
8605   f64 before = 0;
8606   u32 classify_table_index = ~0;
8607   u8 is_classify = 0;
8608   u8 resolve_host = 0, resolve_attached = 0;
8609   u8 is_interface_rx = 0;
8610   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8611   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8612   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8613   mpls_label_t local_label = MPLS_LABEL_INVALID;
8614   u8 is_eos = 0;
8615   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8616
8617   /* Parse args required to build the message */
8618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8619     {
8620       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8621         ;
8622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8623         ;
8624       else if (unformat (i, "%d", &local_label))
8625         ;
8626       else if (unformat (i, "eos"))
8627         is_eos = 1;
8628       else if (unformat (i, "non-eos"))
8629         is_eos = 0;
8630       else if (unformat (i, "via %U", unformat_ip4_address,
8631                          &v4_next_hop_address))
8632         {
8633           next_hop_set = 1;
8634           next_hop_proto = DPO_PROTO_IP4;
8635         }
8636       else if (unformat (i, "via %U", unformat_ip6_address,
8637                          &v6_next_hop_address))
8638         {
8639           next_hop_set = 1;
8640           next_hop_proto = DPO_PROTO_IP6;
8641         }
8642       else if (unformat (i, "weight %d", &next_hop_weight))
8643         ;
8644       else if (unformat (i, "classify %d", &classify_table_index))
8645         {
8646           is_classify = 1;
8647         }
8648       else if (unformat (i, "del"))
8649         is_add = 0;
8650       else if (unformat (i, "add"))
8651         is_add = 1;
8652       else if (unformat (i, "resolve-via-host"))
8653         resolve_host = 1;
8654       else if (unformat (i, "resolve-via-attached"))
8655         resolve_attached = 1;
8656       else if (unformat (i, "multipath"))
8657         is_multipath = 1;
8658       else if (unformat (i, "count %d", &count))
8659         ;
8660       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8661         {
8662           next_hop_set = 1;
8663           next_hop_proto = DPO_PROTO_IP4;
8664         }
8665       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8666         {
8667           next_hop_set = 1;
8668           next_hop_proto = DPO_PROTO_IP6;
8669         }
8670       else
8671         if (unformat
8672             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8673              &sw_if_index))
8674         {
8675           next_hop_set = 1;
8676           next_hop_proto = DPO_PROTO_ETHERNET;
8677           is_interface_rx = 1;
8678         }
8679       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8680         {
8681           next_hop_set = 1;
8682           next_hop_proto = DPO_PROTO_ETHERNET;
8683           is_interface_rx = 1;
8684         }
8685       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8686         next_hop_set = 1;
8687       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8688         next_hop_set = 1;
8689       else if (unformat (i, "out-label %d", &next_hop_out_label))
8690         {
8691           vl_api_fib_mpls_label_t fib_label = {
8692             .label = ntohl (next_hop_out_label),
8693             .ttl = 64,
8694             .exp = 0,
8695           };
8696           vec_add1 (next_hop_out_label_stack, fib_label);
8697         }
8698       else
8699         {
8700           clib_warning ("parse error '%U'", format_unformat_error, i);
8701           return -99;
8702         }
8703     }
8704
8705   if (!next_hop_set && !is_classify)
8706     {
8707       errmsg ("next hop / classify not set");
8708       return -99;
8709     }
8710
8711   if (MPLS_LABEL_INVALID == local_label)
8712     {
8713       errmsg ("missing label");
8714       return -99;
8715     }
8716
8717   if (count > 1)
8718     {
8719       /* Turn on async mode */
8720       vam->async_mode = 1;
8721       vam->async_errors = 0;
8722       before = vat_time_now (vam);
8723     }
8724
8725   for (j = 0; j < count; j++)
8726     {
8727       /* Construct the API message */
8728       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8729           vec_len (next_hop_out_label_stack));
8730
8731       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8732       mp->mr_table_id = ntohl (table_id);
8733
8734       mp->mr_is_add = is_add;
8735       mp->mr_next_hop_proto = next_hop_proto;
8736       mp->mr_is_classify = is_classify;
8737       mp->mr_is_multipath = is_multipath;
8738       mp->mr_is_resolve_host = resolve_host;
8739       mp->mr_is_resolve_attached = resolve_attached;
8740       mp->mr_is_interface_rx = is_interface_rx;
8741       mp->mr_next_hop_weight = next_hop_weight;
8742       mp->mr_next_hop_preference = 0;
8743       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8744       mp->mr_classify_table_index = ntohl (classify_table_index);
8745       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8746       mp->mr_label = ntohl (local_label);
8747       mp->mr_eos = is_eos;
8748
8749       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8750       if (0 != mp->mr_next_hop_n_out_labels)
8751         {
8752           memcpy (mp->mr_next_hop_out_label_stack,
8753                   next_hop_out_label_stack,
8754                   vec_len (next_hop_out_label_stack) *
8755                   sizeof (vl_api_fib_mpls_label_t));
8756           vec_free (next_hop_out_label_stack);
8757         }
8758
8759       if (next_hop_set)
8760         {
8761           if (DPO_PROTO_IP4 == next_hop_proto)
8762             {
8763               clib_memcpy (mp->mr_next_hop,
8764                            &v4_next_hop_address,
8765                            sizeof (v4_next_hop_address));
8766             }
8767           else if (DPO_PROTO_IP6 == next_hop_proto)
8768
8769             {
8770               clib_memcpy (mp->mr_next_hop,
8771                            &v6_next_hop_address,
8772                            sizeof (v6_next_hop_address));
8773             }
8774         }
8775       local_label++;
8776
8777       /* send it... */
8778       S (mp);
8779       /* If we receive SIGTERM, stop now... */
8780       if (vam->do_exit)
8781         break;
8782     }
8783
8784   /* When testing multiple add/del ops, use a control-ping to sync */
8785   if (count > 1)
8786     {
8787       vl_api_control_ping_t *mp_ping;
8788       f64 after;
8789       f64 timeout;
8790
8791       /* Shut off async mode */
8792       vam->async_mode = 0;
8793
8794       MPING (CONTROL_PING, mp_ping);
8795       S (mp_ping);
8796
8797       timeout = vat_time_now (vam) + 1.0;
8798       while (vat_time_now (vam) < timeout)
8799         if (vam->result_ready == 1)
8800           goto out;
8801       vam->retval = -99;
8802
8803     out:
8804       if (vam->retval == -99)
8805         errmsg ("timeout");
8806
8807       if (vam->async_errors > 0)
8808         {
8809           errmsg ("%d asynchronous errors", vam->async_errors);
8810           vam->retval = -98;
8811         }
8812       vam->async_errors = 0;
8813       after = vat_time_now (vam);
8814
8815       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8816       if (j > 0)
8817         count = j;
8818
8819       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8820              count, after - before, count / (after - before));
8821     }
8822   else
8823     {
8824       int ret;
8825
8826       /* Wait for a reply... */
8827       W (ret);
8828       return ret;
8829     }
8830
8831   /* Return the good/bad news */
8832   return (vam->retval);
8833 }
8834
8835 static int
8836 api_mpls_ip_bind_unbind (vat_main_t * vam)
8837 {
8838   unformat_input_t *i = vam->input;
8839   vl_api_mpls_ip_bind_unbind_t *mp;
8840   u32 ip_table_id = 0;
8841   u8 is_bind = 1;
8842   u8 is_ip4 = 1;
8843   ip4_address_t v4_address;
8844   ip6_address_t v6_address;
8845   u32 address_length;
8846   u8 address_set = 0;
8847   mpls_label_t local_label = MPLS_LABEL_INVALID;
8848   int ret;
8849
8850   /* Parse args required to build the message */
8851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8852     {
8853       if (unformat (i, "%U/%d", unformat_ip4_address,
8854                     &v4_address, &address_length))
8855         {
8856           is_ip4 = 1;
8857           address_set = 1;
8858         }
8859       else if (unformat (i, "%U/%d", unformat_ip6_address,
8860                          &v6_address, &address_length))
8861         {
8862           is_ip4 = 0;
8863           address_set = 1;
8864         }
8865       else if (unformat (i, "%d", &local_label))
8866         ;
8867       else if (unformat (i, "table-id %d", &ip_table_id))
8868         ;
8869       else if (unformat (i, "unbind"))
8870         is_bind = 0;
8871       else if (unformat (i, "bind"))
8872         is_bind = 1;
8873       else
8874         {
8875           clib_warning ("parse error '%U'", format_unformat_error, i);
8876           return -99;
8877         }
8878     }
8879
8880   if (!address_set)
8881     {
8882       errmsg ("IP address not set");
8883       return -99;
8884     }
8885
8886   if (MPLS_LABEL_INVALID == local_label)
8887     {
8888       errmsg ("missing label");
8889       return -99;
8890     }
8891
8892   /* Construct the API message */
8893   M (MPLS_IP_BIND_UNBIND, mp);
8894
8895   mp->mb_is_bind = is_bind;
8896   mp->mb_is_ip4 = is_ip4;
8897   mp->mb_ip_table_id = ntohl (ip_table_id);
8898   mp->mb_mpls_table_id = 0;
8899   mp->mb_label = ntohl (local_label);
8900   mp->mb_address_length = address_length;
8901
8902   if (is_ip4)
8903     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8904   else
8905     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8906
8907   /* send it... */
8908   S (mp);
8909
8910   /* Wait for a reply... */
8911   W (ret);
8912   return ret;
8913 }
8914
8915 static int
8916 api_sr_mpls_policy_add (vat_main_t * vam)
8917 {
8918   unformat_input_t *i = vam->input;
8919   vl_api_sr_mpls_policy_add_t *mp;
8920   u32 bsid = 0;
8921   u32 weight = 1;
8922   u8 type = 0;
8923   u8 n_segments = 0;
8924   u32 sid;
8925   u32 *segments = NULL;
8926   int ret;
8927
8928   /* Parse args required to build the message */
8929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8930     {
8931       if (unformat (i, "bsid %d", &bsid))
8932         ;
8933       else if (unformat (i, "weight %d", &weight))
8934         ;
8935       else if (unformat (i, "spray"))
8936         type = 1;
8937       else if (unformat (i, "next %d", &sid))
8938         {
8939           n_segments += 1;
8940           vec_add1 (segments, htonl (sid));
8941         }
8942       else
8943         {
8944           clib_warning ("parse error '%U'", format_unformat_error, i);
8945           return -99;
8946         }
8947     }
8948
8949   if (bsid == 0)
8950     {
8951       errmsg ("bsid not set");
8952       return -99;
8953     }
8954
8955   if (n_segments == 0)
8956     {
8957       errmsg ("no sid in segment stack");
8958       return -99;
8959     }
8960
8961   /* Construct the API message */
8962   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8963
8964   mp->bsid = htonl (bsid);
8965   mp->weight = htonl (weight);
8966   mp->type = type;
8967   mp->n_segments = n_segments;
8968   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8969   vec_free (segments);
8970
8971   /* send it... */
8972   S (mp);
8973
8974   /* Wait for a reply... */
8975   W (ret);
8976   return ret;
8977 }
8978
8979 static int
8980 api_sr_mpls_policy_del (vat_main_t * vam)
8981 {
8982   unformat_input_t *i = vam->input;
8983   vl_api_sr_mpls_policy_del_t *mp;
8984   u32 bsid = 0;
8985   int ret;
8986
8987   /* Parse args required to build the message */
8988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8989     {
8990       if (unformat (i, "bsid %d", &bsid))
8991         ;
8992       else
8993         {
8994           clib_warning ("parse error '%U'", format_unformat_error, i);
8995           return -99;
8996         }
8997     }
8998
8999   if (bsid == 0)
9000     {
9001       errmsg ("bsid not set");
9002       return -99;
9003     }
9004
9005   /* Construct the API message */
9006   M (SR_MPLS_POLICY_DEL, mp);
9007
9008   mp->bsid = htonl (bsid);
9009
9010   /* send it... */
9011   S (mp);
9012
9013   /* Wait for a reply... */
9014   W (ret);
9015   return ret;
9016 }
9017
9018 static int
9019 api_bier_table_add_del (vat_main_t * vam)
9020 {
9021   unformat_input_t *i = vam->input;
9022   vl_api_bier_table_add_del_t *mp;
9023   u8 is_add = 1;
9024   u32 set = 0, sub_domain = 0, hdr_len = 3;
9025   mpls_label_t local_label = MPLS_LABEL_INVALID;
9026   int ret;
9027
9028   /* Parse args required to build the message */
9029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9030     {
9031       if (unformat (i, "sub-domain %d", &sub_domain))
9032         ;
9033       else if (unformat (i, "set %d", &set))
9034         ;
9035       else if (unformat (i, "label %d", &local_label))
9036         ;
9037       else if (unformat (i, "hdr-len %d", &hdr_len))
9038         ;
9039       else if (unformat (i, "add"))
9040         is_add = 1;
9041       else if (unformat (i, "del"))
9042         is_add = 0;
9043       else
9044         {
9045           clib_warning ("parse error '%U'", format_unformat_error, i);
9046           return -99;
9047         }
9048     }
9049
9050   if (MPLS_LABEL_INVALID == local_label)
9051     {
9052       errmsg ("missing label\n");
9053       return -99;
9054     }
9055
9056   /* Construct the API message */
9057   M (BIER_TABLE_ADD_DEL, mp);
9058
9059   mp->bt_is_add = is_add;
9060   mp->bt_label = ntohl (local_label);
9061   mp->bt_tbl_id.bt_set = set;
9062   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9063   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9064
9065   /* send it... */
9066   S (mp);
9067
9068   /* Wait for a reply... */
9069   W (ret);
9070
9071   return (ret);
9072 }
9073
9074 static int
9075 api_bier_route_add_del (vat_main_t * vam)
9076 {
9077   unformat_input_t *i = vam->input;
9078   vl_api_bier_route_add_del_t *mp;
9079   u8 is_add = 1;
9080   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9081   ip4_address_t v4_next_hop_address;
9082   ip6_address_t v6_next_hop_address;
9083   u8 next_hop_set = 0;
9084   u8 next_hop_proto_is_ip4 = 1;
9085   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9086   int ret;
9087
9088   /* Parse args required to build the message */
9089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9090     {
9091       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9092         {
9093           next_hop_proto_is_ip4 = 1;
9094           next_hop_set = 1;
9095         }
9096       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9097         {
9098           next_hop_proto_is_ip4 = 0;
9099           next_hop_set = 1;
9100         }
9101       if (unformat (i, "sub-domain %d", &sub_domain))
9102         ;
9103       else if (unformat (i, "set %d", &set))
9104         ;
9105       else if (unformat (i, "hdr-len %d", &hdr_len))
9106         ;
9107       else if (unformat (i, "bp %d", &bp))
9108         ;
9109       else if (unformat (i, "add"))
9110         is_add = 1;
9111       else if (unformat (i, "del"))
9112         is_add = 0;
9113       else if (unformat (i, "out-label %d", &next_hop_out_label))
9114         ;
9115       else
9116         {
9117           clib_warning ("parse error '%U'", format_unformat_error, i);
9118           return -99;
9119         }
9120     }
9121
9122   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9123     {
9124       errmsg ("next hop / label set\n");
9125       return -99;
9126     }
9127   if (0 == bp)
9128     {
9129       errmsg ("bit=position not set\n");
9130       return -99;
9131     }
9132
9133   /* Construct the API message */
9134   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9135
9136   mp->br_is_add = is_add;
9137   mp->br_tbl_id.bt_set = set;
9138   mp->br_tbl_id.bt_sub_domain = sub_domain;
9139   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9140   mp->br_bp = ntohs (bp);
9141   mp->br_n_paths = 1;
9142   mp->br_paths[0].n_labels = 1;
9143   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9144   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9145
9146   if (next_hop_proto_is_ip4)
9147     {
9148       clib_memcpy (mp->br_paths[0].next_hop,
9149                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9150     }
9151   else
9152     {
9153       clib_memcpy (mp->br_paths[0].next_hop,
9154                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9155     }
9156
9157   /* send it... */
9158   S (mp);
9159
9160   /* Wait for a reply... */
9161   W (ret);
9162
9163   return (ret);
9164 }
9165
9166 static int
9167 api_proxy_arp_add_del (vat_main_t * vam)
9168 {
9169   unformat_input_t *i = vam->input;
9170   vl_api_proxy_arp_add_del_t *mp;
9171   u32 vrf_id = 0;
9172   u8 is_add = 1;
9173   ip4_address_t lo, hi;
9174   u8 range_set = 0;
9175   int ret;
9176
9177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9178     {
9179       if (unformat (i, "vrf %d", &vrf_id))
9180         ;
9181       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9182                          unformat_ip4_address, &hi))
9183         range_set = 1;
9184       else if (unformat (i, "del"))
9185         is_add = 0;
9186       else
9187         {
9188           clib_warning ("parse error '%U'", format_unformat_error, i);
9189           return -99;
9190         }
9191     }
9192
9193   if (range_set == 0)
9194     {
9195       errmsg ("address range not set");
9196       return -99;
9197     }
9198
9199   M (PROXY_ARP_ADD_DEL, mp);
9200
9201   mp->proxy.vrf_id = ntohl (vrf_id);
9202   mp->is_add = is_add;
9203   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9204   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9205
9206   S (mp);
9207   W (ret);
9208   return ret;
9209 }
9210
9211 static int
9212 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9213 {
9214   unformat_input_t *i = vam->input;
9215   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9216   u32 sw_if_index;
9217   u8 enable = 1;
9218   u8 sw_if_index_set = 0;
9219   int ret;
9220
9221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9222     {
9223       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9224         sw_if_index_set = 1;
9225       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9226         sw_if_index_set = 1;
9227       else if (unformat (i, "enable"))
9228         enable = 1;
9229       else if (unformat (i, "disable"))
9230         enable = 0;
9231       else
9232         {
9233           clib_warning ("parse error '%U'", format_unformat_error, i);
9234           return -99;
9235         }
9236     }
9237
9238   if (sw_if_index_set == 0)
9239     {
9240       errmsg ("missing interface name or sw_if_index");
9241       return -99;
9242     }
9243
9244   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9245
9246   mp->sw_if_index = ntohl (sw_if_index);
9247   mp->enable_disable = enable;
9248
9249   S (mp);
9250   W (ret);
9251   return ret;
9252 }
9253
9254 static int
9255 api_mpls_tunnel_add_del (vat_main_t * vam)
9256 {
9257   unformat_input_t *i = vam->input;
9258   vl_api_mpls_tunnel_add_del_t *mp;
9259
9260   u8 is_add = 1;
9261   u8 l2_only = 0;
9262   u32 sw_if_index = ~0;
9263   u32 next_hop_sw_if_index = ~0;
9264   u32 next_hop_proto_is_ip4 = 1;
9265
9266   u32 next_hop_table_id = 0;
9267   ip4_address_t v4_next_hop_address = {
9268     .as_u32 = 0,
9269   };
9270   ip6_address_t v6_next_hop_address = { {0} };
9271   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9272   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9273   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9274   int ret;
9275
9276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9277     {
9278       if (unformat (i, "add"))
9279         is_add = 1;
9280       else
9281         if (unformat
9282             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9283         is_add = 0;
9284       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9285         is_add = 0;
9286       else if (unformat (i, "via %U",
9287                          unformat_ip4_address, &v4_next_hop_address))
9288         {
9289           next_hop_proto_is_ip4 = 1;
9290         }
9291       else if (unformat (i, "via %U",
9292                          unformat_ip6_address, &v6_next_hop_address))
9293         {
9294           next_hop_proto_is_ip4 = 0;
9295         }
9296       else if (unformat (i, "via-label %d", &next_hop_via_label))
9297         ;
9298       else
9299         if (unformat
9300             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9301         ;
9302       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9303         ;
9304       else if (unformat (i, "l2-only"))
9305         l2_only = 1;
9306       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9307         ;
9308       else if (unformat (i, "out-label %d", &next_hop_out_label))
9309         {
9310           vl_api_fib_mpls_label_t fib_label = {
9311             .label = ntohl (next_hop_out_label),
9312             .ttl = 64,
9313             .exp = 0,
9314           };
9315           vec_add1 (next_hop_out_label_stack, fib_label);
9316         }
9317       else
9318         {
9319           clib_warning ("parse error '%U'", format_unformat_error, i);
9320           return -99;
9321         }
9322     }
9323
9324   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9325       vec_len (next_hop_out_label_stack));
9326
9327   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9328   mp->mt_sw_if_index = ntohl (sw_if_index);
9329   mp->mt_is_add = is_add;
9330   mp->mt_l2_only = l2_only;
9331   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9332   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9333   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9334   mp->mt_next_hop_weight = 1;
9335   mp->mt_next_hop_preference = 0;
9336
9337   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9338
9339   if (0 != mp->mt_next_hop_n_out_labels)
9340     {
9341       clib_memcpy (mp->mt_next_hop_out_label_stack,
9342                    next_hop_out_label_stack,
9343                    (vec_len (next_hop_out_label_stack) *
9344                     sizeof (vl_api_fib_mpls_label_t)));
9345       vec_free (next_hop_out_label_stack);
9346     }
9347
9348   if (next_hop_proto_is_ip4)
9349     {
9350       clib_memcpy (mp->mt_next_hop,
9351                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9352     }
9353   else
9354     {
9355       clib_memcpy (mp->mt_next_hop,
9356                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9357     }
9358
9359   S (mp);
9360   W (ret);
9361   return ret;
9362 }
9363
9364 static int
9365 api_sw_interface_set_unnumbered (vat_main_t * vam)
9366 {
9367   unformat_input_t *i = vam->input;
9368   vl_api_sw_interface_set_unnumbered_t *mp;
9369   u32 sw_if_index;
9370   u32 unnum_sw_index = ~0;
9371   u8 is_add = 1;
9372   u8 sw_if_index_set = 0;
9373   int ret;
9374
9375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9376     {
9377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9378         sw_if_index_set = 1;
9379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9380         sw_if_index_set = 1;
9381       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9382         ;
9383       else if (unformat (i, "del"))
9384         is_add = 0;
9385       else
9386         {
9387           clib_warning ("parse error '%U'", format_unformat_error, i);
9388           return -99;
9389         }
9390     }
9391
9392   if (sw_if_index_set == 0)
9393     {
9394       errmsg ("missing interface name or sw_if_index");
9395       return -99;
9396     }
9397
9398   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9399
9400   mp->sw_if_index = ntohl (sw_if_index);
9401   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9402   mp->is_add = is_add;
9403
9404   S (mp);
9405   W (ret);
9406   return ret;
9407 }
9408
9409 static int
9410 api_ip_neighbor_add_del (vat_main_t * vam)
9411 {
9412   unformat_input_t *i = vam->input;
9413   vl_api_ip_neighbor_add_del_t *mp;
9414   u32 sw_if_index;
9415   u8 sw_if_index_set = 0;
9416   u8 is_add = 1;
9417   u8 is_static = 0;
9418   u8 is_no_fib_entry = 0;
9419   u8 mac_address[6];
9420   u8 mac_set = 0;
9421   u8 v4_address_set = 0;
9422   u8 v6_address_set = 0;
9423   ip4_address_t v4address;
9424   ip6_address_t v6address;
9425   int ret;
9426
9427   clib_memset (mac_address, 0, sizeof (mac_address));
9428
9429   /* Parse args required to build the message */
9430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9431     {
9432       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9433         {
9434           mac_set = 1;
9435         }
9436       else if (unformat (i, "del"))
9437         is_add = 0;
9438       else
9439         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9440         sw_if_index_set = 1;
9441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9442         sw_if_index_set = 1;
9443       else if (unformat (i, "is_static"))
9444         is_static = 1;
9445       else if (unformat (i, "no-fib-entry"))
9446         is_no_fib_entry = 1;
9447       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9448         v4_address_set = 1;
9449       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9450         v6_address_set = 1;
9451       else
9452         {
9453           clib_warning ("parse error '%U'", format_unformat_error, i);
9454           return -99;
9455         }
9456     }
9457
9458   if (sw_if_index_set == 0)
9459     {
9460       errmsg ("missing interface name or sw_if_index");
9461       return -99;
9462     }
9463   if (v4_address_set && v6_address_set)
9464     {
9465       errmsg ("both v4 and v6 addresses set");
9466       return -99;
9467     }
9468   if (!v4_address_set && !v6_address_set)
9469     {
9470       errmsg ("no address set");
9471       return -99;
9472     }
9473
9474   /* Construct the API message */
9475   M (IP_NEIGHBOR_ADD_DEL, mp);
9476
9477   mp->sw_if_index = ntohl (sw_if_index);
9478   mp->is_add = is_add;
9479   mp->is_static = is_static;
9480   mp->is_no_adj_fib = is_no_fib_entry;
9481   if (mac_set)
9482     clib_memcpy (mp->mac_address, mac_address, 6);
9483   if (v6_address_set)
9484     {
9485       mp->is_ipv6 = 1;
9486       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9487     }
9488   else
9489     {
9490       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9491       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9492     }
9493
9494   /* send it... */
9495   S (mp);
9496
9497   /* Wait for a reply, return good/bad news  */
9498   W (ret);
9499   return ret;
9500 }
9501
9502 static int
9503 api_create_vlan_subif (vat_main_t * vam)
9504 {
9505   unformat_input_t *i = vam->input;
9506   vl_api_create_vlan_subif_t *mp;
9507   u32 sw_if_index;
9508   u8 sw_if_index_set = 0;
9509   u32 vlan_id;
9510   u8 vlan_id_set = 0;
9511   int ret;
9512
9513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9514     {
9515       if (unformat (i, "sw_if_index %d", &sw_if_index))
9516         sw_if_index_set = 1;
9517       else
9518         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9519         sw_if_index_set = 1;
9520       else if (unformat (i, "vlan %d", &vlan_id))
9521         vlan_id_set = 1;
9522       else
9523         {
9524           clib_warning ("parse error '%U'", format_unformat_error, i);
9525           return -99;
9526         }
9527     }
9528
9529   if (sw_if_index_set == 0)
9530     {
9531       errmsg ("missing interface name or sw_if_index");
9532       return -99;
9533     }
9534
9535   if (vlan_id_set == 0)
9536     {
9537       errmsg ("missing vlan_id");
9538       return -99;
9539     }
9540   M (CREATE_VLAN_SUBIF, mp);
9541
9542   mp->sw_if_index = ntohl (sw_if_index);
9543   mp->vlan_id = ntohl (vlan_id);
9544
9545   S (mp);
9546   W (ret);
9547   return ret;
9548 }
9549
9550 #define foreach_create_subif_bit                \
9551 _(no_tags)                                      \
9552 _(one_tag)                                      \
9553 _(two_tags)                                     \
9554 _(dot1ad)                                       \
9555 _(exact_match)                                  \
9556 _(default_sub)                                  \
9557 _(outer_vlan_id_any)                            \
9558 _(inner_vlan_id_any)
9559
9560 static int
9561 api_create_subif (vat_main_t * vam)
9562 {
9563   unformat_input_t *i = vam->input;
9564   vl_api_create_subif_t *mp;
9565   u32 sw_if_index;
9566   u8 sw_if_index_set = 0;
9567   u32 sub_id;
9568   u8 sub_id_set = 0;
9569   u32 no_tags = 0;
9570   u32 one_tag = 0;
9571   u32 two_tags = 0;
9572   u32 dot1ad = 0;
9573   u32 exact_match = 0;
9574   u32 default_sub = 0;
9575   u32 outer_vlan_id_any = 0;
9576   u32 inner_vlan_id_any = 0;
9577   u32 tmp;
9578   u16 outer_vlan_id = 0;
9579   u16 inner_vlan_id = 0;
9580   int ret;
9581
9582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9583     {
9584       if (unformat (i, "sw_if_index %d", &sw_if_index))
9585         sw_if_index_set = 1;
9586       else
9587         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9588         sw_if_index_set = 1;
9589       else if (unformat (i, "sub_id %d", &sub_id))
9590         sub_id_set = 1;
9591       else if (unformat (i, "outer_vlan_id %d", &tmp))
9592         outer_vlan_id = tmp;
9593       else if (unformat (i, "inner_vlan_id %d", &tmp))
9594         inner_vlan_id = tmp;
9595
9596 #define _(a) else if (unformat (i, #a)) a = 1 ;
9597       foreach_create_subif_bit
9598 #undef _
9599         else
9600         {
9601           clib_warning ("parse error '%U'", format_unformat_error, i);
9602           return -99;
9603         }
9604     }
9605
9606   if (sw_if_index_set == 0)
9607     {
9608       errmsg ("missing interface name or sw_if_index");
9609       return -99;
9610     }
9611
9612   if (sub_id_set == 0)
9613     {
9614       errmsg ("missing sub_id");
9615       return -99;
9616     }
9617   M (CREATE_SUBIF, mp);
9618
9619   mp->sw_if_index = ntohl (sw_if_index);
9620   mp->sub_id = ntohl (sub_id);
9621
9622 #define _(a) mp->a = a;
9623   foreach_create_subif_bit;
9624 #undef _
9625
9626   mp->outer_vlan_id = ntohs (outer_vlan_id);
9627   mp->inner_vlan_id = ntohs (inner_vlan_id);
9628
9629   S (mp);
9630   W (ret);
9631   return ret;
9632 }
9633
9634 static int
9635 api_oam_add_del (vat_main_t * vam)
9636 {
9637   unformat_input_t *i = vam->input;
9638   vl_api_oam_add_del_t *mp;
9639   u32 vrf_id = 0;
9640   u8 is_add = 1;
9641   ip4_address_t src, dst;
9642   u8 src_set = 0;
9643   u8 dst_set = 0;
9644   int ret;
9645
9646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9647     {
9648       if (unformat (i, "vrf %d", &vrf_id))
9649         ;
9650       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9651         src_set = 1;
9652       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9653         dst_set = 1;
9654       else if (unformat (i, "del"))
9655         is_add = 0;
9656       else
9657         {
9658           clib_warning ("parse error '%U'", format_unformat_error, i);
9659           return -99;
9660         }
9661     }
9662
9663   if (src_set == 0)
9664     {
9665       errmsg ("missing src addr");
9666       return -99;
9667     }
9668
9669   if (dst_set == 0)
9670     {
9671       errmsg ("missing dst addr");
9672       return -99;
9673     }
9674
9675   M (OAM_ADD_DEL, mp);
9676
9677   mp->vrf_id = ntohl (vrf_id);
9678   mp->is_add = is_add;
9679   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9680   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9681
9682   S (mp);
9683   W (ret);
9684   return ret;
9685 }
9686
9687 static int
9688 api_reset_fib (vat_main_t * vam)
9689 {
9690   unformat_input_t *i = vam->input;
9691   vl_api_reset_fib_t *mp;
9692   u32 vrf_id = 0;
9693   u8 is_ipv6 = 0;
9694   u8 vrf_id_set = 0;
9695
9696   int ret;
9697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9698     {
9699       if (unformat (i, "vrf %d", &vrf_id))
9700         vrf_id_set = 1;
9701       else if (unformat (i, "ipv6"))
9702         is_ipv6 = 1;
9703       else
9704         {
9705           clib_warning ("parse error '%U'", format_unformat_error, i);
9706           return -99;
9707         }
9708     }
9709
9710   if (vrf_id_set == 0)
9711     {
9712       errmsg ("missing vrf id");
9713       return -99;
9714     }
9715
9716   M (RESET_FIB, mp);
9717
9718   mp->vrf_id = ntohl (vrf_id);
9719   mp->is_ipv6 = is_ipv6;
9720
9721   S (mp);
9722   W (ret);
9723   return ret;
9724 }
9725
9726 static int
9727 api_dhcp_proxy_config (vat_main_t * vam)
9728 {
9729   unformat_input_t *i = vam->input;
9730   vl_api_dhcp_proxy_config_t *mp;
9731   u32 rx_vrf_id = 0;
9732   u32 server_vrf_id = 0;
9733   u8 is_add = 1;
9734   u8 v4_address_set = 0;
9735   u8 v6_address_set = 0;
9736   ip4_address_t v4address;
9737   ip6_address_t v6address;
9738   u8 v4_src_address_set = 0;
9739   u8 v6_src_address_set = 0;
9740   ip4_address_t v4srcaddress;
9741   ip6_address_t v6srcaddress;
9742   int ret;
9743
9744   /* Parse args required to build the message */
9745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9746     {
9747       if (unformat (i, "del"))
9748         is_add = 0;
9749       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9750         ;
9751       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9752         ;
9753       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9754         v4_address_set = 1;
9755       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9756         v6_address_set = 1;
9757       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9758         v4_src_address_set = 1;
9759       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9760         v6_src_address_set = 1;
9761       else
9762         break;
9763     }
9764
9765   if (v4_address_set && v6_address_set)
9766     {
9767       errmsg ("both v4 and v6 server addresses set");
9768       return -99;
9769     }
9770   if (!v4_address_set && !v6_address_set)
9771     {
9772       errmsg ("no server addresses set");
9773       return -99;
9774     }
9775
9776   if (v4_src_address_set && v6_src_address_set)
9777     {
9778       errmsg ("both v4 and v6  src addresses set");
9779       return -99;
9780     }
9781   if (!v4_src_address_set && !v6_src_address_set)
9782     {
9783       errmsg ("no src addresses set");
9784       return -99;
9785     }
9786
9787   if (!(v4_src_address_set && v4_address_set) &&
9788       !(v6_src_address_set && v6_address_set))
9789     {
9790       errmsg ("no matching server and src addresses set");
9791       return -99;
9792     }
9793
9794   /* Construct the API message */
9795   M (DHCP_PROXY_CONFIG, mp);
9796
9797   mp->is_add = is_add;
9798   mp->rx_vrf_id = ntohl (rx_vrf_id);
9799   mp->server_vrf_id = ntohl (server_vrf_id);
9800   if (v6_address_set)
9801     {
9802       mp->is_ipv6 = 1;
9803       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9804       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9805     }
9806   else
9807     {
9808       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9809       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9810     }
9811
9812   /* send it... */
9813   S (mp);
9814
9815   /* Wait for a reply, return good/bad news  */
9816   W (ret);
9817   return ret;
9818 }
9819
9820 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9821 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9822
9823 static void
9824 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9825 {
9826   vat_main_t *vam = &vat_main;
9827   u32 i, count = mp->count;
9828   vl_api_dhcp_server_t *s;
9829
9830   if (mp->is_ipv6)
9831     print (vam->ofp,
9832            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9833            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9834            ntohl (mp->rx_vrf_id),
9835            format_ip6_address, mp->dhcp_src_address,
9836            mp->vss_type, mp->vss_vpn_ascii_id,
9837            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9838   else
9839     print (vam->ofp,
9840            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9841            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9842            ntohl (mp->rx_vrf_id),
9843            format_ip4_address, mp->dhcp_src_address,
9844            mp->vss_type, mp->vss_vpn_ascii_id,
9845            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9846
9847   for (i = 0; i < count; i++)
9848     {
9849       s = &mp->servers[i];
9850
9851       if (mp->is_ipv6)
9852         print (vam->ofp,
9853                " Server Table-ID %d, Server Address %U",
9854                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9855       else
9856         print (vam->ofp,
9857                " Server Table-ID %d, Server Address %U",
9858                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9859     }
9860 }
9861
9862 static void vl_api_dhcp_proxy_details_t_handler_json
9863   (vl_api_dhcp_proxy_details_t * mp)
9864 {
9865   vat_main_t *vam = &vat_main;
9866   vat_json_node_t *node = NULL;
9867   u32 i, count = mp->count;
9868   struct in_addr ip4;
9869   struct in6_addr ip6;
9870   vl_api_dhcp_server_t *s;
9871
9872   if (VAT_JSON_ARRAY != vam->json_tree.type)
9873     {
9874       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9875       vat_json_init_array (&vam->json_tree);
9876     }
9877   node = vat_json_array_add (&vam->json_tree);
9878
9879   vat_json_init_object (node);
9880   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9881   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9882                              sizeof (mp->vss_type));
9883   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9884                                    mp->vss_vpn_ascii_id);
9885   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9886   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9887
9888   if (mp->is_ipv6)
9889     {
9890       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9891       vat_json_object_add_ip6 (node, "src_address", ip6);
9892     }
9893   else
9894     {
9895       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9896       vat_json_object_add_ip4 (node, "src_address", ip4);
9897     }
9898
9899   for (i = 0; i < count; i++)
9900     {
9901       s = &mp->servers[i];
9902
9903       vat_json_object_add_uint (node, "server-table-id",
9904                                 ntohl (s->server_vrf_id));
9905
9906       if (mp->is_ipv6)
9907         {
9908           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9909           vat_json_object_add_ip4 (node, "src_address", ip4);
9910         }
9911       else
9912         {
9913           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9914           vat_json_object_add_ip6 (node, "server_address", ip6);
9915         }
9916     }
9917 }
9918
9919 static int
9920 api_dhcp_proxy_dump (vat_main_t * vam)
9921 {
9922   unformat_input_t *i = vam->input;
9923   vl_api_control_ping_t *mp_ping;
9924   vl_api_dhcp_proxy_dump_t *mp;
9925   u8 is_ipv6 = 0;
9926   int ret;
9927
9928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9929     {
9930       if (unformat (i, "ipv6"))
9931         is_ipv6 = 1;
9932       else
9933         {
9934           clib_warning ("parse error '%U'", format_unformat_error, i);
9935           return -99;
9936         }
9937     }
9938
9939   M (DHCP_PROXY_DUMP, mp);
9940
9941   mp->is_ip6 = is_ipv6;
9942   S (mp);
9943
9944   /* Use a control ping for synchronization */
9945   MPING (CONTROL_PING, mp_ping);
9946   S (mp_ping);
9947
9948   W (ret);
9949   return ret;
9950 }
9951
9952 static int
9953 api_dhcp_proxy_set_vss (vat_main_t * vam)
9954 {
9955   unformat_input_t *i = vam->input;
9956   vl_api_dhcp_proxy_set_vss_t *mp;
9957   u8 is_ipv6 = 0;
9958   u8 is_add = 1;
9959   u32 tbl_id = ~0;
9960   u8 vss_type = VSS_TYPE_DEFAULT;
9961   u8 *vpn_ascii_id = 0;
9962   u32 oui = 0;
9963   u32 fib_id = 0;
9964   int ret;
9965
9966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9967     {
9968       if (unformat (i, "tbl_id %d", &tbl_id))
9969         ;
9970       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9971         vss_type = VSS_TYPE_ASCII;
9972       else if (unformat (i, "fib_id %d", &fib_id))
9973         vss_type = VSS_TYPE_VPN_ID;
9974       else if (unformat (i, "oui %d", &oui))
9975         vss_type = VSS_TYPE_VPN_ID;
9976       else if (unformat (i, "ipv6"))
9977         is_ipv6 = 1;
9978       else if (unformat (i, "del"))
9979         is_add = 0;
9980       else
9981         break;
9982     }
9983
9984   if (tbl_id == ~0)
9985     {
9986       errmsg ("missing tbl_id ");
9987       vec_free (vpn_ascii_id);
9988       return -99;
9989     }
9990
9991   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9992     {
9993       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9994       vec_free (vpn_ascii_id);
9995       return -99;
9996     }
9997
9998   M (DHCP_PROXY_SET_VSS, mp);
9999   mp->tbl_id = ntohl (tbl_id);
10000   mp->vss_type = vss_type;
10001   if (vpn_ascii_id)
10002     {
10003       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10004       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10005     }
10006   mp->vpn_index = ntohl (fib_id);
10007   mp->oui = ntohl (oui);
10008   mp->is_ipv6 = is_ipv6;
10009   mp->is_add = is_add;
10010
10011   S (mp);
10012   W (ret);
10013
10014   vec_free (vpn_ascii_id);
10015   return ret;
10016 }
10017
10018 static int
10019 api_dhcp_client_config (vat_main_t * vam)
10020 {
10021   unformat_input_t *i = vam->input;
10022   vl_api_dhcp_client_config_t *mp;
10023   u32 sw_if_index;
10024   u8 sw_if_index_set = 0;
10025   u8 is_add = 1;
10026   u8 *hostname = 0;
10027   u8 disable_event = 0;
10028   int ret;
10029
10030   /* Parse args required to build the message */
10031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10032     {
10033       if (unformat (i, "del"))
10034         is_add = 0;
10035       else
10036         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10037         sw_if_index_set = 1;
10038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10039         sw_if_index_set = 1;
10040       else if (unformat (i, "hostname %s", &hostname))
10041         ;
10042       else if (unformat (i, "disable_event"))
10043         disable_event = 1;
10044       else
10045         break;
10046     }
10047
10048   if (sw_if_index_set == 0)
10049     {
10050       errmsg ("missing interface name or sw_if_index");
10051       return -99;
10052     }
10053
10054   if (vec_len (hostname) > 63)
10055     {
10056       errmsg ("hostname too long");
10057     }
10058   vec_add1 (hostname, 0);
10059
10060   /* Construct the API message */
10061   M (DHCP_CLIENT_CONFIG, mp);
10062
10063   mp->is_add = is_add;
10064   mp->client.sw_if_index = htonl (sw_if_index);
10065   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10066   vec_free (hostname);
10067   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10068   mp->client.pid = htonl (getpid ());
10069
10070   /* send it... */
10071   S (mp);
10072
10073   /* Wait for a reply, return good/bad news  */
10074   W (ret);
10075   return ret;
10076 }
10077
10078 static int
10079 api_set_ip_flow_hash (vat_main_t * vam)
10080 {
10081   unformat_input_t *i = vam->input;
10082   vl_api_set_ip_flow_hash_t *mp;
10083   u32 vrf_id = 0;
10084   u8 is_ipv6 = 0;
10085   u8 vrf_id_set = 0;
10086   u8 src = 0;
10087   u8 dst = 0;
10088   u8 sport = 0;
10089   u8 dport = 0;
10090   u8 proto = 0;
10091   u8 reverse = 0;
10092   int ret;
10093
10094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10095     {
10096       if (unformat (i, "vrf %d", &vrf_id))
10097         vrf_id_set = 1;
10098       else if (unformat (i, "ipv6"))
10099         is_ipv6 = 1;
10100       else if (unformat (i, "src"))
10101         src = 1;
10102       else if (unformat (i, "dst"))
10103         dst = 1;
10104       else if (unformat (i, "sport"))
10105         sport = 1;
10106       else if (unformat (i, "dport"))
10107         dport = 1;
10108       else if (unformat (i, "proto"))
10109         proto = 1;
10110       else if (unformat (i, "reverse"))
10111         reverse = 1;
10112
10113       else
10114         {
10115           clib_warning ("parse error '%U'", format_unformat_error, i);
10116           return -99;
10117         }
10118     }
10119
10120   if (vrf_id_set == 0)
10121     {
10122       errmsg ("missing vrf id");
10123       return -99;
10124     }
10125
10126   M (SET_IP_FLOW_HASH, mp);
10127   mp->src = src;
10128   mp->dst = dst;
10129   mp->sport = sport;
10130   mp->dport = dport;
10131   mp->proto = proto;
10132   mp->reverse = reverse;
10133   mp->vrf_id = ntohl (vrf_id);
10134   mp->is_ipv6 = is_ipv6;
10135
10136   S (mp);
10137   W (ret);
10138   return ret;
10139 }
10140
10141 static int
10142 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10143 {
10144   unformat_input_t *i = vam->input;
10145   vl_api_sw_interface_ip6_enable_disable_t *mp;
10146   u32 sw_if_index;
10147   u8 sw_if_index_set = 0;
10148   u8 enable = 0;
10149   int ret;
10150
10151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10152     {
10153       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10154         sw_if_index_set = 1;
10155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10156         sw_if_index_set = 1;
10157       else if (unformat (i, "enable"))
10158         enable = 1;
10159       else if (unformat (i, "disable"))
10160         enable = 0;
10161       else
10162         {
10163           clib_warning ("parse error '%U'", format_unformat_error, i);
10164           return -99;
10165         }
10166     }
10167
10168   if (sw_if_index_set == 0)
10169     {
10170       errmsg ("missing interface name or sw_if_index");
10171       return -99;
10172     }
10173
10174   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10175
10176   mp->sw_if_index = ntohl (sw_if_index);
10177   mp->enable = enable;
10178
10179   S (mp);
10180   W (ret);
10181   return ret;
10182 }
10183
10184 static int
10185 api_ip6nd_proxy_add_del (vat_main_t * vam)
10186 {
10187   unformat_input_t *i = vam->input;
10188   vl_api_ip6nd_proxy_add_del_t *mp;
10189   u32 sw_if_index = ~0;
10190   u8 v6_address_set = 0;
10191   ip6_address_t v6address;
10192   u8 is_del = 0;
10193   int ret;
10194
10195   /* Parse args required to build the message */
10196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10197     {
10198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10199         ;
10200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10201         ;
10202       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10203         v6_address_set = 1;
10204       if (unformat (i, "del"))
10205         is_del = 1;
10206       else
10207         {
10208           clib_warning ("parse error '%U'", format_unformat_error, i);
10209           return -99;
10210         }
10211     }
10212
10213   if (sw_if_index == ~0)
10214     {
10215       errmsg ("missing interface name or sw_if_index");
10216       return -99;
10217     }
10218   if (!v6_address_set)
10219     {
10220       errmsg ("no address set");
10221       return -99;
10222     }
10223
10224   /* Construct the API message */
10225   M (IP6ND_PROXY_ADD_DEL, mp);
10226
10227   mp->is_del = is_del;
10228   mp->sw_if_index = ntohl (sw_if_index);
10229   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10230
10231   /* send it... */
10232   S (mp);
10233
10234   /* Wait for a reply, return good/bad news  */
10235   W (ret);
10236   return ret;
10237 }
10238
10239 static int
10240 api_ip6nd_proxy_dump (vat_main_t * vam)
10241 {
10242   vl_api_ip6nd_proxy_dump_t *mp;
10243   vl_api_control_ping_t *mp_ping;
10244   int ret;
10245
10246   M (IP6ND_PROXY_DUMP, mp);
10247
10248   S (mp);
10249
10250   /* Use a control ping for synchronization */
10251   MPING (CONTROL_PING, mp_ping);
10252   S (mp_ping);
10253
10254   W (ret);
10255   return ret;
10256 }
10257
10258 static void vl_api_ip6nd_proxy_details_t_handler
10259   (vl_api_ip6nd_proxy_details_t * mp)
10260 {
10261   vat_main_t *vam = &vat_main;
10262
10263   print (vam->ofp, "host %U sw_if_index %d",
10264          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10265 }
10266
10267 static void vl_api_ip6nd_proxy_details_t_handler_json
10268   (vl_api_ip6nd_proxy_details_t * mp)
10269 {
10270   vat_main_t *vam = &vat_main;
10271   struct in6_addr ip6;
10272   vat_json_node_t *node = NULL;
10273
10274   if (VAT_JSON_ARRAY != vam->json_tree.type)
10275     {
10276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10277       vat_json_init_array (&vam->json_tree);
10278     }
10279   node = vat_json_array_add (&vam->json_tree);
10280
10281   vat_json_init_object (node);
10282   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10283
10284   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10285   vat_json_object_add_ip6 (node, "host", ip6);
10286 }
10287
10288 static int
10289 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10290 {
10291   unformat_input_t *i = vam->input;
10292   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10293   u32 sw_if_index;
10294   u8 sw_if_index_set = 0;
10295   u32 address_length = 0;
10296   u8 v6_address_set = 0;
10297   ip6_address_t v6address;
10298   u8 use_default = 0;
10299   u8 no_advertise = 0;
10300   u8 off_link = 0;
10301   u8 no_autoconfig = 0;
10302   u8 no_onlink = 0;
10303   u8 is_no = 0;
10304   u32 val_lifetime = 0;
10305   u32 pref_lifetime = 0;
10306   int ret;
10307
10308   /* Parse args required to build the message */
10309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10310     {
10311       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10312         sw_if_index_set = 1;
10313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10314         sw_if_index_set = 1;
10315       else if (unformat (i, "%U/%d",
10316                          unformat_ip6_address, &v6address, &address_length))
10317         v6_address_set = 1;
10318       else if (unformat (i, "val_life %d", &val_lifetime))
10319         ;
10320       else if (unformat (i, "pref_life %d", &pref_lifetime))
10321         ;
10322       else if (unformat (i, "def"))
10323         use_default = 1;
10324       else if (unformat (i, "noadv"))
10325         no_advertise = 1;
10326       else if (unformat (i, "offl"))
10327         off_link = 1;
10328       else if (unformat (i, "noauto"))
10329         no_autoconfig = 1;
10330       else if (unformat (i, "nolink"))
10331         no_onlink = 1;
10332       else if (unformat (i, "isno"))
10333         is_no = 1;
10334       else
10335         {
10336           clib_warning ("parse error '%U'", format_unformat_error, i);
10337           return -99;
10338         }
10339     }
10340
10341   if (sw_if_index_set == 0)
10342     {
10343       errmsg ("missing interface name or sw_if_index");
10344       return -99;
10345     }
10346   if (!v6_address_set)
10347     {
10348       errmsg ("no address set");
10349       return -99;
10350     }
10351
10352   /* Construct the API message */
10353   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10354
10355   mp->sw_if_index = ntohl (sw_if_index);
10356   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10357   mp->address_length = address_length;
10358   mp->use_default = use_default;
10359   mp->no_advertise = no_advertise;
10360   mp->off_link = off_link;
10361   mp->no_autoconfig = no_autoconfig;
10362   mp->no_onlink = no_onlink;
10363   mp->is_no = is_no;
10364   mp->val_lifetime = ntohl (val_lifetime);
10365   mp->pref_lifetime = ntohl (pref_lifetime);
10366
10367   /* send it... */
10368   S (mp);
10369
10370   /* Wait for a reply, return good/bad news  */
10371   W (ret);
10372   return ret;
10373 }
10374
10375 static int
10376 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10377 {
10378   unformat_input_t *i = vam->input;
10379   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10380   u32 sw_if_index;
10381   u8 sw_if_index_set = 0;
10382   u8 suppress = 0;
10383   u8 managed = 0;
10384   u8 other = 0;
10385   u8 ll_option = 0;
10386   u8 send_unicast = 0;
10387   u8 cease = 0;
10388   u8 is_no = 0;
10389   u8 default_router = 0;
10390   u32 max_interval = 0;
10391   u32 min_interval = 0;
10392   u32 lifetime = 0;
10393   u32 initial_count = 0;
10394   u32 initial_interval = 0;
10395   int ret;
10396
10397
10398   /* Parse args required to build the message */
10399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10400     {
10401       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10402         sw_if_index_set = 1;
10403       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10404         sw_if_index_set = 1;
10405       else if (unformat (i, "maxint %d", &max_interval))
10406         ;
10407       else if (unformat (i, "minint %d", &min_interval))
10408         ;
10409       else if (unformat (i, "life %d", &lifetime))
10410         ;
10411       else if (unformat (i, "count %d", &initial_count))
10412         ;
10413       else if (unformat (i, "interval %d", &initial_interval))
10414         ;
10415       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10416         suppress = 1;
10417       else if (unformat (i, "managed"))
10418         managed = 1;
10419       else if (unformat (i, "other"))
10420         other = 1;
10421       else if (unformat (i, "ll"))
10422         ll_option = 1;
10423       else if (unformat (i, "send"))
10424         send_unicast = 1;
10425       else if (unformat (i, "cease"))
10426         cease = 1;
10427       else if (unformat (i, "isno"))
10428         is_no = 1;
10429       else if (unformat (i, "def"))
10430         default_router = 1;
10431       else
10432         {
10433           clib_warning ("parse error '%U'", format_unformat_error, i);
10434           return -99;
10435         }
10436     }
10437
10438   if (sw_if_index_set == 0)
10439     {
10440       errmsg ("missing interface name or sw_if_index");
10441       return -99;
10442     }
10443
10444   /* Construct the API message */
10445   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10446
10447   mp->sw_if_index = ntohl (sw_if_index);
10448   mp->max_interval = ntohl (max_interval);
10449   mp->min_interval = ntohl (min_interval);
10450   mp->lifetime = ntohl (lifetime);
10451   mp->initial_count = ntohl (initial_count);
10452   mp->initial_interval = ntohl (initial_interval);
10453   mp->suppress = suppress;
10454   mp->managed = managed;
10455   mp->other = other;
10456   mp->ll_option = ll_option;
10457   mp->send_unicast = send_unicast;
10458   mp->cease = cease;
10459   mp->is_no = is_no;
10460   mp->default_router = default_router;
10461
10462   /* send it... */
10463   S (mp);
10464
10465   /* Wait for a reply, return good/bad news  */
10466   W (ret);
10467   return ret;
10468 }
10469
10470 static int
10471 api_set_arp_neighbor_limit (vat_main_t * vam)
10472 {
10473   unformat_input_t *i = vam->input;
10474   vl_api_set_arp_neighbor_limit_t *mp;
10475   u32 arp_nbr_limit;
10476   u8 limit_set = 0;
10477   u8 is_ipv6 = 0;
10478   int ret;
10479
10480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10481     {
10482       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10483         limit_set = 1;
10484       else if (unformat (i, "ipv6"))
10485         is_ipv6 = 1;
10486       else
10487         {
10488           clib_warning ("parse error '%U'", format_unformat_error, i);
10489           return -99;
10490         }
10491     }
10492
10493   if (limit_set == 0)
10494     {
10495       errmsg ("missing limit value");
10496       return -99;
10497     }
10498
10499   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10500
10501   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10502   mp->is_ipv6 = is_ipv6;
10503
10504   S (mp);
10505   W (ret);
10506   return ret;
10507 }
10508
10509 static int
10510 api_l2_patch_add_del (vat_main_t * vam)
10511 {
10512   unformat_input_t *i = vam->input;
10513   vl_api_l2_patch_add_del_t *mp;
10514   u32 rx_sw_if_index;
10515   u8 rx_sw_if_index_set = 0;
10516   u32 tx_sw_if_index;
10517   u8 tx_sw_if_index_set = 0;
10518   u8 is_add = 1;
10519   int ret;
10520
10521   /* Parse args required to build the message */
10522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10523     {
10524       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10525         rx_sw_if_index_set = 1;
10526       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10527         tx_sw_if_index_set = 1;
10528       else if (unformat (i, "rx"))
10529         {
10530           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10531             {
10532               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10533                             &rx_sw_if_index))
10534                 rx_sw_if_index_set = 1;
10535             }
10536           else
10537             break;
10538         }
10539       else if (unformat (i, "tx"))
10540         {
10541           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10542             {
10543               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10544                             &tx_sw_if_index))
10545                 tx_sw_if_index_set = 1;
10546             }
10547           else
10548             break;
10549         }
10550       else if (unformat (i, "del"))
10551         is_add = 0;
10552       else
10553         break;
10554     }
10555
10556   if (rx_sw_if_index_set == 0)
10557     {
10558       errmsg ("missing rx interface name or rx_sw_if_index");
10559       return -99;
10560     }
10561
10562   if (tx_sw_if_index_set == 0)
10563     {
10564       errmsg ("missing tx interface name or tx_sw_if_index");
10565       return -99;
10566     }
10567
10568   M (L2_PATCH_ADD_DEL, mp);
10569
10570   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10571   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10572   mp->is_add = is_add;
10573
10574   S (mp);
10575   W (ret);
10576   return ret;
10577 }
10578
10579 u8 is_del;
10580 u8 localsid_addr[16];
10581 u8 end_psp;
10582 u8 behavior;
10583 u32 sw_if_index;
10584 u32 vlan_index;
10585 u32 fib_table;
10586 u8 nh_addr[16];
10587
10588 static int
10589 api_sr_localsid_add_del (vat_main_t * vam)
10590 {
10591   unformat_input_t *i = vam->input;
10592   vl_api_sr_localsid_add_del_t *mp;
10593
10594   u8 is_del;
10595   ip6_address_t localsid;
10596   u8 end_psp = 0;
10597   u8 behavior = ~0;
10598   u32 sw_if_index;
10599   u32 fib_table = ~(u32) 0;
10600   ip6_address_t nh_addr6;
10601   ip4_address_t nh_addr4;
10602   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10603   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10604
10605   bool nexthop_set = 0;
10606
10607   int ret;
10608
10609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10610     {
10611       if (unformat (i, "del"))
10612         is_del = 1;
10613       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10614       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10615         nexthop_set = 1;
10616       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10617         nexthop_set = 1;
10618       else if (unformat (i, "behavior %u", &behavior));
10619       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10620       else if (unformat (i, "fib-table %u", &fib_table));
10621       else if (unformat (i, "end.psp %u", &behavior));
10622       else
10623         break;
10624     }
10625
10626   M (SR_LOCALSID_ADD_DEL, mp);
10627
10628   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10629   if (nexthop_set)
10630     {
10631       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10632       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10633     }
10634   mp->behavior = behavior;
10635   mp->sw_if_index = ntohl (sw_if_index);
10636   mp->fib_table = ntohl (fib_table);
10637   mp->end_psp = end_psp;
10638   mp->is_del = is_del;
10639
10640   S (mp);
10641   W (ret);
10642   return ret;
10643 }
10644
10645 static int
10646 api_ioam_enable (vat_main_t * vam)
10647 {
10648   unformat_input_t *input = vam->input;
10649   vl_api_ioam_enable_t *mp;
10650   u32 id = 0;
10651   int has_trace_option = 0;
10652   int has_pot_option = 0;
10653   int has_seqno_option = 0;
10654   int has_analyse_option = 0;
10655   int ret;
10656
10657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10658     {
10659       if (unformat (input, "trace"))
10660         has_trace_option = 1;
10661       else if (unformat (input, "pot"))
10662         has_pot_option = 1;
10663       else if (unformat (input, "seqno"))
10664         has_seqno_option = 1;
10665       else if (unformat (input, "analyse"))
10666         has_analyse_option = 1;
10667       else
10668         break;
10669     }
10670   M (IOAM_ENABLE, mp);
10671   mp->id = htons (id);
10672   mp->seqno = has_seqno_option;
10673   mp->analyse = has_analyse_option;
10674   mp->pot_enable = has_pot_option;
10675   mp->trace_enable = has_trace_option;
10676
10677   S (mp);
10678   W (ret);
10679   return ret;
10680 }
10681
10682
10683 static int
10684 api_ioam_disable (vat_main_t * vam)
10685 {
10686   vl_api_ioam_disable_t *mp;
10687   int ret;
10688
10689   M (IOAM_DISABLE, mp);
10690   S (mp);
10691   W (ret);
10692   return ret;
10693 }
10694
10695 #define foreach_tcp_proto_field                 \
10696 _(src_port)                                     \
10697 _(dst_port)
10698
10699 #define foreach_udp_proto_field                 \
10700 _(src_port)                                     \
10701 _(dst_port)
10702
10703 #define foreach_ip4_proto_field                 \
10704 _(src_address)                                  \
10705 _(dst_address)                                  \
10706 _(tos)                                          \
10707 _(length)                                       \
10708 _(fragment_id)                                  \
10709 _(ttl)                                          \
10710 _(protocol)                                     \
10711 _(checksum)
10712
10713 typedef struct
10714 {
10715   u16 src_port, dst_port;
10716 } tcpudp_header_t;
10717
10718 #if VPP_API_TEST_BUILTIN == 0
10719 uword
10720 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10721 {
10722   u8 **maskp = va_arg (*args, u8 **);
10723   u8 *mask = 0;
10724   u8 found_something = 0;
10725   tcp_header_t *tcp;
10726
10727 #define _(a) u8 a=0;
10728   foreach_tcp_proto_field;
10729 #undef _
10730
10731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10732     {
10733       if (0);
10734 #define _(a) else if (unformat (input, #a)) a=1;
10735       foreach_tcp_proto_field
10736 #undef _
10737         else
10738         break;
10739     }
10740
10741 #define _(a) found_something += a;
10742   foreach_tcp_proto_field;
10743 #undef _
10744
10745   if (found_something == 0)
10746     return 0;
10747
10748   vec_validate (mask, sizeof (*tcp) - 1);
10749
10750   tcp = (tcp_header_t *) mask;
10751
10752 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10753   foreach_tcp_proto_field;
10754 #undef _
10755
10756   *maskp = mask;
10757   return 1;
10758 }
10759
10760 uword
10761 unformat_udp_mask (unformat_input_t * input, va_list * args)
10762 {
10763   u8 **maskp = va_arg (*args, u8 **);
10764   u8 *mask = 0;
10765   u8 found_something = 0;
10766   udp_header_t *udp;
10767
10768 #define _(a) u8 a=0;
10769   foreach_udp_proto_field;
10770 #undef _
10771
10772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10773     {
10774       if (0);
10775 #define _(a) else if (unformat (input, #a)) a=1;
10776       foreach_udp_proto_field
10777 #undef _
10778         else
10779         break;
10780     }
10781
10782 #define _(a) found_something += a;
10783   foreach_udp_proto_field;
10784 #undef _
10785
10786   if (found_something == 0)
10787     return 0;
10788
10789   vec_validate (mask, sizeof (*udp) - 1);
10790
10791   udp = (udp_header_t *) mask;
10792
10793 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10794   foreach_udp_proto_field;
10795 #undef _
10796
10797   *maskp = mask;
10798   return 1;
10799 }
10800
10801 uword
10802 unformat_l4_mask (unformat_input_t * input, va_list * args)
10803 {
10804   u8 **maskp = va_arg (*args, u8 **);
10805   u16 src_port = 0, dst_port = 0;
10806   tcpudp_header_t *tcpudp;
10807
10808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10809     {
10810       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10811         return 1;
10812       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10813         return 1;
10814       else if (unformat (input, "src_port"))
10815         src_port = 0xFFFF;
10816       else if (unformat (input, "dst_port"))
10817         dst_port = 0xFFFF;
10818       else
10819         return 0;
10820     }
10821
10822   if (!src_port && !dst_port)
10823     return 0;
10824
10825   u8 *mask = 0;
10826   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10827
10828   tcpudp = (tcpudp_header_t *) mask;
10829   tcpudp->src_port = src_port;
10830   tcpudp->dst_port = dst_port;
10831
10832   *maskp = mask;
10833
10834   return 1;
10835 }
10836
10837 uword
10838 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10839 {
10840   u8 **maskp = va_arg (*args, u8 **);
10841   u8 *mask = 0;
10842   u8 found_something = 0;
10843   ip4_header_t *ip;
10844
10845 #define _(a) u8 a=0;
10846   foreach_ip4_proto_field;
10847 #undef _
10848   u8 version = 0;
10849   u8 hdr_length = 0;
10850
10851
10852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10853     {
10854       if (unformat (input, "version"))
10855         version = 1;
10856       else if (unformat (input, "hdr_length"))
10857         hdr_length = 1;
10858       else if (unformat (input, "src"))
10859         src_address = 1;
10860       else if (unformat (input, "dst"))
10861         dst_address = 1;
10862       else if (unformat (input, "proto"))
10863         protocol = 1;
10864
10865 #define _(a) else if (unformat (input, #a)) a=1;
10866       foreach_ip4_proto_field
10867 #undef _
10868         else
10869         break;
10870     }
10871
10872 #define _(a) found_something += a;
10873   foreach_ip4_proto_field;
10874 #undef _
10875
10876   if (found_something == 0)
10877     return 0;
10878
10879   vec_validate (mask, sizeof (*ip) - 1);
10880
10881   ip = (ip4_header_t *) mask;
10882
10883 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10884   foreach_ip4_proto_field;
10885 #undef _
10886
10887   ip->ip_version_and_header_length = 0;
10888
10889   if (version)
10890     ip->ip_version_and_header_length |= 0xF0;
10891
10892   if (hdr_length)
10893     ip->ip_version_and_header_length |= 0x0F;
10894
10895   *maskp = mask;
10896   return 1;
10897 }
10898
10899 #define foreach_ip6_proto_field                 \
10900 _(src_address)                                  \
10901 _(dst_address)                                  \
10902 _(payload_length)                               \
10903 _(hop_limit)                                    \
10904 _(protocol)
10905
10906 uword
10907 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10908 {
10909   u8 **maskp = va_arg (*args, u8 **);
10910   u8 *mask = 0;
10911   u8 found_something = 0;
10912   ip6_header_t *ip;
10913   u32 ip_version_traffic_class_and_flow_label;
10914
10915 #define _(a) u8 a=0;
10916   foreach_ip6_proto_field;
10917 #undef _
10918   u8 version = 0;
10919   u8 traffic_class = 0;
10920   u8 flow_label = 0;
10921
10922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10923     {
10924       if (unformat (input, "version"))
10925         version = 1;
10926       else if (unformat (input, "traffic-class"))
10927         traffic_class = 1;
10928       else if (unformat (input, "flow-label"))
10929         flow_label = 1;
10930       else if (unformat (input, "src"))
10931         src_address = 1;
10932       else if (unformat (input, "dst"))
10933         dst_address = 1;
10934       else if (unformat (input, "proto"))
10935         protocol = 1;
10936
10937 #define _(a) else if (unformat (input, #a)) a=1;
10938       foreach_ip6_proto_field
10939 #undef _
10940         else
10941         break;
10942     }
10943
10944 #define _(a) found_something += a;
10945   foreach_ip6_proto_field;
10946 #undef _
10947
10948   if (found_something == 0)
10949     return 0;
10950
10951   vec_validate (mask, sizeof (*ip) - 1);
10952
10953   ip = (ip6_header_t *) mask;
10954
10955 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10956   foreach_ip6_proto_field;
10957 #undef _
10958
10959   ip_version_traffic_class_and_flow_label = 0;
10960
10961   if (version)
10962     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10963
10964   if (traffic_class)
10965     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10966
10967   if (flow_label)
10968     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10969
10970   ip->ip_version_traffic_class_and_flow_label =
10971     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10972
10973   *maskp = mask;
10974   return 1;
10975 }
10976
10977 uword
10978 unformat_l3_mask (unformat_input_t * input, va_list * args)
10979 {
10980   u8 **maskp = va_arg (*args, u8 **);
10981
10982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10985         return 1;
10986       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10987         return 1;
10988       else
10989         break;
10990     }
10991   return 0;
10992 }
10993
10994 uword
10995 unformat_l2_mask (unformat_input_t * input, va_list * args)
10996 {
10997   u8 **maskp = va_arg (*args, u8 **);
10998   u8 *mask = 0;
10999   u8 src = 0;
11000   u8 dst = 0;
11001   u8 proto = 0;
11002   u8 tag1 = 0;
11003   u8 tag2 = 0;
11004   u8 ignore_tag1 = 0;
11005   u8 ignore_tag2 = 0;
11006   u8 cos1 = 0;
11007   u8 cos2 = 0;
11008   u8 dot1q = 0;
11009   u8 dot1ad = 0;
11010   int len = 14;
11011
11012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11013     {
11014       if (unformat (input, "src"))
11015         src = 1;
11016       else if (unformat (input, "dst"))
11017         dst = 1;
11018       else if (unformat (input, "proto"))
11019         proto = 1;
11020       else if (unformat (input, "tag1"))
11021         tag1 = 1;
11022       else if (unformat (input, "tag2"))
11023         tag2 = 1;
11024       else if (unformat (input, "ignore-tag1"))
11025         ignore_tag1 = 1;
11026       else if (unformat (input, "ignore-tag2"))
11027         ignore_tag2 = 1;
11028       else if (unformat (input, "cos1"))
11029         cos1 = 1;
11030       else if (unformat (input, "cos2"))
11031         cos2 = 1;
11032       else if (unformat (input, "dot1q"))
11033         dot1q = 1;
11034       else if (unformat (input, "dot1ad"))
11035         dot1ad = 1;
11036       else
11037         break;
11038     }
11039   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11040        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11041     return 0;
11042
11043   if (tag1 || ignore_tag1 || cos1 || dot1q)
11044     len = 18;
11045   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11046     len = 22;
11047
11048   vec_validate (mask, len - 1);
11049
11050   if (dst)
11051     clib_memset (mask, 0xff, 6);
11052
11053   if (src)
11054     clib_memset (mask + 6, 0xff, 6);
11055
11056   if (tag2 || dot1ad)
11057     {
11058       /* inner vlan tag */
11059       if (tag2)
11060         {
11061           mask[19] = 0xff;
11062           mask[18] = 0x0f;
11063         }
11064       if (cos2)
11065         mask[18] |= 0xe0;
11066       if (proto)
11067         mask[21] = mask[20] = 0xff;
11068       if (tag1)
11069         {
11070           mask[15] = 0xff;
11071           mask[14] = 0x0f;
11072         }
11073       if (cos1)
11074         mask[14] |= 0xe0;
11075       *maskp = mask;
11076       return 1;
11077     }
11078   if (tag1 | dot1q)
11079     {
11080       if (tag1)
11081         {
11082           mask[15] = 0xff;
11083           mask[14] = 0x0f;
11084         }
11085       if (cos1)
11086         mask[14] |= 0xe0;
11087       if (proto)
11088         mask[16] = mask[17] = 0xff;
11089
11090       *maskp = mask;
11091       return 1;
11092     }
11093   if (cos2)
11094     mask[18] |= 0xe0;
11095   if (cos1)
11096     mask[14] |= 0xe0;
11097   if (proto)
11098     mask[12] = mask[13] = 0xff;
11099
11100   *maskp = mask;
11101   return 1;
11102 }
11103
11104 uword
11105 unformat_classify_mask (unformat_input_t * input, va_list * args)
11106 {
11107   u8 **maskp = va_arg (*args, u8 **);
11108   u32 *skipp = va_arg (*args, u32 *);
11109   u32 *matchp = va_arg (*args, u32 *);
11110   u32 match;
11111   u8 *mask = 0;
11112   u8 *l2 = 0;
11113   u8 *l3 = 0;
11114   u8 *l4 = 0;
11115   int i;
11116
11117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11118     {
11119       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11120         ;
11121       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11122         ;
11123       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11124         ;
11125       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11126         ;
11127       else
11128         break;
11129     }
11130
11131   if (l4 && !l3)
11132     {
11133       vec_free (mask);
11134       vec_free (l2);
11135       vec_free (l4);
11136       return 0;
11137     }
11138
11139   if (mask || l2 || l3 || l4)
11140     {
11141       if (l2 || l3 || l4)
11142         {
11143           /* "With a free Ethernet header in every package" */
11144           if (l2 == 0)
11145             vec_validate (l2, 13);
11146           mask = l2;
11147           if (vec_len (l3))
11148             {
11149               vec_append (mask, l3);
11150               vec_free (l3);
11151             }
11152           if (vec_len (l4))
11153             {
11154               vec_append (mask, l4);
11155               vec_free (l4);
11156             }
11157         }
11158
11159       /* Scan forward looking for the first significant mask octet */
11160       for (i = 0; i < vec_len (mask); i++)
11161         if (mask[i])
11162           break;
11163
11164       /* compute (skip, match) params */
11165       *skipp = i / sizeof (u32x4);
11166       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11167
11168       /* Pad mask to an even multiple of the vector size */
11169       while (vec_len (mask) % sizeof (u32x4))
11170         vec_add1 (mask, 0);
11171
11172       match = vec_len (mask) / sizeof (u32x4);
11173
11174       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11175         {
11176           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11177           if (*tmp || *(tmp + 1))
11178             break;
11179           match--;
11180         }
11181       if (match == 0)
11182         clib_warning ("BUG: match 0");
11183
11184       _vec_len (mask) = match * sizeof (u32x4);
11185
11186       *matchp = match;
11187       *maskp = mask;
11188
11189       return 1;
11190     }
11191
11192   return 0;
11193 }
11194 #endif /* VPP_API_TEST_BUILTIN */
11195
11196 #define foreach_l2_next                         \
11197 _(drop, DROP)                                   \
11198 _(ethernet, ETHERNET_INPUT)                     \
11199 _(ip4, IP4_INPUT)                               \
11200 _(ip6, IP6_INPUT)
11201
11202 uword
11203 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11204 {
11205   u32 *miss_next_indexp = va_arg (*args, u32 *);
11206   u32 next_index = 0;
11207   u32 tmp;
11208
11209 #define _(n,N) \
11210   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11211   foreach_l2_next;
11212 #undef _
11213
11214   if (unformat (input, "%d", &tmp))
11215     {
11216       next_index = tmp;
11217       goto out;
11218     }
11219
11220   return 0;
11221
11222 out:
11223   *miss_next_indexp = next_index;
11224   return 1;
11225 }
11226
11227 #define foreach_ip_next                         \
11228 _(drop, DROP)                                   \
11229 _(local, LOCAL)                                 \
11230 _(rewrite, REWRITE)
11231
11232 uword
11233 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11234 {
11235   u32 *miss_next_indexp = va_arg (*args, u32 *);
11236   u32 next_index = 0;
11237   u32 tmp;
11238
11239 #define _(n,N) \
11240   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11241   foreach_ip_next;
11242 #undef _
11243
11244   if (unformat (input, "%d", &tmp))
11245     {
11246       next_index = tmp;
11247       goto out;
11248     }
11249
11250   return 0;
11251
11252 out:
11253   *miss_next_indexp = next_index;
11254   return 1;
11255 }
11256
11257 #define foreach_acl_next                        \
11258 _(deny, DENY)
11259
11260 uword
11261 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11262 {
11263   u32 *miss_next_indexp = va_arg (*args, u32 *);
11264   u32 next_index = 0;
11265   u32 tmp;
11266
11267 #define _(n,N) \
11268   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11269   foreach_acl_next;
11270 #undef _
11271
11272   if (unformat (input, "permit"))
11273     {
11274       next_index = ~0;
11275       goto out;
11276     }
11277   else if (unformat (input, "%d", &tmp))
11278     {
11279       next_index = tmp;
11280       goto out;
11281     }
11282
11283   return 0;
11284
11285 out:
11286   *miss_next_indexp = next_index;
11287   return 1;
11288 }
11289
11290 uword
11291 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11292 {
11293   u32 *r = va_arg (*args, u32 *);
11294
11295   if (unformat (input, "conform-color"))
11296     *r = POLICE_CONFORM;
11297   else if (unformat (input, "exceed-color"))
11298     *r = POLICE_EXCEED;
11299   else
11300     return 0;
11301
11302   return 1;
11303 }
11304
11305 static int
11306 api_classify_add_del_table (vat_main_t * vam)
11307 {
11308   unformat_input_t *i = vam->input;
11309   vl_api_classify_add_del_table_t *mp;
11310
11311   u32 nbuckets = 2;
11312   u32 skip = ~0;
11313   u32 match = ~0;
11314   int is_add = 1;
11315   int del_chain = 0;
11316   u32 table_index = ~0;
11317   u32 next_table_index = ~0;
11318   u32 miss_next_index = ~0;
11319   u32 memory_size = 32 << 20;
11320   u8 *mask = 0;
11321   u32 current_data_flag = 0;
11322   int current_data_offset = 0;
11323   int ret;
11324
11325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11326     {
11327       if (unformat (i, "del"))
11328         is_add = 0;
11329       else if (unformat (i, "del-chain"))
11330         {
11331           is_add = 0;
11332           del_chain = 1;
11333         }
11334       else if (unformat (i, "buckets %d", &nbuckets))
11335         ;
11336       else if (unformat (i, "memory_size %d", &memory_size))
11337         ;
11338       else if (unformat (i, "skip %d", &skip))
11339         ;
11340       else if (unformat (i, "match %d", &match))
11341         ;
11342       else if (unformat (i, "table %d", &table_index))
11343         ;
11344       else if (unformat (i, "mask %U", unformat_classify_mask,
11345                          &mask, &skip, &match))
11346         ;
11347       else if (unformat (i, "next-table %d", &next_table_index))
11348         ;
11349       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11350                          &miss_next_index))
11351         ;
11352       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11353                          &miss_next_index))
11354         ;
11355       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11356                          &miss_next_index))
11357         ;
11358       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11359         ;
11360       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11361         ;
11362       else
11363         break;
11364     }
11365
11366   if (is_add && mask == 0)
11367     {
11368       errmsg ("Mask required");
11369       return -99;
11370     }
11371
11372   if (is_add && skip == ~0)
11373     {
11374       errmsg ("skip count required");
11375       return -99;
11376     }
11377
11378   if (is_add && match == ~0)
11379     {
11380       errmsg ("match count required");
11381       return -99;
11382     }
11383
11384   if (!is_add && table_index == ~0)
11385     {
11386       errmsg ("table index required for delete");
11387       return -99;
11388     }
11389
11390   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11391
11392   mp->is_add = is_add;
11393   mp->del_chain = del_chain;
11394   mp->table_index = ntohl (table_index);
11395   mp->nbuckets = ntohl (nbuckets);
11396   mp->memory_size = ntohl (memory_size);
11397   mp->skip_n_vectors = ntohl (skip);
11398   mp->match_n_vectors = ntohl (match);
11399   mp->next_table_index = ntohl (next_table_index);
11400   mp->miss_next_index = ntohl (miss_next_index);
11401   mp->current_data_flag = ntohl (current_data_flag);
11402   mp->current_data_offset = ntohl (current_data_offset);
11403   mp->mask_len = ntohl (vec_len (mask));
11404   clib_memcpy (mp->mask, mask, vec_len (mask));
11405
11406   vec_free (mask);
11407
11408   S (mp);
11409   W (ret);
11410   return ret;
11411 }
11412
11413 #if VPP_API_TEST_BUILTIN == 0
11414 uword
11415 unformat_l4_match (unformat_input_t * input, va_list * args)
11416 {
11417   u8 **matchp = va_arg (*args, u8 **);
11418
11419   u8 *proto_header = 0;
11420   int src_port = 0;
11421   int dst_port = 0;
11422
11423   tcpudp_header_t h;
11424
11425   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11426     {
11427       if (unformat (input, "src_port %d", &src_port))
11428         ;
11429       else if (unformat (input, "dst_port %d", &dst_port))
11430         ;
11431       else
11432         return 0;
11433     }
11434
11435   h.src_port = clib_host_to_net_u16 (src_port);
11436   h.dst_port = clib_host_to_net_u16 (dst_port);
11437   vec_validate (proto_header, sizeof (h) - 1);
11438   memcpy (proto_header, &h, sizeof (h));
11439
11440   *matchp = proto_header;
11441
11442   return 1;
11443 }
11444
11445 uword
11446 unformat_ip4_match (unformat_input_t * input, va_list * args)
11447 {
11448   u8 **matchp = va_arg (*args, u8 **);
11449   u8 *match = 0;
11450   ip4_header_t *ip;
11451   int version = 0;
11452   u32 version_val;
11453   int hdr_length = 0;
11454   u32 hdr_length_val;
11455   int src = 0, dst = 0;
11456   ip4_address_t src_val, dst_val;
11457   int proto = 0;
11458   u32 proto_val;
11459   int tos = 0;
11460   u32 tos_val;
11461   int length = 0;
11462   u32 length_val;
11463   int fragment_id = 0;
11464   u32 fragment_id_val;
11465   int ttl = 0;
11466   int ttl_val;
11467   int checksum = 0;
11468   u32 checksum_val;
11469
11470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11471     {
11472       if (unformat (input, "version %d", &version_val))
11473         version = 1;
11474       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11475         hdr_length = 1;
11476       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11477         src = 1;
11478       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11479         dst = 1;
11480       else if (unformat (input, "proto %d", &proto_val))
11481         proto = 1;
11482       else if (unformat (input, "tos %d", &tos_val))
11483         tos = 1;
11484       else if (unformat (input, "length %d", &length_val))
11485         length = 1;
11486       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11487         fragment_id = 1;
11488       else if (unformat (input, "ttl %d", &ttl_val))
11489         ttl = 1;
11490       else if (unformat (input, "checksum %d", &checksum_val))
11491         checksum = 1;
11492       else
11493         break;
11494     }
11495
11496   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11497       + ttl + checksum == 0)
11498     return 0;
11499
11500   /*
11501    * Aligned because we use the real comparison functions
11502    */
11503   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11504
11505   ip = (ip4_header_t *) match;
11506
11507   /* These are realistically matched in practice */
11508   if (src)
11509     ip->src_address.as_u32 = src_val.as_u32;
11510
11511   if (dst)
11512     ip->dst_address.as_u32 = dst_val.as_u32;
11513
11514   if (proto)
11515     ip->protocol = proto_val;
11516
11517
11518   /* These are not, but they're included for completeness */
11519   if (version)
11520     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11521
11522   if (hdr_length)
11523     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11524
11525   if (tos)
11526     ip->tos = tos_val;
11527
11528   if (length)
11529     ip->length = clib_host_to_net_u16 (length_val);
11530
11531   if (ttl)
11532     ip->ttl = ttl_val;
11533
11534   if (checksum)
11535     ip->checksum = clib_host_to_net_u16 (checksum_val);
11536
11537   *matchp = match;
11538   return 1;
11539 }
11540
11541 uword
11542 unformat_ip6_match (unformat_input_t * input, va_list * args)
11543 {
11544   u8 **matchp = va_arg (*args, u8 **);
11545   u8 *match = 0;
11546   ip6_header_t *ip;
11547   int version = 0;
11548   u32 version_val;
11549   u8 traffic_class = 0;
11550   u32 traffic_class_val = 0;
11551   u8 flow_label = 0;
11552   u8 flow_label_val;
11553   int src = 0, dst = 0;
11554   ip6_address_t src_val, dst_val;
11555   int proto = 0;
11556   u32 proto_val;
11557   int payload_length = 0;
11558   u32 payload_length_val;
11559   int hop_limit = 0;
11560   int hop_limit_val;
11561   u32 ip_version_traffic_class_and_flow_label;
11562
11563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11564     {
11565       if (unformat (input, "version %d", &version_val))
11566         version = 1;
11567       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11568         traffic_class = 1;
11569       else if (unformat (input, "flow_label %d", &flow_label_val))
11570         flow_label = 1;
11571       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11572         src = 1;
11573       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11574         dst = 1;
11575       else if (unformat (input, "proto %d", &proto_val))
11576         proto = 1;
11577       else if (unformat (input, "payload_length %d", &payload_length_val))
11578         payload_length = 1;
11579       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11580         hop_limit = 1;
11581       else
11582         break;
11583     }
11584
11585   if (version + traffic_class + flow_label + src + dst + proto +
11586       payload_length + hop_limit == 0)
11587     return 0;
11588
11589   /*
11590    * Aligned because we use the real comparison functions
11591    */
11592   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11593
11594   ip = (ip6_header_t *) match;
11595
11596   if (src)
11597     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11598
11599   if (dst)
11600     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11601
11602   if (proto)
11603     ip->protocol = proto_val;
11604
11605   ip_version_traffic_class_and_flow_label = 0;
11606
11607   if (version)
11608     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11609
11610   if (traffic_class)
11611     ip_version_traffic_class_and_flow_label |=
11612       (traffic_class_val & 0xFF) << 20;
11613
11614   if (flow_label)
11615     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11616
11617   ip->ip_version_traffic_class_and_flow_label =
11618     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11619
11620   if (payload_length)
11621     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11622
11623   if (hop_limit)
11624     ip->hop_limit = hop_limit_val;
11625
11626   *matchp = match;
11627   return 1;
11628 }
11629
11630 uword
11631 unformat_l3_match (unformat_input_t * input, va_list * args)
11632 {
11633   u8 **matchp = va_arg (*args, u8 **);
11634
11635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11636     {
11637       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11638         return 1;
11639       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11640         return 1;
11641       else
11642         break;
11643     }
11644   return 0;
11645 }
11646
11647 uword
11648 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11649 {
11650   u8 *tagp = va_arg (*args, u8 *);
11651   u32 tag;
11652
11653   if (unformat (input, "%d", &tag))
11654     {
11655       tagp[0] = (tag >> 8) & 0x0F;
11656       tagp[1] = tag & 0xFF;
11657       return 1;
11658     }
11659
11660   return 0;
11661 }
11662
11663 uword
11664 unformat_l2_match (unformat_input_t * input, va_list * args)
11665 {
11666   u8 **matchp = va_arg (*args, u8 **);
11667   u8 *match = 0;
11668   u8 src = 0;
11669   u8 src_val[6];
11670   u8 dst = 0;
11671   u8 dst_val[6];
11672   u8 proto = 0;
11673   u16 proto_val;
11674   u8 tag1 = 0;
11675   u8 tag1_val[2];
11676   u8 tag2 = 0;
11677   u8 tag2_val[2];
11678   int len = 14;
11679   u8 ignore_tag1 = 0;
11680   u8 ignore_tag2 = 0;
11681   u8 cos1 = 0;
11682   u8 cos2 = 0;
11683   u32 cos1_val = 0;
11684   u32 cos2_val = 0;
11685
11686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11687     {
11688       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11689         src = 1;
11690       else
11691         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11692         dst = 1;
11693       else if (unformat (input, "proto %U",
11694                          unformat_ethernet_type_host_byte_order, &proto_val))
11695         proto = 1;
11696       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11697         tag1 = 1;
11698       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11699         tag2 = 1;
11700       else if (unformat (input, "ignore-tag1"))
11701         ignore_tag1 = 1;
11702       else if (unformat (input, "ignore-tag2"))
11703         ignore_tag2 = 1;
11704       else if (unformat (input, "cos1 %d", &cos1_val))
11705         cos1 = 1;
11706       else if (unformat (input, "cos2 %d", &cos2_val))
11707         cos2 = 1;
11708       else
11709         break;
11710     }
11711   if ((src + dst + proto + tag1 + tag2 +
11712        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11713     return 0;
11714
11715   if (tag1 || ignore_tag1 || cos1)
11716     len = 18;
11717   if (tag2 || ignore_tag2 || cos2)
11718     len = 22;
11719
11720   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11721
11722   if (dst)
11723     clib_memcpy (match, dst_val, 6);
11724
11725   if (src)
11726     clib_memcpy (match + 6, src_val, 6);
11727
11728   if (tag2)
11729     {
11730       /* inner vlan tag */
11731       match[19] = tag2_val[1];
11732       match[18] = tag2_val[0];
11733       if (cos2)
11734         match[18] |= (cos2_val & 0x7) << 5;
11735       if (proto)
11736         {
11737           match[21] = proto_val & 0xff;
11738           match[20] = proto_val >> 8;
11739         }
11740       if (tag1)
11741         {
11742           match[15] = tag1_val[1];
11743           match[14] = tag1_val[0];
11744         }
11745       if (cos1)
11746         match[14] |= (cos1_val & 0x7) << 5;
11747       *matchp = match;
11748       return 1;
11749     }
11750   if (tag1)
11751     {
11752       match[15] = tag1_val[1];
11753       match[14] = tag1_val[0];
11754       if (proto)
11755         {
11756           match[17] = proto_val & 0xff;
11757           match[16] = proto_val >> 8;
11758         }
11759       if (cos1)
11760         match[14] |= (cos1_val & 0x7) << 5;
11761
11762       *matchp = match;
11763       return 1;
11764     }
11765   if (cos2)
11766     match[18] |= (cos2_val & 0x7) << 5;
11767   if (cos1)
11768     match[14] |= (cos1_val & 0x7) << 5;
11769   if (proto)
11770     {
11771       match[13] = proto_val & 0xff;
11772       match[12] = proto_val >> 8;
11773     }
11774
11775   *matchp = match;
11776   return 1;
11777 }
11778
11779 uword
11780 unformat_qos_source (unformat_input_t * input, va_list * args)
11781 {
11782   int *qs = va_arg (*args, int *);
11783
11784   if (unformat (input, "ip"))
11785     *qs = QOS_SOURCE_IP;
11786   else if (unformat (input, "mpls"))
11787     *qs = QOS_SOURCE_MPLS;
11788   else if (unformat (input, "ext"))
11789     *qs = QOS_SOURCE_EXT;
11790   else if (unformat (input, "vlan"))
11791     *qs = QOS_SOURCE_VLAN;
11792   else
11793     return 0;
11794
11795   return 1;
11796 }
11797 #endif
11798
11799 uword
11800 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11801 {
11802   u8 **matchp = va_arg (*args, u8 **);
11803   u32 skip_n_vectors = va_arg (*args, u32);
11804   u32 match_n_vectors = va_arg (*args, u32);
11805
11806   u8 *match = 0;
11807   u8 *l2 = 0;
11808   u8 *l3 = 0;
11809   u8 *l4 = 0;
11810
11811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11812     {
11813       if (unformat (input, "hex %U", unformat_hex_string, &match))
11814         ;
11815       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11816         ;
11817       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11818         ;
11819       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11820         ;
11821       else
11822         break;
11823     }
11824
11825   if (l4 && !l3)
11826     {
11827       vec_free (match);
11828       vec_free (l2);
11829       vec_free (l4);
11830       return 0;
11831     }
11832
11833   if (match || l2 || l3 || l4)
11834     {
11835       if (l2 || l3 || l4)
11836         {
11837           /* "Win a free Ethernet header in every packet" */
11838           if (l2 == 0)
11839             vec_validate_aligned (l2, 13, sizeof (u32x4));
11840           match = l2;
11841           if (vec_len (l3))
11842             {
11843               vec_append_aligned (match, l3, sizeof (u32x4));
11844               vec_free (l3);
11845             }
11846           if (vec_len (l4))
11847             {
11848               vec_append_aligned (match, l4, sizeof (u32x4));
11849               vec_free (l4);
11850             }
11851         }
11852
11853       /* Make sure the vector is big enough even if key is all 0's */
11854       vec_validate_aligned
11855         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11856          sizeof (u32x4));
11857
11858       /* Set size, include skipped vectors */
11859       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11860
11861       *matchp = match;
11862
11863       return 1;
11864     }
11865
11866   return 0;
11867 }
11868
11869 static int
11870 api_classify_add_del_session (vat_main_t * vam)
11871 {
11872   unformat_input_t *i = vam->input;
11873   vl_api_classify_add_del_session_t *mp;
11874   int is_add = 1;
11875   u32 table_index = ~0;
11876   u32 hit_next_index = ~0;
11877   u32 opaque_index = ~0;
11878   u8 *match = 0;
11879   i32 advance = 0;
11880   u32 skip_n_vectors = 0;
11881   u32 match_n_vectors = 0;
11882   u32 action = 0;
11883   u32 metadata = 0;
11884   int ret;
11885
11886   /*
11887    * Warning: you have to supply skip_n and match_n
11888    * because the API client cant simply look at the classify
11889    * table object.
11890    */
11891
11892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11893     {
11894       if (unformat (i, "del"))
11895         is_add = 0;
11896       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11897                          &hit_next_index))
11898         ;
11899       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11900                          &hit_next_index))
11901         ;
11902       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11903                          &hit_next_index))
11904         ;
11905       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11906         ;
11907       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11908         ;
11909       else if (unformat (i, "opaque-index %d", &opaque_index))
11910         ;
11911       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11912         ;
11913       else if (unformat (i, "match_n %d", &match_n_vectors))
11914         ;
11915       else if (unformat (i, "match %U", api_unformat_classify_match,
11916                          &match, skip_n_vectors, match_n_vectors))
11917         ;
11918       else if (unformat (i, "advance %d", &advance))
11919         ;
11920       else if (unformat (i, "table-index %d", &table_index))
11921         ;
11922       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11923         action = 1;
11924       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11925         action = 2;
11926       else if (unformat (i, "action %d", &action))
11927         ;
11928       else if (unformat (i, "metadata %d", &metadata))
11929         ;
11930       else
11931         break;
11932     }
11933
11934   if (table_index == ~0)
11935     {
11936       errmsg ("Table index required");
11937       return -99;
11938     }
11939
11940   if (is_add && match == 0)
11941     {
11942       errmsg ("Match value required");
11943       return -99;
11944     }
11945
11946   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11947
11948   mp->is_add = is_add;
11949   mp->table_index = ntohl (table_index);
11950   mp->hit_next_index = ntohl (hit_next_index);
11951   mp->opaque_index = ntohl (opaque_index);
11952   mp->advance = ntohl (advance);
11953   mp->action = action;
11954   mp->metadata = ntohl (metadata);
11955   mp->match_len = ntohl (vec_len (match));
11956   clib_memcpy (mp->match, match, vec_len (match));
11957   vec_free (match);
11958
11959   S (mp);
11960   W (ret);
11961   return ret;
11962 }
11963
11964 static int
11965 api_classify_set_interface_ip_table (vat_main_t * vam)
11966 {
11967   unformat_input_t *i = vam->input;
11968   vl_api_classify_set_interface_ip_table_t *mp;
11969   u32 sw_if_index;
11970   int sw_if_index_set;
11971   u32 table_index = ~0;
11972   u8 is_ipv6 = 0;
11973   int ret;
11974
11975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11976     {
11977       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11978         sw_if_index_set = 1;
11979       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11980         sw_if_index_set = 1;
11981       else if (unformat (i, "table %d", &table_index))
11982         ;
11983       else
11984         {
11985           clib_warning ("parse error '%U'", format_unformat_error, i);
11986           return -99;
11987         }
11988     }
11989
11990   if (sw_if_index_set == 0)
11991     {
11992       errmsg ("missing interface name or sw_if_index");
11993       return -99;
11994     }
11995
11996
11997   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11998
11999   mp->sw_if_index = ntohl (sw_if_index);
12000   mp->table_index = ntohl (table_index);
12001   mp->is_ipv6 = is_ipv6;
12002
12003   S (mp);
12004   W (ret);
12005   return ret;
12006 }
12007
12008 static int
12009 api_classify_set_interface_l2_tables (vat_main_t * vam)
12010 {
12011   unformat_input_t *i = vam->input;
12012   vl_api_classify_set_interface_l2_tables_t *mp;
12013   u32 sw_if_index;
12014   int sw_if_index_set;
12015   u32 ip4_table_index = ~0;
12016   u32 ip6_table_index = ~0;
12017   u32 other_table_index = ~0;
12018   u32 is_input = 1;
12019   int ret;
12020
12021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12022     {
12023       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12024         sw_if_index_set = 1;
12025       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12026         sw_if_index_set = 1;
12027       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12028         ;
12029       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12030         ;
12031       else if (unformat (i, "other-table %d", &other_table_index))
12032         ;
12033       else if (unformat (i, "is-input %d", &is_input))
12034         ;
12035       else
12036         {
12037           clib_warning ("parse error '%U'", format_unformat_error, i);
12038           return -99;
12039         }
12040     }
12041
12042   if (sw_if_index_set == 0)
12043     {
12044       errmsg ("missing interface name or sw_if_index");
12045       return -99;
12046     }
12047
12048
12049   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12050
12051   mp->sw_if_index = ntohl (sw_if_index);
12052   mp->ip4_table_index = ntohl (ip4_table_index);
12053   mp->ip6_table_index = ntohl (ip6_table_index);
12054   mp->other_table_index = ntohl (other_table_index);
12055   mp->is_input = (u8) is_input;
12056
12057   S (mp);
12058   W (ret);
12059   return ret;
12060 }
12061
12062 static int
12063 api_set_ipfix_exporter (vat_main_t * vam)
12064 {
12065   unformat_input_t *i = vam->input;
12066   vl_api_set_ipfix_exporter_t *mp;
12067   ip4_address_t collector_address;
12068   u8 collector_address_set = 0;
12069   u32 collector_port = ~0;
12070   ip4_address_t src_address;
12071   u8 src_address_set = 0;
12072   u32 vrf_id = ~0;
12073   u32 path_mtu = ~0;
12074   u32 template_interval = ~0;
12075   u8 udp_checksum = 0;
12076   int ret;
12077
12078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12079     {
12080       if (unformat (i, "collector_address %U", unformat_ip4_address,
12081                     &collector_address))
12082         collector_address_set = 1;
12083       else if (unformat (i, "collector_port %d", &collector_port))
12084         ;
12085       else if (unformat (i, "src_address %U", unformat_ip4_address,
12086                          &src_address))
12087         src_address_set = 1;
12088       else if (unformat (i, "vrf_id %d", &vrf_id))
12089         ;
12090       else if (unformat (i, "path_mtu %d", &path_mtu))
12091         ;
12092       else if (unformat (i, "template_interval %d", &template_interval))
12093         ;
12094       else if (unformat (i, "udp_checksum"))
12095         udp_checksum = 1;
12096       else
12097         break;
12098     }
12099
12100   if (collector_address_set == 0)
12101     {
12102       errmsg ("collector_address required");
12103       return -99;
12104     }
12105
12106   if (src_address_set == 0)
12107     {
12108       errmsg ("src_address required");
12109       return -99;
12110     }
12111
12112   M (SET_IPFIX_EXPORTER, mp);
12113
12114   memcpy (mp->collector_address, collector_address.data,
12115           sizeof (collector_address.data));
12116   mp->collector_port = htons ((u16) collector_port);
12117   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12118   mp->vrf_id = htonl (vrf_id);
12119   mp->path_mtu = htonl (path_mtu);
12120   mp->template_interval = htonl (template_interval);
12121   mp->udp_checksum = udp_checksum;
12122
12123   S (mp);
12124   W (ret);
12125   return ret;
12126 }
12127
12128 static int
12129 api_set_ipfix_classify_stream (vat_main_t * vam)
12130 {
12131   unformat_input_t *i = vam->input;
12132   vl_api_set_ipfix_classify_stream_t *mp;
12133   u32 domain_id = 0;
12134   u32 src_port = UDP_DST_PORT_ipfix;
12135   int ret;
12136
12137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12138     {
12139       if (unformat (i, "domain %d", &domain_id))
12140         ;
12141       else if (unformat (i, "src_port %d", &src_port))
12142         ;
12143       else
12144         {
12145           errmsg ("unknown input `%U'", format_unformat_error, i);
12146           return -99;
12147         }
12148     }
12149
12150   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12151
12152   mp->domain_id = htonl (domain_id);
12153   mp->src_port = htons ((u16) src_port);
12154
12155   S (mp);
12156   W (ret);
12157   return ret;
12158 }
12159
12160 static int
12161 api_ipfix_classify_table_add_del (vat_main_t * vam)
12162 {
12163   unformat_input_t *i = vam->input;
12164   vl_api_ipfix_classify_table_add_del_t *mp;
12165   int is_add = -1;
12166   u32 classify_table_index = ~0;
12167   u8 ip_version = 0;
12168   u8 transport_protocol = 255;
12169   int ret;
12170
12171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12172     {
12173       if (unformat (i, "add"))
12174         is_add = 1;
12175       else if (unformat (i, "del"))
12176         is_add = 0;
12177       else if (unformat (i, "table %d", &classify_table_index))
12178         ;
12179       else if (unformat (i, "ip4"))
12180         ip_version = 4;
12181       else if (unformat (i, "ip6"))
12182         ip_version = 6;
12183       else if (unformat (i, "tcp"))
12184         transport_protocol = 6;
12185       else if (unformat (i, "udp"))
12186         transport_protocol = 17;
12187       else
12188         {
12189           errmsg ("unknown input `%U'", format_unformat_error, i);
12190           return -99;
12191         }
12192     }
12193
12194   if (is_add == -1)
12195     {
12196       errmsg ("expecting: add|del");
12197       return -99;
12198     }
12199   if (classify_table_index == ~0)
12200     {
12201       errmsg ("classifier table not specified");
12202       return -99;
12203     }
12204   if (ip_version == 0)
12205     {
12206       errmsg ("IP version not specified");
12207       return -99;
12208     }
12209
12210   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12211
12212   mp->is_add = is_add;
12213   mp->table_id = htonl (classify_table_index);
12214   mp->ip_version = ip_version;
12215   mp->transport_protocol = transport_protocol;
12216
12217   S (mp);
12218   W (ret);
12219   return ret;
12220 }
12221
12222 static int
12223 api_get_node_index (vat_main_t * vam)
12224 {
12225   unformat_input_t *i = vam->input;
12226   vl_api_get_node_index_t *mp;
12227   u8 *name = 0;
12228   int ret;
12229
12230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12231     {
12232       if (unformat (i, "node %s", &name))
12233         ;
12234       else
12235         break;
12236     }
12237   if (name == 0)
12238     {
12239       errmsg ("node name required");
12240       return -99;
12241     }
12242   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12243     {
12244       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12245       return -99;
12246     }
12247
12248   M (GET_NODE_INDEX, mp);
12249   clib_memcpy (mp->node_name, name, vec_len (name));
12250   vec_free (name);
12251
12252   S (mp);
12253   W (ret);
12254   return ret;
12255 }
12256
12257 static int
12258 api_get_next_index (vat_main_t * vam)
12259 {
12260   unformat_input_t *i = vam->input;
12261   vl_api_get_next_index_t *mp;
12262   u8 *node_name = 0, *next_node_name = 0;
12263   int ret;
12264
12265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12266     {
12267       if (unformat (i, "node-name %s", &node_name))
12268         ;
12269       else if (unformat (i, "next-node-name %s", &next_node_name))
12270         break;
12271     }
12272
12273   if (node_name == 0)
12274     {
12275       errmsg ("node name required");
12276       return -99;
12277     }
12278   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12279     {
12280       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12281       return -99;
12282     }
12283
12284   if (next_node_name == 0)
12285     {
12286       errmsg ("next node name required");
12287       return -99;
12288     }
12289   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12290     {
12291       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12292       return -99;
12293     }
12294
12295   M (GET_NEXT_INDEX, mp);
12296   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12297   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12298   vec_free (node_name);
12299   vec_free (next_node_name);
12300
12301   S (mp);
12302   W (ret);
12303   return ret;
12304 }
12305
12306 static int
12307 api_add_node_next (vat_main_t * vam)
12308 {
12309   unformat_input_t *i = vam->input;
12310   vl_api_add_node_next_t *mp;
12311   u8 *name = 0;
12312   u8 *next = 0;
12313   int ret;
12314
12315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12316     {
12317       if (unformat (i, "node %s", &name))
12318         ;
12319       else if (unformat (i, "next %s", &next))
12320         ;
12321       else
12322         break;
12323     }
12324   if (name == 0)
12325     {
12326       errmsg ("node name required");
12327       return -99;
12328     }
12329   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12330     {
12331       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12332       return -99;
12333     }
12334   if (next == 0)
12335     {
12336       errmsg ("next node required");
12337       return -99;
12338     }
12339   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12340     {
12341       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12342       return -99;
12343     }
12344
12345   M (ADD_NODE_NEXT, mp);
12346   clib_memcpy (mp->node_name, name, vec_len (name));
12347   clib_memcpy (mp->next_name, next, vec_len (next));
12348   vec_free (name);
12349   vec_free (next);
12350
12351   S (mp);
12352   W (ret);
12353   return ret;
12354 }
12355
12356 static int
12357 api_l2tpv3_create_tunnel (vat_main_t * vam)
12358 {
12359   unformat_input_t *i = vam->input;
12360   ip6_address_t client_address, our_address;
12361   int client_address_set = 0;
12362   int our_address_set = 0;
12363   u32 local_session_id = 0;
12364   u32 remote_session_id = 0;
12365   u64 local_cookie = 0;
12366   u64 remote_cookie = 0;
12367   u8 l2_sublayer_present = 0;
12368   vl_api_l2tpv3_create_tunnel_t *mp;
12369   int ret;
12370
12371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12372     {
12373       if (unformat (i, "client_address %U", unformat_ip6_address,
12374                     &client_address))
12375         client_address_set = 1;
12376       else if (unformat (i, "our_address %U", unformat_ip6_address,
12377                          &our_address))
12378         our_address_set = 1;
12379       else if (unformat (i, "local_session_id %d", &local_session_id))
12380         ;
12381       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12382         ;
12383       else if (unformat (i, "local_cookie %lld", &local_cookie))
12384         ;
12385       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12386         ;
12387       else if (unformat (i, "l2-sublayer-present"))
12388         l2_sublayer_present = 1;
12389       else
12390         break;
12391     }
12392
12393   if (client_address_set == 0)
12394     {
12395       errmsg ("client_address required");
12396       return -99;
12397     }
12398
12399   if (our_address_set == 0)
12400     {
12401       errmsg ("our_address required");
12402       return -99;
12403     }
12404
12405   M (L2TPV3_CREATE_TUNNEL, mp);
12406
12407   clib_memcpy (mp->client_address, client_address.as_u8,
12408                sizeof (mp->client_address));
12409
12410   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12411
12412   mp->local_session_id = ntohl (local_session_id);
12413   mp->remote_session_id = ntohl (remote_session_id);
12414   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12415   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12416   mp->l2_sublayer_present = l2_sublayer_present;
12417   mp->is_ipv6 = 1;
12418
12419   S (mp);
12420   W (ret);
12421   return ret;
12422 }
12423
12424 static int
12425 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12426 {
12427   unformat_input_t *i = vam->input;
12428   u32 sw_if_index;
12429   u8 sw_if_index_set = 0;
12430   u64 new_local_cookie = 0;
12431   u64 new_remote_cookie = 0;
12432   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12433   int ret;
12434
12435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12436     {
12437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12438         sw_if_index_set = 1;
12439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12440         sw_if_index_set = 1;
12441       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12442         ;
12443       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12444         ;
12445       else
12446         break;
12447     }
12448
12449   if (sw_if_index_set == 0)
12450     {
12451       errmsg ("missing interface name or sw_if_index");
12452       return -99;
12453     }
12454
12455   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12456
12457   mp->sw_if_index = ntohl (sw_if_index);
12458   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12459   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12460
12461   S (mp);
12462   W (ret);
12463   return ret;
12464 }
12465
12466 static int
12467 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12468 {
12469   unformat_input_t *i = vam->input;
12470   vl_api_l2tpv3_interface_enable_disable_t *mp;
12471   u32 sw_if_index;
12472   u8 sw_if_index_set = 0;
12473   u8 enable_disable = 1;
12474   int ret;
12475
12476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12477     {
12478       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12479         sw_if_index_set = 1;
12480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12481         sw_if_index_set = 1;
12482       else if (unformat (i, "enable"))
12483         enable_disable = 1;
12484       else if (unformat (i, "disable"))
12485         enable_disable = 0;
12486       else
12487         break;
12488     }
12489
12490   if (sw_if_index_set == 0)
12491     {
12492       errmsg ("missing interface name or sw_if_index");
12493       return -99;
12494     }
12495
12496   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12497
12498   mp->sw_if_index = ntohl (sw_if_index);
12499   mp->enable_disable = enable_disable;
12500
12501   S (mp);
12502   W (ret);
12503   return ret;
12504 }
12505
12506 static int
12507 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12508 {
12509   unformat_input_t *i = vam->input;
12510   vl_api_l2tpv3_set_lookup_key_t *mp;
12511   u8 key = ~0;
12512   int ret;
12513
12514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12515     {
12516       if (unformat (i, "lookup_v6_src"))
12517         key = L2T_LOOKUP_SRC_ADDRESS;
12518       else if (unformat (i, "lookup_v6_dst"))
12519         key = L2T_LOOKUP_DST_ADDRESS;
12520       else if (unformat (i, "lookup_session_id"))
12521         key = L2T_LOOKUP_SESSION_ID;
12522       else
12523         break;
12524     }
12525
12526   if (key == (u8) ~ 0)
12527     {
12528       errmsg ("l2tp session lookup key unset");
12529       return -99;
12530     }
12531
12532   M (L2TPV3_SET_LOOKUP_KEY, mp);
12533
12534   mp->key = key;
12535
12536   S (mp);
12537   W (ret);
12538   return ret;
12539 }
12540
12541 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12542   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12543 {
12544   vat_main_t *vam = &vat_main;
12545
12546   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12547          format_ip6_address, mp->our_address,
12548          format_ip6_address, mp->client_address,
12549          clib_net_to_host_u32 (mp->sw_if_index));
12550
12551   print (vam->ofp,
12552          "   local cookies %016llx %016llx remote cookie %016llx",
12553          clib_net_to_host_u64 (mp->local_cookie[0]),
12554          clib_net_to_host_u64 (mp->local_cookie[1]),
12555          clib_net_to_host_u64 (mp->remote_cookie));
12556
12557   print (vam->ofp, "   local session-id %d remote session-id %d",
12558          clib_net_to_host_u32 (mp->local_session_id),
12559          clib_net_to_host_u32 (mp->remote_session_id));
12560
12561   print (vam->ofp, "   l2 specific sublayer %s\n",
12562          mp->l2_sublayer_present ? "preset" : "absent");
12563
12564 }
12565
12566 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12567   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12568 {
12569   vat_main_t *vam = &vat_main;
12570   vat_json_node_t *node = NULL;
12571   struct in6_addr addr;
12572
12573   if (VAT_JSON_ARRAY != vam->json_tree.type)
12574     {
12575       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12576       vat_json_init_array (&vam->json_tree);
12577     }
12578   node = vat_json_array_add (&vam->json_tree);
12579
12580   vat_json_init_object (node);
12581
12582   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12583   vat_json_object_add_ip6 (node, "our_address", addr);
12584   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12585   vat_json_object_add_ip6 (node, "client_address", addr);
12586
12587   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12588   vat_json_init_array (lc);
12589   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12590   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12591   vat_json_object_add_uint (node, "remote_cookie",
12592                             clib_net_to_host_u64 (mp->remote_cookie));
12593
12594   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12595   vat_json_object_add_uint (node, "local_session_id",
12596                             clib_net_to_host_u32 (mp->local_session_id));
12597   vat_json_object_add_uint (node, "remote_session_id",
12598                             clib_net_to_host_u32 (mp->remote_session_id));
12599   vat_json_object_add_string_copy (node, "l2_sublayer",
12600                                    mp->l2_sublayer_present ? (u8 *) "present"
12601                                    : (u8 *) "absent");
12602 }
12603
12604 static int
12605 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12606 {
12607   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12608   vl_api_control_ping_t *mp_ping;
12609   int ret;
12610
12611   /* Get list of l2tpv3-tunnel interfaces */
12612   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12613   S (mp);
12614
12615   /* Use a control ping for synchronization */
12616   MPING (CONTROL_PING, mp_ping);
12617   S (mp_ping);
12618
12619   W (ret);
12620   return ret;
12621 }
12622
12623
12624 static void vl_api_sw_interface_tap_details_t_handler
12625   (vl_api_sw_interface_tap_details_t * mp)
12626 {
12627   vat_main_t *vam = &vat_main;
12628
12629   print (vam->ofp, "%-16s %d",
12630          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12631 }
12632
12633 static void vl_api_sw_interface_tap_details_t_handler_json
12634   (vl_api_sw_interface_tap_details_t * mp)
12635 {
12636   vat_main_t *vam = &vat_main;
12637   vat_json_node_t *node = NULL;
12638
12639   if (VAT_JSON_ARRAY != vam->json_tree.type)
12640     {
12641       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12642       vat_json_init_array (&vam->json_tree);
12643     }
12644   node = vat_json_array_add (&vam->json_tree);
12645
12646   vat_json_init_object (node);
12647   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12648   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12649 }
12650
12651 static int
12652 api_sw_interface_tap_dump (vat_main_t * vam)
12653 {
12654   vl_api_sw_interface_tap_dump_t *mp;
12655   vl_api_control_ping_t *mp_ping;
12656   int ret;
12657
12658   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12659   /* Get list of tap interfaces */
12660   M (SW_INTERFACE_TAP_DUMP, mp);
12661   S (mp);
12662
12663   /* Use a control ping for synchronization */
12664   MPING (CONTROL_PING, mp_ping);
12665   S (mp_ping);
12666
12667   W (ret);
12668   return ret;
12669 }
12670
12671 static void vl_api_sw_interface_tap_v2_details_t_handler
12672   (vl_api_sw_interface_tap_v2_details_t * mp)
12673 {
12674   vat_main_t *vam = &vat_main;
12675
12676   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12677                     mp->host_ip4_prefix_len);
12678   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12679                     mp->host_ip6_prefix_len);
12680
12681   print (vam->ofp,
12682          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12683          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12684          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12685          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12686          mp->host_bridge, ip4, ip6);
12687
12688   vec_free (ip4);
12689   vec_free (ip6);
12690 }
12691
12692 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12693   (vl_api_sw_interface_tap_v2_details_t * mp)
12694 {
12695   vat_main_t *vam = &vat_main;
12696   vat_json_node_t *node = NULL;
12697
12698   if (VAT_JSON_ARRAY != vam->json_tree.type)
12699     {
12700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12701       vat_json_init_array (&vam->json_tree);
12702     }
12703   node = vat_json_array_add (&vam->json_tree);
12704
12705   vat_json_init_object (node);
12706   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12707   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12708   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12709   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12710   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12711   vat_json_object_add_string_copy (node, "host_mac_addr",
12712                                    format (0, "%U", format_ethernet_address,
12713                                            &mp->host_mac_addr));
12714   vat_json_object_add_string_copy (node, "host_namespace",
12715                                    mp->host_namespace);
12716   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12717   vat_json_object_add_string_copy (node, "host_ip4_addr",
12718                                    format (0, "%U/%d", format_ip4_address,
12719                                            mp->host_ip4_addr,
12720                                            mp->host_ip4_prefix_len));
12721   vat_json_object_add_string_copy (node, "host_ip6_addr",
12722                                    format (0, "%U/%d", format_ip6_address,
12723                                            mp->host_ip6_addr,
12724                                            mp->host_ip6_prefix_len));
12725
12726 }
12727
12728 static int
12729 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12730 {
12731   vl_api_sw_interface_tap_v2_dump_t *mp;
12732   vl_api_control_ping_t *mp_ping;
12733   int ret;
12734
12735   print (vam->ofp,
12736          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12737          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12738          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12739          "host_ip6_addr");
12740
12741   /* Get list of tap interfaces */
12742   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12743   S (mp);
12744
12745   /* Use a control ping for synchronization */
12746   MPING (CONTROL_PING, mp_ping);
12747   S (mp_ping);
12748
12749   W (ret);
12750   return ret;
12751 }
12752
12753 static int
12754 api_vxlan_offload_rx (vat_main_t * vam)
12755 {
12756   unformat_input_t *line_input = vam->input;
12757   vl_api_vxlan_offload_rx_t *mp;
12758   u32 hw_if_index = ~0, rx_if_index = ~0;
12759   u8 is_add = 1;
12760   int ret;
12761
12762   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12763     {
12764       if (unformat (line_input, "del"))
12765         is_add = 0;
12766       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12767                          &hw_if_index))
12768         ;
12769       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12770         ;
12771       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12772                          &rx_if_index))
12773         ;
12774       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12775         ;
12776       else
12777         {
12778           errmsg ("parse error '%U'", format_unformat_error, line_input);
12779           return -99;
12780         }
12781     }
12782
12783   if (hw_if_index == ~0)
12784     {
12785       errmsg ("no hw interface");
12786       return -99;
12787     }
12788
12789   if (rx_if_index == ~0)
12790     {
12791       errmsg ("no rx tunnel");
12792       return -99;
12793     }
12794
12795   M (VXLAN_OFFLOAD_RX, mp);
12796
12797   mp->hw_if_index = ntohl (hw_if_index);
12798   mp->sw_if_index = ntohl (rx_if_index);
12799   mp->enable = is_add;
12800
12801   S (mp);
12802   W (ret);
12803   return ret;
12804 }
12805
12806 static uword unformat_vxlan_decap_next
12807   (unformat_input_t * input, va_list * args)
12808 {
12809   u32 *result = va_arg (*args, u32 *);
12810   u32 tmp;
12811
12812   if (unformat (input, "l2"))
12813     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12814   else if (unformat (input, "%d", &tmp))
12815     *result = tmp;
12816   else
12817     return 0;
12818   return 1;
12819 }
12820
12821 static int
12822 api_vxlan_add_del_tunnel (vat_main_t * vam)
12823 {
12824   unformat_input_t *line_input = vam->input;
12825   vl_api_vxlan_add_del_tunnel_t *mp;
12826   ip46_address_t src, dst;
12827   u8 is_add = 1;
12828   u8 ipv4_set = 0, ipv6_set = 0;
12829   u8 src_set = 0;
12830   u8 dst_set = 0;
12831   u8 grp_set = 0;
12832   u32 instance = ~0;
12833   u32 mcast_sw_if_index = ~0;
12834   u32 encap_vrf_id = 0;
12835   u32 decap_next_index = ~0;
12836   u32 vni = 0;
12837   int ret;
12838
12839   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12840   clib_memset (&src, 0, sizeof src);
12841   clib_memset (&dst, 0, sizeof dst);
12842
12843   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12844     {
12845       if (unformat (line_input, "del"))
12846         is_add = 0;
12847       else if (unformat (line_input, "instance %d", &instance))
12848         ;
12849       else
12850         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12851         {
12852           ipv4_set = 1;
12853           src_set = 1;
12854         }
12855       else
12856         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12857         {
12858           ipv4_set = 1;
12859           dst_set = 1;
12860         }
12861       else
12862         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12863         {
12864           ipv6_set = 1;
12865           src_set = 1;
12866         }
12867       else
12868         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12869         {
12870           ipv6_set = 1;
12871           dst_set = 1;
12872         }
12873       else if (unformat (line_input, "group %U %U",
12874                          unformat_ip4_address, &dst.ip4,
12875                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12876         {
12877           grp_set = dst_set = 1;
12878           ipv4_set = 1;
12879         }
12880       else if (unformat (line_input, "group %U",
12881                          unformat_ip4_address, &dst.ip4))
12882         {
12883           grp_set = dst_set = 1;
12884           ipv4_set = 1;
12885         }
12886       else if (unformat (line_input, "group %U %U",
12887                          unformat_ip6_address, &dst.ip6,
12888                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12889         {
12890           grp_set = dst_set = 1;
12891           ipv6_set = 1;
12892         }
12893       else if (unformat (line_input, "group %U",
12894                          unformat_ip6_address, &dst.ip6))
12895         {
12896           grp_set = dst_set = 1;
12897           ipv6_set = 1;
12898         }
12899       else
12900         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12901         ;
12902       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12903         ;
12904       else if (unformat (line_input, "decap-next %U",
12905                          unformat_vxlan_decap_next, &decap_next_index))
12906         ;
12907       else if (unformat (line_input, "vni %d", &vni))
12908         ;
12909       else
12910         {
12911           errmsg ("parse error '%U'", format_unformat_error, line_input);
12912           return -99;
12913         }
12914     }
12915
12916   if (src_set == 0)
12917     {
12918       errmsg ("tunnel src address not specified");
12919       return -99;
12920     }
12921   if (dst_set == 0)
12922     {
12923       errmsg ("tunnel dst address not specified");
12924       return -99;
12925     }
12926
12927   if (grp_set && !ip46_address_is_multicast (&dst))
12928     {
12929       errmsg ("tunnel group address not multicast");
12930       return -99;
12931     }
12932   if (grp_set && mcast_sw_if_index == ~0)
12933     {
12934       errmsg ("tunnel nonexistent multicast device");
12935       return -99;
12936     }
12937   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12938     {
12939       errmsg ("tunnel dst address must be unicast");
12940       return -99;
12941     }
12942
12943
12944   if (ipv4_set && ipv6_set)
12945     {
12946       errmsg ("both IPv4 and IPv6 addresses specified");
12947       return -99;
12948     }
12949
12950   if ((vni == 0) || (vni >> 24))
12951     {
12952       errmsg ("vni not specified or out of range");
12953       return -99;
12954     }
12955
12956   M (VXLAN_ADD_DEL_TUNNEL, mp);
12957
12958   if (ipv6_set)
12959     {
12960       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12961       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12962     }
12963   else
12964     {
12965       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12966       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12967     }
12968
12969   mp->instance = htonl (instance);
12970   mp->encap_vrf_id = ntohl (encap_vrf_id);
12971   mp->decap_next_index = ntohl (decap_next_index);
12972   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12973   mp->vni = ntohl (vni);
12974   mp->is_add = is_add;
12975   mp->is_ipv6 = ipv6_set;
12976
12977   S (mp);
12978   W (ret);
12979   return ret;
12980 }
12981
12982 static void vl_api_vxlan_tunnel_details_t_handler
12983   (vl_api_vxlan_tunnel_details_t * mp)
12984 {
12985   vat_main_t *vam = &vat_main;
12986   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12987   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12988
12989   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12990          ntohl (mp->sw_if_index),
12991          ntohl (mp->instance),
12992          format_ip46_address, &src, IP46_TYPE_ANY,
12993          format_ip46_address, &dst, IP46_TYPE_ANY,
12994          ntohl (mp->encap_vrf_id),
12995          ntohl (mp->decap_next_index), ntohl (mp->vni),
12996          ntohl (mp->mcast_sw_if_index));
12997 }
12998
12999 static void vl_api_vxlan_tunnel_details_t_handler_json
13000   (vl_api_vxlan_tunnel_details_t * mp)
13001 {
13002   vat_main_t *vam = &vat_main;
13003   vat_json_node_t *node = NULL;
13004
13005   if (VAT_JSON_ARRAY != vam->json_tree.type)
13006     {
13007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13008       vat_json_init_array (&vam->json_tree);
13009     }
13010   node = vat_json_array_add (&vam->json_tree);
13011
13012   vat_json_init_object (node);
13013   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13014
13015   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13016
13017   if (mp->is_ipv6)
13018     {
13019       struct in6_addr ip6;
13020
13021       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13022       vat_json_object_add_ip6 (node, "src_address", ip6);
13023       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13024       vat_json_object_add_ip6 (node, "dst_address", ip6);
13025     }
13026   else
13027     {
13028       struct in_addr ip4;
13029
13030       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13031       vat_json_object_add_ip4 (node, "src_address", ip4);
13032       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13033       vat_json_object_add_ip4 (node, "dst_address", ip4);
13034     }
13035   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13036   vat_json_object_add_uint (node, "decap_next_index",
13037                             ntohl (mp->decap_next_index));
13038   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13039   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13040   vat_json_object_add_uint (node, "mcast_sw_if_index",
13041                             ntohl (mp->mcast_sw_if_index));
13042 }
13043
13044 static int
13045 api_vxlan_tunnel_dump (vat_main_t * vam)
13046 {
13047   unformat_input_t *i = vam->input;
13048   vl_api_vxlan_tunnel_dump_t *mp;
13049   vl_api_control_ping_t *mp_ping;
13050   u32 sw_if_index;
13051   u8 sw_if_index_set = 0;
13052   int ret;
13053
13054   /* Parse args required to build the message */
13055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13056     {
13057       if (unformat (i, "sw_if_index %d", &sw_if_index))
13058         sw_if_index_set = 1;
13059       else
13060         break;
13061     }
13062
13063   if (sw_if_index_set == 0)
13064     {
13065       sw_if_index = ~0;
13066     }
13067
13068   if (!vam->json_output)
13069     {
13070       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13071              "sw_if_index", "instance", "src_address", "dst_address",
13072              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13073     }
13074
13075   /* Get list of vxlan-tunnel interfaces */
13076   M (VXLAN_TUNNEL_DUMP, mp);
13077
13078   mp->sw_if_index = htonl (sw_if_index);
13079
13080   S (mp);
13081
13082   /* Use a control ping for synchronization */
13083   MPING (CONTROL_PING, mp_ping);
13084   S (mp_ping);
13085
13086   W (ret);
13087   return ret;
13088 }
13089
13090 static uword unformat_geneve_decap_next
13091   (unformat_input_t * input, va_list * args)
13092 {
13093   u32 *result = va_arg (*args, u32 *);
13094   u32 tmp;
13095
13096   if (unformat (input, "l2"))
13097     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13098   else if (unformat (input, "%d", &tmp))
13099     *result = tmp;
13100   else
13101     return 0;
13102   return 1;
13103 }
13104
13105 static int
13106 api_geneve_add_del_tunnel (vat_main_t * vam)
13107 {
13108   unformat_input_t *line_input = vam->input;
13109   vl_api_geneve_add_del_tunnel_t *mp;
13110   ip46_address_t src, dst;
13111   u8 is_add = 1;
13112   u8 ipv4_set = 0, ipv6_set = 0;
13113   u8 src_set = 0;
13114   u8 dst_set = 0;
13115   u8 grp_set = 0;
13116   u32 mcast_sw_if_index = ~0;
13117   u32 encap_vrf_id = 0;
13118   u32 decap_next_index = ~0;
13119   u32 vni = 0;
13120   int ret;
13121
13122   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13123   clib_memset (&src, 0, sizeof src);
13124   clib_memset (&dst, 0, sizeof dst);
13125
13126   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13127     {
13128       if (unformat (line_input, "del"))
13129         is_add = 0;
13130       else
13131         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13132         {
13133           ipv4_set = 1;
13134           src_set = 1;
13135         }
13136       else
13137         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13138         {
13139           ipv4_set = 1;
13140           dst_set = 1;
13141         }
13142       else
13143         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13144         {
13145           ipv6_set = 1;
13146           src_set = 1;
13147         }
13148       else
13149         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13150         {
13151           ipv6_set = 1;
13152           dst_set = 1;
13153         }
13154       else if (unformat (line_input, "group %U %U",
13155                          unformat_ip4_address, &dst.ip4,
13156                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13157         {
13158           grp_set = dst_set = 1;
13159           ipv4_set = 1;
13160         }
13161       else if (unformat (line_input, "group %U",
13162                          unformat_ip4_address, &dst.ip4))
13163         {
13164           grp_set = dst_set = 1;
13165           ipv4_set = 1;
13166         }
13167       else if (unformat (line_input, "group %U %U",
13168                          unformat_ip6_address, &dst.ip6,
13169                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13170         {
13171           grp_set = dst_set = 1;
13172           ipv6_set = 1;
13173         }
13174       else if (unformat (line_input, "group %U",
13175                          unformat_ip6_address, &dst.ip6))
13176         {
13177           grp_set = dst_set = 1;
13178           ipv6_set = 1;
13179         }
13180       else
13181         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13182         ;
13183       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13184         ;
13185       else if (unformat (line_input, "decap-next %U",
13186                          unformat_geneve_decap_next, &decap_next_index))
13187         ;
13188       else if (unformat (line_input, "vni %d", &vni))
13189         ;
13190       else
13191         {
13192           errmsg ("parse error '%U'", format_unformat_error, line_input);
13193           return -99;
13194         }
13195     }
13196
13197   if (src_set == 0)
13198     {
13199       errmsg ("tunnel src address not specified");
13200       return -99;
13201     }
13202   if (dst_set == 0)
13203     {
13204       errmsg ("tunnel dst address not specified");
13205       return -99;
13206     }
13207
13208   if (grp_set && !ip46_address_is_multicast (&dst))
13209     {
13210       errmsg ("tunnel group address not multicast");
13211       return -99;
13212     }
13213   if (grp_set && mcast_sw_if_index == ~0)
13214     {
13215       errmsg ("tunnel nonexistent multicast device");
13216       return -99;
13217     }
13218   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13219     {
13220       errmsg ("tunnel dst address must be unicast");
13221       return -99;
13222     }
13223
13224
13225   if (ipv4_set && ipv6_set)
13226     {
13227       errmsg ("both IPv4 and IPv6 addresses specified");
13228       return -99;
13229     }
13230
13231   if ((vni == 0) || (vni >> 24))
13232     {
13233       errmsg ("vni not specified or out of range");
13234       return -99;
13235     }
13236
13237   M (GENEVE_ADD_DEL_TUNNEL, mp);
13238
13239   if (ipv6_set)
13240     {
13241       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13242       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13243     }
13244   else
13245     {
13246       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13247       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13248     }
13249   mp->encap_vrf_id = ntohl (encap_vrf_id);
13250   mp->decap_next_index = ntohl (decap_next_index);
13251   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13252   mp->vni = ntohl (vni);
13253   mp->is_add = is_add;
13254   mp->is_ipv6 = ipv6_set;
13255
13256   S (mp);
13257   W (ret);
13258   return ret;
13259 }
13260
13261 static void vl_api_geneve_tunnel_details_t_handler
13262   (vl_api_geneve_tunnel_details_t * mp)
13263 {
13264   vat_main_t *vam = &vat_main;
13265   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13266   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13267
13268   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13269          ntohl (mp->sw_if_index),
13270          format_ip46_address, &src, IP46_TYPE_ANY,
13271          format_ip46_address, &dst, IP46_TYPE_ANY,
13272          ntohl (mp->encap_vrf_id),
13273          ntohl (mp->decap_next_index), ntohl (mp->vni),
13274          ntohl (mp->mcast_sw_if_index));
13275 }
13276
13277 static void vl_api_geneve_tunnel_details_t_handler_json
13278   (vl_api_geneve_tunnel_details_t * mp)
13279 {
13280   vat_main_t *vam = &vat_main;
13281   vat_json_node_t *node = NULL;
13282
13283   if (VAT_JSON_ARRAY != vam->json_tree.type)
13284     {
13285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13286       vat_json_init_array (&vam->json_tree);
13287     }
13288   node = vat_json_array_add (&vam->json_tree);
13289
13290   vat_json_init_object (node);
13291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13292   if (mp->is_ipv6)
13293     {
13294       struct in6_addr ip6;
13295
13296       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13297       vat_json_object_add_ip6 (node, "src_address", ip6);
13298       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13299       vat_json_object_add_ip6 (node, "dst_address", ip6);
13300     }
13301   else
13302     {
13303       struct in_addr ip4;
13304
13305       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13306       vat_json_object_add_ip4 (node, "src_address", ip4);
13307       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13308       vat_json_object_add_ip4 (node, "dst_address", ip4);
13309     }
13310   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13311   vat_json_object_add_uint (node, "decap_next_index",
13312                             ntohl (mp->decap_next_index));
13313   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13314   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13315   vat_json_object_add_uint (node, "mcast_sw_if_index",
13316                             ntohl (mp->mcast_sw_if_index));
13317 }
13318
13319 static int
13320 api_geneve_tunnel_dump (vat_main_t * vam)
13321 {
13322   unformat_input_t *i = vam->input;
13323   vl_api_geneve_tunnel_dump_t *mp;
13324   vl_api_control_ping_t *mp_ping;
13325   u32 sw_if_index;
13326   u8 sw_if_index_set = 0;
13327   int ret;
13328
13329   /* Parse args required to build the message */
13330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13331     {
13332       if (unformat (i, "sw_if_index %d", &sw_if_index))
13333         sw_if_index_set = 1;
13334       else
13335         break;
13336     }
13337
13338   if (sw_if_index_set == 0)
13339     {
13340       sw_if_index = ~0;
13341     }
13342
13343   if (!vam->json_output)
13344     {
13345       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13346              "sw_if_index", "local_address", "remote_address",
13347              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13348     }
13349
13350   /* Get list of geneve-tunnel interfaces */
13351   M (GENEVE_TUNNEL_DUMP, mp);
13352
13353   mp->sw_if_index = htonl (sw_if_index);
13354
13355   S (mp);
13356
13357   /* Use a control ping for synchronization */
13358   M (CONTROL_PING, mp_ping);
13359   S (mp_ping);
13360
13361   W (ret);
13362   return ret;
13363 }
13364
13365 static int
13366 api_gre_add_del_tunnel (vat_main_t * vam)
13367 {
13368   unformat_input_t *line_input = vam->input;
13369   vl_api_gre_add_del_tunnel_t *mp;
13370   ip4_address_t src4, dst4;
13371   ip6_address_t src6, dst6;
13372   u8 is_add = 1;
13373   u8 ipv4_set = 0;
13374   u8 ipv6_set = 0;
13375   u8 t_type = GRE_TUNNEL_TYPE_L3;
13376   u8 src_set = 0;
13377   u8 dst_set = 0;
13378   u32 outer_fib_id = 0;
13379   u32 session_id = 0;
13380   u32 instance = ~0;
13381   int ret;
13382
13383   clib_memset (&src4, 0, sizeof src4);
13384   clib_memset (&dst4, 0, sizeof dst4);
13385   clib_memset (&src6, 0, sizeof src6);
13386   clib_memset (&dst6, 0, sizeof dst6);
13387
13388   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13389     {
13390       if (unformat (line_input, "del"))
13391         is_add = 0;
13392       else if (unformat (line_input, "instance %d", &instance))
13393         ;
13394       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13395         {
13396           src_set = 1;
13397           ipv4_set = 1;
13398         }
13399       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13400         {
13401           dst_set = 1;
13402           ipv4_set = 1;
13403         }
13404       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13405         {
13406           src_set = 1;
13407           ipv6_set = 1;
13408         }
13409       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13410         {
13411           dst_set = 1;
13412           ipv6_set = 1;
13413         }
13414       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13415         ;
13416       else if (unformat (line_input, "teb"))
13417         t_type = GRE_TUNNEL_TYPE_TEB;
13418       else if (unformat (line_input, "erspan %d", &session_id))
13419         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13420       else
13421         {
13422           errmsg ("parse error '%U'", format_unformat_error, line_input);
13423           return -99;
13424         }
13425     }
13426
13427   if (src_set == 0)
13428     {
13429       errmsg ("tunnel src address not specified");
13430       return -99;
13431     }
13432   if (dst_set == 0)
13433     {
13434       errmsg ("tunnel dst address not specified");
13435       return -99;
13436     }
13437   if (ipv4_set && ipv6_set)
13438     {
13439       errmsg ("both IPv4 and IPv6 addresses specified");
13440       return -99;
13441     }
13442
13443
13444   M (GRE_ADD_DEL_TUNNEL, mp);
13445
13446   if (ipv4_set)
13447     {
13448       clib_memcpy (&mp->src_address, &src4, 4);
13449       clib_memcpy (&mp->dst_address, &dst4, 4);
13450     }
13451   else
13452     {
13453       clib_memcpy (&mp->src_address, &src6, 16);
13454       clib_memcpy (&mp->dst_address, &dst6, 16);
13455     }
13456   mp->instance = htonl (instance);
13457   mp->outer_fib_id = htonl (outer_fib_id);
13458   mp->is_add = is_add;
13459   mp->session_id = htons ((u16) session_id);
13460   mp->tunnel_type = t_type;
13461   mp->is_ipv6 = ipv6_set;
13462
13463   S (mp);
13464   W (ret);
13465   return ret;
13466 }
13467
13468 static void vl_api_gre_tunnel_details_t_handler
13469   (vl_api_gre_tunnel_details_t * mp)
13470 {
13471   vat_main_t *vam = &vat_main;
13472   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13473   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13474
13475   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13476          ntohl (mp->sw_if_index),
13477          ntohl (mp->instance),
13478          format_ip46_address, &src, IP46_TYPE_ANY,
13479          format_ip46_address, &dst, IP46_TYPE_ANY,
13480          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13481 }
13482
13483 static void vl_api_gre_tunnel_details_t_handler_json
13484   (vl_api_gre_tunnel_details_t * mp)
13485 {
13486   vat_main_t *vam = &vat_main;
13487   vat_json_node_t *node = NULL;
13488   struct in_addr ip4;
13489   struct in6_addr ip6;
13490
13491   if (VAT_JSON_ARRAY != vam->json_tree.type)
13492     {
13493       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13494       vat_json_init_array (&vam->json_tree);
13495     }
13496   node = vat_json_array_add (&vam->json_tree);
13497
13498   vat_json_init_object (node);
13499   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13500   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13501   if (!mp->is_ipv6)
13502     {
13503       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13504       vat_json_object_add_ip4 (node, "src_address", ip4);
13505       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13506       vat_json_object_add_ip4 (node, "dst_address", ip4);
13507     }
13508   else
13509     {
13510       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13511       vat_json_object_add_ip6 (node, "src_address", ip6);
13512       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13513       vat_json_object_add_ip6 (node, "dst_address", ip6);
13514     }
13515   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13516   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13517   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13518   vat_json_object_add_uint (node, "session_id", mp->session_id);
13519 }
13520
13521 static int
13522 api_gre_tunnel_dump (vat_main_t * vam)
13523 {
13524   unformat_input_t *i = vam->input;
13525   vl_api_gre_tunnel_dump_t *mp;
13526   vl_api_control_ping_t *mp_ping;
13527   u32 sw_if_index;
13528   u8 sw_if_index_set = 0;
13529   int ret;
13530
13531   /* Parse args required to build the message */
13532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13533     {
13534       if (unformat (i, "sw_if_index %d", &sw_if_index))
13535         sw_if_index_set = 1;
13536       else
13537         break;
13538     }
13539
13540   if (sw_if_index_set == 0)
13541     {
13542       sw_if_index = ~0;
13543     }
13544
13545   if (!vam->json_output)
13546     {
13547       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13548              "sw_if_index", "instance", "src_address", "dst_address",
13549              "tunnel_type", "outer_fib_id", "session_id");
13550     }
13551
13552   /* Get list of gre-tunnel interfaces */
13553   M (GRE_TUNNEL_DUMP, mp);
13554
13555   mp->sw_if_index = htonl (sw_if_index);
13556
13557   S (mp);
13558
13559   /* Use a control ping for synchronization */
13560   MPING (CONTROL_PING, mp_ping);
13561   S (mp_ping);
13562
13563   W (ret);
13564   return ret;
13565 }
13566
13567 static int
13568 api_l2_fib_clear_table (vat_main_t * vam)
13569 {
13570 //  unformat_input_t * i = vam->input;
13571   vl_api_l2_fib_clear_table_t *mp;
13572   int ret;
13573
13574   M (L2_FIB_CLEAR_TABLE, mp);
13575
13576   S (mp);
13577   W (ret);
13578   return ret;
13579 }
13580
13581 static int
13582 api_l2_interface_efp_filter (vat_main_t * vam)
13583 {
13584   unformat_input_t *i = vam->input;
13585   vl_api_l2_interface_efp_filter_t *mp;
13586   u32 sw_if_index;
13587   u8 enable = 1;
13588   u8 sw_if_index_set = 0;
13589   int ret;
13590
13591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13592     {
13593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13594         sw_if_index_set = 1;
13595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13596         sw_if_index_set = 1;
13597       else if (unformat (i, "enable"))
13598         enable = 1;
13599       else if (unformat (i, "disable"))
13600         enable = 0;
13601       else
13602         {
13603           clib_warning ("parse error '%U'", format_unformat_error, i);
13604           return -99;
13605         }
13606     }
13607
13608   if (sw_if_index_set == 0)
13609     {
13610       errmsg ("missing sw_if_index");
13611       return -99;
13612     }
13613
13614   M (L2_INTERFACE_EFP_FILTER, mp);
13615
13616   mp->sw_if_index = ntohl (sw_if_index);
13617   mp->enable_disable = enable;
13618
13619   S (mp);
13620   W (ret);
13621   return ret;
13622 }
13623
13624 #define foreach_vtr_op                          \
13625 _("disable",  L2_VTR_DISABLED)                  \
13626 _("push-1",  L2_VTR_PUSH_1)                     \
13627 _("push-2",  L2_VTR_PUSH_2)                     \
13628 _("pop-1",  L2_VTR_POP_1)                       \
13629 _("pop-2",  L2_VTR_POP_2)                       \
13630 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13631 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13632 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13633 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13634
13635 static int
13636 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13637 {
13638   unformat_input_t *i = vam->input;
13639   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13640   u32 sw_if_index;
13641   u8 sw_if_index_set = 0;
13642   u8 vtr_op_set = 0;
13643   u32 vtr_op = 0;
13644   u32 push_dot1q = 1;
13645   u32 tag1 = ~0;
13646   u32 tag2 = ~0;
13647   int ret;
13648
13649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13650     {
13651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13652         sw_if_index_set = 1;
13653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13654         sw_if_index_set = 1;
13655       else if (unformat (i, "vtr_op %d", &vtr_op))
13656         vtr_op_set = 1;
13657 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13658       foreach_vtr_op
13659 #undef _
13660         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13661         ;
13662       else if (unformat (i, "tag1 %d", &tag1))
13663         ;
13664       else if (unformat (i, "tag2 %d", &tag2))
13665         ;
13666       else
13667         {
13668           clib_warning ("parse error '%U'", format_unformat_error, i);
13669           return -99;
13670         }
13671     }
13672
13673   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13674     {
13675       errmsg ("missing vtr operation or sw_if_index");
13676       return -99;
13677     }
13678
13679   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13680   mp->sw_if_index = ntohl (sw_if_index);
13681   mp->vtr_op = ntohl (vtr_op);
13682   mp->push_dot1q = ntohl (push_dot1q);
13683   mp->tag1 = ntohl (tag1);
13684   mp->tag2 = ntohl (tag2);
13685
13686   S (mp);
13687   W (ret);
13688   return ret;
13689 }
13690
13691 static int
13692 api_create_vhost_user_if (vat_main_t * vam)
13693 {
13694   unformat_input_t *i = vam->input;
13695   vl_api_create_vhost_user_if_t *mp;
13696   u8 *file_name;
13697   u8 is_server = 0;
13698   u8 file_name_set = 0;
13699   u32 custom_dev_instance = ~0;
13700   u8 hwaddr[6];
13701   u8 use_custom_mac = 0;
13702   u8 disable_mrg_rxbuf = 0;
13703   u8 disable_indirect_desc = 0;
13704   u8 *tag = 0;
13705   int ret;
13706
13707   /* Shut up coverity */
13708   clib_memset (hwaddr, 0, sizeof (hwaddr));
13709
13710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13711     {
13712       if (unformat (i, "socket %s", &file_name))
13713         {
13714           file_name_set = 1;
13715         }
13716       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13717         ;
13718       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13719         use_custom_mac = 1;
13720       else if (unformat (i, "server"))
13721         is_server = 1;
13722       else if (unformat (i, "disable_mrg_rxbuf"))
13723         disable_mrg_rxbuf = 1;
13724       else if (unformat (i, "disable_indirect_desc"))
13725         disable_indirect_desc = 1;
13726       else if (unformat (i, "tag %s", &tag))
13727         ;
13728       else
13729         break;
13730     }
13731
13732   if (file_name_set == 0)
13733     {
13734       errmsg ("missing socket file name");
13735       return -99;
13736     }
13737
13738   if (vec_len (file_name) > 255)
13739     {
13740       errmsg ("socket file name too long");
13741       return -99;
13742     }
13743   vec_add1 (file_name, 0);
13744
13745   M (CREATE_VHOST_USER_IF, mp);
13746
13747   mp->is_server = is_server;
13748   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13749   mp->disable_indirect_desc = disable_indirect_desc;
13750   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13751   vec_free (file_name);
13752   if (custom_dev_instance != ~0)
13753     {
13754       mp->renumber = 1;
13755       mp->custom_dev_instance = ntohl (custom_dev_instance);
13756     }
13757
13758   mp->use_custom_mac = use_custom_mac;
13759   clib_memcpy (mp->mac_address, hwaddr, 6);
13760   if (tag)
13761     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13762   vec_free (tag);
13763
13764   S (mp);
13765   W (ret);
13766   return ret;
13767 }
13768
13769 static int
13770 api_modify_vhost_user_if (vat_main_t * vam)
13771 {
13772   unformat_input_t *i = vam->input;
13773   vl_api_modify_vhost_user_if_t *mp;
13774   u8 *file_name;
13775   u8 is_server = 0;
13776   u8 file_name_set = 0;
13777   u32 custom_dev_instance = ~0;
13778   u8 sw_if_index_set = 0;
13779   u32 sw_if_index = (u32) ~ 0;
13780   int ret;
13781
13782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13783     {
13784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13785         sw_if_index_set = 1;
13786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13787         sw_if_index_set = 1;
13788       else if (unformat (i, "socket %s", &file_name))
13789         {
13790           file_name_set = 1;
13791         }
13792       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13793         ;
13794       else if (unformat (i, "server"))
13795         is_server = 1;
13796       else
13797         break;
13798     }
13799
13800   if (sw_if_index_set == 0)
13801     {
13802       errmsg ("missing sw_if_index or interface name");
13803       return -99;
13804     }
13805
13806   if (file_name_set == 0)
13807     {
13808       errmsg ("missing socket file name");
13809       return -99;
13810     }
13811
13812   if (vec_len (file_name) > 255)
13813     {
13814       errmsg ("socket file name too long");
13815       return -99;
13816     }
13817   vec_add1 (file_name, 0);
13818
13819   M (MODIFY_VHOST_USER_IF, mp);
13820
13821   mp->sw_if_index = ntohl (sw_if_index);
13822   mp->is_server = is_server;
13823   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13824   vec_free (file_name);
13825   if (custom_dev_instance != ~0)
13826     {
13827       mp->renumber = 1;
13828       mp->custom_dev_instance = ntohl (custom_dev_instance);
13829     }
13830
13831   S (mp);
13832   W (ret);
13833   return ret;
13834 }
13835
13836 static int
13837 api_delete_vhost_user_if (vat_main_t * vam)
13838 {
13839   unformat_input_t *i = vam->input;
13840   vl_api_delete_vhost_user_if_t *mp;
13841   u32 sw_if_index = ~0;
13842   u8 sw_if_index_set = 0;
13843   int ret;
13844
13845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13846     {
13847       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13848         sw_if_index_set = 1;
13849       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13850         sw_if_index_set = 1;
13851       else
13852         break;
13853     }
13854
13855   if (sw_if_index_set == 0)
13856     {
13857       errmsg ("missing sw_if_index or interface name");
13858       return -99;
13859     }
13860
13861
13862   M (DELETE_VHOST_USER_IF, mp);
13863
13864   mp->sw_if_index = ntohl (sw_if_index);
13865
13866   S (mp);
13867   W (ret);
13868   return ret;
13869 }
13870
13871 static void vl_api_sw_interface_vhost_user_details_t_handler
13872   (vl_api_sw_interface_vhost_user_details_t * mp)
13873 {
13874   vat_main_t *vam = &vat_main;
13875
13876   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13877          (char *) mp->interface_name,
13878          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13879          clib_net_to_host_u64 (mp->features), mp->is_server,
13880          ntohl (mp->num_regions), (char *) mp->sock_filename);
13881   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13882 }
13883
13884 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13885   (vl_api_sw_interface_vhost_user_details_t * mp)
13886 {
13887   vat_main_t *vam = &vat_main;
13888   vat_json_node_t *node = NULL;
13889
13890   if (VAT_JSON_ARRAY != vam->json_tree.type)
13891     {
13892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13893       vat_json_init_array (&vam->json_tree);
13894     }
13895   node = vat_json_array_add (&vam->json_tree);
13896
13897   vat_json_init_object (node);
13898   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13899   vat_json_object_add_string_copy (node, "interface_name",
13900                                    mp->interface_name);
13901   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13902                             ntohl (mp->virtio_net_hdr_sz));
13903   vat_json_object_add_uint (node, "features",
13904                             clib_net_to_host_u64 (mp->features));
13905   vat_json_object_add_uint (node, "is_server", mp->is_server);
13906   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13907   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13908   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13909 }
13910
13911 static int
13912 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13913 {
13914   vl_api_sw_interface_vhost_user_dump_t *mp;
13915   vl_api_control_ping_t *mp_ping;
13916   int ret;
13917   print (vam->ofp,
13918          "Interface name            idx hdr_sz features server regions filename");
13919
13920   /* Get list of vhost-user interfaces */
13921   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13922   S (mp);
13923
13924   /* Use a control ping for synchronization */
13925   MPING (CONTROL_PING, mp_ping);
13926   S (mp_ping);
13927
13928   W (ret);
13929   return ret;
13930 }
13931
13932 static int
13933 api_show_version (vat_main_t * vam)
13934 {
13935   vl_api_show_version_t *mp;
13936   int ret;
13937
13938   M (SHOW_VERSION, mp);
13939
13940   S (mp);
13941   W (ret);
13942   return ret;
13943 }
13944
13945
13946 static int
13947 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13948 {
13949   unformat_input_t *line_input = vam->input;
13950   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13951   ip4_address_t local4, remote4;
13952   ip6_address_t local6, remote6;
13953   u8 is_add = 1;
13954   u8 ipv4_set = 0, ipv6_set = 0;
13955   u8 local_set = 0;
13956   u8 remote_set = 0;
13957   u8 grp_set = 0;
13958   u32 mcast_sw_if_index = ~0;
13959   u32 encap_vrf_id = 0;
13960   u32 decap_vrf_id = 0;
13961   u8 protocol = ~0;
13962   u32 vni;
13963   u8 vni_set = 0;
13964   int ret;
13965
13966   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13967   clib_memset (&local4, 0, sizeof local4);
13968   clib_memset (&remote4, 0, sizeof remote4);
13969   clib_memset (&local6, 0, sizeof local6);
13970   clib_memset (&remote6, 0, sizeof remote6);
13971
13972   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13973     {
13974       if (unformat (line_input, "del"))
13975         is_add = 0;
13976       else if (unformat (line_input, "local %U",
13977                          unformat_ip4_address, &local4))
13978         {
13979           local_set = 1;
13980           ipv4_set = 1;
13981         }
13982       else if (unformat (line_input, "remote %U",
13983                          unformat_ip4_address, &remote4))
13984         {
13985           remote_set = 1;
13986           ipv4_set = 1;
13987         }
13988       else if (unformat (line_input, "local %U",
13989                          unformat_ip6_address, &local6))
13990         {
13991           local_set = 1;
13992           ipv6_set = 1;
13993         }
13994       else if (unformat (line_input, "remote %U",
13995                          unformat_ip6_address, &remote6))
13996         {
13997           remote_set = 1;
13998           ipv6_set = 1;
13999         }
14000       else if (unformat (line_input, "group %U %U",
14001                          unformat_ip4_address, &remote4,
14002                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14003         {
14004           grp_set = remote_set = 1;
14005           ipv4_set = 1;
14006         }
14007       else if (unformat (line_input, "group %U",
14008                          unformat_ip4_address, &remote4))
14009         {
14010           grp_set = remote_set = 1;
14011           ipv4_set = 1;
14012         }
14013       else if (unformat (line_input, "group %U %U",
14014                          unformat_ip6_address, &remote6,
14015                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14016         {
14017           grp_set = remote_set = 1;
14018           ipv6_set = 1;
14019         }
14020       else if (unformat (line_input, "group %U",
14021                          unformat_ip6_address, &remote6))
14022         {
14023           grp_set = remote_set = 1;
14024           ipv6_set = 1;
14025         }
14026       else
14027         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14028         ;
14029       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14030         ;
14031       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14032         ;
14033       else if (unformat (line_input, "vni %d", &vni))
14034         vni_set = 1;
14035       else if (unformat (line_input, "next-ip4"))
14036         protocol = 1;
14037       else if (unformat (line_input, "next-ip6"))
14038         protocol = 2;
14039       else if (unformat (line_input, "next-ethernet"))
14040         protocol = 3;
14041       else if (unformat (line_input, "next-nsh"))
14042         protocol = 4;
14043       else
14044         {
14045           errmsg ("parse error '%U'", format_unformat_error, line_input);
14046           return -99;
14047         }
14048     }
14049
14050   if (local_set == 0)
14051     {
14052       errmsg ("tunnel local address not specified");
14053       return -99;
14054     }
14055   if (remote_set == 0)
14056     {
14057       errmsg ("tunnel remote address not specified");
14058       return -99;
14059     }
14060   if (grp_set && mcast_sw_if_index == ~0)
14061     {
14062       errmsg ("tunnel nonexistent multicast device");
14063       return -99;
14064     }
14065   if (ipv4_set && ipv6_set)
14066     {
14067       errmsg ("both IPv4 and IPv6 addresses specified");
14068       return -99;
14069     }
14070
14071   if (vni_set == 0)
14072     {
14073       errmsg ("vni not specified");
14074       return -99;
14075     }
14076
14077   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14078
14079
14080   if (ipv6_set)
14081     {
14082       clib_memcpy (&mp->local, &local6, sizeof (local6));
14083       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14084     }
14085   else
14086     {
14087       clib_memcpy (&mp->local, &local4, sizeof (local4));
14088       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14089     }
14090
14091   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14092   mp->encap_vrf_id = ntohl (encap_vrf_id);
14093   mp->decap_vrf_id = ntohl (decap_vrf_id);
14094   mp->protocol = protocol;
14095   mp->vni = ntohl (vni);
14096   mp->is_add = is_add;
14097   mp->is_ipv6 = ipv6_set;
14098
14099   S (mp);
14100   W (ret);
14101   return ret;
14102 }
14103
14104 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14105   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14106 {
14107   vat_main_t *vam = &vat_main;
14108   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14109   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14110
14111   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14112          ntohl (mp->sw_if_index),
14113          format_ip46_address, &local, IP46_TYPE_ANY,
14114          format_ip46_address, &remote, IP46_TYPE_ANY,
14115          ntohl (mp->vni), mp->protocol,
14116          ntohl (mp->mcast_sw_if_index),
14117          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14118 }
14119
14120
14121 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14122   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14123 {
14124   vat_main_t *vam = &vat_main;
14125   vat_json_node_t *node = NULL;
14126   struct in_addr ip4;
14127   struct in6_addr ip6;
14128
14129   if (VAT_JSON_ARRAY != vam->json_tree.type)
14130     {
14131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14132       vat_json_init_array (&vam->json_tree);
14133     }
14134   node = vat_json_array_add (&vam->json_tree);
14135
14136   vat_json_init_object (node);
14137   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14138   if (mp->is_ipv6)
14139     {
14140       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14141       vat_json_object_add_ip6 (node, "local", ip6);
14142       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14143       vat_json_object_add_ip6 (node, "remote", ip6);
14144     }
14145   else
14146     {
14147       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14148       vat_json_object_add_ip4 (node, "local", ip4);
14149       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14150       vat_json_object_add_ip4 (node, "remote", ip4);
14151     }
14152   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14153   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14154   vat_json_object_add_uint (node, "mcast_sw_if_index",
14155                             ntohl (mp->mcast_sw_if_index));
14156   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14157   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14158   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14159 }
14160
14161 static int
14162 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14163 {
14164   unformat_input_t *i = vam->input;
14165   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14166   vl_api_control_ping_t *mp_ping;
14167   u32 sw_if_index;
14168   u8 sw_if_index_set = 0;
14169   int ret;
14170
14171   /* Parse args required to build the message */
14172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14173     {
14174       if (unformat (i, "sw_if_index %d", &sw_if_index))
14175         sw_if_index_set = 1;
14176       else
14177         break;
14178     }
14179
14180   if (sw_if_index_set == 0)
14181     {
14182       sw_if_index = ~0;
14183     }
14184
14185   if (!vam->json_output)
14186     {
14187       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14188              "sw_if_index", "local", "remote", "vni",
14189              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14190     }
14191
14192   /* Get list of vxlan-tunnel interfaces */
14193   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14194
14195   mp->sw_if_index = htonl (sw_if_index);
14196
14197   S (mp);
14198
14199   /* Use a control ping for synchronization */
14200   MPING (CONTROL_PING, mp_ping);
14201   S (mp_ping);
14202
14203   W (ret);
14204   return ret;
14205 }
14206
14207 static void vl_api_l2_fib_table_details_t_handler
14208   (vl_api_l2_fib_table_details_t * mp)
14209 {
14210   vat_main_t *vam = &vat_main;
14211
14212   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14213          "       %d       %d     %d",
14214          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14215          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14216          mp->bvi_mac);
14217 }
14218
14219 static void vl_api_l2_fib_table_details_t_handler_json
14220   (vl_api_l2_fib_table_details_t * mp)
14221 {
14222   vat_main_t *vam = &vat_main;
14223   vat_json_node_t *node = NULL;
14224
14225   if (VAT_JSON_ARRAY != vam->json_tree.type)
14226     {
14227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14228       vat_json_init_array (&vam->json_tree);
14229     }
14230   node = vat_json_array_add (&vam->json_tree);
14231
14232   vat_json_init_object (node);
14233   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14234   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14235   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14236   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14237   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14238   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14239 }
14240
14241 static int
14242 api_l2_fib_table_dump (vat_main_t * vam)
14243 {
14244   unformat_input_t *i = vam->input;
14245   vl_api_l2_fib_table_dump_t *mp;
14246   vl_api_control_ping_t *mp_ping;
14247   u32 bd_id;
14248   u8 bd_id_set = 0;
14249   int ret;
14250
14251   /* Parse args required to build the message */
14252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14253     {
14254       if (unformat (i, "bd_id %d", &bd_id))
14255         bd_id_set = 1;
14256       else
14257         break;
14258     }
14259
14260   if (bd_id_set == 0)
14261     {
14262       errmsg ("missing bridge domain");
14263       return -99;
14264     }
14265
14266   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14267
14268   /* Get list of l2 fib entries */
14269   M (L2_FIB_TABLE_DUMP, mp);
14270
14271   mp->bd_id = ntohl (bd_id);
14272   S (mp);
14273
14274   /* Use a control ping for synchronization */
14275   MPING (CONTROL_PING, mp_ping);
14276   S (mp_ping);
14277
14278   W (ret);
14279   return ret;
14280 }
14281
14282
14283 static int
14284 api_interface_name_renumber (vat_main_t * vam)
14285 {
14286   unformat_input_t *line_input = vam->input;
14287   vl_api_interface_name_renumber_t *mp;
14288   u32 sw_if_index = ~0;
14289   u32 new_show_dev_instance = ~0;
14290   int ret;
14291
14292   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14293     {
14294       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14295                     &sw_if_index))
14296         ;
14297       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14298         ;
14299       else if (unformat (line_input, "new_show_dev_instance %d",
14300                          &new_show_dev_instance))
14301         ;
14302       else
14303         break;
14304     }
14305
14306   if (sw_if_index == ~0)
14307     {
14308       errmsg ("missing interface name or sw_if_index");
14309       return -99;
14310     }
14311
14312   if (new_show_dev_instance == ~0)
14313     {
14314       errmsg ("missing new_show_dev_instance");
14315       return -99;
14316     }
14317
14318   M (INTERFACE_NAME_RENUMBER, mp);
14319
14320   mp->sw_if_index = ntohl (sw_if_index);
14321   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14322
14323   S (mp);
14324   W (ret);
14325   return ret;
14326 }
14327
14328 static int
14329 api_ip_probe_neighbor (vat_main_t * vam)
14330 {
14331   unformat_input_t *i = vam->input;
14332   vl_api_ip_probe_neighbor_t *mp;
14333   u8 int_set = 0;
14334   u8 adr_set = 0;
14335   u8 is_ipv6 = 0;
14336   u8 dst_adr[16];
14337   u32 sw_if_index;
14338   int ret;
14339
14340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14341     {
14342       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14343         int_set = 1;
14344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14345         int_set = 1;
14346       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14347         adr_set = 1;
14348       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14349         {
14350           adr_set = 1;
14351           is_ipv6 = 1;
14352         }
14353       else
14354         break;
14355     }
14356
14357   if (int_set == 0)
14358     {
14359       errmsg ("missing interface");
14360       return -99;
14361     }
14362
14363   if (adr_set == 0)
14364     {
14365       errmsg ("missing addresses");
14366       return -99;
14367     }
14368
14369   M (IP_PROBE_NEIGHBOR, mp);
14370
14371   mp->sw_if_index = ntohl (sw_if_index);
14372   mp->is_ipv6 = is_ipv6;
14373   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14374
14375   S (mp);
14376   W (ret);
14377   return ret;
14378 }
14379
14380 static int
14381 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14382 {
14383   unformat_input_t *i = vam->input;
14384   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14385   u8 mode = IP_SCAN_V46_NEIGHBORS;
14386   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14387   int ret;
14388
14389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14390     {
14391       if (unformat (i, "ip4"))
14392         mode = IP_SCAN_V4_NEIGHBORS;
14393       else if (unformat (i, "ip6"))
14394         mode = IP_SCAN_V6_NEIGHBORS;
14395       if (unformat (i, "both"))
14396         mode = IP_SCAN_V46_NEIGHBORS;
14397       else if (unformat (i, "disable"))
14398         mode = IP_SCAN_DISABLED;
14399       else if (unformat (i, "interval %d", &interval))
14400         ;
14401       else if (unformat (i, "max-time %d", &time))
14402         ;
14403       else if (unformat (i, "max-update %d", &update))
14404         ;
14405       else if (unformat (i, "delay %d", &delay))
14406         ;
14407       else if (unformat (i, "stale %d", &stale))
14408         ;
14409       else
14410         break;
14411     }
14412
14413   if (interval > 255)
14414     {
14415       errmsg ("interval cannot exceed 255 minutes.");
14416       return -99;
14417     }
14418   if (time > 255)
14419     {
14420       errmsg ("max-time cannot exceed 255 usec.");
14421       return -99;
14422     }
14423   if (update > 255)
14424     {
14425       errmsg ("max-update cannot exceed 255.");
14426       return -99;
14427     }
14428   if (delay > 255)
14429     {
14430       errmsg ("delay cannot exceed 255 msec.");
14431       return -99;
14432     }
14433   if (stale > 255)
14434     {
14435       errmsg ("stale cannot exceed 255 minutes.");
14436       return -99;
14437     }
14438
14439   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14440   mp->mode = mode;
14441   mp->scan_interval = interval;
14442   mp->max_proc_time = time;
14443   mp->max_update = update;
14444   mp->scan_int_delay = delay;
14445   mp->stale_threshold = stale;
14446
14447   S (mp);
14448   W (ret);
14449   return ret;
14450 }
14451
14452 static int
14453 api_want_ip4_arp_events (vat_main_t * vam)
14454 {
14455   unformat_input_t *line_input = vam->input;
14456   vl_api_want_ip4_arp_events_t *mp;
14457   ip4_address_t address;
14458   int address_set = 0;
14459   u32 enable_disable = 1;
14460   int ret;
14461
14462   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14463     {
14464       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14465         address_set = 1;
14466       else if (unformat (line_input, "del"))
14467         enable_disable = 0;
14468       else
14469         break;
14470     }
14471
14472   if (address_set == 0)
14473     {
14474       errmsg ("missing addresses");
14475       return -99;
14476     }
14477
14478   M (WANT_IP4_ARP_EVENTS, mp);
14479   mp->enable_disable = enable_disable;
14480   mp->pid = htonl (getpid ());
14481   mp->address = address.as_u32;
14482
14483   S (mp);
14484   W (ret);
14485   return ret;
14486 }
14487
14488 static int
14489 api_want_ip6_nd_events (vat_main_t * vam)
14490 {
14491   unformat_input_t *line_input = vam->input;
14492   vl_api_want_ip6_nd_events_t *mp;
14493   ip6_address_t address;
14494   int address_set = 0;
14495   u32 enable_disable = 1;
14496   int ret;
14497
14498   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14499     {
14500       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14501         address_set = 1;
14502       else if (unformat (line_input, "del"))
14503         enable_disable = 0;
14504       else
14505         break;
14506     }
14507
14508   if (address_set == 0)
14509     {
14510       errmsg ("missing addresses");
14511       return -99;
14512     }
14513
14514   M (WANT_IP6_ND_EVENTS, mp);
14515   mp->enable_disable = enable_disable;
14516   mp->pid = htonl (getpid ());
14517   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14518
14519   S (mp);
14520   W (ret);
14521   return ret;
14522 }
14523
14524 static int
14525 api_want_l2_macs_events (vat_main_t * vam)
14526 {
14527   unformat_input_t *line_input = vam->input;
14528   vl_api_want_l2_macs_events_t *mp;
14529   u8 enable_disable = 1;
14530   u32 scan_delay = 0;
14531   u32 max_macs_in_event = 0;
14532   u32 learn_limit = 0;
14533   int ret;
14534
14535   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14536     {
14537       if (unformat (line_input, "learn-limit %d", &learn_limit))
14538         ;
14539       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14540         ;
14541       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14542         ;
14543       else if (unformat (line_input, "disable"))
14544         enable_disable = 0;
14545       else
14546         break;
14547     }
14548
14549   M (WANT_L2_MACS_EVENTS, mp);
14550   mp->enable_disable = enable_disable;
14551   mp->pid = htonl (getpid ());
14552   mp->learn_limit = htonl (learn_limit);
14553   mp->scan_delay = (u8) scan_delay;
14554   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14555   S (mp);
14556   W (ret);
14557   return ret;
14558 }
14559
14560 static int
14561 api_input_acl_set_interface (vat_main_t * vam)
14562 {
14563   unformat_input_t *i = vam->input;
14564   vl_api_input_acl_set_interface_t *mp;
14565   u32 sw_if_index;
14566   int sw_if_index_set;
14567   u32 ip4_table_index = ~0;
14568   u32 ip6_table_index = ~0;
14569   u32 l2_table_index = ~0;
14570   u8 is_add = 1;
14571   int ret;
14572
14573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14574     {
14575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14576         sw_if_index_set = 1;
14577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14578         sw_if_index_set = 1;
14579       else if (unformat (i, "del"))
14580         is_add = 0;
14581       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14582         ;
14583       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14584         ;
14585       else if (unformat (i, "l2-table %d", &l2_table_index))
14586         ;
14587       else
14588         {
14589           clib_warning ("parse error '%U'", format_unformat_error, i);
14590           return -99;
14591         }
14592     }
14593
14594   if (sw_if_index_set == 0)
14595     {
14596       errmsg ("missing interface name or sw_if_index");
14597       return -99;
14598     }
14599
14600   M (INPUT_ACL_SET_INTERFACE, mp);
14601
14602   mp->sw_if_index = ntohl (sw_if_index);
14603   mp->ip4_table_index = ntohl (ip4_table_index);
14604   mp->ip6_table_index = ntohl (ip6_table_index);
14605   mp->l2_table_index = ntohl (l2_table_index);
14606   mp->is_add = is_add;
14607
14608   S (mp);
14609   W (ret);
14610   return ret;
14611 }
14612
14613 static int
14614 api_output_acl_set_interface (vat_main_t * vam)
14615 {
14616   unformat_input_t *i = vam->input;
14617   vl_api_output_acl_set_interface_t *mp;
14618   u32 sw_if_index;
14619   int sw_if_index_set;
14620   u32 ip4_table_index = ~0;
14621   u32 ip6_table_index = ~0;
14622   u32 l2_table_index = ~0;
14623   u8 is_add = 1;
14624   int ret;
14625
14626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14627     {
14628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14629         sw_if_index_set = 1;
14630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14631         sw_if_index_set = 1;
14632       else if (unformat (i, "del"))
14633         is_add = 0;
14634       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14635         ;
14636       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14637         ;
14638       else if (unformat (i, "l2-table %d", &l2_table_index))
14639         ;
14640       else
14641         {
14642           clib_warning ("parse error '%U'", format_unformat_error, i);
14643           return -99;
14644         }
14645     }
14646
14647   if (sw_if_index_set == 0)
14648     {
14649       errmsg ("missing interface name or sw_if_index");
14650       return -99;
14651     }
14652
14653   M (OUTPUT_ACL_SET_INTERFACE, mp);
14654
14655   mp->sw_if_index = ntohl (sw_if_index);
14656   mp->ip4_table_index = ntohl (ip4_table_index);
14657   mp->ip6_table_index = ntohl (ip6_table_index);
14658   mp->l2_table_index = ntohl (l2_table_index);
14659   mp->is_add = is_add;
14660
14661   S (mp);
14662   W (ret);
14663   return ret;
14664 }
14665
14666 static int
14667 api_ip_address_dump (vat_main_t * vam)
14668 {
14669   unformat_input_t *i = vam->input;
14670   vl_api_ip_address_dump_t *mp;
14671   vl_api_control_ping_t *mp_ping;
14672   u32 sw_if_index = ~0;
14673   u8 sw_if_index_set = 0;
14674   u8 ipv4_set = 0;
14675   u8 ipv6_set = 0;
14676   int ret;
14677
14678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (i, "sw_if_index %d", &sw_if_index))
14681         sw_if_index_set = 1;
14682       else
14683         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14684         sw_if_index_set = 1;
14685       else if (unformat (i, "ipv4"))
14686         ipv4_set = 1;
14687       else if (unformat (i, "ipv6"))
14688         ipv6_set = 1;
14689       else
14690         break;
14691     }
14692
14693   if (ipv4_set && ipv6_set)
14694     {
14695       errmsg ("ipv4 and ipv6 flags cannot be both set");
14696       return -99;
14697     }
14698
14699   if ((!ipv4_set) && (!ipv6_set))
14700     {
14701       errmsg ("no ipv4 nor ipv6 flag set");
14702       return -99;
14703     }
14704
14705   if (sw_if_index_set == 0)
14706     {
14707       errmsg ("missing interface name or sw_if_index");
14708       return -99;
14709     }
14710
14711   vam->current_sw_if_index = sw_if_index;
14712   vam->is_ipv6 = ipv6_set;
14713
14714   M (IP_ADDRESS_DUMP, mp);
14715   mp->sw_if_index = ntohl (sw_if_index);
14716   mp->is_ipv6 = ipv6_set;
14717   S (mp);
14718
14719   /* Use a control ping for synchronization */
14720   MPING (CONTROL_PING, mp_ping);
14721   S (mp_ping);
14722
14723   W (ret);
14724   return ret;
14725 }
14726
14727 static int
14728 api_ip_dump (vat_main_t * vam)
14729 {
14730   vl_api_ip_dump_t *mp;
14731   vl_api_control_ping_t *mp_ping;
14732   unformat_input_t *in = vam->input;
14733   int ipv4_set = 0;
14734   int ipv6_set = 0;
14735   int is_ipv6;
14736   int i;
14737   int ret;
14738
14739   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14740     {
14741       if (unformat (in, "ipv4"))
14742         ipv4_set = 1;
14743       else if (unformat (in, "ipv6"))
14744         ipv6_set = 1;
14745       else
14746         break;
14747     }
14748
14749   if (ipv4_set && ipv6_set)
14750     {
14751       errmsg ("ipv4 and ipv6 flags cannot be both set");
14752       return -99;
14753     }
14754
14755   if ((!ipv4_set) && (!ipv6_set))
14756     {
14757       errmsg ("no ipv4 nor ipv6 flag set");
14758       return -99;
14759     }
14760
14761   is_ipv6 = ipv6_set;
14762   vam->is_ipv6 = is_ipv6;
14763
14764   /* free old data */
14765   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14766     {
14767       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14768     }
14769   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14770
14771   M (IP_DUMP, mp);
14772   mp->is_ipv6 = ipv6_set;
14773   S (mp);
14774
14775   /* Use a control ping for synchronization */
14776   MPING (CONTROL_PING, mp_ping);
14777   S (mp_ping);
14778
14779   W (ret);
14780   return ret;
14781 }
14782
14783 static int
14784 api_ipsec_spd_add_del (vat_main_t * vam)
14785 {
14786   unformat_input_t *i = vam->input;
14787   vl_api_ipsec_spd_add_del_t *mp;
14788   u32 spd_id = ~0;
14789   u8 is_add = 1;
14790   int ret;
14791
14792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14793     {
14794       if (unformat (i, "spd_id %d", &spd_id))
14795         ;
14796       else if (unformat (i, "del"))
14797         is_add = 0;
14798       else
14799         {
14800           clib_warning ("parse error '%U'", format_unformat_error, i);
14801           return -99;
14802         }
14803     }
14804   if (spd_id == ~0)
14805     {
14806       errmsg ("spd_id must be set");
14807       return -99;
14808     }
14809
14810   M (IPSEC_SPD_ADD_DEL, mp);
14811
14812   mp->spd_id = ntohl (spd_id);
14813   mp->is_add = is_add;
14814
14815   S (mp);
14816   W (ret);
14817   return ret;
14818 }
14819
14820 static int
14821 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14822 {
14823   unformat_input_t *i = vam->input;
14824   vl_api_ipsec_interface_add_del_spd_t *mp;
14825   u32 sw_if_index;
14826   u8 sw_if_index_set = 0;
14827   u32 spd_id = (u32) ~ 0;
14828   u8 is_add = 1;
14829   int ret;
14830
14831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14832     {
14833       if (unformat (i, "del"))
14834         is_add = 0;
14835       else if (unformat (i, "spd_id %d", &spd_id))
14836         ;
14837       else
14838         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14839         sw_if_index_set = 1;
14840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14841         sw_if_index_set = 1;
14842       else
14843         {
14844           clib_warning ("parse error '%U'", format_unformat_error, i);
14845           return -99;
14846         }
14847
14848     }
14849
14850   if (spd_id == (u32) ~ 0)
14851     {
14852       errmsg ("spd_id must be set");
14853       return -99;
14854     }
14855
14856   if (sw_if_index_set == 0)
14857     {
14858       errmsg ("missing interface name or sw_if_index");
14859       return -99;
14860     }
14861
14862   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14863
14864   mp->spd_id = ntohl (spd_id);
14865   mp->sw_if_index = ntohl (sw_if_index);
14866   mp->is_add = is_add;
14867
14868   S (mp);
14869   W (ret);
14870   return ret;
14871 }
14872
14873 static int
14874 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14875 {
14876   unformat_input_t *i = vam->input;
14877   vl_api_ipsec_spd_add_del_entry_t *mp;
14878   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14879   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14880   i32 priority = 0;
14881   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14882   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14883   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14884   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14885   int ret;
14886
14887   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14888   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14889   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14890   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14891   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14892   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14893
14894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14895     {
14896       if (unformat (i, "del"))
14897         is_add = 0;
14898       if (unformat (i, "outbound"))
14899         is_outbound = 1;
14900       if (unformat (i, "inbound"))
14901         is_outbound = 0;
14902       else if (unformat (i, "spd_id %d", &spd_id))
14903         ;
14904       else if (unformat (i, "sa_id %d", &sa_id))
14905         ;
14906       else if (unformat (i, "priority %d", &priority))
14907         ;
14908       else if (unformat (i, "protocol %d", &protocol))
14909         ;
14910       else if (unformat (i, "lport_start %d", &lport_start))
14911         ;
14912       else if (unformat (i, "lport_stop %d", &lport_stop))
14913         ;
14914       else if (unformat (i, "rport_start %d", &rport_start))
14915         ;
14916       else if (unformat (i, "rport_stop %d", &rport_stop))
14917         ;
14918       else
14919         if (unformat
14920             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14921         {
14922           is_ipv6 = 0;
14923           is_ip_any = 0;
14924         }
14925       else
14926         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14927         {
14928           is_ipv6 = 0;
14929           is_ip_any = 0;
14930         }
14931       else
14932         if (unformat
14933             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14934         {
14935           is_ipv6 = 0;
14936           is_ip_any = 0;
14937         }
14938       else
14939         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14940         {
14941           is_ipv6 = 0;
14942           is_ip_any = 0;
14943         }
14944       else
14945         if (unformat
14946             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14947         {
14948           is_ipv6 = 1;
14949           is_ip_any = 0;
14950         }
14951       else
14952         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14953         {
14954           is_ipv6 = 1;
14955           is_ip_any = 0;
14956         }
14957       else
14958         if (unformat
14959             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14960         {
14961           is_ipv6 = 1;
14962           is_ip_any = 0;
14963         }
14964       else
14965         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14966         {
14967           is_ipv6 = 1;
14968           is_ip_any = 0;
14969         }
14970       else
14971         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14972         {
14973           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14974             {
14975               clib_warning ("unsupported action: 'resolve'");
14976               return -99;
14977             }
14978         }
14979       else
14980         {
14981           clib_warning ("parse error '%U'", format_unformat_error, i);
14982           return -99;
14983         }
14984
14985     }
14986
14987   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14988
14989   mp->spd_id = ntohl (spd_id);
14990   mp->priority = ntohl (priority);
14991   mp->is_outbound = is_outbound;
14992
14993   mp->is_ipv6 = is_ipv6;
14994   if (is_ipv6 || is_ip_any)
14995     {
14996       clib_memcpy (mp->remote_address_start, &raddr6_start,
14997                    sizeof (ip6_address_t));
14998       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14999                    sizeof (ip6_address_t));
15000       clib_memcpy (mp->local_address_start, &laddr6_start,
15001                    sizeof (ip6_address_t));
15002       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15003                    sizeof (ip6_address_t));
15004     }
15005   else
15006     {
15007       clib_memcpy (mp->remote_address_start, &raddr4_start,
15008                    sizeof (ip4_address_t));
15009       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15010                    sizeof (ip4_address_t));
15011       clib_memcpy (mp->local_address_start, &laddr4_start,
15012                    sizeof (ip4_address_t));
15013       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15014                    sizeof (ip4_address_t));
15015     }
15016   mp->protocol = (u8) protocol;
15017   mp->local_port_start = ntohs ((u16) lport_start);
15018   mp->local_port_stop = ntohs ((u16) lport_stop);
15019   mp->remote_port_start = ntohs ((u16) rport_start);
15020   mp->remote_port_stop = ntohs ((u16) rport_stop);
15021   mp->policy = (u8) policy;
15022   mp->sa_id = ntohl (sa_id);
15023   mp->is_add = is_add;
15024   mp->is_ip_any = is_ip_any;
15025   S (mp);
15026   W (ret);
15027   return ret;
15028 }
15029
15030 static int
15031 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15032 {
15033   unformat_input_t *i = vam->input;
15034   vl_api_ipsec_sad_add_del_entry_t *mp;
15035   u32 sad_id = 0, spi = 0;
15036   u8 *ck = 0, *ik = 0;
15037   u8 is_add = 1;
15038
15039   u8 protocol = IPSEC_PROTOCOL_AH;
15040   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15041   u32 crypto_alg = 0, integ_alg = 0;
15042   ip4_address_t tun_src4;
15043   ip4_address_t tun_dst4;
15044   ip6_address_t tun_src6;
15045   ip6_address_t tun_dst6;
15046   int ret;
15047
15048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15049     {
15050       if (unformat (i, "del"))
15051         is_add = 0;
15052       else if (unformat (i, "sad_id %d", &sad_id))
15053         ;
15054       else if (unformat (i, "spi %d", &spi))
15055         ;
15056       else if (unformat (i, "esp"))
15057         protocol = IPSEC_PROTOCOL_ESP;
15058       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15059         {
15060           is_tunnel = 1;
15061           is_tunnel_ipv6 = 0;
15062         }
15063       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15064         {
15065           is_tunnel = 1;
15066           is_tunnel_ipv6 = 0;
15067         }
15068       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15069         {
15070           is_tunnel = 1;
15071           is_tunnel_ipv6 = 1;
15072         }
15073       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15074         {
15075           is_tunnel = 1;
15076           is_tunnel_ipv6 = 1;
15077         }
15078       else
15079         if (unformat
15080             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15081         {
15082           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15083             {
15084               clib_warning ("unsupported crypto-alg: '%U'",
15085                             format_ipsec_crypto_alg, crypto_alg);
15086               return -99;
15087             }
15088         }
15089       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15090         ;
15091       else
15092         if (unformat
15093             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15094         {
15095           if (integ_alg >= IPSEC_INTEG_N_ALG)
15096             {
15097               clib_warning ("unsupported integ-alg: '%U'",
15098                             format_ipsec_integ_alg, integ_alg);
15099               return -99;
15100             }
15101         }
15102       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15103         ;
15104       else
15105         {
15106           clib_warning ("parse error '%U'", format_unformat_error, i);
15107           return -99;
15108         }
15109
15110     }
15111
15112   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15113
15114   mp->sad_id = ntohl (sad_id);
15115   mp->is_add = is_add;
15116   mp->protocol = protocol;
15117   mp->spi = ntohl (spi);
15118   mp->is_tunnel = is_tunnel;
15119   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15120   mp->crypto_algorithm = crypto_alg;
15121   mp->integrity_algorithm = integ_alg;
15122   mp->crypto_key_length = vec_len (ck);
15123   mp->integrity_key_length = vec_len (ik);
15124
15125   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15126     mp->crypto_key_length = sizeof (mp->crypto_key);
15127
15128   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15129     mp->integrity_key_length = sizeof (mp->integrity_key);
15130
15131   if (ck)
15132     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15133   if (ik)
15134     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15135
15136   if (is_tunnel)
15137     {
15138       if (is_tunnel_ipv6)
15139         {
15140           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15141                        sizeof (ip6_address_t));
15142           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15143                        sizeof (ip6_address_t));
15144         }
15145       else
15146         {
15147           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15148                        sizeof (ip4_address_t));
15149           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15150                        sizeof (ip4_address_t));
15151         }
15152     }
15153
15154   S (mp);
15155   W (ret);
15156   return ret;
15157 }
15158
15159 static int
15160 api_ipsec_sa_set_key (vat_main_t * vam)
15161 {
15162   unformat_input_t *i = vam->input;
15163   vl_api_ipsec_sa_set_key_t *mp;
15164   u32 sa_id;
15165   u8 *ck = 0, *ik = 0;
15166   int ret;
15167
15168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15169     {
15170       if (unformat (i, "sa_id %d", &sa_id))
15171         ;
15172       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15173         ;
15174       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15175         ;
15176       else
15177         {
15178           clib_warning ("parse error '%U'", format_unformat_error, i);
15179           return -99;
15180         }
15181     }
15182
15183   M (IPSEC_SA_SET_KEY, mp);
15184
15185   mp->sa_id = ntohl (sa_id);
15186   mp->crypto_key_length = vec_len (ck);
15187   mp->integrity_key_length = vec_len (ik);
15188
15189   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15190     mp->crypto_key_length = sizeof (mp->crypto_key);
15191
15192   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15193     mp->integrity_key_length = sizeof (mp->integrity_key);
15194
15195   if (ck)
15196     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15197   if (ik)
15198     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15199
15200   S (mp);
15201   W (ret);
15202   return ret;
15203 }
15204
15205 static int
15206 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15207 {
15208   unformat_input_t *i = vam->input;
15209   vl_api_ipsec_tunnel_if_add_del_t *mp;
15210   u32 local_spi = 0, remote_spi = 0;
15211   u32 crypto_alg = 0, integ_alg = 0;
15212   u8 *lck = NULL, *rck = NULL;
15213   u8 *lik = NULL, *rik = NULL;
15214   ip4_address_t local_ip = { {0} };
15215   ip4_address_t remote_ip = { {0} };
15216   u8 is_add = 1;
15217   u8 esn = 0;
15218   u8 anti_replay = 0;
15219   u8 renumber = 0;
15220   u32 instance = ~0;
15221   int ret;
15222
15223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15224     {
15225       if (unformat (i, "del"))
15226         is_add = 0;
15227       else if (unformat (i, "esn"))
15228         esn = 1;
15229       else if (unformat (i, "anti_replay"))
15230         anti_replay = 1;
15231       else if (unformat (i, "local_spi %d", &local_spi))
15232         ;
15233       else if (unformat (i, "remote_spi %d", &remote_spi))
15234         ;
15235       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15236         ;
15237       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15238         ;
15239       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15240         ;
15241       else
15242         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15243         ;
15244       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15245         ;
15246       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15247         ;
15248       else
15249         if (unformat
15250             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15251         {
15252           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15253             {
15254               errmsg ("unsupported crypto-alg: '%U'\n",
15255                       format_ipsec_crypto_alg, crypto_alg);
15256               return -99;
15257             }
15258         }
15259       else
15260         if (unformat
15261             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15262         {
15263           if (integ_alg >= IPSEC_INTEG_N_ALG)
15264             {
15265               errmsg ("unsupported integ-alg: '%U'\n",
15266                       format_ipsec_integ_alg, integ_alg);
15267               return -99;
15268             }
15269         }
15270       else if (unformat (i, "instance %u", &instance))
15271         renumber = 1;
15272       else
15273         {
15274           errmsg ("parse error '%U'\n", format_unformat_error, i);
15275           return -99;
15276         }
15277     }
15278
15279   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15280
15281   mp->is_add = is_add;
15282   mp->esn = esn;
15283   mp->anti_replay = anti_replay;
15284
15285   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15286   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15287
15288   mp->local_spi = htonl (local_spi);
15289   mp->remote_spi = htonl (remote_spi);
15290   mp->crypto_alg = (u8) crypto_alg;
15291
15292   mp->local_crypto_key_len = 0;
15293   if (lck)
15294     {
15295       mp->local_crypto_key_len = vec_len (lck);
15296       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15297         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15298       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15299     }
15300
15301   mp->remote_crypto_key_len = 0;
15302   if (rck)
15303     {
15304       mp->remote_crypto_key_len = vec_len (rck);
15305       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15306         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15307       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15308     }
15309
15310   mp->integ_alg = (u8) integ_alg;
15311
15312   mp->local_integ_key_len = 0;
15313   if (lik)
15314     {
15315       mp->local_integ_key_len = vec_len (lik);
15316       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15317         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15318       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15319     }
15320
15321   mp->remote_integ_key_len = 0;
15322   if (rik)
15323     {
15324       mp->remote_integ_key_len = vec_len (rik);
15325       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15326         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15327       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15328     }
15329
15330   if (renumber)
15331     {
15332       mp->renumber = renumber;
15333       mp->show_instance = ntohl (instance);
15334     }
15335
15336   S (mp);
15337   W (ret);
15338   return ret;
15339 }
15340
15341 static void
15342 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15343 {
15344   vat_main_t *vam = &vat_main;
15345
15346   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15347          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15348          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15349          "tunnel_src_addr %U tunnel_dst_addr %U "
15350          "salt %u seq_outbound %lu last_seq_inbound %lu "
15351          "replay_window %lu total_data_size %lu\n",
15352          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15353          mp->protocol,
15354          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15355          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15356          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15357          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15358          mp->tunnel_src_addr,
15359          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15360          mp->tunnel_dst_addr,
15361          ntohl (mp->salt),
15362          clib_net_to_host_u64 (mp->seq_outbound),
15363          clib_net_to_host_u64 (mp->last_seq_inbound),
15364          clib_net_to_host_u64 (mp->replay_window),
15365          clib_net_to_host_u64 (mp->total_data_size));
15366 }
15367
15368 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15369 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15370
15371 static void vl_api_ipsec_sa_details_t_handler_json
15372   (vl_api_ipsec_sa_details_t * mp)
15373 {
15374   vat_main_t *vam = &vat_main;
15375   vat_json_node_t *node = NULL;
15376   struct in_addr src_ip4, dst_ip4;
15377   struct in6_addr src_ip6, dst_ip6;
15378
15379   if (VAT_JSON_ARRAY != vam->json_tree.type)
15380     {
15381       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15382       vat_json_init_array (&vam->json_tree);
15383     }
15384   node = vat_json_array_add (&vam->json_tree);
15385
15386   vat_json_init_object (node);
15387   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15388   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15389   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15390   vat_json_object_add_uint (node, "proto", mp->protocol);
15391   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15392   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15393   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15394   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15395   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15396   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15397   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15398                              mp->crypto_key_len);
15399   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15400                              mp->integ_key_len);
15401   if (mp->is_tunnel_ip6)
15402     {
15403       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15404       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15405       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15406       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15407     }
15408   else
15409     {
15410       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15411       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15412       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15413       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15414     }
15415   vat_json_object_add_uint (node, "replay_window",
15416                             clib_net_to_host_u64 (mp->replay_window));
15417   vat_json_object_add_uint (node, "total_data_size",
15418                             clib_net_to_host_u64 (mp->total_data_size));
15419
15420 }
15421
15422 static int
15423 api_ipsec_sa_dump (vat_main_t * vam)
15424 {
15425   unformat_input_t *i = vam->input;
15426   vl_api_ipsec_sa_dump_t *mp;
15427   vl_api_control_ping_t *mp_ping;
15428   u32 sa_id = ~0;
15429   int ret;
15430
15431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15432     {
15433       if (unformat (i, "sa_id %d", &sa_id))
15434         ;
15435       else
15436         {
15437           clib_warning ("parse error '%U'", format_unformat_error, i);
15438           return -99;
15439         }
15440     }
15441
15442   M (IPSEC_SA_DUMP, mp);
15443
15444   mp->sa_id = ntohl (sa_id);
15445
15446   S (mp);
15447
15448   /* Use a control ping for synchronization */
15449   M (CONTROL_PING, mp_ping);
15450   S (mp_ping);
15451
15452   W (ret);
15453   return ret;
15454 }
15455
15456 static int
15457 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15458 {
15459   unformat_input_t *i = vam->input;
15460   vl_api_ipsec_tunnel_if_set_key_t *mp;
15461   u32 sw_if_index = ~0;
15462   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15463   u8 *key = 0;
15464   u32 alg = ~0;
15465   int ret;
15466
15467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15468     {
15469       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15470         ;
15471       else
15472         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15473         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15474       else
15475         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15476         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15477       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15478         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15479       else
15480         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15481         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15482       else if (unformat (i, "%U", unformat_hex_string, &key))
15483         ;
15484       else
15485         {
15486           clib_warning ("parse error '%U'", format_unformat_error, i);
15487           return -99;
15488         }
15489     }
15490
15491   if (sw_if_index == ~0)
15492     {
15493       errmsg ("interface must be specified");
15494       return -99;
15495     }
15496
15497   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15498     {
15499       errmsg ("key type must be specified");
15500       return -99;
15501     }
15502
15503   if (alg == ~0)
15504     {
15505       errmsg ("algorithm must be specified");
15506       return -99;
15507     }
15508
15509   if (vec_len (key) == 0)
15510     {
15511       errmsg ("key must be specified");
15512       return -99;
15513     }
15514
15515   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15516
15517   mp->sw_if_index = htonl (sw_if_index);
15518   mp->alg = alg;
15519   mp->key_type = key_type;
15520   mp->key_len = vec_len (key);
15521   clib_memcpy (mp->key, key, vec_len (key));
15522
15523   S (mp);
15524   W (ret);
15525
15526   return ret;
15527 }
15528
15529 static int
15530 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15531 {
15532   unformat_input_t *i = vam->input;
15533   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15534   u32 sw_if_index = ~0;
15535   u32 sa_id = ~0;
15536   u8 is_outbound = (u8) ~ 0;
15537   int ret;
15538
15539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15540     {
15541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15542         ;
15543       else if (unformat (i, "sa_id %d", &sa_id))
15544         ;
15545       else if (unformat (i, "outbound"))
15546         is_outbound = 1;
15547       else if (unformat (i, "inbound"))
15548         is_outbound = 0;
15549       else
15550         {
15551           clib_warning ("parse error '%U'", format_unformat_error, i);
15552           return -99;
15553         }
15554     }
15555
15556   if (sw_if_index == ~0)
15557     {
15558       errmsg ("interface must be specified");
15559       return -99;
15560     }
15561
15562   if (sa_id == ~0)
15563     {
15564       errmsg ("SA ID must be specified");
15565       return -99;
15566     }
15567
15568   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15569
15570   mp->sw_if_index = htonl (sw_if_index);
15571   mp->sa_id = htonl (sa_id);
15572   mp->is_outbound = is_outbound;
15573
15574   S (mp);
15575   W (ret);
15576
15577   return ret;
15578 }
15579
15580 static int
15581 api_ikev2_profile_add_del (vat_main_t * vam)
15582 {
15583   unformat_input_t *i = vam->input;
15584   vl_api_ikev2_profile_add_del_t *mp;
15585   u8 is_add = 1;
15586   u8 *name = 0;
15587   int ret;
15588
15589   const char *valid_chars = "a-zA-Z0-9_";
15590
15591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15592     {
15593       if (unformat (i, "del"))
15594         is_add = 0;
15595       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15596         vec_add1 (name, 0);
15597       else
15598         {
15599           errmsg ("parse error '%U'", format_unformat_error, i);
15600           return -99;
15601         }
15602     }
15603
15604   if (!vec_len (name))
15605     {
15606       errmsg ("profile name must be specified");
15607       return -99;
15608     }
15609
15610   if (vec_len (name) > 64)
15611     {
15612       errmsg ("profile name too long");
15613       return -99;
15614     }
15615
15616   M (IKEV2_PROFILE_ADD_DEL, mp);
15617
15618   clib_memcpy (mp->name, name, vec_len (name));
15619   mp->is_add = is_add;
15620   vec_free (name);
15621
15622   S (mp);
15623   W (ret);
15624   return ret;
15625 }
15626
15627 static int
15628 api_ikev2_profile_set_auth (vat_main_t * vam)
15629 {
15630   unformat_input_t *i = vam->input;
15631   vl_api_ikev2_profile_set_auth_t *mp;
15632   u8 *name = 0;
15633   u8 *data = 0;
15634   u32 auth_method = 0;
15635   u8 is_hex = 0;
15636   int ret;
15637
15638   const char *valid_chars = "a-zA-Z0-9_";
15639
15640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15641     {
15642       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15643         vec_add1 (name, 0);
15644       else if (unformat (i, "auth_method %U",
15645                          unformat_ikev2_auth_method, &auth_method))
15646         ;
15647       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15648         is_hex = 1;
15649       else if (unformat (i, "auth_data %v", &data))
15650         ;
15651       else
15652         {
15653           errmsg ("parse error '%U'", format_unformat_error, i);
15654           return -99;
15655         }
15656     }
15657
15658   if (!vec_len (name))
15659     {
15660       errmsg ("profile name must be specified");
15661       return -99;
15662     }
15663
15664   if (vec_len (name) > 64)
15665     {
15666       errmsg ("profile name too long");
15667       return -99;
15668     }
15669
15670   if (!vec_len (data))
15671     {
15672       errmsg ("auth_data must be specified");
15673       return -99;
15674     }
15675
15676   if (!auth_method)
15677     {
15678       errmsg ("auth_method must be specified");
15679       return -99;
15680     }
15681
15682   M (IKEV2_PROFILE_SET_AUTH, mp);
15683
15684   mp->is_hex = is_hex;
15685   mp->auth_method = (u8) auth_method;
15686   mp->data_len = vec_len (data);
15687   clib_memcpy (mp->name, name, vec_len (name));
15688   clib_memcpy (mp->data, data, vec_len (data));
15689   vec_free (name);
15690   vec_free (data);
15691
15692   S (mp);
15693   W (ret);
15694   return ret;
15695 }
15696
15697 static int
15698 api_ikev2_profile_set_id (vat_main_t * vam)
15699 {
15700   unformat_input_t *i = vam->input;
15701   vl_api_ikev2_profile_set_id_t *mp;
15702   u8 *name = 0;
15703   u8 *data = 0;
15704   u8 is_local = 0;
15705   u32 id_type = 0;
15706   ip4_address_t ip4;
15707   int ret;
15708
15709   const char *valid_chars = "a-zA-Z0-9_";
15710
15711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15712     {
15713       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15714         vec_add1 (name, 0);
15715       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15716         ;
15717       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15718         {
15719           data = vec_new (u8, 4);
15720           clib_memcpy (data, ip4.as_u8, 4);
15721         }
15722       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15723         ;
15724       else if (unformat (i, "id_data %v", &data))
15725         ;
15726       else if (unformat (i, "local"))
15727         is_local = 1;
15728       else if (unformat (i, "remote"))
15729         is_local = 0;
15730       else
15731         {
15732           errmsg ("parse error '%U'", format_unformat_error, i);
15733           return -99;
15734         }
15735     }
15736
15737   if (!vec_len (name))
15738     {
15739       errmsg ("profile name must be specified");
15740       return -99;
15741     }
15742
15743   if (vec_len (name) > 64)
15744     {
15745       errmsg ("profile name too long");
15746       return -99;
15747     }
15748
15749   if (!vec_len (data))
15750     {
15751       errmsg ("id_data must be specified");
15752       return -99;
15753     }
15754
15755   if (!id_type)
15756     {
15757       errmsg ("id_type must be specified");
15758       return -99;
15759     }
15760
15761   M (IKEV2_PROFILE_SET_ID, mp);
15762
15763   mp->is_local = is_local;
15764   mp->id_type = (u8) id_type;
15765   mp->data_len = vec_len (data);
15766   clib_memcpy (mp->name, name, vec_len (name));
15767   clib_memcpy (mp->data, data, vec_len (data));
15768   vec_free (name);
15769   vec_free (data);
15770
15771   S (mp);
15772   W (ret);
15773   return ret;
15774 }
15775
15776 static int
15777 api_ikev2_profile_set_ts (vat_main_t * vam)
15778 {
15779   unformat_input_t *i = vam->input;
15780   vl_api_ikev2_profile_set_ts_t *mp;
15781   u8 *name = 0;
15782   u8 is_local = 0;
15783   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15784   ip4_address_t start_addr, end_addr;
15785
15786   const char *valid_chars = "a-zA-Z0-9_";
15787   int ret;
15788
15789   start_addr.as_u32 = 0;
15790   end_addr.as_u32 = (u32) ~ 0;
15791
15792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15793     {
15794       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15795         vec_add1 (name, 0);
15796       else if (unformat (i, "protocol %d", &proto))
15797         ;
15798       else if (unformat (i, "start_port %d", &start_port))
15799         ;
15800       else if (unformat (i, "end_port %d", &end_port))
15801         ;
15802       else
15803         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15804         ;
15805       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15806         ;
15807       else if (unformat (i, "local"))
15808         is_local = 1;
15809       else if (unformat (i, "remote"))
15810         is_local = 0;
15811       else
15812         {
15813           errmsg ("parse error '%U'", format_unformat_error, i);
15814           return -99;
15815         }
15816     }
15817
15818   if (!vec_len (name))
15819     {
15820       errmsg ("profile name must be specified");
15821       return -99;
15822     }
15823
15824   if (vec_len (name) > 64)
15825     {
15826       errmsg ("profile name too long");
15827       return -99;
15828     }
15829
15830   M (IKEV2_PROFILE_SET_TS, mp);
15831
15832   mp->is_local = is_local;
15833   mp->proto = (u8) proto;
15834   mp->start_port = (u16) start_port;
15835   mp->end_port = (u16) end_port;
15836   mp->start_addr = start_addr.as_u32;
15837   mp->end_addr = end_addr.as_u32;
15838   clib_memcpy (mp->name, name, vec_len (name));
15839   vec_free (name);
15840
15841   S (mp);
15842   W (ret);
15843   return ret;
15844 }
15845
15846 static int
15847 api_ikev2_set_local_key (vat_main_t * vam)
15848 {
15849   unformat_input_t *i = vam->input;
15850   vl_api_ikev2_set_local_key_t *mp;
15851   u8 *file = 0;
15852   int ret;
15853
15854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15855     {
15856       if (unformat (i, "file %v", &file))
15857         vec_add1 (file, 0);
15858       else
15859         {
15860           errmsg ("parse error '%U'", format_unformat_error, i);
15861           return -99;
15862         }
15863     }
15864
15865   if (!vec_len (file))
15866     {
15867       errmsg ("RSA key file must be specified");
15868       return -99;
15869     }
15870
15871   if (vec_len (file) > 256)
15872     {
15873       errmsg ("file name too long");
15874       return -99;
15875     }
15876
15877   M (IKEV2_SET_LOCAL_KEY, mp);
15878
15879   clib_memcpy (mp->key_file, file, vec_len (file));
15880   vec_free (file);
15881
15882   S (mp);
15883   W (ret);
15884   return ret;
15885 }
15886
15887 static int
15888 api_ikev2_set_responder (vat_main_t * vam)
15889 {
15890   unformat_input_t *i = vam->input;
15891   vl_api_ikev2_set_responder_t *mp;
15892   int ret;
15893   u8 *name = 0;
15894   u32 sw_if_index = ~0;
15895   ip4_address_t address;
15896
15897   const char *valid_chars = "a-zA-Z0-9_";
15898
15899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15900     {
15901       if (unformat
15902           (i, "%U interface %d address %U", unformat_token, valid_chars,
15903            &name, &sw_if_index, unformat_ip4_address, &address))
15904         vec_add1 (name, 0);
15905       else
15906         {
15907           errmsg ("parse error '%U'", format_unformat_error, i);
15908           return -99;
15909         }
15910     }
15911
15912   if (!vec_len (name))
15913     {
15914       errmsg ("profile name must be specified");
15915       return -99;
15916     }
15917
15918   if (vec_len (name) > 64)
15919     {
15920       errmsg ("profile name too long");
15921       return -99;
15922     }
15923
15924   M (IKEV2_SET_RESPONDER, mp);
15925
15926   clib_memcpy (mp->name, name, vec_len (name));
15927   vec_free (name);
15928
15929   mp->sw_if_index = sw_if_index;
15930   clib_memcpy (mp->address, &address, sizeof (address));
15931
15932   S (mp);
15933   W (ret);
15934   return ret;
15935 }
15936
15937 static int
15938 api_ikev2_set_ike_transforms (vat_main_t * vam)
15939 {
15940   unformat_input_t *i = vam->input;
15941   vl_api_ikev2_set_ike_transforms_t *mp;
15942   int ret;
15943   u8 *name = 0;
15944   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15945
15946   const char *valid_chars = "a-zA-Z0-9_";
15947
15948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15949     {
15950       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15951                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15952         vec_add1 (name, 0);
15953       else
15954         {
15955           errmsg ("parse error '%U'", format_unformat_error, i);
15956           return -99;
15957         }
15958     }
15959
15960   if (!vec_len (name))
15961     {
15962       errmsg ("profile name must be specified");
15963       return -99;
15964     }
15965
15966   if (vec_len (name) > 64)
15967     {
15968       errmsg ("profile name too long");
15969       return -99;
15970     }
15971
15972   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15973
15974   clib_memcpy (mp->name, name, vec_len (name));
15975   vec_free (name);
15976   mp->crypto_alg = crypto_alg;
15977   mp->crypto_key_size = crypto_key_size;
15978   mp->integ_alg = integ_alg;
15979   mp->dh_group = dh_group;
15980
15981   S (mp);
15982   W (ret);
15983   return ret;
15984 }
15985
15986
15987 static int
15988 api_ikev2_set_esp_transforms (vat_main_t * vam)
15989 {
15990   unformat_input_t *i = vam->input;
15991   vl_api_ikev2_set_esp_transforms_t *mp;
15992   int ret;
15993   u8 *name = 0;
15994   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15995
15996   const char *valid_chars = "a-zA-Z0-9_";
15997
15998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15999     {
16000       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16001                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16002         vec_add1 (name, 0);
16003       else
16004         {
16005           errmsg ("parse error '%U'", format_unformat_error, i);
16006           return -99;
16007         }
16008     }
16009
16010   if (!vec_len (name))
16011     {
16012       errmsg ("profile name must be specified");
16013       return -99;
16014     }
16015
16016   if (vec_len (name) > 64)
16017     {
16018       errmsg ("profile name too long");
16019       return -99;
16020     }
16021
16022   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16023
16024   clib_memcpy (mp->name, name, vec_len (name));
16025   vec_free (name);
16026   mp->crypto_alg = crypto_alg;
16027   mp->crypto_key_size = crypto_key_size;
16028   mp->integ_alg = integ_alg;
16029   mp->dh_group = dh_group;
16030
16031   S (mp);
16032   W (ret);
16033   return ret;
16034 }
16035
16036 static int
16037 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16038 {
16039   unformat_input_t *i = vam->input;
16040   vl_api_ikev2_set_sa_lifetime_t *mp;
16041   int ret;
16042   u8 *name = 0;
16043   u64 lifetime, lifetime_maxdata;
16044   u32 lifetime_jitter, handover;
16045
16046   const char *valid_chars = "a-zA-Z0-9_";
16047
16048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16049     {
16050       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16051                     &lifetime, &lifetime_jitter, &handover,
16052                     &lifetime_maxdata))
16053         vec_add1 (name, 0);
16054       else
16055         {
16056           errmsg ("parse error '%U'", format_unformat_error, i);
16057           return -99;
16058         }
16059     }
16060
16061   if (!vec_len (name))
16062     {
16063       errmsg ("profile name must be specified");
16064       return -99;
16065     }
16066
16067   if (vec_len (name) > 64)
16068     {
16069       errmsg ("profile name too long");
16070       return -99;
16071     }
16072
16073   M (IKEV2_SET_SA_LIFETIME, mp);
16074
16075   clib_memcpy (mp->name, name, vec_len (name));
16076   vec_free (name);
16077   mp->lifetime = lifetime;
16078   mp->lifetime_jitter = lifetime_jitter;
16079   mp->handover = handover;
16080   mp->lifetime_maxdata = lifetime_maxdata;
16081
16082   S (mp);
16083   W (ret);
16084   return ret;
16085 }
16086
16087 static int
16088 api_ikev2_initiate_sa_init (vat_main_t * vam)
16089 {
16090   unformat_input_t *i = vam->input;
16091   vl_api_ikev2_initiate_sa_init_t *mp;
16092   int ret;
16093   u8 *name = 0;
16094
16095   const char *valid_chars = "a-zA-Z0-9_";
16096
16097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16098     {
16099       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16100         vec_add1 (name, 0);
16101       else
16102         {
16103           errmsg ("parse error '%U'", format_unformat_error, i);
16104           return -99;
16105         }
16106     }
16107
16108   if (!vec_len (name))
16109     {
16110       errmsg ("profile name must be specified");
16111       return -99;
16112     }
16113
16114   if (vec_len (name) > 64)
16115     {
16116       errmsg ("profile name too long");
16117       return -99;
16118     }
16119
16120   M (IKEV2_INITIATE_SA_INIT, mp);
16121
16122   clib_memcpy (mp->name, name, vec_len (name));
16123   vec_free (name);
16124
16125   S (mp);
16126   W (ret);
16127   return ret;
16128 }
16129
16130 static int
16131 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16132 {
16133   unformat_input_t *i = vam->input;
16134   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16135   int ret;
16136   u64 ispi;
16137
16138
16139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16140     {
16141       if (unformat (i, "%lx", &ispi))
16142         ;
16143       else
16144         {
16145           errmsg ("parse error '%U'", format_unformat_error, i);
16146           return -99;
16147         }
16148     }
16149
16150   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16151
16152   mp->ispi = ispi;
16153
16154   S (mp);
16155   W (ret);
16156   return ret;
16157 }
16158
16159 static int
16160 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16161 {
16162   unformat_input_t *i = vam->input;
16163   vl_api_ikev2_initiate_del_child_sa_t *mp;
16164   int ret;
16165   u32 ispi;
16166
16167
16168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16169     {
16170       if (unformat (i, "%x", &ispi))
16171         ;
16172       else
16173         {
16174           errmsg ("parse error '%U'", format_unformat_error, i);
16175           return -99;
16176         }
16177     }
16178
16179   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16180
16181   mp->ispi = ispi;
16182
16183   S (mp);
16184   W (ret);
16185   return ret;
16186 }
16187
16188 static int
16189 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16190 {
16191   unformat_input_t *i = vam->input;
16192   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16193   int ret;
16194   u32 ispi;
16195
16196
16197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16198     {
16199       if (unformat (i, "%x", &ispi))
16200         ;
16201       else
16202         {
16203           errmsg ("parse error '%U'", format_unformat_error, i);
16204           return -99;
16205         }
16206     }
16207
16208   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16209
16210   mp->ispi = ispi;
16211
16212   S (mp);
16213   W (ret);
16214   return ret;
16215 }
16216
16217 static int
16218 api_get_first_msg_id (vat_main_t * vam)
16219 {
16220   vl_api_get_first_msg_id_t *mp;
16221   unformat_input_t *i = vam->input;
16222   u8 *name;
16223   u8 name_set = 0;
16224   int ret;
16225
16226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16227     {
16228       if (unformat (i, "client %s", &name))
16229         name_set = 1;
16230       else
16231         break;
16232     }
16233
16234   if (name_set == 0)
16235     {
16236       errmsg ("missing client name");
16237       return -99;
16238     }
16239   vec_add1 (name, 0);
16240
16241   if (vec_len (name) > 63)
16242     {
16243       errmsg ("client name too long");
16244       return -99;
16245     }
16246
16247   M (GET_FIRST_MSG_ID, mp);
16248   clib_memcpy (mp->name, name, vec_len (name));
16249   S (mp);
16250   W (ret);
16251   return ret;
16252 }
16253
16254 static int
16255 api_cop_interface_enable_disable (vat_main_t * vam)
16256 {
16257   unformat_input_t *line_input = vam->input;
16258   vl_api_cop_interface_enable_disable_t *mp;
16259   u32 sw_if_index = ~0;
16260   u8 enable_disable = 1;
16261   int ret;
16262
16263   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16264     {
16265       if (unformat (line_input, "disable"))
16266         enable_disable = 0;
16267       if (unformat (line_input, "enable"))
16268         enable_disable = 1;
16269       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16270                          vam, &sw_if_index))
16271         ;
16272       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16273         ;
16274       else
16275         break;
16276     }
16277
16278   if (sw_if_index == ~0)
16279     {
16280       errmsg ("missing interface name or sw_if_index");
16281       return -99;
16282     }
16283
16284   /* Construct the API message */
16285   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16286   mp->sw_if_index = ntohl (sw_if_index);
16287   mp->enable_disable = enable_disable;
16288
16289   /* send it... */
16290   S (mp);
16291   /* Wait for the reply */
16292   W (ret);
16293   return ret;
16294 }
16295
16296 static int
16297 api_cop_whitelist_enable_disable (vat_main_t * vam)
16298 {
16299   unformat_input_t *line_input = vam->input;
16300   vl_api_cop_whitelist_enable_disable_t *mp;
16301   u32 sw_if_index = ~0;
16302   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16303   u32 fib_id = 0;
16304   int ret;
16305
16306   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16307     {
16308       if (unformat (line_input, "ip4"))
16309         ip4 = 1;
16310       else if (unformat (line_input, "ip6"))
16311         ip6 = 1;
16312       else if (unformat (line_input, "default"))
16313         default_cop = 1;
16314       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16315                          vam, &sw_if_index))
16316         ;
16317       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16318         ;
16319       else if (unformat (line_input, "fib-id %d", &fib_id))
16320         ;
16321       else
16322         break;
16323     }
16324
16325   if (sw_if_index == ~0)
16326     {
16327       errmsg ("missing interface name or sw_if_index");
16328       return -99;
16329     }
16330
16331   /* Construct the API message */
16332   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16333   mp->sw_if_index = ntohl (sw_if_index);
16334   mp->fib_id = ntohl (fib_id);
16335   mp->ip4 = ip4;
16336   mp->ip6 = ip6;
16337   mp->default_cop = default_cop;
16338
16339   /* send it... */
16340   S (mp);
16341   /* Wait for the reply */
16342   W (ret);
16343   return ret;
16344 }
16345
16346 static int
16347 api_get_node_graph (vat_main_t * vam)
16348 {
16349   vl_api_get_node_graph_t *mp;
16350   int ret;
16351
16352   M (GET_NODE_GRAPH, mp);
16353
16354   /* send it... */
16355   S (mp);
16356   /* Wait for the reply */
16357   W (ret);
16358   return ret;
16359 }
16360
16361 /* *INDENT-OFF* */
16362 /** Used for parsing LISP eids */
16363 typedef CLIB_PACKED(struct{
16364   u8 addr[16];   /**< eid address */
16365   u32 len;       /**< prefix length if IP */
16366   u8 type;      /**< type of eid */
16367 }) lisp_eid_vat_t;
16368 /* *INDENT-ON* */
16369
16370 static uword
16371 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16372 {
16373   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16374
16375   clib_memset (a, 0, sizeof (a[0]));
16376
16377   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16378     {
16379       a->type = 0;              /* ipv4 type */
16380     }
16381   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16382     {
16383       a->type = 1;              /* ipv6 type */
16384     }
16385   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16386     {
16387       a->type = 2;              /* mac type */
16388     }
16389   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16390     {
16391       a->type = 3;              /* NSH type */
16392       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16393       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16394     }
16395   else
16396     {
16397       return 0;
16398     }
16399
16400   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16401     {
16402       return 0;
16403     }
16404
16405   return 1;
16406 }
16407
16408 static int
16409 lisp_eid_size_vat (u8 type)
16410 {
16411   switch (type)
16412     {
16413     case 0:
16414       return 4;
16415     case 1:
16416       return 16;
16417     case 2:
16418       return 6;
16419     case 3:
16420       return 5;
16421     }
16422   return 0;
16423 }
16424
16425 static void
16426 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16427 {
16428   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16429 }
16430
16431 static int
16432 api_one_add_del_locator_set (vat_main_t * vam)
16433 {
16434   unformat_input_t *input = vam->input;
16435   vl_api_one_add_del_locator_set_t *mp;
16436   u8 is_add = 1;
16437   u8 *locator_set_name = NULL;
16438   u8 locator_set_name_set = 0;
16439   vl_api_local_locator_t locator, *locators = 0;
16440   u32 sw_if_index, priority, weight;
16441   u32 data_len = 0;
16442
16443   int ret;
16444   /* Parse args required to build the message */
16445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16446     {
16447       if (unformat (input, "del"))
16448         {
16449           is_add = 0;
16450         }
16451       else if (unformat (input, "locator-set %s", &locator_set_name))
16452         {
16453           locator_set_name_set = 1;
16454         }
16455       else if (unformat (input, "sw_if_index %u p %u w %u",
16456                          &sw_if_index, &priority, &weight))
16457         {
16458           locator.sw_if_index = htonl (sw_if_index);
16459           locator.priority = priority;
16460           locator.weight = weight;
16461           vec_add1 (locators, locator);
16462         }
16463       else
16464         if (unformat
16465             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16466              &sw_if_index, &priority, &weight))
16467         {
16468           locator.sw_if_index = htonl (sw_if_index);
16469           locator.priority = priority;
16470           locator.weight = weight;
16471           vec_add1 (locators, locator);
16472         }
16473       else
16474         break;
16475     }
16476
16477   if (locator_set_name_set == 0)
16478     {
16479       errmsg ("missing locator-set name");
16480       vec_free (locators);
16481       return -99;
16482     }
16483
16484   if (vec_len (locator_set_name) > 64)
16485     {
16486       errmsg ("locator-set name too long");
16487       vec_free (locator_set_name);
16488       vec_free (locators);
16489       return -99;
16490     }
16491   vec_add1 (locator_set_name, 0);
16492
16493   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16494
16495   /* Construct the API message */
16496   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16497
16498   mp->is_add = is_add;
16499   clib_memcpy (mp->locator_set_name, locator_set_name,
16500                vec_len (locator_set_name));
16501   vec_free (locator_set_name);
16502
16503   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16504   if (locators)
16505     clib_memcpy (mp->locators, locators, data_len);
16506   vec_free (locators);
16507
16508   /* send it... */
16509   S (mp);
16510
16511   /* Wait for a reply... */
16512   W (ret);
16513   return ret;
16514 }
16515
16516 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16517
16518 static int
16519 api_one_add_del_locator (vat_main_t * vam)
16520 {
16521   unformat_input_t *input = vam->input;
16522   vl_api_one_add_del_locator_t *mp;
16523   u32 tmp_if_index = ~0;
16524   u32 sw_if_index = ~0;
16525   u8 sw_if_index_set = 0;
16526   u8 sw_if_index_if_name_set = 0;
16527   u32 priority = ~0;
16528   u8 priority_set = 0;
16529   u32 weight = ~0;
16530   u8 weight_set = 0;
16531   u8 is_add = 1;
16532   u8 *locator_set_name = NULL;
16533   u8 locator_set_name_set = 0;
16534   int ret;
16535
16536   /* Parse args required to build the message */
16537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16538     {
16539       if (unformat (input, "del"))
16540         {
16541           is_add = 0;
16542         }
16543       else if (unformat (input, "locator-set %s", &locator_set_name))
16544         {
16545           locator_set_name_set = 1;
16546         }
16547       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16548                          &tmp_if_index))
16549         {
16550           sw_if_index_if_name_set = 1;
16551           sw_if_index = tmp_if_index;
16552         }
16553       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16554         {
16555           sw_if_index_set = 1;
16556           sw_if_index = tmp_if_index;
16557         }
16558       else if (unformat (input, "p %d", &priority))
16559         {
16560           priority_set = 1;
16561         }
16562       else if (unformat (input, "w %d", &weight))
16563         {
16564           weight_set = 1;
16565         }
16566       else
16567         break;
16568     }
16569
16570   if (locator_set_name_set == 0)
16571     {
16572       errmsg ("missing locator-set name");
16573       return -99;
16574     }
16575
16576   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16577     {
16578       errmsg ("missing sw_if_index");
16579       vec_free (locator_set_name);
16580       return -99;
16581     }
16582
16583   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16584     {
16585       errmsg ("cannot use both params interface name and sw_if_index");
16586       vec_free (locator_set_name);
16587       return -99;
16588     }
16589
16590   if (priority_set == 0)
16591     {
16592       errmsg ("missing locator-set priority");
16593       vec_free (locator_set_name);
16594       return -99;
16595     }
16596
16597   if (weight_set == 0)
16598     {
16599       errmsg ("missing locator-set weight");
16600       vec_free (locator_set_name);
16601       return -99;
16602     }
16603
16604   if (vec_len (locator_set_name) > 64)
16605     {
16606       errmsg ("locator-set name too long");
16607       vec_free (locator_set_name);
16608       return -99;
16609     }
16610   vec_add1 (locator_set_name, 0);
16611
16612   /* Construct the API message */
16613   M (ONE_ADD_DEL_LOCATOR, mp);
16614
16615   mp->is_add = is_add;
16616   mp->sw_if_index = ntohl (sw_if_index);
16617   mp->priority = priority;
16618   mp->weight = weight;
16619   clib_memcpy (mp->locator_set_name, locator_set_name,
16620                vec_len (locator_set_name));
16621   vec_free (locator_set_name);
16622
16623   /* send it... */
16624   S (mp);
16625
16626   /* Wait for a reply... */
16627   W (ret);
16628   return ret;
16629 }
16630
16631 #define api_lisp_add_del_locator api_one_add_del_locator
16632
16633 uword
16634 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16635 {
16636   u32 *key_id = va_arg (*args, u32 *);
16637   u8 *s = 0;
16638
16639   if (unformat (input, "%s", &s))
16640     {
16641       if (!strcmp ((char *) s, "sha1"))
16642         key_id[0] = HMAC_SHA_1_96;
16643       else if (!strcmp ((char *) s, "sha256"))
16644         key_id[0] = HMAC_SHA_256_128;
16645       else
16646         {
16647           clib_warning ("invalid key_id: '%s'", s);
16648           key_id[0] = HMAC_NO_KEY;
16649         }
16650     }
16651   else
16652     return 0;
16653
16654   vec_free (s);
16655   return 1;
16656 }
16657
16658 static int
16659 api_one_add_del_local_eid (vat_main_t * vam)
16660 {
16661   unformat_input_t *input = vam->input;
16662   vl_api_one_add_del_local_eid_t *mp;
16663   u8 is_add = 1;
16664   u8 eid_set = 0;
16665   lisp_eid_vat_t _eid, *eid = &_eid;
16666   u8 *locator_set_name = 0;
16667   u8 locator_set_name_set = 0;
16668   u32 vni = 0;
16669   u16 key_id = 0;
16670   u8 *key = 0;
16671   int ret;
16672
16673   /* Parse args required to build the message */
16674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16675     {
16676       if (unformat (input, "del"))
16677         {
16678           is_add = 0;
16679         }
16680       else if (unformat (input, "vni %d", &vni))
16681         {
16682           ;
16683         }
16684       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16685         {
16686           eid_set = 1;
16687         }
16688       else if (unformat (input, "locator-set %s", &locator_set_name))
16689         {
16690           locator_set_name_set = 1;
16691         }
16692       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16693         ;
16694       else if (unformat (input, "secret-key %_%v%_", &key))
16695         ;
16696       else
16697         break;
16698     }
16699
16700   if (locator_set_name_set == 0)
16701     {
16702       errmsg ("missing locator-set name");
16703       return -99;
16704     }
16705
16706   if (0 == eid_set)
16707     {
16708       errmsg ("EID address not set!");
16709       vec_free (locator_set_name);
16710       return -99;
16711     }
16712
16713   if (key && (0 == key_id))
16714     {
16715       errmsg ("invalid key_id!");
16716       return -99;
16717     }
16718
16719   if (vec_len (key) > 64)
16720     {
16721       errmsg ("key too long");
16722       vec_free (key);
16723       return -99;
16724     }
16725
16726   if (vec_len (locator_set_name) > 64)
16727     {
16728       errmsg ("locator-set name too long");
16729       vec_free (locator_set_name);
16730       return -99;
16731     }
16732   vec_add1 (locator_set_name, 0);
16733
16734   /* Construct the API message */
16735   M (ONE_ADD_DEL_LOCAL_EID, mp);
16736
16737   mp->is_add = is_add;
16738   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16739   mp->eid_type = eid->type;
16740   mp->prefix_len = eid->len;
16741   mp->vni = clib_host_to_net_u32 (vni);
16742   mp->key_id = clib_host_to_net_u16 (key_id);
16743   clib_memcpy (mp->locator_set_name, locator_set_name,
16744                vec_len (locator_set_name));
16745   clib_memcpy (mp->key, key, vec_len (key));
16746
16747   vec_free (locator_set_name);
16748   vec_free (key);
16749
16750   /* send it... */
16751   S (mp);
16752
16753   /* Wait for a reply... */
16754   W (ret);
16755   return ret;
16756 }
16757
16758 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16759
16760 static int
16761 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16762 {
16763   u32 dp_table = 0, vni = 0;;
16764   unformat_input_t *input = vam->input;
16765   vl_api_gpe_add_del_fwd_entry_t *mp;
16766   u8 is_add = 1;
16767   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16768   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16769   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16770   u32 action = ~0, w;
16771   ip4_address_t rmt_rloc4, lcl_rloc4;
16772   ip6_address_t rmt_rloc6, lcl_rloc6;
16773   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16774   int ret;
16775
16776   clib_memset (&rloc, 0, sizeof (rloc));
16777
16778   /* Parse args required to build the message */
16779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16780     {
16781       if (unformat (input, "del"))
16782         is_add = 0;
16783       else if (unformat (input, "add"))
16784         is_add = 1;
16785       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16786         {
16787           rmt_eid_set = 1;
16788         }
16789       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16790         {
16791           lcl_eid_set = 1;
16792         }
16793       else if (unformat (input, "vrf %d", &dp_table))
16794         ;
16795       else if (unformat (input, "bd %d", &dp_table))
16796         ;
16797       else if (unformat (input, "vni %d", &vni))
16798         ;
16799       else if (unformat (input, "w %d", &w))
16800         {
16801           if (!curr_rloc)
16802             {
16803               errmsg ("No RLOC configured for setting priority/weight!");
16804               return -99;
16805             }
16806           curr_rloc->weight = w;
16807         }
16808       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16809                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16810         {
16811           rloc.is_ip4 = 1;
16812
16813           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16814           rloc.weight = 0;
16815           vec_add1 (lcl_locs, rloc);
16816
16817           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16818           vec_add1 (rmt_locs, rloc);
16819           /* weight saved in rmt loc */
16820           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16821         }
16822       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16823                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16824         {
16825           rloc.is_ip4 = 0;
16826           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16827           rloc.weight = 0;
16828           vec_add1 (lcl_locs, rloc);
16829
16830           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16831           vec_add1 (rmt_locs, rloc);
16832           /* weight saved in rmt loc */
16833           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16834         }
16835       else if (unformat (input, "action %d", &action))
16836         {
16837           ;
16838         }
16839       else
16840         {
16841           clib_warning ("parse error '%U'", format_unformat_error, input);
16842           return -99;
16843         }
16844     }
16845
16846   if (!rmt_eid_set)
16847     {
16848       errmsg ("remote eid addresses not set");
16849       return -99;
16850     }
16851
16852   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16853     {
16854       errmsg ("eid types don't match");
16855       return -99;
16856     }
16857
16858   if (0 == rmt_locs && (u32) ~ 0 == action)
16859     {
16860       errmsg ("action not set for negative mapping");
16861       return -99;
16862     }
16863
16864   /* Construct the API message */
16865   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16866       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16867
16868   mp->is_add = is_add;
16869   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16870   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16871   mp->eid_type = rmt_eid->type;
16872   mp->dp_table = clib_host_to_net_u32 (dp_table);
16873   mp->vni = clib_host_to_net_u32 (vni);
16874   mp->rmt_len = rmt_eid->len;
16875   mp->lcl_len = lcl_eid->len;
16876   mp->action = action;
16877
16878   if (0 != rmt_locs && 0 != lcl_locs)
16879     {
16880       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16881       clib_memcpy (mp->locs, lcl_locs,
16882                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16883
16884       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16885       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16886                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16887     }
16888   vec_free (lcl_locs);
16889   vec_free (rmt_locs);
16890
16891   /* send it... */
16892   S (mp);
16893
16894   /* Wait for a reply... */
16895   W (ret);
16896   return ret;
16897 }
16898
16899 static int
16900 api_one_add_del_map_server (vat_main_t * vam)
16901 {
16902   unformat_input_t *input = vam->input;
16903   vl_api_one_add_del_map_server_t *mp;
16904   u8 is_add = 1;
16905   u8 ipv4_set = 0;
16906   u8 ipv6_set = 0;
16907   ip4_address_t ipv4;
16908   ip6_address_t ipv6;
16909   int ret;
16910
16911   /* Parse args required to build the message */
16912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16913     {
16914       if (unformat (input, "del"))
16915         {
16916           is_add = 0;
16917         }
16918       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16919         {
16920           ipv4_set = 1;
16921         }
16922       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16923         {
16924           ipv6_set = 1;
16925         }
16926       else
16927         break;
16928     }
16929
16930   if (ipv4_set && ipv6_set)
16931     {
16932       errmsg ("both eid v4 and v6 addresses set");
16933       return -99;
16934     }
16935
16936   if (!ipv4_set && !ipv6_set)
16937     {
16938       errmsg ("eid addresses not set");
16939       return -99;
16940     }
16941
16942   /* Construct the API message */
16943   M (ONE_ADD_DEL_MAP_SERVER, mp);
16944
16945   mp->is_add = is_add;
16946   if (ipv6_set)
16947     {
16948       mp->is_ipv6 = 1;
16949       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16950     }
16951   else
16952     {
16953       mp->is_ipv6 = 0;
16954       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16955     }
16956
16957   /* send it... */
16958   S (mp);
16959
16960   /* Wait for a reply... */
16961   W (ret);
16962   return ret;
16963 }
16964
16965 #define api_lisp_add_del_map_server api_one_add_del_map_server
16966
16967 static int
16968 api_one_add_del_map_resolver (vat_main_t * vam)
16969 {
16970   unformat_input_t *input = vam->input;
16971   vl_api_one_add_del_map_resolver_t *mp;
16972   u8 is_add = 1;
16973   u8 ipv4_set = 0;
16974   u8 ipv6_set = 0;
16975   ip4_address_t ipv4;
16976   ip6_address_t ipv6;
16977   int ret;
16978
16979   /* Parse args required to build the message */
16980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16981     {
16982       if (unformat (input, "del"))
16983         {
16984           is_add = 0;
16985         }
16986       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16987         {
16988           ipv4_set = 1;
16989         }
16990       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16991         {
16992           ipv6_set = 1;
16993         }
16994       else
16995         break;
16996     }
16997
16998   if (ipv4_set && ipv6_set)
16999     {
17000       errmsg ("both eid v4 and v6 addresses set");
17001       return -99;
17002     }
17003
17004   if (!ipv4_set && !ipv6_set)
17005     {
17006       errmsg ("eid addresses not set");
17007       return -99;
17008     }
17009
17010   /* Construct the API message */
17011   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17012
17013   mp->is_add = is_add;
17014   if (ipv6_set)
17015     {
17016       mp->is_ipv6 = 1;
17017       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17018     }
17019   else
17020     {
17021       mp->is_ipv6 = 0;
17022       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17023     }
17024
17025   /* send it... */
17026   S (mp);
17027
17028   /* Wait for a reply... */
17029   W (ret);
17030   return ret;
17031 }
17032
17033 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17034
17035 static int
17036 api_lisp_gpe_enable_disable (vat_main_t * vam)
17037 {
17038   unformat_input_t *input = vam->input;
17039   vl_api_gpe_enable_disable_t *mp;
17040   u8 is_set = 0;
17041   u8 is_en = 1;
17042   int ret;
17043
17044   /* Parse args required to build the message */
17045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17046     {
17047       if (unformat (input, "enable"))
17048         {
17049           is_set = 1;
17050           is_en = 1;
17051         }
17052       else if (unformat (input, "disable"))
17053         {
17054           is_set = 1;
17055           is_en = 0;
17056         }
17057       else
17058         break;
17059     }
17060
17061   if (is_set == 0)
17062     {
17063       errmsg ("Value not set");
17064       return -99;
17065     }
17066
17067   /* Construct the API message */
17068   M (GPE_ENABLE_DISABLE, mp);
17069
17070   mp->is_en = is_en;
17071
17072   /* send it... */
17073   S (mp);
17074
17075   /* Wait for a reply... */
17076   W (ret);
17077   return ret;
17078 }
17079
17080 static int
17081 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17082 {
17083   unformat_input_t *input = vam->input;
17084   vl_api_one_rloc_probe_enable_disable_t *mp;
17085   u8 is_set = 0;
17086   u8 is_en = 0;
17087   int ret;
17088
17089   /* Parse args required to build the message */
17090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17091     {
17092       if (unformat (input, "enable"))
17093         {
17094           is_set = 1;
17095           is_en = 1;
17096         }
17097       else if (unformat (input, "disable"))
17098         is_set = 1;
17099       else
17100         break;
17101     }
17102
17103   if (!is_set)
17104     {
17105       errmsg ("Value not set");
17106       return -99;
17107     }
17108
17109   /* Construct the API message */
17110   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17111
17112   mp->is_enabled = is_en;
17113
17114   /* send it... */
17115   S (mp);
17116
17117   /* Wait for a reply... */
17118   W (ret);
17119   return ret;
17120 }
17121
17122 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17123
17124 static int
17125 api_one_map_register_enable_disable (vat_main_t * vam)
17126 {
17127   unformat_input_t *input = vam->input;
17128   vl_api_one_map_register_enable_disable_t *mp;
17129   u8 is_set = 0;
17130   u8 is_en = 0;
17131   int ret;
17132
17133   /* Parse args required to build the message */
17134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17135     {
17136       if (unformat (input, "enable"))
17137         {
17138           is_set = 1;
17139           is_en = 1;
17140         }
17141       else if (unformat (input, "disable"))
17142         is_set = 1;
17143       else
17144         break;
17145     }
17146
17147   if (!is_set)
17148     {
17149       errmsg ("Value not set");
17150       return -99;
17151     }
17152
17153   /* Construct the API message */
17154   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17155
17156   mp->is_enabled = is_en;
17157
17158   /* send it... */
17159   S (mp);
17160
17161   /* Wait for a reply... */
17162   W (ret);
17163   return ret;
17164 }
17165
17166 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17167
17168 static int
17169 api_one_enable_disable (vat_main_t * vam)
17170 {
17171   unformat_input_t *input = vam->input;
17172   vl_api_one_enable_disable_t *mp;
17173   u8 is_set = 0;
17174   u8 is_en = 0;
17175   int ret;
17176
17177   /* Parse args required to build the message */
17178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17179     {
17180       if (unformat (input, "enable"))
17181         {
17182           is_set = 1;
17183           is_en = 1;
17184         }
17185       else if (unformat (input, "disable"))
17186         {
17187           is_set = 1;
17188         }
17189       else
17190         break;
17191     }
17192
17193   if (!is_set)
17194     {
17195       errmsg ("Value not set");
17196       return -99;
17197     }
17198
17199   /* Construct the API message */
17200   M (ONE_ENABLE_DISABLE, mp);
17201
17202   mp->is_en = is_en;
17203
17204   /* send it... */
17205   S (mp);
17206
17207   /* Wait for a reply... */
17208   W (ret);
17209   return ret;
17210 }
17211
17212 #define api_lisp_enable_disable api_one_enable_disable
17213
17214 static int
17215 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17216 {
17217   unformat_input_t *input = vam->input;
17218   vl_api_one_enable_disable_xtr_mode_t *mp;
17219   u8 is_set = 0;
17220   u8 is_en = 0;
17221   int ret;
17222
17223   /* Parse args required to build the message */
17224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17225     {
17226       if (unformat (input, "enable"))
17227         {
17228           is_set = 1;
17229           is_en = 1;
17230         }
17231       else if (unformat (input, "disable"))
17232         {
17233           is_set = 1;
17234         }
17235       else
17236         break;
17237     }
17238
17239   if (!is_set)
17240     {
17241       errmsg ("Value not set");
17242       return -99;
17243     }
17244
17245   /* Construct the API message */
17246   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17247
17248   mp->is_en = is_en;
17249
17250   /* send it... */
17251   S (mp);
17252
17253   /* Wait for a reply... */
17254   W (ret);
17255   return ret;
17256 }
17257
17258 static int
17259 api_one_show_xtr_mode (vat_main_t * vam)
17260 {
17261   vl_api_one_show_xtr_mode_t *mp;
17262   int ret;
17263
17264   /* Construct the API message */
17265   M (ONE_SHOW_XTR_MODE, mp);
17266
17267   /* send it... */
17268   S (mp);
17269
17270   /* Wait for a reply... */
17271   W (ret);
17272   return ret;
17273 }
17274
17275 static int
17276 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17277 {
17278   unformat_input_t *input = vam->input;
17279   vl_api_one_enable_disable_pitr_mode_t *mp;
17280   u8 is_set = 0;
17281   u8 is_en = 0;
17282   int ret;
17283
17284   /* Parse args required to build the message */
17285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17286     {
17287       if (unformat (input, "enable"))
17288         {
17289           is_set = 1;
17290           is_en = 1;
17291         }
17292       else if (unformat (input, "disable"))
17293         {
17294           is_set = 1;
17295         }
17296       else
17297         break;
17298     }
17299
17300   if (!is_set)
17301     {
17302       errmsg ("Value not set");
17303       return -99;
17304     }
17305
17306   /* Construct the API message */
17307   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17308
17309   mp->is_en = is_en;
17310
17311   /* send it... */
17312   S (mp);
17313
17314   /* Wait for a reply... */
17315   W (ret);
17316   return ret;
17317 }
17318
17319 static int
17320 api_one_show_pitr_mode (vat_main_t * vam)
17321 {
17322   vl_api_one_show_pitr_mode_t *mp;
17323   int ret;
17324
17325   /* Construct the API message */
17326   M (ONE_SHOW_PITR_MODE, mp);
17327
17328   /* send it... */
17329   S (mp);
17330
17331   /* Wait for a reply... */
17332   W (ret);
17333   return ret;
17334 }
17335
17336 static int
17337 api_one_enable_disable_petr_mode (vat_main_t * vam)
17338 {
17339   unformat_input_t *input = vam->input;
17340   vl_api_one_enable_disable_petr_mode_t *mp;
17341   u8 is_set = 0;
17342   u8 is_en = 0;
17343   int ret;
17344
17345   /* Parse args required to build the message */
17346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17347     {
17348       if (unformat (input, "enable"))
17349         {
17350           is_set = 1;
17351           is_en = 1;
17352         }
17353       else if (unformat (input, "disable"))
17354         {
17355           is_set = 1;
17356         }
17357       else
17358         break;
17359     }
17360
17361   if (!is_set)
17362     {
17363       errmsg ("Value not set");
17364       return -99;
17365     }
17366
17367   /* Construct the API message */
17368   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17369
17370   mp->is_en = is_en;
17371
17372   /* send it... */
17373   S (mp);
17374
17375   /* Wait for a reply... */
17376   W (ret);
17377   return ret;
17378 }
17379
17380 static int
17381 api_one_show_petr_mode (vat_main_t * vam)
17382 {
17383   vl_api_one_show_petr_mode_t *mp;
17384   int ret;
17385
17386   /* Construct the API message */
17387   M (ONE_SHOW_PETR_MODE, mp);
17388
17389   /* send it... */
17390   S (mp);
17391
17392   /* Wait for a reply... */
17393   W (ret);
17394   return ret;
17395 }
17396
17397 static int
17398 api_show_one_map_register_state (vat_main_t * vam)
17399 {
17400   vl_api_show_one_map_register_state_t *mp;
17401   int ret;
17402
17403   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17404
17405   /* send */
17406   S (mp);
17407
17408   /* wait for reply */
17409   W (ret);
17410   return ret;
17411 }
17412
17413 #define api_show_lisp_map_register_state api_show_one_map_register_state
17414
17415 static int
17416 api_show_one_rloc_probe_state (vat_main_t * vam)
17417 {
17418   vl_api_show_one_rloc_probe_state_t *mp;
17419   int ret;
17420
17421   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17422
17423   /* send */
17424   S (mp);
17425
17426   /* wait for reply */
17427   W (ret);
17428   return ret;
17429 }
17430
17431 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17432
17433 static int
17434 api_one_add_del_ndp_entry (vat_main_t * vam)
17435 {
17436   vl_api_one_add_del_ndp_entry_t *mp;
17437   unformat_input_t *input = vam->input;
17438   u8 is_add = 1;
17439   u8 mac_set = 0;
17440   u8 bd_set = 0;
17441   u8 ip_set = 0;
17442   u8 mac[6] = { 0, };
17443   u8 ip6[16] = { 0, };
17444   u32 bd = ~0;
17445   int ret;
17446
17447   /* Parse args required to build the message */
17448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17449     {
17450       if (unformat (input, "del"))
17451         is_add = 0;
17452       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17453         mac_set = 1;
17454       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17455         ip_set = 1;
17456       else if (unformat (input, "bd %d", &bd))
17457         bd_set = 1;
17458       else
17459         {
17460           errmsg ("parse error '%U'", format_unformat_error, input);
17461           return -99;
17462         }
17463     }
17464
17465   if (!bd_set || !ip_set || (!mac_set && is_add))
17466     {
17467       errmsg ("Missing BD, IP or MAC!");
17468       return -99;
17469     }
17470
17471   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17472   mp->is_add = is_add;
17473   clib_memcpy (mp->mac, mac, 6);
17474   mp->bd = clib_host_to_net_u32 (bd);
17475   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17476
17477   /* send */
17478   S (mp);
17479
17480   /* wait for reply */
17481   W (ret);
17482   return ret;
17483 }
17484
17485 static int
17486 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17487 {
17488   vl_api_one_add_del_l2_arp_entry_t *mp;
17489   unformat_input_t *input = vam->input;
17490   u8 is_add = 1;
17491   u8 mac_set = 0;
17492   u8 bd_set = 0;
17493   u8 ip_set = 0;
17494   u8 mac[6] = { 0, };
17495   u32 ip4 = 0, bd = ~0;
17496   int ret;
17497
17498   /* Parse args required to build the message */
17499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17500     {
17501       if (unformat (input, "del"))
17502         is_add = 0;
17503       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17504         mac_set = 1;
17505       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17506         ip_set = 1;
17507       else if (unformat (input, "bd %d", &bd))
17508         bd_set = 1;
17509       else
17510         {
17511           errmsg ("parse error '%U'", format_unformat_error, input);
17512           return -99;
17513         }
17514     }
17515
17516   if (!bd_set || !ip_set || (!mac_set && is_add))
17517     {
17518       errmsg ("Missing BD, IP or MAC!");
17519       return -99;
17520     }
17521
17522   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17523   mp->is_add = is_add;
17524   clib_memcpy (mp->mac, mac, 6);
17525   mp->bd = clib_host_to_net_u32 (bd);
17526   mp->ip4 = ip4;
17527
17528   /* send */
17529   S (mp);
17530
17531   /* wait for reply */
17532   W (ret);
17533   return ret;
17534 }
17535
17536 static int
17537 api_one_ndp_bd_get (vat_main_t * vam)
17538 {
17539   vl_api_one_ndp_bd_get_t *mp;
17540   int ret;
17541
17542   M (ONE_NDP_BD_GET, mp);
17543
17544   /* send */
17545   S (mp);
17546
17547   /* wait for reply */
17548   W (ret);
17549   return ret;
17550 }
17551
17552 static int
17553 api_one_ndp_entries_get (vat_main_t * vam)
17554 {
17555   vl_api_one_ndp_entries_get_t *mp;
17556   unformat_input_t *input = vam->input;
17557   u8 bd_set = 0;
17558   u32 bd = ~0;
17559   int ret;
17560
17561   /* Parse args required to build the message */
17562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17563     {
17564       if (unformat (input, "bd %d", &bd))
17565         bd_set = 1;
17566       else
17567         {
17568           errmsg ("parse error '%U'", format_unformat_error, input);
17569           return -99;
17570         }
17571     }
17572
17573   if (!bd_set)
17574     {
17575       errmsg ("Expected bridge domain!");
17576       return -99;
17577     }
17578
17579   M (ONE_NDP_ENTRIES_GET, mp);
17580   mp->bd = clib_host_to_net_u32 (bd);
17581
17582   /* send */
17583   S (mp);
17584
17585   /* wait for reply */
17586   W (ret);
17587   return ret;
17588 }
17589
17590 static int
17591 api_one_l2_arp_bd_get (vat_main_t * vam)
17592 {
17593   vl_api_one_l2_arp_bd_get_t *mp;
17594   int ret;
17595
17596   M (ONE_L2_ARP_BD_GET, mp);
17597
17598   /* send */
17599   S (mp);
17600
17601   /* wait for reply */
17602   W (ret);
17603   return ret;
17604 }
17605
17606 static int
17607 api_one_l2_arp_entries_get (vat_main_t * vam)
17608 {
17609   vl_api_one_l2_arp_entries_get_t *mp;
17610   unformat_input_t *input = vam->input;
17611   u8 bd_set = 0;
17612   u32 bd = ~0;
17613   int ret;
17614
17615   /* Parse args required to build the message */
17616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17617     {
17618       if (unformat (input, "bd %d", &bd))
17619         bd_set = 1;
17620       else
17621         {
17622           errmsg ("parse error '%U'", format_unformat_error, input);
17623           return -99;
17624         }
17625     }
17626
17627   if (!bd_set)
17628     {
17629       errmsg ("Expected bridge domain!");
17630       return -99;
17631     }
17632
17633   M (ONE_L2_ARP_ENTRIES_GET, mp);
17634   mp->bd = clib_host_to_net_u32 (bd);
17635
17636   /* send */
17637   S (mp);
17638
17639   /* wait for reply */
17640   W (ret);
17641   return ret;
17642 }
17643
17644 static int
17645 api_one_stats_enable_disable (vat_main_t * vam)
17646 {
17647   vl_api_one_stats_enable_disable_t *mp;
17648   unformat_input_t *input = vam->input;
17649   u8 is_set = 0;
17650   u8 is_en = 0;
17651   int ret;
17652
17653   /* Parse args required to build the message */
17654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17655     {
17656       if (unformat (input, "enable"))
17657         {
17658           is_set = 1;
17659           is_en = 1;
17660         }
17661       else if (unformat (input, "disable"))
17662         {
17663           is_set = 1;
17664         }
17665       else
17666         break;
17667     }
17668
17669   if (!is_set)
17670     {
17671       errmsg ("Value not set");
17672       return -99;
17673     }
17674
17675   M (ONE_STATS_ENABLE_DISABLE, mp);
17676   mp->is_en = is_en;
17677
17678   /* send */
17679   S (mp);
17680
17681   /* wait for reply */
17682   W (ret);
17683   return ret;
17684 }
17685
17686 static int
17687 api_show_one_stats_enable_disable (vat_main_t * vam)
17688 {
17689   vl_api_show_one_stats_enable_disable_t *mp;
17690   int ret;
17691
17692   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17693
17694   /* send */
17695   S (mp);
17696
17697   /* wait for reply */
17698   W (ret);
17699   return ret;
17700 }
17701
17702 static int
17703 api_show_one_map_request_mode (vat_main_t * vam)
17704 {
17705   vl_api_show_one_map_request_mode_t *mp;
17706   int ret;
17707
17708   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17709
17710   /* send */
17711   S (mp);
17712
17713   /* wait for reply */
17714   W (ret);
17715   return ret;
17716 }
17717
17718 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17719
17720 static int
17721 api_one_map_request_mode (vat_main_t * vam)
17722 {
17723   unformat_input_t *input = vam->input;
17724   vl_api_one_map_request_mode_t *mp;
17725   u8 mode = 0;
17726   int ret;
17727
17728   /* Parse args required to build the message */
17729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17730     {
17731       if (unformat (input, "dst-only"))
17732         mode = 0;
17733       else if (unformat (input, "src-dst"))
17734         mode = 1;
17735       else
17736         {
17737           errmsg ("parse error '%U'", format_unformat_error, input);
17738           return -99;
17739         }
17740     }
17741
17742   M (ONE_MAP_REQUEST_MODE, mp);
17743
17744   mp->mode = mode;
17745
17746   /* send */
17747   S (mp);
17748
17749   /* wait for reply */
17750   W (ret);
17751   return ret;
17752 }
17753
17754 #define api_lisp_map_request_mode api_one_map_request_mode
17755
17756 /**
17757  * Enable/disable ONE proxy ITR.
17758  *
17759  * @param vam vpp API test context
17760  * @return return code
17761  */
17762 static int
17763 api_one_pitr_set_locator_set (vat_main_t * vam)
17764 {
17765   u8 ls_name_set = 0;
17766   unformat_input_t *input = vam->input;
17767   vl_api_one_pitr_set_locator_set_t *mp;
17768   u8 is_add = 1;
17769   u8 *ls_name = 0;
17770   int ret;
17771
17772   /* Parse args required to build the message */
17773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17774     {
17775       if (unformat (input, "del"))
17776         is_add = 0;
17777       else if (unformat (input, "locator-set %s", &ls_name))
17778         ls_name_set = 1;
17779       else
17780         {
17781           errmsg ("parse error '%U'", format_unformat_error, input);
17782           return -99;
17783         }
17784     }
17785
17786   if (!ls_name_set)
17787     {
17788       errmsg ("locator-set name not set!");
17789       return -99;
17790     }
17791
17792   M (ONE_PITR_SET_LOCATOR_SET, mp);
17793
17794   mp->is_add = is_add;
17795   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17796   vec_free (ls_name);
17797
17798   /* send */
17799   S (mp);
17800
17801   /* wait for reply */
17802   W (ret);
17803   return ret;
17804 }
17805
17806 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17807
17808 static int
17809 api_one_nsh_set_locator_set (vat_main_t * vam)
17810 {
17811   u8 ls_name_set = 0;
17812   unformat_input_t *input = vam->input;
17813   vl_api_one_nsh_set_locator_set_t *mp;
17814   u8 is_add = 1;
17815   u8 *ls_name = 0;
17816   int ret;
17817
17818   /* Parse args required to build the message */
17819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17820     {
17821       if (unformat (input, "del"))
17822         is_add = 0;
17823       else if (unformat (input, "ls %s", &ls_name))
17824         ls_name_set = 1;
17825       else
17826         {
17827           errmsg ("parse error '%U'", format_unformat_error, input);
17828           return -99;
17829         }
17830     }
17831
17832   if (!ls_name_set && is_add)
17833     {
17834       errmsg ("locator-set name not set!");
17835       return -99;
17836     }
17837
17838   M (ONE_NSH_SET_LOCATOR_SET, mp);
17839
17840   mp->is_add = is_add;
17841   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17842   vec_free (ls_name);
17843
17844   /* send */
17845   S (mp);
17846
17847   /* wait for reply */
17848   W (ret);
17849   return ret;
17850 }
17851
17852 static int
17853 api_show_one_pitr (vat_main_t * vam)
17854 {
17855   vl_api_show_one_pitr_t *mp;
17856   int ret;
17857
17858   if (!vam->json_output)
17859     {
17860       print (vam->ofp, "%=20s", "lisp status:");
17861     }
17862
17863   M (SHOW_ONE_PITR, mp);
17864   /* send it... */
17865   S (mp);
17866
17867   /* Wait for a reply... */
17868   W (ret);
17869   return ret;
17870 }
17871
17872 #define api_show_lisp_pitr api_show_one_pitr
17873
17874 static int
17875 api_one_use_petr (vat_main_t * vam)
17876 {
17877   unformat_input_t *input = vam->input;
17878   vl_api_one_use_petr_t *mp;
17879   u8 is_add = 0;
17880   ip_address_t ip;
17881   int ret;
17882
17883   clib_memset (&ip, 0, sizeof (ip));
17884
17885   /* Parse args required to build the message */
17886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17887     {
17888       if (unformat (input, "disable"))
17889         is_add = 0;
17890       else
17891         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17892         {
17893           is_add = 1;
17894           ip_addr_version (&ip) = IP4;
17895         }
17896       else
17897         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17898         {
17899           is_add = 1;
17900           ip_addr_version (&ip) = IP6;
17901         }
17902       else
17903         {
17904           errmsg ("parse error '%U'", format_unformat_error, input);
17905           return -99;
17906         }
17907     }
17908
17909   M (ONE_USE_PETR, mp);
17910
17911   mp->is_add = is_add;
17912   if (is_add)
17913     {
17914       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17915       if (mp->is_ip4)
17916         clib_memcpy (mp->address, &ip, 4);
17917       else
17918         clib_memcpy (mp->address, &ip, 16);
17919     }
17920
17921   /* send */
17922   S (mp);
17923
17924   /* wait for reply */
17925   W (ret);
17926   return ret;
17927 }
17928
17929 #define api_lisp_use_petr api_one_use_petr
17930
17931 static int
17932 api_show_one_nsh_mapping (vat_main_t * vam)
17933 {
17934   vl_api_show_one_use_petr_t *mp;
17935   int ret;
17936
17937   if (!vam->json_output)
17938     {
17939       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17940     }
17941
17942   M (SHOW_ONE_NSH_MAPPING, mp);
17943   /* send it... */
17944   S (mp);
17945
17946   /* Wait for a reply... */
17947   W (ret);
17948   return ret;
17949 }
17950
17951 static int
17952 api_show_one_use_petr (vat_main_t * vam)
17953 {
17954   vl_api_show_one_use_petr_t *mp;
17955   int ret;
17956
17957   if (!vam->json_output)
17958     {
17959       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17960     }
17961
17962   M (SHOW_ONE_USE_PETR, mp);
17963   /* send it... */
17964   S (mp);
17965
17966   /* Wait for a reply... */
17967   W (ret);
17968   return ret;
17969 }
17970
17971 #define api_show_lisp_use_petr api_show_one_use_petr
17972
17973 /**
17974  * Add/delete mapping between vni and vrf
17975  */
17976 static int
17977 api_one_eid_table_add_del_map (vat_main_t * vam)
17978 {
17979   unformat_input_t *input = vam->input;
17980   vl_api_one_eid_table_add_del_map_t *mp;
17981   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17982   u32 vni, vrf, bd_index;
17983   int ret;
17984
17985   /* Parse args required to build the message */
17986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17987     {
17988       if (unformat (input, "del"))
17989         is_add = 0;
17990       else if (unformat (input, "vrf %d", &vrf))
17991         vrf_set = 1;
17992       else if (unformat (input, "bd_index %d", &bd_index))
17993         bd_index_set = 1;
17994       else if (unformat (input, "vni %d", &vni))
17995         vni_set = 1;
17996       else
17997         break;
17998     }
17999
18000   if (!vni_set || (!vrf_set && !bd_index_set))
18001     {
18002       errmsg ("missing arguments!");
18003       return -99;
18004     }
18005
18006   if (vrf_set && bd_index_set)
18007     {
18008       errmsg ("error: both vrf and bd entered!");
18009       return -99;
18010     }
18011
18012   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18013
18014   mp->is_add = is_add;
18015   mp->vni = htonl (vni);
18016   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18017   mp->is_l2 = bd_index_set;
18018
18019   /* send */
18020   S (mp);
18021
18022   /* wait for reply */
18023   W (ret);
18024   return ret;
18025 }
18026
18027 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18028
18029 uword
18030 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18031 {
18032   u32 *action = va_arg (*args, u32 *);
18033   u8 *s = 0;
18034
18035   if (unformat (input, "%s", &s))
18036     {
18037       if (!strcmp ((char *) s, "no-action"))
18038         action[0] = 0;
18039       else if (!strcmp ((char *) s, "natively-forward"))
18040         action[0] = 1;
18041       else if (!strcmp ((char *) s, "send-map-request"))
18042         action[0] = 2;
18043       else if (!strcmp ((char *) s, "drop"))
18044         action[0] = 3;
18045       else
18046         {
18047           clib_warning ("invalid action: '%s'", s);
18048           action[0] = 3;
18049         }
18050     }
18051   else
18052     return 0;
18053
18054   vec_free (s);
18055   return 1;
18056 }
18057
18058 /**
18059  * Add/del remote mapping to/from ONE control plane
18060  *
18061  * @param vam vpp API test context
18062  * @return return code
18063  */
18064 static int
18065 api_one_add_del_remote_mapping (vat_main_t * vam)
18066 {
18067   unformat_input_t *input = vam->input;
18068   vl_api_one_add_del_remote_mapping_t *mp;
18069   u32 vni = 0;
18070   lisp_eid_vat_t _eid, *eid = &_eid;
18071   lisp_eid_vat_t _seid, *seid = &_seid;
18072   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18073   u32 action = ~0, p, w, data_len;
18074   ip4_address_t rloc4;
18075   ip6_address_t rloc6;
18076   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18077   int ret;
18078
18079   clib_memset (&rloc, 0, sizeof (rloc));
18080
18081   /* Parse args required to build the message */
18082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18083     {
18084       if (unformat (input, "del-all"))
18085         {
18086           del_all = 1;
18087         }
18088       else if (unformat (input, "del"))
18089         {
18090           is_add = 0;
18091         }
18092       else if (unformat (input, "add"))
18093         {
18094           is_add = 1;
18095         }
18096       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18097         {
18098           eid_set = 1;
18099         }
18100       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18101         {
18102           seid_set = 1;
18103         }
18104       else if (unformat (input, "vni %d", &vni))
18105         {
18106           ;
18107         }
18108       else if (unformat (input, "p %d w %d", &p, &w))
18109         {
18110           if (!curr_rloc)
18111             {
18112               errmsg ("No RLOC configured for setting priority/weight!");
18113               return -99;
18114             }
18115           curr_rloc->priority = p;
18116           curr_rloc->weight = w;
18117         }
18118       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18119         {
18120           rloc.is_ip4 = 1;
18121           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18122           vec_add1 (rlocs, rloc);
18123           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18124         }
18125       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18126         {
18127           rloc.is_ip4 = 0;
18128           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18129           vec_add1 (rlocs, rloc);
18130           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18131         }
18132       else if (unformat (input, "action %U",
18133                          unformat_negative_mapping_action, &action))
18134         {
18135           ;
18136         }
18137       else
18138         {
18139           clib_warning ("parse error '%U'", format_unformat_error, input);
18140           return -99;
18141         }
18142     }
18143
18144   if (0 == eid_set)
18145     {
18146       errmsg ("missing params!");
18147       return -99;
18148     }
18149
18150   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18151     {
18152       errmsg ("no action set for negative map-reply!");
18153       return -99;
18154     }
18155
18156   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18157
18158   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18159   mp->is_add = is_add;
18160   mp->vni = htonl (vni);
18161   mp->action = (u8) action;
18162   mp->is_src_dst = seid_set;
18163   mp->eid_len = eid->len;
18164   mp->seid_len = seid->len;
18165   mp->del_all = del_all;
18166   mp->eid_type = eid->type;
18167   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18168   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18169
18170   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18171   clib_memcpy (mp->rlocs, rlocs, data_len);
18172   vec_free (rlocs);
18173
18174   /* send it... */
18175   S (mp);
18176
18177   /* Wait for a reply... */
18178   W (ret);
18179   return ret;
18180 }
18181
18182 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18183
18184 /**
18185  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18186  * forwarding entries in data-plane accordingly.
18187  *
18188  * @param vam vpp API test context
18189  * @return return code
18190  */
18191 static int
18192 api_one_add_del_adjacency (vat_main_t * vam)
18193 {
18194   unformat_input_t *input = vam->input;
18195   vl_api_one_add_del_adjacency_t *mp;
18196   u32 vni = 0;
18197   ip4_address_t leid4, reid4;
18198   ip6_address_t leid6, reid6;
18199   u8 reid_mac[6] = { 0 };
18200   u8 leid_mac[6] = { 0 };
18201   u8 reid_type, leid_type;
18202   u32 leid_len = 0, reid_len = 0, len;
18203   u8 is_add = 1;
18204   int ret;
18205
18206   leid_type = reid_type = (u8) ~ 0;
18207
18208   /* Parse args required to build the message */
18209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18210     {
18211       if (unformat (input, "del"))
18212         {
18213           is_add = 0;
18214         }
18215       else if (unformat (input, "add"))
18216         {
18217           is_add = 1;
18218         }
18219       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18220                          &reid4, &len))
18221         {
18222           reid_type = 0;        /* ipv4 */
18223           reid_len = len;
18224         }
18225       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18226                          &reid6, &len))
18227         {
18228           reid_type = 1;        /* ipv6 */
18229           reid_len = len;
18230         }
18231       else if (unformat (input, "reid %U", unformat_ethernet_address,
18232                          reid_mac))
18233         {
18234           reid_type = 2;        /* mac */
18235         }
18236       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18237                          &leid4, &len))
18238         {
18239           leid_type = 0;        /* ipv4 */
18240           leid_len = len;
18241         }
18242       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18243                          &leid6, &len))
18244         {
18245           leid_type = 1;        /* ipv6 */
18246           leid_len = len;
18247         }
18248       else if (unformat (input, "leid %U", unformat_ethernet_address,
18249                          leid_mac))
18250         {
18251           leid_type = 2;        /* mac */
18252         }
18253       else if (unformat (input, "vni %d", &vni))
18254         {
18255           ;
18256         }
18257       else
18258         {
18259           errmsg ("parse error '%U'", format_unformat_error, input);
18260           return -99;
18261         }
18262     }
18263
18264   if ((u8) ~ 0 == reid_type)
18265     {
18266       errmsg ("missing params!");
18267       return -99;
18268     }
18269
18270   if (leid_type != reid_type)
18271     {
18272       errmsg ("remote and local EIDs are of different types!");
18273       return -99;
18274     }
18275
18276   M (ONE_ADD_DEL_ADJACENCY, mp);
18277   mp->is_add = is_add;
18278   mp->vni = htonl (vni);
18279   mp->leid_len = leid_len;
18280   mp->reid_len = reid_len;
18281   mp->eid_type = reid_type;
18282
18283   switch (mp->eid_type)
18284     {
18285     case 0:
18286       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18287       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18288       break;
18289     case 1:
18290       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18291       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18292       break;
18293     case 2:
18294       clib_memcpy (mp->leid, leid_mac, 6);
18295       clib_memcpy (mp->reid, reid_mac, 6);
18296       break;
18297     default:
18298       errmsg ("unknown EID type %d!", mp->eid_type);
18299       return 0;
18300     }
18301
18302   /* send it... */
18303   S (mp);
18304
18305   /* Wait for a reply... */
18306   W (ret);
18307   return ret;
18308 }
18309
18310 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18311
18312 uword
18313 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18314 {
18315   u32 *mode = va_arg (*args, u32 *);
18316
18317   if (unformat (input, "lisp"))
18318     *mode = 0;
18319   else if (unformat (input, "vxlan"))
18320     *mode = 1;
18321   else
18322     return 0;
18323
18324   return 1;
18325 }
18326
18327 static int
18328 api_gpe_get_encap_mode (vat_main_t * vam)
18329 {
18330   vl_api_gpe_get_encap_mode_t *mp;
18331   int ret;
18332
18333   /* Construct the API message */
18334   M (GPE_GET_ENCAP_MODE, mp);
18335
18336   /* send it... */
18337   S (mp);
18338
18339   /* Wait for a reply... */
18340   W (ret);
18341   return ret;
18342 }
18343
18344 static int
18345 api_gpe_set_encap_mode (vat_main_t * vam)
18346 {
18347   unformat_input_t *input = vam->input;
18348   vl_api_gpe_set_encap_mode_t *mp;
18349   int ret;
18350   u32 mode = 0;
18351
18352   /* Parse args required to build the message */
18353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18354     {
18355       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18356         ;
18357       else
18358         break;
18359     }
18360
18361   /* Construct the API message */
18362   M (GPE_SET_ENCAP_MODE, mp);
18363
18364   mp->mode = mode;
18365
18366   /* send it... */
18367   S (mp);
18368
18369   /* Wait for a reply... */
18370   W (ret);
18371   return ret;
18372 }
18373
18374 static int
18375 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18376 {
18377   unformat_input_t *input = vam->input;
18378   vl_api_gpe_add_del_iface_t *mp;
18379   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18380   u32 dp_table = 0, vni = 0;
18381   int ret;
18382
18383   /* Parse args required to build the message */
18384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18385     {
18386       if (unformat (input, "up"))
18387         {
18388           action_set = 1;
18389           is_add = 1;
18390         }
18391       else if (unformat (input, "down"))
18392         {
18393           action_set = 1;
18394           is_add = 0;
18395         }
18396       else if (unformat (input, "table_id %d", &dp_table))
18397         {
18398           dp_table_set = 1;
18399         }
18400       else if (unformat (input, "bd_id %d", &dp_table))
18401         {
18402           dp_table_set = 1;
18403           is_l2 = 1;
18404         }
18405       else if (unformat (input, "vni %d", &vni))
18406         {
18407           vni_set = 1;
18408         }
18409       else
18410         break;
18411     }
18412
18413   if (action_set == 0)
18414     {
18415       errmsg ("Action not set");
18416       return -99;
18417     }
18418   if (dp_table_set == 0 || vni_set == 0)
18419     {
18420       errmsg ("vni and dp_table must be set");
18421       return -99;
18422     }
18423
18424   /* Construct the API message */
18425   M (GPE_ADD_DEL_IFACE, mp);
18426
18427   mp->is_add = is_add;
18428   mp->dp_table = clib_host_to_net_u32 (dp_table);
18429   mp->is_l2 = is_l2;
18430   mp->vni = clib_host_to_net_u32 (vni);
18431
18432   /* send it... */
18433   S (mp);
18434
18435   /* Wait for a reply... */
18436   W (ret);
18437   return ret;
18438 }
18439
18440 static int
18441 api_one_map_register_fallback_threshold (vat_main_t * vam)
18442 {
18443   unformat_input_t *input = vam->input;
18444   vl_api_one_map_register_fallback_threshold_t *mp;
18445   u32 value = 0;
18446   u8 is_set = 0;
18447   int ret;
18448
18449   /* Parse args required to build the message */
18450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18451     {
18452       if (unformat (input, "%u", &value))
18453         is_set = 1;
18454       else
18455         {
18456           clib_warning ("parse error '%U'", format_unformat_error, input);
18457           return -99;
18458         }
18459     }
18460
18461   if (!is_set)
18462     {
18463       errmsg ("fallback threshold value is missing!");
18464       return -99;
18465     }
18466
18467   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18468   mp->value = clib_host_to_net_u32 (value);
18469
18470   /* send it... */
18471   S (mp);
18472
18473   /* Wait for a reply... */
18474   W (ret);
18475   return ret;
18476 }
18477
18478 static int
18479 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18480 {
18481   vl_api_show_one_map_register_fallback_threshold_t *mp;
18482   int ret;
18483
18484   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18485
18486   /* send it... */
18487   S (mp);
18488
18489   /* Wait for a reply... */
18490   W (ret);
18491   return ret;
18492 }
18493
18494 uword
18495 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18496 {
18497   u32 *proto = va_arg (*args, u32 *);
18498
18499   if (unformat (input, "udp"))
18500     *proto = 1;
18501   else if (unformat (input, "api"))
18502     *proto = 2;
18503   else
18504     return 0;
18505
18506   return 1;
18507 }
18508
18509 static int
18510 api_one_set_transport_protocol (vat_main_t * vam)
18511 {
18512   unformat_input_t *input = vam->input;
18513   vl_api_one_set_transport_protocol_t *mp;
18514   u8 is_set = 0;
18515   u32 protocol = 0;
18516   int ret;
18517
18518   /* Parse args required to build the message */
18519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18520     {
18521       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18522         is_set = 1;
18523       else
18524         {
18525           clib_warning ("parse error '%U'", format_unformat_error, input);
18526           return -99;
18527         }
18528     }
18529
18530   if (!is_set)
18531     {
18532       errmsg ("Transport protocol missing!");
18533       return -99;
18534     }
18535
18536   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18537   mp->protocol = (u8) protocol;
18538
18539   /* send it... */
18540   S (mp);
18541
18542   /* Wait for a reply... */
18543   W (ret);
18544   return ret;
18545 }
18546
18547 static int
18548 api_one_get_transport_protocol (vat_main_t * vam)
18549 {
18550   vl_api_one_get_transport_protocol_t *mp;
18551   int ret;
18552
18553   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18554
18555   /* send it... */
18556   S (mp);
18557
18558   /* Wait for a reply... */
18559   W (ret);
18560   return ret;
18561 }
18562
18563 static int
18564 api_one_map_register_set_ttl (vat_main_t * vam)
18565 {
18566   unformat_input_t *input = vam->input;
18567   vl_api_one_map_register_set_ttl_t *mp;
18568   u32 ttl = 0;
18569   u8 is_set = 0;
18570   int ret;
18571
18572   /* Parse args required to build the message */
18573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18574     {
18575       if (unformat (input, "%u", &ttl))
18576         is_set = 1;
18577       else
18578         {
18579           clib_warning ("parse error '%U'", format_unformat_error, input);
18580           return -99;
18581         }
18582     }
18583
18584   if (!is_set)
18585     {
18586       errmsg ("TTL value missing!");
18587       return -99;
18588     }
18589
18590   M (ONE_MAP_REGISTER_SET_TTL, mp);
18591   mp->ttl = clib_host_to_net_u32 (ttl);
18592
18593   /* send it... */
18594   S (mp);
18595
18596   /* Wait for a reply... */
18597   W (ret);
18598   return ret;
18599 }
18600
18601 static int
18602 api_show_one_map_register_ttl (vat_main_t * vam)
18603 {
18604   vl_api_show_one_map_register_ttl_t *mp;
18605   int ret;
18606
18607   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18608
18609   /* send it... */
18610   S (mp);
18611
18612   /* Wait for a reply... */
18613   W (ret);
18614   return ret;
18615 }
18616
18617 /**
18618  * Add/del map request itr rlocs from ONE control plane and updates
18619  *
18620  * @param vam vpp API test context
18621  * @return return code
18622  */
18623 static int
18624 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18625 {
18626   unformat_input_t *input = vam->input;
18627   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18628   u8 *locator_set_name = 0;
18629   u8 locator_set_name_set = 0;
18630   u8 is_add = 1;
18631   int ret;
18632
18633   /* Parse args required to build the message */
18634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18635     {
18636       if (unformat (input, "del"))
18637         {
18638           is_add = 0;
18639         }
18640       else if (unformat (input, "%_%v%_", &locator_set_name))
18641         {
18642           locator_set_name_set = 1;
18643         }
18644       else
18645         {
18646           clib_warning ("parse error '%U'", format_unformat_error, input);
18647           return -99;
18648         }
18649     }
18650
18651   if (is_add && !locator_set_name_set)
18652     {
18653       errmsg ("itr-rloc is not set!");
18654       return -99;
18655     }
18656
18657   if (is_add && vec_len (locator_set_name) > 64)
18658     {
18659       errmsg ("itr-rloc locator-set name too long");
18660       vec_free (locator_set_name);
18661       return -99;
18662     }
18663
18664   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18665   mp->is_add = is_add;
18666   if (is_add)
18667     {
18668       clib_memcpy (mp->locator_set_name, locator_set_name,
18669                    vec_len (locator_set_name));
18670     }
18671   else
18672     {
18673       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18674     }
18675   vec_free (locator_set_name);
18676
18677   /* send it... */
18678   S (mp);
18679
18680   /* Wait for a reply... */
18681   W (ret);
18682   return ret;
18683 }
18684
18685 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18686
18687 static int
18688 api_one_locator_dump (vat_main_t * vam)
18689 {
18690   unformat_input_t *input = vam->input;
18691   vl_api_one_locator_dump_t *mp;
18692   vl_api_control_ping_t *mp_ping;
18693   u8 is_index_set = 0, is_name_set = 0;
18694   u8 *ls_name = 0;
18695   u32 ls_index = ~0;
18696   int ret;
18697
18698   /* Parse args required to build the message */
18699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18700     {
18701       if (unformat (input, "ls_name %_%v%_", &ls_name))
18702         {
18703           is_name_set = 1;
18704         }
18705       else if (unformat (input, "ls_index %d", &ls_index))
18706         {
18707           is_index_set = 1;
18708         }
18709       else
18710         {
18711           errmsg ("parse error '%U'", format_unformat_error, input);
18712           return -99;
18713         }
18714     }
18715
18716   if (!is_index_set && !is_name_set)
18717     {
18718       errmsg ("error: expected one of index or name!");
18719       return -99;
18720     }
18721
18722   if (is_index_set && is_name_set)
18723     {
18724       errmsg ("error: only one param expected!");
18725       return -99;
18726     }
18727
18728   if (vec_len (ls_name) > 62)
18729     {
18730       errmsg ("error: locator set name too long!");
18731       return -99;
18732     }
18733
18734   if (!vam->json_output)
18735     {
18736       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18737     }
18738
18739   M (ONE_LOCATOR_DUMP, mp);
18740   mp->is_index_set = is_index_set;
18741
18742   if (is_index_set)
18743     mp->ls_index = clib_host_to_net_u32 (ls_index);
18744   else
18745     {
18746       vec_add1 (ls_name, 0);
18747       strncpy ((char *) mp->ls_name, (char *) ls_name,
18748                sizeof (mp->ls_name) - 1);
18749     }
18750
18751   /* send it... */
18752   S (mp);
18753
18754   /* Use a control ping for synchronization */
18755   MPING (CONTROL_PING, mp_ping);
18756   S (mp_ping);
18757
18758   /* Wait for a reply... */
18759   W (ret);
18760   return ret;
18761 }
18762
18763 #define api_lisp_locator_dump api_one_locator_dump
18764
18765 static int
18766 api_one_locator_set_dump (vat_main_t * vam)
18767 {
18768   vl_api_one_locator_set_dump_t *mp;
18769   vl_api_control_ping_t *mp_ping;
18770   unformat_input_t *input = vam->input;
18771   u8 filter = 0;
18772   int ret;
18773
18774   /* Parse args required to build the message */
18775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18776     {
18777       if (unformat (input, "local"))
18778         {
18779           filter = 1;
18780         }
18781       else if (unformat (input, "remote"))
18782         {
18783           filter = 2;
18784         }
18785       else
18786         {
18787           errmsg ("parse error '%U'", format_unformat_error, input);
18788           return -99;
18789         }
18790     }
18791
18792   if (!vam->json_output)
18793     {
18794       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18795     }
18796
18797   M (ONE_LOCATOR_SET_DUMP, mp);
18798
18799   mp->filter = filter;
18800
18801   /* send it... */
18802   S (mp);
18803
18804   /* Use a control ping for synchronization */
18805   MPING (CONTROL_PING, mp_ping);
18806   S (mp_ping);
18807
18808   /* Wait for a reply... */
18809   W (ret);
18810   return ret;
18811 }
18812
18813 #define api_lisp_locator_set_dump api_one_locator_set_dump
18814
18815 static int
18816 api_one_eid_table_map_dump (vat_main_t * vam)
18817 {
18818   u8 is_l2 = 0;
18819   u8 mode_set = 0;
18820   unformat_input_t *input = vam->input;
18821   vl_api_one_eid_table_map_dump_t *mp;
18822   vl_api_control_ping_t *mp_ping;
18823   int ret;
18824
18825   /* Parse args required to build the message */
18826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18827     {
18828       if (unformat (input, "l2"))
18829         {
18830           is_l2 = 1;
18831           mode_set = 1;
18832         }
18833       else if (unformat (input, "l3"))
18834         {
18835           is_l2 = 0;
18836           mode_set = 1;
18837         }
18838       else
18839         {
18840           errmsg ("parse error '%U'", format_unformat_error, input);
18841           return -99;
18842         }
18843     }
18844
18845   if (!mode_set)
18846     {
18847       errmsg ("expected one of 'l2' or 'l3' parameter!");
18848       return -99;
18849     }
18850
18851   if (!vam->json_output)
18852     {
18853       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18854     }
18855
18856   M (ONE_EID_TABLE_MAP_DUMP, mp);
18857   mp->is_l2 = is_l2;
18858
18859   /* send it... */
18860   S (mp);
18861
18862   /* Use a control ping for synchronization */
18863   MPING (CONTROL_PING, mp_ping);
18864   S (mp_ping);
18865
18866   /* Wait for a reply... */
18867   W (ret);
18868   return ret;
18869 }
18870
18871 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18872
18873 static int
18874 api_one_eid_table_vni_dump (vat_main_t * vam)
18875 {
18876   vl_api_one_eid_table_vni_dump_t *mp;
18877   vl_api_control_ping_t *mp_ping;
18878   int ret;
18879
18880   if (!vam->json_output)
18881     {
18882       print (vam->ofp, "VNI");
18883     }
18884
18885   M (ONE_EID_TABLE_VNI_DUMP, mp);
18886
18887   /* send it... */
18888   S (mp);
18889
18890   /* Use a control ping for synchronization */
18891   MPING (CONTROL_PING, mp_ping);
18892   S (mp_ping);
18893
18894   /* Wait for a reply... */
18895   W (ret);
18896   return ret;
18897 }
18898
18899 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18900
18901 static int
18902 api_one_eid_table_dump (vat_main_t * vam)
18903 {
18904   unformat_input_t *i = vam->input;
18905   vl_api_one_eid_table_dump_t *mp;
18906   vl_api_control_ping_t *mp_ping;
18907   struct in_addr ip4;
18908   struct in6_addr ip6;
18909   u8 mac[6];
18910   u8 eid_type = ~0, eid_set = 0;
18911   u32 prefix_length = ~0, t, vni = 0;
18912   u8 filter = 0;
18913   int ret;
18914   lisp_nsh_api_t nsh;
18915
18916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18917     {
18918       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18919         {
18920           eid_set = 1;
18921           eid_type = 0;
18922           prefix_length = t;
18923         }
18924       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18925         {
18926           eid_set = 1;
18927           eid_type = 1;
18928           prefix_length = t;
18929         }
18930       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18931         {
18932           eid_set = 1;
18933           eid_type = 2;
18934         }
18935       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18936         {
18937           eid_set = 1;
18938           eid_type = 3;
18939         }
18940       else if (unformat (i, "vni %d", &t))
18941         {
18942           vni = t;
18943         }
18944       else if (unformat (i, "local"))
18945         {
18946           filter = 1;
18947         }
18948       else if (unformat (i, "remote"))
18949         {
18950           filter = 2;
18951         }
18952       else
18953         {
18954           errmsg ("parse error '%U'", format_unformat_error, i);
18955           return -99;
18956         }
18957     }
18958
18959   if (!vam->json_output)
18960     {
18961       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18962              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18963     }
18964
18965   M (ONE_EID_TABLE_DUMP, mp);
18966
18967   mp->filter = filter;
18968   if (eid_set)
18969     {
18970       mp->eid_set = 1;
18971       mp->vni = htonl (vni);
18972       mp->eid_type = eid_type;
18973       switch (eid_type)
18974         {
18975         case 0:
18976           mp->prefix_length = prefix_length;
18977           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18978           break;
18979         case 1:
18980           mp->prefix_length = prefix_length;
18981           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18982           break;
18983         case 2:
18984           clib_memcpy (mp->eid, mac, sizeof (mac));
18985           break;
18986         case 3:
18987           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18988           break;
18989         default:
18990           errmsg ("unknown EID type %d!", eid_type);
18991           return -99;
18992         }
18993     }
18994
18995   /* send it... */
18996   S (mp);
18997
18998   /* Use a control ping for synchronization */
18999   MPING (CONTROL_PING, mp_ping);
19000   S (mp_ping);
19001
19002   /* Wait for a reply... */
19003   W (ret);
19004   return ret;
19005 }
19006
19007 #define api_lisp_eid_table_dump api_one_eid_table_dump
19008
19009 static int
19010 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19011 {
19012   unformat_input_t *i = vam->input;
19013   vl_api_gpe_fwd_entries_get_t *mp;
19014   u8 vni_set = 0;
19015   u32 vni = ~0;
19016   int ret;
19017
19018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19019     {
19020       if (unformat (i, "vni %d", &vni))
19021         {
19022           vni_set = 1;
19023         }
19024       else
19025         {
19026           errmsg ("parse error '%U'", format_unformat_error, i);
19027           return -99;
19028         }
19029     }
19030
19031   if (!vni_set)
19032     {
19033       errmsg ("vni not set!");
19034       return -99;
19035     }
19036
19037   if (!vam->json_output)
19038     {
19039       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19040              "leid", "reid");
19041     }
19042
19043   M (GPE_FWD_ENTRIES_GET, mp);
19044   mp->vni = clib_host_to_net_u32 (vni);
19045
19046   /* send it... */
19047   S (mp);
19048
19049   /* Wait for a reply... */
19050   W (ret);
19051   return ret;
19052 }
19053
19054 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19055 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19056 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19057 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19058 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19059 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19060 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19061 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19062
19063 static int
19064 api_one_adjacencies_get (vat_main_t * vam)
19065 {
19066   unformat_input_t *i = vam->input;
19067   vl_api_one_adjacencies_get_t *mp;
19068   u8 vni_set = 0;
19069   u32 vni = ~0;
19070   int ret;
19071
19072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19073     {
19074       if (unformat (i, "vni %d", &vni))
19075         {
19076           vni_set = 1;
19077         }
19078       else
19079         {
19080           errmsg ("parse error '%U'", format_unformat_error, i);
19081           return -99;
19082         }
19083     }
19084
19085   if (!vni_set)
19086     {
19087       errmsg ("vni not set!");
19088       return -99;
19089     }
19090
19091   if (!vam->json_output)
19092     {
19093       print (vam->ofp, "%s %40s", "leid", "reid");
19094     }
19095
19096   M (ONE_ADJACENCIES_GET, mp);
19097   mp->vni = clib_host_to_net_u32 (vni);
19098
19099   /* send it... */
19100   S (mp);
19101
19102   /* Wait for a reply... */
19103   W (ret);
19104   return ret;
19105 }
19106
19107 #define api_lisp_adjacencies_get api_one_adjacencies_get
19108
19109 static int
19110 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19111 {
19112   unformat_input_t *i = vam->input;
19113   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19114   int ret;
19115   u8 ip_family_set = 0, is_ip4 = 1;
19116
19117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19118     {
19119       if (unformat (i, "ip4"))
19120         {
19121           ip_family_set = 1;
19122           is_ip4 = 1;
19123         }
19124       else if (unformat (i, "ip6"))
19125         {
19126           ip_family_set = 1;
19127           is_ip4 = 0;
19128         }
19129       else
19130         {
19131           errmsg ("parse error '%U'", format_unformat_error, i);
19132           return -99;
19133         }
19134     }
19135
19136   if (!ip_family_set)
19137     {
19138       errmsg ("ip family not set!");
19139       return -99;
19140     }
19141
19142   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19143   mp->is_ip4 = is_ip4;
19144
19145   /* send it... */
19146   S (mp);
19147
19148   /* Wait for a reply... */
19149   W (ret);
19150   return ret;
19151 }
19152
19153 static int
19154 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19155 {
19156   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19157   int ret;
19158
19159   if (!vam->json_output)
19160     {
19161       print (vam->ofp, "VNIs");
19162     }
19163
19164   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19165
19166   /* send it... */
19167   S (mp);
19168
19169   /* Wait for a reply... */
19170   W (ret);
19171   return ret;
19172 }
19173
19174 static int
19175 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19176 {
19177   unformat_input_t *i = vam->input;
19178   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19179   int ret = 0;
19180   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19181   struct in_addr ip4;
19182   struct in6_addr ip6;
19183   u32 table_id = 0, nh_sw_if_index = ~0;
19184
19185   clib_memset (&ip4, 0, sizeof (ip4));
19186   clib_memset (&ip6, 0, sizeof (ip6));
19187
19188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19189     {
19190       if (unformat (i, "del"))
19191         is_add = 0;
19192       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19193                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19194         {
19195           ip_set = 1;
19196           is_ip4 = 1;
19197         }
19198       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19199                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19200         {
19201           ip_set = 1;
19202           is_ip4 = 0;
19203         }
19204       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19205         {
19206           ip_set = 1;
19207           is_ip4 = 1;
19208           nh_sw_if_index = ~0;
19209         }
19210       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19211         {
19212           ip_set = 1;
19213           is_ip4 = 0;
19214           nh_sw_if_index = ~0;
19215         }
19216       else if (unformat (i, "table %d", &table_id))
19217         ;
19218       else
19219         {
19220           errmsg ("parse error '%U'", format_unformat_error, i);
19221           return -99;
19222         }
19223     }
19224
19225   if (!ip_set)
19226     {
19227       errmsg ("nh addr not set!");
19228       return -99;
19229     }
19230
19231   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19232   mp->is_add = is_add;
19233   mp->table_id = clib_host_to_net_u32 (table_id);
19234   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19235   mp->is_ip4 = is_ip4;
19236   if (is_ip4)
19237     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19238   else
19239     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19240
19241   /* send it... */
19242   S (mp);
19243
19244   /* Wait for a reply... */
19245   W (ret);
19246   return ret;
19247 }
19248
19249 static int
19250 api_one_map_server_dump (vat_main_t * vam)
19251 {
19252   vl_api_one_map_server_dump_t *mp;
19253   vl_api_control_ping_t *mp_ping;
19254   int ret;
19255
19256   if (!vam->json_output)
19257     {
19258       print (vam->ofp, "%=20s", "Map server");
19259     }
19260
19261   M (ONE_MAP_SERVER_DUMP, mp);
19262   /* send it... */
19263   S (mp);
19264
19265   /* Use a control ping for synchronization */
19266   MPING (CONTROL_PING, mp_ping);
19267   S (mp_ping);
19268
19269   /* Wait for a reply... */
19270   W (ret);
19271   return ret;
19272 }
19273
19274 #define api_lisp_map_server_dump api_one_map_server_dump
19275
19276 static int
19277 api_one_map_resolver_dump (vat_main_t * vam)
19278 {
19279   vl_api_one_map_resolver_dump_t *mp;
19280   vl_api_control_ping_t *mp_ping;
19281   int ret;
19282
19283   if (!vam->json_output)
19284     {
19285       print (vam->ofp, "%=20s", "Map resolver");
19286     }
19287
19288   M (ONE_MAP_RESOLVER_DUMP, mp);
19289   /* send it... */
19290   S (mp);
19291
19292   /* Use a control ping for synchronization */
19293   MPING (CONTROL_PING, mp_ping);
19294   S (mp_ping);
19295
19296   /* Wait for a reply... */
19297   W (ret);
19298   return ret;
19299 }
19300
19301 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19302
19303 static int
19304 api_one_stats_flush (vat_main_t * vam)
19305 {
19306   vl_api_one_stats_flush_t *mp;
19307   int ret = 0;
19308
19309   M (ONE_STATS_FLUSH, mp);
19310   S (mp);
19311   W (ret);
19312   return ret;
19313 }
19314
19315 static int
19316 api_one_stats_dump (vat_main_t * vam)
19317 {
19318   vl_api_one_stats_dump_t *mp;
19319   vl_api_control_ping_t *mp_ping;
19320   int ret;
19321
19322   M (ONE_STATS_DUMP, mp);
19323   /* send it... */
19324   S (mp);
19325
19326   /* Use a control ping for synchronization */
19327   MPING (CONTROL_PING, mp_ping);
19328   S (mp_ping);
19329
19330   /* Wait for a reply... */
19331   W (ret);
19332   return ret;
19333 }
19334
19335 static int
19336 api_show_one_status (vat_main_t * vam)
19337 {
19338   vl_api_show_one_status_t *mp;
19339   int ret;
19340
19341   if (!vam->json_output)
19342     {
19343       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19344     }
19345
19346   M (SHOW_ONE_STATUS, mp);
19347   /* send it... */
19348   S (mp);
19349   /* Wait for a reply... */
19350   W (ret);
19351   return ret;
19352 }
19353
19354 #define api_show_lisp_status api_show_one_status
19355
19356 static int
19357 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19358 {
19359   vl_api_gpe_fwd_entry_path_dump_t *mp;
19360   vl_api_control_ping_t *mp_ping;
19361   unformat_input_t *i = vam->input;
19362   u32 fwd_entry_index = ~0;
19363   int ret;
19364
19365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19366     {
19367       if (unformat (i, "index %d", &fwd_entry_index))
19368         ;
19369       else
19370         break;
19371     }
19372
19373   if (~0 == fwd_entry_index)
19374     {
19375       errmsg ("no index specified!");
19376       return -99;
19377     }
19378
19379   if (!vam->json_output)
19380     {
19381       print (vam->ofp, "first line");
19382     }
19383
19384   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19385
19386   /* send it... */
19387   S (mp);
19388   /* Use a control ping for synchronization */
19389   MPING (CONTROL_PING, mp_ping);
19390   S (mp_ping);
19391
19392   /* Wait for a reply... */
19393   W (ret);
19394   return ret;
19395 }
19396
19397 static int
19398 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19399 {
19400   vl_api_one_get_map_request_itr_rlocs_t *mp;
19401   int ret;
19402
19403   if (!vam->json_output)
19404     {
19405       print (vam->ofp, "%=20s", "itr-rlocs:");
19406     }
19407
19408   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19409   /* send it... */
19410   S (mp);
19411   /* Wait for a reply... */
19412   W (ret);
19413   return ret;
19414 }
19415
19416 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19417
19418 static int
19419 api_af_packet_create (vat_main_t * vam)
19420 {
19421   unformat_input_t *i = vam->input;
19422   vl_api_af_packet_create_t *mp;
19423   u8 *host_if_name = 0;
19424   u8 hw_addr[6];
19425   u8 random_hw_addr = 1;
19426   int ret;
19427
19428   clib_memset (hw_addr, 0, sizeof (hw_addr));
19429
19430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19431     {
19432       if (unformat (i, "name %s", &host_if_name))
19433         vec_add1 (host_if_name, 0);
19434       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19435         random_hw_addr = 0;
19436       else
19437         break;
19438     }
19439
19440   if (!vec_len (host_if_name))
19441     {
19442       errmsg ("host-interface name must be specified");
19443       return -99;
19444     }
19445
19446   if (vec_len (host_if_name) > 64)
19447     {
19448       errmsg ("host-interface name too long");
19449       return -99;
19450     }
19451
19452   M (AF_PACKET_CREATE, mp);
19453
19454   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19455   clib_memcpy (mp->hw_addr, hw_addr, 6);
19456   mp->use_random_hw_addr = random_hw_addr;
19457   vec_free (host_if_name);
19458
19459   S (mp);
19460
19461   /* *INDENT-OFF* */
19462   W2 (ret,
19463       ({
19464         if (ret == 0)
19465           fprintf (vam->ofp ? vam->ofp : stderr,
19466                    " new sw_if_index = %d\n", vam->sw_if_index);
19467       }));
19468   /* *INDENT-ON* */
19469   return ret;
19470 }
19471
19472 static int
19473 api_af_packet_delete (vat_main_t * vam)
19474 {
19475   unformat_input_t *i = vam->input;
19476   vl_api_af_packet_delete_t *mp;
19477   u8 *host_if_name = 0;
19478   int ret;
19479
19480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19481     {
19482       if (unformat (i, "name %s", &host_if_name))
19483         vec_add1 (host_if_name, 0);
19484       else
19485         break;
19486     }
19487
19488   if (!vec_len (host_if_name))
19489     {
19490       errmsg ("host-interface name must be specified");
19491       return -99;
19492     }
19493
19494   if (vec_len (host_if_name) > 64)
19495     {
19496       errmsg ("host-interface name too long");
19497       return -99;
19498     }
19499
19500   M (AF_PACKET_DELETE, mp);
19501
19502   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19503   vec_free (host_if_name);
19504
19505   S (mp);
19506   W (ret);
19507   return ret;
19508 }
19509
19510 static void vl_api_af_packet_details_t_handler
19511   (vl_api_af_packet_details_t * mp)
19512 {
19513   vat_main_t *vam = &vat_main;
19514
19515   print (vam->ofp, "%-16s %d",
19516          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19517 }
19518
19519 static void vl_api_af_packet_details_t_handler_json
19520   (vl_api_af_packet_details_t * mp)
19521 {
19522   vat_main_t *vam = &vat_main;
19523   vat_json_node_t *node = NULL;
19524
19525   if (VAT_JSON_ARRAY != vam->json_tree.type)
19526     {
19527       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19528       vat_json_init_array (&vam->json_tree);
19529     }
19530   node = vat_json_array_add (&vam->json_tree);
19531
19532   vat_json_init_object (node);
19533   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19534   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19535 }
19536
19537 static int
19538 api_af_packet_dump (vat_main_t * vam)
19539 {
19540   vl_api_af_packet_dump_t *mp;
19541   vl_api_control_ping_t *mp_ping;
19542   int ret;
19543
19544   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19545   /* Get list of tap interfaces */
19546   M (AF_PACKET_DUMP, mp);
19547   S (mp);
19548
19549   /* Use a control ping for synchronization */
19550   MPING (CONTROL_PING, mp_ping);
19551   S (mp_ping);
19552
19553   W (ret);
19554   return ret;
19555 }
19556
19557 static int
19558 api_policer_add_del (vat_main_t * vam)
19559 {
19560   unformat_input_t *i = vam->input;
19561   vl_api_policer_add_del_t *mp;
19562   u8 is_add = 1;
19563   u8 *name = 0;
19564   u32 cir = 0;
19565   u32 eir = 0;
19566   u64 cb = 0;
19567   u64 eb = 0;
19568   u8 rate_type = 0;
19569   u8 round_type = 0;
19570   u8 type = 0;
19571   u8 color_aware = 0;
19572   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19573   int ret;
19574
19575   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19576   conform_action.dscp = 0;
19577   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19578   exceed_action.dscp = 0;
19579   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19580   violate_action.dscp = 0;
19581
19582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19583     {
19584       if (unformat (i, "del"))
19585         is_add = 0;
19586       else if (unformat (i, "name %s", &name))
19587         vec_add1 (name, 0);
19588       else if (unformat (i, "cir %u", &cir))
19589         ;
19590       else if (unformat (i, "eir %u", &eir))
19591         ;
19592       else if (unformat (i, "cb %u", &cb))
19593         ;
19594       else if (unformat (i, "eb %u", &eb))
19595         ;
19596       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19597                          &rate_type))
19598         ;
19599       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19600                          &round_type))
19601         ;
19602       else if (unformat (i, "type %U", unformat_policer_type, &type))
19603         ;
19604       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19605                          &conform_action))
19606         ;
19607       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19608                          &exceed_action))
19609         ;
19610       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19611                          &violate_action))
19612         ;
19613       else if (unformat (i, "color-aware"))
19614         color_aware = 1;
19615       else
19616         break;
19617     }
19618
19619   if (!vec_len (name))
19620     {
19621       errmsg ("policer name must be specified");
19622       return -99;
19623     }
19624
19625   if (vec_len (name) > 64)
19626     {
19627       errmsg ("policer name too long");
19628       return -99;
19629     }
19630
19631   M (POLICER_ADD_DEL, mp);
19632
19633   clib_memcpy (mp->name, name, vec_len (name));
19634   vec_free (name);
19635   mp->is_add = is_add;
19636   mp->cir = ntohl (cir);
19637   mp->eir = ntohl (eir);
19638   mp->cb = clib_net_to_host_u64 (cb);
19639   mp->eb = clib_net_to_host_u64 (eb);
19640   mp->rate_type = rate_type;
19641   mp->round_type = round_type;
19642   mp->type = type;
19643   mp->conform_action_type = conform_action.action_type;
19644   mp->conform_dscp = conform_action.dscp;
19645   mp->exceed_action_type = exceed_action.action_type;
19646   mp->exceed_dscp = exceed_action.dscp;
19647   mp->violate_action_type = violate_action.action_type;
19648   mp->violate_dscp = violate_action.dscp;
19649   mp->color_aware = color_aware;
19650
19651   S (mp);
19652   W (ret);
19653   return ret;
19654 }
19655
19656 static int
19657 api_policer_dump (vat_main_t * vam)
19658 {
19659   unformat_input_t *i = vam->input;
19660   vl_api_policer_dump_t *mp;
19661   vl_api_control_ping_t *mp_ping;
19662   u8 *match_name = 0;
19663   u8 match_name_valid = 0;
19664   int ret;
19665
19666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19667     {
19668       if (unformat (i, "name %s", &match_name))
19669         {
19670           vec_add1 (match_name, 0);
19671           match_name_valid = 1;
19672         }
19673       else
19674         break;
19675     }
19676
19677   M (POLICER_DUMP, mp);
19678   mp->match_name_valid = match_name_valid;
19679   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19680   vec_free (match_name);
19681   /* send it... */
19682   S (mp);
19683
19684   /* Use a control ping for synchronization */
19685   MPING (CONTROL_PING, mp_ping);
19686   S (mp_ping);
19687
19688   /* Wait for a reply... */
19689   W (ret);
19690   return ret;
19691 }
19692
19693 static int
19694 api_policer_classify_set_interface (vat_main_t * vam)
19695 {
19696   unformat_input_t *i = vam->input;
19697   vl_api_policer_classify_set_interface_t *mp;
19698   u32 sw_if_index;
19699   int sw_if_index_set;
19700   u32 ip4_table_index = ~0;
19701   u32 ip6_table_index = ~0;
19702   u32 l2_table_index = ~0;
19703   u8 is_add = 1;
19704   int ret;
19705
19706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19707     {
19708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19709         sw_if_index_set = 1;
19710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19711         sw_if_index_set = 1;
19712       else if (unformat (i, "del"))
19713         is_add = 0;
19714       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19715         ;
19716       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19717         ;
19718       else if (unformat (i, "l2-table %d", &l2_table_index))
19719         ;
19720       else
19721         {
19722           clib_warning ("parse error '%U'", format_unformat_error, i);
19723           return -99;
19724         }
19725     }
19726
19727   if (sw_if_index_set == 0)
19728     {
19729       errmsg ("missing interface name or sw_if_index");
19730       return -99;
19731     }
19732
19733   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19734
19735   mp->sw_if_index = ntohl (sw_if_index);
19736   mp->ip4_table_index = ntohl (ip4_table_index);
19737   mp->ip6_table_index = ntohl (ip6_table_index);
19738   mp->l2_table_index = ntohl (l2_table_index);
19739   mp->is_add = is_add;
19740
19741   S (mp);
19742   W (ret);
19743   return ret;
19744 }
19745
19746 static int
19747 api_policer_classify_dump (vat_main_t * vam)
19748 {
19749   unformat_input_t *i = vam->input;
19750   vl_api_policer_classify_dump_t *mp;
19751   vl_api_control_ping_t *mp_ping;
19752   u8 type = POLICER_CLASSIFY_N_TABLES;
19753   int ret;
19754
19755   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19756     ;
19757   else
19758     {
19759       errmsg ("classify table type must be specified");
19760       return -99;
19761     }
19762
19763   if (!vam->json_output)
19764     {
19765       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19766     }
19767
19768   M (POLICER_CLASSIFY_DUMP, mp);
19769   mp->type = type;
19770   /* send it... */
19771   S (mp);
19772
19773   /* Use a control ping for synchronization */
19774   MPING (CONTROL_PING, mp_ping);
19775   S (mp_ping);
19776
19777   /* Wait for a reply... */
19778   W (ret);
19779   return ret;
19780 }
19781
19782 static int
19783 api_netmap_create (vat_main_t * vam)
19784 {
19785   unformat_input_t *i = vam->input;
19786   vl_api_netmap_create_t *mp;
19787   u8 *if_name = 0;
19788   u8 hw_addr[6];
19789   u8 random_hw_addr = 1;
19790   u8 is_pipe = 0;
19791   u8 is_master = 0;
19792   int ret;
19793
19794   clib_memset (hw_addr, 0, sizeof (hw_addr));
19795
19796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19797     {
19798       if (unformat (i, "name %s", &if_name))
19799         vec_add1 (if_name, 0);
19800       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19801         random_hw_addr = 0;
19802       else if (unformat (i, "pipe"))
19803         is_pipe = 1;
19804       else if (unformat (i, "master"))
19805         is_master = 1;
19806       else if (unformat (i, "slave"))
19807         is_master = 0;
19808       else
19809         break;
19810     }
19811
19812   if (!vec_len (if_name))
19813     {
19814       errmsg ("interface name must be specified");
19815       return -99;
19816     }
19817
19818   if (vec_len (if_name) > 64)
19819     {
19820       errmsg ("interface name too long");
19821       return -99;
19822     }
19823
19824   M (NETMAP_CREATE, mp);
19825
19826   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19827   clib_memcpy (mp->hw_addr, hw_addr, 6);
19828   mp->use_random_hw_addr = random_hw_addr;
19829   mp->is_pipe = is_pipe;
19830   mp->is_master = is_master;
19831   vec_free (if_name);
19832
19833   S (mp);
19834   W (ret);
19835   return ret;
19836 }
19837
19838 static int
19839 api_netmap_delete (vat_main_t * vam)
19840 {
19841   unformat_input_t *i = vam->input;
19842   vl_api_netmap_delete_t *mp;
19843   u8 *if_name = 0;
19844   int ret;
19845
19846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19847     {
19848       if (unformat (i, "name %s", &if_name))
19849         vec_add1 (if_name, 0);
19850       else
19851         break;
19852     }
19853
19854   if (!vec_len (if_name))
19855     {
19856       errmsg ("interface name must be specified");
19857       return -99;
19858     }
19859
19860   if (vec_len (if_name) > 64)
19861     {
19862       errmsg ("interface name too long");
19863       return -99;
19864     }
19865
19866   M (NETMAP_DELETE, mp);
19867
19868   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19869   vec_free (if_name);
19870
19871   S (mp);
19872   W (ret);
19873   return ret;
19874 }
19875
19876 static void
19877 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19878 {
19879   if (fp->afi == IP46_TYPE_IP6)
19880     print (vam->ofp,
19881            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19882            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19883            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19884            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19885            format_ip6_address, fp->next_hop);
19886   else if (fp->afi == IP46_TYPE_IP4)
19887     print (vam->ofp,
19888            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19889            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19890            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19891            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19892            format_ip4_address, fp->next_hop);
19893 }
19894
19895 static void
19896 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19897                                  vl_api_fib_path_t * fp)
19898 {
19899   struct in_addr ip4;
19900   struct in6_addr ip6;
19901
19902   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19903   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19904   vat_json_object_add_uint (node, "is_local", fp->is_local);
19905   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19906   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19907   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19908   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19909   if (fp->afi == IP46_TYPE_IP4)
19910     {
19911       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19912       vat_json_object_add_ip4 (node, "next_hop", ip4);
19913     }
19914   else if (fp->afi == IP46_TYPE_IP6)
19915     {
19916       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19917       vat_json_object_add_ip6 (node, "next_hop", ip6);
19918     }
19919 }
19920
19921 static void
19922 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19923 {
19924   vat_main_t *vam = &vat_main;
19925   int count = ntohl (mp->mt_count);
19926   vl_api_fib_path_t *fp;
19927   i32 i;
19928
19929   print (vam->ofp, "[%d]: sw_if_index %d via:",
19930          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19931   fp = mp->mt_paths;
19932   for (i = 0; i < count; i++)
19933     {
19934       vl_api_mpls_fib_path_print (vam, fp);
19935       fp++;
19936     }
19937
19938   print (vam->ofp, "");
19939 }
19940
19941 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19942 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19943
19944 static void
19945 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19946 {
19947   vat_main_t *vam = &vat_main;
19948   vat_json_node_t *node = NULL;
19949   int count = ntohl (mp->mt_count);
19950   vl_api_fib_path_t *fp;
19951   i32 i;
19952
19953   if (VAT_JSON_ARRAY != vam->json_tree.type)
19954     {
19955       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19956       vat_json_init_array (&vam->json_tree);
19957     }
19958   node = vat_json_array_add (&vam->json_tree);
19959
19960   vat_json_init_object (node);
19961   vat_json_object_add_uint (node, "tunnel_index",
19962                             ntohl (mp->mt_tunnel_index));
19963   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19964
19965   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19966
19967   fp = mp->mt_paths;
19968   for (i = 0; i < count; i++)
19969     {
19970       vl_api_mpls_fib_path_json_print (node, fp);
19971       fp++;
19972     }
19973 }
19974
19975 static int
19976 api_mpls_tunnel_dump (vat_main_t * vam)
19977 {
19978   vl_api_mpls_tunnel_dump_t *mp;
19979   vl_api_control_ping_t *mp_ping;
19980   u32 sw_if_index = ~0;
19981   int ret;
19982
19983   /* Parse args required to build the message */
19984   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19985     {
19986       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19987         ;
19988     }
19989
19990   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19991
19992   M (MPLS_TUNNEL_DUMP, mp);
19993   mp->sw_if_index = htonl (sw_if_index);
19994   S (mp);
19995
19996   /* Use a control ping for synchronization */
19997   MPING (CONTROL_PING, mp_ping);
19998   S (mp_ping);
19999
20000   W (ret);
20001   return ret;
20002 }
20003
20004 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20005 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20006
20007
20008 static void
20009 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20010 {
20011   vat_main_t *vam = &vat_main;
20012   int count = ntohl (mp->count);
20013   vl_api_fib_path_t *fp;
20014   int i;
20015
20016   print (vam->ofp,
20017          "table-id %d, label %u, ess_bit %u",
20018          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20019   fp = mp->path;
20020   for (i = 0; i < count; i++)
20021     {
20022       vl_api_mpls_fib_path_print (vam, fp);
20023       fp++;
20024     }
20025 }
20026
20027 static void vl_api_mpls_fib_details_t_handler_json
20028   (vl_api_mpls_fib_details_t * mp)
20029 {
20030   vat_main_t *vam = &vat_main;
20031   int count = ntohl (mp->count);
20032   vat_json_node_t *node = NULL;
20033   vl_api_fib_path_t *fp;
20034   int i;
20035
20036   if (VAT_JSON_ARRAY != vam->json_tree.type)
20037     {
20038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20039       vat_json_init_array (&vam->json_tree);
20040     }
20041   node = vat_json_array_add (&vam->json_tree);
20042
20043   vat_json_init_object (node);
20044   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20045   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20046   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20047   vat_json_object_add_uint (node, "path_count", count);
20048   fp = mp->path;
20049   for (i = 0; i < count; i++)
20050     {
20051       vl_api_mpls_fib_path_json_print (node, fp);
20052       fp++;
20053     }
20054 }
20055
20056 static int
20057 api_mpls_fib_dump (vat_main_t * vam)
20058 {
20059   vl_api_mpls_fib_dump_t *mp;
20060   vl_api_control_ping_t *mp_ping;
20061   int ret;
20062
20063   M (MPLS_FIB_DUMP, mp);
20064   S (mp);
20065
20066   /* Use a control ping for synchronization */
20067   MPING (CONTROL_PING, mp_ping);
20068   S (mp_ping);
20069
20070   W (ret);
20071   return ret;
20072 }
20073
20074 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20075 #define vl_api_ip_fib_details_t_print vl_noop_handler
20076
20077 static void
20078 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20079 {
20080   vat_main_t *vam = &vat_main;
20081   int count = ntohl (mp->count);
20082   vl_api_fib_path_t *fp;
20083   int i;
20084
20085   print (vam->ofp,
20086          "table-id %d, prefix %U/%d stats-index %d",
20087          ntohl (mp->table_id), format_ip4_address, mp->address,
20088          mp->address_length, ntohl (mp->stats_index));
20089   fp = mp->path;
20090   for (i = 0; i < count; i++)
20091     {
20092       if (fp->afi == IP46_TYPE_IP6)
20093         print (vam->ofp,
20094                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20095                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20096                "next_hop_table %d",
20097                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20098                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20099                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20100       else if (fp->afi == IP46_TYPE_IP4)
20101         print (vam->ofp,
20102                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20103                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20104                "next_hop_table %d",
20105                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20106                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20107                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20108       fp++;
20109     }
20110 }
20111
20112 static void vl_api_ip_fib_details_t_handler_json
20113   (vl_api_ip_fib_details_t * mp)
20114 {
20115   vat_main_t *vam = &vat_main;
20116   int count = ntohl (mp->count);
20117   vat_json_node_t *node = NULL;
20118   struct in_addr ip4;
20119   struct in6_addr ip6;
20120   vl_api_fib_path_t *fp;
20121   int i;
20122
20123   if (VAT_JSON_ARRAY != vam->json_tree.type)
20124     {
20125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20126       vat_json_init_array (&vam->json_tree);
20127     }
20128   node = vat_json_array_add (&vam->json_tree);
20129
20130   vat_json_init_object (node);
20131   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20132   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20133   vat_json_object_add_ip4 (node, "prefix", ip4);
20134   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20135   vat_json_object_add_uint (node, "path_count", count);
20136   fp = mp->path;
20137   for (i = 0; i < count; i++)
20138     {
20139       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20140       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20141       vat_json_object_add_uint (node, "is_local", fp->is_local);
20142       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20143       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20144       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20145       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20146       if (fp->afi == IP46_TYPE_IP4)
20147         {
20148           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20149           vat_json_object_add_ip4 (node, "next_hop", ip4);
20150         }
20151       else if (fp->afi == IP46_TYPE_IP6)
20152         {
20153           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20154           vat_json_object_add_ip6 (node, "next_hop", ip6);
20155         }
20156     }
20157 }
20158
20159 static int
20160 api_ip_fib_dump (vat_main_t * vam)
20161 {
20162   vl_api_ip_fib_dump_t *mp;
20163   vl_api_control_ping_t *mp_ping;
20164   int ret;
20165
20166   M (IP_FIB_DUMP, mp);
20167   S (mp);
20168
20169   /* Use a control ping for synchronization */
20170   MPING (CONTROL_PING, mp_ping);
20171   S (mp_ping);
20172
20173   W (ret);
20174   return ret;
20175 }
20176
20177 static int
20178 api_ip_mfib_dump (vat_main_t * vam)
20179 {
20180   vl_api_ip_mfib_dump_t *mp;
20181   vl_api_control_ping_t *mp_ping;
20182   int ret;
20183
20184   M (IP_MFIB_DUMP, mp);
20185   S (mp);
20186
20187   /* Use a control ping for synchronization */
20188   MPING (CONTROL_PING, mp_ping);
20189   S (mp_ping);
20190
20191   W (ret);
20192   return ret;
20193 }
20194
20195 static void vl_api_ip_neighbor_details_t_handler
20196   (vl_api_ip_neighbor_details_t * mp)
20197 {
20198   vat_main_t *vam = &vat_main;
20199
20200   print (vam->ofp, "%c %U %U",
20201          (mp->is_static) ? 'S' : 'D',
20202          format_ethernet_address, &mp->mac_address,
20203          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20204          &mp->ip_address);
20205 }
20206
20207 static void vl_api_ip_neighbor_details_t_handler_json
20208   (vl_api_ip_neighbor_details_t * mp)
20209 {
20210
20211   vat_main_t *vam = &vat_main;
20212   vat_json_node_t *node;
20213   struct in_addr ip4;
20214   struct in6_addr ip6;
20215
20216   if (VAT_JSON_ARRAY != vam->json_tree.type)
20217     {
20218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20219       vat_json_init_array (&vam->json_tree);
20220     }
20221   node = vat_json_array_add (&vam->json_tree);
20222
20223   vat_json_init_object (node);
20224   vat_json_object_add_string_copy (node, "flag",
20225                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20226                                    "dynamic");
20227
20228   vat_json_object_add_string_copy (node, "link_layer",
20229                                    format (0, "%U", format_ethernet_address,
20230                                            &mp->mac_address));
20231
20232   if (mp->is_ipv6)
20233     {
20234       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20235       vat_json_object_add_ip6 (node, "ip_address", ip6);
20236     }
20237   else
20238     {
20239       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20240       vat_json_object_add_ip4 (node, "ip_address", ip4);
20241     }
20242 }
20243
20244 static int
20245 api_ip_neighbor_dump (vat_main_t * vam)
20246 {
20247   unformat_input_t *i = vam->input;
20248   vl_api_ip_neighbor_dump_t *mp;
20249   vl_api_control_ping_t *mp_ping;
20250   u8 is_ipv6 = 0;
20251   u32 sw_if_index = ~0;
20252   int ret;
20253
20254   /* Parse args required to build the message */
20255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20256     {
20257       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20258         ;
20259       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20260         ;
20261       else if (unformat (i, "ip6"))
20262         is_ipv6 = 1;
20263       else
20264         break;
20265     }
20266
20267   if (sw_if_index == ~0)
20268     {
20269       errmsg ("missing interface name or sw_if_index");
20270       return -99;
20271     }
20272
20273   M (IP_NEIGHBOR_DUMP, mp);
20274   mp->is_ipv6 = (u8) is_ipv6;
20275   mp->sw_if_index = ntohl (sw_if_index);
20276   S (mp);
20277
20278   /* Use a control ping for synchronization */
20279   MPING (CONTROL_PING, mp_ping);
20280   S (mp_ping);
20281
20282   W (ret);
20283   return ret;
20284 }
20285
20286 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20287 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20288
20289 static void
20290 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20291 {
20292   vat_main_t *vam = &vat_main;
20293   int count = ntohl (mp->count);
20294   vl_api_fib_path_t *fp;
20295   int i;
20296
20297   print (vam->ofp,
20298          "table-id %d, prefix %U/%d stats-index %d",
20299          ntohl (mp->table_id), format_ip6_address, mp->address,
20300          mp->address_length, ntohl (mp->stats_index));
20301   fp = mp->path;
20302   for (i = 0; i < count; i++)
20303     {
20304       if (fp->afi == IP46_TYPE_IP6)
20305         print (vam->ofp,
20306                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20307                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20308                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20309                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20310                format_ip6_address, fp->next_hop);
20311       else if (fp->afi == IP46_TYPE_IP4)
20312         print (vam->ofp,
20313                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20314                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20315                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20316                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20317                format_ip4_address, fp->next_hop);
20318       fp++;
20319     }
20320 }
20321
20322 static void vl_api_ip6_fib_details_t_handler_json
20323   (vl_api_ip6_fib_details_t * mp)
20324 {
20325   vat_main_t *vam = &vat_main;
20326   int count = ntohl (mp->count);
20327   vat_json_node_t *node = NULL;
20328   struct in_addr ip4;
20329   struct in6_addr ip6;
20330   vl_api_fib_path_t *fp;
20331   int i;
20332
20333   if (VAT_JSON_ARRAY != vam->json_tree.type)
20334     {
20335       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20336       vat_json_init_array (&vam->json_tree);
20337     }
20338   node = vat_json_array_add (&vam->json_tree);
20339
20340   vat_json_init_object (node);
20341   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20342   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20343   vat_json_object_add_ip6 (node, "prefix", ip6);
20344   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20345   vat_json_object_add_uint (node, "path_count", count);
20346   fp = mp->path;
20347   for (i = 0; i < count; i++)
20348     {
20349       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20350       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20351       vat_json_object_add_uint (node, "is_local", fp->is_local);
20352       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20353       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20354       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20355       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20356       if (fp->afi == IP46_TYPE_IP4)
20357         {
20358           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20359           vat_json_object_add_ip4 (node, "next_hop", ip4);
20360         }
20361       else if (fp->afi == IP46_TYPE_IP6)
20362         {
20363           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20364           vat_json_object_add_ip6 (node, "next_hop", ip6);
20365         }
20366     }
20367 }
20368
20369 static int
20370 api_ip6_fib_dump (vat_main_t * vam)
20371 {
20372   vl_api_ip6_fib_dump_t *mp;
20373   vl_api_control_ping_t *mp_ping;
20374   int ret;
20375
20376   M (IP6_FIB_DUMP, mp);
20377   S (mp);
20378
20379   /* Use a control ping for synchronization */
20380   MPING (CONTROL_PING, mp_ping);
20381   S (mp_ping);
20382
20383   W (ret);
20384   return ret;
20385 }
20386
20387 static int
20388 api_ip6_mfib_dump (vat_main_t * vam)
20389 {
20390   vl_api_ip6_mfib_dump_t *mp;
20391   vl_api_control_ping_t *mp_ping;
20392   int ret;
20393
20394   M (IP6_MFIB_DUMP, mp);
20395   S (mp);
20396
20397   /* Use a control ping for synchronization */
20398   MPING (CONTROL_PING, mp_ping);
20399   S (mp_ping);
20400
20401   W (ret);
20402   return ret;
20403 }
20404
20405 int
20406 api_classify_table_ids (vat_main_t * vam)
20407 {
20408   vl_api_classify_table_ids_t *mp;
20409   int ret;
20410
20411   /* Construct the API message */
20412   M (CLASSIFY_TABLE_IDS, mp);
20413   mp->context = 0;
20414
20415   S (mp);
20416   W (ret);
20417   return ret;
20418 }
20419
20420 int
20421 api_classify_table_by_interface (vat_main_t * vam)
20422 {
20423   unformat_input_t *input = vam->input;
20424   vl_api_classify_table_by_interface_t *mp;
20425
20426   u32 sw_if_index = ~0;
20427   int ret;
20428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20429     {
20430       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20431         ;
20432       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20433         ;
20434       else
20435         break;
20436     }
20437   if (sw_if_index == ~0)
20438     {
20439       errmsg ("missing interface name or sw_if_index");
20440       return -99;
20441     }
20442
20443   /* Construct the API message */
20444   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20445   mp->context = 0;
20446   mp->sw_if_index = ntohl (sw_if_index);
20447
20448   S (mp);
20449   W (ret);
20450   return ret;
20451 }
20452
20453 int
20454 api_classify_table_info (vat_main_t * vam)
20455 {
20456   unformat_input_t *input = vam->input;
20457   vl_api_classify_table_info_t *mp;
20458
20459   u32 table_id = ~0;
20460   int ret;
20461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20462     {
20463       if (unformat (input, "table_id %d", &table_id))
20464         ;
20465       else
20466         break;
20467     }
20468   if (table_id == ~0)
20469     {
20470       errmsg ("missing table id");
20471       return -99;
20472     }
20473
20474   /* Construct the API message */
20475   M (CLASSIFY_TABLE_INFO, mp);
20476   mp->context = 0;
20477   mp->table_id = ntohl (table_id);
20478
20479   S (mp);
20480   W (ret);
20481   return ret;
20482 }
20483
20484 int
20485 api_classify_session_dump (vat_main_t * vam)
20486 {
20487   unformat_input_t *input = vam->input;
20488   vl_api_classify_session_dump_t *mp;
20489   vl_api_control_ping_t *mp_ping;
20490
20491   u32 table_id = ~0;
20492   int ret;
20493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20494     {
20495       if (unformat (input, "table_id %d", &table_id))
20496         ;
20497       else
20498         break;
20499     }
20500   if (table_id == ~0)
20501     {
20502       errmsg ("missing table id");
20503       return -99;
20504     }
20505
20506   /* Construct the API message */
20507   M (CLASSIFY_SESSION_DUMP, mp);
20508   mp->context = 0;
20509   mp->table_id = ntohl (table_id);
20510   S (mp);
20511
20512   /* Use a control ping for synchronization */
20513   MPING (CONTROL_PING, mp_ping);
20514   S (mp_ping);
20515
20516   W (ret);
20517   return ret;
20518 }
20519
20520 static void
20521 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20522 {
20523   vat_main_t *vam = &vat_main;
20524
20525   print (vam->ofp, "collector_address %U, collector_port %d, "
20526          "src_address %U, vrf_id %d, path_mtu %u, "
20527          "template_interval %u, udp_checksum %d",
20528          format_ip4_address, mp->collector_address,
20529          ntohs (mp->collector_port),
20530          format_ip4_address, mp->src_address,
20531          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20532          ntohl (mp->template_interval), mp->udp_checksum);
20533
20534   vam->retval = 0;
20535   vam->result_ready = 1;
20536 }
20537
20538 static void
20539   vl_api_ipfix_exporter_details_t_handler_json
20540   (vl_api_ipfix_exporter_details_t * mp)
20541 {
20542   vat_main_t *vam = &vat_main;
20543   vat_json_node_t node;
20544   struct in_addr collector_address;
20545   struct in_addr src_address;
20546
20547   vat_json_init_object (&node);
20548   clib_memcpy (&collector_address, &mp->collector_address,
20549                sizeof (collector_address));
20550   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20551   vat_json_object_add_uint (&node, "collector_port",
20552                             ntohs (mp->collector_port));
20553   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20554   vat_json_object_add_ip4 (&node, "src_address", src_address);
20555   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20556   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20557   vat_json_object_add_uint (&node, "template_interval",
20558                             ntohl (mp->template_interval));
20559   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20560
20561   vat_json_print (vam->ofp, &node);
20562   vat_json_free (&node);
20563   vam->retval = 0;
20564   vam->result_ready = 1;
20565 }
20566
20567 int
20568 api_ipfix_exporter_dump (vat_main_t * vam)
20569 {
20570   vl_api_ipfix_exporter_dump_t *mp;
20571   int ret;
20572
20573   /* Construct the API message */
20574   M (IPFIX_EXPORTER_DUMP, mp);
20575   mp->context = 0;
20576
20577   S (mp);
20578   W (ret);
20579   return ret;
20580 }
20581
20582 static int
20583 api_ipfix_classify_stream_dump (vat_main_t * vam)
20584 {
20585   vl_api_ipfix_classify_stream_dump_t *mp;
20586   int ret;
20587
20588   /* Construct the API message */
20589   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20590   mp->context = 0;
20591
20592   S (mp);
20593   W (ret);
20594   return ret;
20595   /* NOTREACHED */
20596   return 0;
20597 }
20598
20599 static void
20600   vl_api_ipfix_classify_stream_details_t_handler
20601   (vl_api_ipfix_classify_stream_details_t * mp)
20602 {
20603   vat_main_t *vam = &vat_main;
20604   print (vam->ofp, "domain_id %d, src_port %d",
20605          ntohl (mp->domain_id), ntohs (mp->src_port));
20606   vam->retval = 0;
20607   vam->result_ready = 1;
20608 }
20609
20610 static void
20611   vl_api_ipfix_classify_stream_details_t_handler_json
20612   (vl_api_ipfix_classify_stream_details_t * mp)
20613 {
20614   vat_main_t *vam = &vat_main;
20615   vat_json_node_t node;
20616
20617   vat_json_init_object (&node);
20618   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20619   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20620
20621   vat_json_print (vam->ofp, &node);
20622   vat_json_free (&node);
20623   vam->retval = 0;
20624   vam->result_ready = 1;
20625 }
20626
20627 static int
20628 api_ipfix_classify_table_dump (vat_main_t * vam)
20629 {
20630   vl_api_ipfix_classify_table_dump_t *mp;
20631   vl_api_control_ping_t *mp_ping;
20632   int ret;
20633
20634   if (!vam->json_output)
20635     {
20636       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20637              "transport_protocol");
20638     }
20639
20640   /* Construct the API message */
20641   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20642
20643   /* send it... */
20644   S (mp);
20645
20646   /* Use a control ping for synchronization */
20647   MPING (CONTROL_PING, mp_ping);
20648   S (mp_ping);
20649
20650   W (ret);
20651   return ret;
20652 }
20653
20654 static void
20655   vl_api_ipfix_classify_table_details_t_handler
20656   (vl_api_ipfix_classify_table_details_t * mp)
20657 {
20658   vat_main_t *vam = &vat_main;
20659   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20660          mp->transport_protocol);
20661 }
20662
20663 static void
20664   vl_api_ipfix_classify_table_details_t_handler_json
20665   (vl_api_ipfix_classify_table_details_t * mp)
20666 {
20667   vat_json_node_t *node = NULL;
20668   vat_main_t *vam = &vat_main;
20669
20670   if (VAT_JSON_ARRAY != vam->json_tree.type)
20671     {
20672       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20673       vat_json_init_array (&vam->json_tree);
20674     }
20675
20676   node = vat_json_array_add (&vam->json_tree);
20677   vat_json_init_object (node);
20678
20679   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20680   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20681   vat_json_object_add_uint (node, "transport_protocol",
20682                             mp->transport_protocol);
20683 }
20684
20685 static int
20686 api_sw_interface_span_enable_disable (vat_main_t * vam)
20687 {
20688   unformat_input_t *i = vam->input;
20689   vl_api_sw_interface_span_enable_disable_t *mp;
20690   u32 src_sw_if_index = ~0;
20691   u32 dst_sw_if_index = ~0;
20692   u8 state = 3;
20693   int ret;
20694   u8 is_l2 = 0;
20695
20696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20697     {
20698       if (unformat
20699           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20700         ;
20701       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20702         ;
20703       else
20704         if (unformat
20705             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20706         ;
20707       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20708         ;
20709       else if (unformat (i, "disable"))
20710         state = 0;
20711       else if (unformat (i, "rx"))
20712         state = 1;
20713       else if (unformat (i, "tx"))
20714         state = 2;
20715       else if (unformat (i, "both"))
20716         state = 3;
20717       else if (unformat (i, "l2"))
20718         is_l2 = 1;
20719       else
20720         break;
20721     }
20722
20723   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20724
20725   mp->sw_if_index_from = htonl (src_sw_if_index);
20726   mp->sw_if_index_to = htonl (dst_sw_if_index);
20727   mp->state = state;
20728   mp->is_l2 = is_l2;
20729
20730   S (mp);
20731   W (ret);
20732   return ret;
20733 }
20734
20735 static void
20736 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20737                                             * mp)
20738 {
20739   vat_main_t *vam = &vat_main;
20740   u8 *sw_if_from_name = 0;
20741   u8 *sw_if_to_name = 0;
20742   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20743   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20744   char *states[] = { "none", "rx", "tx", "both" };
20745   hash_pair_t *p;
20746
20747   /* *INDENT-OFF* */
20748   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20749   ({
20750     if ((u32) p->value[0] == sw_if_index_from)
20751       {
20752         sw_if_from_name = (u8 *)(p->key);
20753         if (sw_if_to_name)
20754           break;
20755       }
20756     if ((u32) p->value[0] == sw_if_index_to)
20757       {
20758         sw_if_to_name = (u8 *)(p->key);
20759         if (sw_if_from_name)
20760           break;
20761       }
20762   }));
20763   /* *INDENT-ON* */
20764   print (vam->ofp, "%20s => %20s (%s) %s",
20765          sw_if_from_name, sw_if_to_name, states[mp->state],
20766          mp->is_l2 ? "l2" : "device");
20767 }
20768
20769 static void
20770   vl_api_sw_interface_span_details_t_handler_json
20771   (vl_api_sw_interface_span_details_t * mp)
20772 {
20773   vat_main_t *vam = &vat_main;
20774   vat_json_node_t *node = NULL;
20775   u8 *sw_if_from_name = 0;
20776   u8 *sw_if_to_name = 0;
20777   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20778   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20779   hash_pair_t *p;
20780
20781   /* *INDENT-OFF* */
20782   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20783   ({
20784     if ((u32) p->value[0] == sw_if_index_from)
20785       {
20786         sw_if_from_name = (u8 *)(p->key);
20787         if (sw_if_to_name)
20788           break;
20789       }
20790     if ((u32) p->value[0] == sw_if_index_to)
20791       {
20792         sw_if_to_name = (u8 *)(p->key);
20793         if (sw_if_from_name)
20794           break;
20795       }
20796   }));
20797   /* *INDENT-ON* */
20798
20799   if (VAT_JSON_ARRAY != vam->json_tree.type)
20800     {
20801       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20802       vat_json_init_array (&vam->json_tree);
20803     }
20804   node = vat_json_array_add (&vam->json_tree);
20805
20806   vat_json_init_object (node);
20807   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20808   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20809   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20810   if (0 != sw_if_to_name)
20811     {
20812       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20813     }
20814   vat_json_object_add_uint (node, "state", mp->state);
20815   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20816 }
20817
20818 static int
20819 api_sw_interface_span_dump (vat_main_t * vam)
20820 {
20821   unformat_input_t *input = vam->input;
20822   vl_api_sw_interface_span_dump_t *mp;
20823   vl_api_control_ping_t *mp_ping;
20824   u8 is_l2 = 0;
20825   int ret;
20826
20827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20828     {
20829       if (unformat (input, "l2"))
20830         is_l2 = 1;
20831       else
20832         break;
20833     }
20834
20835   M (SW_INTERFACE_SPAN_DUMP, mp);
20836   mp->is_l2 = is_l2;
20837   S (mp);
20838
20839   /* Use a control ping for synchronization */
20840   MPING (CONTROL_PING, mp_ping);
20841   S (mp_ping);
20842
20843   W (ret);
20844   return ret;
20845 }
20846
20847 int
20848 api_pg_create_interface (vat_main_t * vam)
20849 {
20850   unformat_input_t *input = vam->input;
20851   vl_api_pg_create_interface_t *mp;
20852
20853   u32 if_id = ~0;
20854   int ret;
20855   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20856     {
20857       if (unformat (input, "if_id %d", &if_id))
20858         ;
20859       else
20860         break;
20861     }
20862   if (if_id == ~0)
20863     {
20864       errmsg ("missing pg interface index");
20865       return -99;
20866     }
20867
20868   /* Construct the API message */
20869   M (PG_CREATE_INTERFACE, mp);
20870   mp->context = 0;
20871   mp->interface_id = ntohl (if_id);
20872
20873   S (mp);
20874   W (ret);
20875   return ret;
20876 }
20877
20878 int
20879 api_pg_capture (vat_main_t * vam)
20880 {
20881   unformat_input_t *input = vam->input;
20882   vl_api_pg_capture_t *mp;
20883
20884   u32 if_id = ~0;
20885   u8 enable = 1;
20886   u32 count = 1;
20887   u8 pcap_file_set = 0;
20888   u8 *pcap_file = 0;
20889   int ret;
20890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20891     {
20892       if (unformat (input, "if_id %d", &if_id))
20893         ;
20894       else if (unformat (input, "pcap %s", &pcap_file))
20895         pcap_file_set = 1;
20896       else if (unformat (input, "count %d", &count))
20897         ;
20898       else if (unformat (input, "disable"))
20899         enable = 0;
20900       else
20901         break;
20902     }
20903   if (if_id == ~0)
20904     {
20905       errmsg ("missing pg interface index");
20906       return -99;
20907     }
20908   if (pcap_file_set > 0)
20909     {
20910       if (vec_len (pcap_file) > 255)
20911         {
20912           errmsg ("pcap file name is too long");
20913           return -99;
20914         }
20915     }
20916
20917   u32 name_len = vec_len (pcap_file);
20918   /* Construct the API message */
20919   M (PG_CAPTURE, mp);
20920   mp->context = 0;
20921   mp->interface_id = ntohl (if_id);
20922   mp->is_enabled = enable;
20923   mp->count = ntohl (count);
20924   mp->pcap_name_length = ntohl (name_len);
20925   if (pcap_file_set != 0)
20926     {
20927       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20928     }
20929   vec_free (pcap_file);
20930
20931   S (mp);
20932   W (ret);
20933   return ret;
20934 }
20935
20936 int
20937 api_pg_enable_disable (vat_main_t * vam)
20938 {
20939   unformat_input_t *input = vam->input;
20940   vl_api_pg_enable_disable_t *mp;
20941
20942   u8 enable = 1;
20943   u8 stream_name_set = 0;
20944   u8 *stream_name = 0;
20945   int ret;
20946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20947     {
20948       if (unformat (input, "stream %s", &stream_name))
20949         stream_name_set = 1;
20950       else if (unformat (input, "disable"))
20951         enable = 0;
20952       else
20953         break;
20954     }
20955
20956   if (stream_name_set > 0)
20957     {
20958       if (vec_len (stream_name) > 255)
20959         {
20960           errmsg ("stream name too long");
20961           return -99;
20962         }
20963     }
20964
20965   u32 name_len = vec_len (stream_name);
20966   /* Construct the API message */
20967   M (PG_ENABLE_DISABLE, mp);
20968   mp->context = 0;
20969   mp->is_enabled = enable;
20970   if (stream_name_set != 0)
20971     {
20972       mp->stream_name_length = ntohl (name_len);
20973       clib_memcpy (mp->stream_name, stream_name, name_len);
20974     }
20975   vec_free (stream_name);
20976
20977   S (mp);
20978   W (ret);
20979   return ret;
20980 }
20981
20982 int
20983 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20984 {
20985   unformat_input_t *input = vam->input;
20986   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20987
20988   u16 *low_ports = 0;
20989   u16 *high_ports = 0;
20990   u16 this_low;
20991   u16 this_hi;
20992   ip4_address_t ip4_addr;
20993   ip6_address_t ip6_addr;
20994   u32 length;
20995   u32 tmp, tmp2;
20996   u8 prefix_set = 0;
20997   u32 vrf_id = ~0;
20998   u8 is_add = 1;
20999   u8 is_ipv6 = 0;
21000   int ret;
21001
21002   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21003     {
21004       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21005         {
21006           prefix_set = 1;
21007         }
21008       else
21009         if (unformat
21010             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21011         {
21012           prefix_set = 1;
21013           is_ipv6 = 1;
21014         }
21015       else if (unformat (input, "vrf %d", &vrf_id))
21016         ;
21017       else if (unformat (input, "del"))
21018         is_add = 0;
21019       else if (unformat (input, "port %d", &tmp))
21020         {
21021           if (tmp == 0 || tmp > 65535)
21022             {
21023               errmsg ("port %d out of range", tmp);
21024               return -99;
21025             }
21026           this_low = tmp;
21027           this_hi = this_low + 1;
21028           vec_add1 (low_ports, this_low);
21029           vec_add1 (high_ports, this_hi);
21030         }
21031       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21032         {
21033           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21034             {
21035               errmsg ("incorrect range parameters");
21036               return -99;
21037             }
21038           this_low = tmp;
21039           /* Note: in debug CLI +1 is added to high before
21040              passing to real fn that does "the work"
21041              (ip_source_and_port_range_check_add_del).
21042              This fn is a wrapper around the binary API fn a
21043              control plane will call, which expects this increment
21044              to have occurred. Hence letting the binary API control
21045              plane fn do the increment for consistency between VAT
21046              and other control planes.
21047            */
21048           this_hi = tmp2;
21049           vec_add1 (low_ports, this_low);
21050           vec_add1 (high_ports, this_hi);
21051         }
21052       else
21053         break;
21054     }
21055
21056   if (prefix_set == 0)
21057     {
21058       errmsg ("<address>/<mask> not specified");
21059       return -99;
21060     }
21061
21062   if (vrf_id == ~0)
21063     {
21064       errmsg ("VRF ID required, not specified");
21065       return -99;
21066     }
21067
21068   if (vrf_id == 0)
21069     {
21070       errmsg
21071         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21072       return -99;
21073     }
21074
21075   if (vec_len (low_ports) == 0)
21076     {
21077       errmsg ("At least one port or port range required");
21078       return -99;
21079     }
21080
21081   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21082
21083   mp->is_add = is_add;
21084
21085   if (is_ipv6)
21086     {
21087       mp->is_ipv6 = 1;
21088       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21089     }
21090   else
21091     {
21092       mp->is_ipv6 = 0;
21093       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21094     }
21095
21096   mp->mask_length = length;
21097   mp->number_of_ranges = vec_len (low_ports);
21098
21099   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21100   vec_free (low_ports);
21101
21102   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21103   vec_free (high_ports);
21104
21105   mp->vrf_id = ntohl (vrf_id);
21106
21107   S (mp);
21108   W (ret);
21109   return ret;
21110 }
21111
21112 int
21113 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21114 {
21115   unformat_input_t *input = vam->input;
21116   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21117   u32 sw_if_index = ~0;
21118   int vrf_set = 0;
21119   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21120   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21121   u8 is_add = 1;
21122   int ret;
21123
21124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21125     {
21126       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21127         ;
21128       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21129         ;
21130       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21131         vrf_set = 1;
21132       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21133         vrf_set = 1;
21134       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21135         vrf_set = 1;
21136       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21137         vrf_set = 1;
21138       else if (unformat (input, "del"))
21139         is_add = 0;
21140       else
21141         break;
21142     }
21143
21144   if (sw_if_index == ~0)
21145     {
21146       errmsg ("Interface required but not specified");
21147       return -99;
21148     }
21149
21150   if (vrf_set == 0)
21151     {
21152       errmsg ("VRF ID required but not specified");
21153       return -99;
21154     }
21155
21156   if (tcp_out_vrf_id == 0
21157       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21158     {
21159       errmsg
21160         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21161       return -99;
21162     }
21163
21164   /* Construct the API message */
21165   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21166
21167   mp->sw_if_index = ntohl (sw_if_index);
21168   mp->is_add = is_add;
21169   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21170   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21171   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21172   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21173
21174   /* send it... */
21175   S (mp);
21176
21177   /* Wait for a reply... */
21178   W (ret);
21179   return ret;
21180 }
21181
21182 static int
21183 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21184 {
21185   unformat_input_t *i = vam->input;
21186   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21187   u32 local_sa_id = 0;
21188   u32 remote_sa_id = 0;
21189   ip4_address_t src_address;
21190   ip4_address_t dst_address;
21191   u8 is_add = 1;
21192   int ret;
21193
21194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21195     {
21196       if (unformat (i, "local_sa %d", &local_sa_id))
21197         ;
21198       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21199         ;
21200       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21201         ;
21202       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21203         ;
21204       else if (unformat (i, "del"))
21205         is_add = 0;
21206       else
21207         {
21208           clib_warning ("parse error '%U'", format_unformat_error, i);
21209           return -99;
21210         }
21211     }
21212
21213   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21214
21215   mp->local_sa_id = ntohl (local_sa_id);
21216   mp->remote_sa_id = ntohl (remote_sa_id);
21217   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21218   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21219   mp->is_add = is_add;
21220
21221   S (mp);
21222   W (ret);
21223   return ret;
21224 }
21225
21226 static int
21227 api_set_punt (vat_main_t * vam)
21228 {
21229   unformat_input_t *i = vam->input;
21230   vl_api_set_punt_t *mp;
21231   u32 ipv = ~0;
21232   u32 protocol = ~0;
21233   u32 port = ~0;
21234   int is_add = 1;
21235   int ret;
21236
21237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21238     {
21239       if (unformat (i, "ip %d", &ipv))
21240         ;
21241       else if (unformat (i, "protocol %d", &protocol))
21242         ;
21243       else if (unformat (i, "port %d", &port))
21244         ;
21245       else if (unformat (i, "del"))
21246         is_add = 0;
21247       else
21248         {
21249           clib_warning ("parse error '%U'", format_unformat_error, i);
21250           return -99;
21251         }
21252     }
21253
21254   M (SET_PUNT, mp);
21255
21256   mp->is_add = (u8) is_add;
21257   mp->punt.ipv = (u8) ipv;
21258   mp->punt.l4_protocol = (u8) protocol;
21259   mp->punt.l4_port = htons ((u16) port);
21260
21261   S (mp);
21262   W (ret);
21263   return ret;
21264 }
21265
21266 static void vl_api_ipsec_gre_tunnel_details_t_handler
21267   (vl_api_ipsec_gre_tunnel_details_t * mp)
21268 {
21269   vat_main_t *vam = &vat_main;
21270
21271   print (vam->ofp, "%11d%15U%15U%14d%14d",
21272          ntohl (mp->sw_if_index),
21273          format_ip4_address, &mp->src_address,
21274          format_ip4_address, &mp->dst_address,
21275          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21276 }
21277
21278 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21279   (vl_api_ipsec_gre_tunnel_details_t * mp)
21280 {
21281   vat_main_t *vam = &vat_main;
21282   vat_json_node_t *node = NULL;
21283   struct in_addr ip4;
21284
21285   if (VAT_JSON_ARRAY != vam->json_tree.type)
21286     {
21287       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21288       vat_json_init_array (&vam->json_tree);
21289     }
21290   node = vat_json_array_add (&vam->json_tree);
21291
21292   vat_json_init_object (node);
21293   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21294   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21295   vat_json_object_add_ip4 (node, "src_address", ip4);
21296   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21297   vat_json_object_add_ip4 (node, "dst_address", ip4);
21298   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21299   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21300 }
21301
21302 static int
21303 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21304 {
21305   unformat_input_t *i = vam->input;
21306   vl_api_ipsec_gre_tunnel_dump_t *mp;
21307   vl_api_control_ping_t *mp_ping;
21308   u32 sw_if_index;
21309   u8 sw_if_index_set = 0;
21310   int ret;
21311
21312   /* Parse args required to build the message */
21313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21314     {
21315       if (unformat (i, "sw_if_index %d", &sw_if_index))
21316         sw_if_index_set = 1;
21317       else
21318         break;
21319     }
21320
21321   if (sw_if_index_set == 0)
21322     {
21323       sw_if_index = ~0;
21324     }
21325
21326   if (!vam->json_output)
21327     {
21328       print (vam->ofp, "%11s%15s%15s%14s%14s",
21329              "sw_if_index", "src_address", "dst_address",
21330              "local_sa_id", "remote_sa_id");
21331     }
21332
21333   /* Get list of gre-tunnel interfaces */
21334   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21335
21336   mp->sw_if_index = htonl (sw_if_index);
21337
21338   S (mp);
21339
21340   /* Use a control ping for synchronization */
21341   MPING (CONTROL_PING, mp_ping);
21342   S (mp_ping);
21343
21344   W (ret);
21345   return ret;
21346 }
21347
21348 static int
21349 api_delete_subif (vat_main_t * vam)
21350 {
21351   unformat_input_t *i = vam->input;
21352   vl_api_delete_subif_t *mp;
21353   u32 sw_if_index = ~0;
21354   int ret;
21355
21356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21357     {
21358       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21359         ;
21360       if (unformat (i, "sw_if_index %d", &sw_if_index))
21361         ;
21362       else
21363         break;
21364     }
21365
21366   if (sw_if_index == ~0)
21367     {
21368       errmsg ("missing sw_if_index");
21369       return -99;
21370     }
21371
21372   /* Construct the API message */
21373   M (DELETE_SUBIF, mp);
21374   mp->sw_if_index = ntohl (sw_if_index);
21375
21376   S (mp);
21377   W (ret);
21378   return ret;
21379 }
21380
21381 #define foreach_pbb_vtr_op      \
21382 _("disable",  L2_VTR_DISABLED)  \
21383 _("pop",  L2_VTR_POP_2)         \
21384 _("push",  L2_VTR_PUSH_2)
21385
21386 static int
21387 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21388 {
21389   unformat_input_t *i = vam->input;
21390   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21391   u32 sw_if_index = ~0, vtr_op = ~0;
21392   u16 outer_tag = ~0;
21393   u8 dmac[6], smac[6];
21394   u8 dmac_set = 0, smac_set = 0;
21395   u16 vlanid = 0;
21396   u32 sid = ~0;
21397   u32 tmp;
21398   int ret;
21399
21400   /* Shut up coverity */
21401   clib_memset (dmac, 0, sizeof (dmac));
21402   clib_memset (smac, 0, sizeof (smac));
21403
21404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21405     {
21406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21407         ;
21408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21409         ;
21410       else if (unformat (i, "vtr_op %d", &vtr_op))
21411         ;
21412 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21413       foreach_pbb_vtr_op
21414 #undef _
21415         else if (unformat (i, "translate_pbb_stag"))
21416         {
21417           if (unformat (i, "%d", &tmp))
21418             {
21419               vtr_op = L2_VTR_TRANSLATE_2_1;
21420               outer_tag = tmp;
21421             }
21422           else
21423             {
21424               errmsg
21425                 ("translate_pbb_stag operation requires outer tag definition");
21426               return -99;
21427             }
21428         }
21429       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21430         dmac_set++;
21431       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21432         smac_set++;
21433       else if (unformat (i, "sid %d", &sid))
21434         ;
21435       else if (unformat (i, "vlanid %d", &tmp))
21436         vlanid = tmp;
21437       else
21438         {
21439           clib_warning ("parse error '%U'", format_unformat_error, i);
21440           return -99;
21441         }
21442     }
21443
21444   if ((sw_if_index == ~0) || (vtr_op == ~0))
21445     {
21446       errmsg ("missing sw_if_index or vtr operation");
21447       return -99;
21448     }
21449   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21450       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21451     {
21452       errmsg
21453         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21454       return -99;
21455     }
21456
21457   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21458   mp->sw_if_index = ntohl (sw_if_index);
21459   mp->vtr_op = ntohl (vtr_op);
21460   mp->outer_tag = ntohs (outer_tag);
21461   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21462   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21463   mp->b_vlanid = ntohs (vlanid);
21464   mp->i_sid = ntohl (sid);
21465
21466   S (mp);
21467   W (ret);
21468   return ret;
21469 }
21470
21471 static int
21472 api_flow_classify_set_interface (vat_main_t * vam)
21473 {
21474   unformat_input_t *i = vam->input;
21475   vl_api_flow_classify_set_interface_t *mp;
21476   u32 sw_if_index;
21477   int sw_if_index_set;
21478   u32 ip4_table_index = ~0;
21479   u32 ip6_table_index = ~0;
21480   u8 is_add = 1;
21481   int ret;
21482
21483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21484     {
21485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21486         sw_if_index_set = 1;
21487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21488         sw_if_index_set = 1;
21489       else if (unformat (i, "del"))
21490         is_add = 0;
21491       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21492         ;
21493       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21494         ;
21495       else
21496         {
21497           clib_warning ("parse error '%U'", format_unformat_error, i);
21498           return -99;
21499         }
21500     }
21501
21502   if (sw_if_index_set == 0)
21503     {
21504       errmsg ("missing interface name or sw_if_index");
21505       return -99;
21506     }
21507
21508   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21509
21510   mp->sw_if_index = ntohl (sw_if_index);
21511   mp->ip4_table_index = ntohl (ip4_table_index);
21512   mp->ip6_table_index = ntohl (ip6_table_index);
21513   mp->is_add = is_add;
21514
21515   S (mp);
21516   W (ret);
21517   return ret;
21518 }
21519
21520 static int
21521 api_flow_classify_dump (vat_main_t * vam)
21522 {
21523   unformat_input_t *i = vam->input;
21524   vl_api_flow_classify_dump_t *mp;
21525   vl_api_control_ping_t *mp_ping;
21526   u8 type = FLOW_CLASSIFY_N_TABLES;
21527   int ret;
21528
21529   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21530     ;
21531   else
21532     {
21533       errmsg ("classify table type must be specified");
21534       return -99;
21535     }
21536
21537   if (!vam->json_output)
21538     {
21539       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21540     }
21541
21542   M (FLOW_CLASSIFY_DUMP, mp);
21543   mp->type = type;
21544   /* send it... */
21545   S (mp);
21546
21547   /* Use a control ping for synchronization */
21548   MPING (CONTROL_PING, mp_ping);
21549   S (mp_ping);
21550
21551   /* Wait for a reply... */
21552   W (ret);
21553   return ret;
21554 }
21555
21556 static int
21557 api_feature_enable_disable (vat_main_t * vam)
21558 {
21559   unformat_input_t *i = vam->input;
21560   vl_api_feature_enable_disable_t *mp;
21561   u8 *arc_name = 0;
21562   u8 *feature_name = 0;
21563   u32 sw_if_index = ~0;
21564   u8 enable = 1;
21565   int ret;
21566
21567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21568     {
21569       if (unformat (i, "arc_name %s", &arc_name))
21570         ;
21571       else if (unformat (i, "feature_name %s", &feature_name))
21572         ;
21573       else
21574         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21575         ;
21576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21577         ;
21578       else if (unformat (i, "disable"))
21579         enable = 0;
21580       else
21581         break;
21582     }
21583
21584   if (arc_name == 0)
21585     {
21586       errmsg ("missing arc name");
21587       return -99;
21588     }
21589   if (vec_len (arc_name) > 63)
21590     {
21591       errmsg ("arc name too long");
21592     }
21593
21594   if (feature_name == 0)
21595     {
21596       errmsg ("missing feature name");
21597       return -99;
21598     }
21599   if (vec_len (feature_name) > 63)
21600     {
21601       errmsg ("feature name too long");
21602     }
21603
21604   if (sw_if_index == ~0)
21605     {
21606       errmsg ("missing interface name or sw_if_index");
21607       return -99;
21608     }
21609
21610   /* Construct the API message */
21611   M (FEATURE_ENABLE_DISABLE, mp);
21612   mp->sw_if_index = ntohl (sw_if_index);
21613   mp->enable = enable;
21614   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21615   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21616   vec_free (arc_name);
21617   vec_free (feature_name);
21618
21619   S (mp);
21620   W (ret);
21621   return ret;
21622 }
21623
21624 static int
21625 api_sw_interface_tag_add_del (vat_main_t * vam)
21626 {
21627   unformat_input_t *i = vam->input;
21628   vl_api_sw_interface_tag_add_del_t *mp;
21629   u32 sw_if_index = ~0;
21630   u8 *tag = 0;
21631   u8 enable = 1;
21632   int ret;
21633
21634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21635     {
21636       if (unformat (i, "tag %s", &tag))
21637         ;
21638       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21639         ;
21640       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21641         ;
21642       else if (unformat (i, "del"))
21643         enable = 0;
21644       else
21645         break;
21646     }
21647
21648   if (sw_if_index == ~0)
21649     {
21650       errmsg ("missing interface name or sw_if_index");
21651       return -99;
21652     }
21653
21654   if (enable && (tag == 0))
21655     {
21656       errmsg ("no tag specified");
21657       return -99;
21658     }
21659
21660   /* Construct the API message */
21661   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21662   mp->sw_if_index = ntohl (sw_if_index);
21663   mp->is_add = enable;
21664   if (enable)
21665     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21666   vec_free (tag);
21667
21668   S (mp);
21669   W (ret);
21670   return ret;
21671 }
21672
21673 static void vl_api_l2_xconnect_details_t_handler
21674   (vl_api_l2_xconnect_details_t * mp)
21675 {
21676   vat_main_t *vam = &vat_main;
21677
21678   print (vam->ofp, "%15d%15d",
21679          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21680 }
21681
21682 static void vl_api_l2_xconnect_details_t_handler_json
21683   (vl_api_l2_xconnect_details_t * mp)
21684 {
21685   vat_main_t *vam = &vat_main;
21686   vat_json_node_t *node = NULL;
21687
21688   if (VAT_JSON_ARRAY != vam->json_tree.type)
21689     {
21690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21691       vat_json_init_array (&vam->json_tree);
21692     }
21693   node = vat_json_array_add (&vam->json_tree);
21694
21695   vat_json_init_object (node);
21696   vat_json_object_add_uint (node, "rx_sw_if_index",
21697                             ntohl (mp->rx_sw_if_index));
21698   vat_json_object_add_uint (node, "tx_sw_if_index",
21699                             ntohl (mp->tx_sw_if_index));
21700 }
21701
21702 static int
21703 api_l2_xconnect_dump (vat_main_t * vam)
21704 {
21705   vl_api_l2_xconnect_dump_t *mp;
21706   vl_api_control_ping_t *mp_ping;
21707   int ret;
21708
21709   if (!vam->json_output)
21710     {
21711       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21712     }
21713
21714   M (L2_XCONNECT_DUMP, mp);
21715
21716   S (mp);
21717
21718   /* Use a control ping for synchronization */
21719   MPING (CONTROL_PING, mp_ping);
21720   S (mp_ping);
21721
21722   W (ret);
21723   return ret;
21724 }
21725
21726 static int
21727 api_hw_interface_set_mtu (vat_main_t * vam)
21728 {
21729   unformat_input_t *i = vam->input;
21730   vl_api_hw_interface_set_mtu_t *mp;
21731   u32 sw_if_index = ~0;
21732   u32 mtu = 0;
21733   int ret;
21734
21735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21736     {
21737       if (unformat (i, "mtu %d", &mtu))
21738         ;
21739       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21740         ;
21741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21742         ;
21743       else
21744         break;
21745     }
21746
21747   if (sw_if_index == ~0)
21748     {
21749       errmsg ("missing interface name or sw_if_index");
21750       return -99;
21751     }
21752
21753   if (mtu == 0)
21754     {
21755       errmsg ("no mtu specified");
21756       return -99;
21757     }
21758
21759   /* Construct the API message */
21760   M (HW_INTERFACE_SET_MTU, mp);
21761   mp->sw_if_index = ntohl (sw_if_index);
21762   mp->mtu = ntohs ((u16) mtu);
21763
21764   S (mp);
21765   W (ret);
21766   return ret;
21767 }
21768
21769 static int
21770 api_p2p_ethernet_add (vat_main_t * vam)
21771 {
21772   unformat_input_t *i = vam->input;
21773   vl_api_p2p_ethernet_add_t *mp;
21774   u32 parent_if_index = ~0;
21775   u32 sub_id = ~0;
21776   u8 remote_mac[6];
21777   u8 mac_set = 0;
21778   int ret;
21779
21780   clib_memset (remote_mac, 0, sizeof (remote_mac));
21781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21782     {
21783       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21784         ;
21785       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21786         ;
21787       else
21788         if (unformat
21789             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21790         mac_set++;
21791       else if (unformat (i, "sub_id %d", &sub_id))
21792         ;
21793       else
21794         {
21795           clib_warning ("parse error '%U'", format_unformat_error, i);
21796           return -99;
21797         }
21798     }
21799
21800   if (parent_if_index == ~0)
21801     {
21802       errmsg ("missing interface name or sw_if_index");
21803       return -99;
21804     }
21805   if (mac_set == 0)
21806     {
21807       errmsg ("missing remote mac address");
21808       return -99;
21809     }
21810   if (sub_id == ~0)
21811     {
21812       errmsg ("missing sub-interface id");
21813       return -99;
21814     }
21815
21816   M (P2P_ETHERNET_ADD, mp);
21817   mp->parent_if_index = ntohl (parent_if_index);
21818   mp->subif_id = ntohl (sub_id);
21819   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21820
21821   S (mp);
21822   W (ret);
21823   return ret;
21824 }
21825
21826 static int
21827 api_p2p_ethernet_del (vat_main_t * vam)
21828 {
21829   unformat_input_t *i = vam->input;
21830   vl_api_p2p_ethernet_del_t *mp;
21831   u32 parent_if_index = ~0;
21832   u8 remote_mac[6];
21833   u8 mac_set = 0;
21834   int ret;
21835
21836   clib_memset (remote_mac, 0, sizeof (remote_mac));
21837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21838     {
21839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21840         ;
21841       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21842         ;
21843       else
21844         if (unformat
21845             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21846         mac_set++;
21847       else
21848         {
21849           clib_warning ("parse error '%U'", format_unformat_error, i);
21850           return -99;
21851         }
21852     }
21853
21854   if (parent_if_index == ~0)
21855     {
21856       errmsg ("missing interface name or sw_if_index");
21857       return -99;
21858     }
21859   if (mac_set == 0)
21860     {
21861       errmsg ("missing remote mac address");
21862       return -99;
21863     }
21864
21865   M (P2P_ETHERNET_DEL, mp);
21866   mp->parent_if_index = ntohl (parent_if_index);
21867   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21868
21869   S (mp);
21870   W (ret);
21871   return ret;
21872 }
21873
21874 static int
21875 api_lldp_config (vat_main_t * vam)
21876 {
21877   unformat_input_t *i = vam->input;
21878   vl_api_lldp_config_t *mp;
21879   int tx_hold = 0;
21880   int tx_interval = 0;
21881   u8 *sys_name = NULL;
21882   int ret;
21883
21884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21885     {
21886       if (unformat (i, "system-name %s", &sys_name))
21887         ;
21888       else if (unformat (i, "tx-hold %d", &tx_hold))
21889         ;
21890       else if (unformat (i, "tx-interval %d", &tx_interval))
21891         ;
21892       else
21893         {
21894           clib_warning ("parse error '%U'", format_unformat_error, i);
21895           return -99;
21896         }
21897     }
21898
21899   vec_add1 (sys_name, 0);
21900
21901   M (LLDP_CONFIG, mp);
21902   mp->tx_hold = htonl (tx_hold);
21903   mp->tx_interval = htonl (tx_interval);
21904   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21905   vec_free (sys_name);
21906
21907   S (mp);
21908   W (ret);
21909   return ret;
21910 }
21911
21912 static int
21913 api_sw_interface_set_lldp (vat_main_t * vam)
21914 {
21915   unformat_input_t *i = vam->input;
21916   vl_api_sw_interface_set_lldp_t *mp;
21917   u32 sw_if_index = ~0;
21918   u32 enable = 1;
21919   u8 *port_desc = NULL, *mgmt_oid = NULL;
21920   ip4_address_t ip4_addr;
21921   ip6_address_t ip6_addr;
21922   int ret;
21923
21924   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21925   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21926
21927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21928     {
21929       if (unformat (i, "disable"))
21930         enable = 0;
21931       else
21932         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21933         ;
21934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21935         ;
21936       else if (unformat (i, "port-desc %s", &port_desc))
21937         ;
21938       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21939         ;
21940       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21941         ;
21942       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21943         ;
21944       else
21945         break;
21946     }
21947
21948   if (sw_if_index == ~0)
21949     {
21950       errmsg ("missing interface name or sw_if_index");
21951       return -99;
21952     }
21953
21954   /* Construct the API message */
21955   vec_add1 (port_desc, 0);
21956   vec_add1 (mgmt_oid, 0);
21957   M (SW_INTERFACE_SET_LLDP, mp);
21958   mp->sw_if_index = ntohl (sw_if_index);
21959   mp->enable = enable;
21960   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21961   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21962   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21963   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21964   vec_free (port_desc);
21965   vec_free (mgmt_oid);
21966
21967   S (mp);
21968   W (ret);
21969   return ret;
21970 }
21971
21972 static int
21973 api_tcp_configure_src_addresses (vat_main_t * vam)
21974 {
21975   vl_api_tcp_configure_src_addresses_t *mp;
21976   unformat_input_t *i = vam->input;
21977   ip4_address_t v4first, v4last;
21978   ip6_address_t v6first, v6last;
21979   u8 range_set = 0;
21980   u32 vrf_id = 0;
21981   int ret;
21982
21983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21984     {
21985       if (unformat (i, "%U - %U",
21986                     unformat_ip4_address, &v4first,
21987                     unformat_ip4_address, &v4last))
21988         {
21989           if (range_set)
21990             {
21991               errmsg ("one range per message (range already set)");
21992               return -99;
21993             }
21994           range_set = 1;
21995         }
21996       else if (unformat (i, "%U - %U",
21997                          unformat_ip6_address, &v6first,
21998                          unformat_ip6_address, &v6last))
21999         {
22000           if (range_set)
22001             {
22002               errmsg ("one range per message (range already set)");
22003               return -99;
22004             }
22005           range_set = 2;
22006         }
22007       else if (unformat (i, "vrf %d", &vrf_id))
22008         ;
22009       else
22010         break;
22011     }
22012
22013   if (range_set == 0)
22014     {
22015       errmsg ("address range not set");
22016       return -99;
22017     }
22018
22019   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22020   mp->vrf_id = ntohl (vrf_id);
22021   /* ipv6? */
22022   if (range_set == 2)
22023     {
22024       mp->is_ipv6 = 1;
22025       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22026       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22027     }
22028   else
22029     {
22030       mp->is_ipv6 = 0;
22031       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22032       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22033     }
22034   S (mp);
22035   W (ret);
22036   return ret;
22037 }
22038
22039 static void vl_api_app_namespace_add_del_reply_t_handler
22040   (vl_api_app_namespace_add_del_reply_t * mp)
22041 {
22042   vat_main_t *vam = &vat_main;
22043   i32 retval = ntohl (mp->retval);
22044   if (vam->async_mode)
22045     {
22046       vam->async_errors += (retval < 0);
22047     }
22048   else
22049     {
22050       vam->retval = retval;
22051       if (retval == 0)
22052         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22053       vam->result_ready = 1;
22054     }
22055 }
22056
22057 static void vl_api_app_namespace_add_del_reply_t_handler_json
22058   (vl_api_app_namespace_add_del_reply_t * mp)
22059 {
22060   vat_main_t *vam = &vat_main;
22061   vat_json_node_t node;
22062
22063   vat_json_init_object (&node);
22064   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22065   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22066
22067   vat_json_print (vam->ofp, &node);
22068   vat_json_free (&node);
22069
22070   vam->retval = ntohl (mp->retval);
22071   vam->result_ready = 1;
22072 }
22073
22074 static int
22075 api_app_namespace_add_del (vat_main_t * vam)
22076 {
22077   vl_api_app_namespace_add_del_t *mp;
22078   unformat_input_t *i = vam->input;
22079   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22080   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22081   u64 secret;
22082   int ret;
22083
22084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22085     {
22086       if (unformat (i, "id %_%v%_", &ns_id))
22087         ;
22088       else if (unformat (i, "secret %lu", &secret))
22089         secret_set = 1;
22090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22091         sw_if_index_set = 1;
22092       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22093         ;
22094       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22095         ;
22096       else
22097         break;
22098     }
22099   if (!ns_id || !secret_set || !sw_if_index_set)
22100     {
22101       errmsg ("namespace id, secret and sw_if_index must be set");
22102       return -99;
22103     }
22104   if (vec_len (ns_id) > 64)
22105     {
22106       errmsg ("namespace id too long");
22107       return -99;
22108     }
22109   M (APP_NAMESPACE_ADD_DEL, mp);
22110
22111   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22112   mp->namespace_id_len = vec_len (ns_id);
22113   mp->secret = clib_host_to_net_u64 (secret);
22114   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22115   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22116   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22117   vec_free (ns_id);
22118   S (mp);
22119   W (ret);
22120   return ret;
22121 }
22122
22123 static int
22124 api_sock_init_shm (vat_main_t * vam)
22125 {
22126 #if VPP_API_TEST_BUILTIN == 0
22127   unformat_input_t *i = vam->input;
22128   vl_api_shm_elem_config_t *config = 0;
22129   u64 size = 64 << 20;
22130   int rv;
22131
22132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22133     {
22134       if (unformat (i, "size %U", unformat_memory_size, &size))
22135         ;
22136       else
22137         break;
22138     }
22139
22140   /*
22141    * Canned custom ring allocator config.
22142    * Should probably parse all of this
22143    */
22144   vec_validate (config, 6);
22145   config[0].type = VL_API_VLIB_RING;
22146   config[0].size = 256;
22147   config[0].count = 32;
22148
22149   config[1].type = VL_API_VLIB_RING;
22150   config[1].size = 1024;
22151   config[1].count = 16;
22152
22153   config[2].type = VL_API_VLIB_RING;
22154   config[2].size = 4096;
22155   config[2].count = 2;
22156
22157   config[3].type = VL_API_CLIENT_RING;
22158   config[3].size = 256;
22159   config[3].count = 32;
22160
22161   config[4].type = VL_API_CLIENT_RING;
22162   config[4].size = 1024;
22163   config[4].count = 16;
22164
22165   config[5].type = VL_API_CLIENT_RING;
22166   config[5].size = 4096;
22167   config[5].count = 2;
22168
22169   config[6].type = VL_API_QUEUE;
22170   config[6].count = 128;
22171   config[6].size = sizeof (uword);
22172
22173   rv = vl_socket_client_init_shm (config);
22174   if (!rv)
22175     vam->client_index_invalid = 1;
22176   return rv;
22177 #else
22178   return -99;
22179 #endif
22180 }
22181
22182 static int
22183 api_dns_enable_disable (vat_main_t * vam)
22184 {
22185   unformat_input_t *line_input = vam->input;
22186   vl_api_dns_enable_disable_t *mp;
22187   u8 enable_disable = 1;
22188   int ret;
22189
22190   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22191     {
22192       if (unformat (line_input, "disable"))
22193         enable_disable = 0;
22194       if (unformat (line_input, "enable"))
22195         enable_disable = 1;
22196       else
22197         break;
22198     }
22199
22200   /* Construct the API message */
22201   M (DNS_ENABLE_DISABLE, mp);
22202   mp->enable = enable_disable;
22203
22204   /* send it... */
22205   S (mp);
22206   /* Wait for the reply */
22207   W (ret);
22208   return ret;
22209 }
22210
22211 static int
22212 api_dns_resolve_name (vat_main_t * vam)
22213 {
22214   unformat_input_t *line_input = vam->input;
22215   vl_api_dns_resolve_name_t *mp;
22216   u8 *name = 0;
22217   int ret;
22218
22219   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22220     {
22221       if (unformat (line_input, "%s", &name))
22222         ;
22223       else
22224         break;
22225     }
22226
22227   if (vec_len (name) > 127)
22228     {
22229       errmsg ("name too long");
22230       return -99;
22231     }
22232
22233   /* Construct the API message */
22234   M (DNS_RESOLVE_NAME, mp);
22235   memcpy (mp->name, name, vec_len (name));
22236   vec_free (name);
22237
22238   /* send it... */
22239   S (mp);
22240   /* Wait for the reply */
22241   W (ret);
22242   return ret;
22243 }
22244
22245 static int
22246 api_dns_resolve_ip (vat_main_t * vam)
22247 {
22248   unformat_input_t *line_input = vam->input;
22249   vl_api_dns_resolve_ip_t *mp;
22250   int is_ip6 = -1;
22251   ip4_address_t addr4;
22252   ip6_address_t addr6;
22253   int ret;
22254
22255   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22256     {
22257       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22258         is_ip6 = 1;
22259       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22260         is_ip6 = 0;
22261       else
22262         break;
22263     }
22264
22265   if (is_ip6 == -1)
22266     {
22267       errmsg ("missing address");
22268       return -99;
22269     }
22270
22271   /* Construct the API message */
22272   M (DNS_RESOLVE_IP, mp);
22273   mp->is_ip6 = is_ip6;
22274   if (is_ip6)
22275     memcpy (mp->address, &addr6, sizeof (addr6));
22276   else
22277     memcpy (mp->address, &addr4, sizeof (addr4));
22278
22279   /* send it... */
22280   S (mp);
22281   /* Wait for the reply */
22282   W (ret);
22283   return ret;
22284 }
22285
22286 static int
22287 api_dns_name_server_add_del (vat_main_t * vam)
22288 {
22289   unformat_input_t *i = vam->input;
22290   vl_api_dns_name_server_add_del_t *mp;
22291   u8 is_add = 1;
22292   ip6_address_t ip6_server;
22293   ip4_address_t ip4_server;
22294   int ip6_set = 0;
22295   int ip4_set = 0;
22296   int ret = 0;
22297
22298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22299     {
22300       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22301         ip6_set = 1;
22302       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22303         ip4_set = 1;
22304       else if (unformat (i, "del"))
22305         is_add = 0;
22306       else
22307         {
22308           clib_warning ("parse error '%U'", format_unformat_error, i);
22309           return -99;
22310         }
22311     }
22312
22313   if (ip4_set && ip6_set)
22314     {
22315       errmsg ("Only one server address allowed per message");
22316       return -99;
22317     }
22318   if ((ip4_set + ip6_set) == 0)
22319     {
22320       errmsg ("Server address required");
22321       return -99;
22322     }
22323
22324   /* Construct the API message */
22325   M (DNS_NAME_SERVER_ADD_DEL, mp);
22326
22327   if (ip6_set)
22328     {
22329       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22330       mp->is_ip6 = 1;
22331     }
22332   else
22333     {
22334       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22335       mp->is_ip6 = 0;
22336     }
22337
22338   mp->is_add = is_add;
22339
22340   /* send it... */
22341   S (mp);
22342
22343   /* Wait for a reply, return good/bad news  */
22344   W (ret);
22345   return ret;
22346 }
22347
22348 static void
22349 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22350 {
22351   vat_main_t *vam = &vat_main;
22352
22353   if (mp->is_ip4)
22354     {
22355       print (vam->ofp,
22356              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22357              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22358              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22359              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22360              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22361              clib_net_to_host_u32 (mp->action_index), mp->tag);
22362     }
22363   else
22364     {
22365       print (vam->ofp,
22366              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22367              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22368              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22369              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22370              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22371              clib_net_to_host_u32 (mp->action_index), mp->tag);
22372     }
22373 }
22374
22375 static void
22376 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22377                                              mp)
22378 {
22379   vat_main_t *vam = &vat_main;
22380   vat_json_node_t *node = NULL;
22381   struct in6_addr ip6;
22382   struct in_addr ip4;
22383
22384   if (VAT_JSON_ARRAY != vam->json_tree.type)
22385     {
22386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22387       vat_json_init_array (&vam->json_tree);
22388     }
22389   node = vat_json_array_add (&vam->json_tree);
22390   vat_json_init_object (node);
22391
22392   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22393   vat_json_object_add_uint (node, "appns_index",
22394                             clib_net_to_host_u32 (mp->appns_index));
22395   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22396   vat_json_object_add_uint (node, "scope", mp->scope);
22397   vat_json_object_add_uint (node, "action_index",
22398                             clib_net_to_host_u32 (mp->action_index));
22399   vat_json_object_add_uint (node, "lcl_port",
22400                             clib_net_to_host_u16 (mp->lcl_port));
22401   vat_json_object_add_uint (node, "rmt_port",
22402                             clib_net_to_host_u16 (mp->rmt_port));
22403   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22404   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22405   vat_json_object_add_string_copy (node, "tag", mp->tag);
22406   if (mp->is_ip4)
22407     {
22408       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22409       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22410       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22411       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22412     }
22413   else
22414     {
22415       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22416       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22417       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22418       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22419     }
22420 }
22421
22422 static int
22423 api_session_rule_add_del (vat_main_t * vam)
22424 {
22425   vl_api_session_rule_add_del_t *mp;
22426   unformat_input_t *i = vam->input;
22427   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22428   u32 appns_index = 0, scope = 0;
22429   ip4_address_t lcl_ip4, rmt_ip4;
22430   ip6_address_t lcl_ip6, rmt_ip6;
22431   u8 is_ip4 = 1, conn_set = 0;
22432   u8 is_add = 1, *tag = 0;
22433   int ret;
22434
22435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22436     {
22437       if (unformat (i, "del"))
22438         is_add = 0;
22439       else if (unformat (i, "add"))
22440         ;
22441       else if (unformat (i, "proto tcp"))
22442         proto = 0;
22443       else if (unformat (i, "proto udp"))
22444         proto = 1;
22445       else if (unformat (i, "appns %d", &appns_index))
22446         ;
22447       else if (unformat (i, "scope %d", &scope))
22448         ;
22449       else if (unformat (i, "tag %_%v%_", &tag))
22450         ;
22451       else
22452         if (unformat
22453             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22454              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22455              &rmt_port))
22456         {
22457           is_ip4 = 1;
22458           conn_set = 1;
22459         }
22460       else
22461         if (unformat
22462             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22463              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22464              &rmt_port))
22465         {
22466           is_ip4 = 0;
22467           conn_set = 1;
22468         }
22469       else if (unformat (i, "action %d", &action))
22470         ;
22471       else
22472         break;
22473     }
22474   if (proto == ~0 || !conn_set || action == ~0)
22475     {
22476       errmsg ("transport proto, connection and action must be set");
22477       return -99;
22478     }
22479
22480   if (scope > 3)
22481     {
22482       errmsg ("scope should be 0-3");
22483       return -99;
22484     }
22485
22486   M (SESSION_RULE_ADD_DEL, mp);
22487
22488   mp->is_ip4 = is_ip4;
22489   mp->transport_proto = proto;
22490   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22491   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22492   mp->lcl_plen = lcl_plen;
22493   mp->rmt_plen = rmt_plen;
22494   mp->action_index = clib_host_to_net_u32 (action);
22495   mp->appns_index = clib_host_to_net_u32 (appns_index);
22496   mp->scope = scope;
22497   mp->is_add = is_add;
22498   if (is_ip4)
22499     {
22500       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22501       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22502     }
22503   else
22504     {
22505       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22506       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22507     }
22508   if (tag)
22509     {
22510       clib_memcpy (mp->tag, tag, vec_len (tag));
22511       vec_free (tag);
22512     }
22513
22514   S (mp);
22515   W (ret);
22516   return ret;
22517 }
22518
22519 static int
22520 api_session_rules_dump (vat_main_t * vam)
22521 {
22522   vl_api_session_rules_dump_t *mp;
22523   vl_api_control_ping_t *mp_ping;
22524   int ret;
22525
22526   if (!vam->json_output)
22527     {
22528       print (vam->ofp, "%=20s", "Session Rules");
22529     }
22530
22531   M (SESSION_RULES_DUMP, mp);
22532   /* send it... */
22533   S (mp);
22534
22535   /* Use a control ping for synchronization */
22536   MPING (CONTROL_PING, mp_ping);
22537   S (mp_ping);
22538
22539   /* Wait for a reply... */
22540   W (ret);
22541   return ret;
22542 }
22543
22544 static int
22545 api_ip_container_proxy_add_del (vat_main_t * vam)
22546 {
22547   vl_api_ip_container_proxy_add_del_t *mp;
22548   unformat_input_t *i = vam->input;
22549   u32 plen = ~0, sw_if_index = ~0;
22550   ip4_address_t ip4;
22551   ip6_address_t ip6;
22552   u8 is_ip4 = 1;
22553   u8 is_add = 1;
22554   int ret;
22555
22556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22557     {
22558       if (unformat (i, "del"))
22559         is_add = 0;
22560       else if (unformat (i, "add"))
22561         ;
22562       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22563         {
22564           is_ip4 = 1;
22565           plen = 32;
22566         }
22567       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22568         {
22569           is_ip4 = 0;
22570           plen = 128;
22571         }
22572       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22573         ;
22574       else
22575         break;
22576     }
22577   if (sw_if_index == ~0 || plen == ~0)
22578     {
22579       errmsg ("address and sw_if_index must be set");
22580       return -99;
22581     }
22582
22583   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22584
22585   mp->is_ip4 = is_ip4;
22586   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22587   mp->plen = plen;
22588   mp->is_add = is_add;
22589   if (is_ip4)
22590     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22591   else
22592     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22593
22594   S (mp);
22595   W (ret);
22596   return ret;
22597 }
22598
22599 static int
22600 api_qos_record_enable_disable (vat_main_t * vam)
22601 {
22602   unformat_input_t *i = vam->input;
22603   vl_api_qos_record_enable_disable_t *mp;
22604   u32 sw_if_index, qs = 0xff;
22605   u8 sw_if_index_set = 0;
22606   u8 enable = 1;
22607   int ret;
22608
22609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22610     {
22611       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22612         sw_if_index_set = 1;
22613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22614         sw_if_index_set = 1;
22615       else if (unformat (i, "%U", unformat_qos_source, &qs))
22616         ;
22617       else if (unformat (i, "disable"))
22618         enable = 0;
22619       else
22620         {
22621           clib_warning ("parse error '%U'", format_unformat_error, i);
22622           return -99;
22623         }
22624     }
22625
22626   if (sw_if_index_set == 0)
22627     {
22628       errmsg ("missing interface name or sw_if_index");
22629       return -99;
22630     }
22631   if (qs == 0xff)
22632     {
22633       errmsg ("input location must be specified");
22634       return -99;
22635     }
22636
22637   M (QOS_RECORD_ENABLE_DISABLE, mp);
22638
22639   mp->sw_if_index = ntohl (sw_if_index);
22640   mp->input_source = qs;
22641   mp->enable = enable;
22642
22643   S (mp);
22644   W (ret);
22645   return ret;
22646 }
22647
22648
22649 static int
22650 q_or_quit (vat_main_t * vam)
22651 {
22652 #if VPP_API_TEST_BUILTIN == 0
22653   longjmp (vam->jump_buf, 1);
22654 #endif
22655   return 0;                     /* not so much */
22656 }
22657
22658 static int
22659 q (vat_main_t * vam)
22660 {
22661   return q_or_quit (vam);
22662 }
22663
22664 static int
22665 quit (vat_main_t * vam)
22666 {
22667   return q_or_quit (vam);
22668 }
22669
22670 static int
22671 comment (vat_main_t * vam)
22672 {
22673   return 0;
22674 }
22675
22676 static int
22677 statseg (vat_main_t * vam)
22678 {
22679   ssvm_private_t *ssvmp = &vam->stat_segment;
22680   ssvm_shared_header_t *shared_header = ssvmp->sh;
22681   vlib_counter_t **counters;
22682   u64 thread0_index1_packets;
22683   u64 thread0_index1_bytes;
22684   f64 vector_rate, input_rate;
22685   uword *p;
22686
22687   uword *counter_vector_by_name;
22688   if (vam->stat_segment_lockp == 0)
22689     {
22690       errmsg ("Stat segment not mapped...");
22691       return -99;
22692     }
22693
22694   /* look up "/if/rx for sw_if_index 1 as a test */
22695
22696   clib_spinlock_lock (vam->stat_segment_lockp);
22697
22698   counter_vector_by_name = (uword *) shared_header->opaque[1];
22699
22700   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22701   if (p == 0)
22702     {
22703       clib_spinlock_unlock (vam->stat_segment_lockp);
22704       errmsg ("/if/tx not found?");
22705       return -99;
22706     }
22707
22708   /* Fish per-thread vector of combined counters from shared memory */
22709   counters = (vlib_counter_t **) p[0];
22710
22711   if (vec_len (counters[0]) < 2)
22712     {
22713       clib_spinlock_unlock (vam->stat_segment_lockp);
22714       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22715       return -99;
22716     }
22717
22718   /* Read thread 0 sw_if_index 1 counter */
22719   thread0_index1_packets = counters[0][1].packets;
22720   thread0_index1_bytes = counters[0][1].bytes;
22721
22722   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22723   if (p == 0)
22724     {
22725       clib_spinlock_unlock (vam->stat_segment_lockp);
22726       errmsg ("vector_rate not found?");
22727       return -99;
22728     }
22729
22730   vector_rate = *(f64 *) (p[0]);
22731   p = hash_get_mem (counter_vector_by_name, "input_rate");
22732   if (p == 0)
22733     {
22734       clib_spinlock_unlock (vam->stat_segment_lockp);
22735       errmsg ("input_rate not found?");
22736       return -99;
22737     }
22738   input_rate = *(f64 *) (p[0]);
22739
22740   clib_spinlock_unlock (vam->stat_segment_lockp);
22741
22742   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22743          vector_rate, input_rate);
22744   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22745          thread0_index1_packets, thread0_index1_bytes);
22746
22747   return 0;
22748 }
22749
22750 static int
22751 cmd_cmp (void *a1, void *a2)
22752 {
22753   u8 **c1 = a1;
22754   u8 **c2 = a2;
22755
22756   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22757 }
22758
22759 static int
22760 help (vat_main_t * vam)
22761 {
22762   u8 **cmds = 0;
22763   u8 *name = 0;
22764   hash_pair_t *p;
22765   unformat_input_t *i = vam->input;
22766   int j;
22767
22768   if (unformat (i, "%s", &name))
22769     {
22770       uword *hs;
22771
22772       vec_add1 (name, 0);
22773
22774       hs = hash_get_mem (vam->help_by_name, name);
22775       if (hs)
22776         print (vam->ofp, "usage: %s %s", name, hs[0]);
22777       else
22778         print (vam->ofp, "No such msg / command '%s'", name);
22779       vec_free (name);
22780       return 0;
22781     }
22782
22783   print (vam->ofp, "Help is available for the following:");
22784
22785     /* *INDENT-OFF* */
22786     hash_foreach_pair (p, vam->function_by_name,
22787     ({
22788       vec_add1 (cmds, (u8 *)(p->key));
22789     }));
22790     /* *INDENT-ON* */
22791
22792   vec_sort_with_function (cmds, cmd_cmp);
22793
22794   for (j = 0; j < vec_len (cmds); j++)
22795     print (vam->ofp, "%s", cmds[j]);
22796
22797   vec_free (cmds);
22798   return 0;
22799 }
22800
22801 static int
22802 set (vat_main_t * vam)
22803 {
22804   u8 *name = 0, *value = 0;
22805   unformat_input_t *i = vam->input;
22806
22807   if (unformat (i, "%s", &name))
22808     {
22809       /* The input buffer is a vector, not a string. */
22810       value = vec_dup (i->buffer);
22811       vec_delete (value, i->index, 0);
22812       /* Almost certainly has a trailing newline */
22813       if (value[vec_len (value) - 1] == '\n')
22814         value[vec_len (value) - 1] = 0;
22815       /* Make sure it's a proper string, one way or the other */
22816       vec_add1 (value, 0);
22817       (void) clib_macro_set_value (&vam->macro_main,
22818                                    (char *) name, (char *) value);
22819     }
22820   else
22821     errmsg ("usage: set <name> <value>");
22822
22823   vec_free (name);
22824   vec_free (value);
22825   return 0;
22826 }
22827
22828 static int
22829 unset (vat_main_t * vam)
22830 {
22831   u8 *name = 0;
22832
22833   if (unformat (vam->input, "%s", &name))
22834     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22835       errmsg ("unset: %s wasn't set", name);
22836   vec_free (name);
22837   return 0;
22838 }
22839
22840 typedef struct
22841 {
22842   u8 *name;
22843   u8 *value;
22844 } macro_sort_t;
22845
22846
22847 static int
22848 macro_sort_cmp (void *a1, void *a2)
22849 {
22850   macro_sort_t *s1 = a1;
22851   macro_sort_t *s2 = a2;
22852
22853   return strcmp ((char *) (s1->name), (char *) (s2->name));
22854 }
22855
22856 static int
22857 dump_macro_table (vat_main_t * vam)
22858 {
22859   macro_sort_t *sort_me = 0, *sm;
22860   int i;
22861   hash_pair_t *p;
22862
22863     /* *INDENT-OFF* */
22864     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22865     ({
22866       vec_add2 (sort_me, sm, 1);
22867       sm->name = (u8 *)(p->key);
22868       sm->value = (u8 *) (p->value[0]);
22869     }));
22870     /* *INDENT-ON* */
22871
22872   vec_sort_with_function (sort_me, macro_sort_cmp);
22873
22874   if (vec_len (sort_me))
22875     print (vam->ofp, "%-15s%s", "Name", "Value");
22876   else
22877     print (vam->ofp, "The macro table is empty...");
22878
22879   for (i = 0; i < vec_len (sort_me); i++)
22880     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22881   return 0;
22882 }
22883
22884 static int
22885 dump_node_table (vat_main_t * vam)
22886 {
22887   int i, j;
22888   vlib_node_t *node, *next_node;
22889
22890   if (vec_len (vam->graph_nodes) == 0)
22891     {
22892       print (vam->ofp, "Node table empty, issue get_node_graph...");
22893       return 0;
22894     }
22895
22896   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22897     {
22898       node = vam->graph_nodes[0][i];
22899       print (vam->ofp, "[%d] %s", i, node->name);
22900       for (j = 0; j < vec_len (node->next_nodes); j++)
22901         {
22902           if (node->next_nodes[j] != ~0)
22903             {
22904               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22905               print (vam->ofp, "  [%d] %s", j, next_node->name);
22906             }
22907         }
22908     }
22909   return 0;
22910 }
22911
22912 static int
22913 value_sort_cmp (void *a1, void *a2)
22914 {
22915   name_sort_t *n1 = a1;
22916   name_sort_t *n2 = a2;
22917
22918   if (n1->value < n2->value)
22919     return -1;
22920   if (n1->value > n2->value)
22921     return 1;
22922   return 0;
22923 }
22924
22925
22926 static int
22927 dump_msg_api_table (vat_main_t * vam)
22928 {
22929   api_main_t *am = &api_main;
22930   name_sort_t *nses = 0, *ns;
22931   hash_pair_t *hp;
22932   int i;
22933
22934   /* *INDENT-OFF* */
22935   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22936   ({
22937     vec_add2 (nses, ns, 1);
22938     ns->name = (u8 *)(hp->key);
22939     ns->value = (u32) hp->value[0];
22940   }));
22941   /* *INDENT-ON* */
22942
22943   vec_sort_with_function (nses, value_sort_cmp);
22944
22945   for (i = 0; i < vec_len (nses); i++)
22946     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22947   vec_free (nses);
22948   return 0;
22949 }
22950
22951 static int
22952 get_msg_id (vat_main_t * vam)
22953 {
22954   u8 *name_and_crc;
22955   u32 message_index;
22956
22957   if (unformat (vam->input, "%s", &name_and_crc))
22958     {
22959       message_index = vl_msg_api_get_msg_index (name_and_crc);
22960       if (message_index == ~0)
22961         {
22962           print (vam->ofp, " '%s' not found", name_and_crc);
22963           return 0;
22964         }
22965       print (vam->ofp, " '%s' has message index %d",
22966              name_and_crc, message_index);
22967       return 0;
22968     }
22969   errmsg ("name_and_crc required...");
22970   return 0;
22971 }
22972
22973 static int
22974 search_node_table (vat_main_t * vam)
22975 {
22976   unformat_input_t *line_input = vam->input;
22977   u8 *node_to_find;
22978   int j;
22979   vlib_node_t *node, *next_node;
22980   uword *p;
22981
22982   if (vam->graph_node_index_by_name == 0)
22983     {
22984       print (vam->ofp, "Node table empty, issue get_node_graph...");
22985       return 0;
22986     }
22987
22988   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22989     {
22990       if (unformat (line_input, "%s", &node_to_find))
22991         {
22992           vec_add1 (node_to_find, 0);
22993           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22994           if (p == 0)
22995             {
22996               print (vam->ofp, "%s not found...", node_to_find);
22997               goto out;
22998             }
22999           node = vam->graph_nodes[0][p[0]];
23000           print (vam->ofp, "[%d] %s", p[0], node->name);
23001           for (j = 0; j < vec_len (node->next_nodes); j++)
23002             {
23003               if (node->next_nodes[j] != ~0)
23004                 {
23005                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23006                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23007                 }
23008             }
23009         }
23010
23011       else
23012         {
23013           clib_warning ("parse error '%U'", format_unformat_error,
23014                         line_input);
23015           return -99;
23016         }
23017
23018     out:
23019       vec_free (node_to_find);
23020
23021     }
23022
23023   return 0;
23024 }
23025
23026
23027 static int
23028 script (vat_main_t * vam)
23029 {
23030 #if (VPP_API_TEST_BUILTIN==0)
23031   u8 *s = 0;
23032   char *save_current_file;
23033   unformat_input_t save_input;
23034   jmp_buf save_jump_buf;
23035   u32 save_line_number;
23036
23037   FILE *new_fp, *save_ifp;
23038
23039   if (unformat (vam->input, "%s", &s))
23040     {
23041       new_fp = fopen ((char *) s, "r");
23042       if (new_fp == 0)
23043         {
23044           errmsg ("Couldn't open script file %s", s);
23045           vec_free (s);
23046           return -99;
23047         }
23048     }
23049   else
23050     {
23051       errmsg ("Missing script name");
23052       return -99;
23053     }
23054
23055   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23056   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23057   save_ifp = vam->ifp;
23058   save_line_number = vam->input_line_number;
23059   save_current_file = (char *) vam->current_file;
23060
23061   vam->input_line_number = 0;
23062   vam->ifp = new_fp;
23063   vam->current_file = s;
23064   do_one_file (vam);
23065
23066   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23067   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23068   vam->ifp = save_ifp;
23069   vam->input_line_number = save_line_number;
23070   vam->current_file = (u8 *) save_current_file;
23071   vec_free (s);
23072
23073   return 0;
23074 #else
23075   clib_warning ("use the exec command...");
23076   return -99;
23077 #endif
23078 }
23079
23080 static int
23081 echo (vat_main_t * vam)
23082 {
23083   print (vam->ofp, "%v", vam->input->buffer);
23084   return 0;
23085 }
23086
23087 /* List of API message constructors, CLI names map to api_xxx */
23088 #define foreach_vpe_api_msg                                             \
23089 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23090 _(sw_interface_dump,"")                                                 \
23091 _(sw_interface_set_flags,                                               \
23092   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23093 _(sw_interface_add_del_address,                                         \
23094   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23095 _(sw_interface_set_rx_mode,                                             \
23096   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23097 _(sw_interface_set_rx_placement,                                        \
23098   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23099 _(sw_interface_rx_placement_dump,                                       \
23100   "[<intfc> | sw_if_index <id>]")                                         \
23101 _(sw_interface_set_table,                                               \
23102   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23103 _(sw_interface_set_mpls_enable,                                         \
23104   "<intfc> | sw_if_index [disable | dis]")                              \
23105 _(sw_interface_set_vpath,                                               \
23106   "<intfc> | sw_if_index <id> enable | disable")                        \
23107 _(sw_interface_set_vxlan_bypass,                                        \
23108   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23109 _(sw_interface_set_geneve_bypass,                                       \
23110   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23111 _(sw_interface_set_l2_xconnect,                                         \
23112   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23113   "enable | disable")                                                   \
23114 _(sw_interface_set_l2_bridge,                                           \
23115   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23116   "[shg <split-horizon-group>] [bvi]\n"                                 \
23117   "enable | disable")                                                   \
23118 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23119 _(bridge_domain_add_del,                                                \
23120   "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") \
23121 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23122 _(l2fib_add_del,                                                        \
23123   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23124 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23125 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23126 _(l2_flags,                                                             \
23127   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23128 _(bridge_flags,                                                         \
23129   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23130 _(tap_connect,                                                          \
23131   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23132 _(tap_modify,                                                           \
23133   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23134 _(tap_delete,                                                           \
23135   "<vpp-if-name> | sw_if_index <id>")                                   \
23136 _(sw_interface_tap_dump, "")                                            \
23137 _(tap_create_v2,                                                        \
23138   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23139 _(tap_delete_v2,                                                        \
23140   "<vpp-if-name> | sw_if_index <id>")                                   \
23141 _(sw_interface_tap_v2_dump, "")                                         \
23142 _(bond_create,                                                          \
23143   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23144   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23145 _(bond_delete,                                                          \
23146   "<vpp-if-name> | sw_if_index <id>")                                   \
23147 _(bond_enslave,                                                         \
23148   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23149 _(bond_detach_slave,                                                    \
23150   "sw_if_index <n>")                                                    \
23151 _(sw_interface_bond_dump, "")                                           \
23152 _(sw_interface_slave_dump,                                              \
23153   "<vpp-if-name> | sw_if_index <id>")                                   \
23154 _(ip_table_add_del,                                                     \
23155   "table <n> [ipv6] [add | del]\n")                                     \
23156 _(ip_add_del_route,                                                     \
23157   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23158   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23159   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23160   "[multipath] [count <n>] [del]")                                      \
23161 _(ip_mroute_add_del,                                                    \
23162   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23163   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23164 _(mpls_table_add_del,                                                   \
23165   "table <n> [add | del]\n")                                            \
23166 _(mpls_route_add_del,                                                   \
23167   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23168   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23169   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23170   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23171   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23172   "[count <n>] [del]")                                                  \
23173 _(mpls_ip_bind_unbind,                                                  \
23174   "<label> <addr/len>")                                                 \
23175 _(mpls_tunnel_add_del,                                                  \
23176   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23177   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23178   "[l2-only]  [out-label <n>]")                                         \
23179 _(sr_mpls_policy_add,                                                   \
23180   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23181 _(sr_mpls_policy_del,                                                   \
23182   "bsid <id>")                                                          \
23183 _(bier_table_add_del,                                                   \
23184   "<label> <sub-domain> <set> <bsl> [del]")                             \
23185 _(bier_route_add_del,                                                   \
23186   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23187   "[<intfc> | sw_if_index <id>]"                                        \
23188   "[weight <n>] [del] [multipath]")                                     \
23189 _(proxy_arp_add_del,                                                    \
23190   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23191 _(proxy_arp_intfc_enable_disable,                                       \
23192   "<intfc> | sw_if_index <id> enable | disable")                        \
23193 _(sw_interface_set_unnumbered,                                          \
23194   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23195 _(ip_neighbor_add_del,                                                  \
23196   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23197   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23198 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23199 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23200   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23201   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23202   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23203 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23204 _(reset_fib, "vrf <n> [ipv6]")                                          \
23205 _(dhcp_proxy_config,                                                    \
23206   "svr <v46-address> src <v46-address>\n"                               \
23207    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23208 _(dhcp_proxy_set_vss,                                                   \
23209   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23210 _(dhcp_proxy_dump, "ip6")                                               \
23211 _(dhcp_client_config,                                                   \
23212   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23213 _(set_ip_flow_hash,                                                     \
23214   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23215 _(sw_interface_ip6_enable_disable,                                      \
23216   "<intfc> | sw_if_index <id> enable | disable")                        \
23217 _(ip6nd_proxy_add_del,                                                  \
23218   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23219 _(ip6nd_proxy_dump, "")                                                 \
23220 _(sw_interface_ip6nd_ra_prefix,                                         \
23221   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23222   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23223   "[nolink] [isno]")                                                    \
23224 _(sw_interface_ip6nd_ra_config,                                         \
23225   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23226   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23227   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23228 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23229 _(l2_patch_add_del,                                                     \
23230   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23231   "enable | disable")                                                   \
23232 _(sr_localsid_add_del,                                                  \
23233   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23234   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23235 _(classify_add_del_table,                                               \
23236   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23237   " [del] [del-chain] mask <mask-value>\n"                              \
23238   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23239   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23240 _(classify_add_del_session,                                             \
23241   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23242   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23243   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23244   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23245 _(classify_set_interface_ip_table,                                      \
23246   "<intfc> | sw_if_index <nn> table <nn>")                              \
23247 _(classify_set_interface_l2_tables,                                     \
23248   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23249   "  [other-table <nn>]")                                               \
23250 _(get_node_index, "node <node-name")                                    \
23251 _(add_node_next, "node <node-name> next <next-node-name>")              \
23252 _(l2tpv3_create_tunnel,                                                 \
23253   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23254   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23255   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23256 _(l2tpv3_set_tunnel_cookies,                                            \
23257   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23258   "[new_remote_cookie <nn>]\n")                                         \
23259 _(l2tpv3_interface_enable_disable,                                      \
23260   "<intfc> | sw_if_index <nn> enable | disable")                        \
23261 _(l2tpv3_set_lookup_key,                                                \
23262   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23263 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23264 _(vxlan_offload_rx,                                                     \
23265   "hw { <interface name> | hw_if_index <nn>} "                          \
23266   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23267 _(vxlan_add_del_tunnel,                                                 \
23268   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23269   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23270   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23271 _(geneve_add_del_tunnel,                                                \
23272   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23273   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23274   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23275 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23276 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23277 _(gre_add_del_tunnel,                                                   \
23278   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23279   "[teb | erspan <session-id>] [del]")                                  \
23280 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23281 _(l2_fib_clear_table, "")                                               \
23282 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23283 _(l2_interface_vlan_tag_rewrite,                                        \
23284   "<intfc> | sw_if_index <nn> \n"                                       \
23285   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23286   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23287 _(create_vhost_user_if,                                                 \
23288         "socket <filename> [server] [renumber <dev_instance>] "         \
23289         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23290         "[mac <mac_address>]")                                          \
23291 _(modify_vhost_user_if,                                                 \
23292         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23293         "[server] [renumber <dev_instance>]")                           \
23294 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23295 _(sw_interface_vhost_user_dump, "")                                     \
23296 _(show_version, "")                                                     \
23297 _(show_threads, "")                                                     \
23298 _(vxlan_gpe_add_del_tunnel,                                             \
23299   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23300   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23301   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23302   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23303 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23304 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23305 _(interface_name_renumber,                                              \
23306   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23307 _(input_acl_set_interface,                                              \
23308   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23309   "  [l2-table <nn>] [del]")                                            \
23310 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23311 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23312   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23313 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23314 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23315 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23316 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23317 _(ip_dump, "ipv4 | ipv6")                                               \
23318 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23319 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23320   "  spid_id <n> ")                                                     \
23321 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23322   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23323   "  integ_alg <alg> integ_key <hex>")                                  \
23324 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23325   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23326   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23327   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23328 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23329 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23330   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23331   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23332   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23333   "  [instance <n>]")     \
23334 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23335 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23336   "  <alg> <hex>\n")                                                    \
23337 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23338 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23339 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23340   "(auth_data 0x<data> | auth_data <data>)")                            \
23341 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23342   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23343 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23344   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23345   "(local|remote)")                                                     \
23346 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23347 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23348 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23349 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23350 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23351 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23352 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23353 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23354 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23355 _(delete_loopback,"sw_if_index <nn>")                                   \
23356 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23357 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23358 _(want_interface_events,  "enable|disable")                             \
23359 _(get_first_msg_id, "client <name>")                                    \
23360 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23361 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23362   "fib-id <nn> [ip4][ip6][default]")                                    \
23363 _(get_node_graph, " ")                                                  \
23364 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23365 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23366 _(ioam_disable, "")                                                     \
23367 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23368                             " sw_if_index <sw_if_index> p <priority> "  \
23369                             "w <weight>] [del]")                        \
23370 _(one_add_del_locator, "locator-set <locator_name> "                    \
23371                         "iface <intf> | sw_if_index <sw_if_index> "     \
23372                         "p <priority> w <weight> [del]")                \
23373 _(one_add_del_local_eid,"vni <vni> eid "                                \
23374                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23375                          "locator-set <locator_name> [del]"             \
23376                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23377 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23378 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23379 _(one_enable_disable, "enable|disable")                                 \
23380 _(one_map_register_enable_disable, "enable|disable")                    \
23381 _(one_map_register_fallback_threshold, "<value>")                       \
23382 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23383 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23384                                "[seid <seid>] "                         \
23385                                "rloc <locator> p <prio> "               \
23386                                "w <weight> [rloc <loc> ... ] "          \
23387                                "action <action> [del-all]")             \
23388 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23389                           "<local-eid>")                                \
23390 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23391 _(one_use_petr, "ip-address> | disable")                                \
23392 _(one_map_request_mode, "src-dst|dst-only")                             \
23393 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23394 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23395 _(one_locator_set_dump, "[local | remote]")                             \
23396 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23397 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23398                        "[local] | [remote]")                            \
23399 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23400 _(one_ndp_bd_get, "")                                                   \
23401 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23402 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23403 _(one_l2_arp_bd_get, "")                                                \
23404 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23405 _(one_stats_enable_disable, "enable|disable")                           \
23406 _(show_one_stats_enable_disable, "")                                    \
23407 _(one_eid_table_vni_dump, "")                                           \
23408 _(one_eid_table_map_dump, "l2|l3")                                      \
23409 _(one_map_resolver_dump, "")                                            \
23410 _(one_map_server_dump, "")                                              \
23411 _(one_adjacencies_get, "vni <vni>")                                     \
23412 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23413 _(show_one_rloc_probe_state, "")                                        \
23414 _(show_one_map_register_state, "")                                      \
23415 _(show_one_status, "")                                                  \
23416 _(one_stats_dump, "")                                                   \
23417 _(one_stats_flush, "")                                                  \
23418 _(one_get_map_request_itr_rlocs, "")                                    \
23419 _(one_map_register_set_ttl, "<ttl>")                                    \
23420 _(one_set_transport_protocol, "udp|api")                                \
23421 _(one_get_transport_protocol, "")                                       \
23422 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23423 _(one_show_xtr_mode, "")                                                \
23424 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23425 _(one_show_pitr_mode, "")                                               \
23426 _(one_enable_disable_petr_mode, "enable|disable")                       \
23427 _(one_show_petr_mode, "")                                               \
23428 _(show_one_nsh_mapping, "")                                             \
23429 _(show_one_pitr, "")                                                    \
23430 _(show_one_use_petr, "")                                                \
23431 _(show_one_map_request_mode, "")                                        \
23432 _(show_one_map_register_ttl, "")                                        \
23433 _(show_one_map_register_fallback_threshold, "")                         \
23434 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23435                             " sw_if_index <sw_if_index> p <priority> "  \
23436                             "w <weight>] [del]")                        \
23437 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23438                         "iface <intf> | sw_if_index <sw_if_index> "     \
23439                         "p <priority> w <weight> [del]")                \
23440 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23441                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23442                          "locator-set <locator_name> [del]"             \
23443                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23444 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23445 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23446 _(lisp_enable_disable, "enable|disable")                                \
23447 _(lisp_map_register_enable_disable, "enable|disable")                   \
23448 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23449 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23450                                "[seid <seid>] "                         \
23451                                "rloc <locator> p <prio> "               \
23452                                "w <weight> [rloc <loc> ... ] "          \
23453                                "action <action> [del-all]")             \
23454 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23455                           "<local-eid>")                                \
23456 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23457 _(lisp_use_petr, "<ip-address> | disable")                              \
23458 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23459 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23460 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23461 _(lisp_locator_set_dump, "[local | remote]")                            \
23462 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23463 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23464                        "[local] | [remote]")                            \
23465 _(lisp_eid_table_vni_dump, "")                                          \
23466 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23467 _(lisp_map_resolver_dump, "")                                           \
23468 _(lisp_map_server_dump, "")                                             \
23469 _(lisp_adjacencies_get, "vni <vni>")                                    \
23470 _(gpe_fwd_entry_vnis_get, "")                                           \
23471 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23472 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23473                                 "[table <table-id>]")                   \
23474 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23475 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23476 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23477 _(gpe_get_encap_mode, "")                                               \
23478 _(lisp_gpe_add_del_iface, "up|down")                                    \
23479 _(lisp_gpe_enable_disable, "enable|disable")                            \
23480 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23481   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23482 _(show_lisp_rloc_probe_state, "")                                       \
23483 _(show_lisp_map_register_state, "")                                     \
23484 _(show_lisp_status, "")                                                 \
23485 _(lisp_get_map_request_itr_rlocs, "")                                   \
23486 _(show_lisp_pitr, "")                                                   \
23487 _(show_lisp_use_petr, "")                                               \
23488 _(show_lisp_map_request_mode, "")                                       \
23489 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23490 _(af_packet_delete, "name <host interface name>")                       \
23491 _(af_packet_dump, "")                                                   \
23492 _(policer_add_del, "name <policer name> <params> [del]")                \
23493 _(policer_dump, "[name <policer name>]")                                \
23494 _(policer_classify_set_interface,                                       \
23495   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23496   "  [l2-table <nn>] [del]")                                            \
23497 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23498 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23499     "[master|slave]")                                                   \
23500 _(netmap_delete, "name <interface name>")                               \
23501 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23502 _(mpls_fib_dump, "")                                                    \
23503 _(classify_table_ids, "")                                               \
23504 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23505 _(classify_table_info, "table_id <nn>")                                 \
23506 _(classify_session_dump, "table_id <nn>")                               \
23507 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23508     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23509     "[template_interval <nn>] [udp_checksum]")                          \
23510 _(ipfix_exporter_dump, "")                                              \
23511 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23512 _(ipfix_classify_stream_dump, "")                                       \
23513 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23514 _(ipfix_classify_table_dump, "")                                        \
23515 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23516 _(sw_interface_span_dump, "[l2]")                                           \
23517 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23518 _(pg_create_interface, "if_id <nn>")                                    \
23519 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23520 _(pg_enable_disable, "[stream <id>] disable")                           \
23521 _(ip_source_and_port_range_check_add_del,                               \
23522   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23523 _(ip_source_and_port_range_check_interface_add_del,                     \
23524   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23525   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23526 _(ipsec_gre_add_del_tunnel,                                             \
23527   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23528 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23529 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23530 _(l2_interface_pbb_tag_rewrite,                                         \
23531   "<intfc> | sw_if_index <nn> \n"                                       \
23532   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23533   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23534 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23535 _(flow_classify_set_interface,                                          \
23536   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23537 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23538 _(ip_fib_dump, "")                                                      \
23539 _(ip_mfib_dump, "")                                                     \
23540 _(ip6_fib_dump, "")                                                     \
23541 _(ip6_mfib_dump, "")                                                    \
23542 _(feature_enable_disable, "arc_name <arc_name> "                        \
23543   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23544 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23545 "[disable]")                                                            \
23546 _(l2_xconnect_dump, "")                                                 \
23547 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23548 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23549 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23550 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23551 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23552 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23553 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23554   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23555 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23556 _(sock_init_shm, "size <nnn>")                                          \
23557 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23558 _(dns_enable_disable, "[enable][disable]")                              \
23559 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23560 _(dns_resolve_name, "<hostname>")                                       \
23561 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23562 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23563 _(dns_resolve_name, "<hostname>")                                       \
23564 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23565   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23566 _(session_rules_dump, "")                                               \
23567 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23568 _(output_acl_set_interface,                                             \
23569   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23570   "  [l2-table <nn>] [del]")                                            \
23571 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23572
23573 /* List of command functions, CLI names map directly to functions */
23574 #define foreach_cli_function                                    \
23575 _(comment, "usage: comment <ignore-rest-of-line>")              \
23576 _(dump_interface_table, "usage: dump_interface_table")          \
23577 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23578 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23579 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23580 _(dump_macro_table, "usage: dump_macro_table ")                 \
23581 _(dump_node_table, "usage: dump_node_table")                    \
23582 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23583 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23584 _(echo, "usage: echo <message>")                                \
23585 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23586 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23587 _(help, "usage: help")                                          \
23588 _(q, "usage: quit")                                             \
23589 _(quit, "usage: quit")                                          \
23590 _(search_node_table, "usage: search_node_table <name>...")      \
23591 _(set, "usage: set <variable-name> <value>")                    \
23592 _(script, "usage: script <file-name>")                          \
23593 _(statseg, "usage: statseg");                                   \
23594 _(unset, "usage: unset <variable-name>")
23595
23596 #define _(N,n)                                  \
23597     static void vl_api_##n##_t_handler_uni      \
23598     (vl_api_##n##_t * mp)                       \
23599     {                                           \
23600         vat_main_t * vam = &vat_main;           \
23601         if (vam->json_output) {                 \
23602             vl_api_##n##_t_handler_json(mp);    \
23603         } else {                                \
23604             vl_api_##n##_t_handler(mp);         \
23605         }                                       \
23606     }
23607 foreach_vpe_api_reply_msg;
23608 #if VPP_API_TEST_BUILTIN == 0
23609 foreach_standalone_reply_msg;
23610 #endif
23611 #undef _
23612
23613 void
23614 vat_api_hookup (vat_main_t * vam)
23615 {
23616 #define _(N,n)                                                  \
23617     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23618                            vl_api_##n##_t_handler_uni,          \
23619                            vl_noop_handler,                     \
23620                            vl_api_##n##_t_endian,               \
23621                            vl_api_##n##_t_print,                \
23622                            sizeof(vl_api_##n##_t), 1);
23623   foreach_vpe_api_reply_msg;
23624 #if VPP_API_TEST_BUILTIN == 0
23625   foreach_standalone_reply_msg;
23626 #endif
23627 #undef _
23628
23629 #if (VPP_API_TEST_BUILTIN==0)
23630   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23631
23632   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23633
23634   vam->function_by_name = hash_create_string (0, sizeof (uword));
23635
23636   vam->help_by_name = hash_create_string (0, sizeof (uword));
23637 #endif
23638
23639   /* API messages we can send */
23640 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23641   foreach_vpe_api_msg;
23642 #undef _
23643
23644   /* Help strings */
23645 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23646   foreach_vpe_api_msg;
23647 #undef _
23648
23649   /* CLI functions */
23650 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23651   foreach_cli_function;
23652 #undef _
23653
23654   /* Help strings */
23655 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23656   foreach_cli_function;
23657 #undef _
23658 }
23659
23660 #if VPP_API_TEST_BUILTIN
23661 static clib_error_t *
23662 vat_api_hookup_shim (vlib_main_t * vm)
23663 {
23664   vat_api_hookup (&vat_main);
23665   return 0;
23666 }
23667
23668 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23669 #endif
23670
23671 /*
23672  * fd.io coding-style-patch-verification: ON
23673  *
23674  * Local Variables:
23675  * eval: (c-set-style "gnu")
23676  * End:
23677  */