sock api: add infra for bootstrapping shm clients
[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 <vppinfra/socket.h>
22 #include <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/input_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.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
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   vam->socket_client_main = &socket_client_main;
92   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
93                                    0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 int
103 vl_socket_client_read (int wait)
104 {
105   return -1;
106 };
107
108 int
109 vl_socket_client_write ()
110 {
111   return -1;
112 };
113
114 void *
115 vl_socket_client_msg_alloc (int nbytes)
116 {
117   return 0;
118 }
119 #endif
120
121
122 f64
123 vat_time_now (vat_main_t * vam)
124 {
125 #if VPP_API_TEST_BUILTIN
126   return vlib_time_now (vam->vlib_main);
127 #else
128   return clib_time_now (&vam->clib_time);
129 #endif
130 }
131
132 void
133 errmsg (char *fmt, ...)
134 {
135   vat_main_t *vam = &vat_main;
136   va_list va;
137   u8 *s;
138
139   va_start (va, fmt);
140   s = va_format (0, fmt, &va);
141   va_end (va);
142
143   vec_add1 (s, 0);
144
145 #if VPP_API_TEST_BUILTIN
146   vlib_cli_output (vam->vlib_main, (char *) s);
147 #else
148   {
149     if (vam->ifp != stdin)
150       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
151                vam->input_line_number);
152     fformat (vam->ofp, (char *) s);
153     fflush (vam->ofp);
154   }
155 #endif
156
157   vec_free (s);
158 }
159
160 #if VPP_API_TEST_BUILTIN == 0
161 static uword
162 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
163 {
164   vat_main_t *vam = va_arg (*args, vat_main_t *);
165   u32 *result = va_arg (*args, u32 *);
166   u8 *if_name;
167   uword *p;
168
169   if (!unformat (input, "%s", &if_name))
170     return 0;
171
172   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
173   if (p == 0)
174     return 0;
175   *result = p[0];
176   return 1;
177 }
178
179 /* Parse an IP4 address %d.%d.%d.%d. */
180 uword
181 unformat_ip4_address (unformat_input_t * input, va_list * args)
182 {
183   u8 *result = va_arg (*args, u8 *);
184   unsigned a[4];
185
186   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
187     return 0;
188
189   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
190     return 0;
191
192   result[0] = a[0];
193   result[1] = a[1];
194   result[2] = a[2];
195   result[3] = a[3];
196
197   return 1;
198 }
199
200 uword
201 unformat_ethernet_address (unformat_input_t * input, va_list * args)
202 {
203   u8 *result = va_arg (*args, u8 *);
204   u32 i, a[6];
205
206   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
207                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
208     return 0;
209
210   /* Check range. */
211   for (i = 0; i < 6; i++)
212     if (a[i] >= (1 << 8))
213       return 0;
214
215   for (i = 0; i < 6; i++)
216     result[i] = a[i];
217
218   return 1;
219 }
220
221 /* Returns ethernet type as an int in host byte order. */
222 uword
223 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
224                                         va_list * args)
225 {
226   u16 *result = va_arg (*args, u16 *);
227   int type;
228
229   /* Numeric type. */
230   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
231     {
232       if (type >= (1 << 16))
233         return 0;
234       *result = type;
235       return 1;
236     }
237   return 0;
238 }
239
240 /* Parse an IP6 address. */
241 uword
242 unformat_ip6_address (unformat_input_t * input, va_list * args)
243 {
244   ip6_address_t *result = va_arg (*args, ip6_address_t *);
245   u16 hex_quads[8];
246   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
247   uword c, n_colon, double_colon_index;
248
249   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
250   double_colon_index = ARRAY_LEN (hex_quads);
251   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
252     {
253       hex_digit = 16;
254       if (c >= '0' && c <= '9')
255         hex_digit = c - '0';
256       else if (c >= 'a' && c <= 'f')
257         hex_digit = c + 10 - 'a';
258       else if (c >= 'A' && c <= 'F')
259         hex_digit = c + 10 - 'A';
260       else if (c == ':' && n_colon < 2)
261         n_colon++;
262       else
263         {
264           unformat_put_input (input);
265           break;
266         }
267
268       /* Too many hex quads. */
269       if (n_hex_quads >= ARRAY_LEN (hex_quads))
270         return 0;
271
272       if (hex_digit < 16)
273         {
274           hex_quad = (hex_quad << 4) | hex_digit;
275
276           /* Hex quad must fit in 16 bits. */
277           if (n_hex_digits >= 4)
278             return 0;
279
280           n_colon = 0;
281           n_hex_digits++;
282         }
283
284       /* Save position of :: */
285       if (n_colon == 2)
286         {
287           /* More than one :: ? */
288           if (double_colon_index < ARRAY_LEN (hex_quads))
289             return 0;
290           double_colon_index = n_hex_quads;
291         }
292
293       if (n_colon > 0 && n_hex_digits > 0)
294         {
295           hex_quads[n_hex_quads++] = hex_quad;
296           hex_quad = 0;
297           n_hex_digits = 0;
298         }
299     }
300
301   if (n_hex_digits > 0)
302     hex_quads[n_hex_quads++] = hex_quad;
303
304   {
305     word i;
306
307     /* Expand :: to appropriate number of zero hex quads. */
308     if (double_colon_index < ARRAY_LEN (hex_quads))
309       {
310         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
311
312         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
313           hex_quads[n_zero + i] = hex_quads[i];
314
315         for (i = 0; i < n_zero; i++)
316           hex_quads[double_colon_index + i] = 0;
317
318         n_hex_quads = ARRAY_LEN (hex_quads);
319       }
320
321     /* Too few hex quads given. */
322     if (n_hex_quads < ARRAY_LEN (hex_quads))
323       return 0;
324
325     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
326       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
327
328     return 1;
329   }
330 }
331
332 uword
333 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
339   foreach_ipsec_policy_action
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 uword
347 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
348 {
349   u32 *r = va_arg (*args, u32 *);
350
351   if (0);
352 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
353   foreach_ipsec_crypto_alg
354 #undef _
355     else
356     return 0;
357   return 1;
358 }
359
360 u8 *
361 format_ipsec_crypto_alg (u8 * s, va_list * args)
362 {
363   u32 i = va_arg (*args, u32);
364   u8 *t = 0;
365
366   switch (i)
367     {
368 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
369       foreach_ipsec_crypto_alg
370 #undef _
371     default:
372       return format (s, "unknown");
373     }
374   return format (s, "%s", t);
375 }
376
377 uword
378 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
384   foreach_ipsec_integ_alg
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390
391 u8 *
392 format_ipsec_integ_alg (u8 * s, va_list * args)
393 {
394   u32 i = va_arg (*args, u32);
395   u8 *t = 0;
396
397   switch (i)
398     {
399 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
400       foreach_ipsec_integ_alg
401 #undef _
402     default:
403       return format (s, "unknown");
404     }
405   return format (s, "%s", t);
406 }
407
408 uword
409 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
410 {
411   u32 *r = va_arg (*args, u32 *);
412
413   if (0);
414 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
415   foreach_ikev2_auth_method
416 #undef _
417     else
418     return 0;
419   return 1;
420 }
421
422 uword
423 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
424 {
425   u32 *r = va_arg (*args, u32 *);
426
427   if (0);
428 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
429   foreach_ikev2_id_type
430 #undef _
431     else
432     return 0;
433   return 1;
434 }
435 #else /* VPP_API_TEST_BUILTIN == 1 */
436 static uword
437 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
438 {
439   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
440   vnet_main_t *vnm = vnet_get_main ();
441   u32 *result = va_arg (*args, u32 *);
442   u32 sw_if_index;
443
444   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
445     return 0;
446
447   *result = sw_if_index;
448   return 1;
449 }
450 #endif /* VPP_API_TEST_BUILTIN */
451
452 static uword
453 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
454 {
455   u8 *r = va_arg (*args, u8 *);
456
457   if (unformat (input, "kbps"))
458     *r = SSE2_QOS_RATE_KBPS;
459   else if (unformat (input, "pps"))
460     *r = SSE2_QOS_RATE_PPS;
461   else
462     return 0;
463   return 1;
464 }
465
466 static uword
467 unformat_policer_round_type (unformat_input_t * input, va_list * args)
468 {
469   u8 *r = va_arg (*args, u8 *);
470
471   if (unformat (input, "closest"))
472     *r = SSE2_QOS_ROUND_TO_CLOSEST;
473   else if (unformat (input, "up"))
474     *r = SSE2_QOS_ROUND_TO_UP;
475   else if (unformat (input, "down"))
476     *r = SSE2_QOS_ROUND_TO_DOWN;
477   else
478     return 0;
479   return 1;
480 }
481
482 static uword
483 unformat_policer_type (unformat_input_t * input, va_list * args)
484 {
485   u8 *r = va_arg (*args, u8 *);
486
487   if (unformat (input, "1r2c"))
488     *r = SSE2_QOS_POLICER_TYPE_1R2C;
489   else if (unformat (input, "1r3c"))
490     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
491   else if (unformat (input, "2r3c-2698"))
492     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
493   else if (unformat (input, "2r3c-4115"))
494     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
495   else if (unformat (input, "2r3c-mef5cf1"))
496     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
497   else
498     return 0;
499   return 1;
500 }
501
502 static uword
503 unformat_dscp (unformat_input_t * input, va_list * va)
504 {
505   u8 *r = va_arg (*va, u8 *);
506
507   if (0);
508 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
509   foreach_vnet_dscp
510 #undef _
511     else
512     return 0;
513   return 1;
514 }
515
516 static uword
517 unformat_policer_action_type (unformat_input_t * input, va_list * va)
518 {
519   sse2_qos_pol_action_params_st *a
520     = va_arg (*va, sse2_qos_pol_action_params_st *);
521
522   if (unformat (input, "drop"))
523     a->action_type = SSE2_QOS_ACTION_DROP;
524   else if (unformat (input, "transmit"))
525     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
526   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
527     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
528   else
529     return 0;
530   return 1;
531 }
532
533 static uword
534 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
535 {
536   u32 *r = va_arg (*va, u32 *);
537   u32 tid;
538
539   if (unformat (input, "ip4"))
540     tid = POLICER_CLASSIFY_TABLE_IP4;
541   else if (unformat (input, "ip6"))
542     tid = POLICER_CLASSIFY_TABLE_IP6;
543   else if (unformat (input, "l2"))
544     tid = POLICER_CLASSIFY_TABLE_L2;
545   else
546     return 0;
547
548   *r = tid;
549   return 1;
550 }
551
552 static uword
553 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
554 {
555   u32 *r = va_arg (*va, u32 *);
556   u32 tid;
557
558   if (unformat (input, "ip4"))
559     tid = FLOW_CLASSIFY_TABLE_IP4;
560   else if (unformat (input, "ip6"))
561     tid = FLOW_CLASSIFY_TABLE_IP6;
562   else
563     return 0;
564
565   *r = tid;
566   return 1;
567 }
568
569 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
570 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
571 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
572 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
573
574 #if (VPP_API_TEST_BUILTIN==0)
575 uword
576 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
577 {
578   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
579   mfib_itf_attribute_t attr;
580
581   old = *iflags;
582   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
583   {
584     if (unformat (input, mfib_itf_flag_long_names[attr]))
585       *iflags |= (1 << attr);
586   }
587   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
588   {
589     if (unformat (input, mfib_itf_flag_names[attr]))
590       *iflags |= (1 << attr);
591   }
592
593   return (old == *iflags ? 0 : 1);
594 }
595
596 uword
597 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
598 {
599   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
600   mfib_entry_attribute_t attr;
601
602   old = *eflags;
603   FOR_EACH_MFIB_ATTRIBUTE (attr)
604   {
605     if (unformat (input, mfib_flag_long_names[attr]))
606       *eflags |= (1 << attr);
607   }
608   FOR_EACH_MFIB_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_flag_names[attr]))
611       *eflags |= (1 << attr);
612   }
613
614   return (old == *eflags ? 0 : 1);
615 }
616
617 u8 *
618 format_ip4_address (u8 * s, va_list * args)
619 {
620   u8 *a = va_arg (*args, u8 *);
621   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
622 }
623
624 u8 *
625 format_ip6_address (u8 * s, va_list * args)
626 {
627   ip6_address_t *a = va_arg (*args, ip6_address_t *);
628   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
629
630   i_max_n_zero = ARRAY_LEN (a->as_u16);
631   max_n_zeros = 0;
632   i_first_zero = i_max_n_zero;
633   n_zeros = 0;
634   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
635     {
636       u32 is_zero = a->as_u16[i] == 0;
637       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
638         {
639           i_first_zero = i;
640           n_zeros = 0;
641         }
642       n_zeros += is_zero;
643       if ((!is_zero && n_zeros > max_n_zeros)
644           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
645         {
646           i_max_n_zero = i_first_zero;
647           max_n_zeros = n_zeros;
648           i_first_zero = ARRAY_LEN (a->as_u16);
649           n_zeros = 0;
650         }
651     }
652
653   last_double_colon = 0;
654   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
655     {
656       if (i == i_max_n_zero && max_n_zeros > 1)
657         {
658           s = format (s, "::");
659           i += max_n_zeros - 1;
660           last_double_colon = 1;
661         }
662       else
663         {
664           s = format (s, "%s%x",
665                       (last_double_colon || i == 0) ? "" : ":",
666                       clib_net_to_host_u16 (a->as_u16[i]));
667           last_double_colon = 0;
668         }
669     }
670
671   return s;
672 }
673
674 /* Format an IP46 address. */
675 u8 *
676 format_ip46_address (u8 * s, va_list * args)
677 {
678   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
679   ip46_type_t type = va_arg (*args, ip46_type_t);
680   int is_ip4 = 1;
681
682   switch (type)
683     {
684     case IP46_TYPE_ANY:
685       is_ip4 = ip46_address_is_ip4 (ip46);
686       break;
687     case IP46_TYPE_IP4:
688       is_ip4 = 1;
689       break;
690     case IP46_TYPE_IP6:
691       is_ip4 = 0;
692       break;
693     }
694
695   return is_ip4 ?
696     format (s, "%U", format_ip4_address, &ip46->ip4) :
697     format (s, "%U", format_ip6_address, &ip46->ip6);
698 }
699
700 u8 *
701 format_ethernet_address (u8 * s, va_list * args)
702 {
703   u8 *a = va_arg (*args, u8 *);
704
705   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
706                  a[0], a[1], a[2], a[3], a[4], a[5]);
707 }
708 #endif
709
710 static void
711 increment_v4_address (ip4_address_t * a)
712 {
713   u32 v;
714
715   v = ntohl (a->as_u32) + 1;
716   a->as_u32 = ntohl (v);
717 }
718
719 static void
720 increment_v6_address (ip6_address_t * a)
721 {
722   u64 v0, v1;
723
724   v0 = clib_net_to_host_u64 (a->as_u64[0]);
725   v1 = clib_net_to_host_u64 (a->as_u64[1]);
726
727   v1 += 1;
728   if (v1 == 0)
729     v0 += 1;
730   a->as_u64[0] = clib_net_to_host_u64 (v0);
731   a->as_u64[1] = clib_net_to_host_u64 (v1);
732 }
733
734 static void
735 increment_mac_address (u8 * mac)
736 {
737   u64 tmp = *((u64 *) mac);
738   tmp = clib_net_to_host_u64 (tmp);
739   tmp += 1 << 16;               /* skip unused (least significant) octets */
740   tmp = clib_host_to_net_u64 (tmp);
741
742   clib_memcpy (mac, &tmp, 6);
743 }
744
745 static void vl_api_create_loopback_reply_t_handler
746   (vl_api_create_loopback_reply_t * mp)
747 {
748   vat_main_t *vam = &vat_main;
749   i32 retval = ntohl (mp->retval);
750
751   vam->retval = retval;
752   vam->regenerate_interface_table = 1;
753   vam->sw_if_index = ntohl (mp->sw_if_index);
754   vam->result_ready = 1;
755 }
756
757 static void vl_api_create_loopback_reply_t_handler_json
758   (vl_api_create_loopback_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   vat_json_node_t node;
762
763   vat_json_init_object (&node);
764   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
765   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
766
767   vat_json_print (vam->ofp, &node);
768   vat_json_free (&node);
769   vam->retval = ntohl (mp->retval);
770   vam->result_ready = 1;
771 }
772
773 static void vl_api_create_loopback_instance_reply_t_handler
774   (vl_api_create_loopback_instance_reply_t * mp)
775 {
776   vat_main_t *vam = &vat_main;
777   i32 retval = ntohl (mp->retval);
778
779   vam->retval = retval;
780   vam->regenerate_interface_table = 1;
781   vam->sw_if_index = ntohl (mp->sw_if_index);
782   vam->result_ready = 1;
783 }
784
785 static void vl_api_create_loopback_instance_reply_t_handler_json
786   (vl_api_create_loopback_instance_reply_t * mp)
787 {
788   vat_main_t *vam = &vat_main;
789   vat_json_node_t node;
790
791   vat_json_init_object (&node);
792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
793   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
794
795   vat_json_print (vam->ofp, &node);
796   vat_json_free (&node);
797   vam->retval = ntohl (mp->retval);
798   vam->result_ready = 1;
799 }
800
801 static void vl_api_af_packet_create_reply_t_handler
802   (vl_api_af_packet_create_reply_t * mp)
803 {
804   vat_main_t *vam = &vat_main;
805   i32 retval = ntohl (mp->retval);
806
807   vam->retval = retval;
808   vam->regenerate_interface_table = 1;
809   vam->sw_if_index = ntohl (mp->sw_if_index);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_af_packet_create_reply_t_handler_json
814   (vl_api_af_packet_create_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   vat_json_node_t node;
818
819   vat_json_init_object (&node);
820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
822
823   vat_json_print (vam->ofp, &node);
824   vat_json_free (&node);
825
826   vam->retval = ntohl (mp->retval);
827   vam->result_ready = 1;
828 }
829
830 static void vl_api_create_vlan_subif_reply_t_handler
831   (vl_api_create_vlan_subif_reply_t * mp)
832 {
833   vat_main_t *vam = &vat_main;
834   i32 retval = ntohl (mp->retval);
835
836   vam->retval = retval;
837   vam->regenerate_interface_table = 1;
838   vam->sw_if_index = ntohl (mp->sw_if_index);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_vlan_subif_reply_t_handler_json
843   (vl_api_create_vlan_subif_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   vat_json_node_t node;
847
848   vat_json_init_object (&node);
849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
850   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
851
852   vat_json_print (vam->ofp, &node);
853   vat_json_free (&node);
854
855   vam->retval = ntohl (mp->retval);
856   vam->result_ready = 1;
857 }
858
859 static void vl_api_create_subif_reply_t_handler
860   (vl_api_create_subif_reply_t * mp)
861 {
862   vat_main_t *vam = &vat_main;
863   i32 retval = ntohl (mp->retval);
864
865   vam->retval = retval;
866   vam->regenerate_interface_table = 1;
867   vam->sw_if_index = ntohl (mp->sw_if_index);
868   vam->result_ready = 1;
869 }
870
871 static void vl_api_create_subif_reply_t_handler_json
872   (vl_api_create_subif_reply_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   vat_json_node_t node;
876
877   vat_json_init_object (&node);
878   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
879   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
880
881   vat_json_print (vam->ofp, &node);
882   vat_json_free (&node);
883
884   vam->retval = ntohl (mp->retval);
885   vam->result_ready = 1;
886 }
887
888 static void vl_api_interface_name_renumber_reply_t_handler
889   (vl_api_interface_name_renumber_reply_t * mp)
890 {
891   vat_main_t *vam = &vat_main;
892   i32 retval = ntohl (mp->retval);
893
894   vam->retval = retval;
895   vam->regenerate_interface_table = 1;
896   vam->result_ready = 1;
897 }
898
899 static void vl_api_interface_name_renumber_reply_t_handler_json
900   (vl_api_interface_name_renumber_reply_t * mp)
901 {
902   vat_main_t *vam = &vat_main;
903   vat_json_node_t node;
904
905   vat_json_init_object (&node);
906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 /*
916  * Special-case: build the interface table, maintain
917  * the next loopback sw_if_index vbl.
918  */
919 static void vl_api_sw_interface_details_t_handler
920   (vl_api_sw_interface_details_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   u8 *s = format (0, "%s%c", mp->interface_name, 0);
924
925   hash_set_mem (vam->sw_if_index_by_interface_name, s,
926                 ntohl (mp->sw_if_index));
927
928   /* In sub interface case, fill the sub interface table entry */
929   if (mp->sw_if_index != mp->sup_sw_if_index)
930     {
931       sw_interface_subif_t *sub = NULL;
932
933       vec_add2 (vam->sw_if_subif_table, sub, 1);
934
935       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
936       strncpy ((char *) sub->interface_name, (char *) s,
937                vec_len (sub->interface_name));
938       sub->sw_if_index = ntohl (mp->sw_if_index);
939       sub->sub_id = ntohl (mp->sub_id);
940
941       sub->sub_dot1ad = mp->sub_dot1ad;
942       sub->sub_number_of_tags = mp->sub_number_of_tags;
943       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
944       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
945       sub->sub_exact_match = mp->sub_exact_match;
946       sub->sub_default = mp->sub_default;
947       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
948       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
949
950       /* vlan tag rewrite */
951       sub->vtr_op = ntohl (mp->vtr_op);
952       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
953       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
954       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
955     }
956 }
957
958 static void vl_api_sw_interface_details_t_handler_json
959   (vl_api_sw_interface_details_t * mp)
960 {
961   vat_main_t *vam = &vat_main;
962   vat_json_node_t *node = NULL;
963
964   if (VAT_JSON_ARRAY != vam->json_tree.type)
965     {
966       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
967       vat_json_init_array (&vam->json_tree);
968     }
969   node = vat_json_array_add (&vam->json_tree);
970
971   vat_json_init_object (node);
972   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
973   vat_json_object_add_uint (node, "sup_sw_if_index",
974                             ntohl (mp->sup_sw_if_index));
975   vat_json_object_add_uint (node, "l2_address_length",
976                             ntohl (mp->l2_address_length));
977   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
978                              sizeof (mp->l2_address));
979   vat_json_object_add_string_copy (node, "interface_name",
980                                    mp->interface_name);
981   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
982   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
983   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
984   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
985   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
986   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
987   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
988   vat_json_object_add_uint (node, "sub_number_of_tags",
989                             mp->sub_number_of_tags);
990   vat_json_object_add_uint (node, "sub_outer_vlan_id",
991                             ntohs (mp->sub_outer_vlan_id));
992   vat_json_object_add_uint (node, "sub_inner_vlan_id",
993                             ntohs (mp->sub_inner_vlan_id));
994   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
995   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
996   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
997                             mp->sub_outer_vlan_id_any);
998   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
999                             mp->sub_inner_vlan_id_any);
1000   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1001   vat_json_object_add_uint (node, "vtr_push_dot1q",
1002                             ntohl (mp->vtr_push_dot1q));
1003   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1004   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1005   if (mp->sub_dot1ah)
1006     {
1007       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1008                                        format (0, "%U",
1009                                                format_ethernet_address,
1010                                                &mp->b_dmac));
1011       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1012                                        format (0, "%U",
1013                                                format_ethernet_address,
1014                                                &mp->b_smac));
1015       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1016       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1017     }
1018 }
1019
1020 #if VPP_API_TEST_BUILTIN == 0
1021 static void vl_api_sw_interface_event_t_handler
1022   (vl_api_sw_interface_event_t * mp)
1023 {
1024   vat_main_t *vam = &vat_main;
1025   if (vam->interface_event_display)
1026     errmsg ("interface flags: sw_if_index %d %s %s",
1027             ntohl (mp->sw_if_index),
1028             mp->admin_up_down ? "admin-up" : "admin-down",
1029             mp->link_up_down ? "link-up" : "link-down");
1030 }
1031 #endif
1032
1033 static void vl_api_sw_interface_event_t_handler_json
1034   (vl_api_sw_interface_event_t * mp)
1035 {
1036   /* JSON output not supported */
1037 }
1038
1039 static void
1040 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1041 {
1042   vat_main_t *vam = &vat_main;
1043   i32 retval = ntohl (mp->retval);
1044
1045   vam->retval = retval;
1046   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void
1051 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055   api_main_t *am = &api_main;
1056   void *oldheap;
1057   u8 *reply;
1058
1059   vat_json_init_object (&node);
1060   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1061   vat_json_object_add_uint (&node, "reply_in_shmem",
1062                             ntohl (mp->reply_in_shmem));
1063   /* Toss the shared-memory original... */
1064   pthread_mutex_lock (&am->vlib_rp->mutex);
1065   oldheap = svm_push_data_heap (am->vlib_rp);
1066
1067   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1068   vec_free (reply);
1069
1070   svm_pop_heap (oldheap);
1071   pthread_mutex_unlock (&am->vlib_rp->mutex);
1072
1073   vat_json_print (vam->ofp, &node);
1074   vat_json_free (&node);
1075
1076   vam->retval = ntohl (mp->retval);
1077   vam->result_ready = 1;
1078 }
1079
1080 static void
1081 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1082 {
1083   vat_main_t *vam = &vat_main;
1084   i32 retval = ntohl (mp->retval);
1085   u32 length = ntohl (mp->length);
1086
1087   vec_reset_length (vam->cmd_reply);
1088
1089   vam->retval = retval;
1090   if (retval == 0)
1091     {
1092       vec_validate (vam->cmd_reply, length);
1093       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1094       vam->cmd_reply[length] = 0;
1095     }
1096   vam->result_ready = 1;
1097 }
1098
1099 static void
1100 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1101 {
1102   vat_main_t *vam = &vat_main;
1103   vat_json_node_t node;
1104
1105   vec_reset_length (vam->cmd_reply);
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1110
1111   vat_json_print (vam->ofp, &node);
1112   vat_json_free (&node);
1113
1114   vam->retval = ntohl (mp->retval);
1115   vam->result_ready = 1;
1116 }
1117
1118 static void vl_api_classify_add_del_table_reply_t_handler
1119   (vl_api_classify_add_del_table_reply_t * mp)
1120 {
1121   vat_main_t *vam = &vat_main;
1122   i32 retval = ntohl (mp->retval);
1123   if (vam->async_mode)
1124     {
1125       vam->async_errors += (retval < 0);
1126     }
1127   else
1128     {
1129       vam->retval = retval;
1130       if (retval == 0 &&
1131           ((mp->new_table_index != 0xFFFFFFFF) ||
1132            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1133            (mp->match_n_vectors != 0xFFFFFFFF)))
1134         /*
1135          * Note: this is just barely thread-safe, depends on
1136          * the main thread spinning waiting for an answer...
1137          */
1138         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1139                 ntohl (mp->new_table_index),
1140                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1141       vam->result_ready = 1;
1142     }
1143 }
1144
1145 static void vl_api_classify_add_del_table_reply_t_handler_json
1146   (vl_api_classify_add_del_table_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vat_json_init_object (&node);
1152   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1153   vat_json_object_add_uint (&node, "new_table_index",
1154                             ntohl (mp->new_table_index));
1155   vat_json_object_add_uint (&node, "skip_n_vectors",
1156                             ntohl (mp->skip_n_vectors));
1157   vat_json_object_add_uint (&node, "match_n_vectors",
1158                             ntohl (mp->match_n_vectors));
1159
1160   vat_json_print (vam->ofp, &node);
1161   vat_json_free (&node);
1162
1163   vam->retval = ntohl (mp->retval);
1164   vam->result_ready = 1;
1165 }
1166
1167 static void vl_api_get_node_index_reply_t_handler
1168   (vl_api_get_node_index_reply_t * mp)
1169 {
1170   vat_main_t *vam = &vat_main;
1171   i32 retval = ntohl (mp->retval);
1172   if (vam->async_mode)
1173     {
1174       vam->async_errors += (retval < 0);
1175     }
1176   else
1177     {
1178       vam->retval = retval;
1179       if (retval == 0)
1180         errmsg ("node index %d", ntohl (mp->node_index));
1181       vam->result_ready = 1;
1182     }
1183 }
1184
1185 static void vl_api_get_node_index_reply_t_handler_json
1186   (vl_api_get_node_index_reply_t * mp)
1187 {
1188   vat_main_t *vam = &vat_main;
1189   vat_json_node_t node;
1190
1191   vat_json_init_object (&node);
1192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1193   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1194
1195   vat_json_print (vam->ofp, &node);
1196   vat_json_free (&node);
1197
1198   vam->retval = ntohl (mp->retval);
1199   vam->result_ready = 1;
1200 }
1201
1202 static void vl_api_get_next_index_reply_t_handler
1203   (vl_api_get_next_index_reply_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   i32 retval = ntohl (mp->retval);
1207   if (vam->async_mode)
1208     {
1209       vam->async_errors += (retval < 0);
1210     }
1211   else
1212     {
1213       vam->retval = retval;
1214       if (retval == 0)
1215         errmsg ("next node index %d", ntohl (mp->next_index));
1216       vam->result_ready = 1;
1217     }
1218 }
1219
1220 static void vl_api_get_next_index_reply_t_handler_json
1221   (vl_api_get_next_index_reply_t * mp)
1222 {
1223   vat_main_t *vam = &vat_main;
1224   vat_json_node_t node;
1225
1226   vat_json_init_object (&node);
1227   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1228   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1229
1230   vat_json_print (vam->ofp, &node);
1231   vat_json_free (&node);
1232
1233   vam->retval = ntohl (mp->retval);
1234   vam->result_ready = 1;
1235 }
1236
1237 static void vl_api_add_node_next_reply_t_handler
1238   (vl_api_add_node_next_reply_t * mp)
1239 {
1240   vat_main_t *vam = &vat_main;
1241   i32 retval = ntohl (mp->retval);
1242   if (vam->async_mode)
1243     {
1244       vam->async_errors += (retval < 0);
1245     }
1246   else
1247     {
1248       vam->retval = retval;
1249       if (retval == 0)
1250         errmsg ("next index %d", ntohl (mp->next_index));
1251       vam->result_ready = 1;
1252     }
1253 }
1254
1255 static void vl_api_add_node_next_reply_t_handler_json
1256   (vl_api_add_node_next_reply_t * mp)
1257 {
1258   vat_main_t *vam = &vat_main;
1259   vat_json_node_t node;
1260
1261   vat_json_init_object (&node);
1262   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1263   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1264
1265   vat_json_print (vam->ofp, &node);
1266   vat_json_free (&node);
1267
1268   vam->retval = ntohl (mp->retval);
1269   vam->result_ready = 1;
1270 }
1271
1272 static void vl_api_show_version_reply_t_handler
1273   (vl_api_show_version_reply_t * mp)
1274 {
1275   vat_main_t *vam = &vat_main;
1276   i32 retval = ntohl (mp->retval);
1277
1278   if (retval >= 0)
1279     {
1280       errmsg ("        program: %s", mp->program);
1281       errmsg ("        version: %s", mp->version);
1282       errmsg ("     build date: %s", mp->build_date);
1283       errmsg ("build directory: %s", mp->build_directory);
1284     }
1285   vam->retval = retval;
1286   vam->result_ready = 1;
1287 }
1288
1289 static void vl_api_show_version_reply_t_handler_json
1290   (vl_api_show_version_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_string_copy (&node, "program", mp->program);
1298   vat_json_object_add_string_copy (&node, "version", mp->version);
1299   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1300   vat_json_object_add_string_copy (&node, "build_directory",
1301                                    mp->build_directory);
1302
1303   vat_json_print (vam->ofp, &node);
1304   vat_json_free (&node);
1305
1306   vam->retval = ntohl (mp->retval);
1307   vam->result_ready = 1;
1308 }
1309
1310 static void
1311 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1312 {
1313   u32 sw_if_index = ntohl (mp->sw_if_index);
1314   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1315           mp->mac_ip ? "mac/ip binding" : "address resolution",
1316           ntohl (mp->pid), format_ip4_address, &mp->address,
1317           format_ethernet_address, mp->new_mac, sw_if_index);
1318 }
1319
1320 static void
1321 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1322 {
1323   /* JSON output not supported */
1324 }
1325
1326 static void
1327 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1328 {
1329   u32 sw_if_index = ntohl (mp->sw_if_index);
1330   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1331           mp->mac_ip ? "mac/ip binding" : "address resolution",
1332           ntohl (mp->pid), format_ip6_address, mp->address,
1333           format_ethernet_address, mp->new_mac, sw_if_index);
1334 }
1335
1336 static void
1337 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1338 {
1339   /* JSON output not supported */
1340 }
1341
1342 static void
1343 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1344 {
1345   u32 n_macs = ntohl (mp->n_macs);
1346   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1347           ntohl (mp->pid), mp->client_index, n_macs);
1348   int i;
1349   for (i = 0; i < n_macs; i++)
1350     {
1351       vl_api_mac_entry_t *mac = &mp->mac[i];
1352       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1353               i + 1, ntohl (mac->sw_if_index),
1354               format_ethernet_address, mac->mac_addr, mac->is_del);
1355       if (i == 1000)
1356         break;
1357     }
1358 }
1359
1360 static void
1361 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1362 {
1363   /* JSON output not supported */
1364 }
1365
1366 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1367 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1368
1369 /*
1370  * Special-case: build the bridge domain table, maintain
1371  * the next bd id vbl.
1372  */
1373 static void vl_api_bridge_domain_details_t_handler
1374   (vl_api_bridge_domain_details_t * mp)
1375 {
1376   vat_main_t *vam = &vat_main;
1377   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1378   int i;
1379
1380   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1381          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1382
1383   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1384          ntohl (mp->bd_id), mp->learn, mp->forward,
1385          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1386
1387   if (n_sw_ifs)
1388     {
1389       vl_api_bridge_domain_sw_if_t *sw_ifs;
1390       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1391              "Interface Name");
1392
1393       sw_ifs = mp->sw_if_details;
1394       for (i = 0; i < n_sw_ifs; i++)
1395         {
1396           u8 *sw_if_name = 0;
1397           u32 sw_if_index;
1398           hash_pair_t *p;
1399
1400           sw_if_index = ntohl (sw_ifs->sw_if_index);
1401
1402           /* *INDENT-OFF* */
1403           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1404                              ({
1405                                if ((u32) p->value[0] == sw_if_index)
1406                                  {
1407                                    sw_if_name = (u8 *)(p->key);
1408                                    break;
1409                                  }
1410                              }));
1411           /* *INDENT-ON* */
1412           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1413                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1414                  "sw_if_index not found!");
1415
1416           sw_ifs++;
1417         }
1418     }
1419 }
1420
1421 static void vl_api_bridge_domain_details_t_handler_json
1422   (vl_api_bridge_domain_details_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   vat_json_node_t *node, *array = NULL;
1426   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1427
1428   if (VAT_JSON_ARRAY != vam->json_tree.type)
1429     {
1430       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1431       vat_json_init_array (&vam->json_tree);
1432     }
1433   node = vat_json_array_add (&vam->json_tree);
1434
1435   vat_json_init_object (node);
1436   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1437   vat_json_object_add_uint (node, "flood", mp->flood);
1438   vat_json_object_add_uint (node, "forward", mp->forward);
1439   vat_json_object_add_uint (node, "learn", mp->learn);
1440   vat_json_object_add_uint (node, "bvi_sw_if_index",
1441                             ntohl (mp->bvi_sw_if_index));
1442   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1443   array = vat_json_object_add (node, "sw_if");
1444   vat_json_init_array (array);
1445
1446
1447
1448   if (n_sw_ifs)
1449     {
1450       vl_api_bridge_domain_sw_if_t *sw_ifs;
1451       int i;
1452
1453       sw_ifs = mp->sw_if_details;
1454       for (i = 0; i < n_sw_ifs; i++)
1455         {
1456           node = vat_json_array_add (array);
1457           vat_json_init_object (node);
1458           vat_json_object_add_uint (node, "sw_if_index",
1459                                     ntohl (sw_ifs->sw_if_index));
1460           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1461           sw_ifs++;
1462         }
1463     }
1464 }
1465
1466 static void vl_api_control_ping_reply_t_handler
1467   (vl_api_control_ping_reply_t * mp)
1468 {
1469   vat_main_t *vam = &vat_main;
1470   i32 retval = ntohl (mp->retval);
1471   if (vam->async_mode)
1472     {
1473       vam->async_errors += (retval < 0);
1474     }
1475   else
1476     {
1477       vam->retval = retval;
1478       vam->result_ready = 1;
1479     }
1480   if (vam->socket_client_main)
1481     vam->socket_client_main->control_pings_outstanding--;
1482 }
1483
1484 static void vl_api_control_ping_reply_t_handler_json
1485   (vl_api_control_ping_reply_t * mp)
1486 {
1487   vat_main_t *vam = &vat_main;
1488   i32 retval = ntohl (mp->retval);
1489
1490   if (VAT_JSON_NONE != vam->json_tree.type)
1491     {
1492       vat_json_print (vam->ofp, &vam->json_tree);
1493       vat_json_free (&vam->json_tree);
1494       vam->json_tree.type = VAT_JSON_NONE;
1495     }
1496   else
1497     {
1498       /* just print [] */
1499       vat_json_init_array (&vam->json_tree);
1500       vat_json_print (vam->ofp, &vam->json_tree);
1501       vam->json_tree.type = VAT_JSON_NONE;
1502     }
1503
1504   vam->retval = retval;
1505   vam->result_ready = 1;
1506 }
1507
1508 static void
1509   vl_api_bridge_domain_set_mac_age_reply_t_handler
1510   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   i32 retval = ntohl (mp->retval);
1514   if (vam->async_mode)
1515     {
1516       vam->async_errors += (retval < 0);
1517     }
1518   else
1519     {
1520       vam->retval = retval;
1521       vam->result_ready = 1;
1522     }
1523 }
1524
1525 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1526   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   vat_json_node_t node;
1530
1531   vat_json_init_object (&node);
1532   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1533
1534   vat_json_print (vam->ofp, &node);
1535   vat_json_free (&node);
1536
1537   vam->retval = ntohl (mp->retval);
1538   vam->result_ready = 1;
1539 }
1540
1541 static void
1542 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   i32 retval = ntohl (mp->retval);
1546   if (vam->async_mode)
1547     {
1548       vam->async_errors += (retval < 0);
1549     }
1550   else
1551     {
1552       vam->retval = retval;
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_l2_flags_reply_t_handler_json
1558   (vl_api_l2_flags_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1566                             ntohl (mp->resulting_feature_bitmap));
1567
1568   vat_json_print (vam->ofp, &node);
1569   vat_json_free (&node);
1570
1571   vam->retval = ntohl (mp->retval);
1572   vam->result_ready = 1;
1573 }
1574
1575 static void vl_api_bridge_flags_reply_t_handler
1576   (vl_api_bridge_flags_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   i32 retval = ntohl (mp->retval);
1580   if (vam->async_mode)
1581     {
1582       vam->async_errors += (retval < 0);
1583     }
1584   else
1585     {
1586       vam->retval = retval;
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_bridge_flags_reply_t_handler_json
1592   (vl_api_bridge_flags_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1600                             ntohl (mp->resulting_feature_bitmap));
1601
1602   vat_json_print (vam->ofp, &node);
1603   vat_json_free (&node);
1604
1605   vam->retval = ntohl (mp->retval);
1606   vam->result_ready = 1;
1607 }
1608
1609 static void vl_api_tap_connect_reply_t_handler
1610   (vl_api_tap_connect_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   i32 retval = ntohl (mp->retval);
1614   if (vam->async_mode)
1615     {
1616       vam->async_errors += (retval < 0);
1617     }
1618   else
1619     {
1620       vam->retval = retval;
1621       vam->sw_if_index = ntohl (mp->sw_if_index);
1622       vam->result_ready = 1;
1623     }
1624
1625 }
1626
1627 static void vl_api_tap_connect_reply_t_handler_json
1628   (vl_api_tap_connect_reply_t * mp)
1629 {
1630   vat_main_t *vam = &vat_main;
1631   vat_json_node_t node;
1632
1633   vat_json_init_object (&node);
1634   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1635   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1636
1637   vat_json_print (vam->ofp, &node);
1638   vat_json_free (&node);
1639
1640   vam->retval = ntohl (mp->retval);
1641   vam->result_ready = 1;
1642
1643 }
1644
1645 static void
1646 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   i32 retval = ntohl (mp->retval);
1650   if (vam->async_mode)
1651     {
1652       vam->async_errors += (retval < 0);
1653     }
1654   else
1655     {
1656       vam->retval = retval;
1657       vam->sw_if_index = ntohl (mp->sw_if_index);
1658       vam->result_ready = 1;
1659     }
1660 }
1661
1662 static void vl_api_tap_modify_reply_t_handler_json
1663   (vl_api_tap_modify_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   vat_json_node_t node;
1667
1668   vat_json_init_object (&node);
1669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1671
1672   vat_json_print (vam->ofp, &node);
1673   vat_json_free (&node);
1674
1675   vam->retval = ntohl (mp->retval);
1676   vam->result_ready = 1;
1677 }
1678
1679 static void
1680 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1681 {
1682   vat_main_t *vam = &vat_main;
1683   i32 retval = ntohl (mp->retval);
1684   if (vam->async_mode)
1685     {
1686       vam->async_errors += (retval < 0);
1687     }
1688   else
1689     {
1690       vam->retval = retval;
1691       vam->result_ready = 1;
1692     }
1693 }
1694
1695 static void vl_api_tap_delete_reply_t_handler_json
1696   (vl_api_tap_delete_reply_t * mp)
1697 {
1698   vat_main_t *vam = &vat_main;
1699   vat_json_node_t node;
1700
1701   vat_json_init_object (&node);
1702   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1703
1704   vat_json_print (vam->ofp, &node);
1705   vat_json_free (&node);
1706
1707   vam->retval = ntohl (mp->retval);
1708   vam->result_ready = 1;
1709 }
1710
1711 static void
1712 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1713 {
1714   vat_main_t *vam = &vat_main;
1715   i32 retval = ntohl (mp->retval);
1716   if (vam->async_mode)
1717     {
1718       vam->async_errors += (retval < 0);
1719     }
1720   else
1721     {
1722       vam->retval = retval;
1723       vam->sw_if_index = ntohl (mp->sw_if_index);
1724       vam->result_ready = 1;
1725     }
1726
1727 }
1728
1729 static void vl_api_tap_create_v2_reply_t_handler_json
1730   (vl_api_tap_create_v2_reply_t * mp)
1731 {
1732   vat_main_t *vam = &vat_main;
1733   vat_json_node_t node;
1734
1735   vat_json_init_object (&node);
1736   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1737   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1738
1739   vat_json_print (vam->ofp, &node);
1740   vat_json_free (&node);
1741
1742   vam->retval = ntohl (mp->retval);
1743   vam->result_ready = 1;
1744
1745 }
1746
1747 static void
1748 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   i32 retval = ntohl (mp->retval);
1752   if (vam->async_mode)
1753     {
1754       vam->async_errors += (retval < 0);
1755     }
1756   else
1757     {
1758       vam->retval = retval;
1759       vam->result_ready = 1;
1760     }
1761 }
1762
1763 static void vl_api_tap_delete_v2_reply_t_handler_json
1764   (vl_api_tap_delete_v2_reply_t * mp)
1765 {
1766   vat_main_t *vam = &vat_main;
1767   vat_json_node_t node;
1768
1769   vat_json_init_object (&node);
1770   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1771
1772   vat_json_print (vam->ofp, &node);
1773   vat_json_free (&node);
1774
1775   vam->retval = ntohl (mp->retval);
1776   vam->result_ready = 1;
1777 }
1778
1779 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1780   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1781 {
1782   vat_main_t *vam = &vat_main;
1783   i32 retval = ntohl (mp->retval);
1784   if (vam->async_mode)
1785     {
1786       vam->async_errors += (retval < 0);
1787     }
1788   else
1789     {
1790       vam->retval = retval;
1791       vam->result_ready = 1;
1792     }
1793 }
1794
1795 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1796   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   vat_json_node_t node;
1800
1801   vat_json_init_object (&node);
1802   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1803   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1804                             ntohl (mp->sw_if_index));
1805
1806   vat_json_print (vam->ofp, &node);
1807   vat_json_free (&node);
1808
1809   vam->retval = ntohl (mp->retval);
1810   vam->result_ready = 1;
1811 }
1812
1813 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1814   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1815 {
1816   vat_main_t *vam = &vat_main;
1817   i32 retval = ntohl (mp->retval);
1818   if (vam->async_mode)
1819     {
1820       vam->async_errors += (retval < 0);
1821     }
1822   else
1823     {
1824       vam->retval = retval;
1825       vam->sw_if_index = ntohl (mp->sw_if_index);
1826       vam->result_ready = 1;
1827     }
1828 }
1829
1830 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1831   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1832 {
1833   vat_main_t *vam = &vat_main;
1834   vat_json_node_t node;
1835
1836   vat_json_init_object (&node);
1837   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1838   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1839
1840   vat_json_print (vam->ofp, &node);
1841   vat_json_free (&node);
1842
1843   vam->retval = ntohl (mp->retval);
1844   vam->result_ready = 1;
1845 }
1846
1847 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1848   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1849 {
1850   vat_main_t *vam = &vat_main;
1851   i32 retval = ntohl (mp->retval);
1852   if (vam->async_mode)
1853     {
1854       vam->async_errors += (retval < 0);
1855     }
1856   else
1857     {
1858       vam->retval = retval;
1859       vam->result_ready = 1;
1860     }
1861 }
1862
1863 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1864   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1865 {
1866   vat_main_t *vam = &vat_main;
1867   vat_json_node_t node;
1868
1869   vat_json_init_object (&node);
1870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1871   vat_json_object_add_uint (&node, "fwd_entry_index",
1872                             clib_net_to_host_u32 (mp->fwd_entry_index));
1873
1874   vat_json_print (vam->ofp, &node);
1875   vat_json_free (&node);
1876
1877   vam->retval = ntohl (mp->retval);
1878   vam->result_ready = 1;
1879 }
1880
1881 u8 *
1882 format_lisp_transport_protocol (u8 * s, va_list * args)
1883 {
1884   u32 proto = va_arg (*args, u32);
1885
1886   switch (proto)
1887     {
1888     case 1:
1889       return format (s, "udp");
1890     case 2:
1891       return format (s, "api");
1892     default:
1893       return 0;
1894     }
1895   return 0;
1896 }
1897
1898 static void vl_api_one_get_transport_protocol_reply_t_handler
1899   (vl_api_one_get_transport_protocol_reply_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   i32 retval = ntohl (mp->retval);
1903   if (vam->async_mode)
1904     {
1905       vam->async_errors += (retval < 0);
1906     }
1907   else
1908     {
1909       u32 proto = mp->protocol;
1910       print (vam->ofp, "Transport protocol: %U",
1911              format_lisp_transport_protocol, proto);
1912       vam->retval = retval;
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1918   (vl_api_one_get_transport_protocol_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922   u8 *s;
1923
1924   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1925   vec_add1 (s, 0);
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1930
1931   vec_free (s);
1932   vat_json_print (vam->ofp, &node);
1933   vat_json_free (&node);
1934
1935   vam->retval = ntohl (mp->retval);
1936   vam->result_ready = 1;
1937 }
1938
1939 static void vl_api_one_add_del_locator_set_reply_t_handler
1940   (vl_api_one_add_del_locator_set_reply_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   i32 retval = ntohl (mp->retval);
1944   if (vam->async_mode)
1945     {
1946       vam->async_errors += (retval < 0);
1947     }
1948   else
1949     {
1950       vam->retval = retval;
1951       vam->result_ready = 1;
1952     }
1953 }
1954
1955 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1956   (vl_api_one_add_del_locator_set_reply_t * mp)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   vat_json_node_t node;
1960
1961   vat_json_init_object (&node);
1962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1963   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1964
1965   vat_json_print (vam->ofp, &node);
1966   vat_json_free (&node);
1967
1968   vam->retval = ntohl (mp->retval);
1969   vam->result_ready = 1;
1970 }
1971
1972 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1973   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1974 {
1975   vat_main_t *vam = &vat_main;
1976   i32 retval = ntohl (mp->retval);
1977   if (vam->async_mode)
1978     {
1979       vam->async_errors += (retval < 0);
1980     }
1981   else
1982     {
1983       vam->retval = retval;
1984       vam->sw_if_index = ntohl (mp->sw_if_index);
1985       vam->result_ready = 1;
1986     }
1987 }
1988
1989 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1990   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1991 {
1992   vat_main_t *vam = &vat_main;
1993   vat_json_node_t node;
1994
1995   vat_json_init_object (&node);
1996   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1997   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1998
1999   vat_json_print (vam->ofp, &node);
2000   vat_json_free (&node);
2001
2002   vam->retval = ntohl (mp->retval);
2003   vam->result_ready = 1;
2004 }
2005
2006 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2007   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2008 {
2009   vat_main_t *vam = &vat_main;
2010   i32 retval = ntohl (mp->retval);
2011   if (vam->async_mode)
2012     {
2013       vam->async_errors += (retval < 0);
2014     }
2015   else
2016     {
2017       vam->retval = retval;
2018       vam->sw_if_index = ntohl (mp->sw_if_index);
2019       vam->result_ready = 1;
2020     }
2021 }
2022
2023 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2024   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2025 {
2026   vat_main_t *vam = &vat_main;
2027   vat_json_node_t node;
2028
2029   vat_json_init_object (&node);
2030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2031   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2032
2033   vat_json_print (vam->ofp, &node);
2034   vat_json_free (&node);
2035
2036   vam->retval = ntohl (mp->retval);
2037   vam->result_ready = 1;
2038 }
2039
2040 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2041   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2042 {
2043   vat_main_t *vam = &vat_main;
2044   i32 retval = ntohl (mp->retval);
2045   if (vam->async_mode)
2046     {
2047       vam->async_errors += (retval < 0);
2048     }
2049   else
2050     {
2051       vam->retval = retval;
2052       vam->sw_if_index = ntohl (mp->sw_if_index);
2053       vam->result_ready = 1;
2054     }
2055 }
2056
2057 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2058   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vat_json_node_t node;
2062
2063   vat_json_init_object (&node);
2064   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2065   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2066
2067   vat_json_print (vam->ofp, &node);
2068   vat_json_free (&node);
2069
2070   vam->retval = ntohl (mp->retval);
2071   vam->result_ready = 1;
2072 }
2073
2074 static void vl_api_gre_add_del_tunnel_reply_t_handler
2075   (vl_api_gre_add_del_tunnel_reply_t * mp)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   i32 retval = ntohl (mp->retval);
2079   if (vam->async_mode)
2080     {
2081       vam->async_errors += (retval < 0);
2082     }
2083   else
2084     {
2085       vam->retval = retval;
2086       vam->sw_if_index = ntohl (mp->sw_if_index);
2087       vam->result_ready = 1;
2088     }
2089 }
2090
2091 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2092   (vl_api_gre_add_del_tunnel_reply_t * mp)
2093 {
2094   vat_main_t *vam = &vat_main;
2095   vat_json_node_t node;
2096
2097   vat_json_init_object (&node);
2098   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2099   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2100
2101   vat_json_print (vam->ofp, &node);
2102   vat_json_free (&node);
2103
2104   vam->retval = ntohl (mp->retval);
2105   vam->result_ready = 1;
2106 }
2107
2108 static void vl_api_create_vhost_user_if_reply_t_handler
2109   (vl_api_create_vhost_user_if_reply_t * mp)
2110 {
2111   vat_main_t *vam = &vat_main;
2112   i32 retval = ntohl (mp->retval);
2113   if (vam->async_mode)
2114     {
2115       vam->async_errors += (retval < 0);
2116     }
2117   else
2118     {
2119       vam->retval = retval;
2120       vam->sw_if_index = ntohl (mp->sw_if_index);
2121       vam->result_ready = 1;
2122     }
2123 }
2124
2125 static void vl_api_create_vhost_user_if_reply_t_handler_json
2126   (vl_api_create_vhost_user_if_reply_t * mp)
2127 {
2128   vat_main_t *vam = &vat_main;
2129   vat_json_node_t node;
2130
2131   vat_json_init_object (&node);
2132   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2133   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2134
2135   vat_json_print (vam->ofp, &node);
2136   vat_json_free (&node);
2137
2138   vam->retval = ntohl (mp->retval);
2139   vam->result_ready = 1;
2140 }
2141
2142 static clib_error_t *
2143 receive_fd_msg (int socket_fd, int *my_fd)
2144 {
2145   char msgbuf[16];
2146   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2147   struct msghdr mh = { 0 };
2148   struct iovec iov[1];
2149   ssize_t size;
2150   struct ucred *cr = 0;
2151   struct cmsghdr *cmsg;
2152   pid_t pid __attribute__ ((unused));
2153   uid_t uid __attribute__ ((unused));
2154   gid_t gid __attribute__ ((unused));
2155
2156   iov[0].iov_base = msgbuf;
2157   iov[0].iov_len = 5;
2158   mh.msg_iov = iov;
2159   mh.msg_iovlen = 1;
2160   mh.msg_control = ctl;
2161   mh.msg_controllen = sizeof (ctl);
2162
2163   memset (ctl, 0, sizeof (ctl));
2164
2165   /* receive the incoming message */
2166   size = recvmsg (socket_fd, &mh, 0);
2167   if (size != 5)
2168     {
2169       return (size == 0) ? clib_error_return (0, "disconnected") :
2170         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2171                                 socket_fd);
2172     }
2173
2174   cmsg = CMSG_FIRSTHDR (&mh);
2175   while (cmsg)
2176     {
2177       if (cmsg->cmsg_level == SOL_SOCKET)
2178         {
2179           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2180             {
2181               cr = (struct ucred *) CMSG_DATA (cmsg);
2182               uid = cr->uid;
2183               gid = cr->gid;
2184               pid = cr->pid;
2185             }
2186           else if (cmsg->cmsg_type == SCM_RIGHTS)
2187             {
2188               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2189             }
2190         }
2191       cmsg = CMSG_NXTHDR (&mh, cmsg);
2192     }
2193   return 0;
2194 }
2195
2196 static void vl_api_memfd_segment_create_reply_t_handler
2197   (vl_api_memfd_segment_create_reply_t * mp)
2198 {
2199   /* Dont bother in the builtin version */
2200 #if VPP_API_TEST_BUILTIN == 0
2201   vat_main_t *vam = &vat_main;
2202   api_main_t *am = &api_main;
2203   socket_client_main_t *scm = vam->socket_client_main;
2204   int my_fd = -1;
2205   clib_error_t *error;
2206   memfd_private_t memfd;
2207   i32 retval = ntohl (mp->retval);
2208
2209   if (retval == 0)
2210     {
2211       error = receive_fd_msg (scm->socket_fd, &my_fd);
2212       if (error)
2213         {
2214           retval = -99;
2215           goto out;
2216         }
2217
2218       memset (&memfd, 0, sizeof (memfd));
2219       memfd.fd = my_fd;
2220
2221       vam->client_index_invalid = 1;
2222
2223       /* Note: this closes memfd.fd */
2224       retval = memfd_slave_init (&memfd);
2225       if (retval)
2226         clib_warning ("WARNING: segment map returned %d", retval);
2227
2228       /* Pivot to the memory client segment that vpp just created */
2229
2230       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2231
2232       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2233
2234       vl_client_install_client_message_handlers ();
2235
2236       vl_client_connect_to_vlib_no_map ("pvt",
2237                                         "vpp_api_test(p)",
2238                                         32 /* input_queue_length */ );
2239       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2240
2241       vl_socket_client_enable_disable (0 /* disable socket */ );
2242     }
2243
2244 out:
2245   if (vam->async_mode)
2246     {
2247       vam->async_errors += (retval < 0);
2248     }
2249   else
2250     {
2251       vam->retval = retval;
2252       vam->result_ready = 1;
2253     }
2254 #endif
2255 }
2256
2257 static void vl_api_memfd_segment_create_reply_t_handler_json
2258   (vl_api_memfd_segment_create_reply_t * mp)
2259 {
2260   clib_warning ("no");
2261 }
2262
2263 static void vl_api_dns_resolve_name_reply_t_handler
2264   (vl_api_dns_resolve_name_reply_t * mp)
2265 {
2266   vat_main_t *vam = &vat_main;
2267   i32 retval = ntohl (mp->retval);
2268   if (vam->async_mode)
2269     {
2270       vam->async_errors += (retval < 0);
2271     }
2272   else
2273     {
2274       vam->retval = retval;
2275       vam->result_ready = 1;
2276
2277       if (retval == 0)
2278         {
2279           if (mp->ip4_set)
2280             clib_warning ("ip4 address %U", format_ip4_address,
2281                           (ip4_address_t *) mp->ip4_address);
2282           if (mp->ip6_set)
2283             clib_warning ("ip6 address %U", format_ip6_address,
2284                           (ip6_address_t *) mp->ip6_address);
2285         }
2286       else
2287         clib_warning ("retval %d", retval);
2288     }
2289 }
2290
2291 static void vl_api_dns_resolve_name_reply_t_handler_json
2292   (vl_api_dns_resolve_name_reply_t * mp)
2293 {
2294   clib_warning ("not implemented");
2295 }
2296
2297 static void vl_api_dns_resolve_ip_reply_t_handler
2298   (vl_api_dns_resolve_ip_reply_t * mp)
2299 {
2300   vat_main_t *vam = &vat_main;
2301   i32 retval = ntohl (mp->retval);
2302   if (vam->async_mode)
2303     {
2304       vam->async_errors += (retval < 0);
2305     }
2306   else
2307     {
2308       vam->retval = retval;
2309       vam->result_ready = 1;
2310
2311       if (retval == 0)
2312         {
2313           clib_warning ("canonical name %s", mp->name);
2314         }
2315       else
2316         clib_warning ("retval %d", retval);
2317     }
2318 }
2319
2320 static void vl_api_dns_resolve_ip_reply_t_handler_json
2321   (vl_api_dns_resolve_ip_reply_t * mp)
2322 {
2323   clib_warning ("not implemented");
2324 }
2325
2326
2327 static void vl_api_ip_address_details_t_handler
2328   (vl_api_ip_address_details_t * mp)
2329 {
2330   vat_main_t *vam = &vat_main;
2331   static ip_address_details_t empty_ip_address_details = { {0} };
2332   ip_address_details_t *address = NULL;
2333   ip_details_t *current_ip_details = NULL;
2334   ip_details_t *details = NULL;
2335
2336   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2337
2338   if (!details || vam->current_sw_if_index >= vec_len (details)
2339       || !details[vam->current_sw_if_index].present)
2340     {
2341       errmsg ("ip address details arrived but not stored");
2342       errmsg ("ip_dump should be called first");
2343       return;
2344     }
2345
2346   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2347
2348 #define addresses (current_ip_details->addr)
2349
2350   vec_validate_init_empty (addresses, vec_len (addresses),
2351                            empty_ip_address_details);
2352
2353   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2354
2355   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2356   address->prefix_length = mp->prefix_length;
2357 #undef addresses
2358 }
2359
2360 static void vl_api_ip_address_details_t_handler_json
2361   (vl_api_ip_address_details_t * mp)
2362 {
2363   vat_main_t *vam = &vat_main;
2364   vat_json_node_t *node = NULL;
2365   struct in6_addr ip6;
2366   struct in_addr ip4;
2367
2368   if (VAT_JSON_ARRAY != vam->json_tree.type)
2369     {
2370       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2371       vat_json_init_array (&vam->json_tree);
2372     }
2373   node = vat_json_array_add (&vam->json_tree);
2374
2375   vat_json_init_object (node);
2376   if (vam->is_ipv6)
2377     {
2378       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2379       vat_json_object_add_ip6 (node, "ip", ip6);
2380     }
2381   else
2382     {
2383       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2384       vat_json_object_add_ip4 (node, "ip", ip4);
2385     }
2386   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2387 }
2388
2389 static void
2390 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   static ip_details_t empty_ip_details = { 0 };
2394   ip_details_t *ip = NULL;
2395   u32 sw_if_index = ~0;
2396
2397   sw_if_index = ntohl (mp->sw_if_index);
2398
2399   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2400                            sw_if_index, empty_ip_details);
2401
2402   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2403                          sw_if_index);
2404
2405   ip->present = 1;
2406 }
2407
2408 static void
2409 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412
2413   if (VAT_JSON_ARRAY != vam->json_tree.type)
2414     {
2415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2416       vat_json_init_array (&vam->json_tree);
2417     }
2418   vat_json_array_add_uint (&vam->json_tree,
2419                            clib_net_to_host_u32 (mp->sw_if_index));
2420 }
2421
2422 static void vl_api_map_domain_details_t_handler_json
2423   (vl_api_map_domain_details_t * mp)
2424 {
2425   vat_json_node_t *node = NULL;
2426   vat_main_t *vam = &vat_main;
2427   struct in6_addr ip6;
2428   struct in_addr ip4;
2429
2430   if (VAT_JSON_ARRAY != vam->json_tree.type)
2431     {
2432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2433       vat_json_init_array (&vam->json_tree);
2434     }
2435
2436   node = vat_json_array_add (&vam->json_tree);
2437   vat_json_init_object (node);
2438
2439   vat_json_object_add_uint (node, "domain_index",
2440                             clib_net_to_host_u32 (mp->domain_index));
2441   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2442   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2443   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2444   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2445   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2446   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2447   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2448   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2449   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2450   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2451   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2452   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2453   vat_json_object_add_uint (node, "flags", mp->flags);
2454   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2455   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2456 }
2457
2458 static void vl_api_map_domain_details_t_handler
2459   (vl_api_map_domain_details_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462
2463   if (mp->is_translation)
2464     {
2465       print (vam->ofp,
2466              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2467              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2468              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2469              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2470              clib_net_to_host_u32 (mp->domain_index));
2471     }
2472   else
2473     {
2474       print (vam->ofp,
2475              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2476              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2477              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2478              format_ip6_address, mp->ip6_src,
2479              clib_net_to_host_u32 (mp->domain_index));
2480     }
2481   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2482          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2483          mp->is_translation ? "map-t" : "");
2484 }
2485
2486 static void vl_api_map_rule_details_t_handler_json
2487   (vl_api_map_rule_details_t * mp)
2488 {
2489   struct in6_addr ip6;
2490   vat_json_node_t *node = NULL;
2491   vat_main_t *vam = &vat_main;
2492
2493   if (VAT_JSON_ARRAY != vam->json_tree.type)
2494     {
2495       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2496       vat_json_init_array (&vam->json_tree);
2497     }
2498
2499   node = vat_json_array_add (&vam->json_tree);
2500   vat_json_init_object (node);
2501
2502   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2503   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2504   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2505 }
2506
2507 static void
2508 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2509 {
2510   vat_main_t *vam = &vat_main;
2511   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2512          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2513 }
2514
2515 static void
2516 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2517 {
2518   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2519           "router_addr %U host_mac %U",
2520           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2521           format_ip4_address, &mp->host_address,
2522           format_ip4_address, &mp->router_address,
2523           format_ethernet_address, mp->host_mac);
2524 }
2525
2526 static void vl_api_dhcp_compl_event_t_handler_json
2527   (vl_api_dhcp_compl_event_t * mp)
2528 {
2529   /* JSON output not supported */
2530 }
2531
2532 static void
2533 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2534                               u32 counter)
2535 {
2536   vat_main_t *vam = &vat_main;
2537   static u64 default_counter = 0;
2538
2539   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2540                            NULL);
2541   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2542                            sw_if_index, default_counter);
2543   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2544 }
2545
2546 static void
2547 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2548                                 interface_counter_t counter)
2549 {
2550   vat_main_t *vam = &vat_main;
2551   static interface_counter_t default_counter = { 0, };
2552
2553   vec_validate_init_empty (vam->combined_interface_counters,
2554                            vnet_counter_type, NULL);
2555   vec_validate_init_empty (vam->combined_interface_counters
2556                            [vnet_counter_type], sw_if_index, default_counter);
2557   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2558 }
2559
2560 static void vl_api_vnet_interface_simple_counters_t_handler
2561   (vl_api_vnet_interface_simple_counters_t * mp)
2562 {
2563   /* not supported */
2564 }
2565
2566 static void vl_api_vnet_interface_combined_counters_t_handler
2567   (vl_api_vnet_interface_combined_counters_t * mp)
2568 {
2569   /* not supported */
2570 }
2571
2572 static void vl_api_vnet_interface_simple_counters_t_handler_json
2573   (vl_api_vnet_interface_simple_counters_t * mp)
2574 {
2575   u64 *v_packets;
2576   u64 packets;
2577   u32 count;
2578   u32 first_sw_if_index;
2579   int i;
2580
2581   count = ntohl (mp->count);
2582   first_sw_if_index = ntohl (mp->first_sw_if_index);
2583
2584   v_packets = (u64 *) & mp->data;
2585   for (i = 0; i < count; i++)
2586     {
2587       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2588       set_simple_interface_counter (mp->vnet_counter_type,
2589                                     first_sw_if_index + i, packets);
2590       v_packets++;
2591     }
2592 }
2593
2594 static void vl_api_vnet_interface_combined_counters_t_handler_json
2595   (vl_api_vnet_interface_combined_counters_t * mp)
2596 {
2597   interface_counter_t counter;
2598   vlib_counter_t *v;
2599   u32 first_sw_if_index;
2600   int i;
2601   u32 count;
2602
2603   count = ntohl (mp->count);
2604   first_sw_if_index = ntohl (mp->first_sw_if_index);
2605
2606   v = (vlib_counter_t *) & mp->data;
2607   for (i = 0; i < count; i++)
2608     {
2609       counter.packets =
2610         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2611       counter.bytes =
2612         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2613       set_combined_interface_counter (mp->vnet_counter_type,
2614                                       first_sw_if_index + i, counter);
2615       v++;
2616     }
2617 }
2618
2619 static u32
2620 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2621 {
2622   vat_main_t *vam = &vat_main;
2623   u32 i;
2624
2625   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2626     {
2627       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2628         {
2629           return i;
2630         }
2631     }
2632   return ~0;
2633 }
2634
2635 static u32
2636 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   u32 i;
2640
2641   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2642     {
2643       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2644         {
2645           return i;
2646         }
2647     }
2648   return ~0;
2649 }
2650
2651 static void vl_api_vnet_ip4_fib_counters_t_handler
2652   (vl_api_vnet_ip4_fib_counters_t * mp)
2653 {
2654   /* not supported */
2655 }
2656
2657 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2658   (vl_api_vnet_ip4_fib_counters_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   vl_api_ip4_fib_counter_t *v;
2662   ip4_fib_counter_t *counter;
2663   struct in_addr ip4;
2664   u32 vrf_id;
2665   u32 vrf_index;
2666   u32 count;
2667   int i;
2668
2669   vrf_id = ntohl (mp->vrf_id);
2670   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2671   if (~0 == vrf_index)
2672     {
2673       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2674       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2675       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2676       vec_validate (vam->ip4_fib_counters, vrf_index);
2677       vam->ip4_fib_counters[vrf_index] = NULL;
2678     }
2679
2680   vec_free (vam->ip4_fib_counters[vrf_index]);
2681   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2682   count = ntohl (mp->count);
2683   for (i = 0; i < count; i++)
2684     {
2685       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2686       counter = &vam->ip4_fib_counters[vrf_index][i];
2687       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2688       counter->address = ip4;
2689       counter->address_length = v->address_length;
2690       counter->packets = clib_net_to_host_u64 (v->packets);
2691       counter->bytes = clib_net_to_host_u64 (v->bytes);
2692       v++;
2693     }
2694 }
2695
2696 static void vl_api_vnet_ip4_nbr_counters_t_handler
2697   (vl_api_vnet_ip4_nbr_counters_t * mp)
2698 {
2699   /* not supported */
2700 }
2701
2702 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2703   (vl_api_vnet_ip4_nbr_counters_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   vl_api_ip4_nbr_counter_t *v;
2707   ip4_nbr_counter_t *counter;
2708   u32 sw_if_index;
2709   u32 count;
2710   int i;
2711
2712   sw_if_index = ntohl (mp->sw_if_index);
2713   count = ntohl (mp->count);
2714   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2715
2716   if (mp->begin)
2717     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2718
2719   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2720   for (i = 0; i < count; i++)
2721     {
2722       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2723       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2724       counter->address.s_addr = v->address;
2725       counter->packets = clib_net_to_host_u64 (v->packets);
2726       counter->bytes = clib_net_to_host_u64 (v->bytes);
2727       counter->linkt = v->link_type;
2728       v++;
2729     }
2730 }
2731
2732 static void vl_api_vnet_ip6_fib_counters_t_handler
2733   (vl_api_vnet_ip6_fib_counters_t * mp)
2734 {
2735   /* not supported */
2736 }
2737
2738 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2739   (vl_api_vnet_ip6_fib_counters_t * mp)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   vl_api_ip6_fib_counter_t *v;
2743   ip6_fib_counter_t *counter;
2744   struct in6_addr ip6;
2745   u32 vrf_id;
2746   u32 vrf_index;
2747   u32 count;
2748   int i;
2749
2750   vrf_id = ntohl (mp->vrf_id);
2751   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2752   if (~0 == vrf_index)
2753     {
2754       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2755       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2756       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2757       vec_validate (vam->ip6_fib_counters, vrf_index);
2758       vam->ip6_fib_counters[vrf_index] = NULL;
2759     }
2760
2761   vec_free (vam->ip6_fib_counters[vrf_index]);
2762   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2763   count = ntohl (mp->count);
2764   for (i = 0; i < count; i++)
2765     {
2766       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2767       counter = &vam->ip6_fib_counters[vrf_index][i];
2768       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2769       counter->address = ip6;
2770       counter->address_length = v->address_length;
2771       counter->packets = clib_net_to_host_u64 (v->packets);
2772       counter->bytes = clib_net_to_host_u64 (v->bytes);
2773       v++;
2774     }
2775 }
2776
2777 static void vl_api_vnet_ip6_nbr_counters_t_handler
2778   (vl_api_vnet_ip6_nbr_counters_t * mp)
2779 {
2780   /* not supported */
2781 }
2782
2783 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2784   (vl_api_vnet_ip6_nbr_counters_t * mp)
2785 {
2786   vat_main_t *vam = &vat_main;
2787   vl_api_ip6_nbr_counter_t *v;
2788   ip6_nbr_counter_t *counter;
2789   struct in6_addr ip6;
2790   u32 sw_if_index;
2791   u32 count;
2792   int i;
2793
2794   sw_if_index = ntohl (mp->sw_if_index);
2795   count = ntohl (mp->count);
2796   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2797
2798   if (mp->begin)
2799     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2800
2801   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2802   for (i = 0; i < count; i++)
2803     {
2804       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2805       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2806       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2807       counter->address = ip6;
2808       counter->packets = clib_net_to_host_u64 (v->packets);
2809       counter->bytes = clib_net_to_host_u64 (v->bytes);
2810       v++;
2811     }
2812 }
2813
2814 static void vl_api_get_first_msg_id_reply_t_handler
2815   (vl_api_get_first_msg_id_reply_t * mp)
2816 {
2817   vat_main_t *vam = &vat_main;
2818   i32 retval = ntohl (mp->retval);
2819
2820   if (vam->async_mode)
2821     {
2822       vam->async_errors += (retval < 0);
2823     }
2824   else
2825     {
2826       vam->retval = retval;
2827       vam->result_ready = 1;
2828     }
2829   if (retval >= 0)
2830     {
2831       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2832     }
2833 }
2834
2835 static void vl_api_get_first_msg_id_reply_t_handler_json
2836   (vl_api_get_first_msg_id_reply_t * mp)
2837 {
2838   vat_main_t *vam = &vat_main;
2839   vat_json_node_t node;
2840
2841   vat_json_init_object (&node);
2842   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2843   vat_json_object_add_uint (&node, "first_msg_id",
2844                             (uint) ntohs (mp->first_msg_id));
2845
2846   vat_json_print (vam->ofp, &node);
2847   vat_json_free (&node);
2848
2849   vam->retval = ntohl (mp->retval);
2850   vam->result_ready = 1;
2851 }
2852
2853 static void vl_api_get_node_graph_reply_t_handler
2854   (vl_api_get_node_graph_reply_t * mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   api_main_t *am = &api_main;
2858   i32 retval = ntohl (mp->retval);
2859   u8 *pvt_copy, *reply;
2860   void *oldheap;
2861   vlib_node_t *node;
2862   int i;
2863
2864   if (vam->async_mode)
2865     {
2866       vam->async_errors += (retval < 0);
2867     }
2868   else
2869     {
2870       vam->retval = retval;
2871       vam->result_ready = 1;
2872     }
2873
2874   /* "Should never happen..." */
2875   if (retval != 0)
2876     return;
2877
2878   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2879   pvt_copy = vec_dup (reply);
2880
2881   /* Toss the shared-memory original... */
2882   pthread_mutex_lock (&am->vlib_rp->mutex);
2883   oldheap = svm_push_data_heap (am->vlib_rp);
2884
2885   vec_free (reply);
2886
2887   svm_pop_heap (oldheap);
2888   pthread_mutex_unlock (&am->vlib_rp->mutex);
2889
2890   if (vam->graph_nodes)
2891     {
2892       hash_free (vam->graph_node_index_by_name);
2893
2894       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2895         {
2896           node = vam->graph_nodes[i];
2897           vec_free (node->name);
2898           vec_free (node->next_nodes);
2899           vec_free (node);
2900         }
2901       vec_free (vam->graph_nodes);
2902     }
2903
2904   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2905   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2906   vec_free (pvt_copy);
2907
2908   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2909     {
2910       node = vam->graph_nodes[i];
2911       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2912     }
2913 }
2914
2915 static void vl_api_get_node_graph_reply_t_handler_json
2916   (vl_api_get_node_graph_reply_t * mp)
2917 {
2918   vat_main_t *vam = &vat_main;
2919   api_main_t *am = &api_main;
2920   void *oldheap;
2921   vat_json_node_t node;
2922   u8 *reply;
2923
2924   /* $$$$ make this real? */
2925   vat_json_init_object (&node);
2926   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2927   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2928
2929   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2930
2931   /* Toss the shared-memory original... */
2932   pthread_mutex_lock (&am->vlib_rp->mutex);
2933   oldheap = svm_push_data_heap (am->vlib_rp);
2934
2935   vec_free (reply);
2936
2937   svm_pop_heap (oldheap);
2938   pthread_mutex_unlock (&am->vlib_rp->mutex);
2939
2940   vat_json_print (vam->ofp, &node);
2941   vat_json_free (&node);
2942
2943   vam->retval = ntohl (mp->retval);
2944   vam->result_ready = 1;
2945 }
2946
2947 static void
2948 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2949 {
2950   vat_main_t *vam = &vat_main;
2951   u8 *s = 0;
2952
2953   if (mp->local)
2954     {
2955       s = format (s, "%=16d%=16d%=16d",
2956                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2957     }
2958   else
2959     {
2960       s = format (s, "%=16U%=16d%=16d",
2961                   mp->is_ipv6 ? format_ip6_address :
2962                   format_ip4_address,
2963                   mp->ip_address, mp->priority, mp->weight);
2964     }
2965
2966   print (vam->ofp, "%v", s);
2967   vec_free (s);
2968 }
2969
2970 static void
2971 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2972 {
2973   vat_main_t *vam = &vat_main;
2974   vat_json_node_t *node = NULL;
2975   struct in6_addr ip6;
2976   struct in_addr ip4;
2977
2978   if (VAT_JSON_ARRAY != vam->json_tree.type)
2979     {
2980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2981       vat_json_init_array (&vam->json_tree);
2982     }
2983   node = vat_json_array_add (&vam->json_tree);
2984   vat_json_init_object (node);
2985
2986   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2987   vat_json_object_add_uint (node, "priority", mp->priority);
2988   vat_json_object_add_uint (node, "weight", mp->weight);
2989
2990   if (mp->local)
2991     vat_json_object_add_uint (node, "sw_if_index",
2992                               clib_net_to_host_u32 (mp->sw_if_index));
2993   else
2994     {
2995       if (mp->is_ipv6)
2996         {
2997           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2998           vat_json_object_add_ip6 (node, "address", ip6);
2999         }
3000       else
3001         {
3002           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3003           vat_json_object_add_ip4 (node, "address", ip4);
3004         }
3005     }
3006 }
3007
3008 static void
3009 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3010                                           mp)
3011 {
3012   vat_main_t *vam = &vat_main;
3013   u8 *ls_name = 0;
3014
3015   ls_name = format (0, "%s", mp->ls_name);
3016
3017   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3018          ls_name);
3019   vec_free (ls_name);
3020 }
3021
3022 static void
3023   vl_api_one_locator_set_details_t_handler_json
3024   (vl_api_one_locator_set_details_t * mp)
3025 {
3026   vat_main_t *vam = &vat_main;
3027   vat_json_node_t *node = 0;
3028   u8 *ls_name = 0;
3029
3030   ls_name = format (0, "%s", mp->ls_name);
3031   vec_add1 (ls_name, 0);
3032
3033   if (VAT_JSON_ARRAY != vam->json_tree.type)
3034     {
3035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3036       vat_json_init_array (&vam->json_tree);
3037     }
3038   node = vat_json_array_add (&vam->json_tree);
3039
3040   vat_json_init_object (node);
3041   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3042   vat_json_object_add_uint (node, "ls_index",
3043                             clib_net_to_host_u32 (mp->ls_index));
3044   vec_free (ls_name);
3045 }
3046
3047 typedef struct
3048 {
3049   u32 spi;
3050   u8 si;
3051 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3052
3053 uword
3054 unformat_nsh_address (unformat_input_t * input, va_list * args)
3055 {
3056   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3057   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3058 }
3059
3060 u8 *
3061 format_nsh_address_vat (u8 * s, va_list * args)
3062 {
3063   nsh_t *a = va_arg (*args, nsh_t *);
3064   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3065 }
3066
3067 static u8 *
3068 format_lisp_flat_eid (u8 * s, va_list * args)
3069 {
3070   u32 type = va_arg (*args, u32);
3071   u8 *eid = va_arg (*args, u8 *);
3072   u32 eid_len = va_arg (*args, u32);
3073
3074   switch (type)
3075     {
3076     case 0:
3077       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3078     case 1:
3079       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3080     case 2:
3081       return format (s, "%U", format_ethernet_address, eid);
3082     case 3:
3083       return format (s, "%U", format_nsh_address_vat, eid);
3084     }
3085   return 0;
3086 }
3087
3088 static u8 *
3089 format_lisp_eid_vat (u8 * s, va_list * args)
3090 {
3091   u32 type = va_arg (*args, u32);
3092   u8 *eid = va_arg (*args, u8 *);
3093   u32 eid_len = va_arg (*args, u32);
3094   u8 *seid = va_arg (*args, u8 *);
3095   u32 seid_len = va_arg (*args, u32);
3096   u32 is_src_dst = va_arg (*args, u32);
3097
3098   if (is_src_dst)
3099     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3100
3101   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3102
3103   return s;
3104 }
3105
3106 static void
3107 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   u8 *s = 0, *eid = 0;
3111
3112   if (~0 == mp->locator_set_index)
3113     s = format (0, "action: %d", mp->action);
3114   else
3115     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3116
3117   eid = format (0, "%U", format_lisp_eid_vat,
3118                 mp->eid_type,
3119                 mp->eid,
3120                 mp->eid_prefix_len,
3121                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3122   vec_add1 (eid, 0);
3123
3124   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3125          clib_net_to_host_u32 (mp->vni),
3126          eid,
3127          mp->is_local ? "local" : "remote",
3128          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3129          clib_net_to_host_u16 (mp->key_id), mp->key);
3130
3131   vec_free (s);
3132   vec_free (eid);
3133 }
3134
3135 static void
3136 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3137                                              * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   vat_json_node_t *node = 0;
3141   u8 *eid = 0;
3142
3143   if (VAT_JSON_ARRAY != vam->json_tree.type)
3144     {
3145       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3146       vat_json_init_array (&vam->json_tree);
3147     }
3148   node = vat_json_array_add (&vam->json_tree);
3149
3150   vat_json_init_object (node);
3151   if (~0 == mp->locator_set_index)
3152     vat_json_object_add_uint (node, "action", mp->action);
3153   else
3154     vat_json_object_add_uint (node, "locator_set_index",
3155                               clib_net_to_host_u32 (mp->locator_set_index));
3156
3157   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3158   if (mp->eid_type == 3)
3159     {
3160       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3161       vat_json_init_object (nsh_json);
3162       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3163       vat_json_object_add_uint (nsh_json, "spi",
3164                                 clib_net_to_host_u32 (nsh->spi));
3165       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3166     }
3167   else
3168     {
3169       eid = format (0, "%U", format_lisp_eid_vat,
3170                     mp->eid_type,
3171                     mp->eid,
3172                     mp->eid_prefix_len,
3173                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3174       vec_add1 (eid, 0);
3175       vat_json_object_add_string_copy (node, "eid", eid);
3176       vec_free (eid);
3177     }
3178   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3179   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3180   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3181
3182   if (mp->key_id)
3183     {
3184       vat_json_object_add_uint (node, "key_id",
3185                                 clib_net_to_host_u16 (mp->key_id));
3186       vat_json_object_add_string_copy (node, "key", mp->key);
3187     }
3188 }
3189
3190 static void
3191 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194   u8 *seid = 0, *deid = 0;
3195   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3196
3197   deid = format (0, "%U", format_lisp_eid_vat,
3198                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3199
3200   seid = format (0, "%U", format_lisp_eid_vat,
3201                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3202
3203   vec_add1 (deid, 0);
3204   vec_add1 (seid, 0);
3205
3206   if (mp->is_ip4)
3207     format_ip_address_fcn = format_ip4_address;
3208   else
3209     format_ip_address_fcn = format_ip6_address;
3210
3211
3212   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3213          clib_net_to_host_u32 (mp->vni),
3214          seid, deid,
3215          format_ip_address_fcn, mp->lloc,
3216          format_ip_address_fcn, mp->rloc,
3217          clib_net_to_host_u32 (mp->pkt_count),
3218          clib_net_to_host_u32 (mp->bytes));
3219
3220   vec_free (deid);
3221   vec_free (seid);
3222 }
3223
3224 static void
3225 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3226 {
3227   struct in6_addr ip6;
3228   struct in_addr ip4;
3229   vat_main_t *vam = &vat_main;
3230   vat_json_node_t *node = 0;
3231   u8 *deid = 0, *seid = 0;
3232
3233   if (VAT_JSON_ARRAY != vam->json_tree.type)
3234     {
3235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3236       vat_json_init_array (&vam->json_tree);
3237     }
3238   node = vat_json_array_add (&vam->json_tree);
3239
3240   vat_json_init_object (node);
3241   deid = format (0, "%U", format_lisp_eid_vat,
3242                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3243
3244   seid = format (0, "%U", format_lisp_eid_vat,
3245                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3246
3247   vec_add1 (deid, 0);
3248   vec_add1 (seid, 0);
3249
3250   vat_json_object_add_string_copy (node, "seid", seid);
3251   vat_json_object_add_string_copy (node, "deid", deid);
3252   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3253
3254   if (mp->is_ip4)
3255     {
3256       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3257       vat_json_object_add_ip4 (node, "lloc", ip4);
3258       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3259       vat_json_object_add_ip4 (node, "rloc", ip4);
3260     }
3261   else
3262     {
3263       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3264       vat_json_object_add_ip6 (node, "lloc", ip6);
3265       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3266       vat_json_object_add_ip6 (node, "rloc", ip6);
3267     }
3268   vat_json_object_add_uint (node, "pkt_count",
3269                             clib_net_to_host_u32 (mp->pkt_count));
3270   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3271
3272   vec_free (deid);
3273   vec_free (seid);
3274 }
3275
3276 static void
3277   vl_api_one_eid_table_map_details_t_handler
3278   (vl_api_one_eid_table_map_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281
3282   u8 *line = format (0, "%=10d%=10d",
3283                      clib_net_to_host_u32 (mp->vni),
3284                      clib_net_to_host_u32 (mp->dp_table));
3285   print (vam->ofp, "%v", line);
3286   vec_free (line);
3287 }
3288
3289 static void
3290   vl_api_one_eid_table_map_details_t_handler_json
3291   (vl_api_one_eid_table_map_details_t * mp)
3292 {
3293   vat_main_t *vam = &vat_main;
3294   vat_json_node_t *node = NULL;
3295
3296   if (VAT_JSON_ARRAY != vam->json_tree.type)
3297     {
3298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3299       vat_json_init_array (&vam->json_tree);
3300     }
3301   node = vat_json_array_add (&vam->json_tree);
3302   vat_json_init_object (node);
3303   vat_json_object_add_uint (node, "dp_table",
3304                             clib_net_to_host_u32 (mp->dp_table));
3305   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3306 }
3307
3308 static void
3309   vl_api_one_eid_table_vni_details_t_handler
3310   (vl_api_one_eid_table_vni_details_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313
3314   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3315   print (vam->ofp, "%v", line);
3316   vec_free (line);
3317 }
3318
3319 static void
3320   vl_api_one_eid_table_vni_details_t_handler_json
3321   (vl_api_one_eid_table_vni_details_t * mp)
3322 {
3323   vat_main_t *vam = &vat_main;
3324   vat_json_node_t *node = NULL;
3325
3326   if (VAT_JSON_ARRAY != vam->json_tree.type)
3327     {
3328       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3329       vat_json_init_array (&vam->json_tree);
3330     }
3331   node = vat_json_array_add (&vam->json_tree);
3332   vat_json_init_object (node);
3333   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3334 }
3335
3336 static void
3337   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3338   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   int retval = clib_net_to_host_u32 (mp->retval);
3342
3343   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3344   print (vam->ofp, "fallback threshold value: %d", mp->value);
3345
3346   vam->retval = retval;
3347   vam->result_ready = 1;
3348 }
3349
3350 static void
3351   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3352   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3353 {
3354   vat_main_t *vam = &vat_main;
3355   vat_json_node_t _node, *node = &_node;
3356   int retval = clib_net_to_host_u32 (mp->retval);
3357
3358   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3359   vat_json_init_object (node);
3360   vat_json_object_add_uint (node, "value", mp->value);
3361
3362   vat_json_print (vam->ofp, node);
3363   vat_json_free (node);
3364
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_show_one_map_register_state_reply_t_handler
3371   (vl_api_show_one_map_register_state_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   int retval = clib_net_to_host_u32 (mp->retval);
3375
3376   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3377
3378   vam->retval = retval;
3379   vam->result_ready = 1;
3380 }
3381
3382 static void
3383   vl_api_show_one_map_register_state_reply_t_handler_json
3384   (vl_api_show_one_map_register_state_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   vat_json_node_t _node, *node = &_node;
3388   int retval = clib_net_to_host_u32 (mp->retval);
3389
3390   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3391
3392   vat_json_init_object (node);
3393   vat_json_object_add_string_copy (node, "state", s);
3394
3395   vat_json_print (vam->ofp, node);
3396   vat_json_free (node);
3397
3398   vam->retval = retval;
3399   vam->result_ready = 1;
3400   vec_free (s);
3401 }
3402
3403 static void
3404   vl_api_show_one_rloc_probe_state_reply_t_handler
3405   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3406 {
3407   vat_main_t *vam = &vat_main;
3408   int retval = clib_net_to_host_u32 (mp->retval);
3409
3410   if (retval)
3411     goto end;
3412
3413   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3414 end:
3415   vam->retval = retval;
3416   vam->result_ready = 1;
3417 }
3418
3419 static void
3420   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3421   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3422 {
3423   vat_main_t *vam = &vat_main;
3424   vat_json_node_t _node, *node = &_node;
3425   int retval = clib_net_to_host_u32 (mp->retval);
3426
3427   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3428   vat_json_init_object (node);
3429   vat_json_object_add_string_copy (node, "state", s);
3430
3431   vat_json_print (vam->ofp, node);
3432   vat_json_free (node);
3433
3434   vam->retval = retval;
3435   vam->result_ready = 1;
3436   vec_free (s);
3437 }
3438
3439 static void
3440   vl_api_show_one_stats_enable_disable_reply_t_handler
3441   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3442 {
3443   vat_main_t *vam = &vat_main;
3444   int retval = clib_net_to_host_u32 (mp->retval);
3445
3446   if (retval)
3447     goto end;
3448
3449   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3450 end:
3451   vam->retval = retval;
3452   vam->result_ready = 1;
3453 }
3454
3455 static void
3456   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3457   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460   vat_json_node_t _node, *node = &_node;
3461   int retval = clib_net_to_host_u32 (mp->retval);
3462
3463   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3464   vat_json_init_object (node);
3465   vat_json_object_add_string_copy (node, "state", s);
3466
3467   vat_json_print (vam->ofp, node);
3468   vat_json_free (node);
3469
3470   vam->retval = retval;
3471   vam->result_ready = 1;
3472   vec_free (s);
3473 }
3474
3475 static void
3476 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3477 {
3478   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3479   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3480   e->vni = clib_net_to_host_u32 (e->vni);
3481 }
3482
3483 static void
3484   gpe_fwd_entries_get_reply_t_net_to_host
3485   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3486 {
3487   u32 i;
3488
3489   mp->count = clib_net_to_host_u32 (mp->count);
3490   for (i = 0; i < mp->count; i++)
3491     {
3492       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3493     }
3494 }
3495
3496 static u8 *
3497 format_gpe_encap_mode (u8 * s, va_list * args)
3498 {
3499   u32 mode = va_arg (*args, u32);
3500
3501   switch (mode)
3502     {
3503     case 0:
3504       return format (s, "lisp");
3505     case 1:
3506       return format (s, "vxlan");
3507     }
3508   return 0;
3509 }
3510
3511 static void
3512   vl_api_gpe_get_encap_mode_reply_t_handler
3513   (vl_api_gpe_get_encap_mode_reply_t * mp)
3514 {
3515   vat_main_t *vam = &vat_main;
3516
3517   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3518   vam->retval = ntohl (mp->retval);
3519   vam->result_ready = 1;
3520 }
3521
3522 static void
3523   vl_api_gpe_get_encap_mode_reply_t_handler_json
3524   (vl_api_gpe_get_encap_mode_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   vat_json_node_t node;
3528
3529   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3530   vec_add1 (encap_mode, 0);
3531
3532   vat_json_init_object (&node);
3533   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3534
3535   vec_free (encap_mode);
3536   vat_json_print (vam->ofp, &node);
3537   vat_json_free (&node);
3538
3539   vam->retval = ntohl (mp->retval);
3540   vam->result_ready = 1;
3541 }
3542
3543 static void
3544   vl_api_gpe_fwd_entry_path_details_t_handler
3545   (vl_api_gpe_fwd_entry_path_details_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3549
3550   if (mp->lcl_loc.is_ip4)
3551     format_ip_address_fcn = format_ip4_address;
3552   else
3553     format_ip_address_fcn = format_ip6_address;
3554
3555   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3556          format_ip_address_fcn, &mp->lcl_loc,
3557          format_ip_address_fcn, &mp->rmt_loc);
3558 }
3559
3560 static void
3561 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3562 {
3563   struct in6_addr ip6;
3564   struct in_addr ip4;
3565
3566   if (loc->is_ip4)
3567     {
3568       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3569       vat_json_object_add_ip4 (n, "address", ip4);
3570     }
3571   else
3572     {
3573       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3574       vat_json_object_add_ip6 (n, "address", ip6);
3575     }
3576   vat_json_object_add_uint (n, "weight", loc->weight);
3577 }
3578
3579 static void
3580   vl_api_gpe_fwd_entry_path_details_t_handler_json
3581   (vl_api_gpe_fwd_entry_path_details_t * mp)
3582 {
3583   vat_main_t *vam = &vat_main;
3584   vat_json_node_t *node = NULL;
3585   vat_json_node_t *loc_node;
3586
3587   if (VAT_JSON_ARRAY != vam->json_tree.type)
3588     {
3589       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3590       vat_json_init_array (&vam->json_tree);
3591     }
3592   node = vat_json_array_add (&vam->json_tree);
3593   vat_json_init_object (node);
3594
3595   loc_node = vat_json_object_add (node, "local_locator");
3596   vat_json_init_object (loc_node);
3597   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3598
3599   loc_node = vat_json_object_add (node, "remote_locator");
3600   vat_json_init_object (loc_node);
3601   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3602 }
3603
3604 static void
3605   vl_api_gpe_fwd_entries_get_reply_t_handler
3606   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3607 {
3608   vat_main_t *vam = &vat_main;
3609   u32 i;
3610   int retval = clib_net_to_host_u32 (mp->retval);
3611   vl_api_gpe_fwd_entry_t *e;
3612
3613   if (retval)
3614     goto end;
3615
3616   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3617
3618   for (i = 0; i < mp->count; i++)
3619     {
3620       e = &mp->entries[i];
3621       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3622              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3623              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3624     }
3625
3626 end:
3627   vam->retval = retval;
3628   vam->result_ready = 1;
3629 }
3630
3631 static void
3632   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3633   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3634 {
3635   u8 *s = 0;
3636   vat_main_t *vam = &vat_main;
3637   vat_json_node_t *e = 0, root;
3638   u32 i;
3639   int retval = clib_net_to_host_u32 (mp->retval);
3640   vl_api_gpe_fwd_entry_t *fwd;
3641
3642   if (retval)
3643     goto end;
3644
3645   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3646   vat_json_init_array (&root);
3647
3648   for (i = 0; i < mp->count; i++)
3649     {
3650       e = vat_json_array_add (&root);
3651       fwd = &mp->entries[i];
3652
3653       vat_json_init_object (e);
3654       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3655       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3656       vat_json_object_add_int (e, "vni", fwd->vni);
3657       vat_json_object_add_int (e, "action", fwd->action);
3658
3659       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3660                   fwd->leid_prefix_len);
3661       vec_add1 (s, 0);
3662       vat_json_object_add_string_copy (e, "leid", s);
3663       vec_free (s);
3664
3665       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3666                   fwd->reid_prefix_len);
3667       vec_add1 (s, 0);
3668       vat_json_object_add_string_copy (e, "reid", s);
3669       vec_free (s);
3670     }
3671
3672   vat_json_print (vam->ofp, &root);
3673   vat_json_free (&root);
3674
3675 end:
3676   vam->retval = retval;
3677   vam->result_ready = 1;
3678 }
3679
3680 static void
3681   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3682   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3683 {
3684   vat_main_t *vam = &vat_main;
3685   u32 i, n;
3686   int retval = clib_net_to_host_u32 (mp->retval);
3687   vl_api_gpe_native_fwd_rpath_t *r;
3688
3689   if (retval)
3690     goto end;
3691
3692   n = clib_net_to_host_u32 (mp->count);
3693
3694   for (i = 0; i < n; i++)
3695     {
3696       r = &mp->entries[i];
3697       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3698              clib_net_to_host_u32 (r->fib_index),
3699              clib_net_to_host_u32 (r->nh_sw_if_index),
3700              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3701     }
3702
3703 end:
3704   vam->retval = retval;
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3710   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   vat_json_node_t root, *e;
3714   u32 i, n;
3715   int retval = clib_net_to_host_u32 (mp->retval);
3716   vl_api_gpe_native_fwd_rpath_t *r;
3717   u8 *s;
3718
3719   if (retval)
3720     goto end;
3721
3722   n = clib_net_to_host_u32 (mp->count);
3723   vat_json_init_array (&root);
3724
3725   for (i = 0; i < n; i++)
3726     {
3727       e = vat_json_array_add (&root);
3728       vat_json_init_object (e);
3729       r = &mp->entries[i];
3730       s =
3731         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3732                 r->nh_addr);
3733       vec_add1 (s, 0);
3734       vat_json_object_add_string_copy (e, "ip4", s);
3735       vec_free (s);
3736
3737       vat_json_object_add_uint (e, "fib_index",
3738                                 clib_net_to_host_u32 (r->fib_index));
3739       vat_json_object_add_uint (e, "nh_sw_if_index",
3740                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3741     }
3742
3743   vat_json_print (vam->ofp, &root);
3744   vat_json_free (&root);
3745
3746 end:
3747   vam->retval = retval;
3748   vam->result_ready = 1;
3749 }
3750
3751 static void
3752   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3753   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3754 {
3755   vat_main_t *vam = &vat_main;
3756   u32 i, n;
3757   int retval = clib_net_to_host_u32 (mp->retval);
3758
3759   if (retval)
3760     goto end;
3761
3762   n = clib_net_to_host_u32 (mp->count);
3763
3764   for (i = 0; i < n; i++)
3765     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3766
3767 end:
3768   vam->retval = retval;
3769   vam->result_ready = 1;
3770 }
3771
3772 static void
3773   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3774   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3775 {
3776   vat_main_t *vam = &vat_main;
3777   vat_json_node_t root;
3778   u32 i, n;
3779   int retval = clib_net_to_host_u32 (mp->retval);
3780
3781   if (retval)
3782     goto end;
3783
3784   n = clib_net_to_host_u32 (mp->count);
3785   vat_json_init_array (&root);
3786
3787   for (i = 0; i < n; i++)
3788     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3789
3790   vat_json_print (vam->ofp, &root);
3791   vat_json_free (&root);
3792
3793 end:
3794   vam->retval = retval;
3795   vam->result_ready = 1;
3796 }
3797
3798 static void
3799   vl_api_one_ndp_entries_get_reply_t_handler
3800   (vl_api_one_ndp_entries_get_reply_t * mp)
3801 {
3802   vat_main_t *vam = &vat_main;
3803   u32 i, n;
3804   int retval = clib_net_to_host_u32 (mp->retval);
3805
3806   if (retval)
3807     goto end;
3808
3809   n = clib_net_to_host_u32 (mp->count);
3810
3811   for (i = 0; i < n; i++)
3812     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3813            format_ethernet_address, mp->entries[i].mac);
3814
3815 end:
3816   vam->retval = retval;
3817   vam->result_ready = 1;
3818 }
3819
3820 static void
3821   vl_api_one_ndp_entries_get_reply_t_handler_json
3822   (vl_api_one_ndp_entries_get_reply_t * mp)
3823 {
3824   u8 *s = 0;
3825   vat_main_t *vam = &vat_main;
3826   vat_json_node_t *e = 0, root;
3827   u32 i, n;
3828   int retval = clib_net_to_host_u32 (mp->retval);
3829   vl_api_one_ndp_entry_t *arp_entry;
3830
3831   if (retval)
3832     goto end;
3833
3834   n = clib_net_to_host_u32 (mp->count);
3835   vat_json_init_array (&root);
3836
3837   for (i = 0; i < n; i++)
3838     {
3839       e = vat_json_array_add (&root);
3840       arp_entry = &mp->entries[i];
3841
3842       vat_json_init_object (e);
3843       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3844       vec_add1 (s, 0);
3845
3846       vat_json_object_add_string_copy (e, "mac", s);
3847       vec_free (s);
3848
3849       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3850       vec_add1 (s, 0);
3851       vat_json_object_add_string_copy (e, "ip6", s);
3852       vec_free (s);
3853     }
3854
3855   vat_json_print (vam->ofp, &root);
3856   vat_json_free (&root);
3857
3858 end:
3859   vam->retval = retval;
3860   vam->result_ready = 1;
3861 }
3862
3863 static void
3864   vl_api_one_l2_arp_entries_get_reply_t_handler
3865   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3866 {
3867   vat_main_t *vam = &vat_main;
3868   u32 i, n;
3869   int retval = clib_net_to_host_u32 (mp->retval);
3870
3871   if (retval)
3872     goto end;
3873
3874   n = clib_net_to_host_u32 (mp->count);
3875
3876   for (i = 0; i < n; i++)
3877     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3878            format_ethernet_address, mp->entries[i].mac);
3879
3880 end:
3881   vam->retval = retval;
3882   vam->result_ready = 1;
3883 }
3884
3885 static void
3886   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3887   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3888 {
3889   u8 *s = 0;
3890   vat_main_t *vam = &vat_main;
3891   vat_json_node_t *e = 0, root;
3892   u32 i, n;
3893   int retval = clib_net_to_host_u32 (mp->retval);
3894   vl_api_one_l2_arp_entry_t *arp_entry;
3895
3896   if (retval)
3897     goto end;
3898
3899   n = clib_net_to_host_u32 (mp->count);
3900   vat_json_init_array (&root);
3901
3902   for (i = 0; i < n; i++)
3903     {
3904       e = vat_json_array_add (&root);
3905       arp_entry = &mp->entries[i];
3906
3907       vat_json_init_object (e);
3908       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3909       vec_add1 (s, 0);
3910
3911       vat_json_object_add_string_copy (e, "mac", s);
3912       vec_free (s);
3913
3914       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3915       vec_add1 (s, 0);
3916       vat_json_object_add_string_copy (e, "ip4", s);
3917       vec_free (s);
3918     }
3919
3920   vat_json_print (vam->ofp, &root);
3921   vat_json_free (&root);
3922
3923 end:
3924   vam->retval = retval;
3925   vam->result_ready = 1;
3926 }
3927
3928 static void
3929 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3930 {
3931   vat_main_t *vam = &vat_main;
3932   u32 i, n;
3933   int retval = clib_net_to_host_u32 (mp->retval);
3934
3935   if (retval)
3936     goto end;
3937
3938   n = clib_net_to_host_u32 (mp->count);
3939
3940   for (i = 0; i < n; i++)
3941     {
3942       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3943     }
3944
3945 end:
3946   vam->retval = retval;
3947   vam->result_ready = 1;
3948 }
3949
3950 static void
3951   vl_api_one_ndp_bd_get_reply_t_handler_json
3952   (vl_api_one_ndp_bd_get_reply_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
3955   vat_json_node_t root;
3956   u32 i, n;
3957   int retval = clib_net_to_host_u32 (mp->retval);
3958
3959   if (retval)
3960     goto end;
3961
3962   n = clib_net_to_host_u32 (mp->count);
3963   vat_json_init_array (&root);
3964
3965   for (i = 0; i < n; i++)
3966     {
3967       vat_json_array_add_uint (&root,
3968                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3969     }
3970
3971   vat_json_print (vam->ofp, &root);
3972   vat_json_free (&root);
3973
3974 end:
3975   vam->retval = retval;
3976   vam->result_ready = 1;
3977 }
3978
3979 static void
3980   vl_api_one_l2_arp_bd_get_reply_t_handler
3981   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3982 {
3983   vat_main_t *vam = &vat_main;
3984   u32 i, n;
3985   int retval = clib_net_to_host_u32 (mp->retval);
3986
3987   if (retval)
3988     goto end;
3989
3990   n = clib_net_to_host_u32 (mp->count);
3991
3992   for (i = 0; i < n; i++)
3993     {
3994       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3995     }
3996
3997 end:
3998   vam->retval = retval;
3999   vam->result_ready = 1;
4000 }
4001
4002 static void
4003   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4004   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4005 {
4006   vat_main_t *vam = &vat_main;
4007   vat_json_node_t root;
4008   u32 i, n;
4009   int retval = clib_net_to_host_u32 (mp->retval);
4010
4011   if (retval)
4012     goto end;
4013
4014   n = clib_net_to_host_u32 (mp->count);
4015   vat_json_init_array (&root);
4016
4017   for (i = 0; i < n; i++)
4018     {
4019       vat_json_array_add_uint (&root,
4020                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4021     }
4022
4023   vat_json_print (vam->ofp, &root);
4024   vat_json_free (&root);
4025
4026 end:
4027   vam->retval = retval;
4028   vam->result_ready = 1;
4029 }
4030
4031 static void
4032   vl_api_one_adjacencies_get_reply_t_handler
4033   (vl_api_one_adjacencies_get_reply_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   u32 i, n;
4037   int retval = clib_net_to_host_u32 (mp->retval);
4038   vl_api_one_adjacency_t *a;
4039
4040   if (retval)
4041     goto end;
4042
4043   n = clib_net_to_host_u32 (mp->count);
4044
4045   for (i = 0; i < n; i++)
4046     {
4047       a = &mp->adjacencies[i];
4048       print (vam->ofp, "%U %40U",
4049              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4050              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4051     }
4052
4053 end:
4054   vam->retval = retval;
4055   vam->result_ready = 1;
4056 }
4057
4058 static void
4059   vl_api_one_adjacencies_get_reply_t_handler_json
4060   (vl_api_one_adjacencies_get_reply_t * mp)
4061 {
4062   u8 *s = 0;
4063   vat_main_t *vam = &vat_main;
4064   vat_json_node_t *e = 0, root;
4065   u32 i, n;
4066   int retval = clib_net_to_host_u32 (mp->retval);
4067   vl_api_one_adjacency_t *a;
4068
4069   if (retval)
4070     goto end;
4071
4072   n = clib_net_to_host_u32 (mp->count);
4073   vat_json_init_array (&root);
4074
4075   for (i = 0; i < n; i++)
4076     {
4077       e = vat_json_array_add (&root);
4078       a = &mp->adjacencies[i];
4079
4080       vat_json_init_object (e);
4081       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4082                   a->leid_prefix_len);
4083       vec_add1 (s, 0);
4084       vat_json_object_add_string_copy (e, "leid", s);
4085       vec_free (s);
4086
4087       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4088                   a->reid_prefix_len);
4089       vec_add1 (s, 0);
4090       vat_json_object_add_string_copy (e, "reid", s);
4091       vec_free (s);
4092     }
4093
4094   vat_json_print (vam->ofp, &root);
4095   vat_json_free (&root);
4096
4097 end:
4098   vam->retval = retval;
4099   vam->result_ready = 1;
4100 }
4101
4102 static void
4103 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4104 {
4105   vat_main_t *vam = &vat_main;
4106
4107   print (vam->ofp, "%=20U",
4108          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4109          mp->ip_address);
4110 }
4111
4112 static void
4113   vl_api_one_map_server_details_t_handler_json
4114   (vl_api_one_map_server_details_t * mp)
4115 {
4116   vat_main_t *vam = &vat_main;
4117   vat_json_node_t *node = NULL;
4118   struct in6_addr ip6;
4119   struct in_addr ip4;
4120
4121   if (VAT_JSON_ARRAY != vam->json_tree.type)
4122     {
4123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4124       vat_json_init_array (&vam->json_tree);
4125     }
4126   node = vat_json_array_add (&vam->json_tree);
4127
4128   vat_json_init_object (node);
4129   if (mp->is_ipv6)
4130     {
4131       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4132       vat_json_object_add_ip6 (node, "map-server", ip6);
4133     }
4134   else
4135     {
4136       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4137       vat_json_object_add_ip4 (node, "map-server", ip4);
4138     }
4139 }
4140
4141 static void
4142 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4143                                            * mp)
4144 {
4145   vat_main_t *vam = &vat_main;
4146
4147   print (vam->ofp, "%=20U",
4148          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4149          mp->ip_address);
4150 }
4151
4152 static void
4153   vl_api_one_map_resolver_details_t_handler_json
4154   (vl_api_one_map_resolver_details_t * mp)
4155 {
4156   vat_main_t *vam = &vat_main;
4157   vat_json_node_t *node = NULL;
4158   struct in6_addr ip6;
4159   struct in_addr ip4;
4160
4161   if (VAT_JSON_ARRAY != vam->json_tree.type)
4162     {
4163       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4164       vat_json_init_array (&vam->json_tree);
4165     }
4166   node = vat_json_array_add (&vam->json_tree);
4167
4168   vat_json_init_object (node);
4169   if (mp->is_ipv6)
4170     {
4171       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4172       vat_json_object_add_ip6 (node, "map resolver", ip6);
4173     }
4174   else
4175     {
4176       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4177       vat_json_object_add_ip4 (node, "map resolver", ip4);
4178     }
4179 }
4180
4181 static void
4182 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4183 {
4184   vat_main_t *vam = &vat_main;
4185   i32 retval = ntohl (mp->retval);
4186
4187   if (0 <= retval)
4188     {
4189       print (vam->ofp, "feature: %s\ngpe: %s",
4190              mp->feature_status ? "enabled" : "disabled",
4191              mp->gpe_status ? "enabled" : "disabled");
4192     }
4193
4194   vam->retval = retval;
4195   vam->result_ready = 1;
4196 }
4197
4198 static void
4199   vl_api_show_one_status_reply_t_handler_json
4200   (vl_api_show_one_status_reply_t * mp)
4201 {
4202   vat_main_t *vam = &vat_main;
4203   vat_json_node_t node;
4204   u8 *gpe_status = NULL;
4205   u8 *feature_status = NULL;
4206
4207   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4208   feature_status = format (0, "%s",
4209                            mp->feature_status ? "enabled" : "disabled");
4210   vec_add1 (gpe_status, 0);
4211   vec_add1 (feature_status, 0);
4212
4213   vat_json_init_object (&node);
4214   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4215   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4216
4217   vec_free (gpe_status);
4218   vec_free (feature_status);
4219
4220   vat_json_print (vam->ofp, &node);
4221   vat_json_free (&node);
4222
4223   vam->retval = ntohl (mp->retval);
4224   vam->result_ready = 1;
4225 }
4226
4227 static void
4228   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4229   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4230 {
4231   vat_main_t *vam = &vat_main;
4232   i32 retval = ntohl (mp->retval);
4233
4234   if (retval >= 0)
4235     {
4236       print (vam->ofp, "%=20s", mp->locator_set_name);
4237     }
4238
4239   vam->retval = retval;
4240   vam->result_ready = 1;
4241 }
4242
4243 static void
4244   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4245   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4246 {
4247   vat_main_t *vam = &vat_main;
4248   vat_json_node_t *node = NULL;
4249
4250   if (VAT_JSON_ARRAY != vam->json_tree.type)
4251     {
4252       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4253       vat_json_init_array (&vam->json_tree);
4254     }
4255   node = vat_json_array_add (&vam->json_tree);
4256
4257   vat_json_init_object (node);
4258   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4259
4260   vat_json_print (vam->ofp, node);
4261   vat_json_free (node);
4262
4263   vam->retval = ntohl (mp->retval);
4264   vam->result_ready = 1;
4265 }
4266
4267 static u8 *
4268 format_lisp_map_request_mode (u8 * s, va_list * args)
4269 {
4270   u32 mode = va_arg (*args, u32);
4271
4272   switch (mode)
4273     {
4274     case 0:
4275       return format (0, "dst-only");
4276     case 1:
4277       return format (0, "src-dst");
4278     }
4279   return 0;
4280 }
4281
4282 static void
4283   vl_api_show_one_map_request_mode_reply_t_handler
4284   (vl_api_show_one_map_request_mode_reply_t * mp)
4285 {
4286   vat_main_t *vam = &vat_main;
4287   i32 retval = ntohl (mp->retval);
4288
4289   if (0 <= retval)
4290     {
4291       u32 mode = mp->mode;
4292       print (vam->ofp, "map_request_mode: %U",
4293              format_lisp_map_request_mode, mode);
4294     }
4295
4296   vam->retval = retval;
4297   vam->result_ready = 1;
4298 }
4299
4300 static void
4301   vl_api_show_one_map_request_mode_reply_t_handler_json
4302   (vl_api_show_one_map_request_mode_reply_t * mp)
4303 {
4304   vat_main_t *vam = &vat_main;
4305   vat_json_node_t node;
4306   u8 *s = 0;
4307   u32 mode;
4308
4309   mode = mp->mode;
4310   s = format (0, "%U", format_lisp_map_request_mode, mode);
4311   vec_add1 (s, 0);
4312
4313   vat_json_init_object (&node);
4314   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4315   vat_json_print (vam->ofp, &node);
4316   vat_json_free (&node);
4317
4318   vec_free (s);
4319   vam->retval = ntohl (mp->retval);
4320   vam->result_ready = 1;
4321 }
4322
4323 static void
4324   vl_api_one_show_xtr_mode_reply_t_handler
4325   (vl_api_one_show_xtr_mode_reply_t * mp)
4326 {
4327   vat_main_t *vam = &vat_main;
4328   i32 retval = ntohl (mp->retval);
4329
4330   if (0 <= retval)
4331     {
4332       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4333     }
4334
4335   vam->retval = retval;
4336   vam->result_ready = 1;
4337 }
4338
4339 static void
4340   vl_api_one_show_xtr_mode_reply_t_handler_json
4341   (vl_api_one_show_xtr_mode_reply_t * mp)
4342 {
4343   vat_main_t *vam = &vat_main;
4344   vat_json_node_t node;
4345   u8 *status = 0;
4346
4347   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4348   vec_add1 (status, 0);
4349
4350   vat_json_init_object (&node);
4351   vat_json_object_add_string_copy (&node, "status", status);
4352
4353   vec_free (status);
4354
4355   vat_json_print (vam->ofp, &node);
4356   vat_json_free (&node);
4357
4358   vam->retval = ntohl (mp->retval);
4359   vam->result_ready = 1;
4360 }
4361
4362 static void
4363   vl_api_one_show_pitr_mode_reply_t_handler
4364   (vl_api_one_show_pitr_mode_reply_t * mp)
4365 {
4366   vat_main_t *vam = &vat_main;
4367   i32 retval = ntohl (mp->retval);
4368
4369   if (0 <= retval)
4370     {
4371       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4372     }
4373
4374   vam->retval = retval;
4375   vam->result_ready = 1;
4376 }
4377
4378 static void
4379   vl_api_one_show_pitr_mode_reply_t_handler_json
4380   (vl_api_one_show_pitr_mode_reply_t * mp)
4381 {
4382   vat_main_t *vam = &vat_main;
4383   vat_json_node_t node;
4384   u8 *status = 0;
4385
4386   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4387   vec_add1 (status, 0);
4388
4389   vat_json_init_object (&node);
4390   vat_json_object_add_string_copy (&node, "status", status);
4391
4392   vec_free (status);
4393
4394   vat_json_print (vam->ofp, &node);
4395   vat_json_free (&node);
4396
4397   vam->retval = ntohl (mp->retval);
4398   vam->result_ready = 1;
4399 }
4400
4401 static void
4402   vl_api_one_show_petr_mode_reply_t_handler
4403   (vl_api_one_show_petr_mode_reply_t * mp)
4404 {
4405   vat_main_t *vam = &vat_main;
4406   i32 retval = ntohl (mp->retval);
4407
4408   if (0 <= retval)
4409     {
4410       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4411     }
4412
4413   vam->retval = retval;
4414   vam->result_ready = 1;
4415 }
4416
4417 static void
4418   vl_api_one_show_petr_mode_reply_t_handler_json
4419   (vl_api_one_show_petr_mode_reply_t * mp)
4420 {
4421   vat_main_t *vam = &vat_main;
4422   vat_json_node_t node;
4423   u8 *status = 0;
4424
4425   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4426   vec_add1 (status, 0);
4427
4428   vat_json_init_object (&node);
4429   vat_json_object_add_string_copy (&node, "status", status);
4430
4431   vec_free (status);
4432
4433   vat_json_print (vam->ofp, &node);
4434   vat_json_free (&node);
4435
4436   vam->retval = ntohl (mp->retval);
4437   vam->result_ready = 1;
4438 }
4439
4440 static void
4441   vl_api_show_one_use_petr_reply_t_handler
4442   (vl_api_show_one_use_petr_reply_t * mp)
4443 {
4444   vat_main_t *vam = &vat_main;
4445   i32 retval = ntohl (mp->retval);
4446
4447   if (0 <= retval)
4448     {
4449       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4450       if (mp->status)
4451         {
4452           print (vam->ofp, "Proxy-ETR address; %U",
4453                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4454                  mp->address);
4455         }
4456     }
4457
4458   vam->retval = retval;
4459   vam->result_ready = 1;
4460 }
4461
4462 static void
4463   vl_api_show_one_use_petr_reply_t_handler_json
4464   (vl_api_show_one_use_petr_reply_t * mp)
4465 {
4466   vat_main_t *vam = &vat_main;
4467   vat_json_node_t node;
4468   u8 *status = 0;
4469   struct in_addr ip4;
4470   struct in6_addr ip6;
4471
4472   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4473   vec_add1 (status, 0);
4474
4475   vat_json_init_object (&node);
4476   vat_json_object_add_string_copy (&node, "status", status);
4477   if (mp->status)
4478     {
4479       if (mp->is_ip4)
4480         {
4481           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4482           vat_json_object_add_ip6 (&node, "address", ip6);
4483         }
4484       else
4485         {
4486           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4487           vat_json_object_add_ip4 (&node, "address", ip4);
4488         }
4489     }
4490
4491   vec_free (status);
4492
4493   vat_json_print (vam->ofp, &node);
4494   vat_json_free (&node);
4495
4496   vam->retval = ntohl (mp->retval);
4497   vam->result_ready = 1;
4498 }
4499
4500 static void
4501   vl_api_show_one_nsh_mapping_reply_t_handler
4502   (vl_api_show_one_nsh_mapping_reply_t * mp)
4503 {
4504   vat_main_t *vam = &vat_main;
4505   i32 retval = ntohl (mp->retval);
4506
4507   if (0 <= retval)
4508     {
4509       print (vam->ofp, "%-20s%-16s",
4510              mp->is_set ? "set" : "not-set",
4511              mp->is_set ? (char *) mp->locator_set_name : "");
4512     }
4513
4514   vam->retval = retval;
4515   vam->result_ready = 1;
4516 }
4517
4518 static void
4519   vl_api_show_one_nsh_mapping_reply_t_handler_json
4520   (vl_api_show_one_nsh_mapping_reply_t * mp)
4521 {
4522   vat_main_t *vam = &vat_main;
4523   vat_json_node_t node;
4524   u8 *status = 0;
4525
4526   status = format (0, "%s", mp->is_set ? "yes" : "no");
4527   vec_add1 (status, 0);
4528
4529   vat_json_init_object (&node);
4530   vat_json_object_add_string_copy (&node, "is_set", status);
4531   if (mp->is_set)
4532     {
4533       vat_json_object_add_string_copy (&node, "locator_set",
4534                                        mp->locator_set_name);
4535     }
4536
4537   vec_free (status);
4538
4539   vat_json_print (vam->ofp, &node);
4540   vat_json_free (&node);
4541
4542   vam->retval = ntohl (mp->retval);
4543   vam->result_ready = 1;
4544 }
4545
4546 static void
4547   vl_api_show_one_map_register_ttl_reply_t_handler
4548   (vl_api_show_one_map_register_ttl_reply_t * mp)
4549 {
4550   vat_main_t *vam = &vat_main;
4551   i32 retval = ntohl (mp->retval);
4552
4553   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4554
4555   if (0 <= retval)
4556     {
4557       print (vam->ofp, "ttl: %u", mp->ttl);
4558     }
4559
4560   vam->retval = retval;
4561   vam->result_ready = 1;
4562 }
4563
4564 static void
4565   vl_api_show_one_map_register_ttl_reply_t_handler_json
4566   (vl_api_show_one_map_register_ttl_reply_t * mp)
4567 {
4568   vat_main_t *vam = &vat_main;
4569   vat_json_node_t node;
4570
4571   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4572   vat_json_init_object (&node);
4573   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4574
4575   vat_json_print (vam->ofp, &node);
4576   vat_json_free (&node);
4577
4578   vam->retval = ntohl (mp->retval);
4579   vam->result_ready = 1;
4580 }
4581
4582 static void
4583 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4584 {
4585   vat_main_t *vam = &vat_main;
4586   i32 retval = ntohl (mp->retval);
4587
4588   if (0 <= retval)
4589     {
4590       print (vam->ofp, "%-20s%-16s",
4591              mp->status ? "enabled" : "disabled",
4592              mp->status ? (char *) mp->locator_set_name : "");
4593     }
4594
4595   vam->retval = retval;
4596   vam->result_ready = 1;
4597 }
4598
4599 static void
4600 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4601 {
4602   vat_main_t *vam = &vat_main;
4603   vat_json_node_t node;
4604   u8 *status = 0;
4605
4606   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4607   vec_add1 (status, 0);
4608
4609   vat_json_init_object (&node);
4610   vat_json_object_add_string_copy (&node, "status", status);
4611   if (mp->status)
4612     {
4613       vat_json_object_add_string_copy (&node, "locator_set",
4614                                        mp->locator_set_name);
4615     }
4616
4617   vec_free (status);
4618
4619   vat_json_print (vam->ofp, &node);
4620   vat_json_free (&node);
4621
4622   vam->retval = ntohl (mp->retval);
4623   vam->result_ready = 1;
4624 }
4625
4626 static u8 *
4627 format_policer_type (u8 * s, va_list * va)
4628 {
4629   u32 i = va_arg (*va, u32);
4630
4631   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4632     s = format (s, "1r2c");
4633   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4634     s = format (s, "1r3c");
4635   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4636     s = format (s, "2r3c-2698");
4637   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4638     s = format (s, "2r3c-4115");
4639   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4640     s = format (s, "2r3c-mef5cf1");
4641   else
4642     s = format (s, "ILLEGAL");
4643   return s;
4644 }
4645
4646 static u8 *
4647 format_policer_rate_type (u8 * s, va_list * va)
4648 {
4649   u32 i = va_arg (*va, u32);
4650
4651   if (i == SSE2_QOS_RATE_KBPS)
4652     s = format (s, "kbps");
4653   else if (i == SSE2_QOS_RATE_PPS)
4654     s = format (s, "pps");
4655   else
4656     s = format (s, "ILLEGAL");
4657   return s;
4658 }
4659
4660 static u8 *
4661 format_policer_round_type (u8 * s, va_list * va)
4662 {
4663   u32 i = va_arg (*va, u32);
4664
4665   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4666     s = format (s, "closest");
4667   else if (i == SSE2_QOS_ROUND_TO_UP)
4668     s = format (s, "up");
4669   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4670     s = format (s, "down");
4671   else
4672     s = format (s, "ILLEGAL");
4673   return s;
4674 }
4675
4676 static u8 *
4677 format_policer_action_type (u8 * s, va_list * va)
4678 {
4679   u32 i = va_arg (*va, u32);
4680
4681   if (i == SSE2_QOS_ACTION_DROP)
4682     s = format (s, "drop");
4683   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4684     s = format (s, "transmit");
4685   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4686     s = format (s, "mark-and-transmit");
4687   else
4688     s = format (s, "ILLEGAL");
4689   return s;
4690 }
4691
4692 static u8 *
4693 format_dscp (u8 * s, va_list * va)
4694 {
4695   u32 i = va_arg (*va, u32);
4696   char *t = 0;
4697
4698   switch (i)
4699     {
4700 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4701       foreach_vnet_dscp
4702 #undef _
4703     default:
4704       return format (s, "ILLEGAL");
4705     }
4706   s = format (s, "%s", t);
4707   return s;
4708 }
4709
4710 static void
4711 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4712 {
4713   vat_main_t *vam = &vat_main;
4714   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4715
4716   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4717     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4718   else
4719     conform_dscp_str = format (0, "");
4720
4721   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4722     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4723   else
4724     exceed_dscp_str = format (0, "");
4725
4726   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4727     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4728   else
4729     violate_dscp_str = format (0, "");
4730
4731   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4732          "rate type %U, round type %U, %s rate, %s color-aware, "
4733          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4734          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4735          "conform action %U%s, exceed action %U%s, violate action %U%s",
4736          mp->name,
4737          format_policer_type, mp->type,
4738          ntohl (mp->cir),
4739          ntohl (mp->eir),
4740          clib_net_to_host_u64 (mp->cb),
4741          clib_net_to_host_u64 (mp->eb),
4742          format_policer_rate_type, mp->rate_type,
4743          format_policer_round_type, mp->round_type,
4744          mp->single_rate ? "single" : "dual",
4745          mp->color_aware ? "is" : "not",
4746          ntohl (mp->cir_tokens_per_period),
4747          ntohl (mp->pir_tokens_per_period),
4748          ntohl (mp->scale),
4749          ntohl (mp->current_limit),
4750          ntohl (mp->current_bucket),
4751          ntohl (mp->extended_limit),
4752          ntohl (mp->extended_bucket),
4753          clib_net_to_host_u64 (mp->last_update_time),
4754          format_policer_action_type, mp->conform_action_type,
4755          conform_dscp_str,
4756          format_policer_action_type, mp->exceed_action_type,
4757          exceed_dscp_str,
4758          format_policer_action_type, mp->violate_action_type,
4759          violate_dscp_str);
4760
4761   vec_free (conform_dscp_str);
4762   vec_free (exceed_dscp_str);
4763   vec_free (violate_dscp_str);
4764 }
4765
4766 static void vl_api_policer_details_t_handler_json
4767   (vl_api_policer_details_t * mp)
4768 {
4769   vat_main_t *vam = &vat_main;
4770   vat_json_node_t *node;
4771   u8 *rate_type_str, *round_type_str, *type_str;
4772   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4773
4774   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4775   round_type_str =
4776     format (0, "%U", format_policer_round_type, mp->round_type);
4777   type_str = format (0, "%U", format_policer_type, mp->type);
4778   conform_action_str = format (0, "%U", format_policer_action_type,
4779                                mp->conform_action_type);
4780   exceed_action_str = format (0, "%U", format_policer_action_type,
4781                               mp->exceed_action_type);
4782   violate_action_str = format (0, "%U", format_policer_action_type,
4783                                mp->violate_action_type);
4784
4785   if (VAT_JSON_ARRAY != vam->json_tree.type)
4786     {
4787       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4788       vat_json_init_array (&vam->json_tree);
4789     }
4790   node = vat_json_array_add (&vam->json_tree);
4791
4792   vat_json_init_object (node);
4793   vat_json_object_add_string_copy (node, "name", mp->name);
4794   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4795   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4796   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4797   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4798   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4799   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4800   vat_json_object_add_string_copy (node, "type", type_str);
4801   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4802   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4803   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4804   vat_json_object_add_uint (node, "cir_tokens_per_period",
4805                             ntohl (mp->cir_tokens_per_period));
4806   vat_json_object_add_uint (node, "eir_tokens_per_period",
4807                             ntohl (mp->pir_tokens_per_period));
4808   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4809   vat_json_object_add_uint (node, "current_bucket",
4810                             ntohl (mp->current_bucket));
4811   vat_json_object_add_uint (node, "extended_limit",
4812                             ntohl (mp->extended_limit));
4813   vat_json_object_add_uint (node, "extended_bucket",
4814                             ntohl (mp->extended_bucket));
4815   vat_json_object_add_uint (node, "last_update_time",
4816                             ntohl (mp->last_update_time));
4817   vat_json_object_add_string_copy (node, "conform_action",
4818                                    conform_action_str);
4819   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4820     {
4821       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4822       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4823       vec_free (dscp_str);
4824     }
4825   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4826   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4827     {
4828       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4829       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4830       vec_free (dscp_str);
4831     }
4832   vat_json_object_add_string_copy (node, "violate_action",
4833                                    violate_action_str);
4834   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4835     {
4836       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4837       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4838       vec_free (dscp_str);
4839     }
4840
4841   vec_free (rate_type_str);
4842   vec_free (round_type_str);
4843   vec_free (type_str);
4844   vec_free (conform_action_str);
4845   vec_free (exceed_action_str);
4846   vec_free (violate_action_str);
4847 }
4848
4849 static void
4850 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4851                                            mp)
4852 {
4853   vat_main_t *vam = &vat_main;
4854   int i, count = ntohl (mp->count);
4855
4856   if (count > 0)
4857     print (vam->ofp, "classify table ids (%d) : ", count);
4858   for (i = 0; i < count; i++)
4859     {
4860       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4861       print (vam->ofp, (i < count - 1) ? "," : "");
4862     }
4863   vam->retval = ntohl (mp->retval);
4864   vam->result_ready = 1;
4865 }
4866
4867 static void
4868   vl_api_classify_table_ids_reply_t_handler_json
4869   (vl_api_classify_table_ids_reply_t * mp)
4870 {
4871   vat_main_t *vam = &vat_main;
4872   int i, count = ntohl (mp->count);
4873
4874   if (count > 0)
4875     {
4876       vat_json_node_t node;
4877
4878       vat_json_init_object (&node);
4879       for (i = 0; i < count; i++)
4880         {
4881           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4882         }
4883       vat_json_print (vam->ofp, &node);
4884       vat_json_free (&node);
4885     }
4886   vam->retval = ntohl (mp->retval);
4887   vam->result_ready = 1;
4888 }
4889
4890 static void
4891   vl_api_classify_table_by_interface_reply_t_handler
4892   (vl_api_classify_table_by_interface_reply_t * mp)
4893 {
4894   vat_main_t *vam = &vat_main;
4895   u32 table_id;
4896
4897   table_id = ntohl (mp->l2_table_id);
4898   if (table_id != ~0)
4899     print (vam->ofp, "l2 table id : %d", table_id);
4900   else
4901     print (vam->ofp, "l2 table id : No input ACL tables configured");
4902   table_id = ntohl (mp->ip4_table_id);
4903   if (table_id != ~0)
4904     print (vam->ofp, "ip4 table id : %d", table_id);
4905   else
4906     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4907   table_id = ntohl (mp->ip6_table_id);
4908   if (table_id != ~0)
4909     print (vam->ofp, "ip6 table id : %d", table_id);
4910   else
4911     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4912   vam->retval = ntohl (mp->retval);
4913   vam->result_ready = 1;
4914 }
4915
4916 static void
4917   vl_api_classify_table_by_interface_reply_t_handler_json
4918   (vl_api_classify_table_by_interface_reply_t * mp)
4919 {
4920   vat_main_t *vam = &vat_main;
4921   vat_json_node_t node;
4922
4923   vat_json_init_object (&node);
4924
4925   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4926   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4927   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4928
4929   vat_json_print (vam->ofp, &node);
4930   vat_json_free (&node);
4931
4932   vam->retval = ntohl (mp->retval);
4933   vam->result_ready = 1;
4934 }
4935
4936 static void vl_api_policer_add_del_reply_t_handler
4937   (vl_api_policer_add_del_reply_t * mp)
4938 {
4939   vat_main_t *vam = &vat_main;
4940   i32 retval = ntohl (mp->retval);
4941   if (vam->async_mode)
4942     {
4943       vam->async_errors += (retval < 0);
4944     }
4945   else
4946     {
4947       vam->retval = retval;
4948       vam->result_ready = 1;
4949       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4950         /*
4951          * Note: this is just barely thread-safe, depends on
4952          * the main thread spinning waiting for an answer...
4953          */
4954         errmsg ("policer index %d", ntohl (mp->policer_index));
4955     }
4956 }
4957
4958 static void vl_api_policer_add_del_reply_t_handler_json
4959   (vl_api_policer_add_del_reply_t * mp)
4960 {
4961   vat_main_t *vam = &vat_main;
4962   vat_json_node_t node;
4963
4964   vat_json_init_object (&node);
4965   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4966   vat_json_object_add_uint (&node, "policer_index",
4967                             ntohl (mp->policer_index));
4968
4969   vat_json_print (vam->ofp, &node);
4970   vat_json_free (&node);
4971
4972   vam->retval = ntohl (mp->retval);
4973   vam->result_ready = 1;
4974 }
4975
4976 /* Format hex dump. */
4977 u8 *
4978 format_hex_bytes (u8 * s, va_list * va)
4979 {
4980   u8 *bytes = va_arg (*va, u8 *);
4981   int n_bytes = va_arg (*va, int);
4982   uword i;
4983
4984   /* Print short or long form depending on byte count. */
4985   uword short_form = n_bytes <= 32;
4986   u32 indent = format_get_indent (s);
4987
4988   if (n_bytes == 0)
4989     return s;
4990
4991   for (i = 0; i < n_bytes; i++)
4992     {
4993       if (!short_form && (i % 32) == 0)
4994         s = format (s, "%08x: ", i);
4995       s = format (s, "%02x", bytes[i]);
4996       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4997         s = format (s, "\n%U", format_white_space, indent);
4998     }
4999
5000   return s;
5001 }
5002
5003 static void
5004 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5005                                             * mp)
5006 {
5007   vat_main_t *vam = &vat_main;
5008   i32 retval = ntohl (mp->retval);
5009   if (retval == 0)
5010     {
5011       print (vam->ofp, "classify table info :");
5012       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5013              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5014              ntohl (mp->miss_next_index));
5015       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5016              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5017              ntohl (mp->match_n_vectors));
5018       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5019              ntohl (mp->mask_length));
5020     }
5021   vam->retval = retval;
5022   vam->result_ready = 1;
5023 }
5024
5025 static void
5026   vl_api_classify_table_info_reply_t_handler_json
5027   (vl_api_classify_table_info_reply_t * mp)
5028 {
5029   vat_main_t *vam = &vat_main;
5030   vat_json_node_t node;
5031
5032   i32 retval = ntohl (mp->retval);
5033   if (retval == 0)
5034     {
5035       vat_json_init_object (&node);
5036
5037       vat_json_object_add_int (&node, "sessions",
5038                                ntohl (mp->active_sessions));
5039       vat_json_object_add_int (&node, "nexttbl",
5040                                ntohl (mp->next_table_index));
5041       vat_json_object_add_int (&node, "nextnode",
5042                                ntohl (mp->miss_next_index));
5043       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5044       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5045       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5046       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5047                       ntohl (mp->mask_length), 0);
5048       vat_json_object_add_string_copy (&node, "mask", s);
5049
5050       vat_json_print (vam->ofp, &node);
5051       vat_json_free (&node);
5052     }
5053   vam->retval = ntohl (mp->retval);
5054   vam->result_ready = 1;
5055 }
5056
5057 static void
5058 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5059                                            mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062
5063   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5064          ntohl (mp->hit_next_index), ntohl (mp->advance),
5065          ntohl (mp->opaque_index));
5066   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5067          ntohl (mp->match_length));
5068 }
5069
5070 static void
5071   vl_api_classify_session_details_t_handler_json
5072   (vl_api_classify_session_details_t * mp)
5073 {
5074   vat_main_t *vam = &vat_main;
5075   vat_json_node_t *node = NULL;
5076
5077   if (VAT_JSON_ARRAY != vam->json_tree.type)
5078     {
5079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5080       vat_json_init_array (&vam->json_tree);
5081     }
5082   node = vat_json_array_add (&vam->json_tree);
5083
5084   vat_json_init_object (node);
5085   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5086   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5087   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5088   u8 *s =
5089     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5090             0);
5091   vat_json_object_add_string_copy (node, "match", s);
5092 }
5093
5094 static void vl_api_pg_create_interface_reply_t_handler
5095   (vl_api_pg_create_interface_reply_t * mp)
5096 {
5097   vat_main_t *vam = &vat_main;
5098
5099   vam->retval = ntohl (mp->retval);
5100   vam->result_ready = 1;
5101 }
5102
5103 static void vl_api_pg_create_interface_reply_t_handler_json
5104   (vl_api_pg_create_interface_reply_t * mp)
5105 {
5106   vat_main_t *vam = &vat_main;
5107   vat_json_node_t node;
5108
5109   i32 retval = ntohl (mp->retval);
5110   if (retval == 0)
5111     {
5112       vat_json_init_object (&node);
5113
5114       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5115
5116       vat_json_print (vam->ofp, &node);
5117       vat_json_free (&node);
5118     }
5119   vam->retval = ntohl (mp->retval);
5120   vam->result_ready = 1;
5121 }
5122
5123 static void vl_api_policer_classify_details_t_handler
5124   (vl_api_policer_classify_details_t * mp)
5125 {
5126   vat_main_t *vam = &vat_main;
5127
5128   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5129          ntohl (mp->table_index));
5130 }
5131
5132 static void vl_api_policer_classify_details_t_handler_json
5133   (vl_api_policer_classify_details_t * mp)
5134 {
5135   vat_main_t *vam = &vat_main;
5136   vat_json_node_t *node;
5137
5138   if (VAT_JSON_ARRAY != vam->json_tree.type)
5139     {
5140       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5141       vat_json_init_array (&vam->json_tree);
5142     }
5143   node = vat_json_array_add (&vam->json_tree);
5144
5145   vat_json_init_object (node);
5146   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5147   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5148 }
5149
5150 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5151   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5152 {
5153   vat_main_t *vam = &vat_main;
5154   i32 retval = ntohl (mp->retval);
5155   if (vam->async_mode)
5156     {
5157       vam->async_errors += (retval < 0);
5158     }
5159   else
5160     {
5161       vam->retval = retval;
5162       vam->sw_if_index = ntohl (mp->sw_if_index);
5163       vam->result_ready = 1;
5164     }
5165 }
5166
5167 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5168   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5169 {
5170   vat_main_t *vam = &vat_main;
5171   vat_json_node_t node;
5172
5173   vat_json_init_object (&node);
5174   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5175   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5176
5177   vat_json_print (vam->ofp, &node);
5178   vat_json_free (&node);
5179
5180   vam->retval = ntohl (mp->retval);
5181   vam->result_ready = 1;
5182 }
5183
5184 static void vl_api_flow_classify_details_t_handler
5185   (vl_api_flow_classify_details_t * mp)
5186 {
5187   vat_main_t *vam = &vat_main;
5188
5189   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5190          ntohl (mp->table_index));
5191 }
5192
5193 static void vl_api_flow_classify_details_t_handler_json
5194   (vl_api_flow_classify_details_t * mp)
5195 {
5196   vat_main_t *vam = &vat_main;
5197   vat_json_node_t *node;
5198
5199   if (VAT_JSON_ARRAY != vam->json_tree.type)
5200     {
5201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5202       vat_json_init_array (&vam->json_tree);
5203     }
5204   node = vat_json_array_add (&vam->json_tree);
5205
5206   vat_json_init_object (node);
5207   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5208   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5209 }
5210
5211 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5212 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5213 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5214 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5215 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5216 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5217 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5218 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5219 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5220 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5221 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5222 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5223 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5224 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5225 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5226 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5227 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5228 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5229 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5230 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5231 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5232 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5233
5234 /*
5235  * Generate boilerplate reply handlers, which
5236  * dig the return value out of the xxx_reply_t API message,
5237  * stick it into vam->retval, and set vam->result_ready
5238  *
5239  * Could also do this by pointing N message decode slots at
5240  * a single function, but that could break in subtle ways.
5241  */
5242
5243 #define foreach_standard_reply_retval_handler           \
5244 _(sw_interface_set_flags_reply)                         \
5245 _(sw_interface_add_del_address_reply)                   \
5246 _(sw_interface_set_rx_mode_reply)                       \
5247 _(sw_interface_set_table_reply)                         \
5248 _(sw_interface_set_mpls_enable_reply)                   \
5249 _(sw_interface_set_vpath_reply)                         \
5250 _(sw_interface_set_vxlan_bypass_reply)                  \
5251 _(sw_interface_set_geneve_bypass_reply)                 \
5252 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5253 _(sw_interface_set_l2_bridge_reply)                     \
5254 _(bridge_domain_add_del_reply)                          \
5255 _(sw_interface_set_l2_xconnect_reply)                   \
5256 _(l2fib_add_del_reply)                                  \
5257 _(l2fib_flush_int_reply)                                \
5258 _(l2fib_flush_bd_reply)                                 \
5259 _(ip_add_del_route_reply)                               \
5260 _(ip_table_add_del_reply)                               \
5261 _(ip_mroute_add_del_reply)                              \
5262 _(mpls_route_add_del_reply)                             \
5263 _(mpls_table_add_del_reply)                             \
5264 _(mpls_ip_bind_unbind_reply)                            \
5265 _(bier_route_add_del_reply)                             \
5266 _(bier_table_add_del_reply)                             \
5267 _(proxy_arp_add_del_reply)                              \
5268 _(proxy_arp_intfc_enable_disable_reply)                 \
5269 _(sw_interface_set_unnumbered_reply)                    \
5270 _(ip_neighbor_add_del_reply)                            \
5271 _(oam_add_del_reply)                                    \
5272 _(reset_fib_reply)                                      \
5273 _(dhcp_proxy_config_reply)                              \
5274 _(dhcp_proxy_set_vss_reply)                             \
5275 _(dhcp_client_config_reply)                             \
5276 _(set_ip_flow_hash_reply)                               \
5277 _(sw_interface_ip6_enable_disable_reply)                \
5278 _(sw_interface_ip6_set_link_local_address_reply)        \
5279 _(ip6nd_proxy_add_del_reply)                            \
5280 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5281 _(sw_interface_ip6nd_ra_config_reply)                   \
5282 _(set_arp_neighbor_limit_reply)                         \
5283 _(l2_patch_add_del_reply)                               \
5284 _(sr_policy_add_reply)                                  \
5285 _(sr_policy_mod_reply)                                  \
5286 _(sr_policy_del_reply)                                  \
5287 _(sr_localsid_add_del_reply)                            \
5288 _(sr_steering_add_del_reply)                            \
5289 _(classify_add_del_session_reply)                       \
5290 _(classify_set_interface_ip_table_reply)                \
5291 _(classify_set_interface_l2_tables_reply)               \
5292 _(l2tpv3_set_tunnel_cookies_reply)                      \
5293 _(l2tpv3_interface_enable_disable_reply)                \
5294 _(l2tpv3_set_lookup_key_reply)                          \
5295 _(l2_fib_clear_table_reply)                             \
5296 _(l2_interface_efp_filter_reply)                        \
5297 _(l2_interface_vlan_tag_rewrite_reply)                  \
5298 _(modify_vhost_user_if_reply)                           \
5299 _(delete_vhost_user_if_reply)                           \
5300 _(want_ip4_arp_events_reply)                            \
5301 _(want_ip6_nd_events_reply)                             \
5302 _(want_l2_macs_events_reply)                            \
5303 _(input_acl_set_interface_reply)                        \
5304 _(ipsec_spd_add_del_reply)                              \
5305 _(ipsec_interface_add_del_spd_reply)                    \
5306 _(ipsec_spd_add_del_entry_reply)                        \
5307 _(ipsec_sad_add_del_entry_reply)                        \
5308 _(ipsec_sa_set_key_reply)                               \
5309 _(ipsec_tunnel_if_add_del_reply)                        \
5310 _(ipsec_tunnel_if_set_key_reply)                        \
5311 _(ipsec_tunnel_if_set_sa_reply)                         \
5312 _(ikev2_profile_add_del_reply)                          \
5313 _(ikev2_profile_set_auth_reply)                         \
5314 _(ikev2_profile_set_id_reply)                           \
5315 _(ikev2_profile_set_ts_reply)                           \
5316 _(ikev2_set_local_key_reply)                            \
5317 _(ikev2_set_responder_reply)                            \
5318 _(ikev2_set_ike_transforms_reply)                       \
5319 _(ikev2_set_esp_transforms_reply)                       \
5320 _(ikev2_set_sa_lifetime_reply)                          \
5321 _(ikev2_initiate_sa_init_reply)                         \
5322 _(ikev2_initiate_del_ike_sa_reply)                      \
5323 _(ikev2_initiate_del_child_sa_reply)                    \
5324 _(ikev2_initiate_rekey_child_sa_reply)                  \
5325 _(delete_loopback_reply)                                \
5326 _(bd_ip_mac_add_del_reply)                              \
5327 _(map_del_domain_reply)                                 \
5328 _(map_add_del_rule_reply)                               \
5329 _(want_interface_events_reply)                          \
5330 _(want_stats_reply)                                     \
5331 _(cop_interface_enable_disable_reply)                   \
5332 _(cop_whitelist_enable_disable_reply)                   \
5333 _(sw_interface_clear_stats_reply)                       \
5334 _(ioam_enable_reply)                                    \
5335 _(ioam_disable_reply)                                   \
5336 _(one_add_del_locator_reply)                            \
5337 _(one_add_del_local_eid_reply)                          \
5338 _(one_add_del_remote_mapping_reply)                     \
5339 _(one_add_del_adjacency_reply)                          \
5340 _(one_add_del_map_resolver_reply)                       \
5341 _(one_add_del_map_server_reply)                         \
5342 _(one_enable_disable_reply)                             \
5343 _(one_rloc_probe_enable_disable_reply)                  \
5344 _(one_map_register_enable_disable_reply)                \
5345 _(one_map_register_set_ttl_reply)                       \
5346 _(one_set_transport_protocol_reply)                     \
5347 _(one_map_register_fallback_threshold_reply)            \
5348 _(one_pitr_set_locator_set_reply)                       \
5349 _(one_map_request_mode_reply)                           \
5350 _(one_add_del_map_request_itr_rlocs_reply)              \
5351 _(one_eid_table_add_del_map_reply)                      \
5352 _(one_use_petr_reply)                                   \
5353 _(one_stats_enable_disable_reply)                       \
5354 _(one_add_del_l2_arp_entry_reply)                       \
5355 _(one_add_del_ndp_entry_reply)                          \
5356 _(one_stats_flush_reply)                                \
5357 _(one_enable_disable_xtr_mode_reply)                    \
5358 _(one_enable_disable_pitr_mode_reply)                   \
5359 _(one_enable_disable_petr_mode_reply)                   \
5360 _(gpe_enable_disable_reply)                             \
5361 _(gpe_set_encap_mode_reply)                             \
5362 _(gpe_add_del_iface_reply)                              \
5363 _(gpe_add_del_native_fwd_rpath_reply)                   \
5364 _(af_packet_delete_reply)                               \
5365 _(policer_classify_set_interface_reply)                 \
5366 _(netmap_create_reply)                                  \
5367 _(netmap_delete_reply)                                  \
5368 _(set_ipfix_exporter_reply)                             \
5369 _(set_ipfix_classify_stream_reply)                      \
5370 _(ipfix_classify_table_add_del_reply)                   \
5371 _(flow_classify_set_interface_reply)                    \
5372 _(sw_interface_span_enable_disable_reply)               \
5373 _(pg_capture_reply)                                     \
5374 _(pg_enable_disable_reply)                              \
5375 _(ip_source_and_port_range_check_add_del_reply)         \
5376 _(ip_source_and_port_range_check_interface_add_del_reply)\
5377 _(delete_subif_reply)                                   \
5378 _(l2_interface_pbb_tag_rewrite_reply)                   \
5379 _(punt_reply)                                           \
5380 _(feature_enable_disable_reply)                         \
5381 _(sw_interface_tag_add_del_reply)                       \
5382 _(sw_interface_set_mtu_reply)                           \
5383 _(p2p_ethernet_add_reply)                               \
5384 _(p2p_ethernet_del_reply)                               \
5385 _(lldp_config_reply)                                    \
5386 _(sw_interface_set_lldp_reply)                          \
5387 _(tcp_configure_src_addresses_reply)                    \
5388 _(dns_enable_disable_reply)                             \
5389 _(dns_name_server_add_del_reply)                        \
5390 _(session_rule_add_del_reply)                           \
5391 _(ip_container_proxy_add_del_reply)
5392
5393 #define _(n)                                    \
5394     static void vl_api_##n##_t_handler          \
5395     (vl_api_##n##_t * mp)                       \
5396     {                                           \
5397         vat_main_t * vam = &vat_main;           \
5398         i32 retval = ntohl(mp->retval);         \
5399         if (vam->async_mode) {                  \
5400             vam->async_errors += (retval < 0);  \
5401         } else {                                \
5402             vam->retval = retval;               \
5403             vam->result_ready = 1;              \
5404         }                                       \
5405     }
5406 foreach_standard_reply_retval_handler;
5407 #undef _
5408
5409 #define _(n)                                    \
5410     static void vl_api_##n##_t_handler_json     \
5411     (vl_api_##n##_t * mp)                       \
5412     {                                           \
5413         vat_main_t * vam = &vat_main;           \
5414         vat_json_node_t node;                   \
5415         vat_json_init_object(&node);            \
5416         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5417         vat_json_print(vam->ofp, &node);        \
5418         vam->retval = ntohl(mp->retval);        \
5419         vam->result_ready = 1;                  \
5420     }
5421 foreach_standard_reply_retval_handler;
5422 #undef _
5423
5424 /*
5425  * Table of message reply handlers, must include boilerplate handlers
5426  * we just generated
5427  */
5428
5429 #define foreach_vpe_api_reply_msg                                       \
5430 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5431 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5432 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5433 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5434 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5435 _(CLI_REPLY, cli_reply)                                                 \
5436 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5437 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5438   sw_interface_add_del_address_reply)                                   \
5439 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5440 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5441 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5442 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5443 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5444 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5445 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5446 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5447   sw_interface_set_l2_xconnect_reply)                                   \
5448 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5449   sw_interface_set_l2_bridge_reply)                                     \
5450 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5451 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5452 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5453 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5454 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5455 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5456 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5457 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5458 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5459 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5460 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5461 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5462 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5463 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5464 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5465 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5466 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5467 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5468 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5469 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5470 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5471 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5472 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5473 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5474 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5475   proxy_arp_intfc_enable_disable_reply)                                 \
5476 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5477 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5478   sw_interface_set_unnumbered_reply)                                    \
5479 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5480 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5481 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5482 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5483 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5484 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5485 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5486 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5487 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5488 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5489 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5490   sw_interface_ip6_enable_disable_reply)                                \
5491 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5492   sw_interface_ip6_set_link_local_address_reply)                        \
5493 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5494 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5495 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5496   sw_interface_ip6nd_ra_prefix_reply)                                   \
5497 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5498   sw_interface_ip6nd_ra_config_reply)                                   \
5499 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5500 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5501 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5502 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5503 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5504 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5505 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5506 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5507 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5508 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5509 classify_set_interface_ip_table_reply)                                  \
5510 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5511   classify_set_interface_l2_tables_reply)                               \
5512 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5513 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5514 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5515 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5516 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5517   l2tpv3_interface_enable_disable_reply)                                \
5518 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5519 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5520 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5521 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5522 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5523 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5524 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5525 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5526 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5527 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5528 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5529 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5530 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5531 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5532 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5533 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5534 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5535 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5536 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5537 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5538 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5539 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5540 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5541 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5542 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5543 _(L2_MACS_EVENT, l2_macs_event)                                         \
5544 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5545 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5546 _(IP_DETAILS, ip_details)                                               \
5547 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5548 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5549 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5550 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5551 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5552 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5553 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5554 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5555 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5556 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5557 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5558 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5559 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5560 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5561 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5562 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5563 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5564 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5565 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5566 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5567 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5568 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5569 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5570 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5571 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5572 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5573 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5574 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5575 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5576 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5577 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5578 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5579 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5580 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5581 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5582 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5583 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5584 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5585 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5586 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5587 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5588 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5589 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5590 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5591 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5592 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5593 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5594 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5595   one_map_register_enable_disable_reply)                                \
5596 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5597 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5598 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5599 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5600   one_map_register_fallback_threshold_reply)                            \
5601 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5602   one_rloc_probe_enable_disable_reply)                                  \
5603 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5604 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5605 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5606 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5607 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5608 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5609 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5610 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5611 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5612 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5613 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5614 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5615 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5616 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5617 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5618 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5619   show_one_stats_enable_disable_reply)                                  \
5620 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5621 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5622 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5623 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5624 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5625 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5626 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5627 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5628   one_enable_disable_pitr_mode_reply)                                   \
5629 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5630   one_enable_disable_petr_mode_reply)                                   \
5631 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5632 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5633 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5634 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5635 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5636 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5637 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5638 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5639 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5640 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5641 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5642 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5643   gpe_add_del_native_fwd_rpath_reply)                                   \
5644 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5645   gpe_fwd_entry_path_details)                                           \
5646 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5647 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5648   one_add_del_map_request_itr_rlocs_reply)                              \
5649 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5650   one_get_map_request_itr_rlocs_reply)                                  \
5651 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5652 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5653 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5654 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5655 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5656 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5657   show_one_map_register_state_reply)                                    \
5658 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5659 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5660   show_one_map_register_fallback_threshold_reply)                       \
5661 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5662 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5663 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5664 _(POLICER_DETAILS, policer_details)                                     \
5665 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5666 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5667 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5668 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5669 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5670 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5671 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5672 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5673 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5674 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5675 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5676 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5677 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5678 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5679 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5680 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5681 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5682 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5683 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5684 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5685 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5686 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5687 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5688 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5689 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5690  ip_source_and_port_range_check_add_del_reply)                          \
5691 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5692  ip_source_and_port_range_check_interface_add_del_reply)                \
5693 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5694 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5695 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5696 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5697 _(PUNT_REPLY, punt_reply)                                               \
5698 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5699 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5700 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5701 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5702 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5703 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5704 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5705 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5706 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5707 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5708 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5709 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5710 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5711 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5712 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5713 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5714 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5715 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5716 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5717 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5718 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5719
5720 #define foreach_standalone_reply_msg                                    \
5721 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5722 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5723 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5724 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5725 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5726 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5727 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5728 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5729
5730 typedef struct
5731 {
5732   u8 *name;
5733   u32 value;
5734 } name_sort_t;
5735
5736
5737 #define STR_VTR_OP_CASE(op)     \
5738     case L2_VTR_ ## op:         \
5739         return "" # op;
5740
5741 static const char *
5742 str_vtr_op (u32 vtr_op)
5743 {
5744   switch (vtr_op)
5745     {
5746       STR_VTR_OP_CASE (DISABLED);
5747       STR_VTR_OP_CASE (PUSH_1);
5748       STR_VTR_OP_CASE (PUSH_2);
5749       STR_VTR_OP_CASE (POP_1);
5750       STR_VTR_OP_CASE (POP_2);
5751       STR_VTR_OP_CASE (TRANSLATE_1_1);
5752       STR_VTR_OP_CASE (TRANSLATE_1_2);
5753       STR_VTR_OP_CASE (TRANSLATE_2_1);
5754       STR_VTR_OP_CASE (TRANSLATE_2_2);
5755     }
5756
5757   return "UNKNOWN";
5758 }
5759
5760 static int
5761 dump_sub_interface_table (vat_main_t * vam)
5762 {
5763   const sw_interface_subif_t *sub = NULL;
5764
5765   if (vam->json_output)
5766     {
5767       clib_warning
5768         ("JSON output supported only for VPE API calls and dump_stats_table");
5769       return -99;
5770     }
5771
5772   print (vam->ofp,
5773          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5774          "Interface", "sw_if_index",
5775          "sub id", "dot1ad", "tags", "outer id",
5776          "inner id", "exact", "default", "outer any", "inner any");
5777
5778   vec_foreach (sub, vam->sw_if_subif_table)
5779   {
5780     print (vam->ofp,
5781            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5782            sub->interface_name,
5783            sub->sw_if_index,
5784            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5785            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5786            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5787            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5788     if (sub->vtr_op != L2_VTR_DISABLED)
5789       {
5790         print (vam->ofp,
5791                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5792                "tag1: %d tag2: %d ]",
5793                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5794                sub->vtr_tag1, sub->vtr_tag2);
5795       }
5796   }
5797
5798   return 0;
5799 }
5800
5801 static int
5802 name_sort_cmp (void *a1, void *a2)
5803 {
5804   name_sort_t *n1 = a1;
5805   name_sort_t *n2 = a2;
5806
5807   return strcmp ((char *) n1->name, (char *) n2->name);
5808 }
5809
5810 static int
5811 dump_interface_table (vat_main_t * vam)
5812 {
5813   hash_pair_t *p;
5814   name_sort_t *nses = 0, *ns;
5815
5816   if (vam->json_output)
5817     {
5818       clib_warning
5819         ("JSON output supported only for VPE API calls and dump_stats_table");
5820       return -99;
5821     }
5822
5823   /* *INDENT-OFF* */
5824   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5825   ({
5826     vec_add2 (nses, ns, 1);
5827     ns->name = (u8 *)(p->key);
5828     ns->value = (u32) p->value[0];
5829   }));
5830   /* *INDENT-ON* */
5831
5832   vec_sort_with_function (nses, name_sort_cmp);
5833
5834   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5835   vec_foreach (ns, nses)
5836   {
5837     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5838   }
5839   vec_free (nses);
5840   return 0;
5841 }
5842
5843 static int
5844 dump_ip_table (vat_main_t * vam, int is_ipv6)
5845 {
5846   const ip_details_t *det = NULL;
5847   const ip_address_details_t *address = NULL;
5848   u32 i = ~0;
5849
5850   print (vam->ofp, "%-12s", "sw_if_index");
5851
5852   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5853   {
5854     i++;
5855     if (!det->present)
5856       {
5857         continue;
5858       }
5859     print (vam->ofp, "%-12d", i);
5860     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5861     if (!det->addr)
5862       {
5863         continue;
5864       }
5865     vec_foreach (address, det->addr)
5866     {
5867       print (vam->ofp,
5868              "            %-30U%-13d",
5869              is_ipv6 ? format_ip6_address : format_ip4_address,
5870              address->ip, address->prefix_length);
5871     }
5872   }
5873
5874   return 0;
5875 }
5876
5877 static int
5878 dump_ipv4_table (vat_main_t * vam)
5879 {
5880   if (vam->json_output)
5881     {
5882       clib_warning
5883         ("JSON output supported only for VPE API calls and dump_stats_table");
5884       return -99;
5885     }
5886
5887   return dump_ip_table (vam, 0);
5888 }
5889
5890 static int
5891 dump_ipv6_table (vat_main_t * vam)
5892 {
5893   if (vam->json_output)
5894     {
5895       clib_warning
5896         ("JSON output supported only for VPE API calls and dump_stats_table");
5897       return -99;
5898     }
5899
5900   return dump_ip_table (vam, 1);
5901 }
5902
5903 static char *
5904 counter_type_to_str (u8 counter_type, u8 is_combined)
5905 {
5906   if (!is_combined)
5907     {
5908       switch (counter_type)
5909         {
5910         case VNET_INTERFACE_COUNTER_DROP:
5911           return "drop";
5912         case VNET_INTERFACE_COUNTER_PUNT:
5913           return "punt";
5914         case VNET_INTERFACE_COUNTER_IP4:
5915           return "ip4";
5916         case VNET_INTERFACE_COUNTER_IP6:
5917           return "ip6";
5918         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5919           return "rx-no-buf";
5920         case VNET_INTERFACE_COUNTER_RX_MISS:
5921           return "rx-miss";
5922         case VNET_INTERFACE_COUNTER_RX_ERROR:
5923           return "rx-error";
5924         case VNET_INTERFACE_COUNTER_TX_ERROR:
5925           return "tx-error";
5926         default:
5927           return "INVALID-COUNTER-TYPE";
5928         }
5929     }
5930   else
5931     {
5932       switch (counter_type)
5933         {
5934         case VNET_INTERFACE_COUNTER_RX:
5935           return "rx";
5936         case VNET_INTERFACE_COUNTER_TX:
5937           return "tx";
5938         default:
5939           return "INVALID-COUNTER-TYPE";
5940         }
5941     }
5942 }
5943
5944 static int
5945 dump_stats_table (vat_main_t * vam)
5946 {
5947   vat_json_node_t node;
5948   vat_json_node_t *msg_array;
5949   vat_json_node_t *msg;
5950   vat_json_node_t *counter_array;
5951   vat_json_node_t *counter;
5952   interface_counter_t c;
5953   u64 packets;
5954   ip4_fib_counter_t *c4;
5955   ip6_fib_counter_t *c6;
5956   ip4_nbr_counter_t *n4;
5957   ip6_nbr_counter_t *n6;
5958   int i, j;
5959
5960   if (!vam->json_output)
5961     {
5962       clib_warning ("dump_stats_table supported only in JSON format");
5963       return -99;
5964     }
5965
5966   vat_json_init_object (&node);
5967
5968   /* interface counters */
5969   msg_array = vat_json_object_add (&node, "interface_counters");
5970   vat_json_init_array (msg_array);
5971   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5972     {
5973       msg = vat_json_array_add (msg_array);
5974       vat_json_init_object (msg);
5975       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5976                                        (u8 *) counter_type_to_str (i, 0));
5977       vat_json_object_add_int (msg, "is_combined", 0);
5978       counter_array = vat_json_object_add (msg, "data");
5979       vat_json_init_array (counter_array);
5980       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5981         {
5982           packets = vam->simple_interface_counters[i][j];
5983           vat_json_array_add_uint (counter_array, packets);
5984         }
5985     }
5986   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5987     {
5988       msg = vat_json_array_add (msg_array);
5989       vat_json_init_object (msg);
5990       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5991                                        (u8 *) counter_type_to_str (i, 1));
5992       vat_json_object_add_int (msg, "is_combined", 1);
5993       counter_array = vat_json_object_add (msg, "data");
5994       vat_json_init_array (counter_array);
5995       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5996         {
5997           c = vam->combined_interface_counters[i][j];
5998           counter = vat_json_array_add (counter_array);
5999           vat_json_init_object (counter);
6000           vat_json_object_add_uint (counter, "packets", c.packets);
6001           vat_json_object_add_uint (counter, "bytes", c.bytes);
6002         }
6003     }
6004
6005   /* ip4 fib counters */
6006   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6007   vat_json_init_array (msg_array);
6008   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6009     {
6010       msg = vat_json_array_add (msg_array);
6011       vat_json_init_object (msg);
6012       vat_json_object_add_uint (msg, "vrf_id",
6013                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6014       counter_array = vat_json_object_add (msg, "c");
6015       vat_json_init_array (counter_array);
6016       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6017         {
6018           counter = vat_json_array_add (counter_array);
6019           vat_json_init_object (counter);
6020           c4 = &vam->ip4_fib_counters[i][j];
6021           vat_json_object_add_ip4 (counter, "address", c4->address);
6022           vat_json_object_add_uint (counter, "address_length",
6023                                     c4->address_length);
6024           vat_json_object_add_uint (counter, "packets", c4->packets);
6025           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6026         }
6027     }
6028
6029   /* ip6 fib counters */
6030   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6031   vat_json_init_array (msg_array);
6032   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6033     {
6034       msg = vat_json_array_add (msg_array);
6035       vat_json_init_object (msg);
6036       vat_json_object_add_uint (msg, "vrf_id",
6037                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6038       counter_array = vat_json_object_add (msg, "c");
6039       vat_json_init_array (counter_array);
6040       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6041         {
6042           counter = vat_json_array_add (counter_array);
6043           vat_json_init_object (counter);
6044           c6 = &vam->ip6_fib_counters[i][j];
6045           vat_json_object_add_ip6 (counter, "address", c6->address);
6046           vat_json_object_add_uint (counter, "address_length",
6047                                     c6->address_length);
6048           vat_json_object_add_uint (counter, "packets", c6->packets);
6049           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6050         }
6051     }
6052
6053   /* ip4 nbr counters */
6054   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6055   vat_json_init_array (msg_array);
6056   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6057     {
6058       msg = vat_json_array_add (msg_array);
6059       vat_json_init_object (msg);
6060       vat_json_object_add_uint (msg, "sw_if_index", i);
6061       counter_array = vat_json_object_add (msg, "c");
6062       vat_json_init_array (counter_array);
6063       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6064         {
6065           counter = vat_json_array_add (counter_array);
6066           vat_json_init_object (counter);
6067           n4 = &vam->ip4_nbr_counters[i][j];
6068           vat_json_object_add_ip4 (counter, "address", n4->address);
6069           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6070           vat_json_object_add_uint (counter, "packets", n4->packets);
6071           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6072         }
6073     }
6074
6075   /* ip6 nbr counters */
6076   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6077   vat_json_init_array (msg_array);
6078   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6079     {
6080       msg = vat_json_array_add (msg_array);
6081       vat_json_init_object (msg);
6082       vat_json_object_add_uint (msg, "sw_if_index", i);
6083       counter_array = vat_json_object_add (msg, "c");
6084       vat_json_init_array (counter_array);
6085       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6086         {
6087           counter = vat_json_array_add (counter_array);
6088           vat_json_init_object (counter);
6089           n6 = &vam->ip6_nbr_counters[i][j];
6090           vat_json_object_add_ip6 (counter, "address", n6->address);
6091           vat_json_object_add_uint (counter, "packets", n6->packets);
6092           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6093         }
6094     }
6095
6096   vat_json_print (vam->ofp, &node);
6097   vat_json_free (&node);
6098
6099   return 0;
6100 }
6101
6102 /*
6103  * Pass CLI buffers directly in the CLI_INBAND API message,
6104  * instead of an additional shared memory area.
6105  */
6106 static int
6107 exec_inband (vat_main_t * vam)
6108 {
6109   vl_api_cli_inband_t *mp;
6110   unformat_input_t *i = vam->input;
6111   int ret;
6112
6113   if (vec_len (i->buffer) == 0)
6114     return -1;
6115
6116   if (vam->exec_mode == 0 && unformat (i, "mode"))
6117     {
6118       vam->exec_mode = 1;
6119       return 0;
6120     }
6121   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6122     {
6123       vam->exec_mode = 0;
6124       return 0;
6125     }
6126
6127   /*
6128    * In order for the CLI command to work, it
6129    * must be a vector ending in \n, not a C-string ending
6130    * in \n\0.
6131    */
6132   u32 len = vec_len (vam->input->buffer);
6133   M2 (CLI_INBAND, mp, len);
6134   clib_memcpy (mp->cmd, vam->input->buffer, len);
6135   mp->length = htonl (len);
6136
6137   S (mp);
6138   W (ret);
6139   /* json responses may or may not include a useful reply... */
6140   if (vec_len (vam->cmd_reply))
6141     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6142   return ret;
6143 }
6144
6145 int
6146 exec (vat_main_t * vam)
6147 {
6148   return exec_inband (vam);
6149 }
6150
6151 static int
6152 api_create_loopback (vat_main_t * vam)
6153 {
6154   unformat_input_t *i = vam->input;
6155   vl_api_create_loopback_t *mp;
6156   vl_api_create_loopback_instance_t *mp_lbi;
6157   u8 mac_address[6];
6158   u8 mac_set = 0;
6159   u8 is_specified = 0;
6160   u32 user_instance = 0;
6161   int ret;
6162
6163   memset (mac_address, 0, sizeof (mac_address));
6164
6165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6166     {
6167       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6168         mac_set = 1;
6169       if (unformat (i, "instance %d", &user_instance))
6170         is_specified = 1;
6171       else
6172         break;
6173     }
6174
6175   if (is_specified)
6176     {
6177       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6178       mp_lbi->is_specified = is_specified;
6179       if (is_specified)
6180         mp_lbi->user_instance = htonl (user_instance);
6181       if (mac_set)
6182         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6183       S (mp_lbi);
6184     }
6185   else
6186     {
6187       /* Construct the API message */
6188       M (CREATE_LOOPBACK, mp);
6189       if (mac_set)
6190         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6191       S (mp);
6192     }
6193
6194   W (ret);
6195   return ret;
6196 }
6197
6198 static int
6199 api_delete_loopback (vat_main_t * vam)
6200 {
6201   unformat_input_t *i = vam->input;
6202   vl_api_delete_loopback_t *mp;
6203   u32 sw_if_index = ~0;
6204   int ret;
6205
6206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6207     {
6208       if (unformat (i, "sw_if_index %d", &sw_if_index))
6209         ;
6210       else
6211         break;
6212     }
6213
6214   if (sw_if_index == ~0)
6215     {
6216       errmsg ("missing sw_if_index");
6217       return -99;
6218     }
6219
6220   /* Construct the API message */
6221   M (DELETE_LOOPBACK, mp);
6222   mp->sw_if_index = ntohl (sw_if_index);
6223
6224   S (mp);
6225   W (ret);
6226   return ret;
6227 }
6228
6229 static int
6230 api_want_stats (vat_main_t * vam)
6231 {
6232   unformat_input_t *i = vam->input;
6233   vl_api_want_stats_t *mp;
6234   int enable = -1;
6235   int ret;
6236
6237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6238     {
6239       if (unformat (i, "enable"))
6240         enable = 1;
6241       else if (unformat (i, "disable"))
6242         enable = 0;
6243       else
6244         break;
6245     }
6246
6247   if (enable == -1)
6248     {
6249       errmsg ("missing enable|disable");
6250       return -99;
6251     }
6252
6253   M (WANT_STATS, mp);
6254   mp->enable_disable = enable;
6255
6256   S (mp);
6257   W (ret);
6258   return ret;
6259 }
6260
6261 static int
6262 api_want_interface_events (vat_main_t * vam)
6263 {
6264   unformat_input_t *i = vam->input;
6265   vl_api_want_interface_events_t *mp;
6266   int enable = -1;
6267   int ret;
6268
6269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6270     {
6271       if (unformat (i, "enable"))
6272         enable = 1;
6273       else if (unformat (i, "disable"))
6274         enable = 0;
6275       else
6276         break;
6277     }
6278
6279   if (enable == -1)
6280     {
6281       errmsg ("missing enable|disable");
6282       return -99;
6283     }
6284
6285   M (WANT_INTERFACE_EVENTS, mp);
6286   mp->enable_disable = enable;
6287
6288   vam->interface_event_display = enable;
6289
6290   S (mp);
6291   W (ret);
6292   return ret;
6293 }
6294
6295
6296 /* Note: non-static, called once to set up the initial intfc table */
6297 int
6298 api_sw_interface_dump (vat_main_t * vam)
6299 {
6300   vl_api_sw_interface_dump_t *mp;
6301   vl_api_control_ping_t *mp_ping;
6302   hash_pair_t *p;
6303   name_sort_t *nses = 0, *ns;
6304   sw_interface_subif_t *sub = NULL;
6305   int ret;
6306
6307   /* Toss the old name table */
6308   /* *INDENT-OFF* */
6309   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6310   ({
6311     vec_add2 (nses, ns, 1);
6312     ns->name = (u8 *)(p->key);
6313     ns->value = (u32) p->value[0];
6314   }));
6315   /* *INDENT-ON* */
6316
6317   hash_free (vam->sw_if_index_by_interface_name);
6318
6319   vec_foreach (ns, nses) vec_free (ns->name);
6320
6321   vec_free (nses);
6322
6323   vec_foreach (sub, vam->sw_if_subif_table)
6324   {
6325     vec_free (sub->interface_name);
6326   }
6327   vec_free (vam->sw_if_subif_table);
6328
6329   /* recreate the interface name hash table */
6330   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6331
6332   /* Get list of ethernets */
6333   M (SW_INTERFACE_DUMP, mp);
6334   mp->name_filter_valid = 1;
6335   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6336   S (mp);
6337
6338   /* and local / loopback interfaces */
6339   M (SW_INTERFACE_DUMP, mp);
6340   mp->name_filter_valid = 1;
6341   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6342   S (mp);
6343
6344   /* and packet-generator interfaces */
6345   M (SW_INTERFACE_DUMP, mp);
6346   mp->name_filter_valid = 1;
6347   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6348   S (mp);
6349
6350   /* and vxlan-gpe tunnel interfaces */
6351   M (SW_INTERFACE_DUMP, mp);
6352   mp->name_filter_valid = 1;
6353   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6354            sizeof (mp->name_filter) - 1);
6355   S (mp);
6356
6357   /* and vxlan tunnel interfaces */
6358   M (SW_INTERFACE_DUMP, mp);
6359   mp->name_filter_valid = 1;
6360   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6361   S (mp);
6362
6363   /* and geneve tunnel interfaces */
6364   M (SW_INTERFACE_DUMP, mp);
6365   mp->name_filter_valid = 1;
6366   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6367   S (mp);
6368
6369   /* and host (af_packet) interfaces */
6370   M (SW_INTERFACE_DUMP, mp);
6371   mp->name_filter_valid = 1;
6372   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6373   S (mp);
6374
6375   /* and l2tpv3 tunnel interfaces */
6376   M (SW_INTERFACE_DUMP, mp);
6377   mp->name_filter_valid = 1;
6378   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6379            sizeof (mp->name_filter) - 1);
6380   S (mp);
6381
6382   /* and GRE tunnel interfaces */
6383   M (SW_INTERFACE_DUMP, mp);
6384   mp->name_filter_valid = 1;
6385   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6386   S (mp);
6387
6388   /* and LISP-GPE interfaces */
6389   M (SW_INTERFACE_DUMP, mp);
6390   mp->name_filter_valid = 1;
6391   strncpy ((char *) mp->name_filter, "lisp_gpe",
6392            sizeof (mp->name_filter) - 1);
6393   S (mp);
6394
6395   /* and IPSEC tunnel interfaces */
6396   M (SW_INTERFACE_DUMP, mp);
6397   mp->name_filter_valid = 1;
6398   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6399   S (mp);
6400
6401   /* Use a control ping for synchronization */
6402   MPING (CONTROL_PING, mp_ping);
6403   S (mp_ping);
6404
6405   W (ret);
6406   return ret;
6407 }
6408
6409 static int
6410 api_sw_interface_set_flags (vat_main_t * vam)
6411 {
6412   unformat_input_t *i = vam->input;
6413   vl_api_sw_interface_set_flags_t *mp;
6414   u32 sw_if_index;
6415   u8 sw_if_index_set = 0;
6416   u8 admin_up = 0;
6417   int ret;
6418
6419   /* Parse args required to build the message */
6420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6421     {
6422       if (unformat (i, "admin-up"))
6423         admin_up = 1;
6424       else if (unformat (i, "admin-down"))
6425         admin_up = 0;
6426       else
6427         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6428         sw_if_index_set = 1;
6429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6430         sw_if_index_set = 1;
6431       else
6432         break;
6433     }
6434
6435   if (sw_if_index_set == 0)
6436     {
6437       errmsg ("missing interface name or sw_if_index");
6438       return -99;
6439     }
6440
6441   /* Construct the API message */
6442   M (SW_INTERFACE_SET_FLAGS, mp);
6443   mp->sw_if_index = ntohl (sw_if_index);
6444   mp->admin_up_down = admin_up;
6445
6446   /* send it... */
6447   S (mp);
6448
6449   /* Wait for a reply, return the good/bad news... */
6450   W (ret);
6451   return ret;
6452 }
6453
6454 static int
6455 api_sw_interface_set_rx_mode (vat_main_t * vam)
6456 {
6457   unformat_input_t *i = vam->input;
6458   vl_api_sw_interface_set_rx_mode_t *mp;
6459   u32 sw_if_index;
6460   u8 sw_if_index_set = 0;
6461   int ret;
6462   u8 queue_id_valid = 0;
6463   u32 queue_id;
6464   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6465
6466   /* Parse args required to build the message */
6467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6468     {
6469       if (unformat (i, "queue %d", &queue_id))
6470         queue_id_valid = 1;
6471       else if (unformat (i, "polling"))
6472         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6473       else if (unformat (i, "interrupt"))
6474         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6475       else if (unformat (i, "adaptive"))
6476         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6477       else
6478         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6479         sw_if_index_set = 1;
6480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6481         sw_if_index_set = 1;
6482       else
6483         break;
6484     }
6485
6486   if (sw_if_index_set == 0)
6487     {
6488       errmsg ("missing interface name or sw_if_index");
6489       return -99;
6490     }
6491   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6492     {
6493       errmsg ("missing rx-mode");
6494       return -99;
6495     }
6496
6497   /* Construct the API message */
6498   M (SW_INTERFACE_SET_RX_MODE, mp);
6499   mp->sw_if_index = ntohl (sw_if_index);
6500   mp->mode = mode;
6501   mp->queue_id_valid = queue_id_valid;
6502   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6503
6504   /* send it... */
6505   S (mp);
6506
6507   /* Wait for a reply, return the good/bad news... */
6508   W (ret);
6509   return ret;
6510 }
6511
6512 static int
6513 api_sw_interface_clear_stats (vat_main_t * vam)
6514 {
6515   unformat_input_t *i = vam->input;
6516   vl_api_sw_interface_clear_stats_t *mp;
6517   u32 sw_if_index;
6518   u8 sw_if_index_set = 0;
6519   int ret;
6520
6521   /* Parse args required to build the message */
6522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6523     {
6524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6525         sw_if_index_set = 1;
6526       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6527         sw_if_index_set = 1;
6528       else
6529         break;
6530     }
6531
6532   /* Construct the API message */
6533   M (SW_INTERFACE_CLEAR_STATS, mp);
6534
6535   if (sw_if_index_set == 1)
6536     mp->sw_if_index = ntohl (sw_if_index);
6537   else
6538     mp->sw_if_index = ~0;
6539
6540   /* send it... */
6541   S (mp);
6542
6543   /* Wait for a reply, return the good/bad news... */
6544   W (ret);
6545   return ret;
6546 }
6547
6548 static int
6549 api_sw_interface_add_del_address (vat_main_t * vam)
6550 {
6551   unformat_input_t *i = vam->input;
6552   vl_api_sw_interface_add_del_address_t *mp;
6553   u32 sw_if_index;
6554   u8 sw_if_index_set = 0;
6555   u8 is_add = 1, del_all = 0;
6556   u32 address_length = 0;
6557   u8 v4_address_set = 0;
6558   u8 v6_address_set = 0;
6559   ip4_address_t v4address;
6560   ip6_address_t v6address;
6561   int ret;
6562
6563   /* Parse args required to build the message */
6564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6565     {
6566       if (unformat (i, "del-all"))
6567         del_all = 1;
6568       else if (unformat (i, "del"))
6569         is_add = 0;
6570       else
6571         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6572         sw_if_index_set = 1;
6573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6574         sw_if_index_set = 1;
6575       else if (unformat (i, "%U/%d",
6576                          unformat_ip4_address, &v4address, &address_length))
6577         v4_address_set = 1;
6578       else if (unformat (i, "%U/%d",
6579                          unformat_ip6_address, &v6address, &address_length))
6580         v6_address_set = 1;
6581       else
6582         break;
6583     }
6584
6585   if (sw_if_index_set == 0)
6586     {
6587       errmsg ("missing interface name or sw_if_index");
6588       return -99;
6589     }
6590   if (v4_address_set && v6_address_set)
6591     {
6592       errmsg ("both v4 and v6 addresses set");
6593       return -99;
6594     }
6595   if (!v4_address_set && !v6_address_set && !del_all)
6596     {
6597       errmsg ("no addresses set");
6598       return -99;
6599     }
6600
6601   /* Construct the API message */
6602   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6603
6604   mp->sw_if_index = ntohl (sw_if_index);
6605   mp->is_add = is_add;
6606   mp->del_all = del_all;
6607   if (v6_address_set)
6608     {
6609       mp->is_ipv6 = 1;
6610       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6611     }
6612   else
6613     {
6614       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6615     }
6616   mp->address_length = address_length;
6617
6618   /* send it... */
6619   S (mp);
6620
6621   /* Wait for a reply, return good/bad news  */
6622   W (ret);
6623   return ret;
6624 }
6625
6626 static int
6627 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6628 {
6629   unformat_input_t *i = vam->input;
6630   vl_api_sw_interface_set_mpls_enable_t *mp;
6631   u32 sw_if_index;
6632   u8 sw_if_index_set = 0;
6633   u8 enable = 1;
6634   int ret;
6635
6636   /* Parse args required to build the message */
6637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6638     {
6639       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6640         sw_if_index_set = 1;
6641       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6642         sw_if_index_set = 1;
6643       else if (unformat (i, "disable"))
6644         enable = 0;
6645       else if (unformat (i, "dis"))
6646         enable = 0;
6647       else
6648         break;
6649     }
6650
6651   if (sw_if_index_set == 0)
6652     {
6653       errmsg ("missing interface name or sw_if_index");
6654       return -99;
6655     }
6656
6657   /* Construct the API message */
6658   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6659
6660   mp->sw_if_index = ntohl (sw_if_index);
6661   mp->enable = enable;
6662
6663   /* send it... */
6664   S (mp);
6665
6666   /* Wait for a reply... */
6667   W (ret);
6668   return ret;
6669 }
6670
6671 static int
6672 api_sw_interface_set_table (vat_main_t * vam)
6673 {
6674   unformat_input_t *i = vam->input;
6675   vl_api_sw_interface_set_table_t *mp;
6676   u32 sw_if_index, vrf_id = 0;
6677   u8 sw_if_index_set = 0;
6678   u8 is_ipv6 = 0;
6679   int ret;
6680
6681   /* Parse args required to build the message */
6682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6683     {
6684       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6685         sw_if_index_set = 1;
6686       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6687         sw_if_index_set = 1;
6688       else if (unformat (i, "vrf %d", &vrf_id))
6689         ;
6690       else if (unformat (i, "ipv6"))
6691         is_ipv6 = 1;
6692       else
6693         break;
6694     }
6695
6696   if (sw_if_index_set == 0)
6697     {
6698       errmsg ("missing interface name or sw_if_index");
6699       return -99;
6700     }
6701
6702   /* Construct the API message */
6703   M (SW_INTERFACE_SET_TABLE, mp);
6704
6705   mp->sw_if_index = ntohl (sw_if_index);
6706   mp->is_ipv6 = is_ipv6;
6707   mp->vrf_id = ntohl (vrf_id);
6708
6709   /* send it... */
6710   S (mp);
6711
6712   /* Wait for a reply... */
6713   W (ret);
6714   return ret;
6715 }
6716
6717 static void vl_api_sw_interface_get_table_reply_t_handler
6718   (vl_api_sw_interface_get_table_reply_t * mp)
6719 {
6720   vat_main_t *vam = &vat_main;
6721
6722   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6723
6724   vam->retval = ntohl (mp->retval);
6725   vam->result_ready = 1;
6726
6727 }
6728
6729 static void vl_api_sw_interface_get_table_reply_t_handler_json
6730   (vl_api_sw_interface_get_table_reply_t * mp)
6731 {
6732   vat_main_t *vam = &vat_main;
6733   vat_json_node_t node;
6734
6735   vat_json_init_object (&node);
6736   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6737   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6738
6739   vat_json_print (vam->ofp, &node);
6740   vat_json_free (&node);
6741
6742   vam->retval = ntohl (mp->retval);
6743   vam->result_ready = 1;
6744 }
6745
6746 static int
6747 api_sw_interface_get_table (vat_main_t * vam)
6748 {
6749   unformat_input_t *i = vam->input;
6750   vl_api_sw_interface_get_table_t *mp;
6751   u32 sw_if_index;
6752   u8 sw_if_index_set = 0;
6753   u8 is_ipv6 = 0;
6754   int ret;
6755
6756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757     {
6758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6759         sw_if_index_set = 1;
6760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6761         sw_if_index_set = 1;
6762       else if (unformat (i, "ipv6"))
6763         is_ipv6 = 1;
6764       else
6765         break;
6766     }
6767
6768   if (sw_if_index_set == 0)
6769     {
6770       errmsg ("missing interface name or sw_if_index");
6771       return -99;
6772     }
6773
6774   M (SW_INTERFACE_GET_TABLE, mp);
6775   mp->sw_if_index = htonl (sw_if_index);
6776   mp->is_ipv6 = is_ipv6;
6777
6778   S (mp);
6779   W (ret);
6780   return ret;
6781 }
6782
6783 static int
6784 api_sw_interface_set_vpath (vat_main_t * vam)
6785 {
6786   unformat_input_t *i = vam->input;
6787   vl_api_sw_interface_set_vpath_t *mp;
6788   u32 sw_if_index = 0;
6789   u8 sw_if_index_set = 0;
6790   u8 is_enable = 0;
6791   int ret;
6792
6793   /* Parse args required to build the message */
6794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6795     {
6796       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6797         sw_if_index_set = 1;
6798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6799         sw_if_index_set = 1;
6800       else if (unformat (i, "enable"))
6801         is_enable = 1;
6802       else if (unformat (i, "disable"))
6803         is_enable = 0;
6804       else
6805         break;
6806     }
6807
6808   if (sw_if_index_set == 0)
6809     {
6810       errmsg ("missing interface name or sw_if_index");
6811       return -99;
6812     }
6813
6814   /* Construct the API message */
6815   M (SW_INTERFACE_SET_VPATH, mp);
6816
6817   mp->sw_if_index = ntohl (sw_if_index);
6818   mp->enable = is_enable;
6819
6820   /* send it... */
6821   S (mp);
6822
6823   /* Wait for a reply... */
6824   W (ret);
6825   return ret;
6826 }
6827
6828 static int
6829 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6830 {
6831   unformat_input_t *i = vam->input;
6832   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6833   u32 sw_if_index = 0;
6834   u8 sw_if_index_set = 0;
6835   u8 is_enable = 1;
6836   u8 is_ipv6 = 0;
6837   int ret;
6838
6839   /* Parse args required to build the message */
6840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6841     {
6842       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6843         sw_if_index_set = 1;
6844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6845         sw_if_index_set = 1;
6846       else if (unformat (i, "enable"))
6847         is_enable = 1;
6848       else if (unformat (i, "disable"))
6849         is_enable = 0;
6850       else if (unformat (i, "ip4"))
6851         is_ipv6 = 0;
6852       else if (unformat (i, "ip6"))
6853         is_ipv6 = 1;
6854       else
6855         break;
6856     }
6857
6858   if (sw_if_index_set == 0)
6859     {
6860       errmsg ("missing interface name or sw_if_index");
6861       return -99;
6862     }
6863
6864   /* Construct the API message */
6865   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6866
6867   mp->sw_if_index = ntohl (sw_if_index);
6868   mp->enable = is_enable;
6869   mp->is_ipv6 = is_ipv6;
6870
6871   /* send it... */
6872   S (mp);
6873
6874   /* Wait for a reply... */
6875   W (ret);
6876   return ret;
6877 }
6878
6879 static int
6880 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6881 {
6882   unformat_input_t *i = vam->input;
6883   vl_api_sw_interface_set_geneve_bypass_t *mp;
6884   u32 sw_if_index = 0;
6885   u8 sw_if_index_set = 0;
6886   u8 is_enable = 1;
6887   u8 is_ipv6 = 0;
6888   int ret;
6889
6890   /* Parse args required to build the message */
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6894         sw_if_index_set = 1;
6895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6896         sw_if_index_set = 1;
6897       else if (unformat (i, "enable"))
6898         is_enable = 1;
6899       else if (unformat (i, "disable"))
6900         is_enable = 0;
6901       else if (unformat (i, "ip4"))
6902         is_ipv6 = 0;
6903       else if (unformat (i, "ip6"))
6904         is_ipv6 = 1;
6905       else
6906         break;
6907     }
6908
6909   if (sw_if_index_set == 0)
6910     {
6911       errmsg ("missing interface name or sw_if_index");
6912       return -99;
6913     }
6914
6915   /* Construct the API message */
6916   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6917
6918   mp->sw_if_index = ntohl (sw_if_index);
6919   mp->enable = is_enable;
6920   mp->is_ipv6 = is_ipv6;
6921
6922   /* send it... */
6923   S (mp);
6924
6925   /* Wait for a reply... */
6926   W (ret);
6927   return ret;
6928 }
6929
6930 static int
6931 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6932 {
6933   unformat_input_t *i = vam->input;
6934   vl_api_sw_interface_set_l2_xconnect_t *mp;
6935   u32 rx_sw_if_index;
6936   u8 rx_sw_if_index_set = 0;
6937   u32 tx_sw_if_index;
6938   u8 tx_sw_if_index_set = 0;
6939   u8 enable = 1;
6940   int ret;
6941
6942   /* Parse args required to build the message */
6943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6944     {
6945       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6946         rx_sw_if_index_set = 1;
6947       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6948         tx_sw_if_index_set = 1;
6949       else if (unformat (i, "rx"))
6950         {
6951           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6952             {
6953               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6954                             &rx_sw_if_index))
6955                 rx_sw_if_index_set = 1;
6956             }
6957           else
6958             break;
6959         }
6960       else if (unformat (i, "tx"))
6961         {
6962           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6963             {
6964               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6965                             &tx_sw_if_index))
6966                 tx_sw_if_index_set = 1;
6967             }
6968           else
6969             break;
6970         }
6971       else if (unformat (i, "enable"))
6972         enable = 1;
6973       else if (unformat (i, "disable"))
6974         enable = 0;
6975       else
6976         break;
6977     }
6978
6979   if (rx_sw_if_index_set == 0)
6980     {
6981       errmsg ("missing rx interface name or rx_sw_if_index");
6982       return -99;
6983     }
6984
6985   if (enable && (tx_sw_if_index_set == 0))
6986     {
6987       errmsg ("missing tx interface name or tx_sw_if_index");
6988       return -99;
6989     }
6990
6991   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6992
6993   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6994   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6995   mp->enable = enable;
6996
6997   S (mp);
6998   W (ret);
6999   return ret;
7000 }
7001
7002 static int
7003 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7004 {
7005   unformat_input_t *i = vam->input;
7006   vl_api_sw_interface_set_l2_bridge_t *mp;
7007   u32 rx_sw_if_index;
7008   u8 rx_sw_if_index_set = 0;
7009   u32 bd_id;
7010   u8 bd_id_set = 0;
7011   u8 bvi = 0;
7012   u32 shg = 0;
7013   u8 enable = 1;
7014   int ret;
7015
7016   /* Parse args required to build the message */
7017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7018     {
7019       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7020         rx_sw_if_index_set = 1;
7021       else if (unformat (i, "bd_id %d", &bd_id))
7022         bd_id_set = 1;
7023       else
7024         if (unformat
7025             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7026         rx_sw_if_index_set = 1;
7027       else if (unformat (i, "shg %d", &shg))
7028         ;
7029       else if (unformat (i, "bvi"))
7030         bvi = 1;
7031       else if (unformat (i, "enable"))
7032         enable = 1;
7033       else if (unformat (i, "disable"))
7034         enable = 0;
7035       else
7036         break;
7037     }
7038
7039   if (rx_sw_if_index_set == 0)
7040     {
7041       errmsg ("missing rx interface name or sw_if_index");
7042       return -99;
7043     }
7044
7045   if (enable && (bd_id_set == 0))
7046     {
7047       errmsg ("missing bridge domain");
7048       return -99;
7049     }
7050
7051   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7052
7053   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7054   mp->bd_id = ntohl (bd_id);
7055   mp->shg = (u8) shg;
7056   mp->bvi = bvi;
7057   mp->enable = enable;
7058
7059   S (mp);
7060   W (ret);
7061   return ret;
7062 }
7063
7064 static int
7065 api_bridge_domain_dump (vat_main_t * vam)
7066 {
7067   unformat_input_t *i = vam->input;
7068   vl_api_bridge_domain_dump_t *mp;
7069   vl_api_control_ping_t *mp_ping;
7070   u32 bd_id = ~0;
7071   int ret;
7072
7073   /* Parse args required to build the message */
7074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7075     {
7076       if (unformat (i, "bd_id %d", &bd_id))
7077         ;
7078       else
7079         break;
7080     }
7081
7082   M (BRIDGE_DOMAIN_DUMP, mp);
7083   mp->bd_id = ntohl (bd_id);
7084   S (mp);
7085
7086   /* Use a control ping for synchronization */
7087   MPING (CONTROL_PING, mp_ping);
7088   S (mp_ping);
7089
7090   W (ret);
7091   return ret;
7092 }
7093
7094 static int
7095 api_bridge_domain_add_del (vat_main_t * vam)
7096 {
7097   unformat_input_t *i = vam->input;
7098   vl_api_bridge_domain_add_del_t *mp;
7099   u32 bd_id = ~0;
7100   u8 is_add = 1;
7101   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7102   u8 *bd_tag = NULL;
7103   u32 mac_age = 0;
7104   int ret;
7105
7106   /* Parse args required to build the message */
7107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7108     {
7109       if (unformat (i, "bd_id %d", &bd_id))
7110         ;
7111       else if (unformat (i, "flood %d", &flood))
7112         ;
7113       else if (unformat (i, "uu-flood %d", &uu_flood))
7114         ;
7115       else if (unformat (i, "forward %d", &forward))
7116         ;
7117       else if (unformat (i, "learn %d", &learn))
7118         ;
7119       else if (unformat (i, "arp-term %d", &arp_term))
7120         ;
7121       else if (unformat (i, "mac-age %d", &mac_age))
7122         ;
7123       else if (unformat (i, "bd-tag %s", &bd_tag))
7124         ;
7125       else if (unformat (i, "del"))
7126         {
7127           is_add = 0;
7128           flood = uu_flood = forward = learn = 0;
7129         }
7130       else
7131         break;
7132     }
7133
7134   if (bd_id == ~0)
7135     {
7136       errmsg ("missing bridge domain");
7137       ret = -99;
7138       goto done;
7139     }
7140
7141   if (mac_age > 255)
7142     {
7143       errmsg ("mac age must be less than 256 ");
7144       ret = -99;
7145       goto done;
7146     }
7147
7148   if ((bd_tag) && (vec_len (bd_tag) > 63))
7149     {
7150       errmsg ("bd-tag cannot be longer than 63");
7151       ret = -99;
7152       goto done;
7153     }
7154
7155   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7156
7157   mp->bd_id = ntohl (bd_id);
7158   mp->flood = flood;
7159   mp->uu_flood = uu_flood;
7160   mp->forward = forward;
7161   mp->learn = learn;
7162   mp->arp_term = arp_term;
7163   mp->is_add = is_add;
7164   mp->mac_age = (u8) mac_age;
7165   if (bd_tag)
7166     {
7167       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7168       mp->bd_tag[vec_len (bd_tag)] = 0;
7169     }
7170   S (mp);
7171   W (ret);
7172
7173 done:
7174   vec_free (bd_tag);
7175   return ret;
7176 }
7177
7178 static int
7179 api_l2fib_flush_bd (vat_main_t * vam)
7180 {
7181   unformat_input_t *i = vam->input;
7182   vl_api_l2fib_flush_bd_t *mp;
7183   u32 bd_id = ~0;
7184   int ret;
7185
7186   /* Parse args required to build the message */
7187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7188     {
7189       if (unformat (i, "bd_id %d", &bd_id));
7190       else
7191         break;
7192     }
7193
7194   if (bd_id == ~0)
7195     {
7196       errmsg ("missing bridge domain");
7197       return -99;
7198     }
7199
7200   M (L2FIB_FLUSH_BD, mp);
7201
7202   mp->bd_id = htonl (bd_id);
7203
7204   S (mp);
7205   W (ret);
7206   return ret;
7207 }
7208
7209 static int
7210 api_l2fib_flush_int (vat_main_t * vam)
7211 {
7212   unformat_input_t *i = vam->input;
7213   vl_api_l2fib_flush_int_t *mp;
7214   u32 sw_if_index = ~0;
7215   int ret;
7216
7217   /* Parse args required to build the message */
7218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7219     {
7220       if (unformat (i, "sw_if_index %d", &sw_if_index));
7221       else
7222         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7223       else
7224         break;
7225     }
7226
7227   if (sw_if_index == ~0)
7228     {
7229       errmsg ("missing interface name or sw_if_index");
7230       return -99;
7231     }
7232
7233   M (L2FIB_FLUSH_INT, mp);
7234
7235   mp->sw_if_index = ntohl (sw_if_index);
7236
7237   S (mp);
7238   W (ret);
7239   return ret;
7240 }
7241
7242 static int
7243 api_l2fib_add_del (vat_main_t * vam)
7244 {
7245   unformat_input_t *i = vam->input;
7246   vl_api_l2fib_add_del_t *mp;
7247   f64 timeout;
7248   u8 mac[6] = { 0 };
7249   u8 mac_set = 0;
7250   u32 bd_id;
7251   u8 bd_id_set = 0;
7252   u32 sw_if_index = ~0;
7253   u8 sw_if_index_set = 0;
7254   u8 is_add = 1;
7255   u8 static_mac = 0;
7256   u8 filter_mac = 0;
7257   u8 bvi_mac = 0;
7258   int count = 1;
7259   f64 before = 0;
7260   int j;
7261
7262   /* Parse args required to build the message */
7263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7264     {
7265       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7266         mac_set = 1;
7267       else if (unformat (i, "bd_id %d", &bd_id))
7268         bd_id_set = 1;
7269       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7270         sw_if_index_set = 1;
7271       else if (unformat (i, "sw_if"))
7272         {
7273           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7274             {
7275               if (unformat
7276                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7277                 sw_if_index_set = 1;
7278             }
7279           else
7280             break;
7281         }
7282       else if (unformat (i, "static"))
7283         static_mac = 1;
7284       else if (unformat (i, "filter"))
7285         {
7286           filter_mac = 1;
7287           static_mac = 1;
7288         }
7289       else if (unformat (i, "bvi"))
7290         {
7291           bvi_mac = 1;
7292           static_mac = 1;
7293         }
7294       else if (unformat (i, "del"))
7295         is_add = 0;
7296       else if (unformat (i, "count %d", &count))
7297         ;
7298       else
7299         break;
7300     }
7301
7302   if (mac_set == 0)
7303     {
7304       errmsg ("missing mac address");
7305       return -99;
7306     }
7307
7308   if (bd_id_set == 0)
7309     {
7310       errmsg ("missing bridge domain");
7311       return -99;
7312     }
7313
7314   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7315     {
7316       errmsg ("missing interface name or sw_if_index");
7317       return -99;
7318     }
7319
7320   if (count > 1)
7321     {
7322       /* Turn on async mode */
7323       vam->async_mode = 1;
7324       vam->async_errors = 0;
7325       before = vat_time_now (vam);
7326     }
7327
7328   for (j = 0; j < count; j++)
7329     {
7330       M (L2FIB_ADD_DEL, mp);
7331
7332       clib_memcpy (mp->mac, mac, 6);
7333       mp->bd_id = ntohl (bd_id);
7334       mp->is_add = is_add;
7335
7336       if (is_add)
7337         {
7338           mp->sw_if_index = ntohl (sw_if_index);
7339           mp->static_mac = static_mac;
7340           mp->filter_mac = filter_mac;
7341           mp->bvi_mac = bvi_mac;
7342         }
7343       increment_mac_address (mac);
7344       /* send it... */
7345       S (mp);
7346     }
7347
7348   if (count > 1)
7349     {
7350       vl_api_control_ping_t *mp_ping;
7351       f64 after;
7352
7353       /* Shut off async mode */
7354       vam->async_mode = 0;
7355
7356       MPING (CONTROL_PING, mp_ping);
7357       S (mp_ping);
7358
7359       timeout = vat_time_now (vam) + 1.0;
7360       while (vat_time_now (vam) < timeout)
7361         if (vam->result_ready == 1)
7362           goto out;
7363       vam->retval = -99;
7364
7365     out:
7366       if (vam->retval == -99)
7367         errmsg ("timeout");
7368
7369       if (vam->async_errors > 0)
7370         {
7371           errmsg ("%d asynchronous errors", vam->async_errors);
7372           vam->retval = -98;
7373         }
7374       vam->async_errors = 0;
7375       after = vat_time_now (vam);
7376
7377       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7378              count, after - before, count / (after - before));
7379     }
7380   else
7381     {
7382       int ret;
7383
7384       /* Wait for a reply... */
7385       W (ret);
7386       return ret;
7387     }
7388   /* Return the good/bad news */
7389   return (vam->retval);
7390 }
7391
7392 static int
7393 api_bridge_domain_set_mac_age (vat_main_t * vam)
7394 {
7395   unformat_input_t *i = vam->input;
7396   vl_api_bridge_domain_set_mac_age_t *mp;
7397   u32 bd_id = ~0;
7398   u32 mac_age = 0;
7399   int ret;
7400
7401   /* Parse args required to build the message */
7402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7403     {
7404       if (unformat (i, "bd_id %d", &bd_id));
7405       else if (unformat (i, "mac-age %d", &mac_age));
7406       else
7407         break;
7408     }
7409
7410   if (bd_id == ~0)
7411     {
7412       errmsg ("missing bridge domain");
7413       return -99;
7414     }
7415
7416   if (mac_age > 255)
7417     {
7418       errmsg ("mac age must be less than 256 ");
7419       return -99;
7420     }
7421
7422   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7423
7424   mp->bd_id = htonl (bd_id);
7425   mp->mac_age = (u8) mac_age;
7426
7427   S (mp);
7428   W (ret);
7429   return ret;
7430 }
7431
7432 static int
7433 api_l2_flags (vat_main_t * vam)
7434 {
7435   unformat_input_t *i = vam->input;
7436   vl_api_l2_flags_t *mp;
7437   u32 sw_if_index;
7438   u32 flags = 0;
7439   u8 sw_if_index_set = 0;
7440   u8 is_set = 0;
7441   int ret;
7442
7443   /* Parse args required to build the message */
7444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7445     {
7446       if (unformat (i, "sw_if_index %d", &sw_if_index))
7447         sw_if_index_set = 1;
7448       else if (unformat (i, "sw_if"))
7449         {
7450           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7451             {
7452               if (unformat
7453                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7454                 sw_if_index_set = 1;
7455             }
7456           else
7457             break;
7458         }
7459       else if (unformat (i, "learn"))
7460         flags |= L2_LEARN;
7461       else if (unformat (i, "forward"))
7462         flags |= L2_FWD;
7463       else if (unformat (i, "flood"))
7464         flags |= L2_FLOOD;
7465       else if (unformat (i, "uu-flood"))
7466         flags |= L2_UU_FLOOD;
7467       else if (unformat (i, "arp-term"))
7468         flags |= L2_ARP_TERM;
7469       else if (unformat (i, "off"))
7470         is_set = 0;
7471       else if (unformat (i, "disable"))
7472         is_set = 0;
7473       else
7474         break;
7475     }
7476
7477   if (sw_if_index_set == 0)
7478     {
7479       errmsg ("missing interface name or sw_if_index");
7480       return -99;
7481     }
7482
7483   M (L2_FLAGS, mp);
7484
7485   mp->sw_if_index = ntohl (sw_if_index);
7486   mp->feature_bitmap = ntohl (flags);
7487   mp->is_set = is_set;
7488
7489   S (mp);
7490   W (ret);
7491   return ret;
7492 }
7493
7494 static int
7495 api_bridge_flags (vat_main_t * vam)
7496 {
7497   unformat_input_t *i = vam->input;
7498   vl_api_bridge_flags_t *mp;
7499   u32 bd_id;
7500   u8 bd_id_set = 0;
7501   u8 is_set = 1;
7502   u32 flags = 0;
7503   int ret;
7504
7505   /* Parse args required to build the message */
7506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7507     {
7508       if (unformat (i, "bd_id %d", &bd_id))
7509         bd_id_set = 1;
7510       else if (unformat (i, "learn"))
7511         flags |= L2_LEARN;
7512       else if (unformat (i, "forward"))
7513         flags |= L2_FWD;
7514       else if (unformat (i, "flood"))
7515         flags |= L2_FLOOD;
7516       else if (unformat (i, "uu-flood"))
7517         flags |= L2_UU_FLOOD;
7518       else if (unformat (i, "arp-term"))
7519         flags |= L2_ARP_TERM;
7520       else if (unformat (i, "off"))
7521         is_set = 0;
7522       else if (unformat (i, "disable"))
7523         is_set = 0;
7524       else
7525         break;
7526     }
7527
7528   if (bd_id_set == 0)
7529     {
7530       errmsg ("missing bridge domain");
7531       return -99;
7532     }
7533
7534   M (BRIDGE_FLAGS, mp);
7535
7536   mp->bd_id = ntohl (bd_id);
7537   mp->feature_bitmap = ntohl (flags);
7538   mp->is_set = is_set;
7539
7540   S (mp);
7541   W (ret);
7542   return ret;
7543 }
7544
7545 static int
7546 api_bd_ip_mac_add_del (vat_main_t * vam)
7547 {
7548   unformat_input_t *i = vam->input;
7549   vl_api_bd_ip_mac_add_del_t *mp;
7550   u32 bd_id;
7551   u8 is_ipv6 = 0;
7552   u8 is_add = 1;
7553   u8 bd_id_set = 0;
7554   u8 ip_set = 0;
7555   u8 mac_set = 0;
7556   ip4_address_t v4addr;
7557   ip6_address_t v6addr;
7558   u8 macaddr[6];
7559   int ret;
7560
7561
7562   /* Parse args required to build the message */
7563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7564     {
7565       if (unformat (i, "bd_id %d", &bd_id))
7566         {
7567           bd_id_set++;
7568         }
7569       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7570         {
7571           ip_set++;
7572         }
7573       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7574         {
7575           ip_set++;
7576           is_ipv6++;
7577         }
7578       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7579         {
7580           mac_set++;
7581         }
7582       else if (unformat (i, "del"))
7583         is_add = 0;
7584       else
7585         break;
7586     }
7587
7588   if (bd_id_set == 0)
7589     {
7590       errmsg ("missing bridge domain");
7591       return -99;
7592     }
7593   else if (ip_set == 0)
7594     {
7595       errmsg ("missing IP address");
7596       return -99;
7597     }
7598   else if (mac_set == 0)
7599     {
7600       errmsg ("missing MAC address");
7601       return -99;
7602     }
7603
7604   M (BD_IP_MAC_ADD_DEL, mp);
7605
7606   mp->bd_id = ntohl (bd_id);
7607   mp->is_ipv6 = is_ipv6;
7608   mp->is_add = is_add;
7609   if (is_ipv6)
7610     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7611   else
7612     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7613   clib_memcpy (mp->mac_address, macaddr, 6);
7614   S (mp);
7615   W (ret);
7616   return ret;
7617 }
7618
7619 static int
7620 api_tap_connect (vat_main_t * vam)
7621 {
7622   unformat_input_t *i = vam->input;
7623   vl_api_tap_connect_t *mp;
7624   u8 mac_address[6];
7625   u8 random_mac = 1;
7626   u8 name_set = 0;
7627   u8 *tap_name;
7628   u8 *tag = 0;
7629   ip4_address_t ip4_address;
7630   u32 ip4_mask_width;
7631   int ip4_address_set = 0;
7632   ip6_address_t ip6_address;
7633   u32 ip6_mask_width;
7634   int ip6_address_set = 0;
7635   int ret;
7636
7637   memset (mac_address, 0, sizeof (mac_address));
7638
7639   /* Parse args required to build the message */
7640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7641     {
7642       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7643         {
7644           random_mac = 0;
7645         }
7646       else if (unformat (i, "random-mac"))
7647         random_mac = 1;
7648       else if (unformat (i, "tapname %s", &tap_name))
7649         name_set = 1;
7650       else if (unformat (i, "tag %s", &tag))
7651         ;
7652       else if (unformat (i, "address %U/%d",
7653                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7654         ip4_address_set = 1;
7655       else if (unformat (i, "address %U/%d",
7656                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7657         ip6_address_set = 1;
7658       else
7659         break;
7660     }
7661
7662   if (name_set == 0)
7663     {
7664       errmsg ("missing tap name");
7665       return -99;
7666     }
7667   if (vec_len (tap_name) > 63)
7668     {
7669       errmsg ("tap name too long");
7670       return -99;
7671     }
7672   vec_add1 (tap_name, 0);
7673
7674   if (vec_len (tag) > 63)
7675     {
7676       errmsg ("tag too long");
7677       return -99;
7678     }
7679
7680   /* Construct the API message */
7681   M (TAP_CONNECT, mp);
7682
7683   mp->use_random_mac = random_mac;
7684   clib_memcpy (mp->mac_address, mac_address, 6);
7685   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7686   if (tag)
7687     clib_memcpy (mp->tag, tag, vec_len (tag));
7688
7689   if (ip4_address_set)
7690     {
7691       mp->ip4_address_set = 1;
7692       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7693       mp->ip4_mask_width = ip4_mask_width;
7694     }
7695   if (ip6_address_set)
7696     {
7697       mp->ip6_address_set = 1;
7698       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7699       mp->ip6_mask_width = ip6_mask_width;
7700     }
7701
7702   vec_free (tap_name);
7703   vec_free (tag);
7704
7705   /* send it... */
7706   S (mp);
7707
7708   /* Wait for a reply... */
7709   W (ret);
7710   return ret;
7711 }
7712
7713 static int
7714 api_tap_modify (vat_main_t * vam)
7715 {
7716   unformat_input_t *i = vam->input;
7717   vl_api_tap_modify_t *mp;
7718   u8 mac_address[6];
7719   u8 random_mac = 1;
7720   u8 name_set = 0;
7721   u8 *tap_name;
7722   u32 sw_if_index = ~0;
7723   u8 sw_if_index_set = 0;
7724   int ret;
7725
7726   memset (mac_address, 0, sizeof (mac_address));
7727
7728   /* Parse args required to build the message */
7729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7730     {
7731       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7732         sw_if_index_set = 1;
7733       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7734         sw_if_index_set = 1;
7735       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7736         {
7737           random_mac = 0;
7738         }
7739       else if (unformat (i, "random-mac"))
7740         random_mac = 1;
7741       else if (unformat (i, "tapname %s", &tap_name))
7742         name_set = 1;
7743       else
7744         break;
7745     }
7746
7747   if (sw_if_index_set == 0)
7748     {
7749       errmsg ("missing vpp interface name");
7750       return -99;
7751     }
7752   if (name_set == 0)
7753     {
7754       errmsg ("missing tap name");
7755       return -99;
7756     }
7757   if (vec_len (tap_name) > 63)
7758     {
7759       errmsg ("tap name too long");
7760     }
7761   vec_add1 (tap_name, 0);
7762
7763   /* Construct the API message */
7764   M (TAP_MODIFY, mp);
7765
7766   mp->use_random_mac = random_mac;
7767   mp->sw_if_index = ntohl (sw_if_index);
7768   clib_memcpy (mp->mac_address, mac_address, 6);
7769   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7770   vec_free (tap_name);
7771
7772   /* send it... */
7773   S (mp);
7774
7775   /* Wait for a reply... */
7776   W (ret);
7777   return ret;
7778 }
7779
7780 static int
7781 api_tap_delete (vat_main_t * vam)
7782 {
7783   unformat_input_t *i = vam->input;
7784   vl_api_tap_delete_t *mp;
7785   u32 sw_if_index = ~0;
7786   u8 sw_if_index_set = 0;
7787   int ret;
7788
7789   /* Parse args required to build the message */
7790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7791     {
7792       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7793         sw_if_index_set = 1;
7794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7795         sw_if_index_set = 1;
7796       else
7797         break;
7798     }
7799
7800   if (sw_if_index_set == 0)
7801     {
7802       errmsg ("missing vpp interface name");
7803       return -99;
7804     }
7805
7806   /* Construct the API message */
7807   M (TAP_DELETE, mp);
7808
7809   mp->sw_if_index = ntohl (sw_if_index);
7810
7811   /* send it... */
7812   S (mp);
7813
7814   /* Wait for a reply... */
7815   W (ret);
7816   return ret;
7817 }
7818
7819 static int
7820 api_tap_create_v2 (vat_main_t * vam)
7821 {
7822   unformat_input_t *i = vam->input;
7823   vl_api_tap_create_v2_t *mp;
7824   u8 mac_address[6];
7825   u8 random_mac = 1;
7826   u32 id = ~0;
7827   u8 *host_if_name = 0;
7828   u8 *host_ns = 0;
7829   u8 host_mac_addr[6];
7830   u8 host_mac_addr_set = 0;
7831   u8 *host_bridge = 0;
7832   ip4_address_t host_ip4_addr;
7833   u32 host_ip4_prefix_len = 0;
7834   ip6_address_t host_ip6_addr;
7835   u32 host_ip6_prefix_len = 0;
7836   int ret;
7837   int rx_ring_sz = 0, tx_ring_sz = 0;
7838
7839   memset (mac_address, 0, sizeof (mac_address));
7840
7841   /* Parse args required to build the message */
7842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7843     {
7844       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7845         {
7846           random_mac = 0;
7847         }
7848       else if (unformat (i, "id %s", &id))
7849         ;
7850       else if (unformat (i, "host-if-name %s", &host_if_name))
7851         ;
7852       else if (unformat (i, "host-ns %s", &host_ns))
7853         ;
7854       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7855                          host_mac_addr))
7856         host_mac_addr_set = 1;
7857       else if (unformat (i, "host-bridge %s", &host_bridge))
7858         ;
7859       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7860                          &host_ip4_addr, &host_ip4_prefix_len))
7861         ;
7862       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7863                          &host_ip6_addr, &host_ip6_prefix_len))
7864         ;
7865       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7866         ;
7867       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7868         ;
7869       else
7870         break;
7871     }
7872
7873   if (vec_len (host_if_name) > 63)
7874     {
7875       errmsg ("tap name too long. ");
7876       return -99;
7877     }
7878   if (vec_len (host_ns) > 63)
7879     {
7880       errmsg ("host name space too long. ");
7881       return -99;
7882     }
7883   if (vec_len (host_bridge) > 63)
7884     {
7885       errmsg ("host bridge name too long. ");
7886       return -99;
7887     }
7888   if (host_ip4_prefix_len > 32)
7889     {
7890       errmsg ("host ip4 prefix length not valid. ");
7891       return -99;
7892     }
7893   if (host_ip6_prefix_len > 128)
7894     {
7895       errmsg ("host ip6 prefix length not valid. ");
7896       return -99;
7897     }
7898   if (!is_pow2 (rx_ring_sz))
7899     {
7900       errmsg ("rx ring size must be power of 2. ");
7901       return -99;
7902     }
7903   if (rx_ring_sz > 32768)
7904     {
7905       errmsg ("rx ring size must be 32768 or lower. ");
7906       return -99;
7907     }
7908   if (!is_pow2 (tx_ring_sz))
7909     {
7910       errmsg ("tx ring size must be power of 2. ");
7911       return -99;
7912     }
7913   if (tx_ring_sz > 32768)
7914     {
7915       errmsg ("tx ring size must be 32768 or lower. ");
7916       return -99;
7917     }
7918
7919   /* Construct the API message */
7920   M (TAP_CREATE_V2, mp);
7921
7922   mp->use_random_mac = random_mac;
7923
7924   mp->id = id;
7925   mp->host_namespace_set = host_ns != 0;
7926   mp->host_bridge_set = host_bridge != 0;
7927   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7928   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7929   mp->rx_ring_sz = rx_ring_sz;
7930   mp->tx_ring_sz = tx_ring_sz;
7931
7932   if (random_mac)
7933     clib_memcpy (mp->mac_address, mac_address, 6);
7934   if (host_mac_addr_set)
7935     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7936   if (host_if_name)
7937     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7938   if (host_ns)
7939     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7940   if (host_bridge)
7941     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7942   if (host_ip4_prefix_len)
7943     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7944   if (host_ip4_prefix_len)
7945     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7946
7947
7948   vec_free (host_ns);
7949   vec_free (host_if_name);
7950   vec_free (host_bridge);
7951
7952   /* send it... */
7953   S (mp);
7954
7955   /* Wait for a reply... */
7956   W (ret);
7957   return ret;
7958 }
7959
7960 static int
7961 api_tap_delete_v2 (vat_main_t * vam)
7962 {
7963   unformat_input_t *i = vam->input;
7964   vl_api_tap_delete_v2_t *mp;
7965   u32 sw_if_index = ~0;
7966   u8 sw_if_index_set = 0;
7967   int ret;
7968
7969   /* Parse args required to build the message */
7970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7971     {
7972       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7973         sw_if_index_set = 1;
7974       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7975         sw_if_index_set = 1;
7976       else
7977         break;
7978     }
7979
7980   if (sw_if_index_set == 0)
7981     {
7982       errmsg ("missing vpp interface name. ");
7983       return -99;
7984     }
7985
7986   /* Construct the API message */
7987   M (TAP_DELETE_V2, mp);
7988
7989   mp->sw_if_index = ntohl (sw_if_index);
7990
7991   /* send it... */
7992   S (mp);
7993
7994   /* Wait for a reply... */
7995   W (ret);
7996   return ret;
7997 }
7998
7999 static int
8000 api_ip_table_add_del (vat_main_t * vam)
8001 {
8002   unformat_input_t *i = vam->input;
8003   vl_api_ip_table_add_del_t *mp;
8004   u32 table_id = ~0;
8005   u8 is_ipv6 = 0;
8006   u8 is_add = 1;
8007   int ret = 0;
8008
8009   /* Parse args required to build the message */
8010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8011     {
8012       if (unformat (i, "ipv6"))
8013         is_ipv6 = 1;
8014       else if (unformat (i, "del"))
8015         is_add = 0;
8016       else if (unformat (i, "add"))
8017         is_add = 1;
8018       else if (unformat (i, "table %d", &table_id))
8019         ;
8020       else
8021         {
8022           clib_warning ("parse error '%U'", format_unformat_error, i);
8023           return -99;
8024         }
8025     }
8026
8027   if (~0 == table_id)
8028     {
8029       errmsg ("missing table-ID");
8030       return -99;
8031     }
8032
8033   /* Construct the API message */
8034   M (IP_TABLE_ADD_DEL, mp);
8035
8036   mp->table_id = ntohl (table_id);
8037   mp->is_ipv6 = is_ipv6;
8038   mp->is_add = is_add;
8039
8040   /* send it... */
8041   S (mp);
8042
8043   /* Wait for a reply... */
8044   W (ret);
8045
8046   return ret;
8047 }
8048
8049 static int
8050 api_ip_add_del_route (vat_main_t * vam)
8051 {
8052   unformat_input_t *i = vam->input;
8053   vl_api_ip_add_del_route_t *mp;
8054   u32 sw_if_index = ~0, vrf_id = 0;
8055   u8 is_ipv6 = 0;
8056   u8 is_local = 0, is_drop = 0;
8057   u8 is_unreach = 0, is_prohibit = 0;
8058   u8 is_add = 1;
8059   u32 next_hop_weight = 1;
8060   u8 is_multipath = 0;
8061   u8 address_set = 0;
8062   u8 address_length_set = 0;
8063   u32 next_hop_table_id = 0;
8064   u32 resolve_attempts = 0;
8065   u32 dst_address_length = 0;
8066   u8 next_hop_set = 0;
8067   ip4_address_t v4_dst_address, v4_next_hop_address;
8068   ip6_address_t v6_dst_address, v6_next_hop_address;
8069   int count = 1;
8070   int j;
8071   f64 before = 0;
8072   u32 random_add_del = 0;
8073   u32 *random_vector = 0;
8074   uword *random_hash;
8075   u32 random_seed = 0xdeaddabe;
8076   u32 classify_table_index = ~0;
8077   u8 is_classify = 0;
8078   u8 resolve_host = 0, resolve_attached = 0;
8079   mpls_label_t *next_hop_out_label_stack = NULL;
8080   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8081   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8082
8083   /* Parse args required to build the message */
8084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8085     {
8086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8087         ;
8088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8089         ;
8090       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8091         {
8092           address_set = 1;
8093           is_ipv6 = 0;
8094         }
8095       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8096         {
8097           address_set = 1;
8098           is_ipv6 = 1;
8099         }
8100       else if (unformat (i, "/%d", &dst_address_length))
8101         {
8102           address_length_set = 1;
8103         }
8104
8105       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8106                                          &v4_next_hop_address))
8107         {
8108           next_hop_set = 1;
8109         }
8110       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8111                                          &v6_next_hop_address))
8112         {
8113           next_hop_set = 1;
8114         }
8115       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8116         ;
8117       else if (unformat (i, "weight %d", &next_hop_weight))
8118         ;
8119       else if (unformat (i, "drop"))
8120         {
8121           is_drop = 1;
8122         }
8123       else if (unformat (i, "null-send-unreach"))
8124         {
8125           is_unreach = 1;
8126         }
8127       else if (unformat (i, "null-send-prohibit"))
8128         {
8129           is_prohibit = 1;
8130         }
8131       else if (unformat (i, "local"))
8132         {
8133           is_local = 1;
8134         }
8135       else if (unformat (i, "classify %d", &classify_table_index))
8136         {
8137           is_classify = 1;
8138         }
8139       else if (unformat (i, "del"))
8140         is_add = 0;
8141       else if (unformat (i, "add"))
8142         is_add = 1;
8143       else if (unformat (i, "resolve-via-host"))
8144         resolve_host = 1;
8145       else if (unformat (i, "resolve-via-attached"))
8146         resolve_attached = 1;
8147       else if (unformat (i, "multipath"))
8148         is_multipath = 1;
8149       else if (unformat (i, "vrf %d", &vrf_id))
8150         ;
8151       else if (unformat (i, "count %d", &count))
8152         ;
8153       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8154         ;
8155       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8156         ;
8157       else if (unformat (i, "out-label %d", &next_hop_out_label))
8158         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8159       else if (unformat (i, "via-label %d", &next_hop_via_label))
8160         ;
8161       else if (unformat (i, "random"))
8162         random_add_del = 1;
8163       else if (unformat (i, "seed %d", &random_seed))
8164         ;
8165       else
8166         {
8167           clib_warning ("parse error '%U'", format_unformat_error, i);
8168           return -99;
8169         }
8170     }
8171
8172   if (!next_hop_set && !is_drop && !is_local &&
8173       !is_classify && !is_unreach && !is_prohibit &&
8174       MPLS_LABEL_INVALID == next_hop_via_label)
8175     {
8176       errmsg
8177         ("next hop / local / drop / unreach / prohibit / classify not set");
8178       return -99;
8179     }
8180
8181   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8182     {
8183       errmsg ("next hop and next-hop via label set");
8184       return -99;
8185     }
8186   if (address_set == 0)
8187     {
8188       errmsg ("missing addresses");
8189       return -99;
8190     }
8191
8192   if (address_length_set == 0)
8193     {
8194       errmsg ("missing address length");
8195       return -99;
8196     }
8197
8198   /* Generate a pile of unique, random routes */
8199   if (random_add_del)
8200     {
8201       u32 this_random_address;
8202       random_hash = hash_create (count, sizeof (uword));
8203
8204       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8205       for (j = 0; j <= count; j++)
8206         {
8207           do
8208             {
8209               this_random_address = random_u32 (&random_seed);
8210               this_random_address =
8211                 clib_host_to_net_u32 (this_random_address);
8212             }
8213           while (hash_get (random_hash, this_random_address));
8214           vec_add1 (random_vector, this_random_address);
8215           hash_set (random_hash, this_random_address, 1);
8216         }
8217       hash_free (random_hash);
8218       v4_dst_address.as_u32 = random_vector[0];
8219     }
8220
8221   if (count > 1)
8222     {
8223       /* Turn on async mode */
8224       vam->async_mode = 1;
8225       vam->async_errors = 0;
8226       before = vat_time_now (vam);
8227     }
8228
8229   for (j = 0; j < count; j++)
8230     {
8231       /* Construct the API message */
8232       M2 (IP_ADD_DEL_ROUTE, mp,
8233           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8234
8235       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8236       mp->table_id = ntohl (vrf_id);
8237
8238       mp->is_add = is_add;
8239       mp->is_drop = is_drop;
8240       mp->is_unreach = is_unreach;
8241       mp->is_prohibit = is_prohibit;
8242       mp->is_ipv6 = is_ipv6;
8243       mp->is_local = is_local;
8244       mp->is_classify = is_classify;
8245       mp->is_multipath = is_multipath;
8246       mp->is_resolve_host = resolve_host;
8247       mp->is_resolve_attached = resolve_attached;
8248       mp->next_hop_weight = next_hop_weight;
8249       mp->dst_address_length = dst_address_length;
8250       mp->next_hop_table_id = ntohl (next_hop_table_id);
8251       mp->classify_table_index = ntohl (classify_table_index);
8252       mp->next_hop_via_label = ntohl (next_hop_via_label);
8253       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8254       if (0 != mp->next_hop_n_out_labels)
8255         {
8256           memcpy (mp->next_hop_out_label_stack,
8257                   next_hop_out_label_stack,
8258                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8259           vec_free (next_hop_out_label_stack);
8260         }
8261
8262       if (is_ipv6)
8263         {
8264           clib_memcpy (mp->dst_address, &v6_dst_address,
8265                        sizeof (v6_dst_address));
8266           if (next_hop_set)
8267             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8268                          sizeof (v6_next_hop_address));
8269           increment_v6_address (&v6_dst_address);
8270         }
8271       else
8272         {
8273           clib_memcpy (mp->dst_address, &v4_dst_address,
8274                        sizeof (v4_dst_address));
8275           if (next_hop_set)
8276             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8277                          sizeof (v4_next_hop_address));
8278           if (random_add_del)
8279             v4_dst_address.as_u32 = random_vector[j + 1];
8280           else
8281             increment_v4_address (&v4_dst_address);
8282         }
8283       /* send it... */
8284       S (mp);
8285       /* If we receive SIGTERM, stop now... */
8286       if (vam->do_exit)
8287         break;
8288     }
8289
8290   /* When testing multiple add/del ops, use a control-ping to sync */
8291   if (count > 1)
8292     {
8293       vl_api_control_ping_t *mp_ping;
8294       f64 after;
8295       f64 timeout;
8296
8297       /* Shut off async mode */
8298       vam->async_mode = 0;
8299
8300       MPING (CONTROL_PING, mp_ping);
8301       S (mp_ping);
8302
8303       timeout = vat_time_now (vam) + 1.0;
8304       while (vat_time_now (vam) < timeout)
8305         if (vam->result_ready == 1)
8306           goto out;
8307       vam->retval = -99;
8308
8309     out:
8310       if (vam->retval == -99)
8311         errmsg ("timeout");
8312
8313       if (vam->async_errors > 0)
8314         {
8315           errmsg ("%d asynchronous errors", vam->async_errors);
8316           vam->retval = -98;
8317         }
8318       vam->async_errors = 0;
8319       after = vat_time_now (vam);
8320
8321       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8322       if (j > 0)
8323         count = j;
8324
8325       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8326              count, after - before, count / (after - before));
8327     }
8328   else
8329     {
8330       int ret;
8331
8332       /* Wait for a reply... */
8333       W (ret);
8334       return ret;
8335     }
8336
8337   /* Return the good/bad news */
8338   return (vam->retval);
8339 }
8340
8341 static int
8342 api_ip_mroute_add_del (vat_main_t * vam)
8343 {
8344   unformat_input_t *i = vam->input;
8345   vl_api_ip_mroute_add_del_t *mp;
8346   u32 sw_if_index = ~0, vrf_id = 0;
8347   u8 is_ipv6 = 0;
8348   u8 is_local = 0;
8349   u8 is_add = 1;
8350   u8 address_set = 0;
8351   u32 grp_address_length = 0;
8352   ip4_address_t v4_grp_address, v4_src_address;
8353   ip6_address_t v6_grp_address, v6_src_address;
8354   mfib_itf_flags_t iflags = 0;
8355   mfib_entry_flags_t eflags = 0;
8356   int ret;
8357
8358   /* Parse args required to build the message */
8359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8360     {
8361       if (unformat (i, "sw_if_index %d", &sw_if_index))
8362         ;
8363       else if (unformat (i, "%U %U",
8364                          unformat_ip4_address, &v4_src_address,
8365                          unformat_ip4_address, &v4_grp_address))
8366         {
8367           grp_address_length = 64;
8368           address_set = 1;
8369           is_ipv6 = 0;
8370         }
8371       else if (unformat (i, "%U %U",
8372                          unformat_ip6_address, &v6_src_address,
8373                          unformat_ip6_address, &v6_grp_address))
8374         {
8375           grp_address_length = 256;
8376           address_set = 1;
8377           is_ipv6 = 1;
8378         }
8379       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8380         {
8381           memset (&v4_src_address, 0, sizeof (v4_src_address));
8382           grp_address_length = 32;
8383           address_set = 1;
8384           is_ipv6 = 0;
8385         }
8386       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8387         {
8388           memset (&v6_src_address, 0, sizeof (v6_src_address));
8389           grp_address_length = 128;
8390           address_set = 1;
8391           is_ipv6 = 1;
8392         }
8393       else if (unformat (i, "/%d", &grp_address_length))
8394         ;
8395       else if (unformat (i, "local"))
8396         {
8397           is_local = 1;
8398         }
8399       else if (unformat (i, "del"))
8400         is_add = 0;
8401       else if (unformat (i, "add"))
8402         is_add = 1;
8403       else if (unformat (i, "vrf %d", &vrf_id))
8404         ;
8405       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8406         ;
8407       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8408         ;
8409       else
8410         {
8411           clib_warning ("parse error '%U'", format_unformat_error, i);
8412           return -99;
8413         }
8414     }
8415
8416   if (address_set == 0)
8417     {
8418       errmsg ("missing addresses\n");
8419       return -99;
8420     }
8421
8422   /* Construct the API message */
8423   M (IP_MROUTE_ADD_DEL, mp);
8424
8425   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8426   mp->table_id = ntohl (vrf_id);
8427
8428   mp->is_add = is_add;
8429   mp->is_ipv6 = is_ipv6;
8430   mp->is_local = is_local;
8431   mp->itf_flags = ntohl (iflags);
8432   mp->entry_flags = ntohl (eflags);
8433   mp->grp_address_length = grp_address_length;
8434   mp->grp_address_length = ntohs (mp->grp_address_length);
8435
8436   if (is_ipv6)
8437     {
8438       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8439       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8440     }
8441   else
8442     {
8443       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8444       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8445
8446     }
8447
8448   /* send it... */
8449   S (mp);
8450   /* Wait for a reply... */
8451   W (ret);
8452   return ret;
8453 }
8454
8455 static int
8456 api_mpls_table_add_del (vat_main_t * vam)
8457 {
8458   unformat_input_t *i = vam->input;
8459   vl_api_mpls_table_add_del_t *mp;
8460   u32 table_id = ~0;
8461   u8 is_add = 1;
8462   int ret = 0;
8463
8464   /* Parse args required to build the message */
8465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8466     {
8467       if (unformat (i, "table %d", &table_id))
8468         ;
8469       else if (unformat (i, "del"))
8470         is_add = 0;
8471       else if (unformat (i, "add"))
8472         is_add = 1;
8473       else
8474         {
8475           clib_warning ("parse error '%U'", format_unformat_error, i);
8476           return -99;
8477         }
8478     }
8479
8480   if (~0 == table_id)
8481     {
8482       errmsg ("missing table-ID");
8483       return -99;
8484     }
8485
8486   /* Construct the API message */
8487   M (MPLS_TABLE_ADD_DEL, mp);
8488
8489   mp->mt_table_id = ntohl (table_id);
8490   mp->mt_is_add = is_add;
8491
8492   /* send it... */
8493   S (mp);
8494
8495   /* Wait for a reply... */
8496   W (ret);
8497
8498   return ret;
8499 }
8500
8501 static int
8502 api_mpls_route_add_del (vat_main_t * vam)
8503 {
8504   unformat_input_t *i = vam->input;
8505   vl_api_mpls_route_add_del_t *mp;
8506   u32 sw_if_index = ~0, table_id = 0;
8507   u8 is_add = 1;
8508   u32 next_hop_weight = 1;
8509   u8 is_multipath = 0;
8510   u32 next_hop_table_id = 0;
8511   u8 next_hop_set = 0;
8512   ip4_address_t v4_next_hop_address = {
8513     .as_u32 = 0,
8514   };
8515   ip6_address_t v6_next_hop_address = { {0} };
8516   int count = 1;
8517   int j;
8518   f64 before = 0;
8519   u32 classify_table_index = ~0;
8520   u8 is_classify = 0;
8521   u8 resolve_host = 0, resolve_attached = 0;
8522   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8523   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8524   mpls_label_t *next_hop_out_label_stack = NULL;
8525   mpls_label_t local_label = MPLS_LABEL_INVALID;
8526   u8 is_eos = 0;
8527   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8528
8529   /* Parse args required to build the message */
8530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8531     {
8532       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8533         ;
8534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8535         ;
8536       else if (unformat (i, "%d", &local_label))
8537         ;
8538       else if (unformat (i, "eos"))
8539         is_eos = 1;
8540       else if (unformat (i, "non-eos"))
8541         is_eos = 0;
8542       else if (unformat (i, "via %U", unformat_ip4_address,
8543                          &v4_next_hop_address))
8544         {
8545           next_hop_set = 1;
8546           next_hop_proto = DPO_PROTO_IP4;
8547         }
8548       else if (unformat (i, "via %U", unformat_ip6_address,
8549                          &v6_next_hop_address))
8550         {
8551           next_hop_set = 1;
8552           next_hop_proto = DPO_PROTO_IP6;
8553         }
8554       else if (unformat (i, "weight %d", &next_hop_weight))
8555         ;
8556       else if (unformat (i, "classify %d", &classify_table_index))
8557         {
8558           is_classify = 1;
8559         }
8560       else if (unformat (i, "del"))
8561         is_add = 0;
8562       else if (unformat (i, "add"))
8563         is_add = 1;
8564       else if (unformat (i, "resolve-via-host"))
8565         resolve_host = 1;
8566       else if (unformat (i, "resolve-via-attached"))
8567         resolve_attached = 1;
8568       else if (unformat (i, "multipath"))
8569         is_multipath = 1;
8570       else if (unformat (i, "count %d", &count))
8571         ;
8572       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8573         {
8574           next_hop_set = 1;
8575           next_hop_proto = DPO_PROTO_IP4;
8576         }
8577       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8578         {
8579           next_hop_set = 1;
8580           next_hop_proto = DPO_PROTO_IP6;
8581         }
8582       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8583         ;
8584       else if (unformat (i, "via-label %d", &next_hop_via_label))
8585         ;
8586       else if (unformat (i, "out-label %d", &next_hop_out_label))
8587         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8588       else
8589         {
8590           clib_warning ("parse error '%U'", format_unformat_error, i);
8591           return -99;
8592         }
8593     }
8594
8595   if (!next_hop_set && !is_classify)
8596     {
8597       errmsg ("next hop / classify not set");
8598       return -99;
8599     }
8600
8601   if (MPLS_LABEL_INVALID == local_label)
8602     {
8603       errmsg ("missing label");
8604       return -99;
8605     }
8606
8607   if (count > 1)
8608     {
8609       /* Turn on async mode */
8610       vam->async_mode = 1;
8611       vam->async_errors = 0;
8612       before = vat_time_now (vam);
8613     }
8614
8615   for (j = 0; j < count; j++)
8616     {
8617       /* Construct the API message */
8618       M2 (MPLS_ROUTE_ADD_DEL, mp,
8619           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8620
8621       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8622       mp->mr_table_id = ntohl (table_id);
8623
8624       mp->mr_is_add = is_add;
8625       mp->mr_next_hop_proto = next_hop_proto;
8626       mp->mr_is_classify = is_classify;
8627       mp->mr_is_multipath = is_multipath;
8628       mp->mr_is_resolve_host = resolve_host;
8629       mp->mr_is_resolve_attached = resolve_attached;
8630       mp->mr_next_hop_weight = next_hop_weight;
8631       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8632       mp->mr_classify_table_index = ntohl (classify_table_index);
8633       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8634       mp->mr_label = ntohl (local_label);
8635       mp->mr_eos = is_eos;
8636
8637       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8638       if (0 != mp->mr_next_hop_n_out_labels)
8639         {
8640           memcpy (mp->mr_next_hop_out_label_stack,
8641                   next_hop_out_label_stack,
8642                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8643           vec_free (next_hop_out_label_stack);
8644         }
8645
8646       if (next_hop_set)
8647         {
8648           if (DPO_PROTO_IP4 == next_hop_proto)
8649             {
8650               clib_memcpy (mp->mr_next_hop,
8651                            &v4_next_hop_address,
8652                            sizeof (v4_next_hop_address));
8653             }
8654           else if (DPO_PROTO_IP6 == next_hop_proto)
8655
8656             {
8657               clib_memcpy (mp->mr_next_hop,
8658                            &v6_next_hop_address,
8659                            sizeof (v6_next_hop_address));
8660             }
8661         }
8662       local_label++;
8663
8664       /* send it... */
8665       S (mp);
8666       /* If we receive SIGTERM, stop now... */
8667       if (vam->do_exit)
8668         break;
8669     }
8670
8671   /* When testing multiple add/del ops, use a control-ping to sync */
8672   if (count > 1)
8673     {
8674       vl_api_control_ping_t *mp_ping;
8675       f64 after;
8676       f64 timeout;
8677
8678       /* Shut off async mode */
8679       vam->async_mode = 0;
8680
8681       MPING (CONTROL_PING, mp_ping);
8682       S (mp_ping);
8683
8684       timeout = vat_time_now (vam) + 1.0;
8685       while (vat_time_now (vam) < timeout)
8686         if (vam->result_ready == 1)
8687           goto out;
8688       vam->retval = -99;
8689
8690     out:
8691       if (vam->retval == -99)
8692         errmsg ("timeout");
8693
8694       if (vam->async_errors > 0)
8695         {
8696           errmsg ("%d asynchronous errors", vam->async_errors);
8697           vam->retval = -98;
8698         }
8699       vam->async_errors = 0;
8700       after = vat_time_now (vam);
8701
8702       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8703       if (j > 0)
8704         count = j;
8705
8706       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8707              count, after - before, count / (after - before));
8708     }
8709   else
8710     {
8711       int ret;
8712
8713       /* Wait for a reply... */
8714       W (ret);
8715       return ret;
8716     }
8717
8718   /* Return the good/bad news */
8719   return (vam->retval);
8720 }
8721
8722 static int
8723 api_mpls_ip_bind_unbind (vat_main_t * vam)
8724 {
8725   unformat_input_t *i = vam->input;
8726   vl_api_mpls_ip_bind_unbind_t *mp;
8727   u32 ip_table_id = 0;
8728   u8 is_bind = 1;
8729   u8 is_ip4 = 1;
8730   ip4_address_t v4_address;
8731   ip6_address_t v6_address;
8732   u32 address_length;
8733   u8 address_set = 0;
8734   mpls_label_t local_label = MPLS_LABEL_INVALID;
8735   int ret;
8736
8737   /* Parse args required to build the message */
8738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8739     {
8740       if (unformat (i, "%U/%d", unformat_ip4_address,
8741                     &v4_address, &address_length))
8742         {
8743           is_ip4 = 1;
8744           address_set = 1;
8745         }
8746       else if (unformat (i, "%U/%d", unformat_ip6_address,
8747                          &v6_address, &address_length))
8748         {
8749           is_ip4 = 0;
8750           address_set = 1;
8751         }
8752       else if (unformat (i, "%d", &local_label))
8753         ;
8754       else if (unformat (i, "table-id %d", &ip_table_id))
8755         ;
8756       else if (unformat (i, "unbind"))
8757         is_bind = 0;
8758       else if (unformat (i, "bind"))
8759         is_bind = 1;
8760       else
8761         {
8762           clib_warning ("parse error '%U'", format_unformat_error, i);
8763           return -99;
8764         }
8765     }
8766
8767   if (!address_set)
8768     {
8769       errmsg ("IP addres not set");
8770       return -99;
8771     }
8772
8773   if (MPLS_LABEL_INVALID == local_label)
8774     {
8775       errmsg ("missing label");
8776       return -99;
8777     }
8778
8779   /* Construct the API message */
8780   M (MPLS_IP_BIND_UNBIND, mp);
8781
8782   mp->mb_is_bind = is_bind;
8783   mp->mb_is_ip4 = is_ip4;
8784   mp->mb_ip_table_id = ntohl (ip_table_id);
8785   mp->mb_mpls_table_id = 0;
8786   mp->mb_label = ntohl (local_label);
8787   mp->mb_address_length = address_length;
8788
8789   if (is_ip4)
8790     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8791   else
8792     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8793
8794   /* send it... */
8795   S (mp);
8796
8797   /* Wait for a reply... */
8798   W (ret);
8799   return ret;
8800 }
8801
8802 static int
8803 api_bier_table_add_del (vat_main_t * vam)
8804 {
8805   unformat_input_t *i = vam->input;
8806   vl_api_bier_table_add_del_t *mp;
8807   u8 is_add = 1;
8808   u32 set = 0, sub_domain = 0, hdr_len = 3;
8809   mpls_label_t local_label = MPLS_LABEL_INVALID;
8810   int ret;
8811
8812   /* Parse args required to build the message */
8813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8814     {
8815       if (unformat (i, "sub-domain %d", &sub_domain))
8816         ;
8817       else if (unformat (i, "set %d", &set))
8818         ;
8819       else if (unformat (i, "label %d", &local_label))
8820         ;
8821       else if (unformat (i, "hdr-len %d", &hdr_len))
8822         ;
8823       else if (unformat (i, "add"))
8824         is_add = 1;
8825       else if (unformat (i, "del"))
8826         is_add = 0;
8827       else
8828         {
8829           clib_warning ("parse error '%U'", format_unformat_error, i);
8830           return -99;
8831         }
8832     }
8833
8834   if (MPLS_LABEL_INVALID == local_label)
8835     {
8836       errmsg ("missing label\n");
8837       return -99;
8838     }
8839
8840   /* Construct the API message */
8841   M (BIER_TABLE_ADD_DEL, mp);
8842
8843   mp->bt_is_add = is_add;
8844   mp->bt_label = ntohl (local_label);
8845   mp->bt_tbl_id.bt_set = set;
8846   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8847   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8848
8849   /* send it... */
8850   S (mp);
8851
8852   /* Wait for a reply... */
8853   W (ret);
8854
8855   return (ret);
8856 }
8857
8858 static int
8859 api_bier_route_add_del (vat_main_t * vam)
8860 {
8861   unformat_input_t *i = vam->input;
8862   vl_api_bier_route_add_del_t *mp;
8863   u8 is_add = 1;
8864   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8865   ip4_address_t v4_next_hop_address;
8866   ip6_address_t v6_next_hop_address;
8867   u8 next_hop_set = 0;
8868   u8 next_hop_proto_is_ip4 = 1;
8869   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8870   int ret;
8871
8872   /* Parse args required to build the message */
8873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8874     {
8875       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8876         {
8877           next_hop_proto_is_ip4 = 1;
8878           next_hop_set = 1;
8879         }
8880       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8881         {
8882           next_hop_proto_is_ip4 = 0;
8883           next_hop_set = 1;
8884         }
8885       if (unformat (i, "sub-domain %d", &sub_domain))
8886         ;
8887       else if (unformat (i, "set %d", &set))
8888         ;
8889       else if (unformat (i, "hdr-len %d", &hdr_len))
8890         ;
8891       else if (unformat (i, "bp %d", &bp))
8892         ;
8893       else if (unformat (i, "add"))
8894         is_add = 1;
8895       else if (unformat (i, "del"))
8896         is_add = 0;
8897       else if (unformat (i, "out-label %d", &next_hop_out_label))
8898         ;
8899       else
8900         {
8901           clib_warning ("parse error '%U'", format_unformat_error, i);
8902           return -99;
8903         }
8904     }
8905
8906   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8907     {
8908       errmsg ("next hop / label set\n");
8909       return -99;
8910     }
8911   if (0 == bp)
8912     {
8913       errmsg ("bit=position not set\n");
8914       return -99;
8915     }
8916
8917   /* Construct the API message */
8918   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8919
8920   mp->br_is_add = is_add;
8921   mp->br_tbl_id.bt_set = set;
8922   mp->br_tbl_id.bt_sub_domain = sub_domain;
8923   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8924   mp->br_bp = ntohs (bp);
8925   mp->br_n_paths = 1;
8926   mp->br_paths[0].n_labels = 1;
8927   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8928   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8929
8930   if (next_hop_proto_is_ip4)
8931     {
8932       clib_memcpy (mp->br_paths[0].next_hop,
8933                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8934     }
8935   else
8936     {
8937       clib_memcpy (mp->br_paths[0].next_hop,
8938                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8939     }
8940
8941   /* send it... */
8942   S (mp);
8943
8944   /* Wait for a reply... */
8945   W (ret);
8946
8947   return (ret);
8948 }
8949
8950 static int
8951 api_proxy_arp_add_del (vat_main_t * vam)
8952 {
8953   unformat_input_t *i = vam->input;
8954   vl_api_proxy_arp_add_del_t *mp;
8955   u32 vrf_id = 0;
8956   u8 is_add = 1;
8957   ip4_address_t lo, hi;
8958   u8 range_set = 0;
8959   int ret;
8960
8961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8962     {
8963       if (unformat (i, "vrf %d", &vrf_id))
8964         ;
8965       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8966                          unformat_ip4_address, &hi))
8967         range_set = 1;
8968       else if (unformat (i, "del"))
8969         is_add = 0;
8970       else
8971         {
8972           clib_warning ("parse error '%U'", format_unformat_error, i);
8973           return -99;
8974         }
8975     }
8976
8977   if (range_set == 0)
8978     {
8979       errmsg ("address range not set");
8980       return -99;
8981     }
8982
8983   M (PROXY_ARP_ADD_DEL, mp);
8984
8985   mp->vrf_id = ntohl (vrf_id);
8986   mp->is_add = is_add;
8987   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8988   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8989
8990   S (mp);
8991   W (ret);
8992   return ret;
8993 }
8994
8995 static int
8996 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8997 {
8998   unformat_input_t *i = vam->input;
8999   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9000   u32 sw_if_index;
9001   u8 enable = 1;
9002   u8 sw_if_index_set = 0;
9003   int ret;
9004
9005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9006     {
9007       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9008         sw_if_index_set = 1;
9009       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9010         sw_if_index_set = 1;
9011       else if (unformat (i, "enable"))
9012         enable = 1;
9013       else if (unformat (i, "disable"))
9014         enable = 0;
9015       else
9016         {
9017           clib_warning ("parse error '%U'", format_unformat_error, i);
9018           return -99;
9019         }
9020     }
9021
9022   if (sw_if_index_set == 0)
9023     {
9024       errmsg ("missing interface name or sw_if_index");
9025       return -99;
9026     }
9027
9028   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9029
9030   mp->sw_if_index = ntohl (sw_if_index);
9031   mp->enable_disable = enable;
9032
9033   S (mp);
9034   W (ret);
9035   return ret;
9036 }
9037
9038 static int
9039 api_mpls_tunnel_add_del (vat_main_t * vam)
9040 {
9041   unformat_input_t *i = vam->input;
9042   vl_api_mpls_tunnel_add_del_t *mp;
9043
9044   u8 is_add = 1;
9045   u8 l2_only = 0;
9046   u32 sw_if_index = ~0;
9047   u32 next_hop_sw_if_index = ~0;
9048   u32 next_hop_proto_is_ip4 = 1;
9049
9050   u32 next_hop_table_id = 0;
9051   ip4_address_t v4_next_hop_address = {
9052     .as_u32 = 0,
9053   };
9054   ip6_address_t v6_next_hop_address = { {0} };
9055   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9056   int ret;
9057
9058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9059     {
9060       if (unformat (i, "add"))
9061         is_add = 1;
9062       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9063         is_add = 0;
9064       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9065         ;
9066       else if (unformat (i, "via %U",
9067                          unformat_ip4_address, &v4_next_hop_address))
9068         {
9069           next_hop_proto_is_ip4 = 1;
9070         }
9071       else if (unformat (i, "via %U",
9072                          unformat_ip6_address, &v6_next_hop_address))
9073         {
9074           next_hop_proto_is_ip4 = 0;
9075         }
9076       else if (unformat (i, "l2-only"))
9077         l2_only = 1;
9078       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9079         ;
9080       else if (unformat (i, "out-label %d", &next_hop_out_label))
9081         vec_add1 (labels, ntohl (next_hop_out_label));
9082       else
9083         {
9084           clib_warning ("parse error '%U'", format_unformat_error, i);
9085           return -99;
9086         }
9087     }
9088
9089   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9090
9091   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9092   mp->mt_sw_if_index = ntohl (sw_if_index);
9093   mp->mt_is_add = is_add;
9094   mp->mt_l2_only = l2_only;
9095   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9096   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9097
9098   mp->mt_next_hop_n_out_labels = vec_len (labels);
9099
9100   if (0 != mp->mt_next_hop_n_out_labels)
9101     {
9102       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9103                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9104       vec_free (labels);
9105     }
9106
9107   if (next_hop_proto_is_ip4)
9108     {
9109       clib_memcpy (mp->mt_next_hop,
9110                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9111     }
9112   else
9113     {
9114       clib_memcpy (mp->mt_next_hop,
9115                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9116     }
9117
9118   S (mp);
9119   W (ret);
9120   return ret;
9121 }
9122
9123 static int
9124 api_sw_interface_set_unnumbered (vat_main_t * vam)
9125 {
9126   unformat_input_t *i = vam->input;
9127   vl_api_sw_interface_set_unnumbered_t *mp;
9128   u32 sw_if_index;
9129   u32 unnum_sw_index = ~0;
9130   u8 is_add = 1;
9131   u8 sw_if_index_set = 0;
9132   int ret;
9133
9134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9135     {
9136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9137         sw_if_index_set = 1;
9138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9139         sw_if_index_set = 1;
9140       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9141         ;
9142       else if (unformat (i, "del"))
9143         is_add = 0;
9144       else
9145         {
9146           clib_warning ("parse error '%U'", format_unformat_error, i);
9147           return -99;
9148         }
9149     }
9150
9151   if (sw_if_index_set == 0)
9152     {
9153       errmsg ("missing interface name or sw_if_index");
9154       return -99;
9155     }
9156
9157   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9158
9159   mp->sw_if_index = ntohl (sw_if_index);
9160   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9161   mp->is_add = is_add;
9162
9163   S (mp);
9164   W (ret);
9165   return ret;
9166 }
9167
9168 static int
9169 api_ip_neighbor_add_del (vat_main_t * vam)
9170 {
9171   unformat_input_t *i = vam->input;
9172   vl_api_ip_neighbor_add_del_t *mp;
9173   u32 sw_if_index;
9174   u8 sw_if_index_set = 0;
9175   u8 is_add = 1;
9176   u8 is_static = 0;
9177   u8 is_no_fib_entry = 0;
9178   u8 mac_address[6];
9179   u8 mac_set = 0;
9180   u8 v4_address_set = 0;
9181   u8 v6_address_set = 0;
9182   ip4_address_t v4address;
9183   ip6_address_t v6address;
9184   int ret;
9185
9186   memset (mac_address, 0, sizeof (mac_address));
9187
9188   /* Parse args required to build the message */
9189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9190     {
9191       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9192         {
9193           mac_set = 1;
9194         }
9195       else if (unformat (i, "del"))
9196         is_add = 0;
9197       else
9198         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9199         sw_if_index_set = 1;
9200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9201         sw_if_index_set = 1;
9202       else if (unformat (i, "is_static"))
9203         is_static = 1;
9204       else if (unformat (i, "no-fib-entry"))
9205         is_no_fib_entry = 1;
9206       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9207         v4_address_set = 1;
9208       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9209         v6_address_set = 1;
9210       else
9211         {
9212           clib_warning ("parse error '%U'", format_unformat_error, i);
9213           return -99;
9214         }
9215     }
9216
9217   if (sw_if_index_set == 0)
9218     {
9219       errmsg ("missing interface name or sw_if_index");
9220       return -99;
9221     }
9222   if (v4_address_set && v6_address_set)
9223     {
9224       errmsg ("both v4 and v6 addresses set");
9225       return -99;
9226     }
9227   if (!v4_address_set && !v6_address_set)
9228     {
9229       errmsg ("no address set");
9230       return -99;
9231     }
9232
9233   /* Construct the API message */
9234   M (IP_NEIGHBOR_ADD_DEL, mp);
9235
9236   mp->sw_if_index = ntohl (sw_if_index);
9237   mp->is_add = is_add;
9238   mp->is_static = is_static;
9239   mp->is_no_adj_fib = is_no_fib_entry;
9240   if (mac_set)
9241     clib_memcpy (mp->mac_address, mac_address, 6);
9242   if (v6_address_set)
9243     {
9244       mp->is_ipv6 = 1;
9245       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9246     }
9247   else
9248     {
9249       /* mp->is_ipv6 = 0; via memset in M macro above */
9250       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9251     }
9252
9253   /* send it... */
9254   S (mp);
9255
9256   /* Wait for a reply, return good/bad news  */
9257   W (ret);
9258   return ret;
9259 }
9260
9261 static int
9262 api_create_vlan_subif (vat_main_t * vam)
9263 {
9264   unformat_input_t *i = vam->input;
9265   vl_api_create_vlan_subif_t *mp;
9266   u32 sw_if_index;
9267   u8 sw_if_index_set = 0;
9268   u32 vlan_id;
9269   u8 vlan_id_set = 0;
9270   int ret;
9271
9272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9273     {
9274       if (unformat (i, "sw_if_index %d", &sw_if_index))
9275         sw_if_index_set = 1;
9276       else
9277         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9278         sw_if_index_set = 1;
9279       else if (unformat (i, "vlan %d", &vlan_id))
9280         vlan_id_set = 1;
9281       else
9282         {
9283           clib_warning ("parse error '%U'", format_unformat_error, i);
9284           return -99;
9285         }
9286     }
9287
9288   if (sw_if_index_set == 0)
9289     {
9290       errmsg ("missing interface name or sw_if_index");
9291       return -99;
9292     }
9293
9294   if (vlan_id_set == 0)
9295     {
9296       errmsg ("missing vlan_id");
9297       return -99;
9298     }
9299   M (CREATE_VLAN_SUBIF, mp);
9300
9301   mp->sw_if_index = ntohl (sw_if_index);
9302   mp->vlan_id = ntohl (vlan_id);
9303
9304   S (mp);
9305   W (ret);
9306   return ret;
9307 }
9308
9309 #define foreach_create_subif_bit                \
9310 _(no_tags)                                      \
9311 _(one_tag)                                      \
9312 _(two_tags)                                     \
9313 _(dot1ad)                                       \
9314 _(exact_match)                                  \
9315 _(default_sub)                                  \
9316 _(outer_vlan_id_any)                            \
9317 _(inner_vlan_id_any)
9318
9319 static int
9320 api_create_subif (vat_main_t * vam)
9321 {
9322   unformat_input_t *i = vam->input;
9323   vl_api_create_subif_t *mp;
9324   u32 sw_if_index;
9325   u8 sw_if_index_set = 0;
9326   u32 sub_id;
9327   u8 sub_id_set = 0;
9328   u32 no_tags = 0;
9329   u32 one_tag = 0;
9330   u32 two_tags = 0;
9331   u32 dot1ad = 0;
9332   u32 exact_match = 0;
9333   u32 default_sub = 0;
9334   u32 outer_vlan_id_any = 0;
9335   u32 inner_vlan_id_any = 0;
9336   u32 tmp;
9337   u16 outer_vlan_id = 0;
9338   u16 inner_vlan_id = 0;
9339   int ret;
9340
9341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9342     {
9343       if (unformat (i, "sw_if_index %d", &sw_if_index))
9344         sw_if_index_set = 1;
9345       else
9346         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9347         sw_if_index_set = 1;
9348       else if (unformat (i, "sub_id %d", &sub_id))
9349         sub_id_set = 1;
9350       else if (unformat (i, "outer_vlan_id %d", &tmp))
9351         outer_vlan_id = tmp;
9352       else if (unformat (i, "inner_vlan_id %d", &tmp))
9353         inner_vlan_id = tmp;
9354
9355 #define _(a) else if (unformat (i, #a)) a = 1 ;
9356       foreach_create_subif_bit
9357 #undef _
9358         else
9359         {
9360           clib_warning ("parse error '%U'", format_unformat_error, i);
9361           return -99;
9362         }
9363     }
9364
9365   if (sw_if_index_set == 0)
9366     {
9367       errmsg ("missing interface name or sw_if_index");
9368       return -99;
9369     }
9370
9371   if (sub_id_set == 0)
9372     {
9373       errmsg ("missing sub_id");
9374       return -99;
9375     }
9376   M (CREATE_SUBIF, mp);
9377
9378   mp->sw_if_index = ntohl (sw_if_index);
9379   mp->sub_id = ntohl (sub_id);
9380
9381 #define _(a) mp->a = a;
9382   foreach_create_subif_bit;
9383 #undef _
9384
9385   mp->outer_vlan_id = ntohs (outer_vlan_id);
9386   mp->inner_vlan_id = ntohs (inner_vlan_id);
9387
9388   S (mp);
9389   W (ret);
9390   return ret;
9391 }
9392
9393 static int
9394 api_oam_add_del (vat_main_t * vam)
9395 {
9396   unformat_input_t *i = vam->input;
9397   vl_api_oam_add_del_t *mp;
9398   u32 vrf_id = 0;
9399   u8 is_add = 1;
9400   ip4_address_t src, dst;
9401   u8 src_set = 0;
9402   u8 dst_set = 0;
9403   int ret;
9404
9405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9406     {
9407       if (unformat (i, "vrf %d", &vrf_id))
9408         ;
9409       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9410         src_set = 1;
9411       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9412         dst_set = 1;
9413       else if (unformat (i, "del"))
9414         is_add = 0;
9415       else
9416         {
9417           clib_warning ("parse error '%U'", format_unformat_error, i);
9418           return -99;
9419         }
9420     }
9421
9422   if (src_set == 0)
9423     {
9424       errmsg ("missing src addr");
9425       return -99;
9426     }
9427
9428   if (dst_set == 0)
9429     {
9430       errmsg ("missing dst addr");
9431       return -99;
9432     }
9433
9434   M (OAM_ADD_DEL, mp);
9435
9436   mp->vrf_id = ntohl (vrf_id);
9437   mp->is_add = is_add;
9438   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9439   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9440
9441   S (mp);
9442   W (ret);
9443   return ret;
9444 }
9445
9446 static int
9447 api_reset_fib (vat_main_t * vam)
9448 {
9449   unformat_input_t *i = vam->input;
9450   vl_api_reset_fib_t *mp;
9451   u32 vrf_id = 0;
9452   u8 is_ipv6 = 0;
9453   u8 vrf_id_set = 0;
9454
9455   int ret;
9456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9457     {
9458       if (unformat (i, "vrf %d", &vrf_id))
9459         vrf_id_set = 1;
9460       else if (unformat (i, "ipv6"))
9461         is_ipv6 = 1;
9462       else
9463         {
9464           clib_warning ("parse error '%U'", format_unformat_error, i);
9465           return -99;
9466         }
9467     }
9468
9469   if (vrf_id_set == 0)
9470     {
9471       errmsg ("missing vrf id");
9472       return -99;
9473     }
9474
9475   M (RESET_FIB, mp);
9476
9477   mp->vrf_id = ntohl (vrf_id);
9478   mp->is_ipv6 = is_ipv6;
9479
9480   S (mp);
9481   W (ret);
9482   return ret;
9483 }
9484
9485 static int
9486 api_dhcp_proxy_config (vat_main_t * vam)
9487 {
9488   unformat_input_t *i = vam->input;
9489   vl_api_dhcp_proxy_config_t *mp;
9490   u32 rx_vrf_id = 0;
9491   u32 server_vrf_id = 0;
9492   u8 is_add = 1;
9493   u8 v4_address_set = 0;
9494   u8 v6_address_set = 0;
9495   ip4_address_t v4address;
9496   ip6_address_t v6address;
9497   u8 v4_src_address_set = 0;
9498   u8 v6_src_address_set = 0;
9499   ip4_address_t v4srcaddress;
9500   ip6_address_t v6srcaddress;
9501   int ret;
9502
9503   /* Parse args required to build the message */
9504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9505     {
9506       if (unformat (i, "del"))
9507         is_add = 0;
9508       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9509         ;
9510       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9511         ;
9512       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9513         v4_address_set = 1;
9514       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9515         v6_address_set = 1;
9516       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9517         v4_src_address_set = 1;
9518       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9519         v6_src_address_set = 1;
9520       else
9521         break;
9522     }
9523
9524   if (v4_address_set && v6_address_set)
9525     {
9526       errmsg ("both v4 and v6 server addresses set");
9527       return -99;
9528     }
9529   if (!v4_address_set && !v6_address_set)
9530     {
9531       errmsg ("no server addresses set");
9532       return -99;
9533     }
9534
9535   if (v4_src_address_set && v6_src_address_set)
9536     {
9537       errmsg ("both v4 and v6  src addresses set");
9538       return -99;
9539     }
9540   if (!v4_src_address_set && !v6_src_address_set)
9541     {
9542       errmsg ("no src addresses set");
9543       return -99;
9544     }
9545
9546   if (!(v4_src_address_set && v4_address_set) &&
9547       !(v6_src_address_set && v6_address_set))
9548     {
9549       errmsg ("no matching server and src addresses set");
9550       return -99;
9551     }
9552
9553   /* Construct the API message */
9554   M (DHCP_PROXY_CONFIG, mp);
9555
9556   mp->is_add = is_add;
9557   mp->rx_vrf_id = ntohl (rx_vrf_id);
9558   mp->server_vrf_id = ntohl (server_vrf_id);
9559   if (v6_address_set)
9560     {
9561       mp->is_ipv6 = 1;
9562       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9563       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9564     }
9565   else
9566     {
9567       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9568       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9569     }
9570
9571   /* send it... */
9572   S (mp);
9573
9574   /* Wait for a reply, return good/bad news  */
9575   W (ret);
9576   return ret;
9577 }
9578
9579 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9580 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9581
9582 static void
9583 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9584 {
9585   vat_main_t *vam = &vat_main;
9586   u32 i, count = mp->count;
9587   vl_api_dhcp_server_t *s;
9588
9589   if (mp->is_ipv6)
9590     print (vam->ofp,
9591            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9592            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9593            ntohl (mp->rx_vrf_id),
9594            format_ip6_address, mp->dhcp_src_address,
9595            mp->vss_type, mp->vss_vpn_ascii_id,
9596            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9597   else
9598     print (vam->ofp,
9599            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9600            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9601            ntohl (mp->rx_vrf_id),
9602            format_ip4_address, mp->dhcp_src_address,
9603            mp->vss_type, mp->vss_vpn_ascii_id,
9604            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9605
9606   for (i = 0; i < count; i++)
9607     {
9608       s = &mp->servers[i];
9609
9610       if (mp->is_ipv6)
9611         print (vam->ofp,
9612                " Server Table-ID %d, Server Address %U",
9613                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9614       else
9615         print (vam->ofp,
9616                " Server Table-ID %d, Server Address %U",
9617                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9618     }
9619 }
9620
9621 static void vl_api_dhcp_proxy_details_t_handler_json
9622   (vl_api_dhcp_proxy_details_t * mp)
9623 {
9624   vat_main_t *vam = &vat_main;
9625   vat_json_node_t *node = NULL;
9626   u32 i, count = mp->count;
9627   struct in_addr ip4;
9628   struct in6_addr ip6;
9629   vl_api_dhcp_server_t *s;
9630
9631   if (VAT_JSON_ARRAY != vam->json_tree.type)
9632     {
9633       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9634       vat_json_init_array (&vam->json_tree);
9635     }
9636   node = vat_json_array_add (&vam->json_tree);
9637
9638   vat_json_init_object (node);
9639   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9640   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9641                              sizeof (mp->vss_type));
9642   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9643                                    mp->vss_vpn_ascii_id);
9644   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9645   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9646
9647   if (mp->is_ipv6)
9648     {
9649       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9650       vat_json_object_add_ip6 (node, "src_address", ip6);
9651     }
9652   else
9653     {
9654       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9655       vat_json_object_add_ip4 (node, "src_address", ip4);
9656     }
9657
9658   for (i = 0; i < count; i++)
9659     {
9660       s = &mp->servers[i];
9661
9662       vat_json_object_add_uint (node, "server-table-id",
9663                                 ntohl (s->server_vrf_id));
9664
9665       if (mp->is_ipv6)
9666         {
9667           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9668           vat_json_object_add_ip4 (node, "src_address", ip4);
9669         }
9670       else
9671         {
9672           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9673           vat_json_object_add_ip6 (node, "server_address", ip6);
9674         }
9675     }
9676 }
9677
9678 static int
9679 api_dhcp_proxy_dump (vat_main_t * vam)
9680 {
9681   unformat_input_t *i = vam->input;
9682   vl_api_control_ping_t *mp_ping;
9683   vl_api_dhcp_proxy_dump_t *mp;
9684   u8 is_ipv6 = 0;
9685   int ret;
9686
9687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9688     {
9689       if (unformat (i, "ipv6"))
9690         is_ipv6 = 1;
9691       else
9692         {
9693           clib_warning ("parse error '%U'", format_unformat_error, i);
9694           return -99;
9695         }
9696     }
9697
9698   M (DHCP_PROXY_DUMP, mp);
9699
9700   mp->is_ip6 = is_ipv6;
9701   S (mp);
9702
9703   /* Use a control ping for synchronization */
9704   MPING (CONTROL_PING, mp_ping);
9705   S (mp_ping);
9706
9707   W (ret);
9708   return ret;
9709 }
9710
9711 static int
9712 api_dhcp_proxy_set_vss (vat_main_t * vam)
9713 {
9714   unformat_input_t *i = vam->input;
9715   vl_api_dhcp_proxy_set_vss_t *mp;
9716   u8 is_ipv6 = 0;
9717   u8 is_add = 1;
9718   u32 tbl_id = ~0;
9719   u8 vss_type = VSS_TYPE_DEFAULT;
9720   u8 *vpn_ascii_id = 0;
9721   u32 oui = 0;
9722   u32 fib_id = 0;
9723   int ret;
9724
9725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9726     {
9727       if (unformat (i, "tbl_id %d", &tbl_id))
9728         ;
9729       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9730         vss_type = VSS_TYPE_ASCII;
9731       else if (unformat (i, "fib_id %d", &fib_id))
9732         vss_type = VSS_TYPE_VPN_ID;
9733       else if (unformat (i, "oui %d", &oui))
9734         vss_type = VSS_TYPE_VPN_ID;
9735       else if (unformat (i, "ipv6"))
9736         is_ipv6 = 1;
9737       else if (unformat (i, "del"))
9738         is_add = 0;
9739       else
9740         break;
9741     }
9742
9743   if (tbl_id == ~0)
9744     {
9745       errmsg ("missing tbl_id ");
9746       vec_free (vpn_ascii_id);
9747       return -99;
9748     }
9749
9750   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9751     {
9752       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9753       vec_free (vpn_ascii_id);
9754       return -99;
9755     }
9756
9757   M (DHCP_PROXY_SET_VSS, mp);
9758   mp->tbl_id = ntohl (tbl_id);
9759   mp->vss_type = vss_type;
9760   if (vpn_ascii_id)
9761     {
9762       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9763       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9764     }
9765   mp->vpn_index = ntohl (fib_id);
9766   mp->oui = ntohl (oui);
9767   mp->is_ipv6 = is_ipv6;
9768   mp->is_add = is_add;
9769
9770   S (mp);
9771   W (ret);
9772
9773   vec_free (vpn_ascii_id);
9774   return ret;
9775 }
9776
9777 static int
9778 api_dhcp_client_config (vat_main_t * vam)
9779 {
9780   unformat_input_t *i = vam->input;
9781   vl_api_dhcp_client_config_t *mp;
9782   u32 sw_if_index;
9783   u8 sw_if_index_set = 0;
9784   u8 is_add = 1;
9785   u8 *hostname = 0;
9786   u8 disable_event = 0;
9787   int ret;
9788
9789   /* Parse args required to build the message */
9790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9791     {
9792       if (unformat (i, "del"))
9793         is_add = 0;
9794       else
9795         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9796         sw_if_index_set = 1;
9797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9798         sw_if_index_set = 1;
9799       else if (unformat (i, "hostname %s", &hostname))
9800         ;
9801       else if (unformat (i, "disable_event"))
9802         disable_event = 1;
9803       else
9804         break;
9805     }
9806
9807   if (sw_if_index_set == 0)
9808     {
9809       errmsg ("missing interface name or sw_if_index");
9810       return -99;
9811     }
9812
9813   if (vec_len (hostname) > 63)
9814     {
9815       errmsg ("hostname too long");
9816     }
9817   vec_add1 (hostname, 0);
9818
9819   /* Construct the API message */
9820   M (DHCP_CLIENT_CONFIG, mp);
9821
9822   mp->sw_if_index = htonl (sw_if_index);
9823   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9824   vec_free (hostname);
9825   mp->is_add = is_add;
9826   mp->want_dhcp_event = disable_event ? 0 : 1;
9827   mp->pid = htonl (getpid ());
9828
9829   /* send it... */
9830   S (mp);
9831
9832   /* Wait for a reply, return good/bad news  */
9833   W (ret);
9834   return ret;
9835 }
9836
9837 static int
9838 api_set_ip_flow_hash (vat_main_t * vam)
9839 {
9840   unformat_input_t *i = vam->input;
9841   vl_api_set_ip_flow_hash_t *mp;
9842   u32 vrf_id = 0;
9843   u8 is_ipv6 = 0;
9844   u8 vrf_id_set = 0;
9845   u8 src = 0;
9846   u8 dst = 0;
9847   u8 sport = 0;
9848   u8 dport = 0;
9849   u8 proto = 0;
9850   u8 reverse = 0;
9851   int ret;
9852
9853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9854     {
9855       if (unformat (i, "vrf %d", &vrf_id))
9856         vrf_id_set = 1;
9857       else if (unformat (i, "ipv6"))
9858         is_ipv6 = 1;
9859       else if (unformat (i, "src"))
9860         src = 1;
9861       else if (unformat (i, "dst"))
9862         dst = 1;
9863       else if (unformat (i, "sport"))
9864         sport = 1;
9865       else if (unformat (i, "dport"))
9866         dport = 1;
9867       else if (unformat (i, "proto"))
9868         proto = 1;
9869       else if (unformat (i, "reverse"))
9870         reverse = 1;
9871
9872       else
9873         {
9874           clib_warning ("parse error '%U'", format_unformat_error, i);
9875           return -99;
9876         }
9877     }
9878
9879   if (vrf_id_set == 0)
9880     {
9881       errmsg ("missing vrf id");
9882       return -99;
9883     }
9884
9885   M (SET_IP_FLOW_HASH, mp);
9886   mp->src = src;
9887   mp->dst = dst;
9888   mp->sport = sport;
9889   mp->dport = dport;
9890   mp->proto = proto;
9891   mp->reverse = reverse;
9892   mp->vrf_id = ntohl (vrf_id);
9893   mp->is_ipv6 = is_ipv6;
9894
9895   S (mp);
9896   W (ret);
9897   return ret;
9898 }
9899
9900 static int
9901 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9902 {
9903   unformat_input_t *i = vam->input;
9904   vl_api_sw_interface_ip6_enable_disable_t *mp;
9905   u32 sw_if_index;
9906   u8 sw_if_index_set = 0;
9907   u8 enable = 0;
9908   int ret;
9909
9910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9911     {
9912       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9913         sw_if_index_set = 1;
9914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9915         sw_if_index_set = 1;
9916       else if (unformat (i, "enable"))
9917         enable = 1;
9918       else if (unformat (i, "disable"))
9919         enable = 0;
9920       else
9921         {
9922           clib_warning ("parse error '%U'", format_unformat_error, i);
9923           return -99;
9924         }
9925     }
9926
9927   if (sw_if_index_set == 0)
9928     {
9929       errmsg ("missing interface name or sw_if_index");
9930       return -99;
9931     }
9932
9933   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9934
9935   mp->sw_if_index = ntohl (sw_if_index);
9936   mp->enable = enable;
9937
9938   S (mp);
9939   W (ret);
9940   return ret;
9941 }
9942
9943 static int
9944 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9945 {
9946   unformat_input_t *i = vam->input;
9947   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9948   u32 sw_if_index;
9949   u8 sw_if_index_set = 0;
9950   u8 v6_address_set = 0;
9951   ip6_address_t v6address;
9952   int ret;
9953
9954   /* Parse args required to build the message */
9955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9956     {
9957       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9958         sw_if_index_set = 1;
9959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9960         sw_if_index_set = 1;
9961       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9962         v6_address_set = 1;
9963       else
9964         break;
9965     }
9966
9967   if (sw_if_index_set == 0)
9968     {
9969       errmsg ("missing interface name or sw_if_index");
9970       return -99;
9971     }
9972   if (!v6_address_set)
9973     {
9974       errmsg ("no address set");
9975       return -99;
9976     }
9977
9978   /* Construct the API message */
9979   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9980
9981   mp->sw_if_index = ntohl (sw_if_index);
9982   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9983
9984   /* send it... */
9985   S (mp);
9986
9987   /* Wait for a reply, return good/bad news  */
9988   W (ret);
9989   return ret;
9990 }
9991
9992 static int
9993 api_ip6nd_proxy_add_del (vat_main_t * vam)
9994 {
9995   unformat_input_t *i = vam->input;
9996   vl_api_ip6nd_proxy_add_del_t *mp;
9997   u32 sw_if_index = ~0;
9998   u8 v6_address_set = 0;
9999   ip6_address_t v6address;
10000   u8 is_del = 0;
10001   int ret;
10002
10003   /* Parse args required to build the message */
10004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10005     {
10006       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10007         ;
10008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10009         ;
10010       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10011         v6_address_set = 1;
10012       if (unformat (i, "del"))
10013         is_del = 1;
10014       else
10015         {
10016           clib_warning ("parse error '%U'", format_unformat_error, i);
10017           return -99;
10018         }
10019     }
10020
10021   if (sw_if_index == ~0)
10022     {
10023       errmsg ("missing interface name or sw_if_index");
10024       return -99;
10025     }
10026   if (!v6_address_set)
10027     {
10028       errmsg ("no address set");
10029       return -99;
10030     }
10031
10032   /* Construct the API message */
10033   M (IP6ND_PROXY_ADD_DEL, mp);
10034
10035   mp->is_del = is_del;
10036   mp->sw_if_index = ntohl (sw_if_index);
10037   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10038
10039   /* send it... */
10040   S (mp);
10041
10042   /* Wait for a reply, return good/bad news  */
10043   W (ret);
10044   return ret;
10045 }
10046
10047 static int
10048 api_ip6nd_proxy_dump (vat_main_t * vam)
10049 {
10050   vl_api_ip6nd_proxy_dump_t *mp;
10051   vl_api_control_ping_t *mp_ping;
10052   int ret;
10053
10054   M (IP6ND_PROXY_DUMP, mp);
10055
10056   S (mp);
10057
10058   /* Use a control ping for synchronization */
10059   MPING (CONTROL_PING, mp_ping);
10060   S (mp_ping);
10061
10062   W (ret);
10063   return ret;
10064 }
10065
10066 static void vl_api_ip6nd_proxy_details_t_handler
10067   (vl_api_ip6nd_proxy_details_t * mp)
10068 {
10069   vat_main_t *vam = &vat_main;
10070
10071   print (vam->ofp, "host %U sw_if_index %d",
10072          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10073 }
10074
10075 static void vl_api_ip6nd_proxy_details_t_handler_json
10076   (vl_api_ip6nd_proxy_details_t * mp)
10077 {
10078   vat_main_t *vam = &vat_main;
10079   struct in6_addr ip6;
10080   vat_json_node_t *node = NULL;
10081
10082   if (VAT_JSON_ARRAY != vam->json_tree.type)
10083     {
10084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10085       vat_json_init_array (&vam->json_tree);
10086     }
10087   node = vat_json_array_add (&vam->json_tree);
10088
10089   vat_json_init_object (node);
10090   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10091
10092   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10093   vat_json_object_add_ip6 (node, "host", ip6);
10094 }
10095
10096 static int
10097 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10098 {
10099   unformat_input_t *i = vam->input;
10100   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10101   u32 sw_if_index;
10102   u8 sw_if_index_set = 0;
10103   u32 address_length = 0;
10104   u8 v6_address_set = 0;
10105   ip6_address_t v6address;
10106   u8 use_default = 0;
10107   u8 no_advertise = 0;
10108   u8 off_link = 0;
10109   u8 no_autoconfig = 0;
10110   u8 no_onlink = 0;
10111   u8 is_no = 0;
10112   u32 val_lifetime = 0;
10113   u32 pref_lifetime = 0;
10114   int ret;
10115
10116   /* Parse args required to build the message */
10117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10118     {
10119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10120         sw_if_index_set = 1;
10121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10122         sw_if_index_set = 1;
10123       else if (unformat (i, "%U/%d",
10124                          unformat_ip6_address, &v6address, &address_length))
10125         v6_address_set = 1;
10126       else if (unformat (i, "val_life %d", &val_lifetime))
10127         ;
10128       else if (unformat (i, "pref_life %d", &pref_lifetime))
10129         ;
10130       else if (unformat (i, "def"))
10131         use_default = 1;
10132       else if (unformat (i, "noadv"))
10133         no_advertise = 1;
10134       else if (unformat (i, "offl"))
10135         off_link = 1;
10136       else if (unformat (i, "noauto"))
10137         no_autoconfig = 1;
10138       else if (unformat (i, "nolink"))
10139         no_onlink = 1;
10140       else if (unformat (i, "isno"))
10141         is_no = 1;
10142       else
10143         {
10144           clib_warning ("parse error '%U'", format_unformat_error, i);
10145           return -99;
10146         }
10147     }
10148
10149   if (sw_if_index_set == 0)
10150     {
10151       errmsg ("missing interface name or sw_if_index");
10152       return -99;
10153     }
10154   if (!v6_address_set)
10155     {
10156       errmsg ("no address set");
10157       return -99;
10158     }
10159
10160   /* Construct the API message */
10161   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10162
10163   mp->sw_if_index = ntohl (sw_if_index);
10164   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10165   mp->address_length = address_length;
10166   mp->use_default = use_default;
10167   mp->no_advertise = no_advertise;
10168   mp->off_link = off_link;
10169   mp->no_autoconfig = no_autoconfig;
10170   mp->no_onlink = no_onlink;
10171   mp->is_no = is_no;
10172   mp->val_lifetime = ntohl (val_lifetime);
10173   mp->pref_lifetime = ntohl (pref_lifetime);
10174
10175   /* send it... */
10176   S (mp);
10177
10178   /* Wait for a reply, return good/bad news  */
10179   W (ret);
10180   return ret;
10181 }
10182
10183 static int
10184 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10185 {
10186   unformat_input_t *i = vam->input;
10187   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10188   u32 sw_if_index;
10189   u8 sw_if_index_set = 0;
10190   u8 suppress = 0;
10191   u8 managed = 0;
10192   u8 other = 0;
10193   u8 ll_option = 0;
10194   u8 send_unicast = 0;
10195   u8 cease = 0;
10196   u8 is_no = 0;
10197   u8 default_router = 0;
10198   u32 max_interval = 0;
10199   u32 min_interval = 0;
10200   u32 lifetime = 0;
10201   u32 initial_count = 0;
10202   u32 initial_interval = 0;
10203   int ret;
10204
10205
10206   /* Parse args required to build the message */
10207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10208     {
10209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10210         sw_if_index_set = 1;
10211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10212         sw_if_index_set = 1;
10213       else if (unformat (i, "maxint %d", &max_interval))
10214         ;
10215       else if (unformat (i, "minint %d", &min_interval))
10216         ;
10217       else if (unformat (i, "life %d", &lifetime))
10218         ;
10219       else if (unformat (i, "count %d", &initial_count))
10220         ;
10221       else if (unformat (i, "interval %d", &initial_interval))
10222         ;
10223       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10224         suppress = 1;
10225       else if (unformat (i, "managed"))
10226         managed = 1;
10227       else if (unformat (i, "other"))
10228         other = 1;
10229       else if (unformat (i, "ll"))
10230         ll_option = 1;
10231       else if (unformat (i, "send"))
10232         send_unicast = 1;
10233       else if (unformat (i, "cease"))
10234         cease = 1;
10235       else if (unformat (i, "isno"))
10236         is_no = 1;
10237       else if (unformat (i, "def"))
10238         default_router = 1;
10239       else
10240         {
10241           clib_warning ("parse error '%U'", format_unformat_error, i);
10242           return -99;
10243         }
10244     }
10245
10246   if (sw_if_index_set == 0)
10247     {
10248       errmsg ("missing interface name or sw_if_index");
10249       return -99;
10250     }
10251
10252   /* Construct the API message */
10253   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10254
10255   mp->sw_if_index = ntohl (sw_if_index);
10256   mp->max_interval = ntohl (max_interval);
10257   mp->min_interval = ntohl (min_interval);
10258   mp->lifetime = ntohl (lifetime);
10259   mp->initial_count = ntohl (initial_count);
10260   mp->initial_interval = ntohl (initial_interval);
10261   mp->suppress = suppress;
10262   mp->managed = managed;
10263   mp->other = other;
10264   mp->ll_option = ll_option;
10265   mp->send_unicast = send_unicast;
10266   mp->cease = cease;
10267   mp->is_no = is_no;
10268   mp->default_router = default_router;
10269
10270   /* send it... */
10271   S (mp);
10272
10273   /* Wait for a reply, return good/bad news  */
10274   W (ret);
10275   return ret;
10276 }
10277
10278 static int
10279 api_set_arp_neighbor_limit (vat_main_t * vam)
10280 {
10281   unformat_input_t *i = vam->input;
10282   vl_api_set_arp_neighbor_limit_t *mp;
10283   u32 arp_nbr_limit;
10284   u8 limit_set = 0;
10285   u8 is_ipv6 = 0;
10286   int ret;
10287
10288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10289     {
10290       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10291         limit_set = 1;
10292       else if (unformat (i, "ipv6"))
10293         is_ipv6 = 1;
10294       else
10295         {
10296           clib_warning ("parse error '%U'", format_unformat_error, i);
10297           return -99;
10298         }
10299     }
10300
10301   if (limit_set == 0)
10302     {
10303       errmsg ("missing limit value");
10304       return -99;
10305     }
10306
10307   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10308
10309   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10310   mp->is_ipv6 = is_ipv6;
10311
10312   S (mp);
10313   W (ret);
10314   return ret;
10315 }
10316
10317 static int
10318 api_l2_patch_add_del (vat_main_t * vam)
10319 {
10320   unformat_input_t *i = vam->input;
10321   vl_api_l2_patch_add_del_t *mp;
10322   u32 rx_sw_if_index;
10323   u8 rx_sw_if_index_set = 0;
10324   u32 tx_sw_if_index;
10325   u8 tx_sw_if_index_set = 0;
10326   u8 is_add = 1;
10327   int ret;
10328
10329   /* Parse args required to build the message */
10330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10331     {
10332       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10333         rx_sw_if_index_set = 1;
10334       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10335         tx_sw_if_index_set = 1;
10336       else if (unformat (i, "rx"))
10337         {
10338           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10339             {
10340               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10341                             &rx_sw_if_index))
10342                 rx_sw_if_index_set = 1;
10343             }
10344           else
10345             break;
10346         }
10347       else if (unformat (i, "tx"))
10348         {
10349           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10350             {
10351               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10352                             &tx_sw_if_index))
10353                 tx_sw_if_index_set = 1;
10354             }
10355           else
10356             break;
10357         }
10358       else if (unformat (i, "del"))
10359         is_add = 0;
10360       else
10361         break;
10362     }
10363
10364   if (rx_sw_if_index_set == 0)
10365     {
10366       errmsg ("missing rx interface name or rx_sw_if_index");
10367       return -99;
10368     }
10369
10370   if (tx_sw_if_index_set == 0)
10371     {
10372       errmsg ("missing tx interface name or tx_sw_if_index");
10373       return -99;
10374     }
10375
10376   M (L2_PATCH_ADD_DEL, mp);
10377
10378   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10379   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10380   mp->is_add = is_add;
10381
10382   S (mp);
10383   W (ret);
10384   return ret;
10385 }
10386
10387 u8 is_del;
10388 u8 localsid_addr[16];
10389 u8 end_psp;
10390 u8 behavior;
10391 u32 sw_if_index;
10392 u32 vlan_index;
10393 u32 fib_table;
10394 u8 nh_addr[16];
10395
10396 static int
10397 api_sr_localsid_add_del (vat_main_t * vam)
10398 {
10399   unformat_input_t *i = vam->input;
10400   vl_api_sr_localsid_add_del_t *mp;
10401
10402   u8 is_del;
10403   ip6_address_t localsid;
10404   u8 end_psp = 0;
10405   u8 behavior = ~0;
10406   u32 sw_if_index;
10407   u32 fib_table = ~(u32) 0;
10408   ip6_address_t next_hop;
10409
10410   bool nexthop_set = 0;
10411
10412   int ret;
10413
10414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10415     {
10416       if (unformat (i, "del"))
10417         is_del = 1;
10418       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10419       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10420         nexthop_set = 1;
10421       else if (unformat (i, "behavior %u", &behavior));
10422       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10423       else if (unformat (i, "fib-table %u", &fib_table));
10424       else if (unformat (i, "end.psp %u", &behavior));
10425       else
10426         break;
10427     }
10428
10429   M (SR_LOCALSID_ADD_DEL, mp);
10430
10431   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10432   if (nexthop_set)
10433     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10434   mp->behavior = behavior;
10435   mp->sw_if_index = ntohl (sw_if_index);
10436   mp->fib_table = ntohl (fib_table);
10437   mp->end_psp = end_psp;
10438   mp->is_del = is_del;
10439
10440   S (mp);
10441   W (ret);
10442   return ret;
10443 }
10444
10445 static int
10446 api_ioam_enable (vat_main_t * vam)
10447 {
10448   unformat_input_t *input = vam->input;
10449   vl_api_ioam_enable_t *mp;
10450   u32 id = 0;
10451   int has_trace_option = 0;
10452   int has_pot_option = 0;
10453   int has_seqno_option = 0;
10454   int has_analyse_option = 0;
10455   int ret;
10456
10457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10458     {
10459       if (unformat (input, "trace"))
10460         has_trace_option = 1;
10461       else if (unformat (input, "pot"))
10462         has_pot_option = 1;
10463       else if (unformat (input, "seqno"))
10464         has_seqno_option = 1;
10465       else if (unformat (input, "analyse"))
10466         has_analyse_option = 1;
10467       else
10468         break;
10469     }
10470   M (IOAM_ENABLE, mp);
10471   mp->id = htons (id);
10472   mp->seqno = has_seqno_option;
10473   mp->analyse = has_analyse_option;
10474   mp->pot_enable = has_pot_option;
10475   mp->trace_enable = has_trace_option;
10476
10477   S (mp);
10478   W (ret);
10479   return ret;
10480 }
10481
10482
10483 static int
10484 api_ioam_disable (vat_main_t * vam)
10485 {
10486   vl_api_ioam_disable_t *mp;
10487   int ret;
10488
10489   M (IOAM_DISABLE, mp);
10490   S (mp);
10491   W (ret);
10492   return ret;
10493 }
10494
10495 #define foreach_tcp_proto_field                 \
10496 _(src_port)                                     \
10497 _(dst_port)
10498
10499 #define foreach_udp_proto_field                 \
10500 _(src_port)                                     \
10501 _(dst_port)
10502
10503 #define foreach_ip4_proto_field                 \
10504 _(src_address)                                  \
10505 _(dst_address)                                  \
10506 _(tos)                                          \
10507 _(length)                                       \
10508 _(fragment_id)                                  \
10509 _(ttl)                                          \
10510 _(protocol)                                     \
10511 _(checksum)
10512
10513 typedef struct
10514 {
10515   u16 src_port, dst_port;
10516 } tcpudp_header_t;
10517
10518 #if VPP_API_TEST_BUILTIN == 0
10519 uword
10520 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10521 {
10522   u8 **maskp = va_arg (*args, u8 **);
10523   u8 *mask = 0;
10524   u8 found_something = 0;
10525   tcp_header_t *tcp;
10526
10527 #define _(a) u8 a=0;
10528   foreach_tcp_proto_field;
10529 #undef _
10530
10531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10532     {
10533       if (0);
10534 #define _(a) else if (unformat (input, #a)) a=1;
10535       foreach_tcp_proto_field
10536 #undef _
10537         else
10538         break;
10539     }
10540
10541 #define _(a) found_something += a;
10542   foreach_tcp_proto_field;
10543 #undef _
10544
10545   if (found_something == 0)
10546     return 0;
10547
10548   vec_validate (mask, sizeof (*tcp) - 1);
10549
10550   tcp = (tcp_header_t *) mask;
10551
10552 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10553   foreach_tcp_proto_field;
10554 #undef _
10555
10556   *maskp = mask;
10557   return 1;
10558 }
10559
10560 uword
10561 unformat_udp_mask (unformat_input_t * input, va_list * args)
10562 {
10563   u8 **maskp = va_arg (*args, u8 **);
10564   u8 *mask = 0;
10565   u8 found_something = 0;
10566   udp_header_t *udp;
10567
10568 #define _(a) u8 a=0;
10569   foreach_udp_proto_field;
10570 #undef _
10571
10572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10573     {
10574       if (0);
10575 #define _(a) else if (unformat (input, #a)) a=1;
10576       foreach_udp_proto_field
10577 #undef _
10578         else
10579         break;
10580     }
10581
10582 #define _(a) found_something += a;
10583   foreach_udp_proto_field;
10584 #undef _
10585
10586   if (found_something == 0)
10587     return 0;
10588
10589   vec_validate (mask, sizeof (*udp) - 1);
10590
10591   udp = (udp_header_t *) mask;
10592
10593 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10594   foreach_udp_proto_field;
10595 #undef _
10596
10597   *maskp = mask;
10598   return 1;
10599 }
10600
10601 uword
10602 unformat_l4_mask (unformat_input_t * input, va_list * args)
10603 {
10604   u8 **maskp = va_arg (*args, u8 **);
10605   u16 src_port = 0, dst_port = 0;
10606   tcpudp_header_t *tcpudp;
10607
10608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10609     {
10610       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10611         return 1;
10612       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10613         return 1;
10614       else if (unformat (input, "src_port"))
10615         src_port = 0xFFFF;
10616       else if (unformat (input, "dst_port"))
10617         dst_port = 0xFFFF;
10618       else
10619         return 0;
10620     }
10621
10622   if (!src_port && !dst_port)
10623     return 0;
10624
10625   u8 *mask = 0;
10626   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10627
10628   tcpudp = (tcpudp_header_t *) mask;
10629   tcpudp->src_port = src_port;
10630   tcpudp->dst_port = dst_port;
10631
10632   *maskp = mask;
10633
10634   return 1;
10635 }
10636
10637 uword
10638 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10639 {
10640   u8 **maskp = va_arg (*args, u8 **);
10641   u8 *mask = 0;
10642   u8 found_something = 0;
10643   ip4_header_t *ip;
10644
10645 #define _(a) u8 a=0;
10646   foreach_ip4_proto_field;
10647 #undef _
10648   u8 version = 0;
10649   u8 hdr_length = 0;
10650
10651
10652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10653     {
10654       if (unformat (input, "version"))
10655         version = 1;
10656       else if (unformat (input, "hdr_length"))
10657         hdr_length = 1;
10658       else if (unformat (input, "src"))
10659         src_address = 1;
10660       else if (unformat (input, "dst"))
10661         dst_address = 1;
10662       else if (unformat (input, "proto"))
10663         protocol = 1;
10664
10665 #define _(a) else if (unformat (input, #a)) a=1;
10666       foreach_ip4_proto_field
10667 #undef _
10668         else
10669         break;
10670     }
10671
10672 #define _(a) found_something += a;
10673   foreach_ip4_proto_field;
10674 #undef _
10675
10676   if (found_something == 0)
10677     return 0;
10678
10679   vec_validate (mask, sizeof (*ip) - 1);
10680
10681   ip = (ip4_header_t *) mask;
10682
10683 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10684   foreach_ip4_proto_field;
10685 #undef _
10686
10687   ip->ip_version_and_header_length = 0;
10688
10689   if (version)
10690     ip->ip_version_and_header_length |= 0xF0;
10691
10692   if (hdr_length)
10693     ip->ip_version_and_header_length |= 0x0F;
10694
10695   *maskp = mask;
10696   return 1;
10697 }
10698
10699 #define foreach_ip6_proto_field                 \
10700 _(src_address)                                  \
10701 _(dst_address)                                  \
10702 _(payload_length)                               \
10703 _(hop_limit)                                    \
10704 _(protocol)
10705
10706 uword
10707 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10708 {
10709   u8 **maskp = va_arg (*args, u8 **);
10710   u8 *mask = 0;
10711   u8 found_something = 0;
10712   ip6_header_t *ip;
10713   u32 ip_version_traffic_class_and_flow_label;
10714
10715 #define _(a) u8 a=0;
10716   foreach_ip6_proto_field;
10717 #undef _
10718   u8 version = 0;
10719   u8 traffic_class = 0;
10720   u8 flow_label = 0;
10721
10722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10723     {
10724       if (unformat (input, "version"))
10725         version = 1;
10726       else if (unformat (input, "traffic-class"))
10727         traffic_class = 1;
10728       else if (unformat (input, "flow-label"))
10729         flow_label = 1;
10730       else if (unformat (input, "src"))
10731         src_address = 1;
10732       else if (unformat (input, "dst"))
10733         dst_address = 1;
10734       else if (unformat (input, "proto"))
10735         protocol = 1;
10736
10737 #define _(a) else if (unformat (input, #a)) a=1;
10738       foreach_ip6_proto_field
10739 #undef _
10740         else
10741         break;
10742     }
10743
10744 #define _(a) found_something += a;
10745   foreach_ip6_proto_field;
10746 #undef _
10747
10748   if (found_something == 0)
10749     return 0;
10750
10751   vec_validate (mask, sizeof (*ip) - 1);
10752
10753   ip = (ip6_header_t *) mask;
10754
10755 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10756   foreach_ip6_proto_field;
10757 #undef _
10758
10759   ip_version_traffic_class_and_flow_label = 0;
10760
10761   if (version)
10762     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10763
10764   if (traffic_class)
10765     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10766
10767   if (flow_label)
10768     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10769
10770   ip->ip_version_traffic_class_and_flow_label =
10771     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10772
10773   *maskp = mask;
10774   return 1;
10775 }
10776
10777 uword
10778 unformat_l3_mask (unformat_input_t * input, va_list * args)
10779 {
10780   u8 **maskp = va_arg (*args, u8 **);
10781
10782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10783     {
10784       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10785         return 1;
10786       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10787         return 1;
10788       else
10789         break;
10790     }
10791   return 0;
10792 }
10793
10794 uword
10795 unformat_l2_mask (unformat_input_t * input, va_list * args)
10796 {
10797   u8 **maskp = va_arg (*args, u8 **);
10798   u8 *mask = 0;
10799   u8 src = 0;
10800   u8 dst = 0;
10801   u8 proto = 0;
10802   u8 tag1 = 0;
10803   u8 tag2 = 0;
10804   u8 ignore_tag1 = 0;
10805   u8 ignore_tag2 = 0;
10806   u8 cos1 = 0;
10807   u8 cos2 = 0;
10808   u8 dot1q = 0;
10809   u8 dot1ad = 0;
10810   int len = 14;
10811
10812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10813     {
10814       if (unformat (input, "src"))
10815         src = 1;
10816       else if (unformat (input, "dst"))
10817         dst = 1;
10818       else if (unformat (input, "proto"))
10819         proto = 1;
10820       else if (unformat (input, "tag1"))
10821         tag1 = 1;
10822       else if (unformat (input, "tag2"))
10823         tag2 = 1;
10824       else if (unformat (input, "ignore-tag1"))
10825         ignore_tag1 = 1;
10826       else if (unformat (input, "ignore-tag2"))
10827         ignore_tag2 = 1;
10828       else if (unformat (input, "cos1"))
10829         cos1 = 1;
10830       else if (unformat (input, "cos2"))
10831         cos2 = 1;
10832       else if (unformat (input, "dot1q"))
10833         dot1q = 1;
10834       else if (unformat (input, "dot1ad"))
10835         dot1ad = 1;
10836       else
10837         break;
10838     }
10839   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10840        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10841     return 0;
10842
10843   if (tag1 || ignore_tag1 || cos1 || dot1q)
10844     len = 18;
10845   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10846     len = 22;
10847
10848   vec_validate (mask, len - 1);
10849
10850   if (dst)
10851     memset (mask, 0xff, 6);
10852
10853   if (src)
10854     memset (mask + 6, 0xff, 6);
10855
10856   if (tag2 || dot1ad)
10857     {
10858       /* inner vlan tag */
10859       if (tag2)
10860         {
10861           mask[19] = 0xff;
10862           mask[18] = 0x0f;
10863         }
10864       if (cos2)
10865         mask[18] |= 0xe0;
10866       if (proto)
10867         mask[21] = mask[20] = 0xff;
10868       if (tag1)
10869         {
10870           mask[15] = 0xff;
10871           mask[14] = 0x0f;
10872         }
10873       if (cos1)
10874         mask[14] |= 0xe0;
10875       *maskp = mask;
10876       return 1;
10877     }
10878   if (tag1 | dot1q)
10879     {
10880       if (tag1)
10881         {
10882           mask[15] = 0xff;
10883           mask[14] = 0x0f;
10884         }
10885       if (cos1)
10886         mask[14] |= 0xe0;
10887       if (proto)
10888         mask[16] = mask[17] = 0xff;
10889
10890       *maskp = mask;
10891       return 1;
10892     }
10893   if (cos2)
10894     mask[18] |= 0xe0;
10895   if (cos1)
10896     mask[14] |= 0xe0;
10897   if (proto)
10898     mask[12] = mask[13] = 0xff;
10899
10900   *maskp = mask;
10901   return 1;
10902 }
10903
10904 uword
10905 unformat_classify_mask (unformat_input_t * input, va_list * args)
10906 {
10907   u8 **maskp = va_arg (*args, u8 **);
10908   u32 *skipp = va_arg (*args, u32 *);
10909   u32 *matchp = va_arg (*args, u32 *);
10910   u32 match;
10911   u8 *mask = 0;
10912   u8 *l2 = 0;
10913   u8 *l3 = 0;
10914   u8 *l4 = 0;
10915   int i;
10916
10917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10918     {
10919       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10920         ;
10921       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10922         ;
10923       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10924         ;
10925       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10926         ;
10927       else
10928         break;
10929     }
10930
10931   if (l4 && !l3)
10932     {
10933       vec_free (mask);
10934       vec_free (l2);
10935       vec_free (l4);
10936       return 0;
10937     }
10938
10939   if (mask || l2 || l3 || l4)
10940     {
10941       if (l2 || l3 || l4)
10942         {
10943           /* "With a free Ethernet header in every package" */
10944           if (l2 == 0)
10945             vec_validate (l2, 13);
10946           mask = l2;
10947           if (vec_len (l3))
10948             {
10949               vec_append (mask, l3);
10950               vec_free (l3);
10951             }
10952           if (vec_len (l4))
10953             {
10954               vec_append (mask, l4);
10955               vec_free (l4);
10956             }
10957         }
10958
10959       /* Scan forward looking for the first significant mask octet */
10960       for (i = 0; i < vec_len (mask); i++)
10961         if (mask[i])
10962           break;
10963
10964       /* compute (skip, match) params */
10965       *skipp = i / sizeof (u32x4);
10966       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10967
10968       /* Pad mask to an even multiple of the vector size */
10969       while (vec_len (mask) % sizeof (u32x4))
10970         vec_add1 (mask, 0);
10971
10972       match = vec_len (mask) / sizeof (u32x4);
10973
10974       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10975         {
10976           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10977           if (*tmp || *(tmp + 1))
10978             break;
10979           match--;
10980         }
10981       if (match == 0)
10982         clib_warning ("BUG: match 0");
10983
10984       _vec_len (mask) = match * sizeof (u32x4);
10985
10986       *matchp = match;
10987       *maskp = mask;
10988
10989       return 1;
10990     }
10991
10992   return 0;
10993 }
10994 #endif /* VPP_API_TEST_BUILTIN */
10995
10996 #define foreach_l2_next                         \
10997 _(drop, DROP)                                   \
10998 _(ethernet, ETHERNET_INPUT)                     \
10999 _(ip4, IP4_INPUT)                               \
11000 _(ip6, IP6_INPUT)
11001
11002 uword
11003 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11004 {
11005   u32 *miss_next_indexp = va_arg (*args, u32 *);
11006   u32 next_index = 0;
11007   u32 tmp;
11008
11009 #define _(n,N) \
11010   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11011   foreach_l2_next;
11012 #undef _
11013
11014   if (unformat (input, "%d", &tmp))
11015     {
11016       next_index = tmp;
11017       goto out;
11018     }
11019
11020   return 0;
11021
11022 out:
11023   *miss_next_indexp = next_index;
11024   return 1;
11025 }
11026
11027 #define foreach_ip_next                         \
11028 _(drop, DROP)                                   \
11029 _(local, LOCAL)                                 \
11030 _(rewrite, REWRITE)
11031
11032 uword
11033 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11034 {
11035   u32 *miss_next_indexp = va_arg (*args, u32 *);
11036   u32 next_index = 0;
11037   u32 tmp;
11038
11039 #define _(n,N) \
11040   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11041   foreach_ip_next;
11042 #undef _
11043
11044   if (unformat (input, "%d", &tmp))
11045     {
11046       next_index = tmp;
11047       goto out;
11048     }
11049
11050   return 0;
11051
11052 out:
11053   *miss_next_indexp = next_index;
11054   return 1;
11055 }
11056
11057 #define foreach_acl_next                        \
11058 _(deny, DENY)
11059
11060 uword
11061 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11062 {
11063   u32 *miss_next_indexp = va_arg (*args, u32 *);
11064   u32 next_index = 0;
11065   u32 tmp;
11066
11067 #define _(n,N) \
11068   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11069   foreach_acl_next;
11070 #undef _
11071
11072   if (unformat (input, "permit"))
11073     {
11074       next_index = ~0;
11075       goto out;
11076     }
11077   else if (unformat (input, "%d", &tmp))
11078     {
11079       next_index = tmp;
11080       goto out;
11081     }
11082
11083   return 0;
11084
11085 out:
11086   *miss_next_indexp = next_index;
11087   return 1;
11088 }
11089
11090 uword
11091 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11092 {
11093   u32 *r = va_arg (*args, u32 *);
11094
11095   if (unformat (input, "conform-color"))
11096     *r = POLICE_CONFORM;
11097   else if (unformat (input, "exceed-color"))
11098     *r = POLICE_EXCEED;
11099   else
11100     return 0;
11101
11102   return 1;
11103 }
11104
11105 static int
11106 api_classify_add_del_table (vat_main_t * vam)
11107 {
11108   unformat_input_t *i = vam->input;
11109   vl_api_classify_add_del_table_t *mp;
11110
11111   u32 nbuckets = 2;
11112   u32 skip = ~0;
11113   u32 match = ~0;
11114   int is_add = 1;
11115   int del_chain = 0;
11116   u32 table_index = ~0;
11117   u32 next_table_index = ~0;
11118   u32 miss_next_index = ~0;
11119   u32 memory_size = 32 << 20;
11120   u8 *mask = 0;
11121   u32 current_data_flag = 0;
11122   int current_data_offset = 0;
11123   int ret;
11124
11125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11126     {
11127       if (unformat (i, "del"))
11128         is_add = 0;
11129       else if (unformat (i, "del-chain"))
11130         {
11131           is_add = 0;
11132           del_chain = 1;
11133         }
11134       else if (unformat (i, "buckets %d", &nbuckets))
11135         ;
11136       else if (unformat (i, "memory_size %d", &memory_size))
11137         ;
11138       else if (unformat (i, "skip %d", &skip))
11139         ;
11140       else if (unformat (i, "match %d", &match))
11141         ;
11142       else if (unformat (i, "table %d", &table_index))
11143         ;
11144       else if (unformat (i, "mask %U", unformat_classify_mask,
11145                          &mask, &skip, &match))
11146         ;
11147       else if (unformat (i, "next-table %d", &next_table_index))
11148         ;
11149       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11150                          &miss_next_index))
11151         ;
11152       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11153                          &miss_next_index))
11154         ;
11155       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11156                          &miss_next_index))
11157         ;
11158       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11159         ;
11160       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11161         ;
11162       else
11163         break;
11164     }
11165
11166   if (is_add && mask == 0)
11167     {
11168       errmsg ("Mask required");
11169       return -99;
11170     }
11171
11172   if (is_add && skip == ~0)
11173     {
11174       errmsg ("skip count required");
11175       return -99;
11176     }
11177
11178   if (is_add && match == ~0)
11179     {
11180       errmsg ("match count required");
11181       return -99;
11182     }
11183
11184   if (!is_add && table_index == ~0)
11185     {
11186       errmsg ("table index required for delete");
11187       return -99;
11188     }
11189
11190   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11191
11192   mp->is_add = is_add;
11193   mp->del_chain = del_chain;
11194   mp->table_index = ntohl (table_index);
11195   mp->nbuckets = ntohl (nbuckets);
11196   mp->memory_size = ntohl (memory_size);
11197   mp->skip_n_vectors = ntohl (skip);
11198   mp->match_n_vectors = ntohl (match);
11199   mp->next_table_index = ntohl (next_table_index);
11200   mp->miss_next_index = ntohl (miss_next_index);
11201   mp->current_data_flag = ntohl (current_data_flag);
11202   mp->current_data_offset = ntohl (current_data_offset);
11203   clib_memcpy (mp->mask, mask, vec_len (mask));
11204
11205   vec_free (mask);
11206
11207   S (mp);
11208   W (ret);
11209   return ret;
11210 }
11211
11212 #if VPP_API_TEST_BUILTIN == 0
11213 uword
11214 unformat_l4_match (unformat_input_t * input, va_list * args)
11215 {
11216   u8 **matchp = va_arg (*args, u8 **);
11217
11218   u8 *proto_header = 0;
11219   int src_port = 0;
11220   int dst_port = 0;
11221
11222   tcpudp_header_t h;
11223
11224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11225     {
11226       if (unformat (input, "src_port %d", &src_port))
11227         ;
11228       else if (unformat (input, "dst_port %d", &dst_port))
11229         ;
11230       else
11231         return 0;
11232     }
11233
11234   h.src_port = clib_host_to_net_u16 (src_port);
11235   h.dst_port = clib_host_to_net_u16 (dst_port);
11236   vec_validate (proto_header, sizeof (h) - 1);
11237   memcpy (proto_header, &h, sizeof (h));
11238
11239   *matchp = proto_header;
11240
11241   return 1;
11242 }
11243
11244 uword
11245 unformat_ip4_match (unformat_input_t * input, va_list * args)
11246 {
11247   u8 **matchp = va_arg (*args, u8 **);
11248   u8 *match = 0;
11249   ip4_header_t *ip;
11250   int version = 0;
11251   u32 version_val;
11252   int hdr_length = 0;
11253   u32 hdr_length_val;
11254   int src = 0, dst = 0;
11255   ip4_address_t src_val, dst_val;
11256   int proto = 0;
11257   u32 proto_val;
11258   int tos = 0;
11259   u32 tos_val;
11260   int length = 0;
11261   u32 length_val;
11262   int fragment_id = 0;
11263   u32 fragment_id_val;
11264   int ttl = 0;
11265   int ttl_val;
11266   int checksum = 0;
11267   u32 checksum_val;
11268
11269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11270     {
11271       if (unformat (input, "version %d", &version_val))
11272         version = 1;
11273       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11274         hdr_length = 1;
11275       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11276         src = 1;
11277       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11278         dst = 1;
11279       else if (unformat (input, "proto %d", &proto_val))
11280         proto = 1;
11281       else if (unformat (input, "tos %d", &tos_val))
11282         tos = 1;
11283       else if (unformat (input, "length %d", &length_val))
11284         length = 1;
11285       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11286         fragment_id = 1;
11287       else if (unformat (input, "ttl %d", &ttl_val))
11288         ttl = 1;
11289       else if (unformat (input, "checksum %d", &checksum_val))
11290         checksum = 1;
11291       else
11292         break;
11293     }
11294
11295   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11296       + ttl + checksum == 0)
11297     return 0;
11298
11299   /*
11300    * Aligned because we use the real comparison functions
11301    */
11302   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11303
11304   ip = (ip4_header_t *) match;
11305
11306   /* These are realistically matched in practice */
11307   if (src)
11308     ip->src_address.as_u32 = src_val.as_u32;
11309
11310   if (dst)
11311     ip->dst_address.as_u32 = dst_val.as_u32;
11312
11313   if (proto)
11314     ip->protocol = proto_val;
11315
11316
11317   /* These are not, but they're included for completeness */
11318   if (version)
11319     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11320
11321   if (hdr_length)
11322     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11323
11324   if (tos)
11325     ip->tos = tos_val;
11326
11327   if (length)
11328     ip->length = clib_host_to_net_u16 (length_val);
11329
11330   if (ttl)
11331     ip->ttl = ttl_val;
11332
11333   if (checksum)
11334     ip->checksum = clib_host_to_net_u16 (checksum_val);
11335
11336   *matchp = match;
11337   return 1;
11338 }
11339
11340 uword
11341 unformat_ip6_match (unformat_input_t * input, va_list * args)
11342 {
11343   u8 **matchp = va_arg (*args, u8 **);
11344   u8 *match = 0;
11345   ip6_header_t *ip;
11346   int version = 0;
11347   u32 version_val;
11348   u8 traffic_class = 0;
11349   u32 traffic_class_val = 0;
11350   u8 flow_label = 0;
11351   u8 flow_label_val;
11352   int src = 0, dst = 0;
11353   ip6_address_t src_val, dst_val;
11354   int proto = 0;
11355   u32 proto_val;
11356   int payload_length = 0;
11357   u32 payload_length_val;
11358   int hop_limit = 0;
11359   int hop_limit_val;
11360   u32 ip_version_traffic_class_and_flow_label;
11361
11362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11363     {
11364       if (unformat (input, "version %d", &version_val))
11365         version = 1;
11366       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11367         traffic_class = 1;
11368       else if (unformat (input, "flow_label %d", &flow_label_val))
11369         flow_label = 1;
11370       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11371         src = 1;
11372       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11373         dst = 1;
11374       else if (unformat (input, "proto %d", &proto_val))
11375         proto = 1;
11376       else if (unformat (input, "payload_length %d", &payload_length_val))
11377         payload_length = 1;
11378       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11379         hop_limit = 1;
11380       else
11381         break;
11382     }
11383
11384   if (version + traffic_class + flow_label + src + dst + proto +
11385       payload_length + hop_limit == 0)
11386     return 0;
11387
11388   /*
11389    * Aligned because we use the real comparison functions
11390    */
11391   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11392
11393   ip = (ip6_header_t *) match;
11394
11395   if (src)
11396     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11397
11398   if (dst)
11399     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11400
11401   if (proto)
11402     ip->protocol = proto_val;
11403
11404   ip_version_traffic_class_and_flow_label = 0;
11405
11406   if (version)
11407     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11408
11409   if (traffic_class)
11410     ip_version_traffic_class_and_flow_label |=
11411       (traffic_class_val & 0xFF) << 20;
11412
11413   if (flow_label)
11414     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11415
11416   ip->ip_version_traffic_class_and_flow_label =
11417     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11418
11419   if (payload_length)
11420     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11421
11422   if (hop_limit)
11423     ip->hop_limit = hop_limit_val;
11424
11425   *matchp = match;
11426   return 1;
11427 }
11428
11429 uword
11430 unformat_l3_match (unformat_input_t * input, va_list * args)
11431 {
11432   u8 **matchp = va_arg (*args, u8 **);
11433
11434   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11435     {
11436       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11437         return 1;
11438       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11439         return 1;
11440       else
11441         break;
11442     }
11443   return 0;
11444 }
11445
11446 uword
11447 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11448 {
11449   u8 *tagp = va_arg (*args, u8 *);
11450   u32 tag;
11451
11452   if (unformat (input, "%d", &tag))
11453     {
11454       tagp[0] = (tag >> 8) & 0x0F;
11455       tagp[1] = tag & 0xFF;
11456       return 1;
11457     }
11458
11459   return 0;
11460 }
11461
11462 uword
11463 unformat_l2_match (unformat_input_t * input, va_list * args)
11464 {
11465   u8 **matchp = va_arg (*args, u8 **);
11466   u8 *match = 0;
11467   u8 src = 0;
11468   u8 src_val[6];
11469   u8 dst = 0;
11470   u8 dst_val[6];
11471   u8 proto = 0;
11472   u16 proto_val;
11473   u8 tag1 = 0;
11474   u8 tag1_val[2];
11475   u8 tag2 = 0;
11476   u8 tag2_val[2];
11477   int len = 14;
11478   u8 ignore_tag1 = 0;
11479   u8 ignore_tag2 = 0;
11480   u8 cos1 = 0;
11481   u8 cos2 = 0;
11482   u32 cos1_val = 0;
11483   u32 cos2_val = 0;
11484
11485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11486     {
11487       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11488         src = 1;
11489       else
11490         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11491         dst = 1;
11492       else if (unformat (input, "proto %U",
11493                          unformat_ethernet_type_host_byte_order, &proto_val))
11494         proto = 1;
11495       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11496         tag1 = 1;
11497       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11498         tag2 = 1;
11499       else if (unformat (input, "ignore-tag1"))
11500         ignore_tag1 = 1;
11501       else if (unformat (input, "ignore-tag2"))
11502         ignore_tag2 = 1;
11503       else if (unformat (input, "cos1 %d", &cos1_val))
11504         cos1 = 1;
11505       else if (unformat (input, "cos2 %d", &cos2_val))
11506         cos2 = 1;
11507       else
11508         break;
11509     }
11510   if ((src + dst + proto + tag1 + tag2 +
11511        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11512     return 0;
11513
11514   if (tag1 || ignore_tag1 || cos1)
11515     len = 18;
11516   if (tag2 || ignore_tag2 || cos2)
11517     len = 22;
11518
11519   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11520
11521   if (dst)
11522     clib_memcpy (match, dst_val, 6);
11523
11524   if (src)
11525     clib_memcpy (match + 6, src_val, 6);
11526
11527   if (tag2)
11528     {
11529       /* inner vlan tag */
11530       match[19] = tag2_val[1];
11531       match[18] = tag2_val[0];
11532       if (cos2)
11533         match[18] |= (cos2_val & 0x7) << 5;
11534       if (proto)
11535         {
11536           match[21] = proto_val & 0xff;
11537           match[20] = proto_val >> 8;
11538         }
11539       if (tag1)
11540         {
11541           match[15] = tag1_val[1];
11542           match[14] = tag1_val[0];
11543         }
11544       if (cos1)
11545         match[14] |= (cos1_val & 0x7) << 5;
11546       *matchp = match;
11547       return 1;
11548     }
11549   if (tag1)
11550     {
11551       match[15] = tag1_val[1];
11552       match[14] = tag1_val[0];
11553       if (proto)
11554         {
11555           match[17] = proto_val & 0xff;
11556           match[16] = proto_val >> 8;
11557         }
11558       if (cos1)
11559         match[14] |= (cos1_val & 0x7) << 5;
11560
11561       *matchp = match;
11562       return 1;
11563     }
11564   if (cos2)
11565     match[18] |= (cos2_val & 0x7) << 5;
11566   if (cos1)
11567     match[14] |= (cos1_val & 0x7) << 5;
11568   if (proto)
11569     {
11570       match[13] = proto_val & 0xff;
11571       match[12] = proto_val >> 8;
11572     }
11573
11574   *matchp = match;
11575   return 1;
11576 }
11577 #endif
11578
11579 uword
11580 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11581 {
11582   u8 **matchp = va_arg (*args, u8 **);
11583   u32 skip_n_vectors = va_arg (*args, u32);
11584   u32 match_n_vectors = va_arg (*args, u32);
11585
11586   u8 *match = 0;
11587   u8 *l2 = 0;
11588   u8 *l3 = 0;
11589   u8 *l4 = 0;
11590
11591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11592     {
11593       if (unformat (input, "hex %U", unformat_hex_string, &match))
11594         ;
11595       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11596         ;
11597       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11598         ;
11599       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11600         ;
11601       else
11602         break;
11603     }
11604
11605   if (l4 && !l3)
11606     {
11607       vec_free (match);
11608       vec_free (l2);
11609       vec_free (l4);
11610       return 0;
11611     }
11612
11613   if (match || l2 || l3 || l4)
11614     {
11615       if (l2 || l3 || l4)
11616         {
11617           /* "Win a free Ethernet header in every packet" */
11618           if (l2 == 0)
11619             vec_validate_aligned (l2, 13, sizeof (u32x4));
11620           match = l2;
11621           if (vec_len (l3))
11622             {
11623               vec_append_aligned (match, l3, sizeof (u32x4));
11624               vec_free (l3);
11625             }
11626           if (vec_len (l4))
11627             {
11628               vec_append_aligned (match, l4, sizeof (u32x4));
11629               vec_free (l4);
11630             }
11631         }
11632
11633       /* Make sure the vector is big enough even if key is all 0's */
11634       vec_validate_aligned
11635         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11636          sizeof (u32x4));
11637
11638       /* Set size, include skipped vectors */
11639       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11640
11641       *matchp = match;
11642
11643       return 1;
11644     }
11645
11646   return 0;
11647 }
11648
11649 static int
11650 api_classify_add_del_session (vat_main_t * vam)
11651 {
11652   unformat_input_t *i = vam->input;
11653   vl_api_classify_add_del_session_t *mp;
11654   int is_add = 1;
11655   u32 table_index = ~0;
11656   u32 hit_next_index = ~0;
11657   u32 opaque_index = ~0;
11658   u8 *match = 0;
11659   i32 advance = 0;
11660   u32 skip_n_vectors = 0;
11661   u32 match_n_vectors = 0;
11662   u32 action = 0;
11663   u32 metadata = 0;
11664   int ret;
11665
11666   /*
11667    * Warning: you have to supply skip_n and match_n
11668    * because the API client cant simply look at the classify
11669    * table object.
11670    */
11671
11672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11673     {
11674       if (unformat (i, "del"))
11675         is_add = 0;
11676       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11677                          &hit_next_index))
11678         ;
11679       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11680                          &hit_next_index))
11681         ;
11682       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11683                          &hit_next_index))
11684         ;
11685       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11686         ;
11687       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11688         ;
11689       else if (unformat (i, "opaque-index %d", &opaque_index))
11690         ;
11691       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11692         ;
11693       else if (unformat (i, "match_n %d", &match_n_vectors))
11694         ;
11695       else if (unformat (i, "match %U", api_unformat_classify_match,
11696                          &match, skip_n_vectors, match_n_vectors))
11697         ;
11698       else if (unformat (i, "advance %d", &advance))
11699         ;
11700       else if (unformat (i, "table-index %d", &table_index))
11701         ;
11702       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11703         action = 1;
11704       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11705         action = 2;
11706       else if (unformat (i, "action %d", &action))
11707         ;
11708       else if (unformat (i, "metadata %d", &metadata))
11709         ;
11710       else
11711         break;
11712     }
11713
11714   if (table_index == ~0)
11715     {
11716       errmsg ("Table index required");
11717       return -99;
11718     }
11719
11720   if (is_add && match == 0)
11721     {
11722       errmsg ("Match value required");
11723       return -99;
11724     }
11725
11726   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11727
11728   mp->is_add = is_add;
11729   mp->table_index = ntohl (table_index);
11730   mp->hit_next_index = ntohl (hit_next_index);
11731   mp->opaque_index = ntohl (opaque_index);
11732   mp->advance = ntohl (advance);
11733   mp->action = action;
11734   mp->metadata = ntohl (metadata);
11735   clib_memcpy (mp->match, match, vec_len (match));
11736   vec_free (match);
11737
11738   S (mp);
11739   W (ret);
11740   return ret;
11741 }
11742
11743 static int
11744 api_classify_set_interface_ip_table (vat_main_t * vam)
11745 {
11746   unformat_input_t *i = vam->input;
11747   vl_api_classify_set_interface_ip_table_t *mp;
11748   u32 sw_if_index;
11749   int sw_if_index_set;
11750   u32 table_index = ~0;
11751   u8 is_ipv6 = 0;
11752   int ret;
11753
11754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11755     {
11756       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11757         sw_if_index_set = 1;
11758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11759         sw_if_index_set = 1;
11760       else if (unformat (i, "table %d", &table_index))
11761         ;
11762       else
11763         {
11764           clib_warning ("parse error '%U'", format_unformat_error, i);
11765           return -99;
11766         }
11767     }
11768
11769   if (sw_if_index_set == 0)
11770     {
11771       errmsg ("missing interface name or sw_if_index");
11772       return -99;
11773     }
11774
11775
11776   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11777
11778   mp->sw_if_index = ntohl (sw_if_index);
11779   mp->table_index = ntohl (table_index);
11780   mp->is_ipv6 = is_ipv6;
11781
11782   S (mp);
11783   W (ret);
11784   return ret;
11785 }
11786
11787 static int
11788 api_classify_set_interface_l2_tables (vat_main_t * vam)
11789 {
11790   unformat_input_t *i = vam->input;
11791   vl_api_classify_set_interface_l2_tables_t *mp;
11792   u32 sw_if_index;
11793   int sw_if_index_set;
11794   u32 ip4_table_index = ~0;
11795   u32 ip6_table_index = ~0;
11796   u32 other_table_index = ~0;
11797   u32 is_input = 1;
11798   int ret;
11799
11800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11801     {
11802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11803         sw_if_index_set = 1;
11804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11805         sw_if_index_set = 1;
11806       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11807         ;
11808       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11809         ;
11810       else if (unformat (i, "other-table %d", &other_table_index))
11811         ;
11812       else if (unformat (i, "is-input %d", &is_input))
11813         ;
11814       else
11815         {
11816           clib_warning ("parse error '%U'", format_unformat_error, i);
11817           return -99;
11818         }
11819     }
11820
11821   if (sw_if_index_set == 0)
11822     {
11823       errmsg ("missing interface name or sw_if_index");
11824       return -99;
11825     }
11826
11827
11828   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11829
11830   mp->sw_if_index = ntohl (sw_if_index);
11831   mp->ip4_table_index = ntohl (ip4_table_index);
11832   mp->ip6_table_index = ntohl (ip6_table_index);
11833   mp->other_table_index = ntohl (other_table_index);
11834   mp->is_input = (u8) is_input;
11835
11836   S (mp);
11837   W (ret);
11838   return ret;
11839 }
11840
11841 static int
11842 api_set_ipfix_exporter (vat_main_t * vam)
11843 {
11844   unformat_input_t *i = vam->input;
11845   vl_api_set_ipfix_exporter_t *mp;
11846   ip4_address_t collector_address;
11847   u8 collector_address_set = 0;
11848   u32 collector_port = ~0;
11849   ip4_address_t src_address;
11850   u8 src_address_set = 0;
11851   u32 vrf_id = ~0;
11852   u32 path_mtu = ~0;
11853   u32 template_interval = ~0;
11854   u8 udp_checksum = 0;
11855   int ret;
11856
11857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11858     {
11859       if (unformat (i, "collector_address %U", unformat_ip4_address,
11860                     &collector_address))
11861         collector_address_set = 1;
11862       else if (unformat (i, "collector_port %d", &collector_port))
11863         ;
11864       else if (unformat (i, "src_address %U", unformat_ip4_address,
11865                          &src_address))
11866         src_address_set = 1;
11867       else if (unformat (i, "vrf_id %d", &vrf_id))
11868         ;
11869       else if (unformat (i, "path_mtu %d", &path_mtu))
11870         ;
11871       else if (unformat (i, "template_interval %d", &template_interval))
11872         ;
11873       else if (unformat (i, "udp_checksum"))
11874         udp_checksum = 1;
11875       else
11876         break;
11877     }
11878
11879   if (collector_address_set == 0)
11880     {
11881       errmsg ("collector_address required");
11882       return -99;
11883     }
11884
11885   if (src_address_set == 0)
11886     {
11887       errmsg ("src_address required");
11888       return -99;
11889     }
11890
11891   M (SET_IPFIX_EXPORTER, mp);
11892
11893   memcpy (mp->collector_address, collector_address.data,
11894           sizeof (collector_address.data));
11895   mp->collector_port = htons ((u16) collector_port);
11896   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11897   mp->vrf_id = htonl (vrf_id);
11898   mp->path_mtu = htonl (path_mtu);
11899   mp->template_interval = htonl (template_interval);
11900   mp->udp_checksum = udp_checksum;
11901
11902   S (mp);
11903   W (ret);
11904   return ret;
11905 }
11906
11907 static int
11908 api_set_ipfix_classify_stream (vat_main_t * vam)
11909 {
11910   unformat_input_t *i = vam->input;
11911   vl_api_set_ipfix_classify_stream_t *mp;
11912   u32 domain_id = 0;
11913   u32 src_port = UDP_DST_PORT_ipfix;
11914   int ret;
11915
11916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11917     {
11918       if (unformat (i, "domain %d", &domain_id))
11919         ;
11920       else if (unformat (i, "src_port %d", &src_port))
11921         ;
11922       else
11923         {
11924           errmsg ("unknown input `%U'", format_unformat_error, i);
11925           return -99;
11926         }
11927     }
11928
11929   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11930
11931   mp->domain_id = htonl (domain_id);
11932   mp->src_port = htons ((u16) src_port);
11933
11934   S (mp);
11935   W (ret);
11936   return ret;
11937 }
11938
11939 static int
11940 api_ipfix_classify_table_add_del (vat_main_t * vam)
11941 {
11942   unformat_input_t *i = vam->input;
11943   vl_api_ipfix_classify_table_add_del_t *mp;
11944   int is_add = -1;
11945   u32 classify_table_index = ~0;
11946   u8 ip_version = 0;
11947   u8 transport_protocol = 255;
11948   int ret;
11949
11950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11951     {
11952       if (unformat (i, "add"))
11953         is_add = 1;
11954       else if (unformat (i, "del"))
11955         is_add = 0;
11956       else if (unformat (i, "table %d", &classify_table_index))
11957         ;
11958       else if (unformat (i, "ip4"))
11959         ip_version = 4;
11960       else if (unformat (i, "ip6"))
11961         ip_version = 6;
11962       else if (unformat (i, "tcp"))
11963         transport_protocol = 6;
11964       else if (unformat (i, "udp"))
11965         transport_protocol = 17;
11966       else
11967         {
11968           errmsg ("unknown input `%U'", format_unformat_error, i);
11969           return -99;
11970         }
11971     }
11972
11973   if (is_add == -1)
11974     {
11975       errmsg ("expecting: add|del");
11976       return -99;
11977     }
11978   if (classify_table_index == ~0)
11979     {
11980       errmsg ("classifier table not specified");
11981       return -99;
11982     }
11983   if (ip_version == 0)
11984     {
11985       errmsg ("IP version not specified");
11986       return -99;
11987     }
11988
11989   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11990
11991   mp->is_add = is_add;
11992   mp->table_id = htonl (classify_table_index);
11993   mp->ip_version = ip_version;
11994   mp->transport_protocol = transport_protocol;
11995
11996   S (mp);
11997   W (ret);
11998   return ret;
11999 }
12000
12001 static int
12002 api_get_node_index (vat_main_t * vam)
12003 {
12004   unformat_input_t *i = vam->input;
12005   vl_api_get_node_index_t *mp;
12006   u8 *name = 0;
12007   int ret;
12008
12009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12010     {
12011       if (unformat (i, "node %s", &name))
12012         ;
12013       else
12014         break;
12015     }
12016   if (name == 0)
12017     {
12018       errmsg ("node name required");
12019       return -99;
12020     }
12021   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12022     {
12023       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12024       return -99;
12025     }
12026
12027   M (GET_NODE_INDEX, mp);
12028   clib_memcpy (mp->node_name, name, vec_len (name));
12029   vec_free (name);
12030
12031   S (mp);
12032   W (ret);
12033   return ret;
12034 }
12035
12036 static int
12037 api_get_next_index (vat_main_t * vam)
12038 {
12039   unformat_input_t *i = vam->input;
12040   vl_api_get_next_index_t *mp;
12041   u8 *node_name = 0, *next_node_name = 0;
12042   int ret;
12043
12044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12045     {
12046       if (unformat (i, "node-name %s", &node_name))
12047         ;
12048       else if (unformat (i, "next-node-name %s", &next_node_name))
12049         break;
12050     }
12051
12052   if (node_name == 0)
12053     {
12054       errmsg ("node name required");
12055       return -99;
12056     }
12057   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12058     {
12059       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12060       return -99;
12061     }
12062
12063   if (next_node_name == 0)
12064     {
12065       errmsg ("next node name required");
12066       return -99;
12067     }
12068   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12069     {
12070       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12071       return -99;
12072     }
12073
12074   M (GET_NEXT_INDEX, mp);
12075   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12076   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12077   vec_free (node_name);
12078   vec_free (next_node_name);
12079
12080   S (mp);
12081   W (ret);
12082   return ret;
12083 }
12084
12085 static int
12086 api_add_node_next (vat_main_t * vam)
12087 {
12088   unformat_input_t *i = vam->input;
12089   vl_api_add_node_next_t *mp;
12090   u8 *name = 0;
12091   u8 *next = 0;
12092   int ret;
12093
12094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12095     {
12096       if (unformat (i, "node %s", &name))
12097         ;
12098       else if (unformat (i, "next %s", &next))
12099         ;
12100       else
12101         break;
12102     }
12103   if (name == 0)
12104     {
12105       errmsg ("node name required");
12106       return -99;
12107     }
12108   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12109     {
12110       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12111       return -99;
12112     }
12113   if (next == 0)
12114     {
12115       errmsg ("next node required");
12116       return -99;
12117     }
12118   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12119     {
12120       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12121       return -99;
12122     }
12123
12124   M (ADD_NODE_NEXT, mp);
12125   clib_memcpy (mp->node_name, name, vec_len (name));
12126   clib_memcpy (mp->next_name, next, vec_len (next));
12127   vec_free (name);
12128   vec_free (next);
12129
12130   S (mp);
12131   W (ret);
12132   return ret;
12133 }
12134
12135 static int
12136 api_l2tpv3_create_tunnel (vat_main_t * vam)
12137 {
12138   unformat_input_t *i = vam->input;
12139   ip6_address_t client_address, our_address;
12140   int client_address_set = 0;
12141   int our_address_set = 0;
12142   u32 local_session_id = 0;
12143   u32 remote_session_id = 0;
12144   u64 local_cookie = 0;
12145   u64 remote_cookie = 0;
12146   u8 l2_sublayer_present = 0;
12147   vl_api_l2tpv3_create_tunnel_t *mp;
12148   int ret;
12149
12150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12151     {
12152       if (unformat (i, "client_address %U", unformat_ip6_address,
12153                     &client_address))
12154         client_address_set = 1;
12155       else if (unformat (i, "our_address %U", unformat_ip6_address,
12156                          &our_address))
12157         our_address_set = 1;
12158       else if (unformat (i, "local_session_id %d", &local_session_id))
12159         ;
12160       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12161         ;
12162       else if (unformat (i, "local_cookie %lld", &local_cookie))
12163         ;
12164       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12165         ;
12166       else if (unformat (i, "l2-sublayer-present"))
12167         l2_sublayer_present = 1;
12168       else
12169         break;
12170     }
12171
12172   if (client_address_set == 0)
12173     {
12174       errmsg ("client_address required");
12175       return -99;
12176     }
12177
12178   if (our_address_set == 0)
12179     {
12180       errmsg ("our_address required");
12181       return -99;
12182     }
12183
12184   M (L2TPV3_CREATE_TUNNEL, mp);
12185
12186   clib_memcpy (mp->client_address, client_address.as_u8,
12187                sizeof (mp->client_address));
12188
12189   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12190
12191   mp->local_session_id = ntohl (local_session_id);
12192   mp->remote_session_id = ntohl (remote_session_id);
12193   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12194   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12195   mp->l2_sublayer_present = l2_sublayer_present;
12196   mp->is_ipv6 = 1;
12197
12198   S (mp);
12199   W (ret);
12200   return ret;
12201 }
12202
12203 static int
12204 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12205 {
12206   unformat_input_t *i = vam->input;
12207   u32 sw_if_index;
12208   u8 sw_if_index_set = 0;
12209   u64 new_local_cookie = 0;
12210   u64 new_remote_cookie = 0;
12211   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12212   int ret;
12213
12214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12215     {
12216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12217         sw_if_index_set = 1;
12218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12219         sw_if_index_set = 1;
12220       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12221         ;
12222       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12223         ;
12224       else
12225         break;
12226     }
12227
12228   if (sw_if_index_set == 0)
12229     {
12230       errmsg ("missing interface name or sw_if_index");
12231       return -99;
12232     }
12233
12234   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12235
12236   mp->sw_if_index = ntohl (sw_if_index);
12237   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12238   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12239
12240   S (mp);
12241   W (ret);
12242   return ret;
12243 }
12244
12245 static int
12246 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12247 {
12248   unformat_input_t *i = vam->input;
12249   vl_api_l2tpv3_interface_enable_disable_t *mp;
12250   u32 sw_if_index;
12251   u8 sw_if_index_set = 0;
12252   u8 enable_disable = 1;
12253   int ret;
12254
12255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12256     {
12257       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12258         sw_if_index_set = 1;
12259       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12260         sw_if_index_set = 1;
12261       else if (unformat (i, "enable"))
12262         enable_disable = 1;
12263       else if (unformat (i, "disable"))
12264         enable_disable = 0;
12265       else
12266         break;
12267     }
12268
12269   if (sw_if_index_set == 0)
12270     {
12271       errmsg ("missing interface name or sw_if_index");
12272       return -99;
12273     }
12274
12275   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12276
12277   mp->sw_if_index = ntohl (sw_if_index);
12278   mp->enable_disable = enable_disable;
12279
12280   S (mp);
12281   W (ret);
12282   return ret;
12283 }
12284
12285 static int
12286 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12287 {
12288   unformat_input_t *i = vam->input;
12289   vl_api_l2tpv3_set_lookup_key_t *mp;
12290   u8 key = ~0;
12291   int ret;
12292
12293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12294     {
12295       if (unformat (i, "lookup_v6_src"))
12296         key = L2T_LOOKUP_SRC_ADDRESS;
12297       else if (unformat (i, "lookup_v6_dst"))
12298         key = L2T_LOOKUP_DST_ADDRESS;
12299       else if (unformat (i, "lookup_session_id"))
12300         key = L2T_LOOKUP_SESSION_ID;
12301       else
12302         break;
12303     }
12304
12305   if (key == (u8) ~ 0)
12306     {
12307       errmsg ("l2tp session lookup key unset");
12308       return -99;
12309     }
12310
12311   M (L2TPV3_SET_LOOKUP_KEY, mp);
12312
12313   mp->key = key;
12314
12315   S (mp);
12316   W (ret);
12317   return ret;
12318 }
12319
12320 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12321   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12322 {
12323   vat_main_t *vam = &vat_main;
12324
12325   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12326          format_ip6_address, mp->our_address,
12327          format_ip6_address, mp->client_address,
12328          clib_net_to_host_u32 (mp->sw_if_index));
12329
12330   print (vam->ofp,
12331          "   local cookies %016llx %016llx remote cookie %016llx",
12332          clib_net_to_host_u64 (mp->local_cookie[0]),
12333          clib_net_to_host_u64 (mp->local_cookie[1]),
12334          clib_net_to_host_u64 (mp->remote_cookie));
12335
12336   print (vam->ofp, "   local session-id %d remote session-id %d",
12337          clib_net_to_host_u32 (mp->local_session_id),
12338          clib_net_to_host_u32 (mp->remote_session_id));
12339
12340   print (vam->ofp, "   l2 specific sublayer %s\n",
12341          mp->l2_sublayer_present ? "preset" : "absent");
12342
12343 }
12344
12345 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12346   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12347 {
12348   vat_main_t *vam = &vat_main;
12349   vat_json_node_t *node = NULL;
12350   struct in6_addr addr;
12351
12352   if (VAT_JSON_ARRAY != vam->json_tree.type)
12353     {
12354       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12355       vat_json_init_array (&vam->json_tree);
12356     }
12357   node = vat_json_array_add (&vam->json_tree);
12358
12359   vat_json_init_object (node);
12360
12361   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12362   vat_json_object_add_ip6 (node, "our_address", addr);
12363   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12364   vat_json_object_add_ip6 (node, "client_address", addr);
12365
12366   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12367   vat_json_init_array (lc);
12368   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12369   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12370   vat_json_object_add_uint (node, "remote_cookie",
12371                             clib_net_to_host_u64 (mp->remote_cookie));
12372
12373   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12374   vat_json_object_add_uint (node, "local_session_id",
12375                             clib_net_to_host_u32 (mp->local_session_id));
12376   vat_json_object_add_uint (node, "remote_session_id",
12377                             clib_net_to_host_u32 (mp->remote_session_id));
12378   vat_json_object_add_string_copy (node, "l2_sublayer",
12379                                    mp->l2_sublayer_present ? (u8 *) "present"
12380                                    : (u8 *) "absent");
12381 }
12382
12383 static int
12384 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12385 {
12386   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12387   vl_api_control_ping_t *mp_ping;
12388   int ret;
12389
12390   /* Get list of l2tpv3-tunnel interfaces */
12391   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12392   S (mp);
12393
12394   /* Use a control ping for synchronization */
12395   MPING (CONTROL_PING, mp_ping);
12396   S (mp_ping);
12397
12398   W (ret);
12399   return ret;
12400 }
12401
12402
12403 static void vl_api_sw_interface_tap_details_t_handler
12404   (vl_api_sw_interface_tap_details_t * mp)
12405 {
12406   vat_main_t *vam = &vat_main;
12407
12408   print (vam->ofp, "%-16s %d",
12409          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12410 }
12411
12412 static void vl_api_sw_interface_tap_details_t_handler_json
12413   (vl_api_sw_interface_tap_details_t * mp)
12414 {
12415   vat_main_t *vam = &vat_main;
12416   vat_json_node_t *node = NULL;
12417
12418   if (VAT_JSON_ARRAY != vam->json_tree.type)
12419     {
12420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12421       vat_json_init_array (&vam->json_tree);
12422     }
12423   node = vat_json_array_add (&vam->json_tree);
12424
12425   vat_json_init_object (node);
12426   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12427   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12428 }
12429
12430 static int
12431 api_sw_interface_tap_dump (vat_main_t * vam)
12432 {
12433   vl_api_sw_interface_tap_dump_t *mp;
12434   vl_api_control_ping_t *mp_ping;
12435   int ret;
12436
12437   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12438   /* Get list of tap interfaces */
12439   M (SW_INTERFACE_TAP_DUMP, mp);
12440   S (mp);
12441
12442   /* Use a control ping for synchronization */
12443   MPING (CONTROL_PING, mp_ping);
12444   S (mp_ping);
12445
12446   W (ret);
12447   return ret;
12448 }
12449
12450 static void vl_api_sw_interface_tap_v2_details_t_handler
12451   (vl_api_sw_interface_tap_v2_details_t * mp)
12452 {
12453   vat_main_t *vam = &vat_main;
12454
12455   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12456                     mp->host_ip4_prefix_len);
12457   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12458                     mp->host_ip6_prefix_len);
12459
12460   print (vam->ofp,
12461          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12462          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12463          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12464          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12465          mp->host_bridge, ip4, ip6);
12466
12467   vec_free (ip4);
12468   vec_free (ip6);
12469 }
12470
12471 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12472   (vl_api_sw_interface_tap_v2_details_t * mp)
12473 {
12474   vat_main_t *vam = &vat_main;
12475   vat_json_node_t *node = NULL;
12476
12477   if (VAT_JSON_ARRAY != vam->json_tree.type)
12478     {
12479       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12480       vat_json_init_array (&vam->json_tree);
12481     }
12482   node = vat_json_array_add (&vam->json_tree);
12483
12484   vat_json_init_object (node);
12485   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12486   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12487   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12488   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12489   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12490   vat_json_object_add_string_copy (node, "host_mac_addr",
12491                                    format (0, "%U", format_ethernet_address,
12492                                            &mp->host_mac_addr));
12493   vat_json_object_add_string_copy (node, "host_namespace",
12494                                    mp->host_namespace);
12495   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12496   vat_json_object_add_string_copy (node, "host_ip4_addr",
12497                                    format (0, "%U/%d", format_ip4_address,
12498                                            mp->host_ip4_addr,
12499                                            mp->host_ip4_prefix_len));
12500   vat_json_object_add_string_copy (node, "host_ip6_addr",
12501                                    format (0, "%U/%d", format_ip6_address,
12502                                            mp->host_ip6_addr,
12503                                            mp->host_ip6_prefix_len));
12504
12505 }
12506
12507 static int
12508 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12509 {
12510   vl_api_sw_interface_tap_v2_dump_t *mp;
12511   vl_api_control_ping_t *mp_ping;
12512   int ret;
12513
12514   print (vam->ofp,
12515          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12516          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12517          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12518          "host_ip6_addr");
12519
12520   /* Get list of tap interfaces */
12521   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12522   S (mp);
12523
12524   /* Use a control ping for synchronization */
12525   MPING (CONTROL_PING, mp_ping);
12526   S (mp_ping);
12527
12528   W (ret);
12529   return ret;
12530 }
12531
12532 static uword unformat_vxlan_decap_next
12533   (unformat_input_t * input, va_list * args)
12534 {
12535   u32 *result = va_arg (*args, u32 *);
12536   u32 tmp;
12537
12538   if (unformat (input, "l2"))
12539     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12540   else if (unformat (input, "%d", &tmp))
12541     *result = tmp;
12542   else
12543     return 0;
12544   return 1;
12545 }
12546
12547 static int
12548 api_vxlan_add_del_tunnel (vat_main_t * vam)
12549 {
12550   unformat_input_t *line_input = vam->input;
12551   vl_api_vxlan_add_del_tunnel_t *mp;
12552   ip46_address_t src, dst;
12553   u8 is_add = 1;
12554   u8 ipv4_set = 0, ipv6_set = 0;
12555   u8 src_set = 0;
12556   u8 dst_set = 0;
12557   u8 grp_set = 0;
12558   u32 mcast_sw_if_index = ~0;
12559   u32 encap_vrf_id = 0;
12560   u32 decap_next_index = ~0;
12561   u32 vni = 0;
12562   int ret;
12563
12564   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12565   memset (&src, 0, sizeof src);
12566   memset (&dst, 0, sizeof dst);
12567
12568   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12569     {
12570       if (unformat (line_input, "del"))
12571         is_add = 0;
12572       else
12573         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12574         {
12575           ipv4_set = 1;
12576           src_set = 1;
12577         }
12578       else
12579         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12580         {
12581           ipv4_set = 1;
12582           dst_set = 1;
12583         }
12584       else
12585         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12586         {
12587           ipv6_set = 1;
12588           src_set = 1;
12589         }
12590       else
12591         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12592         {
12593           ipv6_set = 1;
12594           dst_set = 1;
12595         }
12596       else if (unformat (line_input, "group %U %U",
12597                          unformat_ip4_address, &dst.ip4,
12598                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12599         {
12600           grp_set = dst_set = 1;
12601           ipv4_set = 1;
12602         }
12603       else if (unformat (line_input, "group %U",
12604                          unformat_ip4_address, &dst.ip4))
12605         {
12606           grp_set = dst_set = 1;
12607           ipv4_set = 1;
12608         }
12609       else if (unformat (line_input, "group %U %U",
12610                          unformat_ip6_address, &dst.ip6,
12611                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12612         {
12613           grp_set = dst_set = 1;
12614           ipv6_set = 1;
12615         }
12616       else if (unformat (line_input, "group %U",
12617                          unformat_ip6_address, &dst.ip6))
12618         {
12619           grp_set = dst_set = 1;
12620           ipv6_set = 1;
12621         }
12622       else
12623         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12624         ;
12625       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12626         ;
12627       else if (unformat (line_input, "decap-next %U",
12628                          unformat_vxlan_decap_next, &decap_next_index))
12629         ;
12630       else if (unformat (line_input, "vni %d", &vni))
12631         ;
12632       else
12633         {
12634           errmsg ("parse error '%U'", format_unformat_error, line_input);
12635           return -99;
12636         }
12637     }
12638
12639   if (src_set == 0)
12640     {
12641       errmsg ("tunnel src address not specified");
12642       return -99;
12643     }
12644   if (dst_set == 0)
12645     {
12646       errmsg ("tunnel dst address not specified");
12647       return -99;
12648     }
12649
12650   if (grp_set && !ip46_address_is_multicast (&dst))
12651     {
12652       errmsg ("tunnel group address not multicast");
12653       return -99;
12654     }
12655   if (grp_set && mcast_sw_if_index == ~0)
12656     {
12657       errmsg ("tunnel nonexistent multicast device");
12658       return -99;
12659     }
12660   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12661     {
12662       errmsg ("tunnel dst address must be unicast");
12663       return -99;
12664     }
12665
12666
12667   if (ipv4_set && ipv6_set)
12668     {
12669       errmsg ("both IPv4 and IPv6 addresses specified");
12670       return -99;
12671     }
12672
12673   if ((vni == 0) || (vni >> 24))
12674     {
12675       errmsg ("vni not specified or out of range");
12676       return -99;
12677     }
12678
12679   M (VXLAN_ADD_DEL_TUNNEL, mp);
12680
12681   if (ipv6_set)
12682     {
12683       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12684       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12685     }
12686   else
12687     {
12688       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12689       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12690     }
12691   mp->encap_vrf_id = ntohl (encap_vrf_id);
12692   mp->decap_next_index = ntohl (decap_next_index);
12693   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12694   mp->vni = ntohl (vni);
12695   mp->is_add = is_add;
12696   mp->is_ipv6 = ipv6_set;
12697
12698   S (mp);
12699   W (ret);
12700   return ret;
12701 }
12702
12703 static void vl_api_vxlan_tunnel_details_t_handler
12704   (vl_api_vxlan_tunnel_details_t * mp)
12705 {
12706   vat_main_t *vam = &vat_main;
12707   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12708   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12709
12710   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12711          ntohl (mp->sw_if_index),
12712          format_ip46_address, &src, IP46_TYPE_ANY,
12713          format_ip46_address, &dst, IP46_TYPE_ANY,
12714          ntohl (mp->encap_vrf_id),
12715          ntohl (mp->decap_next_index), ntohl (mp->vni),
12716          ntohl (mp->mcast_sw_if_index));
12717 }
12718
12719 static void vl_api_vxlan_tunnel_details_t_handler_json
12720   (vl_api_vxlan_tunnel_details_t * mp)
12721 {
12722   vat_main_t *vam = &vat_main;
12723   vat_json_node_t *node = NULL;
12724
12725   if (VAT_JSON_ARRAY != vam->json_tree.type)
12726     {
12727       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12728       vat_json_init_array (&vam->json_tree);
12729     }
12730   node = vat_json_array_add (&vam->json_tree);
12731
12732   vat_json_init_object (node);
12733   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12734   if (mp->is_ipv6)
12735     {
12736       struct in6_addr ip6;
12737
12738       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12739       vat_json_object_add_ip6 (node, "src_address", ip6);
12740       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12741       vat_json_object_add_ip6 (node, "dst_address", ip6);
12742     }
12743   else
12744     {
12745       struct in_addr ip4;
12746
12747       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12748       vat_json_object_add_ip4 (node, "src_address", ip4);
12749       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12750       vat_json_object_add_ip4 (node, "dst_address", ip4);
12751     }
12752   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12753   vat_json_object_add_uint (node, "decap_next_index",
12754                             ntohl (mp->decap_next_index));
12755   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12756   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12757   vat_json_object_add_uint (node, "mcast_sw_if_index",
12758                             ntohl (mp->mcast_sw_if_index));
12759 }
12760
12761 static int
12762 api_vxlan_tunnel_dump (vat_main_t * vam)
12763 {
12764   unformat_input_t *i = vam->input;
12765   vl_api_vxlan_tunnel_dump_t *mp;
12766   vl_api_control_ping_t *mp_ping;
12767   u32 sw_if_index;
12768   u8 sw_if_index_set = 0;
12769   int ret;
12770
12771   /* Parse args required to build the message */
12772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12773     {
12774       if (unformat (i, "sw_if_index %d", &sw_if_index))
12775         sw_if_index_set = 1;
12776       else
12777         break;
12778     }
12779
12780   if (sw_if_index_set == 0)
12781     {
12782       sw_if_index = ~0;
12783     }
12784
12785   if (!vam->json_output)
12786     {
12787       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12788              "sw_if_index", "src_address", "dst_address",
12789              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12790     }
12791
12792   /* Get list of vxlan-tunnel interfaces */
12793   M (VXLAN_TUNNEL_DUMP, mp);
12794
12795   mp->sw_if_index = htonl (sw_if_index);
12796
12797   S (mp);
12798
12799   /* Use a control ping for synchronization */
12800   MPING (CONTROL_PING, mp_ping);
12801   S (mp_ping);
12802
12803   W (ret);
12804   return ret;
12805 }
12806
12807 static uword unformat_geneve_decap_next
12808   (unformat_input_t * input, va_list * args)
12809 {
12810   u32 *result = va_arg (*args, u32 *);
12811   u32 tmp;
12812
12813   if (unformat (input, "l2"))
12814     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12815   else if (unformat (input, "%d", &tmp))
12816     *result = tmp;
12817   else
12818     return 0;
12819   return 1;
12820 }
12821
12822 static int
12823 api_geneve_add_del_tunnel (vat_main_t * vam)
12824 {
12825   unformat_input_t *line_input = vam->input;
12826   vl_api_geneve_add_del_tunnel_t *mp;
12827   ip46_address_t src, dst;
12828   u8 is_add = 1;
12829   u8 ipv4_set = 0, ipv6_set = 0;
12830   u8 src_set = 0;
12831   u8 dst_set = 0;
12832   u8 grp_set = 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   memset (&src, 0, sizeof src);
12841   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
12848         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12849         {
12850           ipv4_set = 1;
12851           src_set = 1;
12852         }
12853       else
12854         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12855         {
12856           ipv4_set = 1;
12857           dst_set = 1;
12858         }
12859       else
12860         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12861         {
12862           ipv6_set = 1;
12863           src_set = 1;
12864         }
12865       else
12866         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12867         {
12868           ipv6_set = 1;
12869           dst_set = 1;
12870         }
12871       else if (unformat (line_input, "group %U %U",
12872                          unformat_ip4_address, &dst.ip4,
12873                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12874         {
12875           grp_set = dst_set = 1;
12876           ipv4_set = 1;
12877         }
12878       else if (unformat (line_input, "group %U",
12879                          unformat_ip4_address, &dst.ip4))
12880         {
12881           grp_set = dst_set = 1;
12882           ipv4_set = 1;
12883         }
12884       else if (unformat (line_input, "group %U %U",
12885                          unformat_ip6_address, &dst.ip6,
12886                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12887         {
12888           grp_set = dst_set = 1;
12889           ipv6_set = 1;
12890         }
12891       else if (unformat (line_input, "group %U",
12892                          unformat_ip6_address, &dst.ip6))
12893         {
12894           grp_set = dst_set = 1;
12895           ipv6_set = 1;
12896         }
12897       else
12898         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12899         ;
12900       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12901         ;
12902       else if (unformat (line_input, "decap-next %U",
12903                          unformat_geneve_decap_next, &decap_next_index))
12904         ;
12905       else if (unformat (line_input, "vni %d", &vni))
12906         ;
12907       else
12908         {
12909           errmsg ("parse error '%U'", format_unformat_error, line_input);
12910           return -99;
12911         }
12912     }
12913
12914   if (src_set == 0)
12915     {
12916       errmsg ("tunnel src address not specified");
12917       return -99;
12918     }
12919   if (dst_set == 0)
12920     {
12921       errmsg ("tunnel dst address not specified");
12922       return -99;
12923     }
12924
12925   if (grp_set && !ip46_address_is_multicast (&dst))
12926     {
12927       errmsg ("tunnel group address not multicast");
12928       return -99;
12929     }
12930   if (grp_set && mcast_sw_if_index == ~0)
12931     {
12932       errmsg ("tunnel nonexistent multicast device");
12933       return -99;
12934     }
12935   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12936     {
12937       errmsg ("tunnel dst address must be unicast");
12938       return -99;
12939     }
12940
12941
12942   if (ipv4_set && ipv6_set)
12943     {
12944       errmsg ("both IPv4 and IPv6 addresses specified");
12945       return -99;
12946     }
12947
12948   if ((vni == 0) || (vni >> 24))
12949     {
12950       errmsg ("vni not specified or out of range");
12951       return -99;
12952     }
12953
12954   M (GENEVE_ADD_DEL_TUNNEL, mp);
12955
12956   if (ipv6_set)
12957     {
12958       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12959       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12960     }
12961   else
12962     {
12963       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12964       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12965     }
12966   mp->encap_vrf_id = ntohl (encap_vrf_id);
12967   mp->decap_next_index = ntohl (decap_next_index);
12968   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12969   mp->vni = ntohl (vni);
12970   mp->is_add = is_add;
12971   mp->is_ipv6 = ipv6_set;
12972
12973   S (mp);
12974   W (ret);
12975   return ret;
12976 }
12977
12978 static void vl_api_geneve_tunnel_details_t_handler
12979   (vl_api_geneve_tunnel_details_t * mp)
12980 {
12981   vat_main_t *vam = &vat_main;
12982   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12983   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12984
12985   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12986          ntohl (mp->sw_if_index),
12987          format_ip46_address, &src, IP46_TYPE_ANY,
12988          format_ip46_address, &dst, IP46_TYPE_ANY,
12989          ntohl (mp->encap_vrf_id),
12990          ntohl (mp->decap_next_index), ntohl (mp->vni),
12991          ntohl (mp->mcast_sw_if_index));
12992 }
12993
12994 static void vl_api_geneve_tunnel_details_t_handler_json
12995   (vl_api_geneve_tunnel_details_t * mp)
12996 {
12997   vat_main_t *vam = &vat_main;
12998   vat_json_node_t *node = NULL;
12999
13000   if (VAT_JSON_ARRAY != vam->json_tree.type)
13001     {
13002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13003       vat_json_init_array (&vam->json_tree);
13004     }
13005   node = vat_json_array_add (&vam->json_tree);
13006
13007   vat_json_init_object (node);
13008   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13009   if (mp->is_ipv6)
13010     {
13011       struct in6_addr ip6;
13012
13013       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13014       vat_json_object_add_ip6 (node, "src_address", ip6);
13015       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13016       vat_json_object_add_ip6 (node, "dst_address", ip6);
13017     }
13018   else
13019     {
13020       struct in_addr ip4;
13021
13022       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13023       vat_json_object_add_ip4 (node, "src_address", ip4);
13024       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13025       vat_json_object_add_ip4 (node, "dst_address", ip4);
13026     }
13027   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13028   vat_json_object_add_uint (node, "decap_next_index",
13029                             ntohl (mp->decap_next_index));
13030   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13031   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13032   vat_json_object_add_uint (node, "mcast_sw_if_index",
13033                             ntohl (mp->mcast_sw_if_index));
13034 }
13035
13036 static int
13037 api_geneve_tunnel_dump (vat_main_t * vam)
13038 {
13039   unformat_input_t *i = vam->input;
13040   vl_api_geneve_tunnel_dump_t *mp;
13041   vl_api_control_ping_t *mp_ping;
13042   u32 sw_if_index;
13043   u8 sw_if_index_set = 0;
13044   int ret;
13045
13046   /* Parse args required to build the message */
13047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13048     {
13049       if (unformat (i, "sw_if_index %d", &sw_if_index))
13050         sw_if_index_set = 1;
13051       else
13052         break;
13053     }
13054
13055   if (sw_if_index_set == 0)
13056     {
13057       sw_if_index = ~0;
13058     }
13059
13060   if (!vam->json_output)
13061     {
13062       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13063              "sw_if_index", "local_address", "remote_address",
13064              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13065     }
13066
13067   /* Get list of geneve-tunnel interfaces */
13068   M (GENEVE_TUNNEL_DUMP, mp);
13069
13070   mp->sw_if_index = htonl (sw_if_index);
13071
13072   S (mp);
13073
13074   /* Use a control ping for synchronization */
13075   M (CONTROL_PING, mp_ping);
13076   S (mp_ping);
13077
13078   W (ret);
13079   return ret;
13080 }
13081
13082 static int
13083 api_gre_add_del_tunnel (vat_main_t * vam)
13084 {
13085   unformat_input_t *line_input = vam->input;
13086   vl_api_gre_add_del_tunnel_t *mp;
13087   ip4_address_t src4, dst4;
13088   ip6_address_t src6, dst6;
13089   u8 is_add = 1;
13090   u8 ipv4_set = 0;
13091   u8 ipv6_set = 0;
13092   u8 teb = 0;
13093   u8 src_set = 0;
13094   u8 dst_set = 0;
13095   u32 outer_fib_id = 0;
13096   int ret;
13097
13098   memset (&src4, 0, sizeof src4);
13099   memset (&dst4, 0, sizeof dst4);
13100   memset (&src6, 0, sizeof src6);
13101   memset (&dst6, 0, sizeof dst6);
13102
13103   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13104     {
13105       if (unformat (line_input, "del"))
13106         is_add = 0;
13107       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13108         {
13109           src_set = 1;
13110           ipv4_set = 1;
13111         }
13112       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13113         {
13114           dst_set = 1;
13115           ipv4_set = 1;
13116         }
13117       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13118         {
13119           src_set = 1;
13120           ipv6_set = 1;
13121         }
13122       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13123         {
13124           dst_set = 1;
13125           ipv6_set = 1;
13126         }
13127       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13128         ;
13129       else if (unformat (line_input, "teb"))
13130         teb = 1;
13131       else
13132         {
13133           errmsg ("parse error '%U'", format_unformat_error, line_input);
13134           return -99;
13135         }
13136     }
13137
13138   if (src_set == 0)
13139     {
13140       errmsg ("tunnel src address not specified");
13141       return -99;
13142     }
13143   if (dst_set == 0)
13144     {
13145       errmsg ("tunnel dst address not specified");
13146       return -99;
13147     }
13148   if (ipv4_set && ipv6_set)
13149     {
13150       errmsg ("both IPv4 and IPv6 addresses specified");
13151       return -99;
13152     }
13153
13154
13155   M (GRE_ADD_DEL_TUNNEL, mp);
13156
13157   if (ipv4_set)
13158     {
13159       clib_memcpy (&mp->src_address, &src4, 4);
13160       clib_memcpy (&mp->dst_address, &dst4, 4);
13161     }
13162   else
13163     {
13164       clib_memcpy (&mp->src_address, &src6, 16);
13165       clib_memcpy (&mp->dst_address, &dst6, 16);
13166     }
13167   mp->outer_fib_id = ntohl (outer_fib_id);
13168   mp->is_add = is_add;
13169   mp->teb = teb;
13170   mp->is_ipv6 = ipv6_set;
13171
13172   S (mp);
13173   W (ret);
13174   return ret;
13175 }
13176
13177 static void vl_api_gre_tunnel_details_t_handler
13178   (vl_api_gre_tunnel_details_t * mp)
13179 {
13180   vat_main_t *vam = &vat_main;
13181   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13182   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13183
13184   print (vam->ofp, "%11d%24U%24U%6d%14d",
13185          ntohl (mp->sw_if_index),
13186          format_ip46_address, &src, IP46_TYPE_ANY,
13187          format_ip46_address, &dst, IP46_TYPE_ANY,
13188          mp->teb, ntohl (mp->outer_fib_id));
13189 }
13190
13191 static void vl_api_gre_tunnel_details_t_handler_json
13192   (vl_api_gre_tunnel_details_t * mp)
13193 {
13194   vat_main_t *vam = &vat_main;
13195   vat_json_node_t *node = NULL;
13196   struct in_addr ip4;
13197   struct in6_addr ip6;
13198
13199   if (VAT_JSON_ARRAY != vam->json_tree.type)
13200     {
13201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13202       vat_json_init_array (&vam->json_tree);
13203     }
13204   node = vat_json_array_add (&vam->json_tree);
13205
13206   vat_json_init_object (node);
13207   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13208   if (!mp->is_ipv6)
13209     {
13210       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13211       vat_json_object_add_ip4 (node, "src_address", ip4);
13212       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13213       vat_json_object_add_ip4 (node, "dst_address", ip4);
13214     }
13215   else
13216     {
13217       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13218       vat_json_object_add_ip6 (node, "src_address", ip6);
13219       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13220       vat_json_object_add_ip6 (node, "dst_address", ip6);
13221     }
13222   vat_json_object_add_uint (node, "teb", mp->teb);
13223   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13224   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13225 }
13226
13227 static int
13228 api_gre_tunnel_dump (vat_main_t * vam)
13229 {
13230   unformat_input_t *i = vam->input;
13231   vl_api_gre_tunnel_dump_t *mp;
13232   vl_api_control_ping_t *mp_ping;
13233   u32 sw_if_index;
13234   u8 sw_if_index_set = 0;
13235   int ret;
13236
13237   /* Parse args required to build the message */
13238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13239     {
13240       if (unformat (i, "sw_if_index %d", &sw_if_index))
13241         sw_if_index_set = 1;
13242       else
13243         break;
13244     }
13245
13246   if (sw_if_index_set == 0)
13247     {
13248       sw_if_index = ~0;
13249     }
13250
13251   if (!vam->json_output)
13252     {
13253       print (vam->ofp, "%11s%24s%24s%6s%14s",
13254              "sw_if_index", "src_address", "dst_address", "teb",
13255              "outer_fib_id");
13256     }
13257
13258   /* Get list of gre-tunnel interfaces */
13259   M (GRE_TUNNEL_DUMP, mp);
13260
13261   mp->sw_if_index = htonl (sw_if_index);
13262
13263   S (mp);
13264
13265   /* Use a control ping for synchronization */
13266   MPING (CONTROL_PING, mp_ping);
13267   S (mp_ping);
13268
13269   W (ret);
13270   return ret;
13271 }
13272
13273 static int
13274 api_l2_fib_clear_table (vat_main_t * vam)
13275 {
13276 //  unformat_input_t * i = vam->input;
13277   vl_api_l2_fib_clear_table_t *mp;
13278   int ret;
13279
13280   M (L2_FIB_CLEAR_TABLE, mp);
13281
13282   S (mp);
13283   W (ret);
13284   return ret;
13285 }
13286
13287 static int
13288 api_l2_interface_efp_filter (vat_main_t * vam)
13289 {
13290   unformat_input_t *i = vam->input;
13291   vl_api_l2_interface_efp_filter_t *mp;
13292   u32 sw_if_index;
13293   u8 enable = 1;
13294   u8 sw_if_index_set = 0;
13295   int ret;
13296
13297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13298     {
13299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13300         sw_if_index_set = 1;
13301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13302         sw_if_index_set = 1;
13303       else if (unformat (i, "enable"))
13304         enable = 1;
13305       else if (unformat (i, "disable"))
13306         enable = 0;
13307       else
13308         {
13309           clib_warning ("parse error '%U'", format_unformat_error, i);
13310           return -99;
13311         }
13312     }
13313
13314   if (sw_if_index_set == 0)
13315     {
13316       errmsg ("missing sw_if_index");
13317       return -99;
13318     }
13319
13320   M (L2_INTERFACE_EFP_FILTER, mp);
13321
13322   mp->sw_if_index = ntohl (sw_if_index);
13323   mp->enable_disable = enable;
13324
13325   S (mp);
13326   W (ret);
13327   return ret;
13328 }
13329
13330 #define foreach_vtr_op                          \
13331 _("disable",  L2_VTR_DISABLED)                  \
13332 _("push-1",  L2_VTR_PUSH_1)                     \
13333 _("push-2",  L2_VTR_PUSH_2)                     \
13334 _("pop-1",  L2_VTR_POP_1)                       \
13335 _("pop-2",  L2_VTR_POP_2)                       \
13336 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13337 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13338 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13339 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13340
13341 static int
13342 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13343 {
13344   unformat_input_t *i = vam->input;
13345   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13346   u32 sw_if_index;
13347   u8 sw_if_index_set = 0;
13348   u8 vtr_op_set = 0;
13349   u32 vtr_op = 0;
13350   u32 push_dot1q = 1;
13351   u32 tag1 = ~0;
13352   u32 tag2 = ~0;
13353   int ret;
13354
13355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13356     {
13357       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13358         sw_if_index_set = 1;
13359       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13360         sw_if_index_set = 1;
13361       else if (unformat (i, "vtr_op %d", &vtr_op))
13362         vtr_op_set = 1;
13363 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13364       foreach_vtr_op
13365 #undef _
13366         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13367         ;
13368       else if (unformat (i, "tag1 %d", &tag1))
13369         ;
13370       else if (unformat (i, "tag2 %d", &tag2))
13371         ;
13372       else
13373         {
13374           clib_warning ("parse error '%U'", format_unformat_error, i);
13375           return -99;
13376         }
13377     }
13378
13379   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13380     {
13381       errmsg ("missing vtr operation or sw_if_index");
13382       return -99;
13383     }
13384
13385   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13386   mp->sw_if_index = ntohl (sw_if_index);
13387   mp->vtr_op = ntohl (vtr_op);
13388   mp->push_dot1q = ntohl (push_dot1q);
13389   mp->tag1 = ntohl (tag1);
13390   mp->tag2 = ntohl (tag2);
13391
13392   S (mp);
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static int
13398 api_create_vhost_user_if (vat_main_t * vam)
13399 {
13400   unformat_input_t *i = vam->input;
13401   vl_api_create_vhost_user_if_t *mp;
13402   u8 *file_name;
13403   u8 is_server = 0;
13404   u8 file_name_set = 0;
13405   u32 custom_dev_instance = ~0;
13406   u8 hwaddr[6];
13407   u8 use_custom_mac = 0;
13408   u8 *tag = 0;
13409   int ret;
13410
13411   /* Shut up coverity */
13412   memset (hwaddr, 0, sizeof (hwaddr));
13413
13414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13415     {
13416       if (unformat (i, "socket %s", &file_name))
13417         {
13418           file_name_set = 1;
13419         }
13420       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13421         ;
13422       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13423         use_custom_mac = 1;
13424       else if (unformat (i, "server"))
13425         is_server = 1;
13426       else if (unformat (i, "tag %s", &tag))
13427         ;
13428       else
13429         break;
13430     }
13431
13432   if (file_name_set == 0)
13433     {
13434       errmsg ("missing socket file name");
13435       return -99;
13436     }
13437
13438   if (vec_len (file_name) > 255)
13439     {
13440       errmsg ("socket file name too long");
13441       return -99;
13442     }
13443   vec_add1 (file_name, 0);
13444
13445   M (CREATE_VHOST_USER_IF, mp);
13446
13447   mp->is_server = is_server;
13448   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13449   vec_free (file_name);
13450   if (custom_dev_instance != ~0)
13451     {
13452       mp->renumber = 1;
13453       mp->custom_dev_instance = ntohl (custom_dev_instance);
13454     }
13455   mp->use_custom_mac = use_custom_mac;
13456   clib_memcpy (mp->mac_address, hwaddr, 6);
13457   if (tag)
13458     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13459   vec_free (tag);
13460
13461   S (mp);
13462   W (ret);
13463   return ret;
13464 }
13465
13466 static int
13467 api_modify_vhost_user_if (vat_main_t * vam)
13468 {
13469   unformat_input_t *i = vam->input;
13470   vl_api_modify_vhost_user_if_t *mp;
13471   u8 *file_name;
13472   u8 is_server = 0;
13473   u8 file_name_set = 0;
13474   u32 custom_dev_instance = ~0;
13475   u8 sw_if_index_set = 0;
13476   u32 sw_if_index = (u32) ~ 0;
13477   int ret;
13478
13479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13480     {
13481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13482         sw_if_index_set = 1;
13483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13484         sw_if_index_set = 1;
13485       else if (unformat (i, "socket %s", &file_name))
13486         {
13487           file_name_set = 1;
13488         }
13489       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13490         ;
13491       else if (unformat (i, "server"))
13492         is_server = 1;
13493       else
13494         break;
13495     }
13496
13497   if (sw_if_index_set == 0)
13498     {
13499       errmsg ("missing sw_if_index or interface name");
13500       return -99;
13501     }
13502
13503   if (file_name_set == 0)
13504     {
13505       errmsg ("missing socket file name");
13506       return -99;
13507     }
13508
13509   if (vec_len (file_name) > 255)
13510     {
13511       errmsg ("socket file name too long");
13512       return -99;
13513     }
13514   vec_add1 (file_name, 0);
13515
13516   M (MODIFY_VHOST_USER_IF, mp);
13517
13518   mp->sw_if_index = ntohl (sw_if_index);
13519   mp->is_server = is_server;
13520   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13521   vec_free (file_name);
13522   if (custom_dev_instance != ~0)
13523     {
13524       mp->renumber = 1;
13525       mp->custom_dev_instance = ntohl (custom_dev_instance);
13526     }
13527
13528   S (mp);
13529   W (ret);
13530   return ret;
13531 }
13532
13533 static int
13534 api_delete_vhost_user_if (vat_main_t * vam)
13535 {
13536   unformat_input_t *i = vam->input;
13537   vl_api_delete_vhost_user_if_t *mp;
13538   u32 sw_if_index = ~0;
13539   u8 sw_if_index_set = 0;
13540   int ret;
13541
13542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13543     {
13544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13545         sw_if_index_set = 1;
13546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13547         sw_if_index_set = 1;
13548       else
13549         break;
13550     }
13551
13552   if (sw_if_index_set == 0)
13553     {
13554       errmsg ("missing sw_if_index or interface name");
13555       return -99;
13556     }
13557
13558
13559   M (DELETE_VHOST_USER_IF, mp);
13560
13561   mp->sw_if_index = ntohl (sw_if_index);
13562
13563   S (mp);
13564   W (ret);
13565   return ret;
13566 }
13567
13568 static void vl_api_sw_interface_vhost_user_details_t_handler
13569   (vl_api_sw_interface_vhost_user_details_t * mp)
13570 {
13571   vat_main_t *vam = &vat_main;
13572
13573   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13574          (char *) mp->interface_name,
13575          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13576          clib_net_to_host_u64 (mp->features), mp->is_server,
13577          ntohl (mp->num_regions), (char *) mp->sock_filename);
13578   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13579 }
13580
13581 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13582   (vl_api_sw_interface_vhost_user_details_t * mp)
13583 {
13584   vat_main_t *vam = &vat_main;
13585   vat_json_node_t *node = NULL;
13586
13587   if (VAT_JSON_ARRAY != vam->json_tree.type)
13588     {
13589       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13590       vat_json_init_array (&vam->json_tree);
13591     }
13592   node = vat_json_array_add (&vam->json_tree);
13593
13594   vat_json_init_object (node);
13595   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13596   vat_json_object_add_string_copy (node, "interface_name",
13597                                    mp->interface_name);
13598   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13599                             ntohl (mp->virtio_net_hdr_sz));
13600   vat_json_object_add_uint (node, "features",
13601                             clib_net_to_host_u64 (mp->features));
13602   vat_json_object_add_uint (node, "is_server", mp->is_server);
13603   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13604   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13605   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13606 }
13607
13608 static int
13609 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13610 {
13611   vl_api_sw_interface_vhost_user_dump_t *mp;
13612   vl_api_control_ping_t *mp_ping;
13613   int ret;
13614   print (vam->ofp,
13615          "Interface name            idx hdr_sz features server regions filename");
13616
13617   /* Get list of vhost-user interfaces */
13618   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13619   S (mp);
13620
13621   /* Use a control ping for synchronization */
13622   MPING (CONTROL_PING, mp_ping);
13623   S (mp_ping);
13624
13625   W (ret);
13626   return ret;
13627 }
13628
13629 static int
13630 api_show_version (vat_main_t * vam)
13631 {
13632   vl_api_show_version_t *mp;
13633   int ret;
13634
13635   M (SHOW_VERSION, mp);
13636
13637   S (mp);
13638   W (ret);
13639   return ret;
13640 }
13641
13642
13643 static int
13644 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13645 {
13646   unformat_input_t *line_input = vam->input;
13647   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13648   ip4_address_t local4, remote4;
13649   ip6_address_t local6, remote6;
13650   u8 is_add = 1;
13651   u8 ipv4_set = 0, ipv6_set = 0;
13652   u8 local_set = 0;
13653   u8 remote_set = 0;
13654   u8 grp_set = 0;
13655   u32 mcast_sw_if_index = ~0;
13656   u32 encap_vrf_id = 0;
13657   u32 decap_vrf_id = 0;
13658   u8 protocol = ~0;
13659   u32 vni;
13660   u8 vni_set = 0;
13661   int ret;
13662
13663   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13664   memset (&local4, 0, sizeof local4);
13665   memset (&remote4, 0, sizeof remote4);
13666   memset (&local6, 0, sizeof local6);
13667   memset (&remote6, 0, sizeof remote6);
13668
13669   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13670     {
13671       if (unformat (line_input, "del"))
13672         is_add = 0;
13673       else if (unformat (line_input, "local %U",
13674                          unformat_ip4_address, &local4))
13675         {
13676           local_set = 1;
13677           ipv4_set = 1;
13678         }
13679       else if (unformat (line_input, "remote %U",
13680                          unformat_ip4_address, &remote4))
13681         {
13682           remote_set = 1;
13683           ipv4_set = 1;
13684         }
13685       else if (unformat (line_input, "local %U",
13686                          unformat_ip6_address, &local6))
13687         {
13688           local_set = 1;
13689           ipv6_set = 1;
13690         }
13691       else if (unformat (line_input, "remote %U",
13692                          unformat_ip6_address, &remote6))
13693         {
13694           remote_set = 1;
13695           ipv6_set = 1;
13696         }
13697       else if (unformat (line_input, "group %U %U",
13698                          unformat_ip4_address, &remote4,
13699                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13700         {
13701           grp_set = remote_set = 1;
13702           ipv4_set = 1;
13703         }
13704       else if (unformat (line_input, "group %U",
13705                          unformat_ip4_address, &remote4))
13706         {
13707           grp_set = remote_set = 1;
13708           ipv4_set = 1;
13709         }
13710       else if (unformat (line_input, "group %U %U",
13711                          unformat_ip6_address, &remote6,
13712                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13713         {
13714           grp_set = remote_set = 1;
13715           ipv6_set = 1;
13716         }
13717       else if (unformat (line_input, "group %U",
13718                          unformat_ip6_address, &remote6))
13719         {
13720           grp_set = remote_set = 1;
13721           ipv6_set = 1;
13722         }
13723       else
13724         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13725         ;
13726       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13727         ;
13728       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13729         ;
13730       else if (unformat (line_input, "vni %d", &vni))
13731         vni_set = 1;
13732       else if (unformat (line_input, "next-ip4"))
13733         protocol = 1;
13734       else if (unformat (line_input, "next-ip6"))
13735         protocol = 2;
13736       else if (unformat (line_input, "next-ethernet"))
13737         protocol = 3;
13738       else if (unformat (line_input, "next-nsh"))
13739         protocol = 4;
13740       else
13741         {
13742           errmsg ("parse error '%U'", format_unformat_error, line_input);
13743           return -99;
13744         }
13745     }
13746
13747   if (local_set == 0)
13748     {
13749       errmsg ("tunnel local address not specified");
13750       return -99;
13751     }
13752   if (remote_set == 0)
13753     {
13754       errmsg ("tunnel remote address not specified");
13755       return -99;
13756     }
13757   if (grp_set && mcast_sw_if_index == ~0)
13758     {
13759       errmsg ("tunnel nonexistent multicast device");
13760       return -99;
13761     }
13762   if (ipv4_set && ipv6_set)
13763     {
13764       errmsg ("both IPv4 and IPv6 addresses specified");
13765       return -99;
13766     }
13767
13768   if (vni_set == 0)
13769     {
13770       errmsg ("vni not specified");
13771       return -99;
13772     }
13773
13774   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13775
13776
13777   if (ipv6_set)
13778     {
13779       clib_memcpy (&mp->local, &local6, sizeof (local6));
13780       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13781     }
13782   else
13783     {
13784       clib_memcpy (&mp->local, &local4, sizeof (local4));
13785       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13786     }
13787
13788   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13789   mp->encap_vrf_id = ntohl (encap_vrf_id);
13790   mp->decap_vrf_id = ntohl (decap_vrf_id);
13791   mp->protocol = protocol;
13792   mp->vni = ntohl (vni);
13793   mp->is_add = is_add;
13794   mp->is_ipv6 = ipv6_set;
13795
13796   S (mp);
13797   W (ret);
13798   return ret;
13799 }
13800
13801 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13802   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13803 {
13804   vat_main_t *vam = &vat_main;
13805   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13806   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13807
13808   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13809          ntohl (mp->sw_if_index),
13810          format_ip46_address, &local, IP46_TYPE_ANY,
13811          format_ip46_address, &remote, IP46_TYPE_ANY,
13812          ntohl (mp->vni), mp->protocol,
13813          ntohl (mp->mcast_sw_if_index),
13814          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13815 }
13816
13817
13818 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13819   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13820 {
13821   vat_main_t *vam = &vat_main;
13822   vat_json_node_t *node = NULL;
13823   struct in_addr ip4;
13824   struct in6_addr ip6;
13825
13826   if (VAT_JSON_ARRAY != vam->json_tree.type)
13827     {
13828       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13829       vat_json_init_array (&vam->json_tree);
13830     }
13831   node = vat_json_array_add (&vam->json_tree);
13832
13833   vat_json_init_object (node);
13834   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13835   if (mp->is_ipv6)
13836     {
13837       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13838       vat_json_object_add_ip6 (node, "local", ip6);
13839       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13840       vat_json_object_add_ip6 (node, "remote", ip6);
13841     }
13842   else
13843     {
13844       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13845       vat_json_object_add_ip4 (node, "local", ip4);
13846       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13847       vat_json_object_add_ip4 (node, "remote", ip4);
13848     }
13849   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13850   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13851   vat_json_object_add_uint (node, "mcast_sw_if_index",
13852                             ntohl (mp->mcast_sw_if_index));
13853   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13854   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13855   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13856 }
13857
13858 static int
13859 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13860 {
13861   unformat_input_t *i = vam->input;
13862   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13863   vl_api_control_ping_t *mp_ping;
13864   u32 sw_if_index;
13865   u8 sw_if_index_set = 0;
13866   int ret;
13867
13868   /* Parse args required to build the message */
13869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13870     {
13871       if (unformat (i, "sw_if_index %d", &sw_if_index))
13872         sw_if_index_set = 1;
13873       else
13874         break;
13875     }
13876
13877   if (sw_if_index_set == 0)
13878     {
13879       sw_if_index = ~0;
13880     }
13881
13882   if (!vam->json_output)
13883     {
13884       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13885              "sw_if_index", "local", "remote", "vni",
13886              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13887     }
13888
13889   /* Get list of vxlan-tunnel interfaces */
13890   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13891
13892   mp->sw_if_index = htonl (sw_if_index);
13893
13894   S (mp);
13895
13896   /* Use a control ping for synchronization */
13897   MPING (CONTROL_PING, mp_ping);
13898   S (mp_ping);
13899
13900   W (ret);
13901   return ret;
13902 }
13903
13904 static void vl_api_l2_fib_table_details_t_handler
13905   (vl_api_l2_fib_table_details_t * mp)
13906 {
13907   vat_main_t *vam = &vat_main;
13908
13909   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13910          "       %d       %d     %d",
13911          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13912          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13913          mp->bvi_mac);
13914 }
13915
13916 static void vl_api_l2_fib_table_details_t_handler_json
13917   (vl_api_l2_fib_table_details_t * mp)
13918 {
13919   vat_main_t *vam = &vat_main;
13920   vat_json_node_t *node = NULL;
13921
13922   if (VAT_JSON_ARRAY != vam->json_tree.type)
13923     {
13924       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13925       vat_json_init_array (&vam->json_tree);
13926     }
13927   node = vat_json_array_add (&vam->json_tree);
13928
13929   vat_json_init_object (node);
13930   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13931   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13932   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13933   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13934   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13935   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13936 }
13937
13938 static int
13939 api_l2_fib_table_dump (vat_main_t * vam)
13940 {
13941   unformat_input_t *i = vam->input;
13942   vl_api_l2_fib_table_dump_t *mp;
13943   vl_api_control_ping_t *mp_ping;
13944   u32 bd_id;
13945   u8 bd_id_set = 0;
13946   int ret;
13947
13948   /* Parse args required to build the message */
13949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13950     {
13951       if (unformat (i, "bd_id %d", &bd_id))
13952         bd_id_set = 1;
13953       else
13954         break;
13955     }
13956
13957   if (bd_id_set == 0)
13958     {
13959       errmsg ("missing bridge domain");
13960       return -99;
13961     }
13962
13963   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13964
13965   /* Get list of l2 fib entries */
13966   M (L2_FIB_TABLE_DUMP, mp);
13967
13968   mp->bd_id = ntohl (bd_id);
13969   S (mp);
13970
13971   /* Use a control ping for synchronization */
13972   MPING (CONTROL_PING, mp_ping);
13973   S (mp_ping);
13974
13975   W (ret);
13976   return ret;
13977 }
13978
13979
13980 static int
13981 api_interface_name_renumber (vat_main_t * vam)
13982 {
13983   unformat_input_t *line_input = vam->input;
13984   vl_api_interface_name_renumber_t *mp;
13985   u32 sw_if_index = ~0;
13986   u32 new_show_dev_instance = ~0;
13987   int ret;
13988
13989   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13990     {
13991       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13992                     &sw_if_index))
13993         ;
13994       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13995         ;
13996       else if (unformat (line_input, "new_show_dev_instance %d",
13997                          &new_show_dev_instance))
13998         ;
13999       else
14000         break;
14001     }
14002
14003   if (sw_if_index == ~0)
14004     {
14005       errmsg ("missing interface name or sw_if_index");
14006       return -99;
14007     }
14008
14009   if (new_show_dev_instance == ~0)
14010     {
14011       errmsg ("missing new_show_dev_instance");
14012       return -99;
14013     }
14014
14015   M (INTERFACE_NAME_RENUMBER, mp);
14016
14017   mp->sw_if_index = ntohl (sw_if_index);
14018   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14019
14020   S (mp);
14021   W (ret);
14022   return ret;
14023 }
14024
14025 static int
14026 api_want_ip4_arp_events (vat_main_t * vam)
14027 {
14028   unformat_input_t *line_input = vam->input;
14029   vl_api_want_ip4_arp_events_t *mp;
14030   ip4_address_t address;
14031   int address_set = 0;
14032   u32 enable_disable = 1;
14033   int ret;
14034
14035   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14036     {
14037       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14038         address_set = 1;
14039       else if (unformat (line_input, "del"))
14040         enable_disable = 0;
14041       else
14042         break;
14043     }
14044
14045   if (address_set == 0)
14046     {
14047       errmsg ("missing addresses");
14048       return -99;
14049     }
14050
14051   M (WANT_IP4_ARP_EVENTS, mp);
14052   mp->enable_disable = enable_disable;
14053   mp->pid = htonl (getpid ());
14054   mp->address = address.as_u32;
14055
14056   S (mp);
14057   W (ret);
14058   return ret;
14059 }
14060
14061 static int
14062 api_want_ip6_nd_events (vat_main_t * vam)
14063 {
14064   unformat_input_t *line_input = vam->input;
14065   vl_api_want_ip6_nd_events_t *mp;
14066   ip6_address_t address;
14067   int address_set = 0;
14068   u32 enable_disable = 1;
14069   int ret;
14070
14071   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14072     {
14073       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14074         address_set = 1;
14075       else if (unformat (line_input, "del"))
14076         enable_disable = 0;
14077       else
14078         break;
14079     }
14080
14081   if (address_set == 0)
14082     {
14083       errmsg ("missing addresses");
14084       return -99;
14085     }
14086
14087   M (WANT_IP6_ND_EVENTS, mp);
14088   mp->enable_disable = enable_disable;
14089   mp->pid = htonl (getpid ());
14090   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14091
14092   S (mp);
14093   W (ret);
14094   return ret;
14095 }
14096
14097 static int
14098 api_want_l2_macs_events (vat_main_t * vam)
14099 {
14100   unformat_input_t *line_input = vam->input;
14101   vl_api_want_l2_macs_events_t *mp;
14102   u8 enable_disable = 1;
14103   u32 scan_delay = 0;
14104   u32 max_macs_in_event = 0;
14105   u32 learn_limit = 0;
14106   int ret;
14107
14108   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14109     {
14110       if (unformat (line_input, "learn-limit %d", &learn_limit))
14111         ;
14112       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14113         ;
14114       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14115         ;
14116       else if (unformat (line_input, "disable"))
14117         enable_disable = 0;
14118       else
14119         break;
14120     }
14121
14122   M (WANT_L2_MACS_EVENTS, mp);
14123   mp->enable_disable = enable_disable;
14124   mp->pid = htonl (getpid ());
14125   mp->learn_limit = htonl (learn_limit);
14126   mp->scan_delay = (u8) scan_delay;
14127   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14128   S (mp);
14129   W (ret);
14130   return ret;
14131 }
14132
14133 static int
14134 api_input_acl_set_interface (vat_main_t * vam)
14135 {
14136   unformat_input_t *i = vam->input;
14137   vl_api_input_acl_set_interface_t *mp;
14138   u32 sw_if_index;
14139   int sw_if_index_set;
14140   u32 ip4_table_index = ~0;
14141   u32 ip6_table_index = ~0;
14142   u32 l2_table_index = ~0;
14143   u8 is_add = 1;
14144   int ret;
14145
14146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14147     {
14148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14149         sw_if_index_set = 1;
14150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14151         sw_if_index_set = 1;
14152       else if (unformat (i, "del"))
14153         is_add = 0;
14154       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14155         ;
14156       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14157         ;
14158       else if (unformat (i, "l2-table %d", &l2_table_index))
14159         ;
14160       else
14161         {
14162           clib_warning ("parse error '%U'", format_unformat_error, i);
14163           return -99;
14164         }
14165     }
14166
14167   if (sw_if_index_set == 0)
14168     {
14169       errmsg ("missing interface name or sw_if_index");
14170       return -99;
14171     }
14172
14173   M (INPUT_ACL_SET_INTERFACE, mp);
14174
14175   mp->sw_if_index = ntohl (sw_if_index);
14176   mp->ip4_table_index = ntohl (ip4_table_index);
14177   mp->ip6_table_index = ntohl (ip6_table_index);
14178   mp->l2_table_index = ntohl (l2_table_index);
14179   mp->is_add = is_add;
14180
14181   S (mp);
14182   W (ret);
14183   return ret;
14184 }
14185
14186 static int
14187 api_ip_address_dump (vat_main_t * vam)
14188 {
14189   unformat_input_t *i = vam->input;
14190   vl_api_ip_address_dump_t *mp;
14191   vl_api_control_ping_t *mp_ping;
14192   u32 sw_if_index = ~0;
14193   u8 sw_if_index_set = 0;
14194   u8 ipv4_set = 0;
14195   u8 ipv6_set = 0;
14196   int ret;
14197
14198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14199     {
14200       if (unformat (i, "sw_if_index %d", &sw_if_index))
14201         sw_if_index_set = 1;
14202       else
14203         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14204         sw_if_index_set = 1;
14205       else if (unformat (i, "ipv4"))
14206         ipv4_set = 1;
14207       else if (unformat (i, "ipv6"))
14208         ipv6_set = 1;
14209       else
14210         break;
14211     }
14212
14213   if (ipv4_set && ipv6_set)
14214     {
14215       errmsg ("ipv4 and ipv6 flags cannot be both set");
14216       return -99;
14217     }
14218
14219   if ((!ipv4_set) && (!ipv6_set))
14220     {
14221       errmsg ("no ipv4 nor ipv6 flag set");
14222       return -99;
14223     }
14224
14225   if (sw_if_index_set == 0)
14226     {
14227       errmsg ("missing interface name or sw_if_index");
14228       return -99;
14229     }
14230
14231   vam->current_sw_if_index = sw_if_index;
14232   vam->is_ipv6 = ipv6_set;
14233
14234   M (IP_ADDRESS_DUMP, mp);
14235   mp->sw_if_index = ntohl (sw_if_index);
14236   mp->is_ipv6 = ipv6_set;
14237   S (mp);
14238
14239   /* Use a control ping for synchronization */
14240   MPING (CONTROL_PING, mp_ping);
14241   S (mp_ping);
14242
14243   W (ret);
14244   return ret;
14245 }
14246
14247 static int
14248 api_ip_dump (vat_main_t * vam)
14249 {
14250   vl_api_ip_dump_t *mp;
14251   vl_api_control_ping_t *mp_ping;
14252   unformat_input_t *in = vam->input;
14253   int ipv4_set = 0;
14254   int ipv6_set = 0;
14255   int is_ipv6;
14256   int i;
14257   int ret;
14258
14259   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14260     {
14261       if (unformat (in, "ipv4"))
14262         ipv4_set = 1;
14263       else if (unformat (in, "ipv6"))
14264         ipv6_set = 1;
14265       else
14266         break;
14267     }
14268
14269   if (ipv4_set && ipv6_set)
14270     {
14271       errmsg ("ipv4 and ipv6 flags cannot be both set");
14272       return -99;
14273     }
14274
14275   if ((!ipv4_set) && (!ipv6_set))
14276     {
14277       errmsg ("no ipv4 nor ipv6 flag set");
14278       return -99;
14279     }
14280
14281   is_ipv6 = ipv6_set;
14282   vam->is_ipv6 = is_ipv6;
14283
14284   /* free old data */
14285   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14286     {
14287       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14288     }
14289   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14290
14291   M (IP_DUMP, mp);
14292   mp->is_ipv6 = ipv6_set;
14293   S (mp);
14294
14295   /* Use a control ping for synchronization */
14296   MPING (CONTROL_PING, mp_ping);
14297   S (mp_ping);
14298
14299   W (ret);
14300   return ret;
14301 }
14302
14303 static int
14304 api_ipsec_spd_add_del (vat_main_t * vam)
14305 {
14306   unformat_input_t *i = vam->input;
14307   vl_api_ipsec_spd_add_del_t *mp;
14308   u32 spd_id = ~0;
14309   u8 is_add = 1;
14310   int ret;
14311
14312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14313     {
14314       if (unformat (i, "spd_id %d", &spd_id))
14315         ;
14316       else if (unformat (i, "del"))
14317         is_add = 0;
14318       else
14319         {
14320           clib_warning ("parse error '%U'", format_unformat_error, i);
14321           return -99;
14322         }
14323     }
14324   if (spd_id == ~0)
14325     {
14326       errmsg ("spd_id must be set");
14327       return -99;
14328     }
14329
14330   M (IPSEC_SPD_ADD_DEL, mp);
14331
14332   mp->spd_id = ntohl (spd_id);
14333   mp->is_add = is_add;
14334
14335   S (mp);
14336   W (ret);
14337   return ret;
14338 }
14339
14340 static int
14341 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14342 {
14343   unformat_input_t *i = vam->input;
14344   vl_api_ipsec_interface_add_del_spd_t *mp;
14345   u32 sw_if_index;
14346   u8 sw_if_index_set = 0;
14347   u32 spd_id = (u32) ~ 0;
14348   u8 is_add = 1;
14349   int ret;
14350
14351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14352     {
14353       if (unformat (i, "del"))
14354         is_add = 0;
14355       else if (unformat (i, "spd_id %d", &spd_id))
14356         ;
14357       else
14358         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14359         sw_if_index_set = 1;
14360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14361         sw_if_index_set = 1;
14362       else
14363         {
14364           clib_warning ("parse error '%U'", format_unformat_error, i);
14365           return -99;
14366         }
14367
14368     }
14369
14370   if (spd_id == (u32) ~ 0)
14371     {
14372       errmsg ("spd_id must be set");
14373       return -99;
14374     }
14375
14376   if (sw_if_index_set == 0)
14377     {
14378       errmsg ("missing interface name or sw_if_index");
14379       return -99;
14380     }
14381
14382   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14383
14384   mp->spd_id = ntohl (spd_id);
14385   mp->sw_if_index = ntohl (sw_if_index);
14386   mp->is_add = is_add;
14387
14388   S (mp);
14389   W (ret);
14390   return ret;
14391 }
14392
14393 static int
14394 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14395 {
14396   unformat_input_t *i = vam->input;
14397   vl_api_ipsec_spd_add_del_entry_t *mp;
14398   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14399   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14400   i32 priority = 0;
14401   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14402   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14403   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14404   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14405   int ret;
14406
14407   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14408   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14409   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14410   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14411   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14412   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14413
14414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14415     {
14416       if (unformat (i, "del"))
14417         is_add = 0;
14418       if (unformat (i, "outbound"))
14419         is_outbound = 1;
14420       if (unformat (i, "inbound"))
14421         is_outbound = 0;
14422       else if (unformat (i, "spd_id %d", &spd_id))
14423         ;
14424       else if (unformat (i, "sa_id %d", &sa_id))
14425         ;
14426       else if (unformat (i, "priority %d", &priority))
14427         ;
14428       else if (unformat (i, "protocol %d", &protocol))
14429         ;
14430       else if (unformat (i, "lport_start %d", &lport_start))
14431         ;
14432       else if (unformat (i, "lport_stop %d", &lport_stop))
14433         ;
14434       else if (unformat (i, "rport_start %d", &rport_start))
14435         ;
14436       else if (unformat (i, "rport_stop %d", &rport_stop))
14437         ;
14438       else
14439         if (unformat
14440             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14441         {
14442           is_ipv6 = 0;
14443           is_ip_any = 0;
14444         }
14445       else
14446         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14447         {
14448           is_ipv6 = 0;
14449           is_ip_any = 0;
14450         }
14451       else
14452         if (unformat
14453             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14454         {
14455           is_ipv6 = 0;
14456           is_ip_any = 0;
14457         }
14458       else
14459         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14460         {
14461           is_ipv6 = 0;
14462           is_ip_any = 0;
14463         }
14464       else
14465         if (unformat
14466             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14467         {
14468           is_ipv6 = 1;
14469           is_ip_any = 0;
14470         }
14471       else
14472         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14473         {
14474           is_ipv6 = 1;
14475           is_ip_any = 0;
14476         }
14477       else
14478         if (unformat
14479             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14480         {
14481           is_ipv6 = 1;
14482           is_ip_any = 0;
14483         }
14484       else
14485         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14486         {
14487           is_ipv6 = 1;
14488           is_ip_any = 0;
14489         }
14490       else
14491         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14492         {
14493           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14494             {
14495               clib_warning ("unsupported action: 'resolve'");
14496               return -99;
14497             }
14498         }
14499       else
14500         {
14501           clib_warning ("parse error '%U'", format_unformat_error, i);
14502           return -99;
14503         }
14504
14505     }
14506
14507   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14508
14509   mp->spd_id = ntohl (spd_id);
14510   mp->priority = ntohl (priority);
14511   mp->is_outbound = is_outbound;
14512
14513   mp->is_ipv6 = is_ipv6;
14514   if (is_ipv6 || is_ip_any)
14515     {
14516       clib_memcpy (mp->remote_address_start, &raddr6_start,
14517                    sizeof (ip6_address_t));
14518       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14519                    sizeof (ip6_address_t));
14520       clib_memcpy (mp->local_address_start, &laddr6_start,
14521                    sizeof (ip6_address_t));
14522       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14523                    sizeof (ip6_address_t));
14524     }
14525   else
14526     {
14527       clib_memcpy (mp->remote_address_start, &raddr4_start,
14528                    sizeof (ip4_address_t));
14529       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14530                    sizeof (ip4_address_t));
14531       clib_memcpy (mp->local_address_start, &laddr4_start,
14532                    sizeof (ip4_address_t));
14533       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14534                    sizeof (ip4_address_t));
14535     }
14536   mp->protocol = (u8) protocol;
14537   mp->local_port_start = ntohs ((u16) lport_start);
14538   mp->local_port_stop = ntohs ((u16) lport_stop);
14539   mp->remote_port_start = ntohs ((u16) rport_start);
14540   mp->remote_port_stop = ntohs ((u16) rport_stop);
14541   mp->policy = (u8) policy;
14542   mp->sa_id = ntohl (sa_id);
14543   mp->is_add = is_add;
14544   mp->is_ip_any = is_ip_any;
14545   S (mp);
14546   W (ret);
14547   return ret;
14548 }
14549
14550 static int
14551 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14552 {
14553   unformat_input_t *i = vam->input;
14554   vl_api_ipsec_sad_add_del_entry_t *mp;
14555   u32 sad_id = 0, spi = 0;
14556   u8 *ck = 0, *ik = 0;
14557   u8 is_add = 1;
14558
14559   u8 protocol = IPSEC_PROTOCOL_AH;
14560   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14561   u32 crypto_alg = 0, integ_alg = 0;
14562   ip4_address_t tun_src4;
14563   ip4_address_t tun_dst4;
14564   ip6_address_t tun_src6;
14565   ip6_address_t tun_dst6;
14566   int ret;
14567
14568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14569     {
14570       if (unformat (i, "del"))
14571         is_add = 0;
14572       else if (unformat (i, "sad_id %d", &sad_id))
14573         ;
14574       else if (unformat (i, "spi %d", &spi))
14575         ;
14576       else if (unformat (i, "esp"))
14577         protocol = IPSEC_PROTOCOL_ESP;
14578       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14579         {
14580           is_tunnel = 1;
14581           is_tunnel_ipv6 = 0;
14582         }
14583       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14584         {
14585           is_tunnel = 1;
14586           is_tunnel_ipv6 = 0;
14587         }
14588       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14589         {
14590           is_tunnel = 1;
14591           is_tunnel_ipv6 = 1;
14592         }
14593       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14594         {
14595           is_tunnel = 1;
14596           is_tunnel_ipv6 = 1;
14597         }
14598       else
14599         if (unformat
14600             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14601         {
14602           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14603               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14604             {
14605               clib_warning ("unsupported crypto-alg: '%U'",
14606                             format_ipsec_crypto_alg, crypto_alg);
14607               return -99;
14608             }
14609         }
14610       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14611         ;
14612       else
14613         if (unformat
14614             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14615         {
14616           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14617               integ_alg >= IPSEC_INTEG_N_ALG)
14618             {
14619               clib_warning ("unsupported integ-alg: '%U'",
14620                             format_ipsec_integ_alg, integ_alg);
14621               return -99;
14622             }
14623         }
14624       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14625         ;
14626       else
14627         {
14628           clib_warning ("parse error '%U'", format_unformat_error, i);
14629           return -99;
14630         }
14631
14632     }
14633
14634   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14635
14636   mp->sad_id = ntohl (sad_id);
14637   mp->is_add = is_add;
14638   mp->protocol = protocol;
14639   mp->spi = ntohl (spi);
14640   mp->is_tunnel = is_tunnel;
14641   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14642   mp->crypto_algorithm = crypto_alg;
14643   mp->integrity_algorithm = integ_alg;
14644   mp->crypto_key_length = vec_len (ck);
14645   mp->integrity_key_length = vec_len (ik);
14646
14647   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14648     mp->crypto_key_length = sizeof (mp->crypto_key);
14649
14650   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14651     mp->integrity_key_length = sizeof (mp->integrity_key);
14652
14653   if (ck)
14654     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14655   if (ik)
14656     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14657
14658   if (is_tunnel)
14659     {
14660       if (is_tunnel_ipv6)
14661         {
14662           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14663                        sizeof (ip6_address_t));
14664           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14665                        sizeof (ip6_address_t));
14666         }
14667       else
14668         {
14669           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14670                        sizeof (ip4_address_t));
14671           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14672                        sizeof (ip4_address_t));
14673         }
14674     }
14675
14676   S (mp);
14677   W (ret);
14678   return ret;
14679 }
14680
14681 static int
14682 api_ipsec_sa_set_key (vat_main_t * vam)
14683 {
14684   unformat_input_t *i = vam->input;
14685   vl_api_ipsec_sa_set_key_t *mp;
14686   u32 sa_id;
14687   u8 *ck = 0, *ik = 0;
14688   int ret;
14689
14690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14691     {
14692       if (unformat (i, "sa_id %d", &sa_id))
14693         ;
14694       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14695         ;
14696       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14697         ;
14698       else
14699         {
14700           clib_warning ("parse error '%U'", format_unformat_error, i);
14701           return -99;
14702         }
14703     }
14704
14705   M (IPSEC_SA_SET_KEY, mp);
14706
14707   mp->sa_id = ntohl (sa_id);
14708   mp->crypto_key_length = vec_len (ck);
14709   mp->integrity_key_length = vec_len (ik);
14710
14711   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14712     mp->crypto_key_length = sizeof (mp->crypto_key);
14713
14714   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14715     mp->integrity_key_length = sizeof (mp->integrity_key);
14716
14717   if (ck)
14718     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14719   if (ik)
14720     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14721
14722   S (mp);
14723   W (ret);
14724   return ret;
14725 }
14726
14727 static int
14728 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14729 {
14730   unformat_input_t *i = vam->input;
14731   vl_api_ipsec_tunnel_if_add_del_t *mp;
14732   u32 local_spi = 0, remote_spi = 0;
14733   u32 crypto_alg = 0, integ_alg = 0;
14734   u8 *lck = NULL, *rck = NULL;
14735   u8 *lik = NULL, *rik = NULL;
14736   ip4_address_t local_ip = { {0} };
14737   ip4_address_t remote_ip = { {0} };
14738   u8 is_add = 1;
14739   u8 esn = 0;
14740   u8 anti_replay = 0;
14741   int ret;
14742
14743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14744     {
14745       if (unformat (i, "del"))
14746         is_add = 0;
14747       else if (unformat (i, "esn"))
14748         esn = 1;
14749       else if (unformat (i, "anti_replay"))
14750         anti_replay = 1;
14751       else if (unformat (i, "local_spi %d", &local_spi))
14752         ;
14753       else if (unformat (i, "remote_spi %d", &remote_spi))
14754         ;
14755       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14756         ;
14757       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14758         ;
14759       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14760         ;
14761       else
14762         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14763         ;
14764       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14765         ;
14766       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14767         ;
14768       else
14769         if (unformat
14770             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14771         {
14772           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14773               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14774             {
14775               errmsg ("unsupported crypto-alg: '%U'\n",
14776                       format_ipsec_crypto_alg, crypto_alg);
14777               return -99;
14778             }
14779         }
14780       else
14781         if (unformat
14782             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14783         {
14784           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14785               integ_alg >= IPSEC_INTEG_N_ALG)
14786             {
14787               errmsg ("unsupported integ-alg: '%U'\n",
14788                       format_ipsec_integ_alg, integ_alg);
14789               return -99;
14790             }
14791         }
14792       else
14793         {
14794           errmsg ("parse error '%U'\n", format_unformat_error, i);
14795           return -99;
14796         }
14797     }
14798
14799   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14800
14801   mp->is_add = is_add;
14802   mp->esn = esn;
14803   mp->anti_replay = anti_replay;
14804
14805   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14806   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14807
14808   mp->local_spi = htonl (local_spi);
14809   mp->remote_spi = htonl (remote_spi);
14810   mp->crypto_alg = (u8) crypto_alg;
14811
14812   mp->local_crypto_key_len = 0;
14813   if (lck)
14814     {
14815       mp->local_crypto_key_len = vec_len (lck);
14816       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14817         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14818       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14819     }
14820
14821   mp->remote_crypto_key_len = 0;
14822   if (rck)
14823     {
14824       mp->remote_crypto_key_len = vec_len (rck);
14825       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14826         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14827       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14828     }
14829
14830   mp->integ_alg = (u8) integ_alg;
14831
14832   mp->local_integ_key_len = 0;
14833   if (lik)
14834     {
14835       mp->local_integ_key_len = vec_len (lik);
14836       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14837         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14838       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14839     }
14840
14841   mp->remote_integ_key_len = 0;
14842   if (rik)
14843     {
14844       mp->remote_integ_key_len = vec_len (rik);
14845       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14846         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14847       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14848     }
14849
14850   S (mp);
14851   W (ret);
14852   return ret;
14853 }
14854
14855 static void
14856 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14857 {
14858   vat_main_t *vam = &vat_main;
14859
14860   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14861          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14862          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14863          "tunnel_src_addr %U tunnel_dst_addr %U "
14864          "salt %u seq_outbound %lu last_seq_inbound %lu "
14865          "replay_window %lu total_data_size %lu\n",
14866          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14867          mp->protocol,
14868          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14869          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14870          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14871          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14872          mp->tunnel_src_addr,
14873          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14874          mp->tunnel_dst_addr,
14875          ntohl (mp->salt),
14876          clib_net_to_host_u64 (mp->seq_outbound),
14877          clib_net_to_host_u64 (mp->last_seq_inbound),
14878          clib_net_to_host_u64 (mp->replay_window),
14879          clib_net_to_host_u64 (mp->total_data_size));
14880 }
14881
14882 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14883 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14884
14885 static void vl_api_ipsec_sa_details_t_handler_json
14886   (vl_api_ipsec_sa_details_t * mp)
14887 {
14888   vat_main_t *vam = &vat_main;
14889   vat_json_node_t *node = NULL;
14890   struct in_addr src_ip4, dst_ip4;
14891   struct in6_addr src_ip6, dst_ip6;
14892
14893   if (VAT_JSON_ARRAY != vam->json_tree.type)
14894     {
14895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14896       vat_json_init_array (&vam->json_tree);
14897     }
14898   node = vat_json_array_add (&vam->json_tree);
14899
14900   vat_json_init_object (node);
14901   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14902   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14903   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14904   vat_json_object_add_uint (node, "proto", mp->protocol);
14905   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14906   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14907   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14908   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14909   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14910   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14911   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14912                              mp->crypto_key_len);
14913   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14914                              mp->integ_key_len);
14915   if (mp->is_tunnel_ip6)
14916     {
14917       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14918       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14919       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14920       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14921     }
14922   else
14923     {
14924       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14925       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14926       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14927       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14928     }
14929   vat_json_object_add_uint (node, "replay_window",
14930                             clib_net_to_host_u64 (mp->replay_window));
14931   vat_json_object_add_uint (node, "total_data_size",
14932                             clib_net_to_host_u64 (mp->total_data_size));
14933
14934 }
14935
14936 static int
14937 api_ipsec_sa_dump (vat_main_t * vam)
14938 {
14939   unformat_input_t *i = vam->input;
14940   vl_api_ipsec_sa_dump_t *mp;
14941   vl_api_control_ping_t *mp_ping;
14942   u32 sa_id = ~0;
14943   int ret;
14944
14945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14946     {
14947       if (unformat (i, "sa_id %d", &sa_id))
14948         ;
14949       else
14950         {
14951           clib_warning ("parse error '%U'", format_unformat_error, i);
14952           return -99;
14953         }
14954     }
14955
14956   M (IPSEC_SA_DUMP, mp);
14957
14958   mp->sa_id = ntohl (sa_id);
14959
14960   S (mp);
14961
14962   /* Use a control ping for synchronization */
14963   M (CONTROL_PING, mp_ping);
14964   S (mp_ping);
14965
14966   W (ret);
14967   return ret;
14968 }
14969
14970 static int
14971 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14972 {
14973   unformat_input_t *i = vam->input;
14974   vl_api_ipsec_tunnel_if_set_key_t *mp;
14975   u32 sw_if_index = ~0;
14976   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14977   u8 *key = 0;
14978   u32 alg = ~0;
14979   int ret;
14980
14981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14982     {
14983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14984         ;
14985       else
14986         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14987         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14988       else
14989         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14990         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14991       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14992         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14993       else
14994         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14995         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14996       else if (unformat (i, "%U", unformat_hex_string, &key))
14997         ;
14998       else
14999         {
15000           clib_warning ("parse error '%U'", format_unformat_error, i);
15001           return -99;
15002         }
15003     }
15004
15005   if (sw_if_index == ~0)
15006     {
15007       errmsg ("interface must be specified");
15008       return -99;
15009     }
15010
15011   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15012     {
15013       errmsg ("key type must be specified");
15014       return -99;
15015     }
15016
15017   if (alg == ~0)
15018     {
15019       errmsg ("algorithm must be specified");
15020       return -99;
15021     }
15022
15023   if (vec_len (key) == 0)
15024     {
15025       errmsg ("key must be specified");
15026       return -99;
15027     }
15028
15029   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15030
15031   mp->sw_if_index = htonl (sw_if_index);
15032   mp->alg = alg;
15033   mp->key_type = key_type;
15034   mp->key_len = vec_len (key);
15035   clib_memcpy (mp->key, key, vec_len (key));
15036
15037   S (mp);
15038   W (ret);
15039
15040   return ret;
15041 }
15042
15043 static int
15044 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15045 {
15046   unformat_input_t *i = vam->input;
15047   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15048   u32 sw_if_index = ~0;
15049   u32 sa_id = ~0;
15050   u8 is_outbound = (u8) ~ 0;
15051   int ret;
15052
15053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15054     {
15055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15056         ;
15057       else if (unformat (i, "sa_id %d", &sa_id))
15058         ;
15059       else if (unformat (i, "outbound"))
15060         is_outbound = 1;
15061       else if (unformat (i, "inbound"))
15062         is_outbound = 0;
15063       else
15064         {
15065           clib_warning ("parse error '%U'", format_unformat_error, i);
15066           return -99;
15067         }
15068     }
15069
15070   if (sw_if_index == ~0)
15071     {
15072       errmsg ("interface must be specified");
15073       return -99;
15074     }
15075
15076   if (sa_id == ~0)
15077     {
15078       errmsg ("SA ID must be specified");
15079       return -99;
15080     }
15081
15082   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15083
15084   mp->sw_if_index = htonl (sw_if_index);
15085   mp->sa_id = htonl (sa_id);
15086   mp->is_outbound = is_outbound;
15087
15088   S (mp);
15089   W (ret);
15090
15091   return ret;
15092 }
15093
15094 static int
15095 api_ikev2_profile_add_del (vat_main_t * vam)
15096 {
15097   unformat_input_t *i = vam->input;
15098   vl_api_ikev2_profile_add_del_t *mp;
15099   u8 is_add = 1;
15100   u8 *name = 0;
15101   int ret;
15102
15103   const char *valid_chars = "a-zA-Z0-9_";
15104
15105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15106     {
15107       if (unformat (i, "del"))
15108         is_add = 0;
15109       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15110         vec_add1 (name, 0);
15111       else
15112         {
15113           errmsg ("parse error '%U'", format_unformat_error, i);
15114           return -99;
15115         }
15116     }
15117
15118   if (!vec_len (name))
15119     {
15120       errmsg ("profile name must be specified");
15121       return -99;
15122     }
15123
15124   if (vec_len (name) > 64)
15125     {
15126       errmsg ("profile name too long");
15127       return -99;
15128     }
15129
15130   M (IKEV2_PROFILE_ADD_DEL, mp);
15131
15132   clib_memcpy (mp->name, name, vec_len (name));
15133   mp->is_add = is_add;
15134   vec_free (name);
15135
15136   S (mp);
15137   W (ret);
15138   return ret;
15139 }
15140
15141 static int
15142 api_ikev2_profile_set_auth (vat_main_t * vam)
15143 {
15144   unformat_input_t *i = vam->input;
15145   vl_api_ikev2_profile_set_auth_t *mp;
15146   u8 *name = 0;
15147   u8 *data = 0;
15148   u32 auth_method = 0;
15149   u8 is_hex = 0;
15150   int ret;
15151
15152   const char *valid_chars = "a-zA-Z0-9_";
15153
15154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15155     {
15156       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15157         vec_add1 (name, 0);
15158       else if (unformat (i, "auth_method %U",
15159                          unformat_ikev2_auth_method, &auth_method))
15160         ;
15161       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15162         is_hex = 1;
15163       else if (unformat (i, "auth_data %v", &data))
15164         ;
15165       else
15166         {
15167           errmsg ("parse error '%U'", format_unformat_error, i);
15168           return -99;
15169         }
15170     }
15171
15172   if (!vec_len (name))
15173     {
15174       errmsg ("profile name must be specified");
15175       return -99;
15176     }
15177
15178   if (vec_len (name) > 64)
15179     {
15180       errmsg ("profile name too long");
15181       return -99;
15182     }
15183
15184   if (!vec_len (data))
15185     {
15186       errmsg ("auth_data must be specified");
15187       return -99;
15188     }
15189
15190   if (!auth_method)
15191     {
15192       errmsg ("auth_method must be specified");
15193       return -99;
15194     }
15195
15196   M (IKEV2_PROFILE_SET_AUTH, mp);
15197
15198   mp->is_hex = is_hex;
15199   mp->auth_method = (u8) auth_method;
15200   mp->data_len = vec_len (data);
15201   clib_memcpy (mp->name, name, vec_len (name));
15202   clib_memcpy (mp->data, data, vec_len (data));
15203   vec_free (name);
15204   vec_free (data);
15205
15206   S (mp);
15207   W (ret);
15208   return ret;
15209 }
15210
15211 static int
15212 api_ikev2_profile_set_id (vat_main_t * vam)
15213 {
15214   unformat_input_t *i = vam->input;
15215   vl_api_ikev2_profile_set_id_t *mp;
15216   u8 *name = 0;
15217   u8 *data = 0;
15218   u8 is_local = 0;
15219   u32 id_type = 0;
15220   ip4_address_t ip4;
15221   int ret;
15222
15223   const char *valid_chars = "a-zA-Z0-9_";
15224
15225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15226     {
15227       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15228         vec_add1 (name, 0);
15229       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15230         ;
15231       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15232         {
15233           data = vec_new (u8, 4);
15234           clib_memcpy (data, ip4.as_u8, 4);
15235         }
15236       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15237         ;
15238       else if (unformat (i, "id_data %v", &data))
15239         ;
15240       else if (unformat (i, "local"))
15241         is_local = 1;
15242       else if (unformat (i, "remote"))
15243         is_local = 0;
15244       else
15245         {
15246           errmsg ("parse error '%U'", format_unformat_error, i);
15247           return -99;
15248         }
15249     }
15250
15251   if (!vec_len (name))
15252     {
15253       errmsg ("profile name must be specified");
15254       return -99;
15255     }
15256
15257   if (vec_len (name) > 64)
15258     {
15259       errmsg ("profile name too long");
15260       return -99;
15261     }
15262
15263   if (!vec_len (data))
15264     {
15265       errmsg ("id_data must be specified");
15266       return -99;
15267     }
15268
15269   if (!id_type)
15270     {
15271       errmsg ("id_type must be specified");
15272       return -99;
15273     }
15274
15275   M (IKEV2_PROFILE_SET_ID, mp);
15276
15277   mp->is_local = is_local;
15278   mp->id_type = (u8) id_type;
15279   mp->data_len = vec_len (data);
15280   clib_memcpy (mp->name, name, vec_len (name));
15281   clib_memcpy (mp->data, data, vec_len (data));
15282   vec_free (name);
15283   vec_free (data);
15284
15285   S (mp);
15286   W (ret);
15287   return ret;
15288 }
15289
15290 static int
15291 api_ikev2_profile_set_ts (vat_main_t * vam)
15292 {
15293   unformat_input_t *i = vam->input;
15294   vl_api_ikev2_profile_set_ts_t *mp;
15295   u8 *name = 0;
15296   u8 is_local = 0;
15297   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15298   ip4_address_t start_addr, end_addr;
15299
15300   const char *valid_chars = "a-zA-Z0-9_";
15301   int ret;
15302
15303   start_addr.as_u32 = 0;
15304   end_addr.as_u32 = (u32) ~ 0;
15305
15306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15307     {
15308       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15309         vec_add1 (name, 0);
15310       else if (unformat (i, "protocol %d", &proto))
15311         ;
15312       else if (unformat (i, "start_port %d", &start_port))
15313         ;
15314       else if (unformat (i, "end_port %d", &end_port))
15315         ;
15316       else
15317         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15318         ;
15319       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15320         ;
15321       else if (unformat (i, "local"))
15322         is_local = 1;
15323       else if (unformat (i, "remote"))
15324         is_local = 0;
15325       else
15326         {
15327           errmsg ("parse error '%U'", format_unformat_error, i);
15328           return -99;
15329         }
15330     }
15331
15332   if (!vec_len (name))
15333     {
15334       errmsg ("profile name must be specified");
15335       return -99;
15336     }
15337
15338   if (vec_len (name) > 64)
15339     {
15340       errmsg ("profile name too long");
15341       return -99;
15342     }
15343
15344   M (IKEV2_PROFILE_SET_TS, mp);
15345
15346   mp->is_local = is_local;
15347   mp->proto = (u8) proto;
15348   mp->start_port = (u16) start_port;
15349   mp->end_port = (u16) end_port;
15350   mp->start_addr = start_addr.as_u32;
15351   mp->end_addr = end_addr.as_u32;
15352   clib_memcpy (mp->name, name, vec_len (name));
15353   vec_free (name);
15354
15355   S (mp);
15356   W (ret);
15357   return ret;
15358 }
15359
15360 static int
15361 api_ikev2_set_local_key (vat_main_t * vam)
15362 {
15363   unformat_input_t *i = vam->input;
15364   vl_api_ikev2_set_local_key_t *mp;
15365   u8 *file = 0;
15366   int ret;
15367
15368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15369     {
15370       if (unformat (i, "file %v", &file))
15371         vec_add1 (file, 0);
15372       else
15373         {
15374           errmsg ("parse error '%U'", format_unformat_error, i);
15375           return -99;
15376         }
15377     }
15378
15379   if (!vec_len (file))
15380     {
15381       errmsg ("RSA key file must be specified");
15382       return -99;
15383     }
15384
15385   if (vec_len (file) > 256)
15386     {
15387       errmsg ("file name too long");
15388       return -99;
15389     }
15390
15391   M (IKEV2_SET_LOCAL_KEY, mp);
15392
15393   clib_memcpy (mp->key_file, file, vec_len (file));
15394   vec_free (file);
15395
15396   S (mp);
15397   W (ret);
15398   return ret;
15399 }
15400
15401 static int
15402 api_ikev2_set_responder (vat_main_t * vam)
15403 {
15404   unformat_input_t *i = vam->input;
15405   vl_api_ikev2_set_responder_t *mp;
15406   int ret;
15407   u8 *name = 0;
15408   u32 sw_if_index = ~0;
15409   ip4_address_t address;
15410
15411   const char *valid_chars = "a-zA-Z0-9_";
15412
15413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15414     {
15415       if (unformat
15416           (i, "%U interface %d address %U", unformat_token, valid_chars,
15417            &name, &sw_if_index, unformat_ip4_address, &address))
15418         vec_add1 (name, 0);
15419       else
15420         {
15421           errmsg ("parse error '%U'", format_unformat_error, i);
15422           return -99;
15423         }
15424     }
15425
15426   if (!vec_len (name))
15427     {
15428       errmsg ("profile name must be specified");
15429       return -99;
15430     }
15431
15432   if (vec_len (name) > 64)
15433     {
15434       errmsg ("profile name too long");
15435       return -99;
15436     }
15437
15438   M (IKEV2_SET_RESPONDER, mp);
15439
15440   clib_memcpy (mp->name, name, vec_len (name));
15441   vec_free (name);
15442
15443   mp->sw_if_index = sw_if_index;
15444   clib_memcpy (mp->address, &address, sizeof (address));
15445
15446   S (mp);
15447   W (ret);
15448   return ret;
15449 }
15450
15451 static int
15452 api_ikev2_set_ike_transforms (vat_main_t * vam)
15453 {
15454   unformat_input_t *i = vam->input;
15455   vl_api_ikev2_set_ike_transforms_t *mp;
15456   int ret;
15457   u8 *name = 0;
15458   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15459
15460   const char *valid_chars = "a-zA-Z0-9_";
15461
15462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15463     {
15464       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15465                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15466         vec_add1 (name, 0);
15467       else
15468         {
15469           errmsg ("parse error '%U'", format_unformat_error, i);
15470           return -99;
15471         }
15472     }
15473
15474   if (!vec_len (name))
15475     {
15476       errmsg ("profile name must be specified");
15477       return -99;
15478     }
15479
15480   if (vec_len (name) > 64)
15481     {
15482       errmsg ("profile name too long");
15483       return -99;
15484     }
15485
15486   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15487
15488   clib_memcpy (mp->name, name, vec_len (name));
15489   vec_free (name);
15490   mp->crypto_alg = crypto_alg;
15491   mp->crypto_key_size = crypto_key_size;
15492   mp->integ_alg = integ_alg;
15493   mp->dh_group = dh_group;
15494
15495   S (mp);
15496   W (ret);
15497   return ret;
15498 }
15499
15500
15501 static int
15502 api_ikev2_set_esp_transforms (vat_main_t * vam)
15503 {
15504   unformat_input_t *i = vam->input;
15505   vl_api_ikev2_set_esp_transforms_t *mp;
15506   int ret;
15507   u8 *name = 0;
15508   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15509
15510   const char *valid_chars = "a-zA-Z0-9_";
15511
15512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15513     {
15514       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15515                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15516         vec_add1 (name, 0);
15517       else
15518         {
15519           errmsg ("parse error '%U'", format_unformat_error, i);
15520           return -99;
15521         }
15522     }
15523
15524   if (!vec_len (name))
15525     {
15526       errmsg ("profile name must be specified");
15527       return -99;
15528     }
15529
15530   if (vec_len (name) > 64)
15531     {
15532       errmsg ("profile name too long");
15533       return -99;
15534     }
15535
15536   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15537
15538   clib_memcpy (mp->name, name, vec_len (name));
15539   vec_free (name);
15540   mp->crypto_alg = crypto_alg;
15541   mp->crypto_key_size = crypto_key_size;
15542   mp->integ_alg = integ_alg;
15543   mp->dh_group = dh_group;
15544
15545   S (mp);
15546   W (ret);
15547   return ret;
15548 }
15549
15550 static int
15551 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15552 {
15553   unformat_input_t *i = vam->input;
15554   vl_api_ikev2_set_sa_lifetime_t *mp;
15555   int ret;
15556   u8 *name = 0;
15557   u64 lifetime, lifetime_maxdata;
15558   u32 lifetime_jitter, handover;
15559
15560   const char *valid_chars = "a-zA-Z0-9_";
15561
15562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15563     {
15564       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15565                     &lifetime, &lifetime_jitter, &handover,
15566                     &lifetime_maxdata))
15567         vec_add1 (name, 0);
15568       else
15569         {
15570           errmsg ("parse error '%U'", format_unformat_error, i);
15571           return -99;
15572         }
15573     }
15574
15575   if (!vec_len (name))
15576     {
15577       errmsg ("profile name must be specified");
15578       return -99;
15579     }
15580
15581   if (vec_len (name) > 64)
15582     {
15583       errmsg ("profile name too long");
15584       return -99;
15585     }
15586
15587   M (IKEV2_SET_SA_LIFETIME, mp);
15588
15589   clib_memcpy (mp->name, name, vec_len (name));
15590   vec_free (name);
15591   mp->lifetime = lifetime;
15592   mp->lifetime_jitter = lifetime_jitter;
15593   mp->handover = handover;
15594   mp->lifetime_maxdata = lifetime_maxdata;
15595
15596   S (mp);
15597   W (ret);
15598   return ret;
15599 }
15600
15601 static int
15602 api_ikev2_initiate_sa_init (vat_main_t * vam)
15603 {
15604   unformat_input_t *i = vam->input;
15605   vl_api_ikev2_initiate_sa_init_t *mp;
15606   int ret;
15607   u8 *name = 0;
15608
15609   const char *valid_chars = "a-zA-Z0-9_";
15610
15611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15612     {
15613       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15614         vec_add1 (name, 0);
15615       else
15616         {
15617           errmsg ("parse error '%U'", format_unformat_error, i);
15618           return -99;
15619         }
15620     }
15621
15622   if (!vec_len (name))
15623     {
15624       errmsg ("profile name must be specified");
15625       return -99;
15626     }
15627
15628   if (vec_len (name) > 64)
15629     {
15630       errmsg ("profile name too long");
15631       return -99;
15632     }
15633
15634   M (IKEV2_INITIATE_SA_INIT, mp);
15635
15636   clib_memcpy (mp->name, name, vec_len (name));
15637   vec_free (name);
15638
15639   S (mp);
15640   W (ret);
15641   return ret;
15642 }
15643
15644 static int
15645 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15646 {
15647   unformat_input_t *i = vam->input;
15648   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15649   int ret;
15650   u64 ispi;
15651
15652
15653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15654     {
15655       if (unformat (i, "%lx", &ispi))
15656         ;
15657       else
15658         {
15659           errmsg ("parse error '%U'", format_unformat_error, i);
15660           return -99;
15661         }
15662     }
15663
15664   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15665
15666   mp->ispi = ispi;
15667
15668   S (mp);
15669   W (ret);
15670   return ret;
15671 }
15672
15673 static int
15674 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15675 {
15676   unformat_input_t *i = vam->input;
15677   vl_api_ikev2_initiate_del_child_sa_t *mp;
15678   int ret;
15679   u32 ispi;
15680
15681
15682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15683     {
15684       if (unformat (i, "%x", &ispi))
15685         ;
15686       else
15687         {
15688           errmsg ("parse error '%U'", format_unformat_error, i);
15689           return -99;
15690         }
15691     }
15692
15693   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15694
15695   mp->ispi = ispi;
15696
15697   S (mp);
15698   W (ret);
15699   return ret;
15700 }
15701
15702 static int
15703 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15704 {
15705   unformat_input_t *i = vam->input;
15706   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15707   int ret;
15708   u32 ispi;
15709
15710
15711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15712     {
15713       if (unformat (i, "%x", &ispi))
15714         ;
15715       else
15716         {
15717           errmsg ("parse error '%U'", format_unformat_error, i);
15718           return -99;
15719         }
15720     }
15721
15722   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15723
15724   mp->ispi = ispi;
15725
15726   S (mp);
15727   W (ret);
15728   return ret;
15729 }
15730
15731 /*
15732  * MAP
15733  */
15734 static int
15735 api_map_add_domain (vat_main_t * vam)
15736 {
15737   unformat_input_t *i = vam->input;
15738   vl_api_map_add_domain_t *mp;
15739
15740   ip4_address_t ip4_prefix;
15741   ip6_address_t ip6_prefix;
15742   ip6_address_t ip6_src;
15743   u32 num_m_args = 0;
15744   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15745     0, psid_length = 0;
15746   u8 is_translation = 0;
15747   u32 mtu = 0;
15748   u32 ip6_src_len = 128;
15749   int ret;
15750
15751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15752     {
15753       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15754                     &ip4_prefix, &ip4_prefix_len))
15755         num_m_args++;
15756       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15757                          &ip6_prefix, &ip6_prefix_len))
15758         num_m_args++;
15759       else
15760         if (unformat
15761             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15762              &ip6_src_len))
15763         num_m_args++;
15764       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15765         num_m_args++;
15766       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15767         num_m_args++;
15768       else if (unformat (i, "psid-offset %d", &psid_offset))
15769         num_m_args++;
15770       else if (unformat (i, "psid-len %d", &psid_length))
15771         num_m_args++;
15772       else if (unformat (i, "mtu %d", &mtu))
15773         num_m_args++;
15774       else if (unformat (i, "map-t"))
15775         is_translation = 1;
15776       else
15777         {
15778           clib_warning ("parse error '%U'", format_unformat_error, i);
15779           return -99;
15780         }
15781     }
15782
15783   if (num_m_args < 3)
15784     {
15785       errmsg ("mandatory argument(s) missing");
15786       return -99;
15787     }
15788
15789   /* Construct the API message */
15790   M (MAP_ADD_DOMAIN, mp);
15791
15792   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15793   mp->ip4_prefix_len = ip4_prefix_len;
15794
15795   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15796   mp->ip6_prefix_len = ip6_prefix_len;
15797
15798   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15799   mp->ip6_src_prefix_len = ip6_src_len;
15800
15801   mp->ea_bits_len = ea_bits_len;
15802   mp->psid_offset = psid_offset;
15803   mp->psid_length = psid_length;
15804   mp->is_translation = is_translation;
15805   mp->mtu = htons (mtu);
15806
15807   /* send it... */
15808   S (mp);
15809
15810   /* Wait for a reply, return good/bad news  */
15811   W (ret);
15812   return ret;
15813 }
15814
15815 static int
15816 api_map_del_domain (vat_main_t * vam)
15817 {
15818   unformat_input_t *i = vam->input;
15819   vl_api_map_del_domain_t *mp;
15820
15821   u32 num_m_args = 0;
15822   u32 index;
15823   int ret;
15824
15825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15826     {
15827       if (unformat (i, "index %d", &index))
15828         num_m_args++;
15829       else
15830         {
15831           clib_warning ("parse error '%U'", format_unformat_error, i);
15832           return -99;
15833         }
15834     }
15835
15836   if (num_m_args != 1)
15837     {
15838       errmsg ("mandatory argument(s) missing");
15839       return -99;
15840     }
15841
15842   /* Construct the API message */
15843   M (MAP_DEL_DOMAIN, mp);
15844
15845   mp->index = ntohl (index);
15846
15847   /* send it... */
15848   S (mp);
15849
15850   /* Wait for a reply, return good/bad news  */
15851   W (ret);
15852   return ret;
15853 }
15854
15855 static int
15856 api_map_add_del_rule (vat_main_t * vam)
15857 {
15858   unformat_input_t *i = vam->input;
15859   vl_api_map_add_del_rule_t *mp;
15860   u8 is_add = 1;
15861   ip6_address_t ip6_dst;
15862   u32 num_m_args = 0, index, psid = 0;
15863   int ret;
15864
15865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15866     {
15867       if (unformat (i, "index %d", &index))
15868         num_m_args++;
15869       else if (unformat (i, "psid %d", &psid))
15870         num_m_args++;
15871       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15872         num_m_args++;
15873       else if (unformat (i, "del"))
15874         {
15875           is_add = 0;
15876         }
15877       else
15878         {
15879           clib_warning ("parse error '%U'", format_unformat_error, i);
15880           return -99;
15881         }
15882     }
15883
15884   /* Construct the API message */
15885   M (MAP_ADD_DEL_RULE, mp);
15886
15887   mp->index = ntohl (index);
15888   mp->is_add = is_add;
15889   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15890   mp->psid = ntohs (psid);
15891
15892   /* send it... */
15893   S (mp);
15894
15895   /* Wait for a reply, return good/bad news  */
15896   W (ret);
15897   return ret;
15898 }
15899
15900 static int
15901 api_map_domain_dump (vat_main_t * vam)
15902 {
15903   vl_api_map_domain_dump_t *mp;
15904   vl_api_control_ping_t *mp_ping;
15905   int ret;
15906
15907   /* Construct the API message */
15908   M (MAP_DOMAIN_DUMP, mp);
15909
15910   /* send it... */
15911   S (mp);
15912
15913   /* Use a control ping for synchronization */
15914   MPING (CONTROL_PING, mp_ping);
15915   S (mp_ping);
15916
15917   W (ret);
15918   return ret;
15919 }
15920
15921 static int
15922 api_map_rule_dump (vat_main_t * vam)
15923 {
15924   unformat_input_t *i = vam->input;
15925   vl_api_map_rule_dump_t *mp;
15926   vl_api_control_ping_t *mp_ping;
15927   u32 domain_index = ~0;
15928   int ret;
15929
15930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15931     {
15932       if (unformat (i, "index %u", &domain_index))
15933         ;
15934       else
15935         break;
15936     }
15937
15938   if (domain_index == ~0)
15939     {
15940       clib_warning ("parse error: domain index expected");
15941       return -99;
15942     }
15943
15944   /* Construct the API message */
15945   M (MAP_RULE_DUMP, mp);
15946
15947   mp->domain_index = htonl (domain_index);
15948
15949   /* send it... */
15950   S (mp);
15951
15952   /* Use a control ping for synchronization */
15953   MPING (CONTROL_PING, mp_ping);
15954   S (mp_ping);
15955
15956   W (ret);
15957   return ret;
15958 }
15959
15960 static void vl_api_map_add_domain_reply_t_handler
15961   (vl_api_map_add_domain_reply_t * mp)
15962 {
15963   vat_main_t *vam = &vat_main;
15964   i32 retval = ntohl (mp->retval);
15965
15966   if (vam->async_mode)
15967     {
15968       vam->async_errors += (retval < 0);
15969     }
15970   else
15971     {
15972       vam->retval = retval;
15973       vam->result_ready = 1;
15974     }
15975 }
15976
15977 static void vl_api_map_add_domain_reply_t_handler_json
15978   (vl_api_map_add_domain_reply_t * mp)
15979 {
15980   vat_main_t *vam = &vat_main;
15981   vat_json_node_t node;
15982
15983   vat_json_init_object (&node);
15984   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15985   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15986
15987   vat_json_print (vam->ofp, &node);
15988   vat_json_free (&node);
15989
15990   vam->retval = ntohl (mp->retval);
15991   vam->result_ready = 1;
15992 }
15993
15994 static int
15995 api_get_first_msg_id (vat_main_t * vam)
15996 {
15997   vl_api_get_first_msg_id_t *mp;
15998   unformat_input_t *i = vam->input;
15999   u8 *name;
16000   u8 name_set = 0;
16001   int ret;
16002
16003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16004     {
16005       if (unformat (i, "client %s", &name))
16006         name_set = 1;
16007       else
16008         break;
16009     }
16010
16011   if (name_set == 0)
16012     {
16013       errmsg ("missing client name");
16014       return -99;
16015     }
16016   vec_add1 (name, 0);
16017
16018   if (vec_len (name) > 63)
16019     {
16020       errmsg ("client name too long");
16021       return -99;
16022     }
16023
16024   M (GET_FIRST_MSG_ID, mp);
16025   clib_memcpy (mp->name, name, vec_len (name));
16026   S (mp);
16027   W (ret);
16028   return ret;
16029 }
16030
16031 static int
16032 api_cop_interface_enable_disable (vat_main_t * vam)
16033 {
16034   unformat_input_t *line_input = vam->input;
16035   vl_api_cop_interface_enable_disable_t *mp;
16036   u32 sw_if_index = ~0;
16037   u8 enable_disable = 1;
16038   int ret;
16039
16040   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16041     {
16042       if (unformat (line_input, "disable"))
16043         enable_disable = 0;
16044       if (unformat (line_input, "enable"))
16045         enable_disable = 1;
16046       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16047                          vam, &sw_if_index))
16048         ;
16049       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16050         ;
16051       else
16052         break;
16053     }
16054
16055   if (sw_if_index == ~0)
16056     {
16057       errmsg ("missing interface name or sw_if_index");
16058       return -99;
16059     }
16060
16061   /* Construct the API message */
16062   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16063   mp->sw_if_index = ntohl (sw_if_index);
16064   mp->enable_disable = enable_disable;
16065
16066   /* send it... */
16067   S (mp);
16068   /* Wait for the reply */
16069   W (ret);
16070   return ret;
16071 }
16072
16073 static int
16074 api_cop_whitelist_enable_disable (vat_main_t * vam)
16075 {
16076   unformat_input_t *line_input = vam->input;
16077   vl_api_cop_whitelist_enable_disable_t *mp;
16078   u32 sw_if_index = ~0;
16079   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16080   u32 fib_id = 0;
16081   int ret;
16082
16083   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16084     {
16085       if (unformat (line_input, "ip4"))
16086         ip4 = 1;
16087       else if (unformat (line_input, "ip6"))
16088         ip6 = 1;
16089       else if (unformat (line_input, "default"))
16090         default_cop = 1;
16091       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16092                          vam, &sw_if_index))
16093         ;
16094       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16095         ;
16096       else if (unformat (line_input, "fib-id %d", &fib_id))
16097         ;
16098       else
16099         break;
16100     }
16101
16102   if (sw_if_index == ~0)
16103     {
16104       errmsg ("missing interface name or sw_if_index");
16105       return -99;
16106     }
16107
16108   /* Construct the API message */
16109   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16110   mp->sw_if_index = ntohl (sw_if_index);
16111   mp->fib_id = ntohl (fib_id);
16112   mp->ip4 = ip4;
16113   mp->ip6 = ip6;
16114   mp->default_cop = default_cop;
16115
16116   /* send it... */
16117   S (mp);
16118   /* Wait for the reply */
16119   W (ret);
16120   return ret;
16121 }
16122
16123 static int
16124 api_get_node_graph (vat_main_t * vam)
16125 {
16126   vl_api_get_node_graph_t *mp;
16127   int ret;
16128
16129   M (GET_NODE_GRAPH, mp);
16130
16131   /* send it... */
16132   S (mp);
16133   /* Wait for the reply */
16134   W (ret);
16135   return ret;
16136 }
16137
16138 /* *INDENT-OFF* */
16139 /** Used for parsing LISP eids */
16140 typedef CLIB_PACKED(struct{
16141   u8 addr[16];   /**< eid address */
16142   u32 len;       /**< prefix length if IP */
16143   u8 type;      /**< type of eid */
16144 }) lisp_eid_vat_t;
16145 /* *INDENT-ON* */
16146
16147 static uword
16148 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16149 {
16150   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16151
16152   memset (a, 0, sizeof (a[0]));
16153
16154   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16155     {
16156       a->type = 0;              /* ipv4 type */
16157     }
16158   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16159     {
16160       a->type = 1;              /* ipv6 type */
16161     }
16162   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16163     {
16164       a->type = 2;              /* mac type */
16165     }
16166   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16167     {
16168       a->type = 3;              /* NSH type */
16169       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16170       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16171     }
16172   else
16173     {
16174       return 0;
16175     }
16176
16177   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16178     {
16179       return 0;
16180     }
16181
16182   return 1;
16183 }
16184
16185 static int
16186 lisp_eid_size_vat (u8 type)
16187 {
16188   switch (type)
16189     {
16190     case 0:
16191       return 4;
16192     case 1:
16193       return 16;
16194     case 2:
16195       return 6;
16196     case 3:
16197       return 5;
16198     }
16199   return 0;
16200 }
16201
16202 static void
16203 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16204 {
16205   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16206 }
16207
16208 static int
16209 api_one_add_del_locator_set (vat_main_t * vam)
16210 {
16211   unformat_input_t *input = vam->input;
16212   vl_api_one_add_del_locator_set_t *mp;
16213   u8 is_add = 1;
16214   u8 *locator_set_name = NULL;
16215   u8 locator_set_name_set = 0;
16216   vl_api_local_locator_t locator, *locators = 0;
16217   u32 sw_if_index, priority, weight;
16218   u32 data_len = 0;
16219
16220   int ret;
16221   /* Parse args required to build the message */
16222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16223     {
16224       if (unformat (input, "del"))
16225         {
16226           is_add = 0;
16227         }
16228       else if (unformat (input, "locator-set %s", &locator_set_name))
16229         {
16230           locator_set_name_set = 1;
16231         }
16232       else if (unformat (input, "sw_if_index %u p %u w %u",
16233                          &sw_if_index, &priority, &weight))
16234         {
16235           locator.sw_if_index = htonl (sw_if_index);
16236           locator.priority = priority;
16237           locator.weight = weight;
16238           vec_add1 (locators, locator);
16239         }
16240       else
16241         if (unformat
16242             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16243              &sw_if_index, &priority, &weight))
16244         {
16245           locator.sw_if_index = htonl (sw_if_index);
16246           locator.priority = priority;
16247           locator.weight = weight;
16248           vec_add1 (locators, locator);
16249         }
16250       else
16251         break;
16252     }
16253
16254   if (locator_set_name_set == 0)
16255     {
16256       errmsg ("missing locator-set name");
16257       vec_free (locators);
16258       return -99;
16259     }
16260
16261   if (vec_len (locator_set_name) > 64)
16262     {
16263       errmsg ("locator-set name too long");
16264       vec_free (locator_set_name);
16265       vec_free (locators);
16266       return -99;
16267     }
16268   vec_add1 (locator_set_name, 0);
16269
16270   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16271
16272   /* Construct the API message */
16273   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16274
16275   mp->is_add = is_add;
16276   clib_memcpy (mp->locator_set_name, locator_set_name,
16277                vec_len (locator_set_name));
16278   vec_free (locator_set_name);
16279
16280   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16281   if (locators)
16282     clib_memcpy (mp->locators, locators, data_len);
16283   vec_free (locators);
16284
16285   /* send it... */
16286   S (mp);
16287
16288   /* Wait for a reply... */
16289   W (ret);
16290   return ret;
16291 }
16292
16293 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16294
16295 static int
16296 api_one_add_del_locator (vat_main_t * vam)
16297 {
16298   unformat_input_t *input = vam->input;
16299   vl_api_one_add_del_locator_t *mp;
16300   u32 tmp_if_index = ~0;
16301   u32 sw_if_index = ~0;
16302   u8 sw_if_index_set = 0;
16303   u8 sw_if_index_if_name_set = 0;
16304   u32 priority = ~0;
16305   u8 priority_set = 0;
16306   u32 weight = ~0;
16307   u8 weight_set = 0;
16308   u8 is_add = 1;
16309   u8 *locator_set_name = NULL;
16310   u8 locator_set_name_set = 0;
16311   int ret;
16312
16313   /* Parse args required to build the message */
16314   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16315     {
16316       if (unformat (input, "del"))
16317         {
16318           is_add = 0;
16319         }
16320       else if (unformat (input, "locator-set %s", &locator_set_name))
16321         {
16322           locator_set_name_set = 1;
16323         }
16324       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16325                          &tmp_if_index))
16326         {
16327           sw_if_index_if_name_set = 1;
16328           sw_if_index = tmp_if_index;
16329         }
16330       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16331         {
16332           sw_if_index_set = 1;
16333           sw_if_index = tmp_if_index;
16334         }
16335       else if (unformat (input, "p %d", &priority))
16336         {
16337           priority_set = 1;
16338         }
16339       else if (unformat (input, "w %d", &weight))
16340         {
16341           weight_set = 1;
16342         }
16343       else
16344         break;
16345     }
16346
16347   if (locator_set_name_set == 0)
16348     {
16349       errmsg ("missing locator-set name");
16350       return -99;
16351     }
16352
16353   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16354     {
16355       errmsg ("missing sw_if_index");
16356       vec_free (locator_set_name);
16357       return -99;
16358     }
16359
16360   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16361     {
16362       errmsg ("cannot use both params interface name and sw_if_index");
16363       vec_free (locator_set_name);
16364       return -99;
16365     }
16366
16367   if (priority_set == 0)
16368     {
16369       errmsg ("missing locator-set priority");
16370       vec_free (locator_set_name);
16371       return -99;
16372     }
16373
16374   if (weight_set == 0)
16375     {
16376       errmsg ("missing locator-set weight");
16377       vec_free (locator_set_name);
16378       return -99;
16379     }
16380
16381   if (vec_len (locator_set_name) > 64)
16382     {
16383       errmsg ("locator-set name too long");
16384       vec_free (locator_set_name);
16385       return -99;
16386     }
16387   vec_add1 (locator_set_name, 0);
16388
16389   /* Construct the API message */
16390   M (ONE_ADD_DEL_LOCATOR, mp);
16391
16392   mp->is_add = is_add;
16393   mp->sw_if_index = ntohl (sw_if_index);
16394   mp->priority = priority;
16395   mp->weight = weight;
16396   clib_memcpy (mp->locator_set_name, locator_set_name,
16397                vec_len (locator_set_name));
16398   vec_free (locator_set_name);
16399
16400   /* send it... */
16401   S (mp);
16402
16403   /* Wait for a reply... */
16404   W (ret);
16405   return ret;
16406 }
16407
16408 #define api_lisp_add_del_locator api_one_add_del_locator
16409
16410 uword
16411 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16412 {
16413   u32 *key_id = va_arg (*args, u32 *);
16414   u8 *s = 0;
16415
16416   if (unformat (input, "%s", &s))
16417     {
16418       if (!strcmp ((char *) s, "sha1"))
16419         key_id[0] = HMAC_SHA_1_96;
16420       else if (!strcmp ((char *) s, "sha256"))
16421         key_id[0] = HMAC_SHA_256_128;
16422       else
16423         {
16424           clib_warning ("invalid key_id: '%s'", s);
16425           key_id[0] = HMAC_NO_KEY;
16426         }
16427     }
16428   else
16429     return 0;
16430
16431   vec_free (s);
16432   return 1;
16433 }
16434
16435 static int
16436 api_one_add_del_local_eid (vat_main_t * vam)
16437 {
16438   unformat_input_t *input = vam->input;
16439   vl_api_one_add_del_local_eid_t *mp;
16440   u8 is_add = 1;
16441   u8 eid_set = 0;
16442   lisp_eid_vat_t _eid, *eid = &_eid;
16443   u8 *locator_set_name = 0;
16444   u8 locator_set_name_set = 0;
16445   u32 vni = 0;
16446   u16 key_id = 0;
16447   u8 *key = 0;
16448   int ret;
16449
16450   /* Parse args required to build the message */
16451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16452     {
16453       if (unformat (input, "del"))
16454         {
16455           is_add = 0;
16456         }
16457       else if (unformat (input, "vni %d", &vni))
16458         {
16459           ;
16460         }
16461       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16462         {
16463           eid_set = 1;
16464         }
16465       else if (unformat (input, "locator-set %s", &locator_set_name))
16466         {
16467           locator_set_name_set = 1;
16468         }
16469       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16470         ;
16471       else if (unformat (input, "secret-key %_%v%_", &key))
16472         ;
16473       else
16474         break;
16475     }
16476
16477   if (locator_set_name_set == 0)
16478     {
16479       errmsg ("missing locator-set name");
16480       return -99;
16481     }
16482
16483   if (0 == eid_set)
16484     {
16485       errmsg ("EID address not set!");
16486       vec_free (locator_set_name);
16487       return -99;
16488     }
16489
16490   if (key && (0 == key_id))
16491     {
16492       errmsg ("invalid key_id!");
16493       return -99;
16494     }
16495
16496   if (vec_len (key) > 64)
16497     {
16498       errmsg ("key too long");
16499       vec_free (key);
16500       return -99;
16501     }
16502
16503   if (vec_len (locator_set_name) > 64)
16504     {
16505       errmsg ("locator-set name too long");
16506       vec_free (locator_set_name);
16507       return -99;
16508     }
16509   vec_add1 (locator_set_name, 0);
16510
16511   /* Construct the API message */
16512   M (ONE_ADD_DEL_LOCAL_EID, mp);
16513
16514   mp->is_add = is_add;
16515   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16516   mp->eid_type = eid->type;
16517   mp->prefix_len = eid->len;
16518   mp->vni = clib_host_to_net_u32 (vni);
16519   mp->key_id = clib_host_to_net_u16 (key_id);
16520   clib_memcpy (mp->locator_set_name, locator_set_name,
16521                vec_len (locator_set_name));
16522   clib_memcpy (mp->key, key, vec_len (key));
16523
16524   vec_free (locator_set_name);
16525   vec_free (key);
16526
16527   /* send it... */
16528   S (mp);
16529
16530   /* Wait for a reply... */
16531   W (ret);
16532   return ret;
16533 }
16534
16535 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16536
16537 static int
16538 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16539 {
16540   u32 dp_table = 0, vni = 0;;
16541   unformat_input_t *input = vam->input;
16542   vl_api_gpe_add_del_fwd_entry_t *mp;
16543   u8 is_add = 1;
16544   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16545   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16546   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16547   u32 action = ~0, w;
16548   ip4_address_t rmt_rloc4, lcl_rloc4;
16549   ip6_address_t rmt_rloc6, lcl_rloc6;
16550   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16551   int ret;
16552
16553   memset (&rloc, 0, sizeof (rloc));
16554
16555   /* Parse args required to build the message */
16556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16557     {
16558       if (unformat (input, "del"))
16559         is_add = 0;
16560       else if (unformat (input, "add"))
16561         is_add = 1;
16562       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16563         {
16564           rmt_eid_set = 1;
16565         }
16566       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16567         {
16568           lcl_eid_set = 1;
16569         }
16570       else if (unformat (input, "vrf %d", &dp_table))
16571         ;
16572       else if (unformat (input, "bd %d", &dp_table))
16573         ;
16574       else if (unformat (input, "vni %d", &vni))
16575         ;
16576       else if (unformat (input, "w %d", &w))
16577         {
16578           if (!curr_rloc)
16579             {
16580               errmsg ("No RLOC configured for setting priority/weight!");
16581               return -99;
16582             }
16583           curr_rloc->weight = w;
16584         }
16585       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16586                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16587         {
16588           rloc.is_ip4 = 1;
16589
16590           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16591           rloc.weight = 0;
16592           vec_add1 (lcl_locs, rloc);
16593
16594           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16595           vec_add1 (rmt_locs, rloc);
16596           /* weight saved in rmt loc */
16597           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16598         }
16599       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16600                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16601         {
16602           rloc.is_ip4 = 0;
16603           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16604           rloc.weight = 0;
16605           vec_add1 (lcl_locs, rloc);
16606
16607           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16608           vec_add1 (rmt_locs, rloc);
16609           /* weight saved in rmt loc */
16610           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16611         }
16612       else if (unformat (input, "action %d", &action))
16613         {
16614           ;
16615         }
16616       else
16617         {
16618           clib_warning ("parse error '%U'", format_unformat_error, input);
16619           return -99;
16620         }
16621     }
16622
16623   if (!rmt_eid_set)
16624     {
16625       errmsg ("remote eid addresses not set");
16626       return -99;
16627     }
16628
16629   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16630     {
16631       errmsg ("eid types don't match");
16632       return -99;
16633     }
16634
16635   if (0 == rmt_locs && (u32) ~ 0 == action)
16636     {
16637       errmsg ("action not set for negative mapping");
16638       return -99;
16639     }
16640
16641   /* Construct the API message */
16642   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16643       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16644
16645   mp->is_add = is_add;
16646   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16647   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16648   mp->eid_type = rmt_eid->type;
16649   mp->dp_table = clib_host_to_net_u32 (dp_table);
16650   mp->vni = clib_host_to_net_u32 (vni);
16651   mp->rmt_len = rmt_eid->len;
16652   mp->lcl_len = lcl_eid->len;
16653   mp->action = action;
16654
16655   if (0 != rmt_locs && 0 != lcl_locs)
16656     {
16657       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16658       clib_memcpy (mp->locs, lcl_locs,
16659                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16660
16661       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16662       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16663                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16664     }
16665   vec_free (lcl_locs);
16666   vec_free (rmt_locs);
16667
16668   /* send it... */
16669   S (mp);
16670
16671   /* Wait for a reply... */
16672   W (ret);
16673   return ret;
16674 }
16675
16676 static int
16677 api_one_add_del_map_server (vat_main_t * vam)
16678 {
16679   unformat_input_t *input = vam->input;
16680   vl_api_one_add_del_map_server_t *mp;
16681   u8 is_add = 1;
16682   u8 ipv4_set = 0;
16683   u8 ipv6_set = 0;
16684   ip4_address_t ipv4;
16685   ip6_address_t ipv6;
16686   int ret;
16687
16688   /* Parse args required to build the message */
16689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16690     {
16691       if (unformat (input, "del"))
16692         {
16693           is_add = 0;
16694         }
16695       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16696         {
16697           ipv4_set = 1;
16698         }
16699       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16700         {
16701           ipv6_set = 1;
16702         }
16703       else
16704         break;
16705     }
16706
16707   if (ipv4_set && ipv6_set)
16708     {
16709       errmsg ("both eid v4 and v6 addresses set");
16710       return -99;
16711     }
16712
16713   if (!ipv4_set && !ipv6_set)
16714     {
16715       errmsg ("eid addresses not set");
16716       return -99;
16717     }
16718
16719   /* Construct the API message */
16720   M (ONE_ADD_DEL_MAP_SERVER, mp);
16721
16722   mp->is_add = is_add;
16723   if (ipv6_set)
16724     {
16725       mp->is_ipv6 = 1;
16726       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16727     }
16728   else
16729     {
16730       mp->is_ipv6 = 0;
16731       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16732     }
16733
16734   /* send it... */
16735   S (mp);
16736
16737   /* Wait for a reply... */
16738   W (ret);
16739   return ret;
16740 }
16741
16742 #define api_lisp_add_del_map_server api_one_add_del_map_server
16743
16744 static int
16745 api_one_add_del_map_resolver (vat_main_t * vam)
16746 {
16747   unformat_input_t *input = vam->input;
16748   vl_api_one_add_del_map_resolver_t *mp;
16749   u8 is_add = 1;
16750   u8 ipv4_set = 0;
16751   u8 ipv6_set = 0;
16752   ip4_address_t ipv4;
16753   ip6_address_t ipv6;
16754   int ret;
16755
16756   /* Parse args required to build the message */
16757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16758     {
16759       if (unformat (input, "del"))
16760         {
16761           is_add = 0;
16762         }
16763       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16764         {
16765           ipv4_set = 1;
16766         }
16767       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16768         {
16769           ipv6_set = 1;
16770         }
16771       else
16772         break;
16773     }
16774
16775   if (ipv4_set && ipv6_set)
16776     {
16777       errmsg ("both eid v4 and v6 addresses set");
16778       return -99;
16779     }
16780
16781   if (!ipv4_set && !ipv6_set)
16782     {
16783       errmsg ("eid addresses not set");
16784       return -99;
16785     }
16786
16787   /* Construct the API message */
16788   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16789
16790   mp->is_add = is_add;
16791   if (ipv6_set)
16792     {
16793       mp->is_ipv6 = 1;
16794       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16795     }
16796   else
16797     {
16798       mp->is_ipv6 = 0;
16799       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16800     }
16801
16802   /* send it... */
16803   S (mp);
16804
16805   /* Wait for a reply... */
16806   W (ret);
16807   return ret;
16808 }
16809
16810 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16811
16812 static int
16813 api_lisp_gpe_enable_disable (vat_main_t * vam)
16814 {
16815   unformat_input_t *input = vam->input;
16816   vl_api_gpe_enable_disable_t *mp;
16817   u8 is_set = 0;
16818   u8 is_en = 1;
16819   int ret;
16820
16821   /* Parse args required to build the message */
16822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16823     {
16824       if (unformat (input, "enable"))
16825         {
16826           is_set = 1;
16827           is_en = 1;
16828         }
16829       else if (unformat (input, "disable"))
16830         {
16831           is_set = 1;
16832           is_en = 0;
16833         }
16834       else
16835         break;
16836     }
16837
16838   if (is_set == 0)
16839     {
16840       errmsg ("Value not set");
16841       return -99;
16842     }
16843
16844   /* Construct the API message */
16845   M (GPE_ENABLE_DISABLE, mp);
16846
16847   mp->is_en = is_en;
16848
16849   /* send it... */
16850   S (mp);
16851
16852   /* Wait for a reply... */
16853   W (ret);
16854   return ret;
16855 }
16856
16857 static int
16858 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16859 {
16860   unformat_input_t *input = vam->input;
16861   vl_api_one_rloc_probe_enable_disable_t *mp;
16862   u8 is_set = 0;
16863   u8 is_en = 0;
16864   int ret;
16865
16866   /* Parse args required to build the message */
16867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16868     {
16869       if (unformat (input, "enable"))
16870         {
16871           is_set = 1;
16872           is_en = 1;
16873         }
16874       else if (unformat (input, "disable"))
16875         is_set = 1;
16876       else
16877         break;
16878     }
16879
16880   if (!is_set)
16881     {
16882       errmsg ("Value not set");
16883       return -99;
16884     }
16885
16886   /* Construct the API message */
16887   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16888
16889   mp->is_enabled = is_en;
16890
16891   /* send it... */
16892   S (mp);
16893
16894   /* Wait for a reply... */
16895   W (ret);
16896   return ret;
16897 }
16898
16899 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16900
16901 static int
16902 api_one_map_register_enable_disable (vat_main_t * vam)
16903 {
16904   unformat_input_t *input = vam->input;
16905   vl_api_one_map_register_enable_disable_t *mp;
16906   u8 is_set = 0;
16907   u8 is_en = 0;
16908   int ret;
16909
16910   /* Parse args required to build the message */
16911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16912     {
16913       if (unformat (input, "enable"))
16914         {
16915           is_set = 1;
16916           is_en = 1;
16917         }
16918       else if (unformat (input, "disable"))
16919         is_set = 1;
16920       else
16921         break;
16922     }
16923
16924   if (!is_set)
16925     {
16926       errmsg ("Value not set");
16927       return -99;
16928     }
16929
16930   /* Construct the API message */
16931   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16932
16933   mp->is_enabled = is_en;
16934
16935   /* send it... */
16936   S (mp);
16937
16938   /* Wait for a reply... */
16939   W (ret);
16940   return ret;
16941 }
16942
16943 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16944
16945 static int
16946 api_one_enable_disable (vat_main_t * vam)
16947 {
16948   unformat_input_t *input = vam->input;
16949   vl_api_one_enable_disable_t *mp;
16950   u8 is_set = 0;
16951   u8 is_en = 0;
16952   int ret;
16953
16954   /* Parse args required to build the message */
16955   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16956     {
16957       if (unformat (input, "enable"))
16958         {
16959           is_set = 1;
16960           is_en = 1;
16961         }
16962       else if (unformat (input, "disable"))
16963         {
16964           is_set = 1;
16965         }
16966       else
16967         break;
16968     }
16969
16970   if (!is_set)
16971     {
16972       errmsg ("Value not set");
16973       return -99;
16974     }
16975
16976   /* Construct the API message */
16977   M (ONE_ENABLE_DISABLE, mp);
16978
16979   mp->is_en = is_en;
16980
16981   /* send it... */
16982   S (mp);
16983
16984   /* Wait for a reply... */
16985   W (ret);
16986   return ret;
16987 }
16988
16989 #define api_lisp_enable_disable api_one_enable_disable
16990
16991 static int
16992 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16993 {
16994   unformat_input_t *input = vam->input;
16995   vl_api_one_enable_disable_xtr_mode_t *mp;
16996   u8 is_set = 0;
16997   u8 is_en = 0;
16998   int ret;
16999
17000   /* Parse args required to build the message */
17001   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17002     {
17003       if (unformat (input, "enable"))
17004         {
17005           is_set = 1;
17006           is_en = 1;
17007         }
17008       else if (unformat (input, "disable"))
17009         {
17010           is_set = 1;
17011         }
17012       else
17013         break;
17014     }
17015
17016   if (!is_set)
17017     {
17018       errmsg ("Value not set");
17019       return -99;
17020     }
17021
17022   /* Construct the API message */
17023   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17024
17025   mp->is_en = is_en;
17026
17027   /* send it... */
17028   S (mp);
17029
17030   /* Wait for a reply... */
17031   W (ret);
17032   return ret;
17033 }
17034
17035 static int
17036 api_one_show_xtr_mode (vat_main_t * vam)
17037 {
17038   vl_api_one_show_xtr_mode_t *mp;
17039   int ret;
17040
17041   /* Construct the API message */
17042   M (ONE_SHOW_XTR_MODE, mp);
17043
17044   /* send it... */
17045   S (mp);
17046
17047   /* Wait for a reply... */
17048   W (ret);
17049   return ret;
17050 }
17051
17052 static int
17053 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17054 {
17055   unformat_input_t *input = vam->input;
17056   vl_api_one_enable_disable_pitr_mode_t *mp;
17057   u8 is_set = 0;
17058   u8 is_en = 0;
17059   int ret;
17060
17061   /* Parse args required to build the message */
17062   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17063     {
17064       if (unformat (input, "enable"))
17065         {
17066           is_set = 1;
17067           is_en = 1;
17068         }
17069       else if (unformat (input, "disable"))
17070         {
17071           is_set = 1;
17072         }
17073       else
17074         break;
17075     }
17076
17077   if (!is_set)
17078     {
17079       errmsg ("Value not set");
17080       return -99;
17081     }
17082
17083   /* Construct the API message */
17084   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17085
17086   mp->is_en = is_en;
17087
17088   /* send it... */
17089   S (mp);
17090
17091   /* Wait for a reply... */
17092   W (ret);
17093   return ret;
17094 }
17095
17096 static int
17097 api_one_show_pitr_mode (vat_main_t * vam)
17098 {
17099   vl_api_one_show_pitr_mode_t *mp;
17100   int ret;
17101
17102   /* Construct the API message */
17103   M (ONE_SHOW_PITR_MODE, mp);
17104
17105   /* send it... */
17106   S (mp);
17107
17108   /* Wait for a reply... */
17109   W (ret);
17110   return ret;
17111 }
17112
17113 static int
17114 api_one_enable_disable_petr_mode (vat_main_t * vam)
17115 {
17116   unformat_input_t *input = vam->input;
17117   vl_api_one_enable_disable_petr_mode_t *mp;
17118   u8 is_set = 0;
17119   u8 is_en = 0;
17120   int ret;
17121
17122   /* Parse args required to build the message */
17123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17124     {
17125       if (unformat (input, "enable"))
17126         {
17127           is_set = 1;
17128           is_en = 1;
17129         }
17130       else if (unformat (input, "disable"))
17131         {
17132           is_set = 1;
17133         }
17134       else
17135         break;
17136     }
17137
17138   if (!is_set)
17139     {
17140       errmsg ("Value not set");
17141       return -99;
17142     }
17143
17144   /* Construct the API message */
17145   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17146
17147   mp->is_en = is_en;
17148
17149   /* send it... */
17150   S (mp);
17151
17152   /* Wait for a reply... */
17153   W (ret);
17154   return ret;
17155 }
17156
17157 static int
17158 api_one_show_petr_mode (vat_main_t * vam)
17159 {
17160   vl_api_one_show_petr_mode_t *mp;
17161   int ret;
17162
17163   /* Construct the API message */
17164   M (ONE_SHOW_PETR_MODE, mp);
17165
17166   /* send it... */
17167   S (mp);
17168
17169   /* Wait for a reply... */
17170   W (ret);
17171   return ret;
17172 }
17173
17174 static int
17175 api_show_one_map_register_state (vat_main_t * vam)
17176 {
17177   vl_api_show_one_map_register_state_t *mp;
17178   int ret;
17179
17180   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17181
17182   /* send */
17183   S (mp);
17184
17185   /* wait for reply */
17186   W (ret);
17187   return ret;
17188 }
17189
17190 #define api_show_lisp_map_register_state api_show_one_map_register_state
17191
17192 static int
17193 api_show_one_rloc_probe_state (vat_main_t * vam)
17194 {
17195   vl_api_show_one_rloc_probe_state_t *mp;
17196   int ret;
17197
17198   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17199
17200   /* send */
17201   S (mp);
17202
17203   /* wait for reply */
17204   W (ret);
17205   return ret;
17206 }
17207
17208 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17209
17210 static int
17211 api_one_add_del_ndp_entry (vat_main_t * vam)
17212 {
17213   vl_api_one_add_del_ndp_entry_t *mp;
17214   unformat_input_t *input = vam->input;
17215   u8 is_add = 1;
17216   u8 mac_set = 0;
17217   u8 bd_set = 0;
17218   u8 ip_set = 0;
17219   u8 mac[6] = { 0, };
17220   u8 ip6[16] = { 0, };
17221   u32 bd = ~0;
17222   int ret;
17223
17224   /* Parse args required to build the message */
17225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17226     {
17227       if (unformat (input, "del"))
17228         is_add = 0;
17229       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17230         mac_set = 1;
17231       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17232         ip_set = 1;
17233       else if (unformat (input, "bd %d", &bd))
17234         bd_set = 1;
17235       else
17236         {
17237           errmsg ("parse error '%U'", format_unformat_error, input);
17238           return -99;
17239         }
17240     }
17241
17242   if (!bd_set || !ip_set || (!mac_set && is_add))
17243     {
17244       errmsg ("Missing BD, IP or MAC!");
17245       return -99;
17246     }
17247
17248   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17249   mp->is_add = is_add;
17250   clib_memcpy (mp->mac, mac, 6);
17251   mp->bd = clib_host_to_net_u32 (bd);
17252   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17253
17254   /* send */
17255   S (mp);
17256
17257   /* wait for reply */
17258   W (ret);
17259   return ret;
17260 }
17261
17262 static int
17263 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17264 {
17265   vl_api_one_add_del_l2_arp_entry_t *mp;
17266   unformat_input_t *input = vam->input;
17267   u8 is_add = 1;
17268   u8 mac_set = 0;
17269   u8 bd_set = 0;
17270   u8 ip_set = 0;
17271   u8 mac[6] = { 0, };
17272   u32 ip4 = 0, bd = ~0;
17273   int ret;
17274
17275   /* Parse args required to build the message */
17276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17277     {
17278       if (unformat (input, "del"))
17279         is_add = 0;
17280       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17281         mac_set = 1;
17282       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17283         ip_set = 1;
17284       else if (unformat (input, "bd %d", &bd))
17285         bd_set = 1;
17286       else
17287         {
17288           errmsg ("parse error '%U'", format_unformat_error, input);
17289           return -99;
17290         }
17291     }
17292
17293   if (!bd_set || !ip_set || (!mac_set && is_add))
17294     {
17295       errmsg ("Missing BD, IP or MAC!");
17296       return -99;
17297     }
17298
17299   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17300   mp->is_add = is_add;
17301   clib_memcpy (mp->mac, mac, 6);
17302   mp->bd = clib_host_to_net_u32 (bd);
17303   mp->ip4 = ip4;
17304
17305   /* send */
17306   S (mp);
17307
17308   /* wait for reply */
17309   W (ret);
17310   return ret;
17311 }
17312
17313 static int
17314 api_one_ndp_bd_get (vat_main_t * vam)
17315 {
17316   vl_api_one_ndp_bd_get_t *mp;
17317   int ret;
17318
17319   M (ONE_NDP_BD_GET, mp);
17320
17321   /* send */
17322   S (mp);
17323
17324   /* wait for reply */
17325   W (ret);
17326   return ret;
17327 }
17328
17329 static int
17330 api_one_ndp_entries_get (vat_main_t * vam)
17331 {
17332   vl_api_one_ndp_entries_get_t *mp;
17333   unformat_input_t *input = vam->input;
17334   u8 bd_set = 0;
17335   u32 bd = ~0;
17336   int ret;
17337
17338   /* Parse args required to build the message */
17339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17340     {
17341       if (unformat (input, "bd %d", &bd))
17342         bd_set = 1;
17343       else
17344         {
17345           errmsg ("parse error '%U'", format_unformat_error, input);
17346           return -99;
17347         }
17348     }
17349
17350   if (!bd_set)
17351     {
17352       errmsg ("Expected bridge domain!");
17353       return -99;
17354     }
17355
17356   M (ONE_NDP_ENTRIES_GET, mp);
17357   mp->bd = clib_host_to_net_u32 (bd);
17358
17359   /* send */
17360   S (mp);
17361
17362   /* wait for reply */
17363   W (ret);
17364   return ret;
17365 }
17366
17367 static int
17368 api_one_l2_arp_bd_get (vat_main_t * vam)
17369 {
17370   vl_api_one_l2_arp_bd_get_t *mp;
17371   int ret;
17372
17373   M (ONE_L2_ARP_BD_GET, mp);
17374
17375   /* send */
17376   S (mp);
17377
17378   /* wait for reply */
17379   W (ret);
17380   return ret;
17381 }
17382
17383 static int
17384 api_one_l2_arp_entries_get (vat_main_t * vam)
17385 {
17386   vl_api_one_l2_arp_entries_get_t *mp;
17387   unformat_input_t *input = vam->input;
17388   u8 bd_set = 0;
17389   u32 bd = ~0;
17390   int ret;
17391
17392   /* Parse args required to build the message */
17393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17394     {
17395       if (unformat (input, "bd %d", &bd))
17396         bd_set = 1;
17397       else
17398         {
17399           errmsg ("parse error '%U'", format_unformat_error, input);
17400           return -99;
17401         }
17402     }
17403
17404   if (!bd_set)
17405     {
17406       errmsg ("Expected bridge domain!");
17407       return -99;
17408     }
17409
17410   M (ONE_L2_ARP_ENTRIES_GET, mp);
17411   mp->bd = clib_host_to_net_u32 (bd);
17412
17413   /* send */
17414   S (mp);
17415
17416   /* wait for reply */
17417   W (ret);
17418   return ret;
17419 }
17420
17421 static int
17422 api_one_stats_enable_disable (vat_main_t * vam)
17423 {
17424   vl_api_one_stats_enable_disable_t *mp;
17425   unformat_input_t *input = vam->input;
17426   u8 is_set = 0;
17427   u8 is_en = 0;
17428   int ret;
17429
17430   /* Parse args required to build the message */
17431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17432     {
17433       if (unformat (input, "enable"))
17434         {
17435           is_set = 1;
17436           is_en = 1;
17437         }
17438       else if (unformat (input, "disable"))
17439         {
17440           is_set = 1;
17441         }
17442       else
17443         break;
17444     }
17445
17446   if (!is_set)
17447     {
17448       errmsg ("Value not set");
17449       return -99;
17450     }
17451
17452   M (ONE_STATS_ENABLE_DISABLE, mp);
17453   mp->is_en = is_en;
17454
17455   /* send */
17456   S (mp);
17457
17458   /* wait for reply */
17459   W (ret);
17460   return ret;
17461 }
17462
17463 static int
17464 api_show_one_stats_enable_disable (vat_main_t * vam)
17465 {
17466   vl_api_show_one_stats_enable_disable_t *mp;
17467   int ret;
17468
17469   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17470
17471   /* send */
17472   S (mp);
17473
17474   /* wait for reply */
17475   W (ret);
17476   return ret;
17477 }
17478
17479 static int
17480 api_show_one_map_request_mode (vat_main_t * vam)
17481 {
17482   vl_api_show_one_map_request_mode_t *mp;
17483   int ret;
17484
17485   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17486
17487   /* send */
17488   S (mp);
17489
17490   /* wait for reply */
17491   W (ret);
17492   return ret;
17493 }
17494
17495 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17496
17497 static int
17498 api_one_map_request_mode (vat_main_t * vam)
17499 {
17500   unformat_input_t *input = vam->input;
17501   vl_api_one_map_request_mode_t *mp;
17502   u8 mode = 0;
17503   int ret;
17504
17505   /* Parse args required to build the message */
17506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17507     {
17508       if (unformat (input, "dst-only"))
17509         mode = 0;
17510       else if (unformat (input, "src-dst"))
17511         mode = 1;
17512       else
17513         {
17514           errmsg ("parse error '%U'", format_unformat_error, input);
17515           return -99;
17516         }
17517     }
17518
17519   M (ONE_MAP_REQUEST_MODE, mp);
17520
17521   mp->mode = mode;
17522
17523   /* send */
17524   S (mp);
17525
17526   /* wait for reply */
17527   W (ret);
17528   return ret;
17529 }
17530
17531 #define api_lisp_map_request_mode api_one_map_request_mode
17532
17533 /**
17534  * Enable/disable ONE proxy ITR.
17535  *
17536  * @param vam vpp API test context
17537  * @return return code
17538  */
17539 static int
17540 api_one_pitr_set_locator_set (vat_main_t * vam)
17541 {
17542   u8 ls_name_set = 0;
17543   unformat_input_t *input = vam->input;
17544   vl_api_one_pitr_set_locator_set_t *mp;
17545   u8 is_add = 1;
17546   u8 *ls_name = 0;
17547   int ret;
17548
17549   /* Parse args required to build the message */
17550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17551     {
17552       if (unformat (input, "del"))
17553         is_add = 0;
17554       else if (unformat (input, "locator-set %s", &ls_name))
17555         ls_name_set = 1;
17556       else
17557         {
17558           errmsg ("parse error '%U'", format_unformat_error, input);
17559           return -99;
17560         }
17561     }
17562
17563   if (!ls_name_set)
17564     {
17565       errmsg ("locator-set name not set!");
17566       return -99;
17567     }
17568
17569   M (ONE_PITR_SET_LOCATOR_SET, mp);
17570
17571   mp->is_add = is_add;
17572   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17573   vec_free (ls_name);
17574
17575   /* send */
17576   S (mp);
17577
17578   /* wait for reply */
17579   W (ret);
17580   return ret;
17581 }
17582
17583 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17584
17585 static int
17586 api_one_nsh_set_locator_set (vat_main_t * vam)
17587 {
17588   u8 ls_name_set = 0;
17589   unformat_input_t *input = vam->input;
17590   vl_api_one_nsh_set_locator_set_t *mp;
17591   u8 is_add = 1;
17592   u8 *ls_name = 0;
17593   int ret;
17594
17595   /* Parse args required to build the message */
17596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17597     {
17598       if (unformat (input, "del"))
17599         is_add = 0;
17600       else if (unformat (input, "ls %s", &ls_name))
17601         ls_name_set = 1;
17602       else
17603         {
17604           errmsg ("parse error '%U'", format_unformat_error, input);
17605           return -99;
17606         }
17607     }
17608
17609   if (!ls_name_set && is_add)
17610     {
17611       errmsg ("locator-set name not set!");
17612       return -99;
17613     }
17614
17615   M (ONE_NSH_SET_LOCATOR_SET, mp);
17616
17617   mp->is_add = is_add;
17618   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17619   vec_free (ls_name);
17620
17621   /* send */
17622   S (mp);
17623
17624   /* wait for reply */
17625   W (ret);
17626   return ret;
17627 }
17628
17629 static int
17630 api_show_one_pitr (vat_main_t * vam)
17631 {
17632   vl_api_show_one_pitr_t *mp;
17633   int ret;
17634
17635   if (!vam->json_output)
17636     {
17637       print (vam->ofp, "%=20s", "lisp status:");
17638     }
17639
17640   M (SHOW_ONE_PITR, mp);
17641   /* send it... */
17642   S (mp);
17643
17644   /* Wait for a reply... */
17645   W (ret);
17646   return ret;
17647 }
17648
17649 #define api_show_lisp_pitr api_show_one_pitr
17650
17651 static int
17652 api_one_use_petr (vat_main_t * vam)
17653 {
17654   unformat_input_t *input = vam->input;
17655   vl_api_one_use_petr_t *mp;
17656   u8 is_add = 0;
17657   ip_address_t ip;
17658   int ret;
17659
17660   memset (&ip, 0, sizeof (ip));
17661
17662   /* Parse args required to build the message */
17663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17664     {
17665       if (unformat (input, "disable"))
17666         is_add = 0;
17667       else
17668         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17669         {
17670           is_add = 1;
17671           ip_addr_version (&ip) = IP4;
17672         }
17673       else
17674         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17675         {
17676           is_add = 1;
17677           ip_addr_version (&ip) = IP6;
17678         }
17679       else
17680         {
17681           errmsg ("parse error '%U'", format_unformat_error, input);
17682           return -99;
17683         }
17684     }
17685
17686   M (ONE_USE_PETR, mp);
17687
17688   mp->is_add = is_add;
17689   if (is_add)
17690     {
17691       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17692       if (mp->is_ip4)
17693         clib_memcpy (mp->address, &ip, 4);
17694       else
17695         clib_memcpy (mp->address, &ip, 16);
17696     }
17697
17698   /* send */
17699   S (mp);
17700
17701   /* wait for reply */
17702   W (ret);
17703   return ret;
17704 }
17705
17706 #define api_lisp_use_petr api_one_use_petr
17707
17708 static int
17709 api_show_one_nsh_mapping (vat_main_t * vam)
17710 {
17711   vl_api_show_one_use_petr_t *mp;
17712   int ret;
17713
17714   if (!vam->json_output)
17715     {
17716       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17717     }
17718
17719   M (SHOW_ONE_NSH_MAPPING, mp);
17720   /* send it... */
17721   S (mp);
17722
17723   /* Wait for a reply... */
17724   W (ret);
17725   return ret;
17726 }
17727
17728 static int
17729 api_show_one_use_petr (vat_main_t * vam)
17730 {
17731   vl_api_show_one_use_petr_t *mp;
17732   int ret;
17733
17734   if (!vam->json_output)
17735     {
17736       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17737     }
17738
17739   M (SHOW_ONE_USE_PETR, mp);
17740   /* send it... */
17741   S (mp);
17742
17743   /* Wait for a reply... */
17744   W (ret);
17745   return ret;
17746 }
17747
17748 #define api_show_lisp_use_petr api_show_one_use_petr
17749
17750 /**
17751  * Add/delete mapping between vni and vrf
17752  */
17753 static int
17754 api_one_eid_table_add_del_map (vat_main_t * vam)
17755 {
17756   unformat_input_t *input = vam->input;
17757   vl_api_one_eid_table_add_del_map_t *mp;
17758   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17759   u32 vni, vrf, bd_index;
17760   int ret;
17761
17762   /* Parse args required to build the message */
17763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17764     {
17765       if (unformat (input, "del"))
17766         is_add = 0;
17767       else if (unformat (input, "vrf %d", &vrf))
17768         vrf_set = 1;
17769       else if (unformat (input, "bd_index %d", &bd_index))
17770         bd_index_set = 1;
17771       else if (unformat (input, "vni %d", &vni))
17772         vni_set = 1;
17773       else
17774         break;
17775     }
17776
17777   if (!vni_set || (!vrf_set && !bd_index_set))
17778     {
17779       errmsg ("missing arguments!");
17780       return -99;
17781     }
17782
17783   if (vrf_set && bd_index_set)
17784     {
17785       errmsg ("error: both vrf and bd entered!");
17786       return -99;
17787     }
17788
17789   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17790
17791   mp->is_add = is_add;
17792   mp->vni = htonl (vni);
17793   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17794   mp->is_l2 = bd_index_set;
17795
17796   /* send */
17797   S (mp);
17798
17799   /* wait for reply */
17800   W (ret);
17801   return ret;
17802 }
17803
17804 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17805
17806 uword
17807 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17808 {
17809   u32 *action = va_arg (*args, u32 *);
17810   u8 *s = 0;
17811
17812   if (unformat (input, "%s", &s))
17813     {
17814       if (!strcmp ((char *) s, "no-action"))
17815         action[0] = 0;
17816       else if (!strcmp ((char *) s, "natively-forward"))
17817         action[0] = 1;
17818       else if (!strcmp ((char *) s, "send-map-request"))
17819         action[0] = 2;
17820       else if (!strcmp ((char *) s, "drop"))
17821         action[0] = 3;
17822       else
17823         {
17824           clib_warning ("invalid action: '%s'", s);
17825           action[0] = 3;
17826         }
17827     }
17828   else
17829     return 0;
17830
17831   vec_free (s);
17832   return 1;
17833 }
17834
17835 /**
17836  * Add/del remote mapping to/from ONE control plane
17837  *
17838  * @param vam vpp API test context
17839  * @return return code
17840  */
17841 static int
17842 api_one_add_del_remote_mapping (vat_main_t * vam)
17843 {
17844   unformat_input_t *input = vam->input;
17845   vl_api_one_add_del_remote_mapping_t *mp;
17846   u32 vni = 0;
17847   lisp_eid_vat_t _eid, *eid = &_eid;
17848   lisp_eid_vat_t _seid, *seid = &_seid;
17849   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17850   u32 action = ~0, p, w, data_len;
17851   ip4_address_t rloc4;
17852   ip6_address_t rloc6;
17853   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17854   int ret;
17855
17856   memset (&rloc, 0, sizeof (rloc));
17857
17858   /* Parse args required to build the message */
17859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17860     {
17861       if (unformat (input, "del-all"))
17862         {
17863           del_all = 1;
17864         }
17865       else if (unformat (input, "del"))
17866         {
17867           is_add = 0;
17868         }
17869       else if (unformat (input, "add"))
17870         {
17871           is_add = 1;
17872         }
17873       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17874         {
17875           eid_set = 1;
17876         }
17877       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17878         {
17879           seid_set = 1;
17880         }
17881       else if (unformat (input, "vni %d", &vni))
17882         {
17883           ;
17884         }
17885       else if (unformat (input, "p %d w %d", &p, &w))
17886         {
17887           if (!curr_rloc)
17888             {
17889               errmsg ("No RLOC configured for setting priority/weight!");
17890               return -99;
17891             }
17892           curr_rloc->priority = p;
17893           curr_rloc->weight = w;
17894         }
17895       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17896         {
17897           rloc.is_ip4 = 1;
17898           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17899           vec_add1 (rlocs, rloc);
17900           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17901         }
17902       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17903         {
17904           rloc.is_ip4 = 0;
17905           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17906           vec_add1 (rlocs, rloc);
17907           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17908         }
17909       else if (unformat (input, "action %U",
17910                          unformat_negative_mapping_action, &action))
17911         {
17912           ;
17913         }
17914       else
17915         {
17916           clib_warning ("parse error '%U'", format_unformat_error, input);
17917           return -99;
17918         }
17919     }
17920
17921   if (0 == eid_set)
17922     {
17923       errmsg ("missing params!");
17924       return -99;
17925     }
17926
17927   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17928     {
17929       errmsg ("no action set for negative map-reply!");
17930       return -99;
17931     }
17932
17933   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17934
17935   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17936   mp->is_add = is_add;
17937   mp->vni = htonl (vni);
17938   mp->action = (u8) action;
17939   mp->is_src_dst = seid_set;
17940   mp->eid_len = eid->len;
17941   mp->seid_len = seid->len;
17942   mp->del_all = del_all;
17943   mp->eid_type = eid->type;
17944   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17945   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17946
17947   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17948   clib_memcpy (mp->rlocs, rlocs, data_len);
17949   vec_free (rlocs);
17950
17951   /* send it... */
17952   S (mp);
17953
17954   /* Wait for a reply... */
17955   W (ret);
17956   return ret;
17957 }
17958
17959 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17960
17961 /**
17962  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17963  * forwarding entries in data-plane accordingly.
17964  *
17965  * @param vam vpp API test context
17966  * @return return code
17967  */
17968 static int
17969 api_one_add_del_adjacency (vat_main_t * vam)
17970 {
17971   unformat_input_t *input = vam->input;
17972   vl_api_one_add_del_adjacency_t *mp;
17973   u32 vni = 0;
17974   ip4_address_t leid4, reid4;
17975   ip6_address_t leid6, reid6;
17976   u8 reid_mac[6] = { 0 };
17977   u8 leid_mac[6] = { 0 };
17978   u8 reid_type, leid_type;
17979   u32 leid_len = 0, reid_len = 0, len;
17980   u8 is_add = 1;
17981   int ret;
17982
17983   leid_type = reid_type = (u8) ~ 0;
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         {
17990           is_add = 0;
17991         }
17992       else if (unformat (input, "add"))
17993         {
17994           is_add = 1;
17995         }
17996       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17997                          &reid4, &len))
17998         {
17999           reid_type = 0;        /* ipv4 */
18000           reid_len = len;
18001         }
18002       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18003                          &reid6, &len))
18004         {
18005           reid_type = 1;        /* ipv6 */
18006           reid_len = len;
18007         }
18008       else if (unformat (input, "reid %U", unformat_ethernet_address,
18009                          reid_mac))
18010         {
18011           reid_type = 2;        /* mac */
18012         }
18013       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18014                          &leid4, &len))
18015         {
18016           leid_type = 0;        /* ipv4 */
18017           leid_len = len;
18018         }
18019       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18020                          &leid6, &len))
18021         {
18022           leid_type = 1;        /* ipv6 */
18023           leid_len = len;
18024         }
18025       else if (unformat (input, "leid %U", unformat_ethernet_address,
18026                          leid_mac))
18027         {
18028           leid_type = 2;        /* mac */
18029         }
18030       else if (unformat (input, "vni %d", &vni))
18031         {
18032           ;
18033         }
18034       else
18035         {
18036           errmsg ("parse error '%U'", format_unformat_error, input);
18037           return -99;
18038         }
18039     }
18040
18041   if ((u8) ~ 0 == reid_type)
18042     {
18043       errmsg ("missing params!");
18044       return -99;
18045     }
18046
18047   if (leid_type != reid_type)
18048     {
18049       errmsg ("remote and local EIDs are of different types!");
18050       return -99;
18051     }
18052
18053   M (ONE_ADD_DEL_ADJACENCY, mp);
18054   mp->is_add = is_add;
18055   mp->vni = htonl (vni);
18056   mp->leid_len = leid_len;
18057   mp->reid_len = reid_len;
18058   mp->eid_type = reid_type;
18059
18060   switch (mp->eid_type)
18061     {
18062     case 0:
18063       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18064       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18065       break;
18066     case 1:
18067       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18068       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18069       break;
18070     case 2:
18071       clib_memcpy (mp->leid, leid_mac, 6);
18072       clib_memcpy (mp->reid, reid_mac, 6);
18073       break;
18074     default:
18075       errmsg ("unknown EID type %d!", mp->eid_type);
18076       return 0;
18077     }
18078
18079   /* send it... */
18080   S (mp);
18081
18082   /* Wait for a reply... */
18083   W (ret);
18084   return ret;
18085 }
18086
18087 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18088
18089 uword
18090 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18091 {
18092   u32 *mode = va_arg (*args, u32 *);
18093
18094   if (unformat (input, "lisp"))
18095     *mode = 0;
18096   else if (unformat (input, "vxlan"))
18097     *mode = 1;
18098   else
18099     return 0;
18100
18101   return 1;
18102 }
18103
18104 static int
18105 api_gpe_get_encap_mode (vat_main_t * vam)
18106 {
18107   vl_api_gpe_get_encap_mode_t *mp;
18108   int ret;
18109
18110   /* Construct the API message */
18111   M (GPE_GET_ENCAP_MODE, mp);
18112
18113   /* send it... */
18114   S (mp);
18115
18116   /* Wait for a reply... */
18117   W (ret);
18118   return ret;
18119 }
18120
18121 static int
18122 api_gpe_set_encap_mode (vat_main_t * vam)
18123 {
18124   unformat_input_t *input = vam->input;
18125   vl_api_gpe_set_encap_mode_t *mp;
18126   int ret;
18127   u32 mode = 0;
18128
18129   /* Parse args required to build the message */
18130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18131     {
18132       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18133         ;
18134       else
18135         break;
18136     }
18137
18138   /* Construct the API message */
18139   M (GPE_SET_ENCAP_MODE, mp);
18140
18141   mp->mode = mode;
18142
18143   /* send it... */
18144   S (mp);
18145
18146   /* Wait for a reply... */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 static int
18152 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18153 {
18154   unformat_input_t *input = vam->input;
18155   vl_api_gpe_add_del_iface_t *mp;
18156   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18157   u32 dp_table = 0, vni = 0;
18158   int ret;
18159
18160   /* Parse args required to build the message */
18161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18162     {
18163       if (unformat (input, "up"))
18164         {
18165           action_set = 1;
18166           is_add = 1;
18167         }
18168       else if (unformat (input, "down"))
18169         {
18170           action_set = 1;
18171           is_add = 0;
18172         }
18173       else if (unformat (input, "table_id %d", &dp_table))
18174         {
18175           dp_table_set = 1;
18176         }
18177       else if (unformat (input, "bd_id %d", &dp_table))
18178         {
18179           dp_table_set = 1;
18180           is_l2 = 1;
18181         }
18182       else if (unformat (input, "vni %d", &vni))
18183         {
18184           vni_set = 1;
18185         }
18186       else
18187         break;
18188     }
18189
18190   if (action_set == 0)
18191     {
18192       errmsg ("Action not set");
18193       return -99;
18194     }
18195   if (dp_table_set == 0 || vni_set == 0)
18196     {
18197       errmsg ("vni and dp_table must be set");
18198       return -99;
18199     }
18200
18201   /* Construct the API message */
18202   M (GPE_ADD_DEL_IFACE, mp);
18203
18204   mp->is_add = is_add;
18205   mp->dp_table = clib_host_to_net_u32 (dp_table);
18206   mp->is_l2 = is_l2;
18207   mp->vni = clib_host_to_net_u32 (vni);
18208
18209   /* send it... */
18210   S (mp);
18211
18212   /* Wait for a reply... */
18213   W (ret);
18214   return ret;
18215 }
18216
18217 static int
18218 api_one_map_register_fallback_threshold (vat_main_t * vam)
18219 {
18220   unformat_input_t *input = vam->input;
18221   vl_api_one_map_register_fallback_threshold_t *mp;
18222   u32 value = 0;
18223   u8 is_set = 0;
18224   int ret;
18225
18226   /* Parse args required to build the message */
18227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18228     {
18229       if (unformat (input, "%u", &value))
18230         is_set = 1;
18231       else
18232         {
18233           clib_warning ("parse error '%U'", format_unformat_error, input);
18234           return -99;
18235         }
18236     }
18237
18238   if (!is_set)
18239     {
18240       errmsg ("fallback threshold value is missing!");
18241       return -99;
18242     }
18243
18244   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18245   mp->value = clib_host_to_net_u32 (value);
18246
18247   /* send it... */
18248   S (mp);
18249
18250   /* Wait for a reply... */
18251   W (ret);
18252   return ret;
18253 }
18254
18255 static int
18256 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18257 {
18258   vl_api_show_one_map_register_fallback_threshold_t *mp;
18259   int ret;
18260
18261   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18262
18263   /* send it... */
18264   S (mp);
18265
18266   /* Wait for a reply... */
18267   W (ret);
18268   return ret;
18269 }
18270
18271 uword
18272 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18273 {
18274   u32 *proto = va_arg (*args, u32 *);
18275
18276   if (unformat (input, "udp"))
18277     *proto = 1;
18278   else if (unformat (input, "api"))
18279     *proto = 2;
18280   else
18281     return 0;
18282
18283   return 1;
18284 }
18285
18286 static int
18287 api_one_set_transport_protocol (vat_main_t * vam)
18288 {
18289   unformat_input_t *input = vam->input;
18290   vl_api_one_set_transport_protocol_t *mp;
18291   u8 is_set = 0;
18292   u32 protocol = 0;
18293   int ret;
18294
18295   /* Parse args required to build the message */
18296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18297     {
18298       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18299         is_set = 1;
18300       else
18301         {
18302           clib_warning ("parse error '%U'", format_unformat_error, input);
18303           return -99;
18304         }
18305     }
18306
18307   if (!is_set)
18308     {
18309       errmsg ("Transport protocol missing!");
18310       return -99;
18311     }
18312
18313   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18314   mp->protocol = (u8) protocol;
18315
18316   /* send it... */
18317   S (mp);
18318
18319   /* Wait for a reply... */
18320   W (ret);
18321   return ret;
18322 }
18323
18324 static int
18325 api_one_get_transport_protocol (vat_main_t * vam)
18326 {
18327   vl_api_one_get_transport_protocol_t *mp;
18328   int ret;
18329
18330   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18331
18332   /* send it... */
18333   S (mp);
18334
18335   /* Wait for a reply... */
18336   W (ret);
18337   return ret;
18338 }
18339
18340 static int
18341 api_one_map_register_set_ttl (vat_main_t * vam)
18342 {
18343   unformat_input_t *input = vam->input;
18344   vl_api_one_map_register_set_ttl_t *mp;
18345   u32 ttl = 0;
18346   u8 is_set = 0;
18347   int ret;
18348
18349   /* Parse args required to build the message */
18350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18351     {
18352       if (unformat (input, "%u", &ttl))
18353         is_set = 1;
18354       else
18355         {
18356           clib_warning ("parse error '%U'", format_unformat_error, input);
18357           return -99;
18358         }
18359     }
18360
18361   if (!is_set)
18362     {
18363       errmsg ("TTL value missing!");
18364       return -99;
18365     }
18366
18367   M (ONE_MAP_REGISTER_SET_TTL, mp);
18368   mp->ttl = clib_host_to_net_u32 (ttl);
18369
18370   /* send it... */
18371   S (mp);
18372
18373   /* Wait for a reply... */
18374   W (ret);
18375   return ret;
18376 }
18377
18378 static int
18379 api_show_one_map_register_ttl (vat_main_t * vam)
18380 {
18381   vl_api_show_one_map_register_ttl_t *mp;
18382   int ret;
18383
18384   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18385
18386   /* send it... */
18387   S (mp);
18388
18389   /* Wait for a reply... */
18390   W (ret);
18391   return ret;
18392 }
18393
18394 /**
18395  * Add/del map request itr rlocs from ONE control plane and updates
18396  *
18397  * @param vam vpp API test context
18398  * @return return code
18399  */
18400 static int
18401 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18402 {
18403   unformat_input_t *input = vam->input;
18404   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18405   u8 *locator_set_name = 0;
18406   u8 locator_set_name_set = 0;
18407   u8 is_add = 1;
18408   int ret;
18409
18410   /* Parse args required to build the message */
18411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18412     {
18413       if (unformat (input, "del"))
18414         {
18415           is_add = 0;
18416         }
18417       else if (unformat (input, "%_%v%_", &locator_set_name))
18418         {
18419           locator_set_name_set = 1;
18420         }
18421       else
18422         {
18423           clib_warning ("parse error '%U'", format_unformat_error, input);
18424           return -99;
18425         }
18426     }
18427
18428   if (is_add && !locator_set_name_set)
18429     {
18430       errmsg ("itr-rloc is not set!");
18431       return -99;
18432     }
18433
18434   if (is_add && vec_len (locator_set_name) > 64)
18435     {
18436       errmsg ("itr-rloc locator-set name too long");
18437       vec_free (locator_set_name);
18438       return -99;
18439     }
18440
18441   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18442   mp->is_add = is_add;
18443   if (is_add)
18444     {
18445       clib_memcpy (mp->locator_set_name, locator_set_name,
18446                    vec_len (locator_set_name));
18447     }
18448   else
18449     {
18450       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18451     }
18452   vec_free (locator_set_name);
18453
18454   /* send it... */
18455   S (mp);
18456
18457   /* Wait for a reply... */
18458   W (ret);
18459   return ret;
18460 }
18461
18462 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18463
18464 static int
18465 api_one_locator_dump (vat_main_t * vam)
18466 {
18467   unformat_input_t *input = vam->input;
18468   vl_api_one_locator_dump_t *mp;
18469   vl_api_control_ping_t *mp_ping;
18470   u8 is_index_set = 0, is_name_set = 0;
18471   u8 *ls_name = 0;
18472   u32 ls_index = ~0;
18473   int ret;
18474
18475   /* Parse args required to build the message */
18476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18477     {
18478       if (unformat (input, "ls_name %_%v%_", &ls_name))
18479         {
18480           is_name_set = 1;
18481         }
18482       else if (unformat (input, "ls_index %d", &ls_index))
18483         {
18484           is_index_set = 1;
18485         }
18486       else
18487         {
18488           errmsg ("parse error '%U'", format_unformat_error, input);
18489           return -99;
18490         }
18491     }
18492
18493   if (!is_index_set && !is_name_set)
18494     {
18495       errmsg ("error: expected one of index or name!");
18496       return -99;
18497     }
18498
18499   if (is_index_set && is_name_set)
18500     {
18501       errmsg ("error: only one param expected!");
18502       return -99;
18503     }
18504
18505   if (vec_len (ls_name) > 62)
18506     {
18507       errmsg ("error: locator set name too long!");
18508       return -99;
18509     }
18510
18511   if (!vam->json_output)
18512     {
18513       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18514     }
18515
18516   M (ONE_LOCATOR_DUMP, mp);
18517   mp->is_index_set = is_index_set;
18518
18519   if (is_index_set)
18520     mp->ls_index = clib_host_to_net_u32 (ls_index);
18521   else
18522     {
18523       vec_add1 (ls_name, 0);
18524       strncpy ((char *) mp->ls_name, (char *) ls_name,
18525                sizeof (mp->ls_name) - 1);
18526     }
18527
18528   /* send it... */
18529   S (mp);
18530
18531   /* Use a control ping for synchronization */
18532   MPING (CONTROL_PING, mp_ping);
18533   S (mp_ping);
18534
18535   /* Wait for a reply... */
18536   W (ret);
18537   return ret;
18538 }
18539
18540 #define api_lisp_locator_dump api_one_locator_dump
18541
18542 static int
18543 api_one_locator_set_dump (vat_main_t * vam)
18544 {
18545   vl_api_one_locator_set_dump_t *mp;
18546   vl_api_control_ping_t *mp_ping;
18547   unformat_input_t *input = vam->input;
18548   u8 filter = 0;
18549   int ret;
18550
18551   /* Parse args required to build the message */
18552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18553     {
18554       if (unformat (input, "local"))
18555         {
18556           filter = 1;
18557         }
18558       else if (unformat (input, "remote"))
18559         {
18560           filter = 2;
18561         }
18562       else
18563         {
18564           errmsg ("parse error '%U'", format_unformat_error, input);
18565           return -99;
18566         }
18567     }
18568
18569   if (!vam->json_output)
18570     {
18571       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18572     }
18573
18574   M (ONE_LOCATOR_SET_DUMP, mp);
18575
18576   mp->filter = filter;
18577
18578   /* send it... */
18579   S (mp);
18580
18581   /* Use a control ping for synchronization */
18582   MPING (CONTROL_PING, mp_ping);
18583   S (mp_ping);
18584
18585   /* Wait for a reply... */
18586   W (ret);
18587   return ret;
18588 }
18589
18590 #define api_lisp_locator_set_dump api_one_locator_set_dump
18591
18592 static int
18593 api_one_eid_table_map_dump (vat_main_t * vam)
18594 {
18595   u8 is_l2 = 0;
18596   u8 mode_set = 0;
18597   unformat_input_t *input = vam->input;
18598   vl_api_one_eid_table_map_dump_t *mp;
18599   vl_api_control_ping_t *mp_ping;
18600   int ret;
18601
18602   /* Parse args required to build the message */
18603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18604     {
18605       if (unformat (input, "l2"))
18606         {
18607           is_l2 = 1;
18608           mode_set = 1;
18609         }
18610       else if (unformat (input, "l3"))
18611         {
18612           is_l2 = 0;
18613           mode_set = 1;
18614         }
18615       else
18616         {
18617           errmsg ("parse error '%U'", format_unformat_error, input);
18618           return -99;
18619         }
18620     }
18621
18622   if (!mode_set)
18623     {
18624       errmsg ("expected one of 'l2' or 'l3' parameter!");
18625       return -99;
18626     }
18627
18628   if (!vam->json_output)
18629     {
18630       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18631     }
18632
18633   M (ONE_EID_TABLE_MAP_DUMP, mp);
18634   mp->is_l2 = is_l2;
18635
18636   /* send it... */
18637   S (mp);
18638
18639   /* Use a control ping for synchronization */
18640   MPING (CONTROL_PING, mp_ping);
18641   S (mp_ping);
18642
18643   /* Wait for a reply... */
18644   W (ret);
18645   return ret;
18646 }
18647
18648 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18649
18650 static int
18651 api_one_eid_table_vni_dump (vat_main_t * vam)
18652 {
18653   vl_api_one_eid_table_vni_dump_t *mp;
18654   vl_api_control_ping_t *mp_ping;
18655   int ret;
18656
18657   if (!vam->json_output)
18658     {
18659       print (vam->ofp, "VNI");
18660     }
18661
18662   M (ONE_EID_TABLE_VNI_DUMP, mp);
18663
18664   /* send it... */
18665   S (mp);
18666
18667   /* Use a control ping for synchronization */
18668   MPING (CONTROL_PING, mp_ping);
18669   S (mp_ping);
18670
18671   /* Wait for a reply... */
18672   W (ret);
18673   return ret;
18674 }
18675
18676 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18677
18678 static int
18679 api_one_eid_table_dump (vat_main_t * vam)
18680 {
18681   unformat_input_t *i = vam->input;
18682   vl_api_one_eid_table_dump_t *mp;
18683   vl_api_control_ping_t *mp_ping;
18684   struct in_addr ip4;
18685   struct in6_addr ip6;
18686   u8 mac[6];
18687   u8 eid_type = ~0, eid_set = 0;
18688   u32 prefix_length = ~0, t, vni = 0;
18689   u8 filter = 0;
18690   int ret;
18691   lisp_nsh_api_t nsh;
18692
18693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18694     {
18695       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18696         {
18697           eid_set = 1;
18698           eid_type = 0;
18699           prefix_length = t;
18700         }
18701       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18702         {
18703           eid_set = 1;
18704           eid_type = 1;
18705           prefix_length = t;
18706         }
18707       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18708         {
18709           eid_set = 1;
18710           eid_type = 2;
18711         }
18712       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18713         {
18714           eid_set = 1;
18715           eid_type = 3;
18716         }
18717       else if (unformat (i, "vni %d", &t))
18718         {
18719           vni = t;
18720         }
18721       else if (unformat (i, "local"))
18722         {
18723           filter = 1;
18724         }
18725       else if (unformat (i, "remote"))
18726         {
18727           filter = 2;
18728         }
18729       else
18730         {
18731           errmsg ("parse error '%U'", format_unformat_error, i);
18732           return -99;
18733         }
18734     }
18735
18736   if (!vam->json_output)
18737     {
18738       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18739              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18740     }
18741
18742   M (ONE_EID_TABLE_DUMP, mp);
18743
18744   mp->filter = filter;
18745   if (eid_set)
18746     {
18747       mp->eid_set = 1;
18748       mp->vni = htonl (vni);
18749       mp->eid_type = eid_type;
18750       switch (eid_type)
18751         {
18752         case 0:
18753           mp->prefix_length = prefix_length;
18754           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18755           break;
18756         case 1:
18757           mp->prefix_length = prefix_length;
18758           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18759           break;
18760         case 2:
18761           clib_memcpy (mp->eid, mac, sizeof (mac));
18762           break;
18763         case 3:
18764           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18765           break;
18766         default:
18767           errmsg ("unknown EID type %d!", eid_type);
18768           return -99;
18769         }
18770     }
18771
18772   /* send it... */
18773   S (mp);
18774
18775   /* Use a control ping for synchronization */
18776   MPING (CONTROL_PING, mp_ping);
18777   S (mp_ping);
18778
18779   /* Wait for a reply... */
18780   W (ret);
18781   return ret;
18782 }
18783
18784 #define api_lisp_eid_table_dump api_one_eid_table_dump
18785
18786 static int
18787 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18788 {
18789   unformat_input_t *i = vam->input;
18790   vl_api_gpe_fwd_entries_get_t *mp;
18791   u8 vni_set = 0;
18792   u32 vni = ~0;
18793   int ret;
18794
18795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18796     {
18797       if (unformat (i, "vni %d", &vni))
18798         {
18799           vni_set = 1;
18800         }
18801       else
18802         {
18803           errmsg ("parse error '%U'", format_unformat_error, i);
18804           return -99;
18805         }
18806     }
18807
18808   if (!vni_set)
18809     {
18810       errmsg ("vni not set!");
18811       return -99;
18812     }
18813
18814   if (!vam->json_output)
18815     {
18816       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18817              "leid", "reid");
18818     }
18819
18820   M (GPE_FWD_ENTRIES_GET, mp);
18821   mp->vni = clib_host_to_net_u32 (vni);
18822
18823   /* send it... */
18824   S (mp);
18825
18826   /* Wait for a reply... */
18827   W (ret);
18828   return ret;
18829 }
18830
18831 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18832 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18833 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18834 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18835 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18836 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18837 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18838 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18839
18840 static int
18841 api_one_adjacencies_get (vat_main_t * vam)
18842 {
18843   unformat_input_t *i = vam->input;
18844   vl_api_one_adjacencies_get_t *mp;
18845   u8 vni_set = 0;
18846   u32 vni = ~0;
18847   int ret;
18848
18849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18850     {
18851       if (unformat (i, "vni %d", &vni))
18852         {
18853           vni_set = 1;
18854         }
18855       else
18856         {
18857           errmsg ("parse error '%U'", format_unformat_error, i);
18858           return -99;
18859         }
18860     }
18861
18862   if (!vni_set)
18863     {
18864       errmsg ("vni not set!");
18865       return -99;
18866     }
18867
18868   if (!vam->json_output)
18869     {
18870       print (vam->ofp, "%s %40s", "leid", "reid");
18871     }
18872
18873   M (ONE_ADJACENCIES_GET, mp);
18874   mp->vni = clib_host_to_net_u32 (vni);
18875
18876   /* send it... */
18877   S (mp);
18878
18879   /* Wait for a reply... */
18880   W (ret);
18881   return ret;
18882 }
18883
18884 #define api_lisp_adjacencies_get api_one_adjacencies_get
18885
18886 static int
18887 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18888 {
18889   unformat_input_t *i = vam->input;
18890   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18891   int ret;
18892   u8 ip_family_set = 0, is_ip4 = 1;
18893
18894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18895     {
18896       if (unformat (i, "ip4"))
18897         {
18898           ip_family_set = 1;
18899           is_ip4 = 1;
18900         }
18901       else if (unformat (i, "ip6"))
18902         {
18903           ip_family_set = 1;
18904           is_ip4 = 0;
18905         }
18906       else
18907         {
18908           errmsg ("parse error '%U'", format_unformat_error, i);
18909           return -99;
18910         }
18911     }
18912
18913   if (!ip_family_set)
18914     {
18915       errmsg ("ip family not set!");
18916       return -99;
18917     }
18918
18919   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18920   mp->is_ip4 = is_ip4;
18921
18922   /* send it... */
18923   S (mp);
18924
18925   /* Wait for a reply... */
18926   W (ret);
18927   return ret;
18928 }
18929
18930 static int
18931 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18932 {
18933   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18934   int ret;
18935
18936   if (!vam->json_output)
18937     {
18938       print (vam->ofp, "VNIs");
18939     }
18940
18941   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18942
18943   /* send it... */
18944   S (mp);
18945
18946   /* Wait for a reply... */
18947   W (ret);
18948   return ret;
18949 }
18950
18951 static int
18952 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18953 {
18954   unformat_input_t *i = vam->input;
18955   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18956   int ret = 0;
18957   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18958   struct in_addr ip4;
18959   struct in6_addr ip6;
18960   u32 table_id = 0, nh_sw_if_index = ~0;
18961
18962   memset (&ip4, 0, sizeof (ip4));
18963   memset (&ip6, 0, sizeof (ip6));
18964
18965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18966     {
18967       if (unformat (i, "del"))
18968         is_add = 0;
18969       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18970                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18971         {
18972           ip_set = 1;
18973           is_ip4 = 1;
18974         }
18975       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18976                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18977         {
18978           ip_set = 1;
18979           is_ip4 = 0;
18980         }
18981       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18982         {
18983           ip_set = 1;
18984           is_ip4 = 1;
18985           nh_sw_if_index = ~0;
18986         }
18987       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18988         {
18989           ip_set = 1;
18990           is_ip4 = 0;
18991           nh_sw_if_index = ~0;
18992         }
18993       else if (unformat (i, "table %d", &table_id))
18994         ;
18995       else
18996         {
18997           errmsg ("parse error '%U'", format_unformat_error, i);
18998           return -99;
18999         }
19000     }
19001
19002   if (!ip_set)
19003     {
19004       errmsg ("nh addr not set!");
19005       return -99;
19006     }
19007
19008   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19009   mp->is_add = is_add;
19010   mp->table_id = clib_host_to_net_u32 (table_id);
19011   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19012   mp->is_ip4 = is_ip4;
19013   if (is_ip4)
19014     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19015   else
19016     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19017
19018   /* send it... */
19019   S (mp);
19020
19021   /* Wait for a reply... */
19022   W (ret);
19023   return ret;
19024 }
19025
19026 static int
19027 api_one_map_server_dump (vat_main_t * vam)
19028 {
19029   vl_api_one_map_server_dump_t *mp;
19030   vl_api_control_ping_t *mp_ping;
19031   int ret;
19032
19033   if (!vam->json_output)
19034     {
19035       print (vam->ofp, "%=20s", "Map server");
19036     }
19037
19038   M (ONE_MAP_SERVER_DUMP, mp);
19039   /* send it... */
19040   S (mp);
19041
19042   /* Use a control ping for synchronization */
19043   MPING (CONTROL_PING, mp_ping);
19044   S (mp_ping);
19045
19046   /* Wait for a reply... */
19047   W (ret);
19048   return ret;
19049 }
19050
19051 #define api_lisp_map_server_dump api_one_map_server_dump
19052
19053 static int
19054 api_one_map_resolver_dump (vat_main_t * vam)
19055 {
19056   vl_api_one_map_resolver_dump_t *mp;
19057   vl_api_control_ping_t *mp_ping;
19058   int ret;
19059
19060   if (!vam->json_output)
19061     {
19062       print (vam->ofp, "%=20s", "Map resolver");
19063     }
19064
19065   M (ONE_MAP_RESOLVER_DUMP, mp);
19066   /* send it... */
19067   S (mp);
19068
19069   /* Use a control ping for synchronization */
19070   MPING (CONTROL_PING, mp_ping);
19071   S (mp_ping);
19072
19073   /* Wait for a reply... */
19074   W (ret);
19075   return ret;
19076 }
19077
19078 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19079
19080 static int
19081 api_one_stats_flush (vat_main_t * vam)
19082 {
19083   vl_api_one_stats_flush_t *mp;
19084   int ret = 0;
19085
19086   M (ONE_STATS_FLUSH, mp);
19087   S (mp);
19088   W (ret);
19089   return ret;
19090 }
19091
19092 static int
19093 api_one_stats_dump (vat_main_t * vam)
19094 {
19095   vl_api_one_stats_dump_t *mp;
19096   vl_api_control_ping_t *mp_ping;
19097   int ret;
19098
19099   M (ONE_STATS_DUMP, mp);
19100   /* send it... */
19101   S (mp);
19102
19103   /* Use a control ping for synchronization */
19104   MPING (CONTROL_PING, mp_ping);
19105   S (mp_ping);
19106
19107   /* Wait for a reply... */
19108   W (ret);
19109   return ret;
19110 }
19111
19112 static int
19113 api_show_one_status (vat_main_t * vam)
19114 {
19115   vl_api_show_one_status_t *mp;
19116   int ret;
19117
19118   if (!vam->json_output)
19119     {
19120       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19121     }
19122
19123   M (SHOW_ONE_STATUS, mp);
19124   /* send it... */
19125   S (mp);
19126   /* Wait for a reply... */
19127   W (ret);
19128   return ret;
19129 }
19130
19131 #define api_show_lisp_status api_show_one_status
19132
19133 static int
19134 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19135 {
19136   vl_api_gpe_fwd_entry_path_dump_t *mp;
19137   vl_api_control_ping_t *mp_ping;
19138   unformat_input_t *i = vam->input;
19139   u32 fwd_entry_index = ~0;
19140   int ret;
19141
19142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19143     {
19144       if (unformat (i, "index %d", &fwd_entry_index))
19145         ;
19146       else
19147         break;
19148     }
19149
19150   if (~0 == fwd_entry_index)
19151     {
19152       errmsg ("no index specified!");
19153       return -99;
19154     }
19155
19156   if (!vam->json_output)
19157     {
19158       print (vam->ofp, "first line");
19159     }
19160
19161   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19162
19163   /* send it... */
19164   S (mp);
19165   /* Use a control ping for synchronization */
19166   MPING (CONTROL_PING, mp_ping);
19167   S (mp_ping);
19168
19169   /* Wait for a reply... */
19170   W (ret);
19171   return ret;
19172 }
19173
19174 static int
19175 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19176 {
19177   vl_api_one_get_map_request_itr_rlocs_t *mp;
19178   int ret;
19179
19180   if (!vam->json_output)
19181     {
19182       print (vam->ofp, "%=20s", "itr-rlocs:");
19183     }
19184
19185   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19186   /* send it... */
19187   S (mp);
19188   /* Wait for a reply... */
19189   W (ret);
19190   return ret;
19191 }
19192
19193 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19194
19195 static int
19196 api_af_packet_create (vat_main_t * vam)
19197 {
19198   unformat_input_t *i = vam->input;
19199   vl_api_af_packet_create_t *mp;
19200   u8 *host_if_name = 0;
19201   u8 hw_addr[6];
19202   u8 random_hw_addr = 1;
19203   int ret;
19204
19205   memset (hw_addr, 0, sizeof (hw_addr));
19206
19207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19208     {
19209       if (unformat (i, "name %s", &host_if_name))
19210         vec_add1 (host_if_name, 0);
19211       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19212         random_hw_addr = 0;
19213       else
19214         break;
19215     }
19216
19217   if (!vec_len (host_if_name))
19218     {
19219       errmsg ("host-interface name must be specified");
19220       return -99;
19221     }
19222
19223   if (vec_len (host_if_name) > 64)
19224     {
19225       errmsg ("host-interface name too long");
19226       return -99;
19227     }
19228
19229   M (AF_PACKET_CREATE, mp);
19230
19231   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19232   clib_memcpy (mp->hw_addr, hw_addr, 6);
19233   mp->use_random_hw_addr = random_hw_addr;
19234   vec_free (host_if_name);
19235
19236   S (mp);
19237
19238   /* *INDENT-OFF* */
19239   W2 (ret,
19240       ({
19241         if (ret == 0)
19242           fprintf (vam->ofp ? vam->ofp : stderr,
19243                    " new sw_if_index = %d\n", vam->sw_if_index);
19244       }));
19245   /* *INDENT-ON* */
19246   return ret;
19247 }
19248
19249 static int
19250 api_af_packet_delete (vat_main_t * vam)
19251 {
19252   unformat_input_t *i = vam->input;
19253   vl_api_af_packet_delete_t *mp;
19254   u8 *host_if_name = 0;
19255   int ret;
19256
19257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19258     {
19259       if (unformat (i, "name %s", &host_if_name))
19260         vec_add1 (host_if_name, 0);
19261       else
19262         break;
19263     }
19264
19265   if (!vec_len (host_if_name))
19266     {
19267       errmsg ("host-interface name must be specified");
19268       return -99;
19269     }
19270
19271   if (vec_len (host_if_name) > 64)
19272     {
19273       errmsg ("host-interface name too long");
19274       return -99;
19275     }
19276
19277   M (AF_PACKET_DELETE, mp);
19278
19279   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19280   vec_free (host_if_name);
19281
19282   S (mp);
19283   W (ret);
19284   return ret;
19285 }
19286
19287 static int
19288 api_policer_add_del (vat_main_t * vam)
19289 {
19290   unformat_input_t *i = vam->input;
19291   vl_api_policer_add_del_t *mp;
19292   u8 is_add = 1;
19293   u8 *name = 0;
19294   u32 cir = 0;
19295   u32 eir = 0;
19296   u64 cb = 0;
19297   u64 eb = 0;
19298   u8 rate_type = 0;
19299   u8 round_type = 0;
19300   u8 type = 0;
19301   u8 color_aware = 0;
19302   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19303   int ret;
19304
19305   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19306   conform_action.dscp = 0;
19307   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19308   exceed_action.dscp = 0;
19309   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19310   violate_action.dscp = 0;
19311
19312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19313     {
19314       if (unformat (i, "del"))
19315         is_add = 0;
19316       else if (unformat (i, "name %s", &name))
19317         vec_add1 (name, 0);
19318       else if (unformat (i, "cir %u", &cir))
19319         ;
19320       else if (unformat (i, "eir %u", &eir))
19321         ;
19322       else if (unformat (i, "cb %u", &cb))
19323         ;
19324       else if (unformat (i, "eb %u", &eb))
19325         ;
19326       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19327                          &rate_type))
19328         ;
19329       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19330                          &round_type))
19331         ;
19332       else if (unformat (i, "type %U", unformat_policer_type, &type))
19333         ;
19334       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19335                          &conform_action))
19336         ;
19337       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19338                          &exceed_action))
19339         ;
19340       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19341                          &violate_action))
19342         ;
19343       else if (unformat (i, "color-aware"))
19344         color_aware = 1;
19345       else
19346         break;
19347     }
19348
19349   if (!vec_len (name))
19350     {
19351       errmsg ("policer name must be specified");
19352       return -99;
19353     }
19354
19355   if (vec_len (name) > 64)
19356     {
19357       errmsg ("policer name too long");
19358       return -99;
19359     }
19360
19361   M (POLICER_ADD_DEL, mp);
19362
19363   clib_memcpy (mp->name, name, vec_len (name));
19364   vec_free (name);
19365   mp->is_add = is_add;
19366   mp->cir = ntohl (cir);
19367   mp->eir = ntohl (eir);
19368   mp->cb = clib_net_to_host_u64 (cb);
19369   mp->eb = clib_net_to_host_u64 (eb);
19370   mp->rate_type = rate_type;
19371   mp->round_type = round_type;
19372   mp->type = type;
19373   mp->conform_action_type = conform_action.action_type;
19374   mp->conform_dscp = conform_action.dscp;
19375   mp->exceed_action_type = exceed_action.action_type;
19376   mp->exceed_dscp = exceed_action.dscp;
19377   mp->violate_action_type = violate_action.action_type;
19378   mp->violate_dscp = violate_action.dscp;
19379   mp->color_aware = color_aware;
19380
19381   S (mp);
19382   W (ret);
19383   return ret;
19384 }
19385
19386 static int
19387 api_policer_dump (vat_main_t * vam)
19388 {
19389   unformat_input_t *i = vam->input;
19390   vl_api_policer_dump_t *mp;
19391   vl_api_control_ping_t *mp_ping;
19392   u8 *match_name = 0;
19393   u8 match_name_valid = 0;
19394   int ret;
19395
19396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19397     {
19398       if (unformat (i, "name %s", &match_name))
19399         {
19400           vec_add1 (match_name, 0);
19401           match_name_valid = 1;
19402         }
19403       else
19404         break;
19405     }
19406
19407   M (POLICER_DUMP, mp);
19408   mp->match_name_valid = match_name_valid;
19409   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19410   vec_free (match_name);
19411   /* send it... */
19412   S (mp);
19413
19414   /* Use a control ping for synchronization */
19415   MPING (CONTROL_PING, mp_ping);
19416   S (mp_ping);
19417
19418   /* Wait for a reply... */
19419   W (ret);
19420   return ret;
19421 }
19422
19423 static int
19424 api_policer_classify_set_interface (vat_main_t * vam)
19425 {
19426   unformat_input_t *i = vam->input;
19427   vl_api_policer_classify_set_interface_t *mp;
19428   u32 sw_if_index;
19429   int sw_if_index_set;
19430   u32 ip4_table_index = ~0;
19431   u32 ip6_table_index = ~0;
19432   u32 l2_table_index = ~0;
19433   u8 is_add = 1;
19434   int ret;
19435
19436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19437     {
19438       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19439         sw_if_index_set = 1;
19440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19441         sw_if_index_set = 1;
19442       else if (unformat (i, "del"))
19443         is_add = 0;
19444       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19445         ;
19446       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19447         ;
19448       else if (unformat (i, "l2-table %d", &l2_table_index))
19449         ;
19450       else
19451         {
19452           clib_warning ("parse error '%U'", format_unformat_error, i);
19453           return -99;
19454         }
19455     }
19456
19457   if (sw_if_index_set == 0)
19458     {
19459       errmsg ("missing interface name or sw_if_index");
19460       return -99;
19461     }
19462
19463   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19464
19465   mp->sw_if_index = ntohl (sw_if_index);
19466   mp->ip4_table_index = ntohl (ip4_table_index);
19467   mp->ip6_table_index = ntohl (ip6_table_index);
19468   mp->l2_table_index = ntohl (l2_table_index);
19469   mp->is_add = is_add;
19470
19471   S (mp);
19472   W (ret);
19473   return ret;
19474 }
19475
19476 static int
19477 api_policer_classify_dump (vat_main_t * vam)
19478 {
19479   unformat_input_t *i = vam->input;
19480   vl_api_policer_classify_dump_t *mp;
19481   vl_api_control_ping_t *mp_ping;
19482   u8 type = POLICER_CLASSIFY_N_TABLES;
19483   int ret;
19484
19485   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19486     ;
19487   else
19488     {
19489       errmsg ("classify table type must be specified");
19490       return -99;
19491     }
19492
19493   if (!vam->json_output)
19494     {
19495       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19496     }
19497
19498   M (POLICER_CLASSIFY_DUMP, mp);
19499   mp->type = type;
19500   /* send it... */
19501   S (mp);
19502
19503   /* Use a control ping for synchronization */
19504   MPING (CONTROL_PING, mp_ping);
19505   S (mp_ping);
19506
19507   /* Wait for a reply... */
19508   W (ret);
19509   return ret;
19510 }
19511
19512 static int
19513 api_netmap_create (vat_main_t * vam)
19514 {
19515   unformat_input_t *i = vam->input;
19516   vl_api_netmap_create_t *mp;
19517   u8 *if_name = 0;
19518   u8 hw_addr[6];
19519   u8 random_hw_addr = 1;
19520   u8 is_pipe = 0;
19521   u8 is_master = 0;
19522   int ret;
19523
19524   memset (hw_addr, 0, sizeof (hw_addr));
19525
19526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19527     {
19528       if (unformat (i, "name %s", &if_name))
19529         vec_add1 (if_name, 0);
19530       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19531         random_hw_addr = 0;
19532       else if (unformat (i, "pipe"))
19533         is_pipe = 1;
19534       else if (unformat (i, "master"))
19535         is_master = 1;
19536       else if (unformat (i, "slave"))
19537         is_master = 0;
19538       else
19539         break;
19540     }
19541
19542   if (!vec_len (if_name))
19543     {
19544       errmsg ("interface name must be specified");
19545       return -99;
19546     }
19547
19548   if (vec_len (if_name) > 64)
19549     {
19550       errmsg ("interface name too long");
19551       return -99;
19552     }
19553
19554   M (NETMAP_CREATE, mp);
19555
19556   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19557   clib_memcpy (mp->hw_addr, hw_addr, 6);
19558   mp->use_random_hw_addr = random_hw_addr;
19559   mp->is_pipe = is_pipe;
19560   mp->is_master = is_master;
19561   vec_free (if_name);
19562
19563   S (mp);
19564   W (ret);
19565   return ret;
19566 }
19567
19568 static int
19569 api_netmap_delete (vat_main_t * vam)
19570 {
19571   unformat_input_t *i = vam->input;
19572   vl_api_netmap_delete_t *mp;
19573   u8 *if_name = 0;
19574   int ret;
19575
19576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19577     {
19578       if (unformat (i, "name %s", &if_name))
19579         vec_add1 (if_name, 0);
19580       else
19581         break;
19582     }
19583
19584   if (!vec_len (if_name))
19585     {
19586       errmsg ("interface name must be specified");
19587       return -99;
19588     }
19589
19590   if (vec_len (if_name) > 64)
19591     {
19592       errmsg ("interface name too long");
19593       return -99;
19594     }
19595
19596   M (NETMAP_DELETE, mp);
19597
19598   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19599   vec_free (if_name);
19600
19601   S (mp);
19602   W (ret);
19603   return ret;
19604 }
19605
19606 static void
19607 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19608 {
19609   if (fp->afi == IP46_TYPE_IP6)
19610     print (vam->ofp,
19611            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19612            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19613            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19614            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19615            format_ip6_address, fp->next_hop);
19616   else if (fp->afi == IP46_TYPE_IP4)
19617     print (vam->ofp,
19618            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19619            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19620            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19621            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19622            format_ip4_address, fp->next_hop);
19623 }
19624
19625 static void
19626 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19627                                  vl_api_fib_path2_t * fp)
19628 {
19629   struct in_addr ip4;
19630   struct in6_addr ip6;
19631
19632   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19633   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19634   vat_json_object_add_uint (node, "is_local", fp->is_local);
19635   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19636   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19637   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19638   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19639   if (fp->afi == IP46_TYPE_IP4)
19640     {
19641       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19642       vat_json_object_add_ip4 (node, "next_hop", ip4);
19643     }
19644   else if (fp->afi == IP46_TYPE_IP6)
19645     {
19646       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19647       vat_json_object_add_ip6 (node, "next_hop", ip6);
19648     }
19649 }
19650
19651 static void
19652 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19653 {
19654   vat_main_t *vam = &vat_main;
19655   int count = ntohl (mp->mt_count);
19656   vl_api_fib_path2_t *fp;
19657   i32 i;
19658
19659   print (vam->ofp, "[%d]: sw_if_index %d via:",
19660          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19661   fp = mp->mt_paths;
19662   for (i = 0; i < count; i++)
19663     {
19664       vl_api_mpls_fib_path_print (vam, fp);
19665       fp++;
19666     }
19667
19668   print (vam->ofp, "");
19669 }
19670
19671 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19672 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19673
19674 static void
19675 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19676 {
19677   vat_main_t *vam = &vat_main;
19678   vat_json_node_t *node = NULL;
19679   int count = ntohl (mp->mt_count);
19680   vl_api_fib_path2_t *fp;
19681   i32 i;
19682
19683   if (VAT_JSON_ARRAY != vam->json_tree.type)
19684     {
19685       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19686       vat_json_init_array (&vam->json_tree);
19687     }
19688   node = vat_json_array_add (&vam->json_tree);
19689
19690   vat_json_init_object (node);
19691   vat_json_object_add_uint (node, "tunnel_index",
19692                             ntohl (mp->mt_tunnel_index));
19693   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19694
19695   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19696
19697   fp = mp->mt_paths;
19698   for (i = 0; i < count; i++)
19699     {
19700       vl_api_mpls_fib_path_json_print (node, fp);
19701       fp++;
19702     }
19703 }
19704
19705 static int
19706 api_mpls_tunnel_dump (vat_main_t * vam)
19707 {
19708   vl_api_mpls_tunnel_dump_t *mp;
19709   vl_api_control_ping_t *mp_ping;
19710   i32 index = -1;
19711   int ret;
19712
19713   /* Parse args required to build the message */
19714   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19715     {
19716       if (!unformat (vam->input, "tunnel_index %d", &index))
19717         {
19718           index = -1;
19719           break;
19720         }
19721     }
19722
19723   print (vam->ofp, "  tunnel_index %d", index);
19724
19725   M (MPLS_TUNNEL_DUMP, mp);
19726   mp->tunnel_index = htonl (index);
19727   S (mp);
19728
19729   /* Use a control ping for synchronization */
19730   MPING (CONTROL_PING, mp_ping);
19731   S (mp_ping);
19732
19733   W (ret);
19734   return ret;
19735 }
19736
19737 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19738 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19739
19740
19741 static void
19742 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19743 {
19744   vat_main_t *vam = &vat_main;
19745   int count = ntohl (mp->count);
19746   vl_api_fib_path2_t *fp;
19747   int i;
19748
19749   print (vam->ofp,
19750          "table-id %d, label %u, ess_bit %u",
19751          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19752   fp = mp->path;
19753   for (i = 0; i < count; i++)
19754     {
19755       vl_api_mpls_fib_path_print (vam, fp);
19756       fp++;
19757     }
19758 }
19759
19760 static void vl_api_mpls_fib_details_t_handler_json
19761   (vl_api_mpls_fib_details_t * mp)
19762 {
19763   vat_main_t *vam = &vat_main;
19764   int count = ntohl (mp->count);
19765   vat_json_node_t *node = NULL;
19766   vl_api_fib_path2_t *fp;
19767   int i;
19768
19769   if (VAT_JSON_ARRAY != vam->json_tree.type)
19770     {
19771       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19772       vat_json_init_array (&vam->json_tree);
19773     }
19774   node = vat_json_array_add (&vam->json_tree);
19775
19776   vat_json_init_object (node);
19777   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19778   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19779   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19780   vat_json_object_add_uint (node, "path_count", count);
19781   fp = mp->path;
19782   for (i = 0; i < count; i++)
19783     {
19784       vl_api_mpls_fib_path_json_print (node, fp);
19785       fp++;
19786     }
19787 }
19788
19789 static int
19790 api_mpls_fib_dump (vat_main_t * vam)
19791 {
19792   vl_api_mpls_fib_dump_t *mp;
19793   vl_api_control_ping_t *mp_ping;
19794   int ret;
19795
19796   M (MPLS_FIB_DUMP, mp);
19797   S (mp);
19798
19799   /* Use a control ping for synchronization */
19800   MPING (CONTROL_PING, mp_ping);
19801   S (mp_ping);
19802
19803   W (ret);
19804   return ret;
19805 }
19806
19807 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19808 #define vl_api_ip_fib_details_t_print vl_noop_handler
19809
19810 static void
19811 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19812 {
19813   vat_main_t *vam = &vat_main;
19814   int count = ntohl (mp->count);
19815   vl_api_fib_path_t *fp;
19816   int i;
19817
19818   print (vam->ofp,
19819          "table-id %d, prefix %U/%d",
19820          ntohl (mp->table_id), format_ip4_address, mp->address,
19821          mp->address_length);
19822   fp = mp->path;
19823   for (i = 0; i < count; i++)
19824     {
19825       if (fp->afi == IP46_TYPE_IP6)
19826         print (vam->ofp,
19827                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19828                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19829                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19830                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19831                format_ip6_address, fp->next_hop);
19832       else if (fp->afi == IP46_TYPE_IP4)
19833         print (vam->ofp,
19834                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19835                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19836                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19837                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19838                format_ip4_address, fp->next_hop);
19839       fp++;
19840     }
19841 }
19842
19843 static void vl_api_ip_fib_details_t_handler_json
19844   (vl_api_ip_fib_details_t * mp)
19845 {
19846   vat_main_t *vam = &vat_main;
19847   int count = ntohl (mp->count);
19848   vat_json_node_t *node = NULL;
19849   struct in_addr ip4;
19850   struct in6_addr ip6;
19851   vl_api_fib_path_t *fp;
19852   int i;
19853
19854   if (VAT_JSON_ARRAY != vam->json_tree.type)
19855     {
19856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19857       vat_json_init_array (&vam->json_tree);
19858     }
19859   node = vat_json_array_add (&vam->json_tree);
19860
19861   vat_json_init_object (node);
19862   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19863   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19864   vat_json_object_add_ip4 (node, "prefix", ip4);
19865   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19866   vat_json_object_add_uint (node, "path_count", count);
19867   fp = mp->path;
19868   for (i = 0; i < count; i++)
19869     {
19870       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19871       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19872       vat_json_object_add_uint (node, "is_local", fp->is_local);
19873       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19874       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19875       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19876       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19877       if (fp->afi == IP46_TYPE_IP4)
19878         {
19879           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19880           vat_json_object_add_ip4 (node, "next_hop", ip4);
19881         }
19882       else if (fp->afi == IP46_TYPE_IP6)
19883         {
19884           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19885           vat_json_object_add_ip6 (node, "next_hop", ip6);
19886         }
19887     }
19888 }
19889
19890 static int
19891 api_ip_fib_dump (vat_main_t * vam)
19892 {
19893   vl_api_ip_fib_dump_t *mp;
19894   vl_api_control_ping_t *mp_ping;
19895   int ret;
19896
19897   M (IP_FIB_DUMP, mp);
19898   S (mp);
19899
19900   /* Use a control ping for synchronization */
19901   MPING (CONTROL_PING, mp_ping);
19902   S (mp_ping);
19903
19904   W (ret);
19905   return ret;
19906 }
19907
19908 static int
19909 api_ip_mfib_dump (vat_main_t * vam)
19910 {
19911   vl_api_ip_mfib_dump_t *mp;
19912   vl_api_control_ping_t *mp_ping;
19913   int ret;
19914
19915   M (IP_MFIB_DUMP, mp);
19916   S (mp);
19917
19918   /* Use a control ping for synchronization */
19919   MPING (CONTROL_PING, mp_ping);
19920   S (mp_ping);
19921
19922   W (ret);
19923   return ret;
19924 }
19925
19926 static void vl_api_ip_neighbor_details_t_handler
19927   (vl_api_ip_neighbor_details_t * mp)
19928 {
19929   vat_main_t *vam = &vat_main;
19930
19931   print (vam->ofp, "%c %U %U",
19932          (mp->is_static) ? 'S' : 'D',
19933          format_ethernet_address, &mp->mac_address,
19934          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19935          &mp->ip_address);
19936 }
19937
19938 static void vl_api_ip_neighbor_details_t_handler_json
19939   (vl_api_ip_neighbor_details_t * mp)
19940 {
19941
19942   vat_main_t *vam = &vat_main;
19943   vat_json_node_t *node;
19944   struct in_addr ip4;
19945   struct in6_addr ip6;
19946
19947   if (VAT_JSON_ARRAY != vam->json_tree.type)
19948     {
19949       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19950       vat_json_init_array (&vam->json_tree);
19951     }
19952   node = vat_json_array_add (&vam->json_tree);
19953
19954   vat_json_init_object (node);
19955   vat_json_object_add_string_copy (node, "flag",
19956                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19957                                    "dynamic");
19958
19959   vat_json_object_add_string_copy (node, "link_layer",
19960                                    format (0, "%U", format_ethernet_address,
19961                                            &mp->mac_address));
19962
19963   if (mp->is_ipv6)
19964     {
19965       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19966       vat_json_object_add_ip6 (node, "ip_address", ip6);
19967     }
19968   else
19969     {
19970       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19971       vat_json_object_add_ip4 (node, "ip_address", ip4);
19972     }
19973 }
19974
19975 static int
19976 api_ip_neighbor_dump (vat_main_t * vam)
19977 {
19978   unformat_input_t *i = vam->input;
19979   vl_api_ip_neighbor_dump_t *mp;
19980   vl_api_control_ping_t *mp_ping;
19981   u8 is_ipv6 = 0;
19982   u32 sw_if_index = ~0;
19983   int ret;
19984
19985   /* Parse args required to build the message */
19986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19987     {
19988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19989         ;
19990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19991         ;
19992       else if (unformat (i, "ip6"))
19993         is_ipv6 = 1;
19994       else
19995         break;
19996     }
19997
19998   if (sw_if_index == ~0)
19999     {
20000       errmsg ("missing interface name or sw_if_index");
20001       return -99;
20002     }
20003
20004   M (IP_NEIGHBOR_DUMP, mp);
20005   mp->is_ipv6 = (u8) is_ipv6;
20006   mp->sw_if_index = ntohl (sw_if_index);
20007   S (mp);
20008
20009   /* Use a control ping for synchronization */
20010   MPING (CONTROL_PING, mp_ping);
20011   S (mp_ping);
20012
20013   W (ret);
20014   return ret;
20015 }
20016
20017 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20018 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20019
20020 static void
20021 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20022 {
20023   vat_main_t *vam = &vat_main;
20024   int count = ntohl (mp->count);
20025   vl_api_fib_path_t *fp;
20026   int i;
20027
20028   print (vam->ofp,
20029          "table-id %d, prefix %U/%d",
20030          ntohl (mp->table_id), format_ip6_address, mp->address,
20031          mp->address_length);
20032   fp = mp->path;
20033   for (i = 0; i < count; i++)
20034     {
20035       if (fp->afi == IP46_TYPE_IP6)
20036         print (vam->ofp,
20037                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20038                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20039                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20040                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20041                format_ip6_address, fp->next_hop);
20042       else if (fp->afi == IP46_TYPE_IP4)
20043         print (vam->ofp,
20044                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20045                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20046                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20047                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20048                format_ip4_address, fp->next_hop);
20049       fp++;
20050     }
20051 }
20052
20053 static void vl_api_ip6_fib_details_t_handler_json
20054   (vl_api_ip6_fib_details_t * mp)
20055 {
20056   vat_main_t *vam = &vat_main;
20057   int count = ntohl (mp->count);
20058   vat_json_node_t *node = NULL;
20059   struct in_addr ip4;
20060   struct in6_addr ip6;
20061   vl_api_fib_path_t *fp;
20062   int i;
20063
20064   if (VAT_JSON_ARRAY != vam->json_tree.type)
20065     {
20066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20067       vat_json_init_array (&vam->json_tree);
20068     }
20069   node = vat_json_array_add (&vam->json_tree);
20070
20071   vat_json_init_object (node);
20072   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20073   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20074   vat_json_object_add_ip6 (node, "prefix", ip6);
20075   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20076   vat_json_object_add_uint (node, "path_count", count);
20077   fp = mp->path;
20078   for (i = 0; i < count; i++)
20079     {
20080       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20081       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20082       vat_json_object_add_uint (node, "is_local", fp->is_local);
20083       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20084       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20085       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20086       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20087       if (fp->afi == IP46_TYPE_IP4)
20088         {
20089           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20090           vat_json_object_add_ip4 (node, "next_hop", ip4);
20091         }
20092       else if (fp->afi == IP46_TYPE_IP6)
20093         {
20094           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20095           vat_json_object_add_ip6 (node, "next_hop", ip6);
20096         }
20097     }
20098 }
20099
20100 static int
20101 api_ip6_fib_dump (vat_main_t * vam)
20102 {
20103   vl_api_ip6_fib_dump_t *mp;
20104   vl_api_control_ping_t *mp_ping;
20105   int ret;
20106
20107   M (IP6_FIB_DUMP, mp);
20108   S (mp);
20109
20110   /* Use a control ping for synchronization */
20111   MPING (CONTROL_PING, mp_ping);
20112   S (mp_ping);
20113
20114   W (ret);
20115   return ret;
20116 }
20117
20118 static int
20119 api_ip6_mfib_dump (vat_main_t * vam)
20120 {
20121   vl_api_ip6_mfib_dump_t *mp;
20122   vl_api_control_ping_t *mp_ping;
20123   int ret;
20124
20125   M (IP6_MFIB_DUMP, mp);
20126   S (mp);
20127
20128   /* Use a control ping for synchronization */
20129   MPING (CONTROL_PING, mp_ping);
20130   S (mp_ping);
20131
20132   W (ret);
20133   return ret;
20134 }
20135
20136 int
20137 api_classify_table_ids (vat_main_t * vam)
20138 {
20139   vl_api_classify_table_ids_t *mp;
20140   int ret;
20141
20142   /* Construct the API message */
20143   M (CLASSIFY_TABLE_IDS, mp);
20144   mp->context = 0;
20145
20146   S (mp);
20147   W (ret);
20148   return ret;
20149 }
20150
20151 int
20152 api_classify_table_by_interface (vat_main_t * vam)
20153 {
20154   unformat_input_t *input = vam->input;
20155   vl_api_classify_table_by_interface_t *mp;
20156
20157   u32 sw_if_index = ~0;
20158   int ret;
20159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20160     {
20161       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20162         ;
20163       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20164         ;
20165       else
20166         break;
20167     }
20168   if (sw_if_index == ~0)
20169     {
20170       errmsg ("missing interface name or sw_if_index");
20171       return -99;
20172     }
20173
20174   /* Construct the API message */
20175   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20176   mp->context = 0;
20177   mp->sw_if_index = ntohl (sw_if_index);
20178
20179   S (mp);
20180   W (ret);
20181   return ret;
20182 }
20183
20184 int
20185 api_classify_table_info (vat_main_t * vam)
20186 {
20187   unformat_input_t *input = vam->input;
20188   vl_api_classify_table_info_t *mp;
20189
20190   u32 table_id = ~0;
20191   int ret;
20192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20193     {
20194       if (unformat (input, "table_id %d", &table_id))
20195         ;
20196       else
20197         break;
20198     }
20199   if (table_id == ~0)
20200     {
20201       errmsg ("missing table id");
20202       return -99;
20203     }
20204
20205   /* Construct the API message */
20206   M (CLASSIFY_TABLE_INFO, mp);
20207   mp->context = 0;
20208   mp->table_id = ntohl (table_id);
20209
20210   S (mp);
20211   W (ret);
20212   return ret;
20213 }
20214
20215 int
20216 api_classify_session_dump (vat_main_t * vam)
20217 {
20218   unformat_input_t *input = vam->input;
20219   vl_api_classify_session_dump_t *mp;
20220   vl_api_control_ping_t *mp_ping;
20221
20222   u32 table_id = ~0;
20223   int ret;
20224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20225     {
20226       if (unformat (input, "table_id %d", &table_id))
20227         ;
20228       else
20229         break;
20230     }
20231   if (table_id == ~0)
20232     {
20233       errmsg ("missing table id");
20234       return -99;
20235     }
20236
20237   /* Construct the API message */
20238   M (CLASSIFY_SESSION_DUMP, mp);
20239   mp->context = 0;
20240   mp->table_id = ntohl (table_id);
20241   S (mp);
20242
20243   /* Use a control ping for synchronization */
20244   MPING (CONTROL_PING, mp_ping);
20245   S (mp_ping);
20246
20247   W (ret);
20248   return ret;
20249 }
20250
20251 static void
20252 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20253 {
20254   vat_main_t *vam = &vat_main;
20255
20256   print (vam->ofp, "collector_address %U, collector_port %d, "
20257          "src_address %U, vrf_id %d, path_mtu %u, "
20258          "template_interval %u, udp_checksum %d",
20259          format_ip4_address, mp->collector_address,
20260          ntohs (mp->collector_port),
20261          format_ip4_address, mp->src_address,
20262          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20263          ntohl (mp->template_interval), mp->udp_checksum);
20264
20265   vam->retval = 0;
20266   vam->result_ready = 1;
20267 }
20268
20269 static void
20270   vl_api_ipfix_exporter_details_t_handler_json
20271   (vl_api_ipfix_exporter_details_t * mp)
20272 {
20273   vat_main_t *vam = &vat_main;
20274   vat_json_node_t node;
20275   struct in_addr collector_address;
20276   struct in_addr src_address;
20277
20278   vat_json_init_object (&node);
20279   clib_memcpy (&collector_address, &mp->collector_address,
20280                sizeof (collector_address));
20281   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20282   vat_json_object_add_uint (&node, "collector_port",
20283                             ntohs (mp->collector_port));
20284   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20285   vat_json_object_add_ip4 (&node, "src_address", src_address);
20286   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20287   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20288   vat_json_object_add_uint (&node, "template_interval",
20289                             ntohl (mp->template_interval));
20290   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20291
20292   vat_json_print (vam->ofp, &node);
20293   vat_json_free (&node);
20294   vam->retval = 0;
20295   vam->result_ready = 1;
20296 }
20297
20298 int
20299 api_ipfix_exporter_dump (vat_main_t * vam)
20300 {
20301   vl_api_ipfix_exporter_dump_t *mp;
20302   int ret;
20303
20304   /* Construct the API message */
20305   M (IPFIX_EXPORTER_DUMP, mp);
20306   mp->context = 0;
20307
20308   S (mp);
20309   W (ret);
20310   return ret;
20311 }
20312
20313 static int
20314 api_ipfix_classify_stream_dump (vat_main_t * vam)
20315 {
20316   vl_api_ipfix_classify_stream_dump_t *mp;
20317   int ret;
20318
20319   /* Construct the API message */
20320   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20321   mp->context = 0;
20322
20323   S (mp);
20324   W (ret);
20325   return ret;
20326   /* NOTREACHED */
20327   return 0;
20328 }
20329
20330 static void
20331   vl_api_ipfix_classify_stream_details_t_handler
20332   (vl_api_ipfix_classify_stream_details_t * mp)
20333 {
20334   vat_main_t *vam = &vat_main;
20335   print (vam->ofp, "domain_id %d, src_port %d",
20336          ntohl (mp->domain_id), ntohs (mp->src_port));
20337   vam->retval = 0;
20338   vam->result_ready = 1;
20339 }
20340
20341 static void
20342   vl_api_ipfix_classify_stream_details_t_handler_json
20343   (vl_api_ipfix_classify_stream_details_t * mp)
20344 {
20345   vat_main_t *vam = &vat_main;
20346   vat_json_node_t node;
20347
20348   vat_json_init_object (&node);
20349   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20350   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20351
20352   vat_json_print (vam->ofp, &node);
20353   vat_json_free (&node);
20354   vam->retval = 0;
20355   vam->result_ready = 1;
20356 }
20357
20358 static int
20359 api_ipfix_classify_table_dump (vat_main_t * vam)
20360 {
20361   vl_api_ipfix_classify_table_dump_t *mp;
20362   vl_api_control_ping_t *mp_ping;
20363   int ret;
20364
20365   if (!vam->json_output)
20366     {
20367       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20368              "transport_protocol");
20369     }
20370
20371   /* Construct the API message */
20372   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20373
20374   /* send it... */
20375   S (mp);
20376
20377   /* Use a control ping for synchronization */
20378   MPING (CONTROL_PING, mp_ping);
20379   S (mp_ping);
20380
20381   W (ret);
20382   return ret;
20383 }
20384
20385 static void
20386   vl_api_ipfix_classify_table_details_t_handler
20387   (vl_api_ipfix_classify_table_details_t * mp)
20388 {
20389   vat_main_t *vam = &vat_main;
20390   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20391          mp->transport_protocol);
20392 }
20393
20394 static void
20395   vl_api_ipfix_classify_table_details_t_handler_json
20396   (vl_api_ipfix_classify_table_details_t * mp)
20397 {
20398   vat_json_node_t *node = NULL;
20399   vat_main_t *vam = &vat_main;
20400
20401   if (VAT_JSON_ARRAY != vam->json_tree.type)
20402     {
20403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20404       vat_json_init_array (&vam->json_tree);
20405     }
20406
20407   node = vat_json_array_add (&vam->json_tree);
20408   vat_json_init_object (node);
20409
20410   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20411   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20412   vat_json_object_add_uint (node, "transport_protocol",
20413                             mp->transport_protocol);
20414 }
20415
20416 static int
20417 api_sw_interface_span_enable_disable (vat_main_t * vam)
20418 {
20419   unformat_input_t *i = vam->input;
20420   vl_api_sw_interface_span_enable_disable_t *mp;
20421   u32 src_sw_if_index = ~0;
20422   u32 dst_sw_if_index = ~0;
20423   u8 state = 3;
20424   int ret;
20425   u8 is_l2 = 0;
20426
20427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20428     {
20429       if (unformat
20430           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20431         ;
20432       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20433         ;
20434       else
20435         if (unformat
20436             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20437         ;
20438       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20439         ;
20440       else if (unformat (i, "disable"))
20441         state = 0;
20442       else if (unformat (i, "rx"))
20443         state = 1;
20444       else if (unformat (i, "tx"))
20445         state = 2;
20446       else if (unformat (i, "both"))
20447         state = 3;
20448       else if (unformat (i, "l2"))
20449         is_l2 = 1;
20450       else
20451         break;
20452     }
20453
20454   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20455
20456   mp->sw_if_index_from = htonl (src_sw_if_index);
20457   mp->sw_if_index_to = htonl (dst_sw_if_index);
20458   mp->state = state;
20459   mp->is_l2 = is_l2;
20460
20461   S (mp);
20462   W (ret);
20463   return ret;
20464 }
20465
20466 static void
20467 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20468                                             * mp)
20469 {
20470   vat_main_t *vam = &vat_main;
20471   u8 *sw_if_from_name = 0;
20472   u8 *sw_if_to_name = 0;
20473   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20474   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20475   char *states[] = { "none", "rx", "tx", "both" };
20476   hash_pair_t *p;
20477
20478   /* *INDENT-OFF* */
20479   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20480   ({
20481     if ((u32) p->value[0] == sw_if_index_from)
20482       {
20483         sw_if_from_name = (u8 *)(p->key);
20484         if (sw_if_to_name)
20485           break;
20486       }
20487     if ((u32) p->value[0] == sw_if_index_to)
20488       {
20489         sw_if_to_name = (u8 *)(p->key);
20490         if (sw_if_from_name)
20491           break;
20492       }
20493   }));
20494   /* *INDENT-ON* */
20495   print (vam->ofp, "%20s => %20s (%s)",
20496          sw_if_from_name, sw_if_to_name, states[mp->state]);
20497 }
20498
20499 static void
20500   vl_api_sw_interface_span_details_t_handler_json
20501   (vl_api_sw_interface_span_details_t * mp)
20502 {
20503   vat_main_t *vam = &vat_main;
20504   vat_json_node_t *node = NULL;
20505   u8 *sw_if_from_name = 0;
20506   u8 *sw_if_to_name = 0;
20507   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20508   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20509   hash_pair_t *p;
20510
20511   /* *INDENT-OFF* */
20512   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20513   ({
20514     if ((u32) p->value[0] == sw_if_index_from)
20515       {
20516         sw_if_from_name = (u8 *)(p->key);
20517         if (sw_if_to_name)
20518           break;
20519       }
20520     if ((u32) p->value[0] == sw_if_index_to)
20521       {
20522         sw_if_to_name = (u8 *)(p->key);
20523         if (sw_if_from_name)
20524           break;
20525       }
20526   }));
20527   /* *INDENT-ON* */
20528
20529   if (VAT_JSON_ARRAY != vam->json_tree.type)
20530     {
20531       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20532       vat_json_init_array (&vam->json_tree);
20533     }
20534   node = vat_json_array_add (&vam->json_tree);
20535
20536   vat_json_init_object (node);
20537   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20538   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20539   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20540   if (0 != sw_if_to_name)
20541     {
20542       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20543     }
20544   vat_json_object_add_uint (node, "state", mp->state);
20545 }
20546
20547 static int
20548 api_sw_interface_span_dump (vat_main_t * vam)
20549 {
20550   unformat_input_t *input = vam->input;
20551   vl_api_sw_interface_span_dump_t *mp;
20552   vl_api_control_ping_t *mp_ping;
20553   u8 is_l2 = 0;
20554   int ret;
20555
20556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20557     {
20558       if (unformat (input, "l2"))
20559         is_l2 = 1;
20560       else
20561         break;
20562     }
20563
20564   M (SW_INTERFACE_SPAN_DUMP, mp);
20565   mp->is_l2 = is_l2;
20566   S (mp);
20567
20568   /* Use a control ping for synchronization */
20569   MPING (CONTROL_PING, mp_ping);
20570   S (mp_ping);
20571
20572   W (ret);
20573   return ret;
20574 }
20575
20576 int
20577 api_pg_create_interface (vat_main_t * vam)
20578 {
20579   unformat_input_t *input = vam->input;
20580   vl_api_pg_create_interface_t *mp;
20581
20582   u32 if_id = ~0;
20583   int ret;
20584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20585     {
20586       if (unformat (input, "if_id %d", &if_id))
20587         ;
20588       else
20589         break;
20590     }
20591   if (if_id == ~0)
20592     {
20593       errmsg ("missing pg interface index");
20594       return -99;
20595     }
20596
20597   /* Construct the API message */
20598   M (PG_CREATE_INTERFACE, mp);
20599   mp->context = 0;
20600   mp->interface_id = ntohl (if_id);
20601
20602   S (mp);
20603   W (ret);
20604   return ret;
20605 }
20606
20607 int
20608 api_pg_capture (vat_main_t * vam)
20609 {
20610   unformat_input_t *input = vam->input;
20611   vl_api_pg_capture_t *mp;
20612
20613   u32 if_id = ~0;
20614   u8 enable = 1;
20615   u32 count = 1;
20616   u8 pcap_file_set = 0;
20617   u8 *pcap_file = 0;
20618   int ret;
20619   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20620     {
20621       if (unformat (input, "if_id %d", &if_id))
20622         ;
20623       else if (unformat (input, "pcap %s", &pcap_file))
20624         pcap_file_set = 1;
20625       else if (unformat (input, "count %d", &count))
20626         ;
20627       else if (unformat (input, "disable"))
20628         enable = 0;
20629       else
20630         break;
20631     }
20632   if (if_id == ~0)
20633     {
20634       errmsg ("missing pg interface index");
20635       return -99;
20636     }
20637   if (pcap_file_set > 0)
20638     {
20639       if (vec_len (pcap_file) > 255)
20640         {
20641           errmsg ("pcap file name is too long");
20642           return -99;
20643         }
20644     }
20645
20646   u32 name_len = vec_len (pcap_file);
20647   /* Construct the API message */
20648   M (PG_CAPTURE, mp);
20649   mp->context = 0;
20650   mp->interface_id = ntohl (if_id);
20651   mp->is_enabled = enable;
20652   mp->count = ntohl (count);
20653   mp->pcap_name_length = ntohl (name_len);
20654   if (pcap_file_set != 0)
20655     {
20656       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20657     }
20658   vec_free (pcap_file);
20659
20660   S (mp);
20661   W (ret);
20662   return ret;
20663 }
20664
20665 int
20666 api_pg_enable_disable (vat_main_t * vam)
20667 {
20668   unformat_input_t *input = vam->input;
20669   vl_api_pg_enable_disable_t *mp;
20670
20671   u8 enable = 1;
20672   u8 stream_name_set = 0;
20673   u8 *stream_name = 0;
20674   int ret;
20675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20676     {
20677       if (unformat (input, "stream %s", &stream_name))
20678         stream_name_set = 1;
20679       else if (unformat (input, "disable"))
20680         enable = 0;
20681       else
20682         break;
20683     }
20684
20685   if (stream_name_set > 0)
20686     {
20687       if (vec_len (stream_name) > 255)
20688         {
20689           errmsg ("stream name too long");
20690           return -99;
20691         }
20692     }
20693
20694   u32 name_len = vec_len (stream_name);
20695   /* Construct the API message */
20696   M (PG_ENABLE_DISABLE, mp);
20697   mp->context = 0;
20698   mp->is_enabled = enable;
20699   if (stream_name_set != 0)
20700     {
20701       mp->stream_name_length = ntohl (name_len);
20702       clib_memcpy (mp->stream_name, stream_name, name_len);
20703     }
20704   vec_free (stream_name);
20705
20706   S (mp);
20707   W (ret);
20708   return ret;
20709 }
20710
20711 int
20712 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20713 {
20714   unformat_input_t *input = vam->input;
20715   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20716
20717   u16 *low_ports = 0;
20718   u16 *high_ports = 0;
20719   u16 this_low;
20720   u16 this_hi;
20721   ip4_address_t ip4_addr;
20722   ip6_address_t ip6_addr;
20723   u32 length;
20724   u32 tmp, tmp2;
20725   u8 prefix_set = 0;
20726   u32 vrf_id = ~0;
20727   u8 is_add = 1;
20728   u8 is_ipv6 = 0;
20729   int ret;
20730
20731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20732     {
20733       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20734         {
20735           prefix_set = 1;
20736         }
20737       else
20738         if (unformat
20739             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20740         {
20741           prefix_set = 1;
20742           is_ipv6 = 1;
20743         }
20744       else if (unformat (input, "vrf %d", &vrf_id))
20745         ;
20746       else if (unformat (input, "del"))
20747         is_add = 0;
20748       else if (unformat (input, "port %d", &tmp))
20749         {
20750           if (tmp == 0 || tmp > 65535)
20751             {
20752               errmsg ("port %d out of range", tmp);
20753               return -99;
20754             }
20755           this_low = tmp;
20756           this_hi = this_low + 1;
20757           vec_add1 (low_ports, this_low);
20758           vec_add1 (high_ports, this_hi);
20759         }
20760       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20761         {
20762           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20763             {
20764               errmsg ("incorrect range parameters");
20765               return -99;
20766             }
20767           this_low = tmp;
20768           /* Note: in debug CLI +1 is added to high before
20769              passing to real fn that does "the work"
20770              (ip_source_and_port_range_check_add_del).
20771              This fn is a wrapper around the binary API fn a
20772              control plane will call, which expects this increment
20773              to have occurred. Hence letting the binary API control
20774              plane fn do the increment for consistency between VAT
20775              and other control planes.
20776            */
20777           this_hi = tmp2;
20778           vec_add1 (low_ports, this_low);
20779           vec_add1 (high_ports, this_hi);
20780         }
20781       else
20782         break;
20783     }
20784
20785   if (prefix_set == 0)
20786     {
20787       errmsg ("<address>/<mask> not specified");
20788       return -99;
20789     }
20790
20791   if (vrf_id == ~0)
20792     {
20793       errmsg ("VRF ID required, not specified");
20794       return -99;
20795     }
20796
20797   if (vrf_id == 0)
20798     {
20799       errmsg
20800         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20801       return -99;
20802     }
20803
20804   if (vec_len (low_ports) == 0)
20805     {
20806       errmsg ("At least one port or port range required");
20807       return -99;
20808     }
20809
20810   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20811
20812   mp->is_add = is_add;
20813
20814   if (is_ipv6)
20815     {
20816       mp->is_ipv6 = 1;
20817       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20818     }
20819   else
20820     {
20821       mp->is_ipv6 = 0;
20822       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20823     }
20824
20825   mp->mask_length = length;
20826   mp->number_of_ranges = vec_len (low_ports);
20827
20828   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20829   vec_free (low_ports);
20830
20831   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20832   vec_free (high_ports);
20833
20834   mp->vrf_id = ntohl (vrf_id);
20835
20836   S (mp);
20837   W (ret);
20838   return ret;
20839 }
20840
20841 int
20842 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20843 {
20844   unformat_input_t *input = vam->input;
20845   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20846   u32 sw_if_index = ~0;
20847   int vrf_set = 0;
20848   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20849   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20850   u8 is_add = 1;
20851   int ret;
20852
20853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20854     {
20855       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20856         ;
20857       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20858         ;
20859       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20860         vrf_set = 1;
20861       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20862         vrf_set = 1;
20863       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20864         vrf_set = 1;
20865       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20866         vrf_set = 1;
20867       else if (unformat (input, "del"))
20868         is_add = 0;
20869       else
20870         break;
20871     }
20872
20873   if (sw_if_index == ~0)
20874     {
20875       errmsg ("Interface required but not specified");
20876       return -99;
20877     }
20878
20879   if (vrf_set == 0)
20880     {
20881       errmsg ("VRF ID required but not specified");
20882       return -99;
20883     }
20884
20885   if (tcp_out_vrf_id == 0
20886       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20887     {
20888       errmsg
20889         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20890       return -99;
20891     }
20892
20893   /* Construct the API message */
20894   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20895
20896   mp->sw_if_index = ntohl (sw_if_index);
20897   mp->is_add = is_add;
20898   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20899   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20900   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20901   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20902
20903   /* send it... */
20904   S (mp);
20905
20906   /* Wait for a reply... */
20907   W (ret);
20908   return ret;
20909 }
20910
20911 static int
20912 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20913 {
20914   unformat_input_t *i = vam->input;
20915   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20916   u32 local_sa_id = 0;
20917   u32 remote_sa_id = 0;
20918   ip4_address_t src_address;
20919   ip4_address_t dst_address;
20920   u8 is_add = 1;
20921   int ret;
20922
20923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20924     {
20925       if (unformat (i, "local_sa %d", &local_sa_id))
20926         ;
20927       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20928         ;
20929       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20930         ;
20931       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20932         ;
20933       else if (unformat (i, "del"))
20934         is_add = 0;
20935       else
20936         {
20937           clib_warning ("parse error '%U'", format_unformat_error, i);
20938           return -99;
20939         }
20940     }
20941
20942   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20943
20944   mp->local_sa_id = ntohl (local_sa_id);
20945   mp->remote_sa_id = ntohl (remote_sa_id);
20946   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20947   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20948   mp->is_add = is_add;
20949
20950   S (mp);
20951   W (ret);
20952   return ret;
20953 }
20954
20955 static int
20956 api_punt (vat_main_t * vam)
20957 {
20958   unformat_input_t *i = vam->input;
20959   vl_api_punt_t *mp;
20960   u32 ipv = ~0;
20961   u32 protocol = ~0;
20962   u32 port = ~0;
20963   int is_add = 1;
20964   int ret;
20965
20966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20967     {
20968       if (unformat (i, "ip %d", &ipv))
20969         ;
20970       else if (unformat (i, "protocol %d", &protocol))
20971         ;
20972       else if (unformat (i, "port %d", &port))
20973         ;
20974       else if (unformat (i, "del"))
20975         is_add = 0;
20976       else
20977         {
20978           clib_warning ("parse error '%U'", format_unformat_error, i);
20979           return -99;
20980         }
20981     }
20982
20983   M (PUNT, mp);
20984
20985   mp->is_add = (u8) is_add;
20986   mp->ipv = (u8) ipv;
20987   mp->l4_protocol = (u8) protocol;
20988   mp->l4_port = htons ((u16) port);
20989
20990   S (mp);
20991   W (ret);
20992   return ret;
20993 }
20994
20995 static void vl_api_ipsec_gre_tunnel_details_t_handler
20996   (vl_api_ipsec_gre_tunnel_details_t * mp)
20997 {
20998   vat_main_t *vam = &vat_main;
20999
21000   print (vam->ofp, "%11d%15U%15U%14d%14d",
21001          ntohl (mp->sw_if_index),
21002          format_ip4_address, &mp->src_address,
21003          format_ip4_address, &mp->dst_address,
21004          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21005 }
21006
21007 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21008   (vl_api_ipsec_gre_tunnel_details_t * mp)
21009 {
21010   vat_main_t *vam = &vat_main;
21011   vat_json_node_t *node = NULL;
21012   struct in_addr ip4;
21013
21014   if (VAT_JSON_ARRAY != vam->json_tree.type)
21015     {
21016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21017       vat_json_init_array (&vam->json_tree);
21018     }
21019   node = vat_json_array_add (&vam->json_tree);
21020
21021   vat_json_init_object (node);
21022   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21023   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21024   vat_json_object_add_ip4 (node, "src_address", ip4);
21025   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21026   vat_json_object_add_ip4 (node, "dst_address", ip4);
21027   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21028   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21029 }
21030
21031 static int
21032 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21033 {
21034   unformat_input_t *i = vam->input;
21035   vl_api_ipsec_gre_tunnel_dump_t *mp;
21036   vl_api_control_ping_t *mp_ping;
21037   u32 sw_if_index;
21038   u8 sw_if_index_set = 0;
21039   int ret;
21040
21041   /* Parse args required to build the message */
21042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21043     {
21044       if (unformat (i, "sw_if_index %d", &sw_if_index))
21045         sw_if_index_set = 1;
21046       else
21047         break;
21048     }
21049
21050   if (sw_if_index_set == 0)
21051     {
21052       sw_if_index = ~0;
21053     }
21054
21055   if (!vam->json_output)
21056     {
21057       print (vam->ofp, "%11s%15s%15s%14s%14s",
21058              "sw_if_index", "src_address", "dst_address",
21059              "local_sa_id", "remote_sa_id");
21060     }
21061
21062   /* Get list of gre-tunnel interfaces */
21063   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21064
21065   mp->sw_if_index = htonl (sw_if_index);
21066
21067   S (mp);
21068
21069   /* Use a control ping for synchronization */
21070   MPING (CONTROL_PING, mp_ping);
21071   S (mp_ping);
21072
21073   W (ret);
21074   return ret;
21075 }
21076
21077 static int
21078 api_delete_subif (vat_main_t * vam)
21079 {
21080   unformat_input_t *i = vam->input;
21081   vl_api_delete_subif_t *mp;
21082   u32 sw_if_index = ~0;
21083   int ret;
21084
21085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21086     {
21087       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21088         ;
21089       if (unformat (i, "sw_if_index %d", &sw_if_index))
21090         ;
21091       else
21092         break;
21093     }
21094
21095   if (sw_if_index == ~0)
21096     {
21097       errmsg ("missing sw_if_index");
21098       return -99;
21099     }
21100
21101   /* Construct the API message */
21102   M (DELETE_SUBIF, mp);
21103   mp->sw_if_index = ntohl (sw_if_index);
21104
21105   S (mp);
21106   W (ret);
21107   return ret;
21108 }
21109
21110 #define foreach_pbb_vtr_op      \
21111 _("disable",  L2_VTR_DISABLED)  \
21112 _("pop",  L2_VTR_POP_2)         \
21113 _("push",  L2_VTR_PUSH_2)
21114
21115 static int
21116 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21117 {
21118   unformat_input_t *i = vam->input;
21119   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21120   u32 sw_if_index = ~0, vtr_op = ~0;
21121   u16 outer_tag = ~0;
21122   u8 dmac[6], smac[6];
21123   u8 dmac_set = 0, smac_set = 0;
21124   u16 vlanid = 0;
21125   u32 sid = ~0;
21126   u32 tmp;
21127   int ret;
21128
21129   /* Shut up coverity */
21130   memset (dmac, 0, sizeof (dmac));
21131   memset (smac, 0, sizeof (smac));
21132
21133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21134     {
21135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21136         ;
21137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21138         ;
21139       else if (unformat (i, "vtr_op %d", &vtr_op))
21140         ;
21141 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21142       foreach_pbb_vtr_op
21143 #undef _
21144         else if (unformat (i, "translate_pbb_stag"))
21145         {
21146           if (unformat (i, "%d", &tmp))
21147             {
21148               vtr_op = L2_VTR_TRANSLATE_2_1;
21149               outer_tag = tmp;
21150             }
21151           else
21152             {
21153               errmsg
21154                 ("translate_pbb_stag operation requires outer tag definition");
21155               return -99;
21156             }
21157         }
21158       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21159         dmac_set++;
21160       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21161         smac_set++;
21162       else if (unformat (i, "sid %d", &sid))
21163         ;
21164       else if (unformat (i, "vlanid %d", &tmp))
21165         vlanid = tmp;
21166       else
21167         {
21168           clib_warning ("parse error '%U'", format_unformat_error, i);
21169           return -99;
21170         }
21171     }
21172
21173   if ((sw_if_index == ~0) || (vtr_op == ~0))
21174     {
21175       errmsg ("missing sw_if_index or vtr operation");
21176       return -99;
21177     }
21178   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21179       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21180     {
21181       errmsg
21182         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21183       return -99;
21184     }
21185
21186   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21187   mp->sw_if_index = ntohl (sw_if_index);
21188   mp->vtr_op = ntohl (vtr_op);
21189   mp->outer_tag = ntohs (outer_tag);
21190   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21191   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21192   mp->b_vlanid = ntohs (vlanid);
21193   mp->i_sid = ntohl (sid);
21194
21195   S (mp);
21196   W (ret);
21197   return ret;
21198 }
21199
21200 static int
21201 api_flow_classify_set_interface (vat_main_t * vam)
21202 {
21203   unformat_input_t *i = vam->input;
21204   vl_api_flow_classify_set_interface_t *mp;
21205   u32 sw_if_index;
21206   int sw_if_index_set;
21207   u32 ip4_table_index = ~0;
21208   u32 ip6_table_index = ~0;
21209   u8 is_add = 1;
21210   int ret;
21211
21212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21213     {
21214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21215         sw_if_index_set = 1;
21216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21217         sw_if_index_set = 1;
21218       else if (unformat (i, "del"))
21219         is_add = 0;
21220       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21221         ;
21222       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21223         ;
21224       else
21225         {
21226           clib_warning ("parse error '%U'", format_unformat_error, i);
21227           return -99;
21228         }
21229     }
21230
21231   if (sw_if_index_set == 0)
21232     {
21233       errmsg ("missing interface name or sw_if_index");
21234       return -99;
21235     }
21236
21237   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21238
21239   mp->sw_if_index = ntohl (sw_if_index);
21240   mp->ip4_table_index = ntohl (ip4_table_index);
21241   mp->ip6_table_index = ntohl (ip6_table_index);
21242   mp->is_add = is_add;
21243
21244   S (mp);
21245   W (ret);
21246   return ret;
21247 }
21248
21249 static int
21250 api_flow_classify_dump (vat_main_t * vam)
21251 {
21252   unformat_input_t *i = vam->input;
21253   vl_api_flow_classify_dump_t *mp;
21254   vl_api_control_ping_t *mp_ping;
21255   u8 type = FLOW_CLASSIFY_N_TABLES;
21256   int ret;
21257
21258   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21259     ;
21260   else
21261     {
21262       errmsg ("classify table type must be specified");
21263       return -99;
21264     }
21265
21266   if (!vam->json_output)
21267     {
21268       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21269     }
21270
21271   M (FLOW_CLASSIFY_DUMP, mp);
21272   mp->type = type;
21273   /* send it... */
21274   S (mp);
21275
21276   /* Use a control ping for synchronization */
21277   MPING (CONTROL_PING, mp_ping);
21278   S (mp_ping);
21279
21280   /* Wait for a reply... */
21281   W (ret);
21282   return ret;
21283 }
21284
21285 static int
21286 api_feature_enable_disable (vat_main_t * vam)
21287 {
21288   unformat_input_t *i = vam->input;
21289   vl_api_feature_enable_disable_t *mp;
21290   u8 *arc_name = 0;
21291   u8 *feature_name = 0;
21292   u32 sw_if_index = ~0;
21293   u8 enable = 1;
21294   int ret;
21295
21296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21297     {
21298       if (unformat (i, "arc_name %s", &arc_name))
21299         ;
21300       else if (unformat (i, "feature_name %s", &feature_name))
21301         ;
21302       else
21303         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21304         ;
21305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21306         ;
21307       else if (unformat (i, "disable"))
21308         enable = 0;
21309       else
21310         break;
21311     }
21312
21313   if (arc_name == 0)
21314     {
21315       errmsg ("missing arc name");
21316       return -99;
21317     }
21318   if (vec_len (arc_name) > 63)
21319     {
21320       errmsg ("arc name too long");
21321     }
21322
21323   if (feature_name == 0)
21324     {
21325       errmsg ("missing feature name");
21326       return -99;
21327     }
21328   if (vec_len (feature_name) > 63)
21329     {
21330       errmsg ("feature name too long");
21331     }
21332
21333   if (sw_if_index == ~0)
21334     {
21335       errmsg ("missing interface name or sw_if_index");
21336       return -99;
21337     }
21338
21339   /* Construct the API message */
21340   M (FEATURE_ENABLE_DISABLE, mp);
21341   mp->sw_if_index = ntohl (sw_if_index);
21342   mp->enable = enable;
21343   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21344   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21345   vec_free (arc_name);
21346   vec_free (feature_name);
21347
21348   S (mp);
21349   W (ret);
21350   return ret;
21351 }
21352
21353 static int
21354 api_sw_interface_tag_add_del (vat_main_t * vam)
21355 {
21356   unformat_input_t *i = vam->input;
21357   vl_api_sw_interface_tag_add_del_t *mp;
21358   u32 sw_if_index = ~0;
21359   u8 *tag = 0;
21360   u8 enable = 1;
21361   int ret;
21362
21363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21364     {
21365       if (unformat (i, "tag %s", &tag))
21366         ;
21367       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21368         ;
21369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21370         ;
21371       else if (unformat (i, "del"))
21372         enable = 0;
21373       else
21374         break;
21375     }
21376
21377   if (sw_if_index == ~0)
21378     {
21379       errmsg ("missing interface name or sw_if_index");
21380       return -99;
21381     }
21382
21383   if (enable && (tag == 0))
21384     {
21385       errmsg ("no tag specified");
21386       return -99;
21387     }
21388
21389   /* Construct the API message */
21390   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21391   mp->sw_if_index = ntohl (sw_if_index);
21392   mp->is_add = enable;
21393   if (enable)
21394     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21395   vec_free (tag);
21396
21397   S (mp);
21398   W (ret);
21399   return ret;
21400 }
21401
21402 static void vl_api_l2_xconnect_details_t_handler
21403   (vl_api_l2_xconnect_details_t * mp)
21404 {
21405   vat_main_t *vam = &vat_main;
21406
21407   print (vam->ofp, "%15d%15d",
21408          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21409 }
21410
21411 static void vl_api_l2_xconnect_details_t_handler_json
21412   (vl_api_l2_xconnect_details_t * mp)
21413 {
21414   vat_main_t *vam = &vat_main;
21415   vat_json_node_t *node = NULL;
21416
21417   if (VAT_JSON_ARRAY != vam->json_tree.type)
21418     {
21419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21420       vat_json_init_array (&vam->json_tree);
21421     }
21422   node = vat_json_array_add (&vam->json_tree);
21423
21424   vat_json_init_object (node);
21425   vat_json_object_add_uint (node, "rx_sw_if_index",
21426                             ntohl (mp->rx_sw_if_index));
21427   vat_json_object_add_uint (node, "tx_sw_if_index",
21428                             ntohl (mp->tx_sw_if_index));
21429 }
21430
21431 static int
21432 api_l2_xconnect_dump (vat_main_t * vam)
21433 {
21434   vl_api_l2_xconnect_dump_t *mp;
21435   vl_api_control_ping_t *mp_ping;
21436   int ret;
21437
21438   if (!vam->json_output)
21439     {
21440       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21441     }
21442
21443   M (L2_XCONNECT_DUMP, mp);
21444
21445   S (mp);
21446
21447   /* Use a control ping for synchronization */
21448   MPING (CONTROL_PING, mp_ping);
21449   S (mp_ping);
21450
21451   W (ret);
21452   return ret;
21453 }
21454
21455 static int
21456 api_sw_interface_set_mtu (vat_main_t * vam)
21457 {
21458   unformat_input_t *i = vam->input;
21459   vl_api_sw_interface_set_mtu_t *mp;
21460   u32 sw_if_index = ~0;
21461   u32 mtu = 0;
21462   int ret;
21463
21464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21465     {
21466       if (unformat (i, "mtu %d", &mtu))
21467         ;
21468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21469         ;
21470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21471         ;
21472       else
21473         break;
21474     }
21475
21476   if (sw_if_index == ~0)
21477     {
21478       errmsg ("missing interface name or sw_if_index");
21479       return -99;
21480     }
21481
21482   if (mtu == 0)
21483     {
21484       errmsg ("no mtu specified");
21485       return -99;
21486     }
21487
21488   /* Construct the API message */
21489   M (SW_INTERFACE_SET_MTU, mp);
21490   mp->sw_if_index = ntohl (sw_if_index);
21491   mp->mtu = ntohs ((u16) mtu);
21492
21493   S (mp);
21494   W (ret);
21495   return ret;
21496 }
21497
21498 static int
21499 api_p2p_ethernet_add (vat_main_t * vam)
21500 {
21501   unformat_input_t *i = vam->input;
21502   vl_api_p2p_ethernet_add_t *mp;
21503   u32 parent_if_index = ~0;
21504   u32 sub_id = ~0;
21505   u8 remote_mac[6];
21506   u8 mac_set = 0;
21507   int ret;
21508
21509   memset (remote_mac, 0, sizeof (remote_mac));
21510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21511     {
21512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21513         ;
21514       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21515         ;
21516       else
21517         if (unformat
21518             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21519         mac_set++;
21520       else if (unformat (i, "sub_id %d", &sub_id))
21521         ;
21522       else
21523         {
21524           clib_warning ("parse error '%U'", format_unformat_error, i);
21525           return -99;
21526         }
21527     }
21528
21529   if (parent_if_index == ~0)
21530     {
21531       errmsg ("missing interface name or sw_if_index");
21532       return -99;
21533     }
21534   if (mac_set == 0)
21535     {
21536       errmsg ("missing remote mac address");
21537       return -99;
21538     }
21539   if (sub_id == ~0)
21540     {
21541       errmsg ("missing sub-interface id");
21542       return -99;
21543     }
21544
21545   M (P2P_ETHERNET_ADD, mp);
21546   mp->parent_if_index = ntohl (parent_if_index);
21547   mp->subif_id = ntohl (sub_id);
21548   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21549
21550   S (mp);
21551   W (ret);
21552   return ret;
21553 }
21554
21555 static int
21556 api_p2p_ethernet_del (vat_main_t * vam)
21557 {
21558   unformat_input_t *i = vam->input;
21559   vl_api_p2p_ethernet_del_t *mp;
21560   u32 parent_if_index = ~0;
21561   u8 remote_mac[6];
21562   u8 mac_set = 0;
21563   int ret;
21564
21565   memset (remote_mac, 0, sizeof (remote_mac));
21566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21567     {
21568       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21569         ;
21570       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21571         ;
21572       else
21573         if (unformat
21574             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21575         mac_set++;
21576       else
21577         {
21578           clib_warning ("parse error '%U'", format_unformat_error, i);
21579           return -99;
21580         }
21581     }
21582
21583   if (parent_if_index == ~0)
21584     {
21585       errmsg ("missing interface name or sw_if_index");
21586       return -99;
21587     }
21588   if (mac_set == 0)
21589     {
21590       errmsg ("missing remote mac address");
21591       return -99;
21592     }
21593
21594   M (P2P_ETHERNET_DEL, mp);
21595   mp->parent_if_index = ntohl (parent_if_index);
21596   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21597
21598   S (mp);
21599   W (ret);
21600   return ret;
21601 }
21602
21603 static int
21604 api_lldp_config (vat_main_t * vam)
21605 {
21606   unformat_input_t *i = vam->input;
21607   vl_api_lldp_config_t *mp;
21608   int tx_hold = 0;
21609   int tx_interval = 0;
21610   u8 *sys_name = NULL;
21611   int ret;
21612
21613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21614     {
21615       if (unformat (i, "system-name %s", &sys_name))
21616         ;
21617       else if (unformat (i, "tx-hold %d", &tx_hold))
21618         ;
21619       else if (unformat (i, "tx-interval %d", &tx_interval))
21620         ;
21621       else
21622         {
21623           clib_warning ("parse error '%U'", format_unformat_error, i);
21624           return -99;
21625         }
21626     }
21627
21628   vec_add1 (sys_name, 0);
21629
21630   M (LLDP_CONFIG, mp);
21631   mp->tx_hold = htonl (tx_hold);
21632   mp->tx_interval = htonl (tx_interval);
21633   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21634   vec_free (sys_name);
21635
21636   S (mp);
21637   W (ret);
21638   return ret;
21639 }
21640
21641 static int
21642 api_sw_interface_set_lldp (vat_main_t * vam)
21643 {
21644   unformat_input_t *i = vam->input;
21645   vl_api_sw_interface_set_lldp_t *mp;
21646   u32 sw_if_index = ~0;
21647   u32 enable = 1;
21648   u8 *port_desc = NULL, *mgmt_oid = NULL;
21649   ip4_address_t ip4_addr;
21650   ip6_address_t ip6_addr;
21651   int ret;
21652
21653   memset (&ip4_addr, 0, sizeof (ip4_addr));
21654   memset (&ip6_addr, 0, sizeof (ip6_addr));
21655
21656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21657     {
21658       if (unformat (i, "disable"))
21659         enable = 0;
21660       else
21661         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21662         ;
21663       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21664         ;
21665       else if (unformat (i, "port-desc %s", &port_desc))
21666         ;
21667       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21668         ;
21669       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21670         ;
21671       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21672         ;
21673       else
21674         break;
21675     }
21676
21677   if (sw_if_index == ~0)
21678     {
21679       errmsg ("missing interface name or sw_if_index");
21680       return -99;
21681     }
21682
21683   /* Construct the API message */
21684   vec_add1 (port_desc, 0);
21685   vec_add1 (mgmt_oid, 0);
21686   M (SW_INTERFACE_SET_LLDP, mp);
21687   mp->sw_if_index = ntohl (sw_if_index);
21688   mp->enable = enable;
21689   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21690   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21691   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21692   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21693   vec_free (port_desc);
21694   vec_free (mgmt_oid);
21695
21696   S (mp);
21697   W (ret);
21698   return ret;
21699 }
21700
21701 static int
21702 api_tcp_configure_src_addresses (vat_main_t * vam)
21703 {
21704   vl_api_tcp_configure_src_addresses_t *mp;
21705   unformat_input_t *i = vam->input;
21706   ip4_address_t v4first, v4last;
21707   ip6_address_t v6first, v6last;
21708   u8 range_set = 0;
21709   u32 vrf_id = 0;
21710   int ret;
21711
21712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21713     {
21714       if (unformat (i, "%U - %U",
21715                     unformat_ip4_address, &v4first,
21716                     unformat_ip4_address, &v4last))
21717         {
21718           if (range_set)
21719             {
21720               errmsg ("one range per message (range already set)");
21721               return -99;
21722             }
21723           range_set = 1;
21724         }
21725       else if (unformat (i, "%U - %U",
21726                          unformat_ip6_address, &v6first,
21727                          unformat_ip6_address, &v6last))
21728         {
21729           if (range_set)
21730             {
21731               errmsg ("one range per message (range already set)");
21732               return -99;
21733             }
21734           range_set = 2;
21735         }
21736       else if (unformat (i, "vrf %d", &vrf_id))
21737         ;
21738       else
21739         break;
21740     }
21741
21742   if (range_set == 0)
21743     {
21744       errmsg ("address range not set");
21745       return -99;
21746     }
21747
21748   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21749   mp->vrf_id = ntohl (vrf_id);
21750   /* ipv6? */
21751   if (range_set == 2)
21752     {
21753       mp->is_ipv6 = 1;
21754       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21755       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21756     }
21757   else
21758     {
21759       mp->is_ipv6 = 0;
21760       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21761       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21762     }
21763   S (mp);
21764   W (ret);
21765   return ret;
21766 }
21767
21768 static void vl_api_app_namespace_add_del_reply_t_handler
21769   (vl_api_app_namespace_add_del_reply_t * mp)
21770 {
21771   vat_main_t *vam = &vat_main;
21772   i32 retval = ntohl (mp->retval);
21773   if (vam->async_mode)
21774     {
21775       vam->async_errors += (retval < 0);
21776     }
21777   else
21778     {
21779       vam->retval = retval;
21780       if (retval == 0)
21781         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21782       vam->result_ready = 1;
21783     }
21784 }
21785
21786 static void vl_api_app_namespace_add_del_reply_t_handler_json
21787   (vl_api_app_namespace_add_del_reply_t * mp)
21788 {
21789   vat_main_t *vam = &vat_main;
21790   vat_json_node_t node;
21791
21792   vat_json_init_object (&node);
21793   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21794   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21795
21796   vat_json_print (vam->ofp, &node);
21797   vat_json_free (&node);
21798
21799   vam->retval = ntohl (mp->retval);
21800   vam->result_ready = 1;
21801 }
21802
21803 static int
21804 api_app_namespace_add_del (vat_main_t * vam)
21805 {
21806   vl_api_app_namespace_add_del_t *mp;
21807   unformat_input_t *i = vam->input;
21808   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21809   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21810   u64 secret;
21811   int ret;
21812
21813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21814     {
21815       if (unformat (i, "id %_%v%_", &ns_id))
21816         ;
21817       else if (unformat (i, "secret %lu", &secret))
21818         secret_set = 1;
21819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21820         sw_if_index_set = 1;
21821       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21822         ;
21823       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21824         ;
21825       else
21826         break;
21827     }
21828   if (!ns_id || !secret_set || !sw_if_index_set)
21829     {
21830       errmsg ("namespace id, secret and sw_if_index must be set");
21831       return -99;
21832     }
21833   if (vec_len (ns_id) > 64)
21834     {
21835       errmsg ("namespace id too long");
21836       return -99;
21837     }
21838   M (APP_NAMESPACE_ADD_DEL, mp);
21839
21840   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21841   mp->namespace_id_len = vec_len (ns_id);
21842   mp->secret = clib_host_to_net_u64 (secret);
21843   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21844   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21845   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21846   vec_free (ns_id);
21847   S (mp);
21848   W (ret);
21849   return ret;
21850 }
21851
21852 static int
21853 api_memfd_segment_create (vat_main_t * vam)
21854 {
21855 #if VPP_API_TEST_BUILTIN == 0
21856   unformat_input_t *i = vam->input;
21857   vl_api_memfd_segment_create_t *mp;
21858   u64 size = 64 << 20;
21859   int ret;
21860
21861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21862     {
21863       if (unformat (i, "size %U", unformat_memory_size, &size))
21864         ;
21865       else
21866         break;
21867     }
21868
21869   M (MEMFD_SEGMENT_CREATE, mp);
21870   mp->requested_size = size;
21871   S (mp);
21872   W (ret);
21873   return ret;
21874
21875 #else
21876   errmsg ("memfd_segment_create (builtin) not supported");
21877   return -99;
21878 #endif
21879 }
21880
21881 static int
21882 api_sock_init_shm (vat_main_t * vam)
21883 {
21884 #if VPP_API_TEST_BUILTIN == 0
21885   unformat_input_t *i = vam->input;
21886   vl_api_shm_elem_config_t *config = 0;
21887   u64 size = 64 << 20;
21888   int rv;
21889
21890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21891     {
21892       if (unformat (i, "size %U", unformat_memory_size, &size))
21893         ;
21894       else
21895         break;
21896     }
21897
21898   /* Try customized config to see if it works */
21899   vec_validate (config, 3);
21900   config[0].type = VL_API_VLIB_RING;
21901   config[0].count = 256;
21902   config[0].size = 256;
21903   config[1].type = VL_API_CLIENT_RING;
21904   config[1].count = 256;
21905   config[1].size = 1024;
21906   config[2].type = VL_API_CLIENT_RING;
21907   config[2].count = 8;
21908   config[2].size = 4096;
21909   config[3].type = VL_API_QUEUE;
21910   config[3].count = 256;
21911   config[3].size = sizeof (uword);
21912   rv = vl_socket_client_init_shm (config);
21913   if (!rv)
21914     vam->client_index_invalid = 1;
21915   return rv;
21916 #else
21917   return -99;
21918 #endif
21919 }
21920
21921 static int
21922 api_dns_enable_disable (vat_main_t * vam)
21923 {
21924   unformat_input_t *line_input = vam->input;
21925   vl_api_dns_enable_disable_t *mp;
21926   u8 enable_disable = 1;
21927   int ret;
21928
21929   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21930     {
21931       if (unformat (line_input, "disable"))
21932         enable_disable = 0;
21933       if (unformat (line_input, "enable"))
21934         enable_disable = 1;
21935       else
21936         break;
21937     }
21938
21939   /* Construct the API message */
21940   M (DNS_ENABLE_DISABLE, mp);
21941   mp->enable = enable_disable;
21942
21943   /* send it... */
21944   S (mp);
21945   /* Wait for the reply */
21946   W (ret);
21947   return ret;
21948 }
21949
21950 static int
21951 api_dns_resolve_name (vat_main_t * vam)
21952 {
21953   unformat_input_t *line_input = vam->input;
21954   vl_api_dns_resolve_name_t *mp;
21955   u8 *name = 0;
21956   int ret;
21957
21958   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21959     {
21960       if (unformat (line_input, "%s", &name))
21961         ;
21962       else
21963         break;
21964     }
21965
21966   if (vec_len (name) > 127)
21967     {
21968       errmsg ("name too long");
21969       return -99;
21970     }
21971
21972   /* Construct the API message */
21973   M (DNS_RESOLVE_NAME, mp);
21974   memcpy (mp->name, name, vec_len (name));
21975   vec_free (name);
21976
21977   /* send it... */
21978   S (mp);
21979   /* Wait for the reply */
21980   W (ret);
21981   return ret;
21982 }
21983
21984 static int
21985 api_dns_resolve_ip (vat_main_t * vam)
21986 {
21987   unformat_input_t *line_input = vam->input;
21988   vl_api_dns_resolve_ip_t *mp;
21989   int is_ip6 = -1;
21990   ip4_address_t addr4;
21991   ip6_address_t addr6;
21992   int ret;
21993
21994   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21995     {
21996       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21997         is_ip6 = 1;
21998       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21999         is_ip6 = 0;
22000       else
22001         break;
22002     }
22003
22004   if (is_ip6 == -1)
22005     {
22006       errmsg ("missing address");
22007       return -99;
22008     }
22009
22010   /* Construct the API message */
22011   M (DNS_RESOLVE_IP, mp);
22012   mp->is_ip6 = is_ip6;
22013   if (is_ip6)
22014     memcpy (mp->address, &addr6, sizeof (addr6));
22015   else
22016     memcpy (mp->address, &addr4, sizeof (addr4));
22017
22018   /* send it... */
22019   S (mp);
22020   /* Wait for the reply */
22021   W (ret);
22022   return ret;
22023 }
22024
22025 static int
22026 api_dns_name_server_add_del (vat_main_t * vam)
22027 {
22028   unformat_input_t *i = vam->input;
22029   vl_api_dns_name_server_add_del_t *mp;
22030   u8 is_add = 1;
22031   ip6_address_t ip6_server;
22032   ip4_address_t ip4_server;
22033   int ip6_set = 0;
22034   int ip4_set = 0;
22035   int ret = 0;
22036
22037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22038     {
22039       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22040         ip6_set = 1;
22041       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22042         ip4_set = 1;
22043       else if (unformat (i, "del"))
22044         is_add = 0;
22045       else
22046         {
22047           clib_warning ("parse error '%U'", format_unformat_error, i);
22048           return -99;
22049         }
22050     }
22051
22052   if (ip4_set && ip6_set)
22053     {
22054       errmsg ("Only one server address allowed per message");
22055       return -99;
22056     }
22057   if ((ip4_set + ip6_set) == 0)
22058     {
22059       errmsg ("Server address required");
22060       return -99;
22061     }
22062
22063   /* Construct the API message */
22064   M (DNS_NAME_SERVER_ADD_DEL, mp);
22065
22066   if (ip6_set)
22067     {
22068       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22069       mp->is_ip6 = 1;
22070     }
22071   else
22072     {
22073       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22074       mp->is_ip6 = 0;
22075     }
22076
22077   mp->is_add = is_add;
22078
22079   /* send it... */
22080   S (mp);
22081
22082   /* Wait for a reply, return good/bad news  */
22083   W (ret);
22084   return ret;
22085 }
22086
22087 static void
22088 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22089 {
22090   vat_main_t *vam = &vat_main;
22091
22092   if (mp->is_ip4)
22093     {
22094       print (vam->ofp,
22095              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22096              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22097              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22098              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22099              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22100              clib_net_to_host_u32 (mp->action_index), mp->tag);
22101     }
22102   else
22103     {
22104       print (vam->ofp,
22105              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22106              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22107              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22108              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22109              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22110              clib_net_to_host_u32 (mp->action_index), mp->tag);
22111     }
22112 }
22113
22114 static void
22115 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22116                                              mp)
22117 {
22118   vat_main_t *vam = &vat_main;
22119   vat_json_node_t *node = NULL;
22120   struct in6_addr ip6;
22121   struct in_addr ip4;
22122
22123   if (VAT_JSON_ARRAY != vam->json_tree.type)
22124     {
22125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22126       vat_json_init_array (&vam->json_tree);
22127     }
22128   node = vat_json_array_add (&vam->json_tree);
22129   vat_json_init_object (node);
22130
22131   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22132   vat_json_object_add_uint (node, "appns_index",
22133                             clib_net_to_host_u32 (mp->appns_index));
22134   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22135   vat_json_object_add_uint (node, "scope", mp->scope);
22136   vat_json_object_add_uint (node, "action_index",
22137                             clib_net_to_host_u32 (mp->action_index));
22138   vat_json_object_add_uint (node, "lcl_port",
22139                             clib_net_to_host_u16 (mp->lcl_port));
22140   vat_json_object_add_uint (node, "rmt_port",
22141                             clib_net_to_host_u16 (mp->rmt_port));
22142   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22143   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22144   vat_json_object_add_string_copy (node, "tag", mp->tag);
22145   if (mp->is_ip4)
22146     {
22147       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22148       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22149       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22150       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22151     }
22152   else
22153     {
22154       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22155       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22156       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22157       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22158     }
22159 }
22160
22161 static int
22162 api_session_rule_add_del (vat_main_t * vam)
22163 {
22164   vl_api_session_rule_add_del_t *mp;
22165   unformat_input_t *i = vam->input;
22166   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22167   u32 appns_index = 0, scope = 0;
22168   ip4_address_t lcl_ip4, rmt_ip4;
22169   ip6_address_t lcl_ip6, rmt_ip6;
22170   u8 is_ip4 = 1, conn_set = 0;
22171   u8 is_add = 1, *tag = 0;
22172   int ret;
22173
22174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22175     {
22176       if (unformat (i, "del"))
22177         is_add = 0;
22178       else if (unformat (i, "add"))
22179         ;
22180       else if (unformat (i, "proto tcp"))
22181         proto = 0;
22182       else if (unformat (i, "proto udp"))
22183         proto = 1;
22184       else if (unformat (i, "appns %d", &appns_index))
22185         ;
22186       else if (unformat (i, "scope %d", &scope))
22187         ;
22188       else if (unformat (i, "tag %_%v%_", &tag))
22189         ;
22190       else
22191         if (unformat
22192             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22193              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22194              &rmt_port))
22195         {
22196           is_ip4 = 1;
22197           conn_set = 1;
22198         }
22199       else
22200         if (unformat
22201             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22202              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22203              &rmt_port))
22204         {
22205           is_ip4 = 0;
22206           conn_set = 1;
22207         }
22208       else if (unformat (i, "action %d", &action))
22209         ;
22210       else
22211         break;
22212     }
22213   if (proto == ~0 || !conn_set || action == ~0)
22214     {
22215       errmsg ("transport proto, connection and action must be set");
22216       return -99;
22217     }
22218
22219   if (scope > 3)
22220     {
22221       errmsg ("scope should be 0-3");
22222       return -99;
22223     }
22224
22225   M (SESSION_RULE_ADD_DEL, mp);
22226
22227   mp->is_ip4 = is_ip4;
22228   mp->transport_proto = proto;
22229   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22230   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22231   mp->lcl_plen = lcl_plen;
22232   mp->rmt_plen = rmt_plen;
22233   mp->action_index = clib_host_to_net_u32 (action);
22234   mp->appns_index = clib_host_to_net_u32 (appns_index);
22235   mp->scope = scope;
22236   mp->is_add = is_add;
22237   if (is_ip4)
22238     {
22239       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22240       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22241     }
22242   else
22243     {
22244       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22245       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22246     }
22247   if (tag)
22248     {
22249       clib_memcpy (mp->tag, tag, vec_len (tag));
22250       vec_free (tag);
22251     }
22252
22253   S (mp);
22254   W (ret);
22255   return ret;
22256 }
22257
22258 static int
22259 api_session_rules_dump (vat_main_t * vam)
22260 {
22261   vl_api_session_rules_dump_t *mp;
22262   vl_api_control_ping_t *mp_ping;
22263   int ret;
22264
22265   if (!vam->json_output)
22266     {
22267       print (vam->ofp, "%=20s", "Session Rules");
22268     }
22269
22270   M (SESSION_RULES_DUMP, mp);
22271   /* send it... */
22272   S (mp);
22273
22274   /* Use a control ping for synchronization */
22275   MPING (CONTROL_PING, mp_ping);
22276   S (mp_ping);
22277
22278   /* Wait for a reply... */
22279   W (ret);
22280   return ret;
22281 }
22282
22283 static int
22284 api_ip_container_proxy_add_del (vat_main_t * vam)
22285 {
22286   vl_api_ip_container_proxy_add_del_t *mp;
22287   unformat_input_t *i = vam->input;
22288   u32 plen = ~0, sw_if_index = ~0;
22289   ip4_address_t ip4;
22290   ip6_address_t ip6;
22291   u8 is_ip4 = 1;
22292   u8 is_add = 1;
22293   int ret;
22294
22295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22296     {
22297       if (unformat (i, "del"))
22298         is_add = 0;
22299       else if (unformat (i, "add"))
22300         ;
22301       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22302         {
22303           is_ip4 = 1;
22304           plen = 32;
22305         }
22306       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22307         {
22308           is_ip4 = 0;
22309           plen = 128;
22310         }
22311       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22312         ;
22313       else
22314         break;
22315     }
22316   if (sw_if_index == ~0 || plen == ~0)
22317     {
22318       errmsg ("address and sw_if_index must be set");
22319       return -99;
22320     }
22321
22322   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22323
22324   mp->is_ip4 = is_ip4;
22325   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22326   mp->plen = plen;
22327   mp->is_add = is_add;
22328   if (is_ip4)
22329     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22330   else
22331     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22332
22333   S (mp);
22334   W (ret);
22335   return ret;
22336 }
22337
22338 static int
22339 q_or_quit (vat_main_t * vam)
22340 {
22341 #if VPP_API_TEST_BUILTIN == 0
22342   longjmp (vam->jump_buf, 1);
22343 #endif
22344   return 0;                     /* not so much */
22345 }
22346
22347 static int
22348 q (vat_main_t * vam)
22349 {
22350   return q_or_quit (vam);
22351 }
22352
22353 static int
22354 quit (vat_main_t * vam)
22355 {
22356   return q_or_quit (vam);
22357 }
22358
22359 static int
22360 comment (vat_main_t * vam)
22361 {
22362   return 0;
22363 }
22364
22365 static int
22366 cmd_cmp (void *a1, void *a2)
22367 {
22368   u8 **c1 = a1;
22369   u8 **c2 = a2;
22370
22371   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22372 }
22373
22374 static int
22375 help (vat_main_t * vam)
22376 {
22377   u8 **cmds = 0;
22378   u8 *name = 0;
22379   hash_pair_t *p;
22380   unformat_input_t *i = vam->input;
22381   int j;
22382
22383   if (unformat (i, "%s", &name))
22384     {
22385       uword *hs;
22386
22387       vec_add1 (name, 0);
22388
22389       hs = hash_get_mem (vam->help_by_name, name);
22390       if (hs)
22391         print (vam->ofp, "usage: %s %s", name, hs[0]);
22392       else
22393         print (vam->ofp, "No such msg / command '%s'", name);
22394       vec_free (name);
22395       return 0;
22396     }
22397
22398   print (vam->ofp, "Help is available for the following:");
22399
22400     /* *INDENT-OFF* */
22401     hash_foreach_pair (p, vam->function_by_name,
22402     ({
22403       vec_add1 (cmds, (u8 *)(p->key));
22404     }));
22405     /* *INDENT-ON* */
22406
22407   vec_sort_with_function (cmds, cmd_cmp);
22408
22409   for (j = 0; j < vec_len (cmds); j++)
22410     print (vam->ofp, "%s", cmds[j]);
22411
22412   vec_free (cmds);
22413   return 0;
22414 }
22415
22416 static int
22417 set (vat_main_t * vam)
22418 {
22419   u8 *name = 0, *value = 0;
22420   unformat_input_t *i = vam->input;
22421
22422   if (unformat (i, "%s", &name))
22423     {
22424       /* The input buffer is a vector, not a string. */
22425       value = vec_dup (i->buffer);
22426       vec_delete (value, i->index, 0);
22427       /* Almost certainly has a trailing newline */
22428       if (value[vec_len (value) - 1] == '\n')
22429         value[vec_len (value) - 1] = 0;
22430       /* Make sure it's a proper string, one way or the other */
22431       vec_add1 (value, 0);
22432       (void) clib_macro_set_value (&vam->macro_main,
22433                                    (char *) name, (char *) value);
22434     }
22435   else
22436     errmsg ("usage: set <name> <value>");
22437
22438   vec_free (name);
22439   vec_free (value);
22440   return 0;
22441 }
22442
22443 static int
22444 unset (vat_main_t * vam)
22445 {
22446   u8 *name = 0;
22447
22448   if (unformat (vam->input, "%s", &name))
22449     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22450       errmsg ("unset: %s wasn't set", name);
22451   vec_free (name);
22452   return 0;
22453 }
22454
22455 typedef struct
22456 {
22457   u8 *name;
22458   u8 *value;
22459 } macro_sort_t;
22460
22461
22462 static int
22463 macro_sort_cmp (void *a1, void *a2)
22464 {
22465   macro_sort_t *s1 = a1;
22466   macro_sort_t *s2 = a2;
22467
22468   return strcmp ((char *) (s1->name), (char *) (s2->name));
22469 }
22470
22471 static int
22472 dump_macro_table (vat_main_t * vam)
22473 {
22474   macro_sort_t *sort_me = 0, *sm;
22475   int i;
22476   hash_pair_t *p;
22477
22478     /* *INDENT-OFF* */
22479     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22480     ({
22481       vec_add2 (sort_me, sm, 1);
22482       sm->name = (u8 *)(p->key);
22483       sm->value = (u8 *) (p->value[0]);
22484     }));
22485     /* *INDENT-ON* */
22486
22487   vec_sort_with_function (sort_me, macro_sort_cmp);
22488
22489   if (vec_len (sort_me))
22490     print (vam->ofp, "%-15s%s", "Name", "Value");
22491   else
22492     print (vam->ofp, "The macro table is empty...");
22493
22494   for (i = 0; i < vec_len (sort_me); i++)
22495     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22496   return 0;
22497 }
22498
22499 static int
22500 dump_node_table (vat_main_t * vam)
22501 {
22502   int i, j;
22503   vlib_node_t *node, *next_node;
22504
22505   if (vec_len (vam->graph_nodes) == 0)
22506     {
22507       print (vam->ofp, "Node table empty, issue get_node_graph...");
22508       return 0;
22509     }
22510
22511   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22512     {
22513       node = vam->graph_nodes[i];
22514       print (vam->ofp, "[%d] %s", i, node->name);
22515       for (j = 0; j < vec_len (node->next_nodes); j++)
22516         {
22517           if (node->next_nodes[j] != ~0)
22518             {
22519               next_node = vam->graph_nodes[node->next_nodes[j]];
22520               print (vam->ofp, "  [%d] %s", j, next_node->name);
22521             }
22522         }
22523     }
22524   return 0;
22525 }
22526
22527 static int
22528 value_sort_cmp (void *a1, void *a2)
22529 {
22530   name_sort_t *n1 = a1;
22531   name_sort_t *n2 = a2;
22532
22533   if (n1->value < n2->value)
22534     return -1;
22535   if (n1->value > n2->value)
22536     return 1;
22537   return 0;
22538 }
22539
22540
22541 static int
22542 dump_msg_api_table (vat_main_t * vam)
22543 {
22544   api_main_t *am = &api_main;
22545   name_sort_t *nses = 0, *ns;
22546   hash_pair_t *hp;
22547   int i;
22548
22549   /* *INDENT-OFF* */
22550   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22551   ({
22552     vec_add2 (nses, ns, 1);
22553     ns->name = (u8 *)(hp->key);
22554     ns->value = (u32) hp->value[0];
22555   }));
22556   /* *INDENT-ON* */
22557
22558   vec_sort_with_function (nses, value_sort_cmp);
22559
22560   for (i = 0; i < vec_len (nses); i++)
22561     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22562   vec_free (nses);
22563   return 0;
22564 }
22565
22566 static int
22567 get_msg_id (vat_main_t * vam)
22568 {
22569   u8 *name_and_crc;
22570   u32 message_index;
22571
22572   if (unformat (vam->input, "%s", &name_and_crc))
22573     {
22574       message_index = vl_api_get_msg_index (name_and_crc);
22575       if (message_index == ~0)
22576         {
22577           print (vam->ofp, " '%s' not found", name_and_crc);
22578           return 0;
22579         }
22580       print (vam->ofp, " '%s' has message index %d",
22581              name_and_crc, message_index);
22582       return 0;
22583     }
22584   errmsg ("name_and_crc required...");
22585   return 0;
22586 }
22587
22588 static int
22589 search_node_table (vat_main_t * vam)
22590 {
22591   unformat_input_t *line_input = vam->input;
22592   u8 *node_to_find;
22593   int j;
22594   vlib_node_t *node, *next_node;
22595   uword *p;
22596
22597   if (vam->graph_node_index_by_name == 0)
22598     {
22599       print (vam->ofp, "Node table empty, issue get_node_graph...");
22600       return 0;
22601     }
22602
22603   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22604     {
22605       if (unformat (line_input, "%s", &node_to_find))
22606         {
22607           vec_add1 (node_to_find, 0);
22608           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22609           if (p == 0)
22610             {
22611               print (vam->ofp, "%s not found...", node_to_find);
22612               goto out;
22613             }
22614           node = vam->graph_nodes[p[0]];
22615           print (vam->ofp, "[%d] %s", p[0], node->name);
22616           for (j = 0; j < vec_len (node->next_nodes); j++)
22617             {
22618               if (node->next_nodes[j] != ~0)
22619                 {
22620                   next_node = vam->graph_nodes[node->next_nodes[j]];
22621                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22622                 }
22623             }
22624         }
22625
22626       else
22627         {
22628           clib_warning ("parse error '%U'", format_unformat_error,
22629                         line_input);
22630           return -99;
22631         }
22632
22633     out:
22634       vec_free (node_to_find);
22635
22636     }
22637
22638   return 0;
22639 }
22640
22641
22642 static int
22643 script (vat_main_t * vam)
22644 {
22645 #if (VPP_API_TEST_BUILTIN==0)
22646   u8 *s = 0;
22647   char *save_current_file;
22648   unformat_input_t save_input;
22649   jmp_buf save_jump_buf;
22650   u32 save_line_number;
22651
22652   FILE *new_fp, *save_ifp;
22653
22654   if (unformat (vam->input, "%s", &s))
22655     {
22656       new_fp = fopen ((char *) s, "r");
22657       if (new_fp == 0)
22658         {
22659           errmsg ("Couldn't open script file %s", s);
22660           vec_free (s);
22661           return -99;
22662         }
22663     }
22664   else
22665     {
22666       errmsg ("Missing script name");
22667       return -99;
22668     }
22669
22670   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22671   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22672   save_ifp = vam->ifp;
22673   save_line_number = vam->input_line_number;
22674   save_current_file = (char *) vam->current_file;
22675
22676   vam->input_line_number = 0;
22677   vam->ifp = new_fp;
22678   vam->current_file = s;
22679   do_one_file (vam);
22680
22681   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22682   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22683   vam->ifp = save_ifp;
22684   vam->input_line_number = save_line_number;
22685   vam->current_file = (u8 *) save_current_file;
22686   vec_free (s);
22687
22688   return 0;
22689 #else
22690   clib_warning ("use the exec command...");
22691   return -99;
22692 #endif
22693 }
22694
22695 static int
22696 echo (vat_main_t * vam)
22697 {
22698   print (vam->ofp, "%v", vam->input->buffer);
22699   return 0;
22700 }
22701
22702 /* List of API message constructors, CLI names map to api_xxx */
22703 #define foreach_vpe_api_msg                                             \
22704 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22705 _(sw_interface_dump,"")                                                 \
22706 _(sw_interface_set_flags,                                               \
22707   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22708 _(sw_interface_add_del_address,                                         \
22709   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22710 _(sw_interface_set_rx_mode,                                             \
22711   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22712 _(sw_interface_set_table,                                               \
22713   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22714 _(sw_interface_set_mpls_enable,                                         \
22715   "<intfc> | sw_if_index [disable | dis]")                              \
22716 _(sw_interface_set_vpath,                                               \
22717   "<intfc> | sw_if_index <id> enable | disable")                        \
22718 _(sw_interface_set_vxlan_bypass,                                        \
22719   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22720 _(sw_interface_set_geneve_bypass,                                       \
22721   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22722 _(sw_interface_set_l2_xconnect,                                         \
22723   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22724   "enable | disable")                                                   \
22725 _(sw_interface_set_l2_bridge,                                           \
22726   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22727   "[shg <split-horizon-group>] [bvi]\n"                                 \
22728   "enable | disable")                                                   \
22729 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22730 _(bridge_domain_add_del,                                                \
22731   "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") \
22732 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22733 _(l2fib_add_del,                                                        \
22734   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22735 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22736 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22737 _(l2_flags,                                                             \
22738   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22739 _(bridge_flags,                                                         \
22740   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22741 _(tap_connect,                                                          \
22742   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22743 _(tap_modify,                                                           \
22744   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22745 _(tap_delete,                                                           \
22746   "<vpp-if-name> | sw_if_index <id>")                                   \
22747 _(sw_interface_tap_dump, "")                                            \
22748 _(tap_create_v2,                                                        \
22749   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22750 _(tap_delete_v2,                                                        \
22751   "<vpp-if-name> | sw_if_index <id>")                                   \
22752 _(sw_interface_tap_v2_dump, "")                                         \
22753 _(ip_table_add_del,                                                     \
22754   "table-id <n> [ipv6]\n")                                              \
22755 _(ip_add_del_route,                                                     \
22756   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22757   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22758   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22759   "[multipath] [count <n>]")                                            \
22760 _(ip_mroute_add_del,                                                    \
22761   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22762   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22763 _(mpls_table_add_del,                                                   \
22764   "table-id <n>\n")                                                     \
22765 _(mpls_route_add_del,                                                   \
22766   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22767   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22768   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22769   "[multipath] [count <n>]")                                            \
22770 _(mpls_ip_bind_unbind,                                                  \
22771   "<label> <addr/len>")                                                 \
22772 _(mpls_tunnel_add_del,                                                  \
22773   " via <addr> [table-id <n>]\n"                                        \
22774   "sw_if_index <id>] [l2]  [del]")                                      \
22775 _(bier_table_add_del,                                                   \
22776   "<label> <sub-domain> <set> <bsl> [del]")                             \
22777 _(bier_route_add_del,                                                   \
22778   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22779   "[<intfc> | sw_if_index <id>]"                                        \
22780   "[weight <n>] [del] [multipath]")                                     \
22781 _(proxy_arp_add_del,                                                    \
22782   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22783 _(proxy_arp_intfc_enable_disable,                                       \
22784   "<intfc> | sw_if_index <id> enable | disable")                        \
22785 _(sw_interface_set_unnumbered,                                          \
22786   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22787 _(ip_neighbor_add_del,                                                  \
22788   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22789   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22790 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22791 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22792   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22793   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22794   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22795 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22796 _(reset_fib, "vrf <n> [ipv6]")                                          \
22797 _(dhcp_proxy_config,                                                    \
22798   "svr <v46-address> src <v46-address>\n"                               \
22799    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22800 _(dhcp_proxy_set_vss,                                                   \
22801   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22802 _(dhcp_proxy_dump, "ip6")                                               \
22803 _(dhcp_client_config,                                                   \
22804   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22805 _(set_ip_flow_hash,                                                     \
22806   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22807 _(sw_interface_ip6_enable_disable,                                      \
22808   "<intfc> | sw_if_index <id> enable | disable")                        \
22809 _(sw_interface_ip6_set_link_local_address,                              \
22810   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22811 _(ip6nd_proxy_add_del,                                                  \
22812   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22813 _(ip6nd_proxy_dump, "")                                                 \
22814 _(sw_interface_ip6nd_ra_prefix,                                         \
22815   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22816   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22817   "[nolink] [isno]")                                                    \
22818 _(sw_interface_ip6nd_ra_config,                                         \
22819   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22820   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22821   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22822 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22823 _(l2_patch_add_del,                                                     \
22824   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22825   "enable | disable")                                                   \
22826 _(sr_localsid_add_del,                                                  \
22827   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22828   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22829 _(classify_add_del_table,                                               \
22830   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22831   " [del] [del-chain] mask <mask-value>\n"                              \
22832   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22833   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22834 _(classify_add_del_session,                                             \
22835   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22836   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22837   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22838   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22839 _(classify_set_interface_ip_table,                                      \
22840   "<intfc> | sw_if_index <nn> table <nn>")                              \
22841 _(classify_set_interface_l2_tables,                                     \
22842   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22843   "  [other-table <nn>]")                                               \
22844 _(get_node_index, "node <node-name")                                    \
22845 _(add_node_next, "node <node-name> next <next-node-name>")              \
22846 _(l2tpv3_create_tunnel,                                                 \
22847   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22848   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22849   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22850 _(l2tpv3_set_tunnel_cookies,                                            \
22851   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22852   "[new_remote_cookie <nn>]\n")                                         \
22853 _(l2tpv3_interface_enable_disable,                                      \
22854   "<intfc> | sw_if_index <nn> enable | disable")                        \
22855 _(l2tpv3_set_lookup_key,                                                \
22856   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22857 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22858 _(vxlan_add_del_tunnel,                                                 \
22859   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22860   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22861   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22862 _(geneve_add_del_tunnel,                                                \
22863   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22864   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22865   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22866 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22867 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22868 _(gre_add_del_tunnel,                                                   \
22869   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22870 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22871 _(l2_fib_clear_table, "")                                               \
22872 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22873 _(l2_interface_vlan_tag_rewrite,                                        \
22874   "<intfc> | sw_if_index <nn> \n"                                       \
22875   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22876   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22877 _(create_vhost_user_if,                                                 \
22878         "socket <filename> [server] [renumber <dev_instance>] "         \
22879         "[mac <mac_address>]")                                          \
22880 _(modify_vhost_user_if,                                                 \
22881         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22882         "[server] [renumber <dev_instance>]")                           \
22883 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22884 _(sw_interface_vhost_user_dump, "")                                     \
22885 _(show_version, "")                                                     \
22886 _(vxlan_gpe_add_del_tunnel,                                             \
22887   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22888   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22889   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22890   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22891 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22892 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22893 _(interface_name_renumber,                                              \
22894   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22895 _(input_acl_set_interface,                                              \
22896   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22897   "  [l2-table <nn>] [del]")                                            \
22898 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22899 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22900 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22901 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22902 _(ip_dump, "ipv4 | ipv6")                                               \
22903 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22904 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22905   "  spid_id <n> ")                                                     \
22906 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22907   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22908   "  integ_alg <alg> integ_key <hex>")                                  \
22909 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22910   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22911   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22912   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22913 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22914 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22915   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22916   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22917   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22918 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22919 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22920   "  <alg> <hex>\n")                                                    \
22921 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22922 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22923 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22924   "(auth_data 0x<data> | auth_data <data>)")                            \
22925 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22926   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22927 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22928   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22929   "(local|remote)")                                                     \
22930 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22931 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22932 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22933 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22934 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22935 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22936 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22937 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22938 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22939 _(delete_loopback,"sw_if_index <nn>")                                   \
22940 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22941 _(map_add_domain,                                                       \
22942   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22943   "ip6-src <ip6addr> "                                                  \
22944   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22945 _(map_del_domain, "index <n>")                                          \
22946 _(map_add_del_rule,                                                     \
22947   "index <n> psid <n> dst <ip6addr> [del]")                             \
22948 _(map_domain_dump, "")                                                  \
22949 _(map_rule_dump, "index <map-domain>")                                  \
22950 _(want_interface_events,  "enable|disable")                             \
22951 _(want_stats,"enable|disable")                                          \
22952 _(get_first_msg_id, "client <name>")                                    \
22953 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22954 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22955   "fib-id <nn> [ip4][ip6][default]")                                    \
22956 _(get_node_graph, " ")                                                  \
22957 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22958 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22959 _(ioam_disable, "")                                                     \
22960 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22961                             " sw_if_index <sw_if_index> p <priority> "  \
22962                             "w <weight>] [del]")                        \
22963 _(one_add_del_locator, "locator-set <locator_name> "                    \
22964                         "iface <intf> | sw_if_index <sw_if_index> "     \
22965                         "p <priority> w <weight> [del]")                \
22966 _(one_add_del_local_eid,"vni <vni> eid "                                \
22967                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22968                          "locator-set <locator_name> [del]"             \
22969                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22970 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22971 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22972 _(one_enable_disable, "enable|disable")                                 \
22973 _(one_map_register_enable_disable, "enable|disable")                    \
22974 _(one_map_register_fallback_threshold, "<value>")                       \
22975 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22976 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22977                                "[seid <seid>] "                         \
22978                                "rloc <locator> p <prio> "               \
22979                                "w <weight> [rloc <loc> ... ] "          \
22980                                "action <action> [del-all]")             \
22981 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22982                           "<local-eid>")                                \
22983 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22984 _(one_use_petr, "ip-address> | disable")                                \
22985 _(one_map_request_mode, "src-dst|dst-only")                             \
22986 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22987 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22988 _(one_locator_set_dump, "[local | remote]")                             \
22989 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22990 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22991                        "[local] | [remote]")                            \
22992 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22993 _(one_ndp_bd_get, "")                                                   \
22994 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22995 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22996 _(one_l2_arp_bd_get, "")                                                \
22997 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22998 _(one_stats_enable_disable, "enable|disalbe")                           \
22999 _(show_one_stats_enable_disable, "")                                    \
23000 _(one_eid_table_vni_dump, "")                                           \
23001 _(one_eid_table_map_dump, "l2|l3")                                      \
23002 _(one_map_resolver_dump, "")                                            \
23003 _(one_map_server_dump, "")                                              \
23004 _(one_adjacencies_get, "vni <vni>")                                     \
23005 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23006 _(show_one_rloc_probe_state, "")                                        \
23007 _(show_one_map_register_state, "")                                      \
23008 _(show_one_status, "")                                                  \
23009 _(one_stats_dump, "")                                                   \
23010 _(one_stats_flush, "")                                                  \
23011 _(one_get_map_request_itr_rlocs, "")                                    \
23012 _(one_map_register_set_ttl, "<ttl>")                                    \
23013 _(one_set_transport_protocol, "udp|api")                                \
23014 _(one_get_transport_protocol, "")                                       \
23015 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23016 _(one_show_xtr_mode, "")                                                \
23017 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23018 _(one_show_pitr_mode, "")                                               \
23019 _(one_enable_disable_petr_mode, "enable|disable")                       \
23020 _(one_show_petr_mode, "")                                               \
23021 _(show_one_nsh_mapping, "")                                             \
23022 _(show_one_pitr, "")                                                    \
23023 _(show_one_use_petr, "")                                                \
23024 _(show_one_map_request_mode, "")                                        \
23025 _(show_one_map_register_ttl, "")                                        \
23026 _(show_one_map_register_fallback_threshold, "")                         \
23027 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23028                             " sw_if_index <sw_if_index> p <priority> "  \
23029                             "w <weight>] [del]")                        \
23030 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23031                         "iface <intf> | sw_if_index <sw_if_index> "     \
23032                         "p <priority> w <weight> [del]")                \
23033 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23034                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23035                          "locator-set <locator_name> [del]"             \
23036                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23037 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23038 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23039 _(lisp_enable_disable, "enable|disable")                                \
23040 _(lisp_map_register_enable_disable, "enable|disable")                   \
23041 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23042 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23043                                "[seid <seid>] "                         \
23044                                "rloc <locator> p <prio> "               \
23045                                "w <weight> [rloc <loc> ... ] "          \
23046                                "action <action> [del-all]")             \
23047 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23048                           "<local-eid>")                                \
23049 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23050 _(lisp_use_petr, "<ip-address> | disable")                              \
23051 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23052 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23053 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23054 _(lisp_locator_set_dump, "[local | remote]")                            \
23055 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23056 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23057                        "[local] | [remote]")                            \
23058 _(lisp_eid_table_vni_dump, "")                                          \
23059 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23060 _(lisp_map_resolver_dump, "")                                           \
23061 _(lisp_map_server_dump, "")                                             \
23062 _(lisp_adjacencies_get, "vni <vni>")                                    \
23063 _(gpe_fwd_entry_vnis_get, "")                                           \
23064 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23065 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23066                                 "[table <table-id>]")                   \
23067 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23068 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23069 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23070 _(gpe_get_encap_mode, "")                                               \
23071 _(lisp_gpe_add_del_iface, "up|down")                                    \
23072 _(lisp_gpe_enable_disable, "enable|disable")                            \
23073 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23074   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23075 _(show_lisp_rloc_probe_state, "")                                       \
23076 _(show_lisp_map_register_state, "")                                     \
23077 _(show_lisp_status, "")                                                 \
23078 _(lisp_get_map_request_itr_rlocs, "")                                   \
23079 _(show_lisp_pitr, "")                                                   \
23080 _(show_lisp_use_petr, "")                                               \
23081 _(show_lisp_map_request_mode, "")                                       \
23082 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23083 _(af_packet_delete, "name <host interface name>")                       \
23084 _(policer_add_del, "name <policer name> <params> [del]")                \
23085 _(policer_dump, "[name <policer name>]")                                \
23086 _(policer_classify_set_interface,                                       \
23087   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23088   "  [l2-table <nn>] [del]")                                            \
23089 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23090 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23091     "[master|slave]")                                                   \
23092 _(netmap_delete, "name <interface name>")                               \
23093 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23094 _(mpls_fib_dump, "")                                                    \
23095 _(classify_table_ids, "")                                               \
23096 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23097 _(classify_table_info, "table_id <nn>")                                 \
23098 _(classify_session_dump, "table_id <nn>")                               \
23099 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23100     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23101     "[template_interval <nn>] [udp_checksum]")                          \
23102 _(ipfix_exporter_dump, "")                                              \
23103 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23104 _(ipfix_classify_stream_dump, "")                                       \
23105 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23106 _(ipfix_classify_table_dump, "")                                        \
23107 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23108 _(sw_interface_span_dump, "[l2]")                                           \
23109 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23110 _(pg_create_interface, "if_id <nn>")                                    \
23111 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23112 _(pg_enable_disable, "[stream <id>] disable")                           \
23113 _(ip_source_and_port_range_check_add_del,                               \
23114   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23115 _(ip_source_and_port_range_check_interface_add_del,                     \
23116   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23117   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23118 _(ipsec_gre_add_del_tunnel,                                             \
23119   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23120 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23121 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23122 _(l2_interface_pbb_tag_rewrite,                                         \
23123   "<intfc> | sw_if_index <nn> \n"                                       \
23124   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23125   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23126 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23127 _(flow_classify_set_interface,                                          \
23128   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23129 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23130 _(ip_fib_dump, "")                                                      \
23131 _(ip_mfib_dump, "")                                                     \
23132 _(ip6_fib_dump, "")                                                     \
23133 _(ip6_mfib_dump, "")                                                    \
23134 _(feature_enable_disable, "arc_name <arc_name> "                        \
23135   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23136 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23137 "[disable]")                                                            \
23138 _(l2_xconnect_dump, "")                                                 \
23139 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23140 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23141 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23142 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23143 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23144 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23145 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23146   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23147 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23148 _(memfd_segment_create,"size <nnn>")                                    \
23149 _(sock_init_shm, "size <nnn>")                                          \
23150 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23151 _(dns_enable_disable, "[enable][disable]")                              \
23152 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23153 _(dns_resolve_name, "<hostname>")                                       \
23154 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23155 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23156 _(dns_resolve_name, "<hostname>")                                       \
23157 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23158   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23159 _(session_rules_dump, "")                                               \
23160 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23161
23162 /* List of command functions, CLI names map directly to functions */
23163 #define foreach_cli_function                                    \
23164 _(comment, "usage: comment <ignore-rest-of-line>")              \
23165 _(dump_interface_table, "usage: dump_interface_table")          \
23166 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23167 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23168 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23169 _(dump_stats_table, "usage: dump_stats_table")                  \
23170 _(dump_macro_table, "usage: dump_macro_table ")                 \
23171 _(dump_node_table, "usage: dump_node_table")                    \
23172 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23173 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23174 _(echo, "usage: echo <message>")                                \
23175 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23176 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23177 _(help, "usage: help")                                          \
23178 _(q, "usage: quit")                                             \
23179 _(quit, "usage: quit")                                          \
23180 _(search_node_table, "usage: search_node_table <name>...")      \
23181 _(set, "usage: set <variable-name> <value>")                    \
23182 _(script, "usage: script <file-name>")                          \
23183 _(unset, "usage: unset <variable-name>")
23184 #define _(N,n)                                  \
23185     static void vl_api_##n##_t_handler_uni      \
23186     (vl_api_##n##_t * mp)                       \
23187     {                                           \
23188         vat_main_t * vam = &vat_main;           \
23189         if (vam->json_output) {                 \
23190             vl_api_##n##_t_handler_json(mp);    \
23191         } else {                                \
23192             vl_api_##n##_t_handler(mp);         \
23193         }                                       \
23194     }
23195 foreach_vpe_api_reply_msg;
23196 #if VPP_API_TEST_BUILTIN == 0
23197 foreach_standalone_reply_msg;
23198 #endif
23199 #undef _
23200
23201 void
23202 vat_api_hookup (vat_main_t * vam)
23203 {
23204 #define _(N,n)                                                  \
23205     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23206                            vl_api_##n##_t_handler_uni,          \
23207                            vl_noop_handler,                     \
23208                            vl_api_##n##_t_endian,               \
23209                            vl_api_##n##_t_print,                \
23210                            sizeof(vl_api_##n##_t), 1);
23211   foreach_vpe_api_reply_msg;
23212 #if VPP_API_TEST_BUILTIN == 0
23213   foreach_standalone_reply_msg;
23214 #endif
23215 #undef _
23216
23217 #if (VPP_API_TEST_BUILTIN==0)
23218   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23219
23220   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23221
23222   vam->function_by_name = hash_create_string (0, sizeof (uword));
23223
23224   vam->help_by_name = hash_create_string (0, sizeof (uword));
23225 #endif
23226
23227   /* API messages we can send */
23228 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23229   foreach_vpe_api_msg;
23230 #undef _
23231
23232   /* Help strings */
23233 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23234   foreach_vpe_api_msg;
23235 #undef _
23236
23237   /* CLI functions */
23238 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23239   foreach_cli_function;
23240 #undef _
23241
23242   /* Help strings */
23243 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23244   foreach_cli_function;
23245 #undef _
23246 }
23247
23248 #if VPP_API_TEST_BUILTIN
23249 static clib_error_t *
23250 vat_api_hookup_shim (vlib_main_t * vm)
23251 {
23252   vat_api_hookup (&vat_main);
23253   return 0;
23254 }
23255
23256 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23257 #endif
23258
23259 /*
23260  * fd.io coding-style-patch-verification: ON
23261  *
23262  * Local Variables:
23263  * eval: (c-set-style "gnu")
23264  * End:
23265  */