Remove the historical memfd api segment bootstrap
[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 <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/geneve/geneve.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/in_out_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
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  action %d \n",
1353               i + 1, ntohl (mac->sw_if_index),
1354               format_ethernet_address, mac->mac_addr, mac->action);
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
1780 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1781 {
1782   vat_main_t *vam = &vat_main;
1783   i32 retval = ntohl (mp->retval);
1784
1785   if (vam->async_mode)
1786     {
1787       vam->async_errors += (retval < 0);
1788     }
1789   else
1790     {
1791       vam->retval = retval;
1792       vam->sw_if_index = ntohl (mp->sw_if_index);
1793       vam->result_ready = 1;
1794     }
1795 }
1796
1797 static void vl_api_bond_create_reply_t_handler_json
1798   (vl_api_bond_create_reply_t * mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   vat_json_node_t node;
1802
1803   vat_json_init_object (&node);
1804   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1805   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1806
1807   vat_json_print (vam->ofp, &node);
1808   vat_json_free (&node);
1809
1810   vam->retval = ntohl (mp->retval);
1811   vam->result_ready = 1;
1812 }
1813
1814 static void
1815 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   i32 retval = ntohl (mp->retval);
1819
1820   if (vam->async_mode)
1821     {
1822       vam->async_errors += (retval < 0);
1823     }
1824   else
1825     {
1826       vam->retval = retval;
1827       vam->result_ready = 1;
1828     }
1829 }
1830
1831 static void vl_api_bond_delete_reply_t_handler_json
1832   (vl_api_bond_delete_reply_t * mp)
1833 {
1834   vat_main_t *vam = &vat_main;
1835   vat_json_node_t node;
1836
1837   vat_json_init_object (&node);
1838   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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
1848 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1849 {
1850   vat_main_t *vam = &vat_main;
1851   i32 retval = ntohl (mp->retval);
1852
1853   if (vam->async_mode)
1854     {
1855       vam->async_errors += (retval < 0);
1856     }
1857   else
1858     {
1859       vam->retval = retval;
1860       vam->result_ready = 1;
1861     }
1862 }
1863
1864 static void vl_api_bond_enslave_reply_t_handler_json
1865   (vl_api_bond_enslave_reply_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   vat_json_node_t node;
1869
1870   vat_json_init_object (&node);
1871   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1872
1873   vat_json_print (vam->ofp, &node);
1874   vat_json_free (&node);
1875
1876   vam->retval = ntohl (mp->retval);
1877   vam->result_ready = 1;
1878 }
1879
1880 static void
1881 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1882                                           mp)
1883 {
1884   vat_main_t *vam = &vat_main;
1885   i32 retval = ntohl (mp->retval);
1886
1887   if (vam->async_mode)
1888     {
1889       vam->async_errors += (retval < 0);
1890     }
1891   else
1892     {
1893       vam->retval = retval;
1894       vam->result_ready = 1;
1895     }
1896 }
1897
1898 static void vl_api_bond_detach_slave_reply_t_handler_json
1899   (vl_api_bond_detach_slave_reply_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   vat_json_node_t node;
1903
1904   vat_json_init_object (&node);
1905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1906
1907   vat_json_print (vam->ofp, &node);
1908   vat_json_free (&node);
1909
1910   vam->retval = ntohl (mp->retval);
1911   vam->result_ready = 1;
1912 }
1913
1914 static void vl_api_sw_interface_bond_details_t_handler
1915   (vl_api_sw_interface_bond_details_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918
1919   print (vam->ofp,
1920          "%-16s %-12d %-12U %-13U %-14u %-14u",
1921          mp->interface_name, ntohl (mp->sw_if_index),
1922          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1923          ntohl (mp->active_slaves), ntohl (mp->slaves));
1924 }
1925
1926 static void vl_api_sw_interface_bond_details_t_handler_json
1927   (vl_api_sw_interface_bond_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930   vat_json_node_t *node = NULL;
1931
1932   if (VAT_JSON_ARRAY != vam->json_tree.type)
1933     {
1934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1935       vat_json_init_array (&vam->json_tree);
1936     }
1937   node = vat_json_array_add (&vam->json_tree);
1938
1939   vat_json_init_object (node);
1940   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1941   vat_json_object_add_string_copy (node, "interface_name",
1942                                    mp->interface_name);
1943   vat_json_object_add_uint (node, "mode", mp->mode);
1944   vat_json_object_add_uint (node, "load_balance", mp->lb);
1945   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1946   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1947 }
1948
1949 static int
1950 api_sw_interface_bond_dump (vat_main_t * vam)
1951 {
1952   vl_api_sw_interface_bond_dump_t *mp;
1953   vl_api_control_ping_t *mp_ping;
1954   int ret;
1955
1956   print (vam->ofp,
1957          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1958          "interface name", "sw_if_index", "mode", "load balance",
1959          "active slaves", "slaves");
1960
1961   /* Get list of bond interfaces */
1962   M (SW_INTERFACE_BOND_DUMP, mp);
1963   S (mp);
1964
1965   /* Use a control ping for synchronization */
1966   MPING (CONTROL_PING, mp_ping);
1967   S (mp_ping);
1968
1969   W (ret);
1970   return ret;
1971 }
1972
1973 static void vl_api_sw_interface_slave_details_t_handler
1974   (vl_api_sw_interface_slave_details_t * mp)
1975 {
1976   vat_main_t *vam = &vat_main;
1977
1978   print (vam->ofp,
1979          "%-25s %-12d %-12d %d", mp->interface_name,
1980          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1981 }
1982
1983 static void vl_api_sw_interface_slave_details_t_handler_json
1984   (vl_api_sw_interface_slave_details_t * mp)
1985 {
1986   vat_main_t *vam = &vat_main;
1987   vat_json_node_t *node = NULL;
1988
1989   if (VAT_JSON_ARRAY != vam->json_tree.type)
1990     {
1991       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1992       vat_json_init_array (&vam->json_tree);
1993     }
1994   node = vat_json_array_add (&vam->json_tree);
1995
1996   vat_json_init_object (node);
1997   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1998   vat_json_object_add_string_copy (node, "interface_name",
1999                                    mp->interface_name);
2000   vat_json_object_add_uint (node, "passive", mp->is_passive);
2001   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2002 }
2003
2004 static int
2005 api_sw_interface_slave_dump (vat_main_t * vam)
2006 {
2007   unformat_input_t *i = vam->input;
2008   vl_api_sw_interface_slave_dump_t *mp;
2009   vl_api_control_ping_t *mp_ping;
2010   u32 sw_if_index = ~0;
2011   u8 sw_if_index_set = 0;
2012   int ret;
2013
2014   /* Parse args required to build the message */
2015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2016     {
2017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2018         sw_if_index_set = 1;
2019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2020         sw_if_index_set = 1;
2021       else
2022         break;
2023     }
2024
2025   if (sw_if_index_set == 0)
2026     {
2027       errmsg ("missing vpp interface name. ");
2028       return -99;
2029     }
2030
2031   print (vam->ofp,
2032          "\n%-25s %-12s %-12s %s",
2033          "slave interface name", "sw_if_index", "passive", "long_timeout");
2034
2035   /* Get list of bond interfaces */
2036   M (SW_INTERFACE_SLAVE_DUMP, mp);
2037   mp->sw_if_index = ntohl (sw_if_index);
2038   S (mp);
2039
2040   /* Use a control ping for synchronization */
2041   MPING (CONTROL_PING, mp_ping);
2042   S (mp_ping);
2043
2044   W (ret);
2045   return ret;
2046 }
2047
2048 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2049   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2050 {
2051   vat_main_t *vam = &vat_main;
2052   i32 retval = ntohl (mp->retval);
2053   if (vam->async_mode)
2054     {
2055       vam->async_errors += (retval < 0);
2056     }
2057   else
2058     {
2059       vam->retval = retval;
2060       vam->result_ready = 1;
2061     }
2062 }
2063
2064 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2065   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2066 {
2067   vat_main_t *vam = &vat_main;
2068   vat_json_node_t node;
2069
2070   vat_json_init_object (&node);
2071   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2072   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2073                             ntohl (mp->sw_if_index));
2074
2075   vat_json_print (vam->ofp, &node);
2076   vat_json_free (&node);
2077
2078   vam->retval = ntohl (mp->retval);
2079   vam->result_ready = 1;
2080 }
2081
2082 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2083   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2084 {
2085   vat_main_t *vam = &vat_main;
2086   i32 retval = ntohl (mp->retval);
2087   if (vam->async_mode)
2088     {
2089       vam->async_errors += (retval < 0);
2090     }
2091   else
2092     {
2093       vam->retval = retval;
2094       vam->sw_if_index = ntohl (mp->sw_if_index);
2095       vam->result_ready = 1;
2096     }
2097 }
2098
2099 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2100   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2101 {
2102   vat_main_t *vam = &vat_main;
2103   vat_json_node_t node;
2104
2105   vat_json_init_object (&node);
2106   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2107   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2108
2109   vat_json_print (vam->ofp, &node);
2110   vat_json_free (&node);
2111
2112   vam->retval = ntohl (mp->retval);
2113   vam->result_ready = 1;
2114 }
2115
2116 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2117   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2118 {
2119   vat_main_t *vam = &vat_main;
2120   i32 retval = ntohl (mp->retval);
2121   if (vam->async_mode)
2122     {
2123       vam->async_errors += (retval < 0);
2124     }
2125   else
2126     {
2127       vam->retval = retval;
2128       vam->result_ready = 1;
2129     }
2130 }
2131
2132 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2133   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2134 {
2135   vat_main_t *vam = &vat_main;
2136   vat_json_node_t node;
2137
2138   vat_json_init_object (&node);
2139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2140   vat_json_object_add_uint (&node, "fwd_entry_index",
2141                             clib_net_to_host_u32 (mp->fwd_entry_index));
2142
2143   vat_json_print (vam->ofp, &node);
2144   vat_json_free (&node);
2145
2146   vam->retval = ntohl (mp->retval);
2147   vam->result_ready = 1;
2148 }
2149
2150 u8 *
2151 format_lisp_transport_protocol (u8 * s, va_list * args)
2152 {
2153   u32 proto = va_arg (*args, u32);
2154
2155   switch (proto)
2156     {
2157     case 1:
2158       return format (s, "udp");
2159     case 2:
2160       return format (s, "api");
2161     default:
2162       return 0;
2163     }
2164   return 0;
2165 }
2166
2167 static void vl_api_one_get_transport_protocol_reply_t_handler
2168   (vl_api_one_get_transport_protocol_reply_t * mp)
2169 {
2170   vat_main_t *vam = &vat_main;
2171   i32 retval = ntohl (mp->retval);
2172   if (vam->async_mode)
2173     {
2174       vam->async_errors += (retval < 0);
2175     }
2176   else
2177     {
2178       u32 proto = mp->protocol;
2179       print (vam->ofp, "Transport protocol: %U",
2180              format_lisp_transport_protocol, proto);
2181       vam->retval = retval;
2182       vam->result_ready = 1;
2183     }
2184 }
2185
2186 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2187   (vl_api_one_get_transport_protocol_reply_t * mp)
2188 {
2189   vat_main_t *vam = &vat_main;
2190   vat_json_node_t node;
2191   u8 *s;
2192
2193   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2194   vec_add1 (s, 0);
2195
2196   vat_json_init_object (&node);
2197   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2198   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2199
2200   vec_free (s);
2201   vat_json_print (vam->ofp, &node);
2202   vat_json_free (&node);
2203
2204   vam->retval = ntohl (mp->retval);
2205   vam->result_ready = 1;
2206 }
2207
2208 static void vl_api_one_add_del_locator_set_reply_t_handler
2209   (vl_api_one_add_del_locator_set_reply_t * mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   i32 retval = ntohl (mp->retval);
2213   if (vam->async_mode)
2214     {
2215       vam->async_errors += (retval < 0);
2216     }
2217   else
2218     {
2219       vam->retval = retval;
2220       vam->result_ready = 1;
2221     }
2222 }
2223
2224 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2225   (vl_api_one_add_del_locator_set_reply_t * mp)
2226 {
2227   vat_main_t *vam = &vat_main;
2228   vat_json_node_t node;
2229
2230   vat_json_init_object (&node);
2231   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2232   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2233
2234   vat_json_print (vam->ofp, &node);
2235   vat_json_free (&node);
2236
2237   vam->retval = ntohl (mp->retval);
2238   vam->result_ready = 1;
2239 }
2240
2241 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2242   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2243 {
2244   vat_main_t *vam = &vat_main;
2245   i32 retval = ntohl (mp->retval);
2246   if (vam->async_mode)
2247     {
2248       vam->async_errors += (retval < 0);
2249     }
2250   else
2251     {
2252       vam->retval = retval;
2253       vam->sw_if_index = ntohl (mp->sw_if_index);
2254       vam->result_ready = 1;
2255     }
2256   vam->regenerate_interface_table = 1;
2257 }
2258
2259 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2260   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2261 {
2262   vat_main_t *vam = &vat_main;
2263   vat_json_node_t node;
2264
2265   vat_json_init_object (&node);
2266   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2267   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2268
2269   vat_json_print (vam->ofp, &node);
2270   vat_json_free (&node);
2271
2272   vam->retval = ntohl (mp->retval);
2273   vam->result_ready = 1;
2274 }
2275
2276 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2277   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   i32 retval = ntohl (mp->retval);
2281   if (vam->async_mode)
2282     {
2283       vam->async_errors += (retval < 0);
2284     }
2285   else
2286     {
2287       vam->retval = retval;
2288       vam->sw_if_index = ntohl (mp->sw_if_index);
2289       vam->result_ready = 1;
2290     }
2291 }
2292
2293 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2294   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2295 {
2296   vat_main_t *vam = &vat_main;
2297   vat_json_node_t node;
2298
2299   vat_json_init_object (&node);
2300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2301   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2302
2303   vat_json_print (vam->ofp, &node);
2304   vat_json_free (&node);
2305
2306   vam->retval = ntohl (mp->retval);
2307   vam->result_ready = 1;
2308 }
2309
2310 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2311   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   i32 retval = ntohl (mp->retval);
2315   if (vam->async_mode)
2316     {
2317       vam->async_errors += (retval < 0);
2318     }
2319   else
2320     {
2321       vam->retval = retval;
2322       vam->sw_if_index = ntohl (mp->sw_if_index);
2323       vam->result_ready = 1;
2324     }
2325   vam->regenerate_interface_table = 1;
2326 }
2327
2328 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2329   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2330 {
2331   vat_main_t *vam = &vat_main;
2332   vat_json_node_t node;
2333
2334   vat_json_init_object (&node);
2335   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2336   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2337
2338   vat_json_print (vam->ofp, &node);
2339   vat_json_free (&node);
2340
2341   vam->retval = ntohl (mp->retval);
2342   vam->result_ready = 1;
2343 }
2344
2345 static void vl_api_gre_add_del_tunnel_reply_t_handler
2346   (vl_api_gre_add_del_tunnel_reply_t * mp)
2347 {
2348   vat_main_t *vam = &vat_main;
2349   i32 retval = ntohl (mp->retval);
2350   if (vam->async_mode)
2351     {
2352       vam->async_errors += (retval < 0);
2353     }
2354   else
2355     {
2356       vam->retval = retval;
2357       vam->sw_if_index = ntohl (mp->sw_if_index);
2358       vam->result_ready = 1;
2359     }
2360 }
2361
2362 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2363   (vl_api_gre_add_del_tunnel_reply_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   vat_json_node_t node;
2367
2368   vat_json_init_object (&node);
2369   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2370   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2371
2372   vat_json_print (vam->ofp, &node);
2373   vat_json_free (&node);
2374
2375   vam->retval = ntohl (mp->retval);
2376   vam->result_ready = 1;
2377 }
2378
2379 static void vl_api_create_vhost_user_if_reply_t_handler
2380   (vl_api_create_vhost_user_if_reply_t * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   i32 retval = ntohl (mp->retval);
2384   if (vam->async_mode)
2385     {
2386       vam->async_errors += (retval < 0);
2387     }
2388   else
2389     {
2390       vam->retval = retval;
2391       vam->sw_if_index = ntohl (mp->sw_if_index);
2392       vam->result_ready = 1;
2393     }
2394   vam->regenerate_interface_table = 1;
2395 }
2396
2397 static void vl_api_create_vhost_user_if_reply_t_handler_json
2398   (vl_api_create_vhost_user_if_reply_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   vat_json_node_t node;
2402
2403   vat_json_init_object (&node);
2404   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2405   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2406
2407   vat_json_print (vam->ofp, &node);
2408   vat_json_free (&node);
2409
2410   vam->retval = ntohl (mp->retval);
2411   vam->result_ready = 1;
2412 }
2413
2414 static void vl_api_dns_resolve_name_reply_t_handler
2415   (vl_api_dns_resolve_name_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   i32 retval = ntohl (mp->retval);
2419   if (vam->async_mode)
2420     {
2421       vam->async_errors += (retval < 0);
2422     }
2423   else
2424     {
2425       vam->retval = retval;
2426       vam->result_ready = 1;
2427
2428       if (retval == 0)
2429         {
2430           if (mp->ip4_set)
2431             clib_warning ("ip4 address %U", format_ip4_address,
2432                           (ip4_address_t *) mp->ip4_address);
2433           if (mp->ip6_set)
2434             clib_warning ("ip6 address %U", format_ip6_address,
2435                           (ip6_address_t *) mp->ip6_address);
2436         }
2437       else
2438         clib_warning ("retval %d", retval);
2439     }
2440 }
2441
2442 static void vl_api_dns_resolve_name_reply_t_handler_json
2443   (vl_api_dns_resolve_name_reply_t * mp)
2444 {
2445   clib_warning ("not implemented");
2446 }
2447
2448 static void vl_api_dns_resolve_ip_reply_t_handler
2449   (vl_api_dns_resolve_ip_reply_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452   i32 retval = ntohl (mp->retval);
2453   if (vam->async_mode)
2454     {
2455       vam->async_errors += (retval < 0);
2456     }
2457   else
2458     {
2459       vam->retval = retval;
2460       vam->result_ready = 1;
2461
2462       if (retval == 0)
2463         {
2464           clib_warning ("canonical name %s", mp->name);
2465         }
2466       else
2467         clib_warning ("retval %d", retval);
2468     }
2469 }
2470
2471 static void vl_api_dns_resolve_ip_reply_t_handler_json
2472   (vl_api_dns_resolve_ip_reply_t * mp)
2473 {
2474   clib_warning ("not implemented");
2475 }
2476
2477
2478 static void vl_api_ip_address_details_t_handler
2479   (vl_api_ip_address_details_t * mp)
2480 {
2481   vat_main_t *vam = &vat_main;
2482   static ip_address_details_t empty_ip_address_details = { {0} };
2483   ip_address_details_t *address = NULL;
2484   ip_details_t *current_ip_details = NULL;
2485   ip_details_t *details = NULL;
2486
2487   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2488
2489   if (!details || vam->current_sw_if_index >= vec_len (details)
2490       || !details[vam->current_sw_if_index].present)
2491     {
2492       errmsg ("ip address details arrived but not stored");
2493       errmsg ("ip_dump should be called first");
2494       return;
2495     }
2496
2497   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2498
2499 #define addresses (current_ip_details->addr)
2500
2501   vec_validate_init_empty (addresses, vec_len (addresses),
2502                            empty_ip_address_details);
2503
2504   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2505
2506   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2507   address->prefix_length = mp->prefix_length;
2508 #undef addresses
2509 }
2510
2511 static void vl_api_ip_address_details_t_handler_json
2512   (vl_api_ip_address_details_t * mp)
2513 {
2514   vat_main_t *vam = &vat_main;
2515   vat_json_node_t *node = NULL;
2516   struct in6_addr ip6;
2517   struct in_addr ip4;
2518
2519   if (VAT_JSON_ARRAY != vam->json_tree.type)
2520     {
2521       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2522       vat_json_init_array (&vam->json_tree);
2523     }
2524   node = vat_json_array_add (&vam->json_tree);
2525
2526   vat_json_init_object (node);
2527   if (vam->is_ipv6)
2528     {
2529       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2530       vat_json_object_add_ip6 (node, "ip", ip6);
2531     }
2532   else
2533     {
2534       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2535       vat_json_object_add_ip4 (node, "ip", ip4);
2536     }
2537   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2538 }
2539
2540 static void
2541 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   static ip_details_t empty_ip_details = { 0 };
2545   ip_details_t *ip = NULL;
2546   u32 sw_if_index = ~0;
2547
2548   sw_if_index = ntohl (mp->sw_if_index);
2549
2550   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2551                            sw_if_index, empty_ip_details);
2552
2553   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2554                          sw_if_index);
2555
2556   ip->present = 1;
2557 }
2558
2559 static void
2560 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2561 {
2562   vat_main_t *vam = &vat_main;
2563
2564   if (VAT_JSON_ARRAY != vam->json_tree.type)
2565     {
2566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2567       vat_json_init_array (&vam->json_tree);
2568     }
2569   vat_json_array_add_uint (&vam->json_tree,
2570                            clib_net_to_host_u32 (mp->sw_if_index));
2571 }
2572
2573 static void vl_api_map_domain_details_t_handler_json
2574   (vl_api_map_domain_details_t * mp)
2575 {
2576   vat_json_node_t *node = NULL;
2577   vat_main_t *vam = &vat_main;
2578   struct in6_addr ip6;
2579   struct in_addr ip4;
2580
2581   if (VAT_JSON_ARRAY != vam->json_tree.type)
2582     {
2583       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2584       vat_json_init_array (&vam->json_tree);
2585     }
2586
2587   node = vat_json_array_add (&vam->json_tree);
2588   vat_json_init_object (node);
2589
2590   vat_json_object_add_uint (node, "domain_index",
2591                             clib_net_to_host_u32 (mp->domain_index));
2592   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2593   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2594   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2595   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2596   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2597   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2598   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2599   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2600   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2601   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2602   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2603   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2604   vat_json_object_add_uint (node, "flags", mp->flags);
2605   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2606   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2607 }
2608
2609 static void vl_api_map_domain_details_t_handler
2610   (vl_api_map_domain_details_t * mp)
2611 {
2612   vat_main_t *vam = &vat_main;
2613
2614   if (mp->is_translation)
2615     {
2616       print (vam->ofp,
2617              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2618              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2619              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2620              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2621              clib_net_to_host_u32 (mp->domain_index));
2622     }
2623   else
2624     {
2625       print (vam->ofp,
2626              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2627              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2628              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2629              format_ip6_address, mp->ip6_src,
2630              clib_net_to_host_u32 (mp->domain_index));
2631     }
2632   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2633          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2634          mp->is_translation ? "map-t" : "");
2635 }
2636
2637 static void vl_api_map_rule_details_t_handler_json
2638   (vl_api_map_rule_details_t * mp)
2639 {
2640   struct in6_addr ip6;
2641   vat_json_node_t *node = NULL;
2642   vat_main_t *vam = &vat_main;
2643
2644   if (VAT_JSON_ARRAY != vam->json_tree.type)
2645     {
2646       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2647       vat_json_init_array (&vam->json_tree);
2648     }
2649
2650   node = vat_json_array_add (&vam->json_tree);
2651   vat_json_init_object (node);
2652
2653   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2654   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2655   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2656 }
2657
2658 static void
2659 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2663          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2664 }
2665
2666 static void
2667 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2668 {
2669   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2670           "router_addr %U host_mac %U",
2671           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2672           format_ip4_address, &mp->host_address,
2673           format_ip4_address, &mp->router_address,
2674           format_ethernet_address, mp->host_mac);
2675 }
2676
2677 static void vl_api_dhcp_compl_event_t_handler_json
2678   (vl_api_dhcp_compl_event_t * mp)
2679 {
2680   /* JSON output not supported */
2681 }
2682
2683 static void
2684 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2685                               u32 counter)
2686 {
2687   vat_main_t *vam = &vat_main;
2688   static u64 default_counter = 0;
2689
2690   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2691                            NULL);
2692   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2693                            sw_if_index, default_counter);
2694   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2695 }
2696
2697 static void
2698 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2699                                 interface_counter_t counter)
2700 {
2701   vat_main_t *vam = &vat_main;
2702   static interface_counter_t default_counter = { 0, };
2703
2704   vec_validate_init_empty (vam->combined_interface_counters,
2705                            vnet_counter_type, NULL);
2706   vec_validate_init_empty (vam->combined_interface_counters
2707                            [vnet_counter_type], sw_if_index, default_counter);
2708   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2709 }
2710
2711 static void vl_api_vnet_interface_simple_counters_t_handler
2712   (vl_api_vnet_interface_simple_counters_t * mp)
2713 {
2714   /* not supported */
2715 }
2716
2717 static void vl_api_vnet_interface_combined_counters_t_handler
2718   (vl_api_vnet_interface_combined_counters_t * mp)
2719 {
2720   /* not supported */
2721 }
2722
2723 static void vl_api_vnet_interface_simple_counters_t_handler_json
2724   (vl_api_vnet_interface_simple_counters_t * mp)
2725 {
2726   u64 *v_packets;
2727   u64 packets;
2728   u32 count;
2729   u32 first_sw_if_index;
2730   int i;
2731
2732   count = ntohl (mp->count);
2733   first_sw_if_index = ntohl (mp->first_sw_if_index);
2734
2735   v_packets = (u64 *) & mp->data;
2736   for (i = 0; i < count; i++)
2737     {
2738       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2739       set_simple_interface_counter (mp->vnet_counter_type,
2740                                     first_sw_if_index + i, packets);
2741       v_packets++;
2742     }
2743 }
2744
2745 static void vl_api_vnet_interface_combined_counters_t_handler_json
2746   (vl_api_vnet_interface_combined_counters_t * mp)
2747 {
2748   interface_counter_t counter;
2749   vlib_counter_t *v;
2750   u32 first_sw_if_index;
2751   int i;
2752   u32 count;
2753
2754   count = ntohl (mp->count);
2755   first_sw_if_index = ntohl (mp->first_sw_if_index);
2756
2757   v = (vlib_counter_t *) & mp->data;
2758   for (i = 0; i < count; i++)
2759     {
2760       counter.packets =
2761         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2762       counter.bytes =
2763         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2764       set_combined_interface_counter (mp->vnet_counter_type,
2765                                       first_sw_if_index + i, counter);
2766       v++;
2767     }
2768 }
2769
2770 static u32
2771 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   u32 i;
2775
2776   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2777     {
2778       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2779         {
2780           return i;
2781         }
2782     }
2783   return ~0;
2784 }
2785
2786 static u32
2787 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   u32 i;
2791
2792   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2793     {
2794       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2795         {
2796           return i;
2797         }
2798     }
2799   return ~0;
2800 }
2801
2802 static void vl_api_vnet_ip4_fib_counters_t_handler
2803   (vl_api_vnet_ip4_fib_counters_t * mp)
2804 {
2805   /* not supported */
2806 }
2807
2808 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2809   (vl_api_vnet_ip4_fib_counters_t * mp)
2810 {
2811   vat_main_t *vam = &vat_main;
2812   vl_api_ip4_fib_counter_t *v;
2813   ip4_fib_counter_t *counter;
2814   struct in_addr ip4;
2815   u32 vrf_id;
2816   u32 vrf_index;
2817   u32 count;
2818   int i;
2819
2820   vrf_id = ntohl (mp->vrf_id);
2821   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2822   if (~0 == vrf_index)
2823     {
2824       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2825       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2826       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2827       vec_validate (vam->ip4_fib_counters, vrf_index);
2828       vam->ip4_fib_counters[vrf_index] = NULL;
2829     }
2830
2831   vec_free (vam->ip4_fib_counters[vrf_index]);
2832   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2833   count = ntohl (mp->count);
2834   for (i = 0; i < count; i++)
2835     {
2836       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2837       counter = &vam->ip4_fib_counters[vrf_index][i];
2838       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2839       counter->address = ip4;
2840       counter->address_length = v->address_length;
2841       counter->packets = clib_net_to_host_u64 (v->packets);
2842       counter->bytes = clib_net_to_host_u64 (v->bytes);
2843       v++;
2844     }
2845 }
2846
2847 static void vl_api_vnet_ip4_nbr_counters_t_handler
2848   (vl_api_vnet_ip4_nbr_counters_t * mp)
2849 {
2850   /* not supported */
2851 }
2852
2853 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2854   (vl_api_vnet_ip4_nbr_counters_t * mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   vl_api_ip4_nbr_counter_t *v;
2858   ip4_nbr_counter_t *counter;
2859   u32 sw_if_index;
2860   u32 count;
2861   int i;
2862
2863   sw_if_index = ntohl (mp->sw_if_index);
2864   count = ntohl (mp->count);
2865   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2866
2867   if (mp->begin)
2868     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2869
2870   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2871   for (i = 0; i < count; i++)
2872     {
2873       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2874       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2875       counter->address.s_addr = v->address;
2876       counter->packets = clib_net_to_host_u64 (v->packets);
2877       counter->bytes = clib_net_to_host_u64 (v->bytes);
2878       counter->linkt = v->link_type;
2879       v++;
2880     }
2881 }
2882
2883 static void vl_api_vnet_ip6_fib_counters_t_handler
2884   (vl_api_vnet_ip6_fib_counters_t * mp)
2885 {
2886   /* not supported */
2887 }
2888
2889 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2890   (vl_api_vnet_ip6_fib_counters_t * mp)
2891 {
2892   vat_main_t *vam = &vat_main;
2893   vl_api_ip6_fib_counter_t *v;
2894   ip6_fib_counter_t *counter;
2895   struct in6_addr ip6;
2896   u32 vrf_id;
2897   u32 vrf_index;
2898   u32 count;
2899   int i;
2900
2901   vrf_id = ntohl (mp->vrf_id);
2902   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2903   if (~0 == vrf_index)
2904     {
2905       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2906       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2907       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2908       vec_validate (vam->ip6_fib_counters, vrf_index);
2909       vam->ip6_fib_counters[vrf_index] = NULL;
2910     }
2911
2912   vec_free (vam->ip6_fib_counters[vrf_index]);
2913   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2914   count = ntohl (mp->count);
2915   for (i = 0; i < count; i++)
2916     {
2917       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2918       counter = &vam->ip6_fib_counters[vrf_index][i];
2919       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2920       counter->address = ip6;
2921       counter->address_length = v->address_length;
2922       counter->packets = clib_net_to_host_u64 (v->packets);
2923       counter->bytes = clib_net_to_host_u64 (v->bytes);
2924       v++;
2925     }
2926 }
2927
2928 static void vl_api_vnet_ip6_nbr_counters_t_handler
2929   (vl_api_vnet_ip6_nbr_counters_t * mp)
2930 {
2931   /* not supported */
2932 }
2933
2934 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2935   (vl_api_vnet_ip6_nbr_counters_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vl_api_ip6_nbr_counter_t *v;
2939   ip6_nbr_counter_t *counter;
2940   struct in6_addr ip6;
2941   u32 sw_if_index;
2942   u32 count;
2943   int i;
2944
2945   sw_if_index = ntohl (mp->sw_if_index);
2946   count = ntohl (mp->count);
2947   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2948
2949   if (mp->begin)
2950     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2951
2952   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2953   for (i = 0; i < count; i++)
2954     {
2955       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2956       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2957       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2958       counter->address = ip6;
2959       counter->packets = clib_net_to_host_u64 (v->packets);
2960       counter->bytes = clib_net_to_host_u64 (v->bytes);
2961       v++;
2962     }
2963 }
2964
2965 static void vl_api_get_first_msg_id_reply_t_handler
2966   (vl_api_get_first_msg_id_reply_t * mp)
2967 {
2968   vat_main_t *vam = &vat_main;
2969   i32 retval = ntohl (mp->retval);
2970
2971   if (vam->async_mode)
2972     {
2973       vam->async_errors += (retval < 0);
2974     }
2975   else
2976     {
2977       vam->retval = retval;
2978       vam->result_ready = 1;
2979     }
2980   if (retval >= 0)
2981     {
2982       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2983     }
2984 }
2985
2986 static void vl_api_get_first_msg_id_reply_t_handler_json
2987   (vl_api_get_first_msg_id_reply_t * mp)
2988 {
2989   vat_main_t *vam = &vat_main;
2990   vat_json_node_t node;
2991
2992   vat_json_init_object (&node);
2993   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2994   vat_json_object_add_uint (&node, "first_msg_id",
2995                             (uint) ntohs (mp->first_msg_id));
2996
2997   vat_json_print (vam->ofp, &node);
2998   vat_json_free (&node);
2999
3000   vam->retval = ntohl (mp->retval);
3001   vam->result_ready = 1;
3002 }
3003
3004 static void vl_api_get_node_graph_reply_t_handler
3005   (vl_api_get_node_graph_reply_t * mp)
3006 {
3007   vat_main_t *vam = &vat_main;
3008   api_main_t *am = &api_main;
3009   i32 retval = ntohl (mp->retval);
3010   u8 *pvt_copy, *reply;
3011   void *oldheap;
3012   vlib_node_t *node;
3013   int i;
3014
3015   if (vam->async_mode)
3016     {
3017       vam->async_errors += (retval < 0);
3018     }
3019   else
3020     {
3021       vam->retval = retval;
3022       vam->result_ready = 1;
3023     }
3024
3025   /* "Should never happen..." */
3026   if (retval != 0)
3027     return;
3028
3029   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3030   pvt_copy = vec_dup (reply);
3031
3032   /* Toss the shared-memory original... */
3033   pthread_mutex_lock (&am->vlib_rp->mutex);
3034   oldheap = svm_push_data_heap (am->vlib_rp);
3035
3036   vec_free (reply);
3037
3038   svm_pop_heap (oldheap);
3039   pthread_mutex_unlock (&am->vlib_rp->mutex);
3040
3041   if (vam->graph_nodes)
3042     {
3043       hash_free (vam->graph_node_index_by_name);
3044
3045       for (i = 0; i < vec_len (vam->graph_nodes); i++)
3046         {
3047           node = vam->graph_nodes[i];
3048           vec_free (node->name);
3049           vec_free (node->next_nodes);
3050           vec_free (node);
3051         }
3052       vec_free (vam->graph_nodes);
3053     }
3054
3055   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3056   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3057   vec_free (pvt_copy);
3058
3059   for (i = 0; i < vec_len (vam->graph_nodes); i++)
3060     {
3061       node = vam->graph_nodes[i];
3062       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3063     }
3064 }
3065
3066 static void vl_api_get_node_graph_reply_t_handler_json
3067   (vl_api_get_node_graph_reply_t * mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   api_main_t *am = &api_main;
3071   void *oldheap;
3072   vat_json_node_t node;
3073   u8 *reply;
3074
3075   /* $$$$ make this real? */
3076   vat_json_init_object (&node);
3077   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3078   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3079
3080   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3081
3082   /* Toss the shared-memory original... */
3083   pthread_mutex_lock (&am->vlib_rp->mutex);
3084   oldheap = svm_push_data_heap (am->vlib_rp);
3085
3086   vec_free (reply);
3087
3088   svm_pop_heap (oldheap);
3089   pthread_mutex_unlock (&am->vlib_rp->mutex);
3090
3091   vat_json_print (vam->ofp, &node);
3092   vat_json_free (&node);
3093
3094   vam->retval = ntohl (mp->retval);
3095   vam->result_ready = 1;
3096 }
3097
3098 static void
3099 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3100 {
3101   vat_main_t *vam = &vat_main;
3102   u8 *s = 0;
3103
3104   if (mp->local)
3105     {
3106       s = format (s, "%=16d%=16d%=16d",
3107                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3108     }
3109   else
3110     {
3111       s = format (s, "%=16U%=16d%=16d",
3112                   mp->is_ipv6 ? format_ip6_address :
3113                   format_ip4_address,
3114                   mp->ip_address, mp->priority, mp->weight);
3115     }
3116
3117   print (vam->ofp, "%v", s);
3118   vec_free (s);
3119 }
3120
3121 static void
3122 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3123 {
3124   vat_main_t *vam = &vat_main;
3125   vat_json_node_t *node = NULL;
3126   struct in6_addr ip6;
3127   struct in_addr ip4;
3128
3129   if (VAT_JSON_ARRAY != vam->json_tree.type)
3130     {
3131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3132       vat_json_init_array (&vam->json_tree);
3133     }
3134   node = vat_json_array_add (&vam->json_tree);
3135   vat_json_init_object (node);
3136
3137   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3138   vat_json_object_add_uint (node, "priority", mp->priority);
3139   vat_json_object_add_uint (node, "weight", mp->weight);
3140
3141   if (mp->local)
3142     vat_json_object_add_uint (node, "sw_if_index",
3143                               clib_net_to_host_u32 (mp->sw_if_index));
3144   else
3145     {
3146       if (mp->is_ipv6)
3147         {
3148           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3149           vat_json_object_add_ip6 (node, "address", ip6);
3150         }
3151       else
3152         {
3153           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3154           vat_json_object_add_ip4 (node, "address", ip4);
3155         }
3156     }
3157 }
3158
3159 static void
3160 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3161                                           mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164   u8 *ls_name = 0;
3165
3166   ls_name = format (0, "%s", mp->ls_name);
3167
3168   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3169          ls_name);
3170   vec_free (ls_name);
3171 }
3172
3173 static void
3174   vl_api_one_locator_set_details_t_handler_json
3175   (vl_api_one_locator_set_details_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t *node = 0;
3179   u8 *ls_name = 0;
3180
3181   ls_name = format (0, "%s", mp->ls_name);
3182   vec_add1 (ls_name, 0);
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190
3191   vat_json_init_object (node);
3192   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3193   vat_json_object_add_uint (node, "ls_index",
3194                             clib_net_to_host_u32 (mp->ls_index));
3195   vec_free (ls_name);
3196 }
3197
3198 typedef struct
3199 {
3200   u32 spi;
3201   u8 si;
3202 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3203
3204 uword
3205 unformat_nsh_address (unformat_input_t * input, va_list * args)
3206 {
3207   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3208   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3209 }
3210
3211 u8 *
3212 format_nsh_address_vat (u8 * s, va_list * args)
3213 {
3214   nsh_t *a = va_arg (*args, nsh_t *);
3215   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3216 }
3217
3218 static u8 *
3219 format_lisp_flat_eid (u8 * s, va_list * args)
3220 {
3221   u32 type = va_arg (*args, u32);
3222   u8 *eid = va_arg (*args, u8 *);
3223   u32 eid_len = va_arg (*args, u32);
3224
3225   switch (type)
3226     {
3227     case 0:
3228       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3229     case 1:
3230       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3231     case 2:
3232       return format (s, "%U", format_ethernet_address, eid);
3233     case 3:
3234       return format (s, "%U", format_nsh_address_vat, eid);
3235     }
3236   return 0;
3237 }
3238
3239 static u8 *
3240 format_lisp_eid_vat (u8 * s, va_list * args)
3241 {
3242   u32 type = va_arg (*args, u32);
3243   u8 *eid = va_arg (*args, u8 *);
3244   u32 eid_len = va_arg (*args, u32);
3245   u8 *seid = va_arg (*args, u8 *);
3246   u32 seid_len = va_arg (*args, u32);
3247   u32 is_src_dst = va_arg (*args, u32);
3248
3249   if (is_src_dst)
3250     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3251
3252   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3253
3254   return s;
3255 }
3256
3257 static void
3258 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3259 {
3260   vat_main_t *vam = &vat_main;
3261   u8 *s = 0, *eid = 0;
3262
3263   if (~0 == mp->locator_set_index)
3264     s = format (0, "action: %d", mp->action);
3265   else
3266     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3267
3268   eid = format (0, "%U", format_lisp_eid_vat,
3269                 mp->eid_type,
3270                 mp->eid,
3271                 mp->eid_prefix_len,
3272                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3273   vec_add1 (eid, 0);
3274
3275   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3276          clib_net_to_host_u32 (mp->vni),
3277          eid,
3278          mp->is_local ? "local" : "remote",
3279          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3280          clib_net_to_host_u16 (mp->key_id), mp->key);
3281
3282   vec_free (s);
3283   vec_free (eid);
3284 }
3285
3286 static void
3287 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3288                                              * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t *node = 0;
3292   u8 *eid = 0;
3293
3294   if (VAT_JSON_ARRAY != vam->json_tree.type)
3295     {
3296       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3297       vat_json_init_array (&vam->json_tree);
3298     }
3299   node = vat_json_array_add (&vam->json_tree);
3300
3301   vat_json_init_object (node);
3302   if (~0 == mp->locator_set_index)
3303     vat_json_object_add_uint (node, "action", mp->action);
3304   else
3305     vat_json_object_add_uint (node, "locator_set_index",
3306                               clib_net_to_host_u32 (mp->locator_set_index));
3307
3308   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3309   if (mp->eid_type == 3)
3310     {
3311       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3312       vat_json_init_object (nsh_json);
3313       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3314       vat_json_object_add_uint (nsh_json, "spi",
3315                                 clib_net_to_host_u32 (nsh->spi));
3316       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3317     }
3318   else
3319     {
3320       eid = format (0, "%U", format_lisp_eid_vat,
3321                     mp->eid_type,
3322                     mp->eid,
3323                     mp->eid_prefix_len,
3324                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3325       vec_add1 (eid, 0);
3326       vat_json_object_add_string_copy (node, "eid", eid);
3327       vec_free (eid);
3328     }
3329   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3330   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3331   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3332
3333   if (mp->key_id)
3334     {
3335       vat_json_object_add_uint (node, "key_id",
3336                                 clib_net_to_host_u16 (mp->key_id));
3337       vat_json_object_add_string_copy (node, "key", mp->key);
3338     }
3339 }
3340
3341 static void
3342 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3343 {
3344   vat_main_t *vam = &vat_main;
3345   u8 *seid = 0, *deid = 0;
3346   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3347
3348   deid = format (0, "%U", format_lisp_eid_vat,
3349                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3350
3351   seid = format (0, "%U", format_lisp_eid_vat,
3352                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3353
3354   vec_add1 (deid, 0);
3355   vec_add1 (seid, 0);
3356
3357   if (mp->is_ip4)
3358     format_ip_address_fcn = format_ip4_address;
3359   else
3360     format_ip_address_fcn = format_ip6_address;
3361
3362
3363   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3364          clib_net_to_host_u32 (mp->vni),
3365          seid, deid,
3366          format_ip_address_fcn, mp->lloc,
3367          format_ip_address_fcn, mp->rloc,
3368          clib_net_to_host_u32 (mp->pkt_count),
3369          clib_net_to_host_u32 (mp->bytes));
3370
3371   vec_free (deid);
3372   vec_free (seid);
3373 }
3374
3375 static void
3376 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3377 {
3378   struct in6_addr ip6;
3379   struct in_addr ip4;
3380   vat_main_t *vam = &vat_main;
3381   vat_json_node_t *node = 0;
3382   u8 *deid = 0, *seid = 0;
3383
3384   if (VAT_JSON_ARRAY != vam->json_tree.type)
3385     {
3386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3387       vat_json_init_array (&vam->json_tree);
3388     }
3389   node = vat_json_array_add (&vam->json_tree);
3390
3391   vat_json_init_object (node);
3392   deid = format (0, "%U", format_lisp_eid_vat,
3393                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3394
3395   seid = format (0, "%U", format_lisp_eid_vat,
3396                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3397
3398   vec_add1 (deid, 0);
3399   vec_add1 (seid, 0);
3400
3401   vat_json_object_add_string_copy (node, "seid", seid);
3402   vat_json_object_add_string_copy (node, "deid", deid);
3403   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3404
3405   if (mp->is_ip4)
3406     {
3407       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3408       vat_json_object_add_ip4 (node, "lloc", ip4);
3409       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3410       vat_json_object_add_ip4 (node, "rloc", ip4);
3411     }
3412   else
3413     {
3414       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3415       vat_json_object_add_ip6 (node, "lloc", ip6);
3416       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3417       vat_json_object_add_ip6 (node, "rloc", ip6);
3418     }
3419   vat_json_object_add_uint (node, "pkt_count",
3420                             clib_net_to_host_u32 (mp->pkt_count));
3421   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3422
3423   vec_free (deid);
3424   vec_free (seid);
3425 }
3426
3427 static void
3428   vl_api_one_eid_table_map_details_t_handler
3429   (vl_api_one_eid_table_map_details_t * mp)
3430 {
3431   vat_main_t *vam = &vat_main;
3432
3433   u8 *line = format (0, "%=10d%=10d",
3434                      clib_net_to_host_u32 (mp->vni),
3435                      clib_net_to_host_u32 (mp->dp_table));
3436   print (vam->ofp, "%v", line);
3437   vec_free (line);
3438 }
3439
3440 static void
3441   vl_api_one_eid_table_map_details_t_handler_json
3442   (vl_api_one_eid_table_map_details_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   vat_json_node_t *node = NULL;
3446
3447   if (VAT_JSON_ARRAY != vam->json_tree.type)
3448     {
3449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3450       vat_json_init_array (&vam->json_tree);
3451     }
3452   node = vat_json_array_add (&vam->json_tree);
3453   vat_json_init_object (node);
3454   vat_json_object_add_uint (node, "dp_table",
3455                             clib_net_to_host_u32 (mp->dp_table));
3456   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3457 }
3458
3459 static void
3460   vl_api_one_eid_table_vni_details_t_handler
3461   (vl_api_one_eid_table_vni_details_t * mp)
3462 {
3463   vat_main_t *vam = &vat_main;
3464
3465   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3466   print (vam->ofp, "%v", line);
3467   vec_free (line);
3468 }
3469
3470 static void
3471   vl_api_one_eid_table_vni_details_t_handler_json
3472   (vl_api_one_eid_table_vni_details_t * mp)
3473 {
3474   vat_main_t *vam = &vat_main;
3475   vat_json_node_t *node = NULL;
3476
3477   if (VAT_JSON_ARRAY != vam->json_tree.type)
3478     {
3479       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3480       vat_json_init_array (&vam->json_tree);
3481     }
3482   node = vat_json_array_add (&vam->json_tree);
3483   vat_json_init_object (node);
3484   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3485 }
3486
3487 static void
3488   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3489   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3490 {
3491   vat_main_t *vam = &vat_main;
3492   int retval = clib_net_to_host_u32 (mp->retval);
3493
3494   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3495   print (vam->ofp, "fallback threshold value: %d", mp->value);
3496
3497   vam->retval = retval;
3498   vam->result_ready = 1;
3499 }
3500
3501 static void
3502   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3503   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506   vat_json_node_t _node, *node = &_node;
3507   int retval = clib_net_to_host_u32 (mp->retval);
3508
3509   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3510   vat_json_init_object (node);
3511   vat_json_object_add_uint (node, "value", mp->value);
3512
3513   vat_json_print (vam->ofp, node);
3514   vat_json_free (node);
3515
3516   vam->retval = retval;
3517   vam->result_ready = 1;
3518 }
3519
3520 static void
3521   vl_api_show_one_map_register_state_reply_t_handler
3522   (vl_api_show_one_map_register_state_reply_t * mp)
3523 {
3524   vat_main_t *vam = &vat_main;
3525   int retval = clib_net_to_host_u32 (mp->retval);
3526
3527   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3528
3529   vam->retval = retval;
3530   vam->result_ready = 1;
3531 }
3532
3533 static void
3534   vl_api_show_one_map_register_state_reply_t_handler_json
3535   (vl_api_show_one_map_register_state_reply_t * mp)
3536 {
3537   vat_main_t *vam = &vat_main;
3538   vat_json_node_t _node, *node = &_node;
3539   int retval = clib_net_to_host_u32 (mp->retval);
3540
3541   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3542
3543   vat_json_init_object (node);
3544   vat_json_object_add_string_copy (node, "state", s);
3545
3546   vat_json_print (vam->ofp, node);
3547   vat_json_free (node);
3548
3549   vam->retval = retval;
3550   vam->result_ready = 1;
3551   vec_free (s);
3552 }
3553
3554 static void
3555   vl_api_show_one_rloc_probe_state_reply_t_handler
3556   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3557 {
3558   vat_main_t *vam = &vat_main;
3559   int retval = clib_net_to_host_u32 (mp->retval);
3560
3561   if (retval)
3562     goto end;
3563
3564   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3565 end:
3566   vam->retval = retval;
3567   vam->result_ready = 1;
3568 }
3569
3570 static void
3571   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3572   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3573 {
3574   vat_main_t *vam = &vat_main;
3575   vat_json_node_t _node, *node = &_node;
3576   int retval = clib_net_to_host_u32 (mp->retval);
3577
3578   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3579   vat_json_init_object (node);
3580   vat_json_object_add_string_copy (node, "state", s);
3581
3582   vat_json_print (vam->ofp, node);
3583   vat_json_free (node);
3584
3585   vam->retval = retval;
3586   vam->result_ready = 1;
3587   vec_free (s);
3588 }
3589
3590 static void
3591   vl_api_show_one_stats_enable_disable_reply_t_handler
3592   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   int retval = clib_net_to_host_u32 (mp->retval);
3596
3597   if (retval)
3598     goto end;
3599
3600   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3601 end:
3602   vam->retval = retval;
3603   vam->result_ready = 1;
3604 }
3605
3606 static void
3607   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3608   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3609 {
3610   vat_main_t *vam = &vat_main;
3611   vat_json_node_t _node, *node = &_node;
3612   int retval = clib_net_to_host_u32 (mp->retval);
3613
3614   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3615   vat_json_init_object (node);
3616   vat_json_object_add_string_copy (node, "state", s);
3617
3618   vat_json_print (vam->ofp, node);
3619   vat_json_free (node);
3620
3621   vam->retval = retval;
3622   vam->result_ready = 1;
3623   vec_free (s);
3624 }
3625
3626 static void
3627 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3628 {
3629   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3630   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3631   e->vni = clib_net_to_host_u32 (e->vni);
3632 }
3633
3634 static void
3635   gpe_fwd_entries_get_reply_t_net_to_host
3636   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3637 {
3638   u32 i;
3639
3640   mp->count = clib_net_to_host_u32 (mp->count);
3641   for (i = 0; i < mp->count; i++)
3642     {
3643       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3644     }
3645 }
3646
3647 static u8 *
3648 format_gpe_encap_mode (u8 * s, va_list * args)
3649 {
3650   u32 mode = va_arg (*args, u32);
3651
3652   switch (mode)
3653     {
3654     case 0:
3655       return format (s, "lisp");
3656     case 1:
3657       return format (s, "vxlan");
3658     }
3659   return 0;
3660 }
3661
3662 static void
3663   vl_api_gpe_get_encap_mode_reply_t_handler
3664   (vl_api_gpe_get_encap_mode_reply_t * mp)
3665 {
3666   vat_main_t *vam = &vat_main;
3667
3668   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3669   vam->retval = ntohl (mp->retval);
3670   vam->result_ready = 1;
3671 }
3672
3673 static void
3674   vl_api_gpe_get_encap_mode_reply_t_handler_json
3675   (vl_api_gpe_get_encap_mode_reply_t * mp)
3676 {
3677   vat_main_t *vam = &vat_main;
3678   vat_json_node_t node;
3679
3680   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3681   vec_add1 (encap_mode, 0);
3682
3683   vat_json_init_object (&node);
3684   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3685
3686   vec_free (encap_mode);
3687   vat_json_print (vam->ofp, &node);
3688   vat_json_free (&node);
3689
3690   vam->retval = ntohl (mp->retval);
3691   vam->result_ready = 1;
3692 }
3693
3694 static void
3695   vl_api_gpe_fwd_entry_path_details_t_handler
3696   (vl_api_gpe_fwd_entry_path_details_t * mp)
3697 {
3698   vat_main_t *vam = &vat_main;
3699   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3700
3701   if (mp->lcl_loc.is_ip4)
3702     format_ip_address_fcn = format_ip4_address;
3703   else
3704     format_ip_address_fcn = format_ip6_address;
3705
3706   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3707          format_ip_address_fcn, &mp->lcl_loc,
3708          format_ip_address_fcn, &mp->rmt_loc);
3709 }
3710
3711 static void
3712 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3713 {
3714   struct in6_addr ip6;
3715   struct in_addr ip4;
3716
3717   if (loc->is_ip4)
3718     {
3719       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3720       vat_json_object_add_ip4 (n, "address", ip4);
3721     }
3722   else
3723     {
3724       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3725       vat_json_object_add_ip6 (n, "address", ip6);
3726     }
3727   vat_json_object_add_uint (n, "weight", loc->weight);
3728 }
3729
3730 static void
3731   vl_api_gpe_fwd_entry_path_details_t_handler_json
3732   (vl_api_gpe_fwd_entry_path_details_t * mp)
3733 {
3734   vat_main_t *vam = &vat_main;
3735   vat_json_node_t *node = NULL;
3736   vat_json_node_t *loc_node;
3737
3738   if (VAT_JSON_ARRAY != vam->json_tree.type)
3739     {
3740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3741       vat_json_init_array (&vam->json_tree);
3742     }
3743   node = vat_json_array_add (&vam->json_tree);
3744   vat_json_init_object (node);
3745
3746   loc_node = vat_json_object_add (node, "local_locator");
3747   vat_json_init_object (loc_node);
3748   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3749
3750   loc_node = vat_json_object_add (node, "remote_locator");
3751   vat_json_init_object (loc_node);
3752   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3753 }
3754
3755 static void
3756   vl_api_gpe_fwd_entries_get_reply_t_handler
3757   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3758 {
3759   vat_main_t *vam = &vat_main;
3760   u32 i;
3761   int retval = clib_net_to_host_u32 (mp->retval);
3762   vl_api_gpe_fwd_entry_t *e;
3763
3764   if (retval)
3765     goto end;
3766
3767   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3768
3769   for (i = 0; i < mp->count; i++)
3770     {
3771       e = &mp->entries[i];
3772       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3773              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3774              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3775     }
3776
3777 end:
3778   vam->retval = retval;
3779   vam->result_ready = 1;
3780 }
3781
3782 static void
3783   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3784   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3785 {
3786   u8 *s = 0;
3787   vat_main_t *vam = &vat_main;
3788   vat_json_node_t *e = 0, root;
3789   u32 i;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791   vl_api_gpe_fwd_entry_t *fwd;
3792
3793   if (retval)
3794     goto end;
3795
3796   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3797   vat_json_init_array (&root);
3798
3799   for (i = 0; i < mp->count; i++)
3800     {
3801       e = vat_json_array_add (&root);
3802       fwd = &mp->entries[i];
3803
3804       vat_json_init_object (e);
3805       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3806       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3807       vat_json_object_add_int (e, "vni", fwd->vni);
3808       vat_json_object_add_int (e, "action", fwd->action);
3809
3810       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3811                   fwd->leid_prefix_len);
3812       vec_add1 (s, 0);
3813       vat_json_object_add_string_copy (e, "leid", s);
3814       vec_free (s);
3815
3816       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3817                   fwd->reid_prefix_len);
3818       vec_add1 (s, 0);
3819       vat_json_object_add_string_copy (e, "reid", s);
3820       vec_free (s);
3821     }
3822
3823   vat_json_print (vam->ofp, &root);
3824   vat_json_free (&root);
3825
3826 end:
3827   vam->retval = retval;
3828   vam->result_ready = 1;
3829 }
3830
3831 static void
3832   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3833   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3834 {
3835   vat_main_t *vam = &vat_main;
3836   u32 i, n;
3837   int retval = clib_net_to_host_u32 (mp->retval);
3838   vl_api_gpe_native_fwd_rpath_t *r;
3839
3840   if (retval)
3841     goto end;
3842
3843   n = clib_net_to_host_u32 (mp->count);
3844
3845   for (i = 0; i < n; i++)
3846     {
3847       r = &mp->entries[i];
3848       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3849              clib_net_to_host_u32 (r->fib_index),
3850              clib_net_to_host_u32 (r->nh_sw_if_index),
3851              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3852     }
3853
3854 end:
3855   vam->retval = retval;
3856   vam->result_ready = 1;
3857 }
3858
3859 static void
3860   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3861   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3862 {
3863   vat_main_t *vam = &vat_main;
3864   vat_json_node_t root, *e;
3865   u32 i, n;
3866   int retval = clib_net_to_host_u32 (mp->retval);
3867   vl_api_gpe_native_fwd_rpath_t *r;
3868   u8 *s;
3869
3870   if (retval)
3871     goto end;
3872
3873   n = clib_net_to_host_u32 (mp->count);
3874   vat_json_init_array (&root);
3875
3876   for (i = 0; i < n; i++)
3877     {
3878       e = vat_json_array_add (&root);
3879       vat_json_init_object (e);
3880       r = &mp->entries[i];
3881       s =
3882         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3883                 r->nh_addr);
3884       vec_add1 (s, 0);
3885       vat_json_object_add_string_copy (e, "ip4", s);
3886       vec_free (s);
3887
3888       vat_json_object_add_uint (e, "fib_index",
3889                                 clib_net_to_host_u32 (r->fib_index));
3890       vat_json_object_add_uint (e, "nh_sw_if_index",
3891                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3892     }
3893
3894   vat_json_print (vam->ofp, &root);
3895   vat_json_free (&root);
3896
3897 end:
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3904   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   u32 i, n;
3908   int retval = clib_net_to_host_u32 (mp->retval);
3909
3910   if (retval)
3911     goto end;
3912
3913   n = clib_net_to_host_u32 (mp->count);
3914
3915   for (i = 0; i < n; i++)
3916     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3917
3918 end:
3919   vam->retval = retval;
3920   vam->result_ready = 1;
3921 }
3922
3923 static void
3924   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3925   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3926 {
3927   vat_main_t *vam = &vat_main;
3928   vat_json_node_t root;
3929   u32 i, n;
3930   int retval = clib_net_to_host_u32 (mp->retval);
3931
3932   if (retval)
3933     goto end;
3934
3935   n = clib_net_to_host_u32 (mp->count);
3936   vat_json_init_array (&root);
3937
3938   for (i = 0; i < n; i++)
3939     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3940
3941   vat_json_print (vam->ofp, &root);
3942   vat_json_free (&root);
3943
3944 end:
3945   vam->retval = retval;
3946   vam->result_ready = 1;
3947 }
3948
3949 static void
3950   vl_api_one_ndp_entries_get_reply_t_handler
3951   (vl_api_one_ndp_entries_get_reply_t * mp)
3952 {
3953   vat_main_t *vam = &vat_main;
3954   u32 i, n;
3955   int retval = clib_net_to_host_u32 (mp->retval);
3956
3957   if (retval)
3958     goto end;
3959
3960   n = clib_net_to_host_u32 (mp->count);
3961
3962   for (i = 0; i < n; i++)
3963     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3964            format_ethernet_address, mp->entries[i].mac);
3965
3966 end:
3967   vam->retval = retval;
3968   vam->result_ready = 1;
3969 }
3970
3971 static void
3972   vl_api_one_ndp_entries_get_reply_t_handler_json
3973   (vl_api_one_ndp_entries_get_reply_t * mp)
3974 {
3975   u8 *s = 0;
3976   vat_main_t *vam = &vat_main;
3977   vat_json_node_t *e = 0, root;
3978   u32 i, n;
3979   int retval = clib_net_to_host_u32 (mp->retval);
3980   vl_api_one_ndp_entry_t *arp_entry;
3981
3982   if (retval)
3983     goto end;
3984
3985   n = clib_net_to_host_u32 (mp->count);
3986   vat_json_init_array (&root);
3987
3988   for (i = 0; i < n; i++)
3989     {
3990       e = vat_json_array_add (&root);
3991       arp_entry = &mp->entries[i];
3992
3993       vat_json_init_object (e);
3994       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3995       vec_add1 (s, 0);
3996
3997       vat_json_object_add_string_copy (e, "mac", s);
3998       vec_free (s);
3999
4000       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4001       vec_add1 (s, 0);
4002       vat_json_object_add_string_copy (e, "ip6", s);
4003       vec_free (s);
4004     }
4005
4006   vat_json_print (vam->ofp, &root);
4007   vat_json_free (&root);
4008
4009 end:
4010   vam->retval = retval;
4011   vam->result_ready = 1;
4012 }
4013
4014 static void
4015   vl_api_one_l2_arp_entries_get_reply_t_handler
4016   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019   u32 i, n;
4020   int retval = clib_net_to_host_u32 (mp->retval);
4021
4022   if (retval)
4023     goto end;
4024
4025   n = clib_net_to_host_u32 (mp->count);
4026
4027   for (i = 0; i < n; i++)
4028     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4029            format_ethernet_address, mp->entries[i].mac);
4030
4031 end:
4032   vam->retval = retval;
4033   vam->result_ready = 1;
4034 }
4035
4036 static void
4037   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4038   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4039 {
4040   u8 *s = 0;
4041   vat_main_t *vam = &vat_main;
4042   vat_json_node_t *e = 0, root;
4043   u32 i, n;
4044   int retval = clib_net_to_host_u32 (mp->retval);
4045   vl_api_one_l2_arp_entry_t *arp_entry;
4046
4047   if (retval)
4048     goto end;
4049
4050   n = clib_net_to_host_u32 (mp->count);
4051   vat_json_init_array (&root);
4052
4053   for (i = 0; i < n; i++)
4054     {
4055       e = vat_json_array_add (&root);
4056       arp_entry = &mp->entries[i];
4057
4058       vat_json_init_object (e);
4059       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4060       vec_add1 (s, 0);
4061
4062       vat_json_object_add_string_copy (e, "mac", s);
4063       vec_free (s);
4064
4065       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4066       vec_add1 (s, 0);
4067       vat_json_object_add_string_copy (e, "ip4", s);
4068       vec_free (s);
4069     }
4070
4071   vat_json_print (vam->ofp, &root);
4072   vat_json_free (&root);
4073
4074 end:
4075   vam->retval = retval;
4076   vam->result_ready = 1;
4077 }
4078
4079 static void
4080 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4081 {
4082   vat_main_t *vam = &vat_main;
4083   u32 i, n;
4084   int retval = clib_net_to_host_u32 (mp->retval);
4085
4086   if (retval)
4087     goto end;
4088
4089   n = clib_net_to_host_u32 (mp->count);
4090
4091   for (i = 0; i < n; i++)
4092     {
4093       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4094     }
4095
4096 end:
4097   vam->retval = retval;
4098   vam->result_ready = 1;
4099 }
4100
4101 static void
4102   vl_api_one_ndp_bd_get_reply_t_handler_json
4103   (vl_api_one_ndp_bd_get_reply_t * mp)
4104 {
4105   vat_main_t *vam = &vat_main;
4106   vat_json_node_t root;
4107   u32 i, n;
4108   int retval = clib_net_to_host_u32 (mp->retval);
4109
4110   if (retval)
4111     goto end;
4112
4113   n = clib_net_to_host_u32 (mp->count);
4114   vat_json_init_array (&root);
4115
4116   for (i = 0; i < n; i++)
4117     {
4118       vat_json_array_add_uint (&root,
4119                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4120     }
4121
4122   vat_json_print (vam->ofp, &root);
4123   vat_json_free (&root);
4124
4125 end:
4126   vam->retval = retval;
4127   vam->result_ready = 1;
4128 }
4129
4130 static void
4131   vl_api_one_l2_arp_bd_get_reply_t_handler
4132   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4133 {
4134   vat_main_t *vam = &vat_main;
4135   u32 i, n;
4136   int retval = clib_net_to_host_u32 (mp->retval);
4137
4138   if (retval)
4139     goto end;
4140
4141   n = clib_net_to_host_u32 (mp->count);
4142
4143   for (i = 0; i < n; i++)
4144     {
4145       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4146     }
4147
4148 end:
4149   vam->retval = retval;
4150   vam->result_ready = 1;
4151 }
4152
4153 static void
4154   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4155   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4156 {
4157   vat_main_t *vam = &vat_main;
4158   vat_json_node_t root;
4159   u32 i, n;
4160   int retval = clib_net_to_host_u32 (mp->retval);
4161
4162   if (retval)
4163     goto end;
4164
4165   n = clib_net_to_host_u32 (mp->count);
4166   vat_json_init_array (&root);
4167
4168   for (i = 0; i < n; i++)
4169     {
4170       vat_json_array_add_uint (&root,
4171                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4172     }
4173
4174   vat_json_print (vam->ofp, &root);
4175   vat_json_free (&root);
4176
4177 end:
4178   vam->retval = retval;
4179   vam->result_ready = 1;
4180 }
4181
4182 static void
4183   vl_api_one_adjacencies_get_reply_t_handler
4184   (vl_api_one_adjacencies_get_reply_t * mp)
4185 {
4186   vat_main_t *vam = &vat_main;
4187   u32 i, n;
4188   int retval = clib_net_to_host_u32 (mp->retval);
4189   vl_api_one_adjacency_t *a;
4190
4191   if (retval)
4192     goto end;
4193
4194   n = clib_net_to_host_u32 (mp->count);
4195
4196   for (i = 0; i < n; i++)
4197     {
4198       a = &mp->adjacencies[i];
4199       print (vam->ofp, "%U %40U",
4200              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4201              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4202     }
4203
4204 end:
4205   vam->retval = retval;
4206   vam->result_ready = 1;
4207 }
4208
4209 static void
4210   vl_api_one_adjacencies_get_reply_t_handler_json
4211   (vl_api_one_adjacencies_get_reply_t * mp)
4212 {
4213   u8 *s = 0;
4214   vat_main_t *vam = &vat_main;
4215   vat_json_node_t *e = 0, root;
4216   u32 i, n;
4217   int retval = clib_net_to_host_u32 (mp->retval);
4218   vl_api_one_adjacency_t *a;
4219
4220   if (retval)
4221     goto end;
4222
4223   n = clib_net_to_host_u32 (mp->count);
4224   vat_json_init_array (&root);
4225
4226   for (i = 0; i < n; i++)
4227     {
4228       e = vat_json_array_add (&root);
4229       a = &mp->adjacencies[i];
4230
4231       vat_json_init_object (e);
4232       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4233                   a->leid_prefix_len);
4234       vec_add1 (s, 0);
4235       vat_json_object_add_string_copy (e, "leid", s);
4236       vec_free (s);
4237
4238       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4239                   a->reid_prefix_len);
4240       vec_add1 (s, 0);
4241       vat_json_object_add_string_copy (e, "reid", s);
4242       vec_free (s);
4243     }
4244
4245   vat_json_print (vam->ofp, &root);
4246   vat_json_free (&root);
4247
4248 end:
4249   vam->retval = retval;
4250   vam->result_ready = 1;
4251 }
4252
4253 static void
4254 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4255 {
4256   vat_main_t *vam = &vat_main;
4257
4258   print (vam->ofp, "%=20U",
4259          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4260          mp->ip_address);
4261 }
4262
4263 static void
4264   vl_api_one_map_server_details_t_handler_json
4265   (vl_api_one_map_server_details_t * mp)
4266 {
4267   vat_main_t *vam = &vat_main;
4268   vat_json_node_t *node = NULL;
4269   struct in6_addr ip6;
4270   struct in_addr ip4;
4271
4272   if (VAT_JSON_ARRAY != vam->json_tree.type)
4273     {
4274       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4275       vat_json_init_array (&vam->json_tree);
4276     }
4277   node = vat_json_array_add (&vam->json_tree);
4278
4279   vat_json_init_object (node);
4280   if (mp->is_ipv6)
4281     {
4282       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4283       vat_json_object_add_ip6 (node, "map-server", ip6);
4284     }
4285   else
4286     {
4287       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4288       vat_json_object_add_ip4 (node, "map-server", ip4);
4289     }
4290 }
4291
4292 static void
4293 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4294                                            * mp)
4295 {
4296   vat_main_t *vam = &vat_main;
4297
4298   print (vam->ofp, "%=20U",
4299          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4300          mp->ip_address);
4301 }
4302
4303 static void
4304   vl_api_one_map_resolver_details_t_handler_json
4305   (vl_api_one_map_resolver_details_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   vat_json_node_t *node = NULL;
4309   struct in6_addr ip6;
4310   struct in_addr ip4;
4311
4312   if (VAT_JSON_ARRAY != vam->json_tree.type)
4313     {
4314       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4315       vat_json_init_array (&vam->json_tree);
4316     }
4317   node = vat_json_array_add (&vam->json_tree);
4318
4319   vat_json_init_object (node);
4320   if (mp->is_ipv6)
4321     {
4322       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4323       vat_json_object_add_ip6 (node, "map resolver", ip6);
4324     }
4325   else
4326     {
4327       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4328       vat_json_object_add_ip4 (node, "map resolver", ip4);
4329     }
4330 }
4331
4332 static void
4333 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   i32 retval = ntohl (mp->retval);
4337
4338   if (0 <= retval)
4339     {
4340       print (vam->ofp, "feature: %s\ngpe: %s",
4341              mp->feature_status ? "enabled" : "disabled",
4342              mp->gpe_status ? "enabled" : "disabled");
4343     }
4344
4345   vam->retval = retval;
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_show_one_status_reply_t_handler_json
4351   (vl_api_show_one_status_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   vat_json_node_t node;
4355   u8 *gpe_status = NULL;
4356   u8 *feature_status = NULL;
4357
4358   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4359   feature_status = format (0, "%s",
4360                            mp->feature_status ? "enabled" : "disabled");
4361   vec_add1 (gpe_status, 0);
4362   vec_add1 (feature_status, 0);
4363
4364   vat_json_init_object (&node);
4365   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4366   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4367
4368   vec_free (gpe_status);
4369   vec_free (feature_status);
4370
4371   vat_json_print (vam->ofp, &node);
4372   vat_json_free (&node);
4373
4374   vam->retval = ntohl (mp->retval);
4375   vam->result_ready = 1;
4376 }
4377
4378 static void
4379   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4380   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4381 {
4382   vat_main_t *vam = &vat_main;
4383   i32 retval = ntohl (mp->retval);
4384
4385   if (retval >= 0)
4386     {
4387       print (vam->ofp, "%=20s", mp->locator_set_name);
4388     }
4389
4390   vam->retval = retval;
4391   vam->result_ready = 1;
4392 }
4393
4394 static void
4395   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4396   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4397 {
4398   vat_main_t *vam = &vat_main;
4399   vat_json_node_t *node = NULL;
4400
4401   if (VAT_JSON_ARRAY != vam->json_tree.type)
4402     {
4403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4404       vat_json_init_array (&vam->json_tree);
4405     }
4406   node = vat_json_array_add (&vam->json_tree);
4407
4408   vat_json_init_object (node);
4409   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4410
4411   vat_json_print (vam->ofp, node);
4412   vat_json_free (node);
4413
4414   vam->retval = ntohl (mp->retval);
4415   vam->result_ready = 1;
4416 }
4417
4418 static u8 *
4419 format_lisp_map_request_mode (u8 * s, va_list * args)
4420 {
4421   u32 mode = va_arg (*args, u32);
4422
4423   switch (mode)
4424     {
4425     case 0:
4426       return format (0, "dst-only");
4427     case 1:
4428       return format (0, "src-dst");
4429     }
4430   return 0;
4431 }
4432
4433 static void
4434   vl_api_show_one_map_request_mode_reply_t_handler
4435   (vl_api_show_one_map_request_mode_reply_t * mp)
4436 {
4437   vat_main_t *vam = &vat_main;
4438   i32 retval = ntohl (mp->retval);
4439
4440   if (0 <= retval)
4441     {
4442       u32 mode = mp->mode;
4443       print (vam->ofp, "map_request_mode: %U",
4444              format_lisp_map_request_mode, mode);
4445     }
4446
4447   vam->retval = retval;
4448   vam->result_ready = 1;
4449 }
4450
4451 static void
4452   vl_api_show_one_map_request_mode_reply_t_handler_json
4453   (vl_api_show_one_map_request_mode_reply_t * mp)
4454 {
4455   vat_main_t *vam = &vat_main;
4456   vat_json_node_t node;
4457   u8 *s = 0;
4458   u32 mode;
4459
4460   mode = mp->mode;
4461   s = format (0, "%U", format_lisp_map_request_mode, mode);
4462   vec_add1 (s, 0);
4463
4464   vat_json_init_object (&node);
4465   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4466   vat_json_print (vam->ofp, &node);
4467   vat_json_free (&node);
4468
4469   vec_free (s);
4470   vam->retval = ntohl (mp->retval);
4471   vam->result_ready = 1;
4472 }
4473
4474 static void
4475   vl_api_one_show_xtr_mode_reply_t_handler
4476   (vl_api_one_show_xtr_mode_reply_t * mp)
4477 {
4478   vat_main_t *vam = &vat_main;
4479   i32 retval = ntohl (mp->retval);
4480
4481   if (0 <= retval)
4482     {
4483       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4484     }
4485
4486   vam->retval = retval;
4487   vam->result_ready = 1;
4488 }
4489
4490 static void
4491   vl_api_one_show_xtr_mode_reply_t_handler_json
4492   (vl_api_one_show_xtr_mode_reply_t * mp)
4493 {
4494   vat_main_t *vam = &vat_main;
4495   vat_json_node_t node;
4496   u8 *status = 0;
4497
4498   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4499   vec_add1 (status, 0);
4500
4501   vat_json_init_object (&node);
4502   vat_json_object_add_string_copy (&node, "status", status);
4503
4504   vec_free (status);
4505
4506   vat_json_print (vam->ofp, &node);
4507   vat_json_free (&node);
4508
4509   vam->retval = ntohl (mp->retval);
4510   vam->result_ready = 1;
4511 }
4512
4513 static void
4514   vl_api_one_show_pitr_mode_reply_t_handler
4515   (vl_api_one_show_pitr_mode_reply_t * mp)
4516 {
4517   vat_main_t *vam = &vat_main;
4518   i32 retval = ntohl (mp->retval);
4519
4520   if (0 <= retval)
4521     {
4522       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4523     }
4524
4525   vam->retval = retval;
4526   vam->result_ready = 1;
4527 }
4528
4529 static void
4530   vl_api_one_show_pitr_mode_reply_t_handler_json
4531   (vl_api_one_show_pitr_mode_reply_t * mp)
4532 {
4533   vat_main_t *vam = &vat_main;
4534   vat_json_node_t node;
4535   u8 *status = 0;
4536
4537   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4538   vec_add1 (status, 0);
4539
4540   vat_json_init_object (&node);
4541   vat_json_object_add_string_copy (&node, "status", status);
4542
4543   vec_free (status);
4544
4545   vat_json_print (vam->ofp, &node);
4546   vat_json_free (&node);
4547
4548   vam->retval = ntohl (mp->retval);
4549   vam->result_ready = 1;
4550 }
4551
4552 static void
4553   vl_api_one_show_petr_mode_reply_t_handler
4554   (vl_api_one_show_petr_mode_reply_t * mp)
4555 {
4556   vat_main_t *vam = &vat_main;
4557   i32 retval = ntohl (mp->retval);
4558
4559   if (0 <= retval)
4560     {
4561       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4562     }
4563
4564   vam->retval = retval;
4565   vam->result_ready = 1;
4566 }
4567
4568 static void
4569   vl_api_one_show_petr_mode_reply_t_handler_json
4570   (vl_api_one_show_petr_mode_reply_t * mp)
4571 {
4572   vat_main_t *vam = &vat_main;
4573   vat_json_node_t node;
4574   u8 *status = 0;
4575
4576   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4577   vec_add1 (status, 0);
4578
4579   vat_json_init_object (&node);
4580   vat_json_object_add_string_copy (&node, "status", status);
4581
4582   vec_free (status);
4583
4584   vat_json_print (vam->ofp, &node);
4585   vat_json_free (&node);
4586
4587   vam->retval = ntohl (mp->retval);
4588   vam->result_ready = 1;
4589 }
4590
4591 static void
4592   vl_api_show_one_use_petr_reply_t_handler
4593   (vl_api_show_one_use_petr_reply_t * mp)
4594 {
4595   vat_main_t *vam = &vat_main;
4596   i32 retval = ntohl (mp->retval);
4597
4598   if (0 <= retval)
4599     {
4600       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4601       if (mp->status)
4602         {
4603           print (vam->ofp, "Proxy-ETR address; %U",
4604                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4605                  mp->address);
4606         }
4607     }
4608
4609   vam->retval = retval;
4610   vam->result_ready = 1;
4611 }
4612
4613 static void
4614   vl_api_show_one_use_petr_reply_t_handler_json
4615   (vl_api_show_one_use_petr_reply_t * mp)
4616 {
4617   vat_main_t *vam = &vat_main;
4618   vat_json_node_t node;
4619   u8 *status = 0;
4620   struct in_addr ip4;
4621   struct in6_addr ip6;
4622
4623   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4624   vec_add1 (status, 0);
4625
4626   vat_json_init_object (&node);
4627   vat_json_object_add_string_copy (&node, "status", status);
4628   if (mp->status)
4629     {
4630       if (mp->is_ip4)
4631         {
4632           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4633           vat_json_object_add_ip6 (&node, "address", ip6);
4634         }
4635       else
4636         {
4637           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4638           vat_json_object_add_ip4 (&node, "address", ip4);
4639         }
4640     }
4641
4642   vec_free (status);
4643
4644   vat_json_print (vam->ofp, &node);
4645   vat_json_free (&node);
4646
4647   vam->retval = ntohl (mp->retval);
4648   vam->result_ready = 1;
4649 }
4650
4651 static void
4652   vl_api_show_one_nsh_mapping_reply_t_handler
4653   (vl_api_show_one_nsh_mapping_reply_t * mp)
4654 {
4655   vat_main_t *vam = &vat_main;
4656   i32 retval = ntohl (mp->retval);
4657
4658   if (0 <= retval)
4659     {
4660       print (vam->ofp, "%-20s%-16s",
4661              mp->is_set ? "set" : "not-set",
4662              mp->is_set ? (char *) mp->locator_set_name : "");
4663     }
4664
4665   vam->retval = retval;
4666   vam->result_ready = 1;
4667 }
4668
4669 static void
4670   vl_api_show_one_nsh_mapping_reply_t_handler_json
4671   (vl_api_show_one_nsh_mapping_reply_t * mp)
4672 {
4673   vat_main_t *vam = &vat_main;
4674   vat_json_node_t node;
4675   u8 *status = 0;
4676
4677   status = format (0, "%s", mp->is_set ? "yes" : "no");
4678   vec_add1 (status, 0);
4679
4680   vat_json_init_object (&node);
4681   vat_json_object_add_string_copy (&node, "is_set", status);
4682   if (mp->is_set)
4683     {
4684       vat_json_object_add_string_copy (&node, "locator_set",
4685                                        mp->locator_set_name);
4686     }
4687
4688   vec_free (status);
4689
4690   vat_json_print (vam->ofp, &node);
4691   vat_json_free (&node);
4692
4693   vam->retval = ntohl (mp->retval);
4694   vam->result_ready = 1;
4695 }
4696
4697 static void
4698   vl_api_show_one_map_register_ttl_reply_t_handler
4699   (vl_api_show_one_map_register_ttl_reply_t * mp)
4700 {
4701   vat_main_t *vam = &vat_main;
4702   i32 retval = ntohl (mp->retval);
4703
4704   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4705
4706   if (0 <= retval)
4707     {
4708       print (vam->ofp, "ttl: %u", mp->ttl);
4709     }
4710
4711   vam->retval = retval;
4712   vam->result_ready = 1;
4713 }
4714
4715 static void
4716   vl_api_show_one_map_register_ttl_reply_t_handler_json
4717   (vl_api_show_one_map_register_ttl_reply_t * mp)
4718 {
4719   vat_main_t *vam = &vat_main;
4720   vat_json_node_t node;
4721
4722   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4723   vat_json_init_object (&node);
4724   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4725
4726   vat_json_print (vam->ofp, &node);
4727   vat_json_free (&node);
4728
4729   vam->retval = ntohl (mp->retval);
4730   vam->result_ready = 1;
4731 }
4732
4733 static void
4734 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   i32 retval = ntohl (mp->retval);
4738
4739   if (0 <= retval)
4740     {
4741       print (vam->ofp, "%-20s%-16s",
4742              mp->status ? "enabled" : "disabled",
4743              mp->status ? (char *) mp->locator_set_name : "");
4744     }
4745
4746   vam->retval = retval;
4747   vam->result_ready = 1;
4748 }
4749
4750 static void
4751 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4752 {
4753   vat_main_t *vam = &vat_main;
4754   vat_json_node_t node;
4755   u8 *status = 0;
4756
4757   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4758   vec_add1 (status, 0);
4759
4760   vat_json_init_object (&node);
4761   vat_json_object_add_string_copy (&node, "status", status);
4762   if (mp->status)
4763     {
4764       vat_json_object_add_string_copy (&node, "locator_set",
4765                                        mp->locator_set_name);
4766     }
4767
4768   vec_free (status);
4769
4770   vat_json_print (vam->ofp, &node);
4771   vat_json_free (&node);
4772
4773   vam->retval = ntohl (mp->retval);
4774   vam->result_ready = 1;
4775 }
4776
4777 static u8 *
4778 format_policer_type (u8 * s, va_list * va)
4779 {
4780   u32 i = va_arg (*va, u32);
4781
4782   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4783     s = format (s, "1r2c");
4784   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4785     s = format (s, "1r3c");
4786   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4787     s = format (s, "2r3c-2698");
4788   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4789     s = format (s, "2r3c-4115");
4790   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4791     s = format (s, "2r3c-mef5cf1");
4792   else
4793     s = format (s, "ILLEGAL");
4794   return s;
4795 }
4796
4797 static u8 *
4798 format_policer_rate_type (u8 * s, va_list * va)
4799 {
4800   u32 i = va_arg (*va, u32);
4801
4802   if (i == SSE2_QOS_RATE_KBPS)
4803     s = format (s, "kbps");
4804   else if (i == SSE2_QOS_RATE_PPS)
4805     s = format (s, "pps");
4806   else
4807     s = format (s, "ILLEGAL");
4808   return s;
4809 }
4810
4811 static u8 *
4812 format_policer_round_type (u8 * s, va_list * va)
4813 {
4814   u32 i = va_arg (*va, u32);
4815
4816   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4817     s = format (s, "closest");
4818   else if (i == SSE2_QOS_ROUND_TO_UP)
4819     s = format (s, "up");
4820   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4821     s = format (s, "down");
4822   else
4823     s = format (s, "ILLEGAL");
4824   return s;
4825 }
4826
4827 static u8 *
4828 format_policer_action_type (u8 * s, va_list * va)
4829 {
4830   u32 i = va_arg (*va, u32);
4831
4832   if (i == SSE2_QOS_ACTION_DROP)
4833     s = format (s, "drop");
4834   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4835     s = format (s, "transmit");
4836   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4837     s = format (s, "mark-and-transmit");
4838   else
4839     s = format (s, "ILLEGAL");
4840   return s;
4841 }
4842
4843 static u8 *
4844 format_dscp (u8 * s, va_list * va)
4845 {
4846   u32 i = va_arg (*va, u32);
4847   char *t = 0;
4848
4849   switch (i)
4850     {
4851 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4852       foreach_vnet_dscp
4853 #undef _
4854     default:
4855       return format (s, "ILLEGAL");
4856     }
4857   s = format (s, "%s", t);
4858   return s;
4859 }
4860
4861 static void
4862 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4863 {
4864   vat_main_t *vam = &vat_main;
4865   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4866
4867   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4868     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4869   else
4870     conform_dscp_str = format (0, "");
4871
4872   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4873     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4874   else
4875     exceed_dscp_str = format (0, "");
4876
4877   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4878     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4879   else
4880     violate_dscp_str = format (0, "");
4881
4882   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4883          "rate type %U, round type %U, %s rate, %s color-aware, "
4884          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4885          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4886          "conform action %U%s, exceed action %U%s, violate action %U%s",
4887          mp->name,
4888          format_policer_type, mp->type,
4889          ntohl (mp->cir),
4890          ntohl (mp->eir),
4891          clib_net_to_host_u64 (mp->cb),
4892          clib_net_to_host_u64 (mp->eb),
4893          format_policer_rate_type, mp->rate_type,
4894          format_policer_round_type, mp->round_type,
4895          mp->single_rate ? "single" : "dual",
4896          mp->color_aware ? "is" : "not",
4897          ntohl (mp->cir_tokens_per_period),
4898          ntohl (mp->pir_tokens_per_period),
4899          ntohl (mp->scale),
4900          ntohl (mp->current_limit),
4901          ntohl (mp->current_bucket),
4902          ntohl (mp->extended_limit),
4903          ntohl (mp->extended_bucket),
4904          clib_net_to_host_u64 (mp->last_update_time),
4905          format_policer_action_type, mp->conform_action_type,
4906          conform_dscp_str,
4907          format_policer_action_type, mp->exceed_action_type,
4908          exceed_dscp_str,
4909          format_policer_action_type, mp->violate_action_type,
4910          violate_dscp_str);
4911
4912   vec_free (conform_dscp_str);
4913   vec_free (exceed_dscp_str);
4914   vec_free (violate_dscp_str);
4915 }
4916
4917 static void vl_api_policer_details_t_handler_json
4918   (vl_api_policer_details_t * mp)
4919 {
4920   vat_main_t *vam = &vat_main;
4921   vat_json_node_t *node;
4922   u8 *rate_type_str, *round_type_str, *type_str;
4923   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4924
4925   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4926   round_type_str =
4927     format (0, "%U", format_policer_round_type, mp->round_type);
4928   type_str = format (0, "%U", format_policer_type, mp->type);
4929   conform_action_str = format (0, "%U", format_policer_action_type,
4930                                mp->conform_action_type);
4931   exceed_action_str = format (0, "%U", format_policer_action_type,
4932                               mp->exceed_action_type);
4933   violate_action_str = format (0, "%U", format_policer_action_type,
4934                                mp->violate_action_type);
4935
4936   if (VAT_JSON_ARRAY != vam->json_tree.type)
4937     {
4938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4939       vat_json_init_array (&vam->json_tree);
4940     }
4941   node = vat_json_array_add (&vam->json_tree);
4942
4943   vat_json_init_object (node);
4944   vat_json_object_add_string_copy (node, "name", mp->name);
4945   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4946   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4947   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4948   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4949   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4950   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4951   vat_json_object_add_string_copy (node, "type", type_str);
4952   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4953   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4954   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4955   vat_json_object_add_uint (node, "cir_tokens_per_period",
4956                             ntohl (mp->cir_tokens_per_period));
4957   vat_json_object_add_uint (node, "eir_tokens_per_period",
4958                             ntohl (mp->pir_tokens_per_period));
4959   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4960   vat_json_object_add_uint (node, "current_bucket",
4961                             ntohl (mp->current_bucket));
4962   vat_json_object_add_uint (node, "extended_limit",
4963                             ntohl (mp->extended_limit));
4964   vat_json_object_add_uint (node, "extended_bucket",
4965                             ntohl (mp->extended_bucket));
4966   vat_json_object_add_uint (node, "last_update_time",
4967                             ntohl (mp->last_update_time));
4968   vat_json_object_add_string_copy (node, "conform_action",
4969                                    conform_action_str);
4970   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4971     {
4972       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4973       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4974       vec_free (dscp_str);
4975     }
4976   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4977   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4978     {
4979       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4980       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4981       vec_free (dscp_str);
4982     }
4983   vat_json_object_add_string_copy (node, "violate_action",
4984                                    violate_action_str);
4985   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4986     {
4987       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4988       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4989       vec_free (dscp_str);
4990     }
4991
4992   vec_free (rate_type_str);
4993   vec_free (round_type_str);
4994   vec_free (type_str);
4995   vec_free (conform_action_str);
4996   vec_free (exceed_action_str);
4997   vec_free (violate_action_str);
4998 }
4999
5000 static void
5001 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5002                                            mp)
5003 {
5004   vat_main_t *vam = &vat_main;
5005   int i, count = ntohl (mp->count);
5006
5007   if (count > 0)
5008     print (vam->ofp, "classify table ids (%d) : ", count);
5009   for (i = 0; i < count; i++)
5010     {
5011       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5012       print (vam->ofp, (i < count - 1) ? "," : "");
5013     }
5014   vam->retval = ntohl (mp->retval);
5015   vam->result_ready = 1;
5016 }
5017
5018 static void
5019   vl_api_classify_table_ids_reply_t_handler_json
5020   (vl_api_classify_table_ids_reply_t * mp)
5021 {
5022   vat_main_t *vam = &vat_main;
5023   int i, count = ntohl (mp->count);
5024
5025   if (count > 0)
5026     {
5027       vat_json_node_t node;
5028
5029       vat_json_init_object (&node);
5030       for (i = 0; i < count; i++)
5031         {
5032           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5033         }
5034       vat_json_print (vam->ofp, &node);
5035       vat_json_free (&node);
5036     }
5037   vam->retval = ntohl (mp->retval);
5038   vam->result_ready = 1;
5039 }
5040
5041 static void
5042   vl_api_classify_table_by_interface_reply_t_handler
5043   (vl_api_classify_table_by_interface_reply_t * mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046   u32 table_id;
5047
5048   table_id = ntohl (mp->l2_table_id);
5049   if (table_id != ~0)
5050     print (vam->ofp, "l2 table id : %d", table_id);
5051   else
5052     print (vam->ofp, "l2 table id : No input ACL tables configured");
5053   table_id = ntohl (mp->ip4_table_id);
5054   if (table_id != ~0)
5055     print (vam->ofp, "ip4 table id : %d", table_id);
5056   else
5057     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5058   table_id = ntohl (mp->ip6_table_id);
5059   if (table_id != ~0)
5060     print (vam->ofp, "ip6 table id : %d", table_id);
5061   else
5062     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5063   vam->retval = ntohl (mp->retval);
5064   vam->result_ready = 1;
5065 }
5066
5067 static void
5068   vl_api_classify_table_by_interface_reply_t_handler_json
5069   (vl_api_classify_table_by_interface_reply_t * mp)
5070 {
5071   vat_main_t *vam = &vat_main;
5072   vat_json_node_t node;
5073
5074   vat_json_init_object (&node);
5075
5076   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5077   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5078   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5079
5080   vat_json_print (vam->ofp, &node);
5081   vat_json_free (&node);
5082
5083   vam->retval = ntohl (mp->retval);
5084   vam->result_ready = 1;
5085 }
5086
5087 static void vl_api_policer_add_del_reply_t_handler
5088   (vl_api_policer_add_del_reply_t * mp)
5089 {
5090   vat_main_t *vam = &vat_main;
5091   i32 retval = ntohl (mp->retval);
5092   if (vam->async_mode)
5093     {
5094       vam->async_errors += (retval < 0);
5095     }
5096   else
5097     {
5098       vam->retval = retval;
5099       vam->result_ready = 1;
5100       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5101         /*
5102          * Note: this is just barely thread-safe, depends on
5103          * the main thread spinning waiting for an answer...
5104          */
5105         errmsg ("policer index %d", ntohl (mp->policer_index));
5106     }
5107 }
5108
5109 static void vl_api_policer_add_del_reply_t_handler_json
5110   (vl_api_policer_add_del_reply_t * mp)
5111 {
5112   vat_main_t *vam = &vat_main;
5113   vat_json_node_t node;
5114
5115   vat_json_init_object (&node);
5116   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5117   vat_json_object_add_uint (&node, "policer_index",
5118                             ntohl (mp->policer_index));
5119
5120   vat_json_print (vam->ofp, &node);
5121   vat_json_free (&node);
5122
5123   vam->retval = ntohl (mp->retval);
5124   vam->result_ready = 1;
5125 }
5126
5127 /* Format hex dump. */
5128 u8 *
5129 format_hex_bytes (u8 * s, va_list * va)
5130 {
5131   u8 *bytes = va_arg (*va, u8 *);
5132   int n_bytes = va_arg (*va, int);
5133   uword i;
5134
5135   /* Print short or long form depending on byte count. */
5136   uword short_form = n_bytes <= 32;
5137   u32 indent = format_get_indent (s);
5138
5139   if (n_bytes == 0)
5140     return s;
5141
5142   for (i = 0; i < n_bytes; i++)
5143     {
5144       if (!short_form && (i % 32) == 0)
5145         s = format (s, "%08x: ", i);
5146       s = format (s, "%02x", bytes[i]);
5147       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5148         s = format (s, "\n%U", format_white_space, indent);
5149     }
5150
5151   return s;
5152 }
5153
5154 static void
5155 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5156                                             * mp)
5157 {
5158   vat_main_t *vam = &vat_main;
5159   i32 retval = ntohl (mp->retval);
5160   if (retval == 0)
5161     {
5162       print (vam->ofp, "classify table info :");
5163       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5164              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5165              ntohl (mp->miss_next_index));
5166       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5167              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5168              ntohl (mp->match_n_vectors));
5169       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5170              ntohl (mp->mask_length));
5171     }
5172   vam->retval = retval;
5173   vam->result_ready = 1;
5174 }
5175
5176 static void
5177   vl_api_classify_table_info_reply_t_handler_json
5178   (vl_api_classify_table_info_reply_t * mp)
5179 {
5180   vat_main_t *vam = &vat_main;
5181   vat_json_node_t node;
5182
5183   i32 retval = ntohl (mp->retval);
5184   if (retval == 0)
5185     {
5186       vat_json_init_object (&node);
5187
5188       vat_json_object_add_int (&node, "sessions",
5189                                ntohl (mp->active_sessions));
5190       vat_json_object_add_int (&node, "nexttbl",
5191                                ntohl (mp->next_table_index));
5192       vat_json_object_add_int (&node, "nextnode",
5193                                ntohl (mp->miss_next_index));
5194       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5195       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5196       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5197       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5198                       ntohl (mp->mask_length), 0);
5199       vat_json_object_add_string_copy (&node, "mask", s);
5200
5201       vat_json_print (vam->ofp, &node);
5202       vat_json_free (&node);
5203     }
5204   vam->retval = ntohl (mp->retval);
5205   vam->result_ready = 1;
5206 }
5207
5208 static void
5209 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5210                                            mp)
5211 {
5212   vat_main_t *vam = &vat_main;
5213
5214   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5215          ntohl (mp->hit_next_index), ntohl (mp->advance),
5216          ntohl (mp->opaque_index));
5217   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5218          ntohl (mp->match_length));
5219 }
5220
5221 static void
5222   vl_api_classify_session_details_t_handler_json
5223   (vl_api_classify_session_details_t * mp)
5224 {
5225   vat_main_t *vam = &vat_main;
5226   vat_json_node_t *node = NULL;
5227
5228   if (VAT_JSON_ARRAY != vam->json_tree.type)
5229     {
5230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5231       vat_json_init_array (&vam->json_tree);
5232     }
5233   node = vat_json_array_add (&vam->json_tree);
5234
5235   vat_json_init_object (node);
5236   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5237   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5238   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5239   u8 *s =
5240     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5241             0);
5242   vat_json_object_add_string_copy (node, "match", s);
5243 }
5244
5245 static void vl_api_pg_create_interface_reply_t_handler
5246   (vl_api_pg_create_interface_reply_t * mp)
5247 {
5248   vat_main_t *vam = &vat_main;
5249
5250   vam->retval = ntohl (mp->retval);
5251   vam->result_ready = 1;
5252 }
5253
5254 static void vl_api_pg_create_interface_reply_t_handler_json
5255   (vl_api_pg_create_interface_reply_t * mp)
5256 {
5257   vat_main_t *vam = &vat_main;
5258   vat_json_node_t node;
5259
5260   i32 retval = ntohl (mp->retval);
5261   if (retval == 0)
5262     {
5263       vat_json_init_object (&node);
5264
5265       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5266
5267       vat_json_print (vam->ofp, &node);
5268       vat_json_free (&node);
5269     }
5270   vam->retval = ntohl (mp->retval);
5271   vam->result_ready = 1;
5272 }
5273
5274 static void vl_api_policer_classify_details_t_handler
5275   (vl_api_policer_classify_details_t * mp)
5276 {
5277   vat_main_t *vam = &vat_main;
5278
5279   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5280          ntohl (mp->table_index));
5281 }
5282
5283 static void vl_api_policer_classify_details_t_handler_json
5284   (vl_api_policer_classify_details_t * mp)
5285 {
5286   vat_main_t *vam = &vat_main;
5287   vat_json_node_t *node;
5288
5289   if (VAT_JSON_ARRAY != vam->json_tree.type)
5290     {
5291       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5292       vat_json_init_array (&vam->json_tree);
5293     }
5294   node = vat_json_array_add (&vam->json_tree);
5295
5296   vat_json_init_object (node);
5297   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5298   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5299 }
5300
5301 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5302   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5303 {
5304   vat_main_t *vam = &vat_main;
5305   i32 retval = ntohl (mp->retval);
5306   if (vam->async_mode)
5307     {
5308       vam->async_errors += (retval < 0);
5309     }
5310   else
5311     {
5312       vam->retval = retval;
5313       vam->sw_if_index = ntohl (mp->sw_if_index);
5314       vam->result_ready = 1;
5315     }
5316   vam->regenerate_interface_table = 1;
5317 }
5318
5319 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5320   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5321 {
5322   vat_main_t *vam = &vat_main;
5323   vat_json_node_t node;
5324
5325   vat_json_init_object (&node);
5326   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5327   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5328
5329   vat_json_print (vam->ofp, &node);
5330   vat_json_free (&node);
5331
5332   vam->retval = ntohl (mp->retval);
5333   vam->result_ready = 1;
5334 }
5335
5336 static void vl_api_flow_classify_details_t_handler
5337   (vl_api_flow_classify_details_t * mp)
5338 {
5339   vat_main_t *vam = &vat_main;
5340
5341   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5342          ntohl (mp->table_index));
5343 }
5344
5345 static void vl_api_flow_classify_details_t_handler_json
5346   (vl_api_flow_classify_details_t * mp)
5347 {
5348   vat_main_t *vam = &vat_main;
5349   vat_json_node_t *node;
5350
5351   if (VAT_JSON_ARRAY != vam->json_tree.type)
5352     {
5353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5354       vat_json_init_array (&vam->json_tree);
5355     }
5356   node = vat_json_array_add (&vam->json_tree);
5357
5358   vat_json_init_object (node);
5359   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5360   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5361 }
5362
5363 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5364 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5365 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5366 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5367 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5368 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5369 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5370 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5371 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5372 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5373 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5374 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5375 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5376 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5377 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5378 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5379 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5380 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5381 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5382 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5383 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5384 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5385
5386 /*
5387  * Generate boilerplate reply handlers, which
5388  * dig the return value out of the xxx_reply_t API message,
5389  * stick it into vam->retval, and set vam->result_ready
5390  *
5391  * Could also do this by pointing N message decode slots at
5392  * a single function, but that could break in subtle ways.
5393  */
5394
5395 #define foreach_standard_reply_retval_handler           \
5396 _(sw_interface_set_flags_reply)                         \
5397 _(sw_interface_add_del_address_reply)                   \
5398 _(sw_interface_set_rx_mode_reply)                       \
5399 _(sw_interface_set_table_reply)                         \
5400 _(sw_interface_set_mpls_enable_reply)                   \
5401 _(sw_interface_set_vpath_reply)                         \
5402 _(sw_interface_set_vxlan_bypass_reply)                  \
5403 _(sw_interface_set_geneve_bypass_reply)                 \
5404 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5405 _(sw_interface_set_l2_bridge_reply)                     \
5406 _(bridge_domain_add_del_reply)                          \
5407 _(sw_interface_set_l2_xconnect_reply)                   \
5408 _(l2fib_add_del_reply)                                  \
5409 _(l2fib_flush_int_reply)                                \
5410 _(l2fib_flush_bd_reply)                                 \
5411 _(ip_add_del_route_reply)                               \
5412 _(ip_table_add_del_reply)                               \
5413 _(ip_mroute_add_del_reply)                              \
5414 _(mpls_route_add_del_reply)                             \
5415 _(mpls_table_add_del_reply)                             \
5416 _(mpls_ip_bind_unbind_reply)                            \
5417 _(bier_route_add_del_reply)                             \
5418 _(bier_table_add_del_reply)                             \
5419 _(proxy_arp_add_del_reply)                              \
5420 _(proxy_arp_intfc_enable_disable_reply)                 \
5421 _(sw_interface_set_unnumbered_reply)                    \
5422 _(ip_neighbor_add_del_reply)                            \
5423 _(oam_add_del_reply)                                    \
5424 _(reset_fib_reply)                                      \
5425 _(dhcp_proxy_config_reply)                              \
5426 _(dhcp_proxy_set_vss_reply)                             \
5427 _(dhcp_client_config_reply)                             \
5428 _(set_ip_flow_hash_reply)                               \
5429 _(sw_interface_ip6_enable_disable_reply)                \
5430 _(sw_interface_ip6_set_link_local_address_reply)        \
5431 _(ip6nd_proxy_add_del_reply)                            \
5432 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5433 _(sw_interface_ip6nd_ra_config_reply)                   \
5434 _(set_arp_neighbor_limit_reply)                         \
5435 _(l2_patch_add_del_reply)                               \
5436 _(sr_policy_add_reply)                                  \
5437 _(sr_policy_mod_reply)                                  \
5438 _(sr_policy_del_reply)                                  \
5439 _(sr_localsid_add_del_reply)                            \
5440 _(sr_steering_add_del_reply)                            \
5441 _(classify_add_del_session_reply)                       \
5442 _(classify_set_interface_ip_table_reply)                \
5443 _(classify_set_interface_l2_tables_reply)               \
5444 _(l2tpv3_set_tunnel_cookies_reply)                      \
5445 _(l2tpv3_interface_enable_disable_reply)                \
5446 _(l2tpv3_set_lookup_key_reply)                          \
5447 _(l2_fib_clear_table_reply)                             \
5448 _(l2_interface_efp_filter_reply)                        \
5449 _(l2_interface_vlan_tag_rewrite_reply)                  \
5450 _(modify_vhost_user_if_reply)                           \
5451 _(delete_vhost_user_if_reply)                           \
5452 _(ip_probe_neighbor_reply)                              \
5453 _(want_ip4_arp_events_reply)                            \
5454 _(want_ip6_nd_events_reply)                             \
5455 _(want_l2_macs_events_reply)                            \
5456 _(input_acl_set_interface_reply)                        \
5457 _(ipsec_spd_add_del_reply)                              \
5458 _(ipsec_interface_add_del_spd_reply)                    \
5459 _(ipsec_spd_add_del_entry_reply)                        \
5460 _(ipsec_sad_add_del_entry_reply)                        \
5461 _(ipsec_sa_set_key_reply)                               \
5462 _(ipsec_tunnel_if_add_del_reply)                        \
5463 _(ipsec_tunnel_if_set_key_reply)                        \
5464 _(ipsec_tunnel_if_set_sa_reply)                         \
5465 _(ikev2_profile_add_del_reply)                          \
5466 _(ikev2_profile_set_auth_reply)                         \
5467 _(ikev2_profile_set_id_reply)                           \
5468 _(ikev2_profile_set_ts_reply)                           \
5469 _(ikev2_set_local_key_reply)                            \
5470 _(ikev2_set_responder_reply)                            \
5471 _(ikev2_set_ike_transforms_reply)                       \
5472 _(ikev2_set_esp_transforms_reply)                       \
5473 _(ikev2_set_sa_lifetime_reply)                          \
5474 _(ikev2_initiate_sa_init_reply)                         \
5475 _(ikev2_initiate_del_ike_sa_reply)                      \
5476 _(ikev2_initiate_del_child_sa_reply)                    \
5477 _(ikev2_initiate_rekey_child_sa_reply)                  \
5478 _(delete_loopback_reply)                                \
5479 _(bd_ip_mac_add_del_reply)                              \
5480 _(map_del_domain_reply)                                 \
5481 _(map_add_del_rule_reply)                               \
5482 _(want_interface_events_reply)                          \
5483 _(want_stats_reply)                                     \
5484 _(cop_interface_enable_disable_reply)                   \
5485 _(cop_whitelist_enable_disable_reply)                   \
5486 _(sw_interface_clear_stats_reply)                       \
5487 _(ioam_enable_reply)                                    \
5488 _(ioam_disable_reply)                                   \
5489 _(one_add_del_locator_reply)                            \
5490 _(one_add_del_local_eid_reply)                          \
5491 _(one_add_del_remote_mapping_reply)                     \
5492 _(one_add_del_adjacency_reply)                          \
5493 _(one_add_del_map_resolver_reply)                       \
5494 _(one_add_del_map_server_reply)                         \
5495 _(one_enable_disable_reply)                             \
5496 _(one_rloc_probe_enable_disable_reply)                  \
5497 _(one_map_register_enable_disable_reply)                \
5498 _(one_map_register_set_ttl_reply)                       \
5499 _(one_set_transport_protocol_reply)                     \
5500 _(one_map_register_fallback_threshold_reply)            \
5501 _(one_pitr_set_locator_set_reply)                       \
5502 _(one_map_request_mode_reply)                           \
5503 _(one_add_del_map_request_itr_rlocs_reply)              \
5504 _(one_eid_table_add_del_map_reply)                      \
5505 _(one_use_petr_reply)                                   \
5506 _(one_stats_enable_disable_reply)                       \
5507 _(one_add_del_l2_arp_entry_reply)                       \
5508 _(one_add_del_ndp_entry_reply)                          \
5509 _(one_stats_flush_reply)                                \
5510 _(one_enable_disable_xtr_mode_reply)                    \
5511 _(one_enable_disable_pitr_mode_reply)                   \
5512 _(one_enable_disable_petr_mode_reply)                   \
5513 _(gpe_enable_disable_reply)                             \
5514 _(gpe_set_encap_mode_reply)                             \
5515 _(gpe_add_del_iface_reply)                              \
5516 _(gpe_add_del_native_fwd_rpath_reply)                   \
5517 _(af_packet_delete_reply)                               \
5518 _(policer_classify_set_interface_reply)                 \
5519 _(netmap_create_reply)                                  \
5520 _(netmap_delete_reply)                                  \
5521 _(set_ipfix_exporter_reply)                             \
5522 _(set_ipfix_classify_stream_reply)                      \
5523 _(ipfix_classify_table_add_del_reply)                   \
5524 _(flow_classify_set_interface_reply)                    \
5525 _(sw_interface_span_enable_disable_reply)               \
5526 _(pg_capture_reply)                                     \
5527 _(pg_enable_disable_reply)                              \
5528 _(ip_source_and_port_range_check_add_del_reply)         \
5529 _(ip_source_and_port_range_check_interface_add_del_reply)\
5530 _(delete_subif_reply)                                   \
5531 _(l2_interface_pbb_tag_rewrite_reply)                   \
5532 _(punt_reply)                                           \
5533 _(feature_enable_disable_reply)                         \
5534 _(sw_interface_tag_add_del_reply)                       \
5535 _(sw_interface_set_mtu_reply)                           \
5536 _(p2p_ethernet_add_reply)                               \
5537 _(p2p_ethernet_del_reply)                               \
5538 _(lldp_config_reply)                                    \
5539 _(sw_interface_set_lldp_reply)                          \
5540 _(tcp_configure_src_addresses_reply)                    \
5541 _(dns_enable_disable_reply)                             \
5542 _(dns_name_server_add_del_reply)                        \
5543 _(session_rule_add_del_reply)                           \
5544 _(ip_container_proxy_add_del_reply)                     \
5545 _(output_acl_set_interface_reply)                       \
5546 _(qos_record_enable_disable_reply)
5547
5548 #define _(n)                                    \
5549     static void vl_api_##n##_t_handler          \
5550     (vl_api_##n##_t * mp)                       \
5551     {                                           \
5552         vat_main_t * vam = &vat_main;           \
5553         i32 retval = ntohl(mp->retval);         \
5554         if (vam->async_mode) {                  \
5555             vam->async_errors += (retval < 0);  \
5556         } else {                                \
5557             vam->retval = retval;               \
5558             vam->result_ready = 1;              \
5559         }                                       \
5560     }
5561 foreach_standard_reply_retval_handler;
5562 #undef _
5563
5564 #define _(n)                                    \
5565     static void vl_api_##n##_t_handler_json     \
5566     (vl_api_##n##_t * mp)                       \
5567     {                                           \
5568         vat_main_t * vam = &vat_main;           \
5569         vat_json_node_t node;                   \
5570         vat_json_init_object(&node);            \
5571         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5572         vat_json_print(vam->ofp, &node);        \
5573         vam->retval = ntohl(mp->retval);        \
5574         vam->result_ready = 1;                  \
5575     }
5576 foreach_standard_reply_retval_handler;
5577 #undef _
5578
5579 /*
5580  * Table of message reply handlers, must include boilerplate handlers
5581  * we just generated
5582  */
5583
5584 #define foreach_vpe_api_reply_msg                                       \
5585 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5586 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5587 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5588 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5589 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5590 _(CLI_REPLY, cli_reply)                                                 \
5591 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5592 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5593   sw_interface_add_del_address_reply)                                   \
5594 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5595 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5596 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5597 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5598 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5599 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5600 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5601 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5602   sw_interface_set_l2_xconnect_reply)                                   \
5603 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5604   sw_interface_set_l2_bridge_reply)                                     \
5605 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5606 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5607 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5608 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5609 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5610 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5611 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5612 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5613 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5614 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5615 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5616 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5617 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5618 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5619 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5620 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5621 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5622 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5623 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5624 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5625 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5626 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5627 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5628 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5629 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5630 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5631 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5632 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5633 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5634 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5635 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5636   proxy_arp_intfc_enable_disable_reply)                                 \
5637 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5638 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5639   sw_interface_set_unnumbered_reply)                                    \
5640 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5641 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5642 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5643 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5644 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5645 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5646 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5647 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5648 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5649 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5650 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5651   sw_interface_ip6_enable_disable_reply)                                \
5652 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5653   sw_interface_ip6_set_link_local_address_reply)                        \
5654 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5655 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5656 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5657   sw_interface_ip6nd_ra_prefix_reply)                                   \
5658 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5659   sw_interface_ip6nd_ra_config_reply)                                   \
5660 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5661 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5662 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5663 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5664 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5665 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5666 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5667 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5668 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5669 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5670 classify_set_interface_ip_table_reply)                                  \
5671 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5672   classify_set_interface_l2_tables_reply)                               \
5673 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5674 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5675 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5676 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5677 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5678   l2tpv3_interface_enable_disable_reply)                                \
5679 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5680 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5681 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5682 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5683 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5684 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5685 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5686 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5687 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5688 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5689 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5690 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5691 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5692 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5693 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5694 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5695 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5696 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5697 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5698 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5699 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5700 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5701 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5702 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5703 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5704 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5705 _(L2_MACS_EVENT, l2_macs_event)                                         \
5706 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5707 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5708 _(IP_DETAILS, ip_details)                                               \
5709 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5710 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5711 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5712 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5713 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5714 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5715 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5716 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5717 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5718 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5719 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5720 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5721 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5722 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5723 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5724 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5725 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5726 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5727 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5728 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5729 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5730 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5731 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5732 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5733 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5734 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5735 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5736 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5737 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5738 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5739 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5740 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5741 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5742 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5743 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5744 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5745 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5746 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5747 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5748 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5749 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5750 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5751 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5752 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5753 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5754 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5755 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5756 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5757   one_map_register_enable_disable_reply)                                \
5758 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5759 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5760 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5761 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5762   one_map_register_fallback_threshold_reply)                            \
5763 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5764   one_rloc_probe_enable_disable_reply)                                  \
5765 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5766 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5767 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5768 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5769 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5770 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5771 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5772 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5773 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5774 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5775 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5776 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5777 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5778 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5779 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5780 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5781   show_one_stats_enable_disable_reply)                                  \
5782 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5783 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5784 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5785 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5786 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5787 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5788 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5789 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5790   one_enable_disable_pitr_mode_reply)                                   \
5791 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5792   one_enable_disable_petr_mode_reply)                                   \
5793 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5794 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5795 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5796 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5797 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5798 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5799 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5800 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5801 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5802 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5803 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5804 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5805   gpe_add_del_native_fwd_rpath_reply)                                   \
5806 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5807   gpe_fwd_entry_path_details)                                           \
5808 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5809 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5810   one_add_del_map_request_itr_rlocs_reply)                              \
5811 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5812   one_get_map_request_itr_rlocs_reply)                                  \
5813 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5814 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5815 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5816 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5817 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5818 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5819   show_one_map_register_state_reply)                                    \
5820 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5821 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5822   show_one_map_register_fallback_threshold_reply)                       \
5823 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5824 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5825 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5826 _(POLICER_DETAILS, policer_details)                                     \
5827 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5828 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5829 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5830 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5831 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5832 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5833 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5834 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5835 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5836 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5837 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5838 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5839 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5840 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5841 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5842 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5843 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5844 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5845 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5846 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5847 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5848 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5849 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5850 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5851 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5852  ip_source_and_port_range_check_add_del_reply)                          \
5853 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5854  ip_source_and_port_range_check_interface_add_del_reply)                \
5855 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5856 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5857 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5858 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5859 _(PUNT_REPLY, punt_reply)                                               \
5860 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5861 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5862 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5863 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5864 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5865 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5866 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5867 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5868 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5869 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5870 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5871 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5872 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5873 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5874 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5875 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5876 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5877 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5878 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5879 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5880 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5881 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5882 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5883
5884 #define foreach_standalone_reply_msg                                    \
5885 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5886 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5887 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5888 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5889 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5890 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5891 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5892
5893 typedef struct
5894 {
5895   u8 *name;
5896   u32 value;
5897 } name_sort_t;
5898
5899 #define STR_VTR_OP_CASE(op)     \
5900     case L2_VTR_ ## op:         \
5901         return "" # op;
5902
5903 static const char *
5904 str_vtr_op (u32 vtr_op)
5905 {
5906   switch (vtr_op)
5907     {
5908       STR_VTR_OP_CASE (DISABLED);
5909       STR_VTR_OP_CASE (PUSH_1);
5910       STR_VTR_OP_CASE (PUSH_2);
5911       STR_VTR_OP_CASE (POP_1);
5912       STR_VTR_OP_CASE (POP_2);
5913       STR_VTR_OP_CASE (TRANSLATE_1_1);
5914       STR_VTR_OP_CASE (TRANSLATE_1_2);
5915       STR_VTR_OP_CASE (TRANSLATE_2_1);
5916       STR_VTR_OP_CASE (TRANSLATE_2_2);
5917     }
5918
5919   return "UNKNOWN";
5920 }
5921
5922 static int
5923 dump_sub_interface_table (vat_main_t * vam)
5924 {
5925   const sw_interface_subif_t *sub = NULL;
5926
5927   if (vam->json_output)
5928     {
5929       clib_warning
5930         ("JSON output supported only for VPE API calls and dump_stats_table");
5931       return -99;
5932     }
5933
5934   print (vam->ofp,
5935          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5936          "Interface", "sw_if_index",
5937          "sub id", "dot1ad", "tags", "outer id",
5938          "inner id", "exact", "default", "outer any", "inner any");
5939
5940   vec_foreach (sub, vam->sw_if_subif_table)
5941   {
5942     print (vam->ofp,
5943            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5944            sub->interface_name,
5945            sub->sw_if_index,
5946            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5947            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5948            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5949            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5950     if (sub->vtr_op != L2_VTR_DISABLED)
5951       {
5952         print (vam->ofp,
5953                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5954                "tag1: %d tag2: %d ]",
5955                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5956                sub->vtr_tag1, sub->vtr_tag2);
5957       }
5958   }
5959
5960   return 0;
5961 }
5962
5963 static int
5964 name_sort_cmp (void *a1, void *a2)
5965 {
5966   name_sort_t *n1 = a1;
5967   name_sort_t *n2 = a2;
5968
5969   return strcmp ((char *) n1->name, (char *) n2->name);
5970 }
5971
5972 static int
5973 dump_interface_table (vat_main_t * vam)
5974 {
5975   hash_pair_t *p;
5976   name_sort_t *nses = 0, *ns;
5977
5978   if (vam->json_output)
5979     {
5980       clib_warning
5981         ("JSON output supported only for VPE API calls and dump_stats_table");
5982       return -99;
5983     }
5984
5985   /* *INDENT-OFF* */
5986   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5987   ({
5988     vec_add2 (nses, ns, 1);
5989     ns->name = (u8 *)(p->key);
5990     ns->value = (u32) p->value[0];
5991   }));
5992   /* *INDENT-ON* */
5993
5994   vec_sort_with_function (nses, name_sort_cmp);
5995
5996   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5997   vec_foreach (ns, nses)
5998   {
5999     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6000   }
6001   vec_free (nses);
6002   return 0;
6003 }
6004
6005 static int
6006 dump_ip_table (vat_main_t * vam, int is_ipv6)
6007 {
6008   const ip_details_t *det = NULL;
6009   const ip_address_details_t *address = NULL;
6010   u32 i = ~0;
6011
6012   print (vam->ofp, "%-12s", "sw_if_index");
6013
6014   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6015   {
6016     i++;
6017     if (!det->present)
6018       {
6019         continue;
6020       }
6021     print (vam->ofp, "%-12d", i);
6022     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6023     if (!det->addr)
6024       {
6025         continue;
6026       }
6027     vec_foreach (address, det->addr)
6028     {
6029       print (vam->ofp,
6030              "            %-30U%-13d",
6031              is_ipv6 ? format_ip6_address : format_ip4_address,
6032              address->ip, address->prefix_length);
6033     }
6034   }
6035
6036   return 0;
6037 }
6038
6039 static int
6040 dump_ipv4_table (vat_main_t * vam)
6041 {
6042   if (vam->json_output)
6043     {
6044       clib_warning
6045         ("JSON output supported only for VPE API calls and dump_stats_table");
6046       return -99;
6047     }
6048
6049   return dump_ip_table (vam, 0);
6050 }
6051
6052 static int
6053 dump_ipv6_table (vat_main_t * vam)
6054 {
6055   if (vam->json_output)
6056     {
6057       clib_warning
6058         ("JSON output supported only for VPE API calls and dump_stats_table");
6059       return -99;
6060     }
6061
6062   return dump_ip_table (vam, 1);
6063 }
6064
6065 static char *
6066 counter_type_to_str (u8 counter_type, u8 is_combined)
6067 {
6068   if (!is_combined)
6069     {
6070       switch (counter_type)
6071         {
6072         case VNET_INTERFACE_COUNTER_DROP:
6073           return "drop";
6074         case VNET_INTERFACE_COUNTER_PUNT:
6075           return "punt";
6076         case VNET_INTERFACE_COUNTER_IP4:
6077           return "ip4";
6078         case VNET_INTERFACE_COUNTER_IP6:
6079           return "ip6";
6080         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6081           return "rx-no-buf";
6082         case VNET_INTERFACE_COUNTER_RX_MISS:
6083           return "rx-miss";
6084         case VNET_INTERFACE_COUNTER_RX_ERROR:
6085           return "rx-error";
6086         case VNET_INTERFACE_COUNTER_TX_ERROR:
6087           return "tx-error";
6088         default:
6089           return "INVALID-COUNTER-TYPE";
6090         }
6091     }
6092   else
6093     {
6094       switch (counter_type)
6095         {
6096         case VNET_INTERFACE_COUNTER_RX:
6097           return "rx";
6098         case VNET_INTERFACE_COUNTER_TX:
6099           return "tx";
6100         default:
6101           return "INVALID-COUNTER-TYPE";
6102         }
6103     }
6104 }
6105
6106 static int
6107 dump_stats_table (vat_main_t * vam)
6108 {
6109   vat_json_node_t node;
6110   vat_json_node_t *msg_array;
6111   vat_json_node_t *msg;
6112   vat_json_node_t *counter_array;
6113   vat_json_node_t *counter;
6114   interface_counter_t c;
6115   u64 packets;
6116   ip4_fib_counter_t *c4;
6117   ip6_fib_counter_t *c6;
6118   ip4_nbr_counter_t *n4;
6119   ip6_nbr_counter_t *n6;
6120   int i, j;
6121
6122   if (!vam->json_output)
6123     {
6124       clib_warning ("dump_stats_table supported only in JSON format");
6125       return -99;
6126     }
6127
6128   vat_json_init_object (&node);
6129
6130   /* interface counters */
6131   msg_array = vat_json_object_add (&node, "interface_counters");
6132   vat_json_init_array (msg_array);
6133   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6134     {
6135       msg = vat_json_array_add (msg_array);
6136       vat_json_init_object (msg);
6137       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6138                                        (u8 *) counter_type_to_str (i, 0));
6139       vat_json_object_add_int (msg, "is_combined", 0);
6140       counter_array = vat_json_object_add (msg, "data");
6141       vat_json_init_array (counter_array);
6142       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6143         {
6144           packets = vam->simple_interface_counters[i][j];
6145           vat_json_array_add_uint (counter_array, packets);
6146         }
6147     }
6148   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6149     {
6150       msg = vat_json_array_add (msg_array);
6151       vat_json_init_object (msg);
6152       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6153                                        (u8 *) counter_type_to_str (i, 1));
6154       vat_json_object_add_int (msg, "is_combined", 1);
6155       counter_array = vat_json_object_add (msg, "data");
6156       vat_json_init_array (counter_array);
6157       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6158         {
6159           c = vam->combined_interface_counters[i][j];
6160           counter = vat_json_array_add (counter_array);
6161           vat_json_init_object (counter);
6162           vat_json_object_add_uint (counter, "packets", c.packets);
6163           vat_json_object_add_uint (counter, "bytes", c.bytes);
6164         }
6165     }
6166
6167   /* ip4 fib counters */
6168   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6169   vat_json_init_array (msg_array);
6170   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6171     {
6172       msg = vat_json_array_add (msg_array);
6173       vat_json_init_object (msg);
6174       vat_json_object_add_uint (msg, "vrf_id",
6175                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6176       counter_array = vat_json_object_add (msg, "c");
6177       vat_json_init_array (counter_array);
6178       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6179         {
6180           counter = vat_json_array_add (counter_array);
6181           vat_json_init_object (counter);
6182           c4 = &vam->ip4_fib_counters[i][j];
6183           vat_json_object_add_ip4 (counter, "address", c4->address);
6184           vat_json_object_add_uint (counter, "address_length",
6185                                     c4->address_length);
6186           vat_json_object_add_uint (counter, "packets", c4->packets);
6187           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6188         }
6189     }
6190
6191   /* ip6 fib counters */
6192   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6193   vat_json_init_array (msg_array);
6194   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6195     {
6196       msg = vat_json_array_add (msg_array);
6197       vat_json_init_object (msg);
6198       vat_json_object_add_uint (msg, "vrf_id",
6199                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6200       counter_array = vat_json_object_add (msg, "c");
6201       vat_json_init_array (counter_array);
6202       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6203         {
6204           counter = vat_json_array_add (counter_array);
6205           vat_json_init_object (counter);
6206           c6 = &vam->ip6_fib_counters[i][j];
6207           vat_json_object_add_ip6 (counter, "address", c6->address);
6208           vat_json_object_add_uint (counter, "address_length",
6209                                     c6->address_length);
6210           vat_json_object_add_uint (counter, "packets", c6->packets);
6211           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6212         }
6213     }
6214
6215   /* ip4 nbr counters */
6216   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6217   vat_json_init_array (msg_array);
6218   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6219     {
6220       msg = vat_json_array_add (msg_array);
6221       vat_json_init_object (msg);
6222       vat_json_object_add_uint (msg, "sw_if_index", i);
6223       counter_array = vat_json_object_add (msg, "c");
6224       vat_json_init_array (counter_array);
6225       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6226         {
6227           counter = vat_json_array_add (counter_array);
6228           vat_json_init_object (counter);
6229           n4 = &vam->ip4_nbr_counters[i][j];
6230           vat_json_object_add_ip4 (counter, "address", n4->address);
6231           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6232           vat_json_object_add_uint (counter, "packets", n4->packets);
6233           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6234         }
6235     }
6236
6237   /* ip6 nbr counters */
6238   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6239   vat_json_init_array (msg_array);
6240   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6241     {
6242       msg = vat_json_array_add (msg_array);
6243       vat_json_init_object (msg);
6244       vat_json_object_add_uint (msg, "sw_if_index", i);
6245       counter_array = vat_json_object_add (msg, "c");
6246       vat_json_init_array (counter_array);
6247       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6248         {
6249           counter = vat_json_array_add (counter_array);
6250           vat_json_init_object (counter);
6251           n6 = &vam->ip6_nbr_counters[i][j];
6252           vat_json_object_add_ip6 (counter, "address", n6->address);
6253           vat_json_object_add_uint (counter, "packets", n6->packets);
6254           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6255         }
6256     }
6257
6258   vat_json_print (vam->ofp, &node);
6259   vat_json_free (&node);
6260
6261   return 0;
6262 }
6263
6264 /*
6265  * Pass CLI buffers directly in the CLI_INBAND API message,
6266  * instead of an additional shared memory area.
6267  */
6268 static int
6269 exec_inband (vat_main_t * vam)
6270 {
6271   vl_api_cli_inband_t *mp;
6272   unformat_input_t *i = vam->input;
6273   int ret;
6274
6275   if (vec_len (i->buffer) == 0)
6276     return -1;
6277
6278   if (vam->exec_mode == 0 && unformat (i, "mode"))
6279     {
6280       vam->exec_mode = 1;
6281       return 0;
6282     }
6283   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6284     {
6285       vam->exec_mode = 0;
6286       return 0;
6287     }
6288
6289   /*
6290    * In order for the CLI command to work, it
6291    * must be a vector ending in \n, not a C-string ending
6292    * in \n\0.
6293    */
6294   u32 len = vec_len (vam->input->buffer);
6295   M2 (CLI_INBAND, mp, len);
6296   clib_memcpy (mp->cmd, vam->input->buffer, len);
6297   mp->length = htonl (len);
6298
6299   S (mp);
6300   W (ret);
6301   /* json responses may or may not include a useful reply... */
6302   if (vec_len (vam->cmd_reply))
6303     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6304   return ret;
6305 }
6306
6307 int
6308 exec (vat_main_t * vam)
6309 {
6310   return exec_inband (vam);
6311 }
6312
6313 static int
6314 api_create_loopback (vat_main_t * vam)
6315 {
6316   unformat_input_t *i = vam->input;
6317   vl_api_create_loopback_t *mp;
6318   vl_api_create_loopback_instance_t *mp_lbi;
6319   u8 mac_address[6];
6320   u8 mac_set = 0;
6321   u8 is_specified = 0;
6322   u32 user_instance = 0;
6323   int ret;
6324
6325   memset (mac_address, 0, sizeof (mac_address));
6326
6327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6328     {
6329       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6330         mac_set = 1;
6331       if (unformat (i, "instance %d", &user_instance))
6332         is_specified = 1;
6333       else
6334         break;
6335     }
6336
6337   if (is_specified)
6338     {
6339       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6340       mp_lbi->is_specified = is_specified;
6341       if (is_specified)
6342         mp_lbi->user_instance = htonl (user_instance);
6343       if (mac_set)
6344         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6345       S (mp_lbi);
6346     }
6347   else
6348     {
6349       /* Construct the API message */
6350       M (CREATE_LOOPBACK, mp);
6351       if (mac_set)
6352         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6353       S (mp);
6354     }
6355
6356   W (ret);
6357   return ret;
6358 }
6359
6360 static int
6361 api_delete_loopback (vat_main_t * vam)
6362 {
6363   unformat_input_t *i = vam->input;
6364   vl_api_delete_loopback_t *mp;
6365   u32 sw_if_index = ~0;
6366   int ret;
6367
6368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6369     {
6370       if (unformat (i, "sw_if_index %d", &sw_if_index))
6371         ;
6372       else
6373         break;
6374     }
6375
6376   if (sw_if_index == ~0)
6377     {
6378       errmsg ("missing sw_if_index");
6379       return -99;
6380     }
6381
6382   /* Construct the API message */
6383   M (DELETE_LOOPBACK, mp);
6384   mp->sw_if_index = ntohl (sw_if_index);
6385
6386   S (mp);
6387   W (ret);
6388   return ret;
6389 }
6390
6391 static int
6392 api_want_stats (vat_main_t * vam)
6393 {
6394   unformat_input_t *i = vam->input;
6395   vl_api_want_stats_t *mp;
6396   int enable = -1;
6397   int ret;
6398
6399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6400     {
6401       if (unformat (i, "enable"))
6402         enable = 1;
6403       else if (unformat (i, "disable"))
6404         enable = 0;
6405       else
6406         break;
6407     }
6408
6409   if (enable == -1)
6410     {
6411       errmsg ("missing enable|disable");
6412       return -99;
6413     }
6414
6415   M (WANT_STATS, mp);
6416   mp->enable_disable = enable;
6417
6418   S (mp);
6419   W (ret);
6420   return ret;
6421 }
6422
6423 static int
6424 api_want_interface_events (vat_main_t * vam)
6425 {
6426   unformat_input_t *i = vam->input;
6427   vl_api_want_interface_events_t *mp;
6428   int enable = -1;
6429   int ret;
6430
6431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6432     {
6433       if (unformat (i, "enable"))
6434         enable = 1;
6435       else if (unformat (i, "disable"))
6436         enable = 0;
6437       else
6438         break;
6439     }
6440
6441   if (enable == -1)
6442     {
6443       errmsg ("missing enable|disable");
6444       return -99;
6445     }
6446
6447   M (WANT_INTERFACE_EVENTS, mp);
6448   mp->enable_disable = enable;
6449
6450   vam->interface_event_display = enable;
6451
6452   S (mp);
6453   W (ret);
6454   return ret;
6455 }
6456
6457
6458 /* Note: non-static, called once to set up the initial intfc table */
6459 int
6460 api_sw_interface_dump (vat_main_t * vam)
6461 {
6462   vl_api_sw_interface_dump_t *mp;
6463   vl_api_control_ping_t *mp_ping;
6464   hash_pair_t *p;
6465   name_sort_t *nses = 0, *ns;
6466   sw_interface_subif_t *sub = NULL;
6467   int ret;
6468
6469   /* Toss the old name table */
6470   /* *INDENT-OFF* */
6471   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6472   ({
6473     vec_add2 (nses, ns, 1);
6474     ns->name = (u8 *)(p->key);
6475     ns->value = (u32) p->value[0];
6476   }));
6477   /* *INDENT-ON* */
6478
6479   hash_free (vam->sw_if_index_by_interface_name);
6480
6481   vec_foreach (ns, nses) vec_free (ns->name);
6482
6483   vec_free (nses);
6484
6485   vec_foreach (sub, vam->sw_if_subif_table)
6486   {
6487     vec_free (sub->interface_name);
6488   }
6489   vec_free (vam->sw_if_subif_table);
6490
6491   /* recreate the interface name hash table */
6492   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6493
6494   /*
6495    * Ask for all interface names. Otherwise, the epic catalog of
6496    * name filters becomes ridiculously long, and vat ends up needing
6497    * to be taught about new interface types.
6498    */
6499   M (SW_INTERFACE_DUMP, mp);
6500   S (mp);
6501
6502   /* Use a control ping for synchronization */
6503   MPING (CONTROL_PING, mp_ping);
6504   S (mp_ping);
6505
6506   W (ret);
6507   return ret;
6508 }
6509
6510 static int
6511 api_sw_interface_set_flags (vat_main_t * vam)
6512 {
6513   unformat_input_t *i = vam->input;
6514   vl_api_sw_interface_set_flags_t *mp;
6515   u32 sw_if_index;
6516   u8 sw_if_index_set = 0;
6517   u8 admin_up = 0;
6518   int ret;
6519
6520   /* Parse args required to build the message */
6521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6522     {
6523       if (unformat (i, "admin-up"))
6524         admin_up = 1;
6525       else if (unformat (i, "admin-down"))
6526         admin_up = 0;
6527       else
6528         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6529         sw_if_index_set = 1;
6530       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6531         sw_if_index_set = 1;
6532       else
6533         break;
6534     }
6535
6536   if (sw_if_index_set == 0)
6537     {
6538       errmsg ("missing interface name or sw_if_index");
6539       return -99;
6540     }
6541
6542   /* Construct the API message */
6543   M (SW_INTERFACE_SET_FLAGS, mp);
6544   mp->sw_if_index = ntohl (sw_if_index);
6545   mp->admin_up_down = admin_up;
6546
6547   /* send it... */
6548   S (mp);
6549
6550   /* Wait for a reply, return the good/bad news... */
6551   W (ret);
6552   return ret;
6553 }
6554
6555 static int
6556 api_sw_interface_set_rx_mode (vat_main_t * vam)
6557 {
6558   unformat_input_t *i = vam->input;
6559   vl_api_sw_interface_set_rx_mode_t *mp;
6560   u32 sw_if_index;
6561   u8 sw_if_index_set = 0;
6562   int ret;
6563   u8 queue_id_valid = 0;
6564   u32 queue_id;
6565   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6566
6567   /* Parse args required to build the message */
6568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6569     {
6570       if (unformat (i, "queue %d", &queue_id))
6571         queue_id_valid = 1;
6572       else if (unformat (i, "polling"))
6573         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6574       else if (unformat (i, "interrupt"))
6575         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6576       else if (unformat (i, "adaptive"))
6577         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6578       else
6579         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6580         sw_if_index_set = 1;
6581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6582         sw_if_index_set = 1;
6583       else
6584         break;
6585     }
6586
6587   if (sw_if_index_set == 0)
6588     {
6589       errmsg ("missing interface name or sw_if_index");
6590       return -99;
6591     }
6592   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6593     {
6594       errmsg ("missing rx-mode");
6595       return -99;
6596     }
6597
6598   /* Construct the API message */
6599   M (SW_INTERFACE_SET_RX_MODE, mp);
6600   mp->sw_if_index = ntohl (sw_if_index);
6601   mp->mode = mode;
6602   mp->queue_id_valid = queue_id_valid;
6603   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply, return the good/bad news... */
6609   W (ret);
6610   return ret;
6611 }
6612
6613 static int
6614 api_sw_interface_clear_stats (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_sw_interface_clear_stats_t *mp;
6618   u32 sw_if_index;
6619   u8 sw_if_index_set = 0;
6620   int ret;
6621
6622   /* Parse args required to build the message */
6623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6624     {
6625       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6626         sw_if_index_set = 1;
6627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6628         sw_if_index_set = 1;
6629       else
6630         break;
6631     }
6632
6633   /* Construct the API message */
6634   M (SW_INTERFACE_CLEAR_STATS, mp);
6635
6636   if (sw_if_index_set == 1)
6637     mp->sw_if_index = ntohl (sw_if_index);
6638   else
6639     mp->sw_if_index = ~0;
6640
6641   /* send it... */
6642   S (mp);
6643
6644   /* Wait for a reply, return the good/bad news... */
6645   W (ret);
6646   return ret;
6647 }
6648
6649 static int
6650 api_sw_interface_add_del_address (vat_main_t * vam)
6651 {
6652   unformat_input_t *i = vam->input;
6653   vl_api_sw_interface_add_del_address_t *mp;
6654   u32 sw_if_index;
6655   u8 sw_if_index_set = 0;
6656   u8 is_add = 1, del_all = 0;
6657   u32 address_length = 0;
6658   u8 v4_address_set = 0;
6659   u8 v6_address_set = 0;
6660   ip4_address_t v4address;
6661   ip6_address_t v6address;
6662   int ret;
6663
6664   /* Parse args required to build the message */
6665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6666     {
6667       if (unformat (i, "del-all"))
6668         del_all = 1;
6669       else if (unformat (i, "del"))
6670         is_add = 0;
6671       else
6672         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6673         sw_if_index_set = 1;
6674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6675         sw_if_index_set = 1;
6676       else if (unformat (i, "%U/%d",
6677                          unformat_ip4_address, &v4address, &address_length))
6678         v4_address_set = 1;
6679       else if (unformat (i, "%U/%d",
6680                          unformat_ip6_address, &v6address, &address_length))
6681         v6_address_set = 1;
6682       else
6683         break;
6684     }
6685
6686   if (sw_if_index_set == 0)
6687     {
6688       errmsg ("missing interface name or sw_if_index");
6689       return -99;
6690     }
6691   if (v4_address_set && v6_address_set)
6692     {
6693       errmsg ("both v4 and v6 addresses set");
6694       return -99;
6695     }
6696   if (!v4_address_set && !v6_address_set && !del_all)
6697     {
6698       errmsg ("no addresses set");
6699       return -99;
6700     }
6701
6702   /* Construct the API message */
6703   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6704
6705   mp->sw_if_index = ntohl (sw_if_index);
6706   mp->is_add = is_add;
6707   mp->del_all = del_all;
6708   if (v6_address_set)
6709     {
6710       mp->is_ipv6 = 1;
6711       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6712     }
6713   else
6714     {
6715       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6716     }
6717   mp->address_length = address_length;
6718
6719   /* send it... */
6720   S (mp);
6721
6722   /* Wait for a reply, return good/bad news  */
6723   W (ret);
6724   return ret;
6725 }
6726
6727 static int
6728 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6729 {
6730   unformat_input_t *i = vam->input;
6731   vl_api_sw_interface_set_mpls_enable_t *mp;
6732   u32 sw_if_index;
6733   u8 sw_if_index_set = 0;
6734   u8 enable = 1;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6741         sw_if_index_set = 1;
6742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6743         sw_if_index_set = 1;
6744       else if (unformat (i, "disable"))
6745         enable = 0;
6746       else if (unformat (i, "dis"))
6747         enable = 0;
6748       else
6749         break;
6750     }
6751
6752   if (sw_if_index_set == 0)
6753     {
6754       errmsg ("missing interface name or sw_if_index");
6755       return -99;
6756     }
6757
6758   /* Construct the API message */
6759   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6760
6761   mp->sw_if_index = ntohl (sw_if_index);
6762   mp->enable = enable;
6763
6764   /* send it... */
6765   S (mp);
6766
6767   /* Wait for a reply... */
6768   W (ret);
6769   return ret;
6770 }
6771
6772 static int
6773 api_sw_interface_set_table (vat_main_t * vam)
6774 {
6775   unformat_input_t *i = vam->input;
6776   vl_api_sw_interface_set_table_t *mp;
6777   u32 sw_if_index, vrf_id = 0;
6778   u8 sw_if_index_set = 0;
6779   u8 is_ipv6 = 0;
6780   int ret;
6781
6782   /* Parse args required to build the message */
6783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6784     {
6785       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6786         sw_if_index_set = 1;
6787       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6788         sw_if_index_set = 1;
6789       else if (unformat (i, "vrf %d", &vrf_id))
6790         ;
6791       else if (unformat (i, "ipv6"))
6792         is_ipv6 = 1;
6793       else
6794         break;
6795     }
6796
6797   if (sw_if_index_set == 0)
6798     {
6799       errmsg ("missing interface name or sw_if_index");
6800       return -99;
6801     }
6802
6803   /* Construct the API message */
6804   M (SW_INTERFACE_SET_TABLE, mp);
6805
6806   mp->sw_if_index = ntohl (sw_if_index);
6807   mp->is_ipv6 = is_ipv6;
6808   mp->vrf_id = ntohl (vrf_id);
6809
6810   /* send it... */
6811   S (mp);
6812
6813   /* Wait for a reply... */
6814   W (ret);
6815   return ret;
6816 }
6817
6818 static void vl_api_sw_interface_get_table_reply_t_handler
6819   (vl_api_sw_interface_get_table_reply_t * mp)
6820 {
6821   vat_main_t *vam = &vat_main;
6822
6823   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6824
6825   vam->retval = ntohl (mp->retval);
6826   vam->result_ready = 1;
6827
6828 }
6829
6830 static void vl_api_sw_interface_get_table_reply_t_handler_json
6831   (vl_api_sw_interface_get_table_reply_t * mp)
6832 {
6833   vat_main_t *vam = &vat_main;
6834   vat_json_node_t node;
6835
6836   vat_json_init_object (&node);
6837   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6838   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6839
6840   vat_json_print (vam->ofp, &node);
6841   vat_json_free (&node);
6842
6843   vam->retval = ntohl (mp->retval);
6844   vam->result_ready = 1;
6845 }
6846
6847 static int
6848 api_sw_interface_get_table (vat_main_t * vam)
6849 {
6850   unformat_input_t *i = vam->input;
6851   vl_api_sw_interface_get_table_t *mp;
6852   u32 sw_if_index;
6853   u8 sw_if_index_set = 0;
6854   u8 is_ipv6 = 0;
6855   int ret;
6856
6857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6858     {
6859       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6860         sw_if_index_set = 1;
6861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6862         sw_if_index_set = 1;
6863       else if (unformat (i, "ipv6"))
6864         is_ipv6 = 1;
6865       else
6866         break;
6867     }
6868
6869   if (sw_if_index_set == 0)
6870     {
6871       errmsg ("missing interface name or sw_if_index");
6872       return -99;
6873     }
6874
6875   M (SW_INTERFACE_GET_TABLE, mp);
6876   mp->sw_if_index = htonl (sw_if_index);
6877   mp->is_ipv6 = is_ipv6;
6878
6879   S (mp);
6880   W (ret);
6881   return ret;
6882 }
6883
6884 static int
6885 api_sw_interface_set_vpath (vat_main_t * vam)
6886 {
6887   unformat_input_t *i = vam->input;
6888   vl_api_sw_interface_set_vpath_t *mp;
6889   u32 sw_if_index = 0;
6890   u8 sw_if_index_set = 0;
6891   u8 is_enable = 0;
6892   int ret;
6893
6894   /* Parse args required to build the message */
6895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6896     {
6897       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6898         sw_if_index_set = 1;
6899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6900         sw_if_index_set = 1;
6901       else if (unformat (i, "enable"))
6902         is_enable = 1;
6903       else if (unformat (i, "disable"))
6904         is_enable = 0;
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_VPATH, mp);
6917
6918   mp->sw_if_index = ntohl (sw_if_index);
6919   mp->enable = is_enable;
6920
6921   /* send it... */
6922   S (mp);
6923
6924   /* Wait for a reply... */
6925   W (ret);
6926   return ret;
6927 }
6928
6929 static int
6930 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6931 {
6932   unformat_input_t *i = vam->input;
6933   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6934   u32 sw_if_index = 0;
6935   u8 sw_if_index_set = 0;
6936   u8 is_enable = 1;
6937   u8 is_ipv6 = 0;
6938   int ret;
6939
6940   /* Parse args required to build the message */
6941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6942     {
6943       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6944         sw_if_index_set = 1;
6945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6946         sw_if_index_set = 1;
6947       else if (unformat (i, "enable"))
6948         is_enable = 1;
6949       else if (unformat (i, "disable"))
6950         is_enable = 0;
6951       else if (unformat (i, "ip4"))
6952         is_ipv6 = 0;
6953       else if (unformat (i, "ip6"))
6954         is_ipv6 = 1;
6955       else
6956         break;
6957     }
6958
6959   if (sw_if_index_set == 0)
6960     {
6961       errmsg ("missing interface name or sw_if_index");
6962       return -99;
6963     }
6964
6965   /* Construct the API message */
6966   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6967
6968   mp->sw_if_index = ntohl (sw_if_index);
6969   mp->enable = is_enable;
6970   mp->is_ipv6 = is_ipv6;
6971
6972   /* send it... */
6973   S (mp);
6974
6975   /* Wait for a reply... */
6976   W (ret);
6977   return ret;
6978 }
6979
6980 static int
6981 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6982 {
6983   unformat_input_t *i = vam->input;
6984   vl_api_sw_interface_set_geneve_bypass_t *mp;
6985   u32 sw_if_index = 0;
6986   u8 sw_if_index_set = 0;
6987   u8 is_enable = 1;
6988   u8 is_ipv6 = 0;
6989   int ret;
6990
6991   /* Parse args required to build the message */
6992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6993     {
6994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6995         sw_if_index_set = 1;
6996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6997         sw_if_index_set = 1;
6998       else if (unformat (i, "enable"))
6999         is_enable = 1;
7000       else if (unformat (i, "disable"))
7001         is_enable = 0;
7002       else if (unformat (i, "ip4"))
7003         is_ipv6 = 0;
7004       else if (unformat (i, "ip6"))
7005         is_ipv6 = 1;
7006       else
7007         break;
7008     }
7009
7010   if (sw_if_index_set == 0)
7011     {
7012       errmsg ("missing interface name or sw_if_index");
7013       return -99;
7014     }
7015
7016   /* Construct the API message */
7017   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7018
7019   mp->sw_if_index = ntohl (sw_if_index);
7020   mp->enable = is_enable;
7021   mp->is_ipv6 = is_ipv6;
7022
7023   /* send it... */
7024   S (mp);
7025
7026   /* Wait for a reply... */
7027   W (ret);
7028   return ret;
7029 }
7030
7031 static int
7032 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7033 {
7034   unformat_input_t *i = vam->input;
7035   vl_api_sw_interface_set_l2_xconnect_t *mp;
7036   u32 rx_sw_if_index;
7037   u8 rx_sw_if_index_set = 0;
7038   u32 tx_sw_if_index;
7039   u8 tx_sw_if_index_set = 0;
7040   u8 enable = 1;
7041   int ret;
7042
7043   /* Parse args required to build the message */
7044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7045     {
7046       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7047         rx_sw_if_index_set = 1;
7048       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7049         tx_sw_if_index_set = 1;
7050       else if (unformat (i, "rx"))
7051         {
7052           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7053             {
7054               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7055                             &rx_sw_if_index))
7056                 rx_sw_if_index_set = 1;
7057             }
7058           else
7059             break;
7060         }
7061       else if (unformat (i, "tx"))
7062         {
7063           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7064             {
7065               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7066                             &tx_sw_if_index))
7067                 tx_sw_if_index_set = 1;
7068             }
7069           else
7070             break;
7071         }
7072       else if (unformat (i, "enable"))
7073         enable = 1;
7074       else if (unformat (i, "disable"))
7075         enable = 0;
7076       else
7077         break;
7078     }
7079
7080   if (rx_sw_if_index_set == 0)
7081     {
7082       errmsg ("missing rx interface name or rx_sw_if_index");
7083       return -99;
7084     }
7085
7086   if (enable && (tx_sw_if_index_set == 0))
7087     {
7088       errmsg ("missing tx interface name or tx_sw_if_index");
7089       return -99;
7090     }
7091
7092   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7093
7094   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7095   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7096   mp->enable = enable;
7097
7098   S (mp);
7099   W (ret);
7100   return ret;
7101 }
7102
7103 static int
7104 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7105 {
7106   unformat_input_t *i = vam->input;
7107   vl_api_sw_interface_set_l2_bridge_t *mp;
7108   u32 rx_sw_if_index;
7109   u8 rx_sw_if_index_set = 0;
7110   u32 bd_id;
7111   u8 bd_id_set = 0;
7112   u8 bvi = 0;
7113   u32 shg = 0;
7114   u8 enable = 1;
7115   int ret;
7116
7117   /* Parse args required to build the message */
7118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7119     {
7120       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7121         rx_sw_if_index_set = 1;
7122       else if (unformat (i, "bd_id %d", &bd_id))
7123         bd_id_set = 1;
7124       else
7125         if (unformat
7126             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7127         rx_sw_if_index_set = 1;
7128       else if (unformat (i, "shg %d", &shg))
7129         ;
7130       else if (unformat (i, "bvi"))
7131         bvi = 1;
7132       else if (unformat (i, "enable"))
7133         enable = 1;
7134       else if (unformat (i, "disable"))
7135         enable = 0;
7136       else
7137         break;
7138     }
7139
7140   if (rx_sw_if_index_set == 0)
7141     {
7142       errmsg ("missing rx interface name or sw_if_index");
7143       return -99;
7144     }
7145
7146   if (enable && (bd_id_set == 0))
7147     {
7148       errmsg ("missing bridge domain");
7149       return -99;
7150     }
7151
7152   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7153
7154   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7155   mp->bd_id = ntohl (bd_id);
7156   mp->shg = (u8) shg;
7157   mp->bvi = bvi;
7158   mp->enable = enable;
7159
7160   S (mp);
7161   W (ret);
7162   return ret;
7163 }
7164
7165 static int
7166 api_bridge_domain_dump (vat_main_t * vam)
7167 {
7168   unformat_input_t *i = vam->input;
7169   vl_api_bridge_domain_dump_t *mp;
7170   vl_api_control_ping_t *mp_ping;
7171   u32 bd_id = ~0;
7172   int ret;
7173
7174   /* Parse args required to build the message */
7175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7176     {
7177       if (unformat (i, "bd_id %d", &bd_id))
7178         ;
7179       else
7180         break;
7181     }
7182
7183   M (BRIDGE_DOMAIN_DUMP, mp);
7184   mp->bd_id = ntohl (bd_id);
7185   S (mp);
7186
7187   /* Use a control ping for synchronization */
7188   MPING (CONTROL_PING, mp_ping);
7189   S (mp_ping);
7190
7191   W (ret);
7192   return ret;
7193 }
7194
7195 static int
7196 api_bridge_domain_add_del (vat_main_t * vam)
7197 {
7198   unformat_input_t *i = vam->input;
7199   vl_api_bridge_domain_add_del_t *mp;
7200   u32 bd_id = ~0;
7201   u8 is_add = 1;
7202   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7203   u8 *bd_tag = NULL;
7204   u32 mac_age = 0;
7205   int ret;
7206
7207   /* Parse args required to build the message */
7208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7209     {
7210       if (unformat (i, "bd_id %d", &bd_id))
7211         ;
7212       else if (unformat (i, "flood %d", &flood))
7213         ;
7214       else if (unformat (i, "uu-flood %d", &uu_flood))
7215         ;
7216       else if (unformat (i, "forward %d", &forward))
7217         ;
7218       else if (unformat (i, "learn %d", &learn))
7219         ;
7220       else if (unformat (i, "arp-term %d", &arp_term))
7221         ;
7222       else if (unformat (i, "mac-age %d", &mac_age))
7223         ;
7224       else if (unformat (i, "bd-tag %s", &bd_tag))
7225         ;
7226       else if (unformat (i, "del"))
7227         {
7228           is_add = 0;
7229           flood = uu_flood = forward = learn = 0;
7230         }
7231       else
7232         break;
7233     }
7234
7235   if (bd_id == ~0)
7236     {
7237       errmsg ("missing bridge domain");
7238       ret = -99;
7239       goto done;
7240     }
7241
7242   if (mac_age > 255)
7243     {
7244       errmsg ("mac age must be less than 256 ");
7245       ret = -99;
7246       goto done;
7247     }
7248
7249   if ((bd_tag) && (vec_len (bd_tag) > 63))
7250     {
7251       errmsg ("bd-tag cannot be longer than 63");
7252       ret = -99;
7253       goto done;
7254     }
7255
7256   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7257
7258   mp->bd_id = ntohl (bd_id);
7259   mp->flood = flood;
7260   mp->uu_flood = uu_flood;
7261   mp->forward = forward;
7262   mp->learn = learn;
7263   mp->arp_term = arp_term;
7264   mp->is_add = is_add;
7265   mp->mac_age = (u8) mac_age;
7266   if (bd_tag)
7267     {
7268       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7269       mp->bd_tag[vec_len (bd_tag)] = 0;
7270     }
7271   S (mp);
7272   W (ret);
7273
7274 done:
7275   vec_free (bd_tag);
7276   return ret;
7277 }
7278
7279 static int
7280 api_l2fib_flush_bd (vat_main_t * vam)
7281 {
7282   unformat_input_t *i = vam->input;
7283   vl_api_l2fib_flush_bd_t *mp;
7284   u32 bd_id = ~0;
7285   int ret;
7286
7287   /* Parse args required to build the message */
7288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7289     {
7290       if (unformat (i, "bd_id %d", &bd_id));
7291       else
7292         break;
7293     }
7294
7295   if (bd_id == ~0)
7296     {
7297       errmsg ("missing bridge domain");
7298       return -99;
7299     }
7300
7301   M (L2FIB_FLUSH_BD, mp);
7302
7303   mp->bd_id = htonl (bd_id);
7304
7305   S (mp);
7306   W (ret);
7307   return ret;
7308 }
7309
7310 static int
7311 api_l2fib_flush_int (vat_main_t * vam)
7312 {
7313   unformat_input_t *i = vam->input;
7314   vl_api_l2fib_flush_int_t *mp;
7315   u32 sw_if_index = ~0;
7316   int ret;
7317
7318   /* Parse args required to build the message */
7319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7320     {
7321       if (unformat (i, "sw_if_index %d", &sw_if_index));
7322       else
7323         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7324       else
7325         break;
7326     }
7327
7328   if (sw_if_index == ~0)
7329     {
7330       errmsg ("missing interface name or sw_if_index");
7331       return -99;
7332     }
7333
7334   M (L2FIB_FLUSH_INT, mp);
7335
7336   mp->sw_if_index = ntohl (sw_if_index);
7337
7338   S (mp);
7339   W (ret);
7340   return ret;
7341 }
7342
7343 static int
7344 api_l2fib_add_del (vat_main_t * vam)
7345 {
7346   unformat_input_t *i = vam->input;
7347   vl_api_l2fib_add_del_t *mp;
7348   f64 timeout;
7349   u8 mac[6] = { 0 };
7350   u8 mac_set = 0;
7351   u32 bd_id;
7352   u8 bd_id_set = 0;
7353   u32 sw_if_index = ~0;
7354   u8 sw_if_index_set = 0;
7355   u8 is_add = 1;
7356   u8 static_mac = 0;
7357   u8 filter_mac = 0;
7358   u8 bvi_mac = 0;
7359   int count = 1;
7360   f64 before = 0;
7361   int j;
7362
7363   /* Parse args required to build the message */
7364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7365     {
7366       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7367         mac_set = 1;
7368       else if (unformat (i, "bd_id %d", &bd_id))
7369         bd_id_set = 1;
7370       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7371         sw_if_index_set = 1;
7372       else if (unformat (i, "sw_if"))
7373         {
7374           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7375             {
7376               if (unformat
7377                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7378                 sw_if_index_set = 1;
7379             }
7380           else
7381             break;
7382         }
7383       else if (unformat (i, "static"))
7384         static_mac = 1;
7385       else if (unformat (i, "filter"))
7386         {
7387           filter_mac = 1;
7388           static_mac = 1;
7389         }
7390       else if (unformat (i, "bvi"))
7391         {
7392           bvi_mac = 1;
7393           static_mac = 1;
7394         }
7395       else if (unformat (i, "del"))
7396         is_add = 0;
7397       else if (unformat (i, "count %d", &count))
7398         ;
7399       else
7400         break;
7401     }
7402
7403   if (mac_set == 0)
7404     {
7405       errmsg ("missing mac address");
7406       return -99;
7407     }
7408
7409   if (bd_id_set == 0)
7410     {
7411       errmsg ("missing bridge domain");
7412       return -99;
7413     }
7414
7415   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7416     {
7417       errmsg ("missing interface name or sw_if_index");
7418       return -99;
7419     }
7420
7421   if (count > 1)
7422     {
7423       /* Turn on async mode */
7424       vam->async_mode = 1;
7425       vam->async_errors = 0;
7426       before = vat_time_now (vam);
7427     }
7428
7429   for (j = 0; j < count; j++)
7430     {
7431       M (L2FIB_ADD_DEL, mp);
7432
7433       clib_memcpy (mp->mac, mac, 6);
7434       mp->bd_id = ntohl (bd_id);
7435       mp->is_add = is_add;
7436
7437       if (is_add)
7438         {
7439           mp->sw_if_index = ntohl (sw_if_index);
7440           mp->static_mac = static_mac;
7441           mp->filter_mac = filter_mac;
7442           mp->bvi_mac = bvi_mac;
7443         }
7444       increment_mac_address (mac);
7445       /* send it... */
7446       S (mp);
7447     }
7448
7449   if (count > 1)
7450     {
7451       vl_api_control_ping_t *mp_ping;
7452       f64 after;
7453
7454       /* Shut off async mode */
7455       vam->async_mode = 0;
7456
7457       MPING (CONTROL_PING, mp_ping);
7458       S (mp_ping);
7459
7460       timeout = vat_time_now (vam) + 1.0;
7461       while (vat_time_now (vam) < timeout)
7462         if (vam->result_ready == 1)
7463           goto out;
7464       vam->retval = -99;
7465
7466     out:
7467       if (vam->retval == -99)
7468         errmsg ("timeout");
7469
7470       if (vam->async_errors > 0)
7471         {
7472           errmsg ("%d asynchronous errors", vam->async_errors);
7473           vam->retval = -98;
7474         }
7475       vam->async_errors = 0;
7476       after = vat_time_now (vam);
7477
7478       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7479              count, after - before, count / (after - before));
7480     }
7481   else
7482     {
7483       int ret;
7484
7485       /* Wait for a reply... */
7486       W (ret);
7487       return ret;
7488     }
7489   /* Return the good/bad news */
7490   return (vam->retval);
7491 }
7492
7493 static int
7494 api_bridge_domain_set_mac_age (vat_main_t * vam)
7495 {
7496   unformat_input_t *i = vam->input;
7497   vl_api_bridge_domain_set_mac_age_t *mp;
7498   u32 bd_id = ~0;
7499   u32 mac_age = 0;
7500   int ret;
7501
7502   /* Parse args required to build the message */
7503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7504     {
7505       if (unformat (i, "bd_id %d", &bd_id));
7506       else if (unformat (i, "mac-age %d", &mac_age));
7507       else
7508         break;
7509     }
7510
7511   if (bd_id == ~0)
7512     {
7513       errmsg ("missing bridge domain");
7514       return -99;
7515     }
7516
7517   if (mac_age > 255)
7518     {
7519       errmsg ("mac age must be less than 256 ");
7520       return -99;
7521     }
7522
7523   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7524
7525   mp->bd_id = htonl (bd_id);
7526   mp->mac_age = (u8) mac_age;
7527
7528   S (mp);
7529   W (ret);
7530   return ret;
7531 }
7532
7533 static int
7534 api_l2_flags (vat_main_t * vam)
7535 {
7536   unformat_input_t *i = vam->input;
7537   vl_api_l2_flags_t *mp;
7538   u32 sw_if_index;
7539   u32 flags = 0;
7540   u8 sw_if_index_set = 0;
7541   u8 is_set = 0;
7542   int ret;
7543
7544   /* Parse args required to build the message */
7545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7546     {
7547       if (unformat (i, "sw_if_index %d", &sw_if_index))
7548         sw_if_index_set = 1;
7549       else if (unformat (i, "sw_if"))
7550         {
7551           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7552             {
7553               if (unformat
7554                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7555                 sw_if_index_set = 1;
7556             }
7557           else
7558             break;
7559         }
7560       else if (unformat (i, "learn"))
7561         flags |= L2_LEARN;
7562       else if (unformat (i, "forward"))
7563         flags |= L2_FWD;
7564       else if (unformat (i, "flood"))
7565         flags |= L2_FLOOD;
7566       else if (unformat (i, "uu-flood"))
7567         flags |= L2_UU_FLOOD;
7568       else if (unformat (i, "arp-term"))
7569         flags |= L2_ARP_TERM;
7570       else if (unformat (i, "off"))
7571         is_set = 0;
7572       else if (unformat (i, "disable"))
7573         is_set = 0;
7574       else
7575         break;
7576     }
7577
7578   if (sw_if_index_set == 0)
7579     {
7580       errmsg ("missing interface name or sw_if_index");
7581       return -99;
7582     }
7583
7584   M (L2_FLAGS, mp);
7585
7586   mp->sw_if_index = ntohl (sw_if_index);
7587   mp->feature_bitmap = ntohl (flags);
7588   mp->is_set = is_set;
7589
7590   S (mp);
7591   W (ret);
7592   return ret;
7593 }
7594
7595 static int
7596 api_bridge_flags (vat_main_t * vam)
7597 {
7598   unformat_input_t *i = vam->input;
7599   vl_api_bridge_flags_t *mp;
7600   u32 bd_id;
7601   u8 bd_id_set = 0;
7602   u8 is_set = 1;
7603   u32 flags = 0;
7604   int ret;
7605
7606   /* Parse args required to build the message */
7607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7608     {
7609       if (unformat (i, "bd_id %d", &bd_id))
7610         bd_id_set = 1;
7611       else if (unformat (i, "learn"))
7612         flags |= L2_LEARN;
7613       else if (unformat (i, "forward"))
7614         flags |= L2_FWD;
7615       else if (unformat (i, "flood"))
7616         flags |= L2_FLOOD;
7617       else if (unformat (i, "uu-flood"))
7618         flags |= L2_UU_FLOOD;
7619       else if (unformat (i, "arp-term"))
7620         flags |= L2_ARP_TERM;
7621       else if (unformat (i, "off"))
7622         is_set = 0;
7623       else if (unformat (i, "disable"))
7624         is_set = 0;
7625       else
7626         break;
7627     }
7628
7629   if (bd_id_set == 0)
7630     {
7631       errmsg ("missing bridge domain");
7632       return -99;
7633     }
7634
7635   M (BRIDGE_FLAGS, mp);
7636
7637   mp->bd_id = ntohl (bd_id);
7638   mp->feature_bitmap = ntohl (flags);
7639   mp->is_set = is_set;
7640
7641   S (mp);
7642   W (ret);
7643   return ret;
7644 }
7645
7646 static int
7647 api_bd_ip_mac_add_del (vat_main_t * vam)
7648 {
7649   unformat_input_t *i = vam->input;
7650   vl_api_bd_ip_mac_add_del_t *mp;
7651   u32 bd_id;
7652   u8 is_ipv6 = 0;
7653   u8 is_add = 1;
7654   u8 bd_id_set = 0;
7655   u8 ip_set = 0;
7656   u8 mac_set = 0;
7657   ip4_address_t v4addr;
7658   ip6_address_t v6addr;
7659   u8 macaddr[6];
7660   int ret;
7661
7662
7663   /* Parse args required to build the message */
7664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7665     {
7666       if (unformat (i, "bd_id %d", &bd_id))
7667         {
7668           bd_id_set++;
7669         }
7670       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7671         {
7672           ip_set++;
7673         }
7674       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7675         {
7676           ip_set++;
7677           is_ipv6++;
7678         }
7679       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7680         {
7681           mac_set++;
7682         }
7683       else if (unformat (i, "del"))
7684         is_add = 0;
7685       else
7686         break;
7687     }
7688
7689   if (bd_id_set == 0)
7690     {
7691       errmsg ("missing bridge domain");
7692       return -99;
7693     }
7694   else if (ip_set == 0)
7695     {
7696       errmsg ("missing IP address");
7697       return -99;
7698     }
7699   else if (mac_set == 0)
7700     {
7701       errmsg ("missing MAC address");
7702       return -99;
7703     }
7704
7705   M (BD_IP_MAC_ADD_DEL, mp);
7706
7707   mp->bd_id = ntohl (bd_id);
7708   mp->is_ipv6 = is_ipv6;
7709   mp->is_add = is_add;
7710   if (is_ipv6)
7711     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7712   else
7713     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7714   clib_memcpy (mp->mac_address, macaddr, 6);
7715   S (mp);
7716   W (ret);
7717   return ret;
7718 }
7719
7720 static int
7721 api_tap_connect (vat_main_t * vam)
7722 {
7723   unformat_input_t *i = vam->input;
7724   vl_api_tap_connect_t *mp;
7725   u8 mac_address[6];
7726   u8 random_mac = 1;
7727   u8 name_set = 0;
7728   u8 *tap_name;
7729   u8 *tag = 0;
7730   ip4_address_t ip4_address;
7731   u32 ip4_mask_width;
7732   int ip4_address_set = 0;
7733   ip6_address_t ip6_address;
7734   u32 ip6_mask_width;
7735   int ip6_address_set = 0;
7736   int ret;
7737
7738   memset (mac_address, 0, sizeof (mac_address));
7739
7740   /* Parse args required to build the message */
7741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7742     {
7743       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7744         {
7745           random_mac = 0;
7746         }
7747       else if (unformat (i, "random-mac"))
7748         random_mac = 1;
7749       else if (unformat (i, "tapname %s", &tap_name))
7750         name_set = 1;
7751       else if (unformat (i, "tag %s", &tag))
7752         ;
7753       else if (unformat (i, "address %U/%d",
7754                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7755         ip4_address_set = 1;
7756       else if (unformat (i, "address %U/%d",
7757                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7758         ip6_address_set = 1;
7759       else
7760         break;
7761     }
7762
7763   if (name_set == 0)
7764     {
7765       errmsg ("missing tap name");
7766       return -99;
7767     }
7768   if (vec_len (tap_name) > 63)
7769     {
7770       errmsg ("tap name too long");
7771       return -99;
7772     }
7773   vec_add1 (tap_name, 0);
7774
7775   if (vec_len (tag) > 63)
7776     {
7777       errmsg ("tag too long");
7778       return -99;
7779     }
7780
7781   /* Construct the API message */
7782   M (TAP_CONNECT, mp);
7783
7784   mp->use_random_mac = random_mac;
7785   clib_memcpy (mp->mac_address, mac_address, 6);
7786   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7787   if (tag)
7788     clib_memcpy (mp->tag, tag, vec_len (tag));
7789
7790   if (ip4_address_set)
7791     {
7792       mp->ip4_address_set = 1;
7793       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7794       mp->ip4_mask_width = ip4_mask_width;
7795     }
7796   if (ip6_address_set)
7797     {
7798       mp->ip6_address_set = 1;
7799       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7800       mp->ip6_mask_width = ip6_mask_width;
7801     }
7802
7803   vec_free (tap_name);
7804   vec_free (tag);
7805
7806   /* send it... */
7807   S (mp);
7808
7809   /* Wait for a reply... */
7810   W (ret);
7811   return ret;
7812 }
7813
7814 static int
7815 api_tap_modify (vat_main_t * vam)
7816 {
7817   unformat_input_t *i = vam->input;
7818   vl_api_tap_modify_t *mp;
7819   u8 mac_address[6];
7820   u8 random_mac = 1;
7821   u8 name_set = 0;
7822   u8 *tap_name;
7823   u32 sw_if_index = ~0;
7824   u8 sw_if_index_set = 0;
7825   int ret;
7826
7827   memset (mac_address, 0, sizeof (mac_address));
7828
7829   /* Parse args required to build the message */
7830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7831     {
7832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7833         sw_if_index_set = 1;
7834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7835         sw_if_index_set = 1;
7836       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7837         {
7838           random_mac = 0;
7839         }
7840       else if (unformat (i, "random-mac"))
7841         random_mac = 1;
7842       else if (unformat (i, "tapname %s", &tap_name))
7843         name_set = 1;
7844       else
7845         break;
7846     }
7847
7848   if (sw_if_index_set == 0)
7849     {
7850       errmsg ("missing vpp interface name");
7851       return -99;
7852     }
7853   if (name_set == 0)
7854     {
7855       errmsg ("missing tap name");
7856       return -99;
7857     }
7858   if (vec_len (tap_name) > 63)
7859     {
7860       errmsg ("tap name too long");
7861     }
7862   vec_add1 (tap_name, 0);
7863
7864   /* Construct the API message */
7865   M (TAP_MODIFY, mp);
7866
7867   mp->use_random_mac = random_mac;
7868   mp->sw_if_index = ntohl (sw_if_index);
7869   clib_memcpy (mp->mac_address, mac_address, 6);
7870   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7871   vec_free (tap_name);
7872
7873   /* send it... */
7874   S (mp);
7875
7876   /* Wait for a reply... */
7877   W (ret);
7878   return ret;
7879 }
7880
7881 static int
7882 api_tap_delete (vat_main_t * vam)
7883 {
7884   unformat_input_t *i = vam->input;
7885   vl_api_tap_delete_t *mp;
7886   u32 sw_if_index = ~0;
7887   u8 sw_if_index_set = 0;
7888   int ret;
7889
7890   /* Parse args required to build the message */
7891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7892     {
7893       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7894         sw_if_index_set = 1;
7895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7896         sw_if_index_set = 1;
7897       else
7898         break;
7899     }
7900
7901   if (sw_if_index_set == 0)
7902     {
7903       errmsg ("missing vpp interface name");
7904       return -99;
7905     }
7906
7907   /* Construct the API message */
7908   M (TAP_DELETE, mp);
7909
7910   mp->sw_if_index = ntohl (sw_if_index);
7911
7912   /* send it... */
7913   S (mp);
7914
7915   /* Wait for a reply... */
7916   W (ret);
7917   return ret;
7918 }
7919
7920 static int
7921 api_tap_create_v2 (vat_main_t * vam)
7922 {
7923   unformat_input_t *i = vam->input;
7924   vl_api_tap_create_v2_t *mp;
7925   u8 mac_address[6];
7926   u8 random_mac = 1;
7927   u32 id = ~0;
7928   u8 *host_if_name = 0;
7929   u8 *host_ns = 0;
7930   u8 host_mac_addr[6];
7931   u8 host_mac_addr_set = 0;
7932   u8 *host_bridge = 0;
7933   ip4_address_t host_ip4_addr;
7934   ip4_address_t host_ip4_gw;
7935   u8 host_ip4_gw_set = 0;
7936   u32 host_ip4_prefix_len = 0;
7937   ip6_address_t host_ip6_addr;
7938   ip6_address_t host_ip6_gw;
7939   u8 host_ip6_gw_set = 0;
7940   u32 host_ip6_prefix_len = 0;
7941   int ret;
7942   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7943
7944   memset (mac_address, 0, sizeof (mac_address));
7945
7946   /* Parse args required to build the message */
7947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7948     {
7949       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7950         {
7951           random_mac = 0;
7952         }
7953       else if (unformat (i, "id %u", &id))
7954         ;
7955       else if (unformat (i, "host-if-name %s", &host_if_name))
7956         ;
7957       else if (unformat (i, "host-ns %s", &host_ns))
7958         ;
7959       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7960                          host_mac_addr))
7961         host_mac_addr_set = 1;
7962       else if (unformat (i, "host-bridge %s", &host_bridge))
7963         ;
7964       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7965                          &host_ip4_addr, &host_ip4_prefix_len))
7966         ;
7967       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7968                          &host_ip6_addr, &host_ip6_prefix_len))
7969         ;
7970       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7971                          &host_ip4_gw))
7972         host_ip4_gw_set = 1;
7973       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7974                          &host_ip6_gw))
7975         host_ip6_gw_set = 1;
7976       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7977         ;
7978       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7979         ;
7980       else
7981         break;
7982     }
7983
7984   if (vec_len (host_if_name) > 63)
7985     {
7986       errmsg ("tap name too long. ");
7987       return -99;
7988     }
7989   if (vec_len (host_ns) > 63)
7990     {
7991       errmsg ("host name space too long. ");
7992       return -99;
7993     }
7994   if (vec_len (host_bridge) > 63)
7995     {
7996       errmsg ("host bridge name too long. ");
7997       return -99;
7998     }
7999   if (host_ip4_prefix_len > 32)
8000     {
8001       errmsg ("host ip4 prefix length not valid. ");
8002       return -99;
8003     }
8004   if (host_ip6_prefix_len > 128)
8005     {
8006       errmsg ("host ip6 prefix length not valid. ");
8007       return -99;
8008     }
8009   if (!is_pow2 (rx_ring_sz))
8010     {
8011       errmsg ("rx ring size must be power of 2. ");
8012       return -99;
8013     }
8014   if (rx_ring_sz > 32768)
8015     {
8016       errmsg ("rx ring size must be 32768 or lower. ");
8017       return -99;
8018     }
8019   if (!is_pow2 (tx_ring_sz))
8020     {
8021       errmsg ("tx ring size must be power of 2. ");
8022       return -99;
8023     }
8024   if (tx_ring_sz > 32768)
8025     {
8026       errmsg ("tx ring size must be 32768 or lower. ");
8027       return -99;
8028     }
8029
8030   /* Construct the API message */
8031   M (TAP_CREATE_V2, mp);
8032
8033   mp->use_random_mac = random_mac;
8034
8035   mp->id = ntohl (id);
8036   mp->host_namespace_set = host_ns != 0;
8037   mp->host_bridge_set = host_bridge != 0;
8038   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8039   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8040   mp->rx_ring_sz = ntohs (rx_ring_sz);
8041   mp->tx_ring_sz = ntohs (tx_ring_sz);
8042
8043   if (random_mac == 0)
8044     clib_memcpy (mp->mac_address, mac_address, 6);
8045   if (host_mac_addr_set)
8046     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8047   if (host_if_name)
8048     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8049   if (host_ns)
8050     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8051   if (host_bridge)
8052     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8053   if (host_ip4_prefix_len)
8054     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8055   if (host_ip4_prefix_len)
8056     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8057   if (host_ip4_gw_set)
8058     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8059   if (host_ip6_gw_set)
8060     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8061
8062   vec_free (host_ns);
8063   vec_free (host_if_name);
8064   vec_free (host_bridge);
8065
8066   /* send it... */
8067   S (mp);
8068
8069   /* Wait for a reply... */
8070   W (ret);
8071   return ret;
8072 }
8073
8074 static int
8075 api_tap_delete_v2 (vat_main_t * vam)
8076 {
8077   unformat_input_t *i = vam->input;
8078   vl_api_tap_delete_v2_t *mp;
8079   u32 sw_if_index = ~0;
8080   u8 sw_if_index_set = 0;
8081   int ret;
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         sw_if_index_set = 1;
8088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8089         sw_if_index_set = 1;
8090       else
8091         break;
8092     }
8093
8094   if (sw_if_index_set == 0)
8095     {
8096       errmsg ("missing vpp interface name. ");
8097       return -99;
8098     }
8099
8100   /* Construct the API message */
8101   M (TAP_DELETE_V2, mp);
8102
8103   mp->sw_if_index = ntohl (sw_if_index);
8104
8105   /* send it... */
8106   S (mp);
8107
8108   /* Wait for a reply... */
8109   W (ret);
8110   return ret;
8111 }
8112
8113 static int
8114 api_bond_create (vat_main_t * vam)
8115 {
8116   unformat_input_t *i = vam->input;
8117   vl_api_bond_create_t *mp;
8118   u8 mac_address[6];
8119   u8 custom_mac = 0;
8120   int ret;
8121   u8 mode;
8122   u8 lb;
8123   u8 mode_is_set = 0;
8124
8125   memset (mac_address, 0, sizeof (mac_address));
8126   lb = BOND_LB_L2;
8127
8128   /* Parse args required to build the message */
8129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8130     {
8131       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8132         mode_is_set = 1;
8133       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8134                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8135         ;
8136       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8137                          mac_address))
8138         custom_mac = 1;
8139       else
8140         break;
8141     }
8142
8143   if (mode_is_set == 0)
8144     {
8145       errmsg ("Missing bond mode. ");
8146       return -99;
8147     }
8148
8149   /* Construct the API message */
8150   M (BOND_CREATE, mp);
8151
8152   mp->use_custom_mac = custom_mac;
8153
8154   mp->mode = mode;
8155   mp->lb = lb;
8156
8157   if (custom_mac)
8158     clib_memcpy (mp->mac_address, mac_address, 6);
8159
8160   /* send it... */
8161   S (mp);
8162
8163   /* Wait for a reply... */
8164   W (ret);
8165   return ret;
8166 }
8167
8168 static int
8169 api_bond_delete (vat_main_t * vam)
8170 {
8171   unformat_input_t *i = vam->input;
8172   vl_api_bond_delete_t *mp;
8173   u32 sw_if_index = ~0;
8174   u8 sw_if_index_set = 0;
8175   int ret;
8176
8177   /* Parse args required to build the message */
8178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8179     {
8180       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8181         sw_if_index_set = 1;
8182       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8183         sw_if_index_set = 1;
8184       else
8185         break;
8186     }
8187
8188   if (sw_if_index_set == 0)
8189     {
8190       errmsg ("missing vpp interface name. ");
8191       return -99;
8192     }
8193
8194   /* Construct the API message */
8195   M (BOND_DELETE, mp);
8196
8197   mp->sw_if_index = ntohl (sw_if_index);
8198
8199   /* send it... */
8200   S (mp);
8201
8202   /* Wait for a reply... */
8203   W (ret);
8204   return ret;
8205 }
8206
8207 static int
8208 api_bond_enslave (vat_main_t * vam)
8209 {
8210   unformat_input_t *i = vam->input;
8211   vl_api_bond_enslave_t *mp;
8212   u32 bond_sw_if_index;
8213   int ret;
8214   u8 is_passive;
8215   u8 is_long_timeout;
8216   u32 bond_sw_if_index_is_set = 0;
8217   u32 sw_if_index;
8218   u8 sw_if_index_is_set = 0;
8219
8220   /* Parse args required to build the message */
8221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8222     {
8223       if (unformat (i, "sw_if_index %d", &sw_if_index))
8224         sw_if_index_is_set = 1;
8225       else if (unformat (i, "bond %u", &bond_sw_if_index))
8226         bond_sw_if_index_is_set = 1;
8227       else if (unformat (i, "passive %d", &is_passive))
8228         ;
8229       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8230         ;
8231       else
8232         break;
8233     }
8234
8235   if (bond_sw_if_index_is_set == 0)
8236     {
8237       errmsg ("Missing bond sw_if_index. ");
8238       return -99;
8239     }
8240   if (sw_if_index_is_set == 0)
8241     {
8242       errmsg ("Missing slave sw_if_index. ");
8243       return -99;
8244     }
8245
8246   /* Construct the API message */
8247   M (BOND_ENSLAVE, mp);
8248
8249   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8250   mp->sw_if_index = ntohl (sw_if_index);
8251   mp->is_long_timeout = is_long_timeout;
8252   mp->is_passive = is_passive;
8253
8254   /* send it... */
8255   S (mp);
8256
8257   /* Wait for a reply... */
8258   W (ret);
8259   return ret;
8260 }
8261
8262 static int
8263 api_bond_detach_slave (vat_main_t * vam)
8264 {
8265   unformat_input_t *i = vam->input;
8266   vl_api_bond_detach_slave_t *mp;
8267   u32 sw_if_index = ~0;
8268   u8 sw_if_index_set = 0;
8269   int ret;
8270
8271   /* Parse args required to build the message */
8272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8273     {
8274       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8275         sw_if_index_set = 1;
8276       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8277         sw_if_index_set = 1;
8278       else
8279         break;
8280     }
8281
8282   if (sw_if_index_set == 0)
8283     {
8284       errmsg ("missing vpp interface name. ");
8285       return -99;
8286     }
8287
8288   /* Construct the API message */
8289   M (BOND_DETACH_SLAVE, mp);
8290
8291   mp->sw_if_index = ntohl (sw_if_index);
8292
8293   /* send it... */
8294   S (mp);
8295
8296   /* Wait for a reply... */
8297   W (ret);
8298   return ret;
8299 }
8300
8301 static int
8302 api_ip_table_add_del (vat_main_t * vam)
8303 {
8304   unformat_input_t *i = vam->input;
8305   vl_api_ip_table_add_del_t *mp;
8306   u32 table_id = ~0;
8307   u8 is_ipv6 = 0;
8308   u8 is_add = 1;
8309   int ret = 0;
8310
8311   /* Parse args required to build the message */
8312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8313     {
8314       if (unformat (i, "ipv6"))
8315         is_ipv6 = 1;
8316       else if (unformat (i, "del"))
8317         is_add = 0;
8318       else if (unformat (i, "add"))
8319         is_add = 1;
8320       else if (unformat (i, "table %d", &table_id))
8321         ;
8322       else
8323         {
8324           clib_warning ("parse error '%U'", format_unformat_error, i);
8325           return -99;
8326         }
8327     }
8328
8329   if (~0 == table_id)
8330     {
8331       errmsg ("missing table-ID");
8332       return -99;
8333     }
8334
8335   /* Construct the API message */
8336   M (IP_TABLE_ADD_DEL, mp);
8337
8338   mp->table_id = ntohl (table_id);
8339   mp->is_ipv6 = is_ipv6;
8340   mp->is_add = is_add;
8341
8342   /* send it... */
8343   S (mp);
8344
8345   /* Wait for a reply... */
8346   W (ret);
8347
8348   return ret;
8349 }
8350
8351 static int
8352 api_ip_add_del_route (vat_main_t * vam)
8353 {
8354   unformat_input_t *i = vam->input;
8355   vl_api_ip_add_del_route_t *mp;
8356   u32 sw_if_index = ~0, vrf_id = 0;
8357   u8 is_ipv6 = 0;
8358   u8 is_local = 0, is_drop = 0;
8359   u8 is_unreach = 0, is_prohibit = 0;
8360   u8 is_add = 1;
8361   u32 next_hop_weight = 1;
8362   u8 is_multipath = 0;
8363   u8 address_set = 0;
8364   u8 address_length_set = 0;
8365   u32 next_hop_table_id = 0;
8366   u32 resolve_attempts = 0;
8367   u32 dst_address_length = 0;
8368   u8 next_hop_set = 0;
8369   ip4_address_t v4_dst_address, v4_next_hop_address;
8370   ip6_address_t v6_dst_address, v6_next_hop_address;
8371   int count = 1;
8372   int j;
8373   f64 before = 0;
8374   u32 random_add_del = 0;
8375   u32 *random_vector = 0;
8376   uword *random_hash;
8377   u32 random_seed = 0xdeaddabe;
8378   u32 classify_table_index = ~0;
8379   u8 is_classify = 0;
8380   u8 resolve_host = 0, resolve_attached = 0;
8381   mpls_label_t *next_hop_out_label_stack = NULL;
8382   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8383   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8384
8385   /* Parse args required to build the message */
8386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8387     {
8388       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8389         ;
8390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8391         ;
8392       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8393         {
8394           address_set = 1;
8395           is_ipv6 = 0;
8396         }
8397       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8398         {
8399           address_set = 1;
8400           is_ipv6 = 1;
8401         }
8402       else if (unformat (i, "/%d", &dst_address_length))
8403         {
8404           address_length_set = 1;
8405         }
8406
8407       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8408                                          &v4_next_hop_address))
8409         {
8410           next_hop_set = 1;
8411         }
8412       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8413                                          &v6_next_hop_address))
8414         {
8415           next_hop_set = 1;
8416         }
8417       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8418         ;
8419       else if (unformat (i, "weight %d", &next_hop_weight))
8420         ;
8421       else if (unformat (i, "drop"))
8422         {
8423           is_drop = 1;
8424         }
8425       else if (unformat (i, "null-send-unreach"))
8426         {
8427           is_unreach = 1;
8428         }
8429       else if (unformat (i, "null-send-prohibit"))
8430         {
8431           is_prohibit = 1;
8432         }
8433       else if (unformat (i, "local"))
8434         {
8435           is_local = 1;
8436         }
8437       else if (unformat (i, "classify %d", &classify_table_index))
8438         {
8439           is_classify = 1;
8440         }
8441       else if (unformat (i, "del"))
8442         is_add = 0;
8443       else if (unformat (i, "add"))
8444         is_add = 1;
8445       else if (unformat (i, "resolve-via-host"))
8446         resolve_host = 1;
8447       else if (unformat (i, "resolve-via-attached"))
8448         resolve_attached = 1;
8449       else if (unformat (i, "multipath"))
8450         is_multipath = 1;
8451       else if (unformat (i, "vrf %d", &vrf_id))
8452         ;
8453       else if (unformat (i, "count %d", &count))
8454         ;
8455       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8456         ;
8457       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8458         ;
8459       else if (unformat (i, "out-label %d", &next_hop_out_label))
8460         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8461       else if (unformat (i, "via-label %d", &next_hop_via_label))
8462         ;
8463       else if (unformat (i, "random"))
8464         random_add_del = 1;
8465       else if (unformat (i, "seed %d", &random_seed))
8466         ;
8467       else
8468         {
8469           clib_warning ("parse error '%U'", format_unformat_error, i);
8470           return -99;
8471         }
8472     }
8473
8474   if (!next_hop_set && !is_drop && !is_local &&
8475       !is_classify && !is_unreach && !is_prohibit &&
8476       MPLS_LABEL_INVALID == next_hop_via_label)
8477     {
8478       errmsg
8479         ("next hop / local / drop / unreach / prohibit / classify not set");
8480       return -99;
8481     }
8482
8483   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8484     {
8485       errmsg ("next hop and next-hop via label set");
8486       return -99;
8487     }
8488   if (address_set == 0)
8489     {
8490       errmsg ("missing addresses");
8491       return -99;
8492     }
8493
8494   if (address_length_set == 0)
8495     {
8496       errmsg ("missing address length");
8497       return -99;
8498     }
8499
8500   /* Generate a pile of unique, random routes */
8501   if (random_add_del)
8502     {
8503       u32 this_random_address;
8504       random_hash = hash_create (count, sizeof (uword));
8505
8506       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8507       for (j = 0; j <= count; j++)
8508         {
8509           do
8510             {
8511               this_random_address = random_u32 (&random_seed);
8512               this_random_address =
8513                 clib_host_to_net_u32 (this_random_address);
8514             }
8515           while (hash_get (random_hash, this_random_address));
8516           vec_add1 (random_vector, this_random_address);
8517           hash_set (random_hash, this_random_address, 1);
8518         }
8519       hash_free (random_hash);
8520       v4_dst_address.as_u32 = random_vector[0];
8521     }
8522
8523   if (count > 1)
8524     {
8525       /* Turn on async mode */
8526       vam->async_mode = 1;
8527       vam->async_errors = 0;
8528       before = vat_time_now (vam);
8529     }
8530
8531   for (j = 0; j < count; j++)
8532     {
8533       /* Construct the API message */
8534       M2 (IP_ADD_DEL_ROUTE, mp,
8535           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8536
8537       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8538       mp->table_id = ntohl (vrf_id);
8539
8540       mp->is_add = is_add;
8541       mp->is_drop = is_drop;
8542       mp->is_unreach = is_unreach;
8543       mp->is_prohibit = is_prohibit;
8544       mp->is_ipv6 = is_ipv6;
8545       mp->is_local = is_local;
8546       mp->is_classify = is_classify;
8547       mp->is_multipath = is_multipath;
8548       mp->is_resolve_host = resolve_host;
8549       mp->is_resolve_attached = resolve_attached;
8550       mp->next_hop_weight = next_hop_weight;
8551       mp->dst_address_length = dst_address_length;
8552       mp->next_hop_table_id = ntohl (next_hop_table_id);
8553       mp->classify_table_index = ntohl (classify_table_index);
8554       mp->next_hop_via_label = ntohl (next_hop_via_label);
8555       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8556       if (0 != mp->next_hop_n_out_labels)
8557         {
8558           memcpy (mp->next_hop_out_label_stack,
8559                   next_hop_out_label_stack,
8560                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8561           vec_free (next_hop_out_label_stack);
8562         }
8563
8564       if (is_ipv6)
8565         {
8566           clib_memcpy (mp->dst_address, &v6_dst_address,
8567                        sizeof (v6_dst_address));
8568           if (next_hop_set)
8569             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8570                          sizeof (v6_next_hop_address));
8571           increment_v6_address (&v6_dst_address);
8572         }
8573       else
8574         {
8575           clib_memcpy (mp->dst_address, &v4_dst_address,
8576                        sizeof (v4_dst_address));
8577           if (next_hop_set)
8578             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8579                          sizeof (v4_next_hop_address));
8580           if (random_add_del)
8581             v4_dst_address.as_u32 = random_vector[j + 1];
8582           else
8583             increment_v4_address (&v4_dst_address);
8584         }
8585       /* send it... */
8586       S (mp);
8587       /* If we receive SIGTERM, stop now... */
8588       if (vam->do_exit)
8589         break;
8590     }
8591
8592   /* When testing multiple add/del ops, use a control-ping to sync */
8593   if (count > 1)
8594     {
8595       vl_api_control_ping_t *mp_ping;
8596       f64 after;
8597       f64 timeout;
8598
8599       /* Shut off async mode */
8600       vam->async_mode = 0;
8601
8602       MPING (CONTROL_PING, mp_ping);
8603       S (mp_ping);
8604
8605       timeout = vat_time_now (vam) + 1.0;
8606       while (vat_time_now (vam) < timeout)
8607         if (vam->result_ready == 1)
8608           goto out;
8609       vam->retval = -99;
8610
8611     out:
8612       if (vam->retval == -99)
8613         errmsg ("timeout");
8614
8615       if (vam->async_errors > 0)
8616         {
8617           errmsg ("%d asynchronous errors", vam->async_errors);
8618           vam->retval = -98;
8619         }
8620       vam->async_errors = 0;
8621       after = vat_time_now (vam);
8622
8623       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8624       if (j > 0)
8625         count = j;
8626
8627       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8628              count, after - before, count / (after - before));
8629     }
8630   else
8631     {
8632       int ret;
8633
8634       /* Wait for a reply... */
8635       W (ret);
8636       return ret;
8637     }
8638
8639   /* Return the good/bad news */
8640   return (vam->retval);
8641 }
8642
8643 static int
8644 api_ip_mroute_add_del (vat_main_t * vam)
8645 {
8646   unformat_input_t *i = vam->input;
8647   vl_api_ip_mroute_add_del_t *mp;
8648   u32 sw_if_index = ~0, vrf_id = 0;
8649   u8 is_ipv6 = 0;
8650   u8 is_local = 0;
8651   u8 is_add = 1;
8652   u8 address_set = 0;
8653   u32 grp_address_length = 0;
8654   ip4_address_t v4_grp_address, v4_src_address;
8655   ip6_address_t v6_grp_address, v6_src_address;
8656   mfib_itf_flags_t iflags = 0;
8657   mfib_entry_flags_t eflags = 0;
8658   int ret;
8659
8660   /* Parse args required to build the message */
8661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8662     {
8663       if (unformat (i, "sw_if_index %d", &sw_if_index))
8664         ;
8665       else if (unformat (i, "%U %U",
8666                          unformat_ip4_address, &v4_src_address,
8667                          unformat_ip4_address, &v4_grp_address))
8668         {
8669           grp_address_length = 64;
8670           address_set = 1;
8671           is_ipv6 = 0;
8672         }
8673       else if (unformat (i, "%U %U",
8674                          unformat_ip6_address, &v6_src_address,
8675                          unformat_ip6_address, &v6_grp_address))
8676         {
8677           grp_address_length = 256;
8678           address_set = 1;
8679           is_ipv6 = 1;
8680         }
8681       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8682         {
8683           memset (&v4_src_address, 0, sizeof (v4_src_address));
8684           grp_address_length = 32;
8685           address_set = 1;
8686           is_ipv6 = 0;
8687         }
8688       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8689         {
8690           memset (&v6_src_address, 0, sizeof (v6_src_address));
8691           grp_address_length = 128;
8692           address_set = 1;
8693           is_ipv6 = 1;
8694         }
8695       else if (unformat (i, "/%d", &grp_address_length))
8696         ;
8697       else if (unformat (i, "local"))
8698         {
8699           is_local = 1;
8700         }
8701       else if (unformat (i, "del"))
8702         is_add = 0;
8703       else if (unformat (i, "add"))
8704         is_add = 1;
8705       else if (unformat (i, "vrf %d", &vrf_id))
8706         ;
8707       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8708         ;
8709       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8710         ;
8711       else
8712         {
8713           clib_warning ("parse error '%U'", format_unformat_error, i);
8714           return -99;
8715         }
8716     }
8717
8718   if (address_set == 0)
8719     {
8720       errmsg ("missing addresses\n");
8721       return -99;
8722     }
8723
8724   /* Construct the API message */
8725   M (IP_MROUTE_ADD_DEL, mp);
8726
8727   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8728   mp->table_id = ntohl (vrf_id);
8729
8730   mp->is_add = is_add;
8731   mp->is_ipv6 = is_ipv6;
8732   mp->is_local = is_local;
8733   mp->itf_flags = ntohl (iflags);
8734   mp->entry_flags = ntohl (eflags);
8735   mp->grp_address_length = grp_address_length;
8736   mp->grp_address_length = ntohs (mp->grp_address_length);
8737
8738   if (is_ipv6)
8739     {
8740       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8741       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8742     }
8743   else
8744     {
8745       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8746       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8747
8748     }
8749
8750   /* send it... */
8751   S (mp);
8752   /* Wait for a reply... */
8753   W (ret);
8754   return ret;
8755 }
8756
8757 static int
8758 api_mpls_table_add_del (vat_main_t * vam)
8759 {
8760   unformat_input_t *i = vam->input;
8761   vl_api_mpls_table_add_del_t *mp;
8762   u32 table_id = ~0;
8763   u8 is_add = 1;
8764   int ret = 0;
8765
8766   /* Parse args required to build the message */
8767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8768     {
8769       if (unformat (i, "table %d", &table_id))
8770         ;
8771       else if (unformat (i, "del"))
8772         is_add = 0;
8773       else if (unformat (i, "add"))
8774         is_add = 1;
8775       else
8776         {
8777           clib_warning ("parse error '%U'", format_unformat_error, i);
8778           return -99;
8779         }
8780     }
8781
8782   if (~0 == table_id)
8783     {
8784       errmsg ("missing table-ID");
8785       return -99;
8786     }
8787
8788   /* Construct the API message */
8789   M (MPLS_TABLE_ADD_DEL, mp);
8790
8791   mp->mt_table_id = ntohl (table_id);
8792   mp->mt_is_add = is_add;
8793
8794   /* send it... */
8795   S (mp);
8796
8797   /* Wait for a reply... */
8798   W (ret);
8799
8800   return ret;
8801 }
8802
8803 static int
8804 api_mpls_route_add_del (vat_main_t * vam)
8805 {
8806   unformat_input_t *i = vam->input;
8807   vl_api_mpls_route_add_del_t *mp;
8808   u32 sw_if_index = ~0, table_id = 0;
8809   u8 is_add = 1;
8810   u32 next_hop_weight = 1;
8811   u8 is_multipath = 0;
8812   u32 next_hop_table_id = 0;
8813   u8 next_hop_set = 0;
8814   ip4_address_t v4_next_hop_address = {
8815     .as_u32 = 0,
8816   };
8817   ip6_address_t v6_next_hop_address = { {0} };
8818   int count = 1;
8819   int j;
8820   f64 before = 0;
8821   u32 classify_table_index = ~0;
8822   u8 is_classify = 0;
8823   u8 resolve_host = 0, resolve_attached = 0;
8824   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8825   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8826   mpls_label_t *next_hop_out_label_stack = NULL;
8827   mpls_label_t local_label = MPLS_LABEL_INVALID;
8828   u8 is_eos = 0;
8829   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8830
8831   /* Parse args required to build the message */
8832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8833     {
8834       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8835         ;
8836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8837         ;
8838       else if (unformat (i, "%d", &local_label))
8839         ;
8840       else if (unformat (i, "eos"))
8841         is_eos = 1;
8842       else if (unformat (i, "non-eos"))
8843         is_eos = 0;
8844       else if (unformat (i, "via %U", unformat_ip4_address,
8845                          &v4_next_hop_address))
8846         {
8847           next_hop_set = 1;
8848           next_hop_proto = DPO_PROTO_IP4;
8849         }
8850       else if (unformat (i, "via %U", unformat_ip6_address,
8851                          &v6_next_hop_address))
8852         {
8853           next_hop_set = 1;
8854           next_hop_proto = DPO_PROTO_IP6;
8855         }
8856       else if (unformat (i, "weight %d", &next_hop_weight))
8857         ;
8858       else if (unformat (i, "classify %d", &classify_table_index))
8859         {
8860           is_classify = 1;
8861         }
8862       else if (unformat (i, "del"))
8863         is_add = 0;
8864       else if (unformat (i, "add"))
8865         is_add = 1;
8866       else if (unformat (i, "resolve-via-host"))
8867         resolve_host = 1;
8868       else if (unformat (i, "resolve-via-attached"))
8869         resolve_attached = 1;
8870       else if (unformat (i, "multipath"))
8871         is_multipath = 1;
8872       else if (unformat (i, "count %d", &count))
8873         ;
8874       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8875         {
8876           next_hop_set = 1;
8877           next_hop_proto = DPO_PROTO_IP4;
8878         }
8879       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8880         {
8881           next_hop_set = 1;
8882           next_hop_proto = DPO_PROTO_IP6;
8883         }
8884       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8885         ;
8886       else if (unformat (i, "via-label %d", &next_hop_via_label))
8887         ;
8888       else if (unformat (i, "out-label %d", &next_hop_out_label))
8889         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8890       else
8891         {
8892           clib_warning ("parse error '%U'", format_unformat_error, i);
8893           return -99;
8894         }
8895     }
8896
8897   if (!next_hop_set && !is_classify)
8898     {
8899       errmsg ("next hop / classify not set");
8900       return -99;
8901     }
8902
8903   if (MPLS_LABEL_INVALID == local_label)
8904     {
8905       errmsg ("missing label");
8906       return -99;
8907     }
8908
8909   if (count > 1)
8910     {
8911       /* Turn on async mode */
8912       vam->async_mode = 1;
8913       vam->async_errors = 0;
8914       before = vat_time_now (vam);
8915     }
8916
8917   for (j = 0; j < count; j++)
8918     {
8919       /* Construct the API message */
8920       M2 (MPLS_ROUTE_ADD_DEL, mp,
8921           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8922
8923       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8924       mp->mr_table_id = ntohl (table_id);
8925
8926       mp->mr_is_add = is_add;
8927       mp->mr_next_hop_proto = next_hop_proto;
8928       mp->mr_is_classify = is_classify;
8929       mp->mr_is_multipath = is_multipath;
8930       mp->mr_is_resolve_host = resolve_host;
8931       mp->mr_is_resolve_attached = resolve_attached;
8932       mp->mr_next_hop_weight = next_hop_weight;
8933       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8934       mp->mr_classify_table_index = ntohl (classify_table_index);
8935       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8936       mp->mr_label = ntohl (local_label);
8937       mp->mr_eos = is_eos;
8938
8939       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8940       if (0 != mp->mr_next_hop_n_out_labels)
8941         {
8942           memcpy (mp->mr_next_hop_out_label_stack,
8943                   next_hop_out_label_stack,
8944                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8945           vec_free (next_hop_out_label_stack);
8946         }
8947
8948       if (next_hop_set)
8949         {
8950           if (DPO_PROTO_IP4 == next_hop_proto)
8951             {
8952               clib_memcpy (mp->mr_next_hop,
8953                            &v4_next_hop_address,
8954                            sizeof (v4_next_hop_address));
8955             }
8956           else if (DPO_PROTO_IP6 == next_hop_proto)
8957
8958             {
8959               clib_memcpy (mp->mr_next_hop,
8960                            &v6_next_hop_address,
8961                            sizeof (v6_next_hop_address));
8962             }
8963         }
8964       local_label++;
8965
8966       /* send it... */
8967       S (mp);
8968       /* If we receive SIGTERM, stop now... */
8969       if (vam->do_exit)
8970         break;
8971     }
8972
8973   /* When testing multiple add/del ops, use a control-ping to sync */
8974   if (count > 1)
8975     {
8976       vl_api_control_ping_t *mp_ping;
8977       f64 after;
8978       f64 timeout;
8979
8980       /* Shut off async mode */
8981       vam->async_mode = 0;
8982
8983       MPING (CONTROL_PING, mp_ping);
8984       S (mp_ping);
8985
8986       timeout = vat_time_now (vam) + 1.0;
8987       while (vat_time_now (vam) < timeout)
8988         if (vam->result_ready == 1)
8989           goto out;
8990       vam->retval = -99;
8991
8992     out:
8993       if (vam->retval == -99)
8994         errmsg ("timeout");
8995
8996       if (vam->async_errors > 0)
8997         {
8998           errmsg ("%d asynchronous errors", vam->async_errors);
8999           vam->retval = -98;
9000         }
9001       vam->async_errors = 0;
9002       after = vat_time_now (vam);
9003
9004       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9005       if (j > 0)
9006         count = j;
9007
9008       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9009              count, after - before, count / (after - before));
9010     }
9011   else
9012     {
9013       int ret;
9014
9015       /* Wait for a reply... */
9016       W (ret);
9017       return ret;
9018     }
9019
9020   /* Return the good/bad news */
9021   return (vam->retval);
9022 }
9023
9024 static int
9025 api_mpls_ip_bind_unbind (vat_main_t * vam)
9026 {
9027   unformat_input_t *i = vam->input;
9028   vl_api_mpls_ip_bind_unbind_t *mp;
9029   u32 ip_table_id = 0;
9030   u8 is_bind = 1;
9031   u8 is_ip4 = 1;
9032   ip4_address_t v4_address;
9033   ip6_address_t v6_address;
9034   u32 address_length;
9035   u8 address_set = 0;
9036   mpls_label_t local_label = MPLS_LABEL_INVALID;
9037   int ret;
9038
9039   /* Parse args required to build the message */
9040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9041     {
9042       if (unformat (i, "%U/%d", unformat_ip4_address,
9043                     &v4_address, &address_length))
9044         {
9045           is_ip4 = 1;
9046           address_set = 1;
9047         }
9048       else if (unformat (i, "%U/%d", unformat_ip6_address,
9049                          &v6_address, &address_length))
9050         {
9051           is_ip4 = 0;
9052           address_set = 1;
9053         }
9054       else if (unformat (i, "%d", &local_label))
9055         ;
9056       else if (unformat (i, "table-id %d", &ip_table_id))
9057         ;
9058       else if (unformat (i, "unbind"))
9059         is_bind = 0;
9060       else if (unformat (i, "bind"))
9061         is_bind = 1;
9062       else
9063         {
9064           clib_warning ("parse error '%U'", format_unformat_error, i);
9065           return -99;
9066         }
9067     }
9068
9069   if (!address_set)
9070     {
9071       errmsg ("IP addres not set");
9072       return -99;
9073     }
9074
9075   if (MPLS_LABEL_INVALID == local_label)
9076     {
9077       errmsg ("missing label");
9078       return -99;
9079     }
9080
9081   /* Construct the API message */
9082   M (MPLS_IP_BIND_UNBIND, mp);
9083
9084   mp->mb_is_bind = is_bind;
9085   mp->mb_is_ip4 = is_ip4;
9086   mp->mb_ip_table_id = ntohl (ip_table_id);
9087   mp->mb_mpls_table_id = 0;
9088   mp->mb_label = ntohl (local_label);
9089   mp->mb_address_length = address_length;
9090
9091   if (is_ip4)
9092     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9093   else
9094     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9095
9096   /* send it... */
9097   S (mp);
9098
9099   /* Wait for a reply... */
9100   W (ret);
9101   return ret;
9102 }
9103
9104 static int
9105 api_bier_table_add_del (vat_main_t * vam)
9106 {
9107   unformat_input_t *i = vam->input;
9108   vl_api_bier_table_add_del_t *mp;
9109   u8 is_add = 1;
9110   u32 set = 0, sub_domain = 0, hdr_len = 3;
9111   mpls_label_t local_label = MPLS_LABEL_INVALID;
9112   int ret;
9113
9114   /* Parse args required to build the message */
9115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9116     {
9117       if (unformat (i, "sub-domain %d", &sub_domain))
9118         ;
9119       else if (unformat (i, "set %d", &set))
9120         ;
9121       else if (unformat (i, "label %d", &local_label))
9122         ;
9123       else if (unformat (i, "hdr-len %d", &hdr_len))
9124         ;
9125       else if (unformat (i, "add"))
9126         is_add = 1;
9127       else if (unformat (i, "del"))
9128         is_add = 0;
9129       else
9130         {
9131           clib_warning ("parse error '%U'", format_unformat_error, i);
9132           return -99;
9133         }
9134     }
9135
9136   if (MPLS_LABEL_INVALID == local_label)
9137     {
9138       errmsg ("missing label\n");
9139       return -99;
9140     }
9141
9142   /* Construct the API message */
9143   M (BIER_TABLE_ADD_DEL, mp);
9144
9145   mp->bt_is_add = is_add;
9146   mp->bt_label = ntohl (local_label);
9147   mp->bt_tbl_id.bt_set = set;
9148   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9149   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9150
9151   /* send it... */
9152   S (mp);
9153
9154   /* Wait for a reply... */
9155   W (ret);
9156
9157   return (ret);
9158 }
9159
9160 static int
9161 api_bier_route_add_del (vat_main_t * vam)
9162 {
9163   unformat_input_t *i = vam->input;
9164   vl_api_bier_route_add_del_t *mp;
9165   u8 is_add = 1;
9166   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9167   ip4_address_t v4_next_hop_address;
9168   ip6_address_t v6_next_hop_address;
9169   u8 next_hop_set = 0;
9170   u8 next_hop_proto_is_ip4 = 1;
9171   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9172   int ret;
9173
9174   /* Parse args required to build the message */
9175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9176     {
9177       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9178         {
9179           next_hop_proto_is_ip4 = 1;
9180           next_hop_set = 1;
9181         }
9182       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9183         {
9184           next_hop_proto_is_ip4 = 0;
9185           next_hop_set = 1;
9186         }
9187       if (unformat (i, "sub-domain %d", &sub_domain))
9188         ;
9189       else if (unformat (i, "set %d", &set))
9190         ;
9191       else if (unformat (i, "hdr-len %d", &hdr_len))
9192         ;
9193       else if (unformat (i, "bp %d", &bp))
9194         ;
9195       else if (unformat (i, "add"))
9196         is_add = 1;
9197       else if (unformat (i, "del"))
9198         is_add = 0;
9199       else if (unformat (i, "out-label %d", &next_hop_out_label))
9200         ;
9201       else
9202         {
9203           clib_warning ("parse error '%U'", format_unformat_error, i);
9204           return -99;
9205         }
9206     }
9207
9208   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9209     {
9210       errmsg ("next hop / label set\n");
9211       return -99;
9212     }
9213   if (0 == bp)
9214     {
9215       errmsg ("bit=position not set\n");
9216       return -99;
9217     }
9218
9219   /* Construct the API message */
9220   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9221
9222   mp->br_is_add = is_add;
9223   mp->br_tbl_id.bt_set = set;
9224   mp->br_tbl_id.bt_sub_domain = sub_domain;
9225   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9226   mp->br_bp = ntohs (bp);
9227   mp->br_n_paths = 1;
9228   mp->br_paths[0].n_labels = 1;
9229   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9230   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9231
9232   if (next_hop_proto_is_ip4)
9233     {
9234       clib_memcpy (mp->br_paths[0].next_hop,
9235                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9236     }
9237   else
9238     {
9239       clib_memcpy (mp->br_paths[0].next_hop,
9240                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9241     }
9242
9243   /* send it... */
9244   S (mp);
9245
9246   /* Wait for a reply... */
9247   W (ret);
9248
9249   return (ret);
9250 }
9251
9252 static int
9253 api_proxy_arp_add_del (vat_main_t * vam)
9254 {
9255   unformat_input_t *i = vam->input;
9256   vl_api_proxy_arp_add_del_t *mp;
9257   u32 vrf_id = 0;
9258   u8 is_add = 1;
9259   ip4_address_t lo, hi;
9260   u8 range_set = 0;
9261   int ret;
9262
9263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9264     {
9265       if (unformat (i, "vrf %d", &vrf_id))
9266         ;
9267       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9268                          unformat_ip4_address, &hi))
9269         range_set = 1;
9270       else if (unformat (i, "del"))
9271         is_add = 0;
9272       else
9273         {
9274           clib_warning ("parse error '%U'", format_unformat_error, i);
9275           return -99;
9276         }
9277     }
9278
9279   if (range_set == 0)
9280     {
9281       errmsg ("address range not set");
9282       return -99;
9283     }
9284
9285   M (PROXY_ARP_ADD_DEL, mp);
9286
9287   mp->vrf_id = ntohl (vrf_id);
9288   mp->is_add = is_add;
9289   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
9290   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
9291
9292   S (mp);
9293   W (ret);
9294   return ret;
9295 }
9296
9297 static int
9298 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9299 {
9300   unformat_input_t *i = vam->input;
9301   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9302   u32 sw_if_index;
9303   u8 enable = 1;
9304   u8 sw_if_index_set = 0;
9305   int ret;
9306
9307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9308     {
9309       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9310         sw_if_index_set = 1;
9311       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9312         sw_if_index_set = 1;
9313       else if (unformat (i, "enable"))
9314         enable = 1;
9315       else if (unformat (i, "disable"))
9316         enable = 0;
9317       else
9318         {
9319           clib_warning ("parse error '%U'", format_unformat_error, i);
9320           return -99;
9321         }
9322     }
9323
9324   if (sw_if_index_set == 0)
9325     {
9326       errmsg ("missing interface name or sw_if_index");
9327       return -99;
9328     }
9329
9330   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9331
9332   mp->sw_if_index = ntohl (sw_if_index);
9333   mp->enable_disable = enable;
9334
9335   S (mp);
9336   W (ret);
9337   return ret;
9338 }
9339
9340 static int
9341 api_mpls_tunnel_add_del (vat_main_t * vam)
9342 {
9343   unformat_input_t *i = vam->input;
9344   vl_api_mpls_tunnel_add_del_t *mp;
9345
9346   u8 is_add = 1;
9347   u8 l2_only = 0;
9348   u32 sw_if_index = ~0;
9349   u32 next_hop_sw_if_index = ~0;
9350   u32 next_hop_proto_is_ip4 = 1;
9351
9352   u32 next_hop_table_id = 0;
9353   ip4_address_t v4_next_hop_address = {
9354     .as_u32 = 0,
9355   };
9356   ip6_address_t v6_next_hop_address = { {0} };
9357   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9358   int ret;
9359
9360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9361     {
9362       if (unformat (i, "add"))
9363         is_add = 1;
9364       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9365         is_add = 0;
9366       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9367         ;
9368       else if (unformat (i, "via %U",
9369                          unformat_ip4_address, &v4_next_hop_address))
9370         {
9371           next_hop_proto_is_ip4 = 1;
9372         }
9373       else if (unformat (i, "via %U",
9374                          unformat_ip6_address, &v6_next_hop_address))
9375         {
9376           next_hop_proto_is_ip4 = 0;
9377         }
9378       else if (unformat (i, "l2-only"))
9379         l2_only = 1;
9380       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9381         ;
9382       else if (unformat (i, "out-label %d", &next_hop_out_label))
9383         vec_add1 (labels, ntohl (next_hop_out_label));
9384       else
9385         {
9386           clib_warning ("parse error '%U'", format_unformat_error, i);
9387           return -99;
9388         }
9389     }
9390
9391   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9392
9393   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9394   mp->mt_sw_if_index = ntohl (sw_if_index);
9395   mp->mt_is_add = is_add;
9396   mp->mt_l2_only = l2_only;
9397   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9398   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9399
9400   mp->mt_next_hop_n_out_labels = vec_len (labels);
9401
9402   if (0 != mp->mt_next_hop_n_out_labels)
9403     {
9404       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9405                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9406       vec_free (labels);
9407     }
9408
9409   if (next_hop_proto_is_ip4)
9410     {
9411       clib_memcpy (mp->mt_next_hop,
9412                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9413     }
9414   else
9415     {
9416       clib_memcpy (mp->mt_next_hop,
9417                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9418     }
9419
9420   S (mp);
9421   W (ret);
9422   return ret;
9423 }
9424
9425 static int
9426 api_sw_interface_set_unnumbered (vat_main_t * vam)
9427 {
9428   unformat_input_t *i = vam->input;
9429   vl_api_sw_interface_set_unnumbered_t *mp;
9430   u32 sw_if_index;
9431   u32 unnum_sw_index = ~0;
9432   u8 is_add = 1;
9433   u8 sw_if_index_set = 0;
9434   int ret;
9435
9436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9437     {
9438       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9439         sw_if_index_set = 1;
9440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9441         sw_if_index_set = 1;
9442       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9443         ;
9444       else if (unformat (i, "del"))
9445         is_add = 0;
9446       else
9447         {
9448           clib_warning ("parse error '%U'", format_unformat_error, i);
9449           return -99;
9450         }
9451     }
9452
9453   if (sw_if_index_set == 0)
9454     {
9455       errmsg ("missing interface name or sw_if_index");
9456       return -99;
9457     }
9458
9459   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9460
9461   mp->sw_if_index = ntohl (sw_if_index);
9462   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9463   mp->is_add = is_add;
9464
9465   S (mp);
9466   W (ret);
9467   return ret;
9468 }
9469
9470 static int
9471 api_ip_neighbor_add_del (vat_main_t * vam)
9472 {
9473   unformat_input_t *i = vam->input;
9474   vl_api_ip_neighbor_add_del_t *mp;
9475   u32 sw_if_index;
9476   u8 sw_if_index_set = 0;
9477   u8 is_add = 1;
9478   u8 is_static = 0;
9479   u8 is_no_fib_entry = 0;
9480   u8 mac_address[6];
9481   u8 mac_set = 0;
9482   u8 v4_address_set = 0;
9483   u8 v6_address_set = 0;
9484   ip4_address_t v4address;
9485   ip6_address_t v6address;
9486   int ret;
9487
9488   memset (mac_address, 0, sizeof (mac_address));
9489
9490   /* Parse args required to build the message */
9491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9492     {
9493       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9494         {
9495           mac_set = 1;
9496         }
9497       else if (unformat (i, "del"))
9498         is_add = 0;
9499       else
9500         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9501         sw_if_index_set = 1;
9502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9503         sw_if_index_set = 1;
9504       else if (unformat (i, "is_static"))
9505         is_static = 1;
9506       else if (unformat (i, "no-fib-entry"))
9507         is_no_fib_entry = 1;
9508       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9509         v4_address_set = 1;
9510       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9511         v6_address_set = 1;
9512       else
9513         {
9514           clib_warning ("parse error '%U'", format_unformat_error, i);
9515           return -99;
9516         }
9517     }
9518
9519   if (sw_if_index_set == 0)
9520     {
9521       errmsg ("missing interface name or sw_if_index");
9522       return -99;
9523     }
9524   if (v4_address_set && v6_address_set)
9525     {
9526       errmsg ("both v4 and v6 addresses set");
9527       return -99;
9528     }
9529   if (!v4_address_set && !v6_address_set)
9530     {
9531       errmsg ("no address set");
9532       return -99;
9533     }
9534
9535   /* Construct the API message */
9536   M (IP_NEIGHBOR_ADD_DEL, mp);
9537
9538   mp->sw_if_index = ntohl (sw_if_index);
9539   mp->is_add = is_add;
9540   mp->is_static = is_static;
9541   mp->is_no_adj_fib = is_no_fib_entry;
9542   if (mac_set)
9543     clib_memcpy (mp->mac_address, mac_address, 6);
9544   if (v6_address_set)
9545     {
9546       mp->is_ipv6 = 1;
9547       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9548     }
9549   else
9550     {
9551       /* mp->is_ipv6 = 0; via memset in M macro above */
9552       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9553     }
9554
9555   /* send it... */
9556   S (mp);
9557
9558   /* Wait for a reply, return good/bad news  */
9559   W (ret);
9560   return ret;
9561 }
9562
9563 static int
9564 api_create_vlan_subif (vat_main_t * vam)
9565 {
9566   unformat_input_t *i = vam->input;
9567   vl_api_create_vlan_subif_t *mp;
9568   u32 sw_if_index;
9569   u8 sw_if_index_set = 0;
9570   u32 vlan_id;
9571   u8 vlan_id_set = 0;
9572   int ret;
9573
9574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (i, "sw_if_index %d", &sw_if_index))
9577         sw_if_index_set = 1;
9578       else
9579         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9580         sw_if_index_set = 1;
9581       else if (unformat (i, "vlan %d", &vlan_id))
9582         vlan_id_set = 1;
9583       else
9584         {
9585           clib_warning ("parse error '%U'", format_unformat_error, i);
9586           return -99;
9587         }
9588     }
9589
9590   if (sw_if_index_set == 0)
9591     {
9592       errmsg ("missing interface name or sw_if_index");
9593       return -99;
9594     }
9595
9596   if (vlan_id_set == 0)
9597     {
9598       errmsg ("missing vlan_id");
9599       return -99;
9600     }
9601   M (CREATE_VLAN_SUBIF, mp);
9602
9603   mp->sw_if_index = ntohl (sw_if_index);
9604   mp->vlan_id = ntohl (vlan_id);
9605
9606   S (mp);
9607   W (ret);
9608   return ret;
9609 }
9610
9611 #define foreach_create_subif_bit                \
9612 _(no_tags)                                      \
9613 _(one_tag)                                      \
9614 _(two_tags)                                     \
9615 _(dot1ad)                                       \
9616 _(exact_match)                                  \
9617 _(default_sub)                                  \
9618 _(outer_vlan_id_any)                            \
9619 _(inner_vlan_id_any)
9620
9621 static int
9622 api_create_subif (vat_main_t * vam)
9623 {
9624   unformat_input_t *i = vam->input;
9625   vl_api_create_subif_t *mp;
9626   u32 sw_if_index;
9627   u8 sw_if_index_set = 0;
9628   u32 sub_id;
9629   u8 sub_id_set = 0;
9630   u32 no_tags = 0;
9631   u32 one_tag = 0;
9632   u32 two_tags = 0;
9633   u32 dot1ad = 0;
9634   u32 exact_match = 0;
9635   u32 default_sub = 0;
9636   u32 outer_vlan_id_any = 0;
9637   u32 inner_vlan_id_any = 0;
9638   u32 tmp;
9639   u16 outer_vlan_id = 0;
9640   u16 inner_vlan_id = 0;
9641   int ret;
9642
9643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9644     {
9645       if (unformat (i, "sw_if_index %d", &sw_if_index))
9646         sw_if_index_set = 1;
9647       else
9648         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9649         sw_if_index_set = 1;
9650       else if (unformat (i, "sub_id %d", &sub_id))
9651         sub_id_set = 1;
9652       else if (unformat (i, "outer_vlan_id %d", &tmp))
9653         outer_vlan_id = tmp;
9654       else if (unformat (i, "inner_vlan_id %d", &tmp))
9655         inner_vlan_id = tmp;
9656
9657 #define _(a) else if (unformat (i, #a)) a = 1 ;
9658       foreach_create_subif_bit
9659 #undef _
9660         else
9661         {
9662           clib_warning ("parse error '%U'", format_unformat_error, i);
9663           return -99;
9664         }
9665     }
9666
9667   if (sw_if_index_set == 0)
9668     {
9669       errmsg ("missing interface name or sw_if_index");
9670       return -99;
9671     }
9672
9673   if (sub_id_set == 0)
9674     {
9675       errmsg ("missing sub_id");
9676       return -99;
9677     }
9678   M (CREATE_SUBIF, mp);
9679
9680   mp->sw_if_index = ntohl (sw_if_index);
9681   mp->sub_id = ntohl (sub_id);
9682
9683 #define _(a) mp->a = a;
9684   foreach_create_subif_bit;
9685 #undef _
9686
9687   mp->outer_vlan_id = ntohs (outer_vlan_id);
9688   mp->inner_vlan_id = ntohs (inner_vlan_id);
9689
9690   S (mp);
9691   W (ret);
9692   return ret;
9693 }
9694
9695 static int
9696 api_oam_add_del (vat_main_t * vam)
9697 {
9698   unformat_input_t *i = vam->input;
9699   vl_api_oam_add_del_t *mp;
9700   u32 vrf_id = 0;
9701   u8 is_add = 1;
9702   ip4_address_t src, dst;
9703   u8 src_set = 0;
9704   u8 dst_set = 0;
9705   int ret;
9706
9707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9708     {
9709       if (unformat (i, "vrf %d", &vrf_id))
9710         ;
9711       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9712         src_set = 1;
9713       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9714         dst_set = 1;
9715       else if (unformat (i, "del"))
9716         is_add = 0;
9717       else
9718         {
9719           clib_warning ("parse error '%U'", format_unformat_error, i);
9720           return -99;
9721         }
9722     }
9723
9724   if (src_set == 0)
9725     {
9726       errmsg ("missing src addr");
9727       return -99;
9728     }
9729
9730   if (dst_set == 0)
9731     {
9732       errmsg ("missing dst addr");
9733       return -99;
9734     }
9735
9736   M (OAM_ADD_DEL, mp);
9737
9738   mp->vrf_id = ntohl (vrf_id);
9739   mp->is_add = is_add;
9740   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9741   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9742
9743   S (mp);
9744   W (ret);
9745   return ret;
9746 }
9747
9748 static int
9749 api_reset_fib (vat_main_t * vam)
9750 {
9751   unformat_input_t *i = vam->input;
9752   vl_api_reset_fib_t *mp;
9753   u32 vrf_id = 0;
9754   u8 is_ipv6 = 0;
9755   u8 vrf_id_set = 0;
9756
9757   int ret;
9758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9759     {
9760       if (unformat (i, "vrf %d", &vrf_id))
9761         vrf_id_set = 1;
9762       else if (unformat (i, "ipv6"))
9763         is_ipv6 = 1;
9764       else
9765         {
9766           clib_warning ("parse error '%U'", format_unformat_error, i);
9767           return -99;
9768         }
9769     }
9770
9771   if (vrf_id_set == 0)
9772     {
9773       errmsg ("missing vrf id");
9774       return -99;
9775     }
9776
9777   M (RESET_FIB, mp);
9778
9779   mp->vrf_id = ntohl (vrf_id);
9780   mp->is_ipv6 = is_ipv6;
9781
9782   S (mp);
9783   W (ret);
9784   return ret;
9785 }
9786
9787 static int
9788 api_dhcp_proxy_config (vat_main_t * vam)
9789 {
9790   unformat_input_t *i = vam->input;
9791   vl_api_dhcp_proxy_config_t *mp;
9792   u32 rx_vrf_id = 0;
9793   u32 server_vrf_id = 0;
9794   u8 is_add = 1;
9795   u8 v4_address_set = 0;
9796   u8 v6_address_set = 0;
9797   ip4_address_t v4address;
9798   ip6_address_t v6address;
9799   u8 v4_src_address_set = 0;
9800   u8 v6_src_address_set = 0;
9801   ip4_address_t v4srcaddress;
9802   ip6_address_t v6srcaddress;
9803   int ret;
9804
9805   /* Parse args required to build the message */
9806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9807     {
9808       if (unformat (i, "del"))
9809         is_add = 0;
9810       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9811         ;
9812       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9813         ;
9814       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9815         v4_address_set = 1;
9816       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9817         v6_address_set = 1;
9818       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9819         v4_src_address_set = 1;
9820       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9821         v6_src_address_set = 1;
9822       else
9823         break;
9824     }
9825
9826   if (v4_address_set && v6_address_set)
9827     {
9828       errmsg ("both v4 and v6 server addresses set");
9829       return -99;
9830     }
9831   if (!v4_address_set && !v6_address_set)
9832     {
9833       errmsg ("no server addresses set");
9834       return -99;
9835     }
9836
9837   if (v4_src_address_set && v6_src_address_set)
9838     {
9839       errmsg ("both v4 and v6  src addresses set");
9840       return -99;
9841     }
9842   if (!v4_src_address_set && !v6_src_address_set)
9843     {
9844       errmsg ("no src addresses set");
9845       return -99;
9846     }
9847
9848   if (!(v4_src_address_set && v4_address_set) &&
9849       !(v6_src_address_set && v6_address_set))
9850     {
9851       errmsg ("no matching server and src addresses set");
9852       return -99;
9853     }
9854
9855   /* Construct the API message */
9856   M (DHCP_PROXY_CONFIG, mp);
9857
9858   mp->is_add = is_add;
9859   mp->rx_vrf_id = ntohl (rx_vrf_id);
9860   mp->server_vrf_id = ntohl (server_vrf_id);
9861   if (v6_address_set)
9862     {
9863       mp->is_ipv6 = 1;
9864       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9865       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9866     }
9867   else
9868     {
9869       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9870       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9871     }
9872
9873   /* send it... */
9874   S (mp);
9875
9876   /* Wait for a reply, return good/bad news  */
9877   W (ret);
9878   return ret;
9879 }
9880
9881 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9882 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9883
9884 static void
9885 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9886 {
9887   vat_main_t *vam = &vat_main;
9888   u32 i, count = mp->count;
9889   vl_api_dhcp_server_t *s;
9890
9891   if (mp->is_ipv6)
9892     print (vam->ofp,
9893            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9894            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9895            ntohl (mp->rx_vrf_id),
9896            format_ip6_address, mp->dhcp_src_address,
9897            mp->vss_type, mp->vss_vpn_ascii_id,
9898            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9899   else
9900     print (vam->ofp,
9901            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9902            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9903            ntohl (mp->rx_vrf_id),
9904            format_ip4_address, mp->dhcp_src_address,
9905            mp->vss_type, mp->vss_vpn_ascii_id,
9906            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9907
9908   for (i = 0; i < count; i++)
9909     {
9910       s = &mp->servers[i];
9911
9912       if (mp->is_ipv6)
9913         print (vam->ofp,
9914                " Server Table-ID %d, Server Address %U",
9915                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9916       else
9917         print (vam->ofp,
9918                " Server Table-ID %d, Server Address %U",
9919                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9920     }
9921 }
9922
9923 static void vl_api_dhcp_proxy_details_t_handler_json
9924   (vl_api_dhcp_proxy_details_t * mp)
9925 {
9926   vat_main_t *vam = &vat_main;
9927   vat_json_node_t *node = NULL;
9928   u32 i, count = mp->count;
9929   struct in_addr ip4;
9930   struct in6_addr ip6;
9931   vl_api_dhcp_server_t *s;
9932
9933   if (VAT_JSON_ARRAY != vam->json_tree.type)
9934     {
9935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9936       vat_json_init_array (&vam->json_tree);
9937     }
9938   node = vat_json_array_add (&vam->json_tree);
9939
9940   vat_json_init_object (node);
9941   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9942   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9943                              sizeof (mp->vss_type));
9944   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9945                                    mp->vss_vpn_ascii_id);
9946   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9947   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9948
9949   if (mp->is_ipv6)
9950     {
9951       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9952       vat_json_object_add_ip6 (node, "src_address", ip6);
9953     }
9954   else
9955     {
9956       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9957       vat_json_object_add_ip4 (node, "src_address", ip4);
9958     }
9959
9960   for (i = 0; i < count; i++)
9961     {
9962       s = &mp->servers[i];
9963
9964       vat_json_object_add_uint (node, "server-table-id",
9965                                 ntohl (s->server_vrf_id));
9966
9967       if (mp->is_ipv6)
9968         {
9969           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9970           vat_json_object_add_ip4 (node, "src_address", ip4);
9971         }
9972       else
9973         {
9974           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9975           vat_json_object_add_ip6 (node, "server_address", ip6);
9976         }
9977     }
9978 }
9979
9980 static int
9981 api_dhcp_proxy_dump (vat_main_t * vam)
9982 {
9983   unformat_input_t *i = vam->input;
9984   vl_api_control_ping_t *mp_ping;
9985   vl_api_dhcp_proxy_dump_t *mp;
9986   u8 is_ipv6 = 0;
9987   int ret;
9988
9989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9990     {
9991       if (unformat (i, "ipv6"))
9992         is_ipv6 = 1;
9993       else
9994         {
9995           clib_warning ("parse error '%U'", format_unformat_error, i);
9996           return -99;
9997         }
9998     }
9999
10000   M (DHCP_PROXY_DUMP, mp);
10001
10002   mp->is_ip6 = is_ipv6;
10003   S (mp);
10004
10005   /* Use a control ping for synchronization */
10006   MPING (CONTROL_PING, mp_ping);
10007   S (mp_ping);
10008
10009   W (ret);
10010   return ret;
10011 }
10012
10013 static int
10014 api_dhcp_proxy_set_vss (vat_main_t * vam)
10015 {
10016   unformat_input_t *i = vam->input;
10017   vl_api_dhcp_proxy_set_vss_t *mp;
10018   u8 is_ipv6 = 0;
10019   u8 is_add = 1;
10020   u32 tbl_id = ~0;
10021   u8 vss_type = VSS_TYPE_DEFAULT;
10022   u8 *vpn_ascii_id = 0;
10023   u32 oui = 0;
10024   u32 fib_id = 0;
10025   int ret;
10026
10027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10028     {
10029       if (unformat (i, "tbl_id %d", &tbl_id))
10030         ;
10031       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10032         vss_type = VSS_TYPE_ASCII;
10033       else if (unformat (i, "fib_id %d", &fib_id))
10034         vss_type = VSS_TYPE_VPN_ID;
10035       else if (unformat (i, "oui %d", &oui))
10036         vss_type = VSS_TYPE_VPN_ID;
10037       else if (unformat (i, "ipv6"))
10038         is_ipv6 = 1;
10039       else if (unformat (i, "del"))
10040         is_add = 0;
10041       else
10042         break;
10043     }
10044
10045   if (tbl_id == ~0)
10046     {
10047       errmsg ("missing tbl_id ");
10048       vec_free (vpn_ascii_id);
10049       return -99;
10050     }
10051
10052   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10053     {
10054       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10055       vec_free (vpn_ascii_id);
10056       return -99;
10057     }
10058
10059   M (DHCP_PROXY_SET_VSS, mp);
10060   mp->tbl_id = ntohl (tbl_id);
10061   mp->vss_type = vss_type;
10062   if (vpn_ascii_id)
10063     {
10064       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10065       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10066     }
10067   mp->vpn_index = ntohl (fib_id);
10068   mp->oui = ntohl (oui);
10069   mp->is_ipv6 = is_ipv6;
10070   mp->is_add = is_add;
10071
10072   S (mp);
10073   W (ret);
10074
10075   vec_free (vpn_ascii_id);
10076   return ret;
10077 }
10078
10079 static int
10080 api_dhcp_client_config (vat_main_t * vam)
10081 {
10082   unformat_input_t *i = vam->input;
10083   vl_api_dhcp_client_config_t *mp;
10084   u32 sw_if_index;
10085   u8 sw_if_index_set = 0;
10086   u8 is_add = 1;
10087   u8 *hostname = 0;
10088   u8 disable_event = 0;
10089   int ret;
10090
10091   /* Parse args required to build the message */
10092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10093     {
10094       if (unformat (i, "del"))
10095         is_add = 0;
10096       else
10097         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10098         sw_if_index_set = 1;
10099       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10100         sw_if_index_set = 1;
10101       else if (unformat (i, "hostname %s", &hostname))
10102         ;
10103       else if (unformat (i, "disable_event"))
10104         disable_event = 1;
10105       else
10106         break;
10107     }
10108
10109   if (sw_if_index_set == 0)
10110     {
10111       errmsg ("missing interface name or sw_if_index");
10112       return -99;
10113     }
10114
10115   if (vec_len (hostname) > 63)
10116     {
10117       errmsg ("hostname too long");
10118     }
10119   vec_add1 (hostname, 0);
10120
10121   /* Construct the API message */
10122   M (DHCP_CLIENT_CONFIG, mp);
10123
10124   mp->sw_if_index = htonl (sw_if_index);
10125   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
10126   vec_free (hostname);
10127   mp->is_add = is_add;
10128   mp->want_dhcp_event = disable_event ? 0 : 1;
10129   mp->pid = htonl (getpid ());
10130
10131   /* send it... */
10132   S (mp);
10133
10134   /* Wait for a reply, return good/bad news  */
10135   W (ret);
10136   return ret;
10137 }
10138
10139 static int
10140 api_set_ip_flow_hash (vat_main_t * vam)
10141 {
10142   unformat_input_t *i = vam->input;
10143   vl_api_set_ip_flow_hash_t *mp;
10144   u32 vrf_id = 0;
10145   u8 is_ipv6 = 0;
10146   u8 vrf_id_set = 0;
10147   u8 src = 0;
10148   u8 dst = 0;
10149   u8 sport = 0;
10150   u8 dport = 0;
10151   u8 proto = 0;
10152   u8 reverse = 0;
10153   int ret;
10154
10155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10156     {
10157       if (unformat (i, "vrf %d", &vrf_id))
10158         vrf_id_set = 1;
10159       else if (unformat (i, "ipv6"))
10160         is_ipv6 = 1;
10161       else if (unformat (i, "src"))
10162         src = 1;
10163       else if (unformat (i, "dst"))
10164         dst = 1;
10165       else if (unformat (i, "sport"))
10166         sport = 1;
10167       else if (unformat (i, "dport"))
10168         dport = 1;
10169       else if (unformat (i, "proto"))
10170         proto = 1;
10171       else if (unformat (i, "reverse"))
10172         reverse = 1;
10173
10174       else
10175         {
10176           clib_warning ("parse error '%U'", format_unformat_error, i);
10177           return -99;
10178         }
10179     }
10180
10181   if (vrf_id_set == 0)
10182     {
10183       errmsg ("missing vrf id");
10184       return -99;
10185     }
10186
10187   M (SET_IP_FLOW_HASH, mp);
10188   mp->src = src;
10189   mp->dst = dst;
10190   mp->sport = sport;
10191   mp->dport = dport;
10192   mp->proto = proto;
10193   mp->reverse = reverse;
10194   mp->vrf_id = ntohl (vrf_id);
10195   mp->is_ipv6 = is_ipv6;
10196
10197   S (mp);
10198   W (ret);
10199   return ret;
10200 }
10201
10202 static int
10203 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10204 {
10205   unformat_input_t *i = vam->input;
10206   vl_api_sw_interface_ip6_enable_disable_t *mp;
10207   u32 sw_if_index;
10208   u8 sw_if_index_set = 0;
10209   u8 enable = 0;
10210   int ret;
10211
10212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10213     {
10214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10215         sw_if_index_set = 1;
10216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10217         sw_if_index_set = 1;
10218       else if (unformat (i, "enable"))
10219         enable = 1;
10220       else if (unformat (i, "disable"))
10221         enable = 0;
10222       else
10223         {
10224           clib_warning ("parse error '%U'", format_unformat_error, i);
10225           return -99;
10226         }
10227     }
10228
10229   if (sw_if_index_set == 0)
10230     {
10231       errmsg ("missing interface name or sw_if_index");
10232       return -99;
10233     }
10234
10235   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10236
10237   mp->sw_if_index = ntohl (sw_if_index);
10238   mp->enable = enable;
10239
10240   S (mp);
10241   W (ret);
10242   return ret;
10243 }
10244
10245 static int
10246 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10247 {
10248   unformat_input_t *i = vam->input;
10249   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10250   u32 sw_if_index;
10251   u8 sw_if_index_set = 0;
10252   u8 v6_address_set = 0;
10253   ip6_address_t v6address;
10254   int ret;
10255
10256   /* Parse args required to build the message */
10257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10258     {
10259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10260         sw_if_index_set = 1;
10261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10262         sw_if_index_set = 1;
10263       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10264         v6_address_set = 1;
10265       else
10266         break;
10267     }
10268
10269   if (sw_if_index_set == 0)
10270     {
10271       errmsg ("missing interface name or sw_if_index");
10272       return -99;
10273     }
10274   if (!v6_address_set)
10275     {
10276       errmsg ("no address set");
10277       return -99;
10278     }
10279
10280   /* Construct the API message */
10281   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10282
10283   mp->sw_if_index = ntohl (sw_if_index);
10284   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10285
10286   /* send it... */
10287   S (mp);
10288
10289   /* Wait for a reply, return good/bad news  */
10290   W (ret);
10291   return ret;
10292 }
10293
10294 static int
10295 api_ip6nd_proxy_add_del (vat_main_t * vam)
10296 {
10297   unformat_input_t *i = vam->input;
10298   vl_api_ip6nd_proxy_add_del_t *mp;
10299   u32 sw_if_index = ~0;
10300   u8 v6_address_set = 0;
10301   ip6_address_t v6address;
10302   u8 is_del = 0;
10303   int ret;
10304
10305   /* Parse args required to build the message */
10306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10307     {
10308       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10309         ;
10310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10311         ;
10312       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10313         v6_address_set = 1;
10314       if (unformat (i, "del"))
10315         is_del = 1;
10316       else
10317         {
10318           clib_warning ("parse error '%U'", format_unformat_error, i);
10319           return -99;
10320         }
10321     }
10322
10323   if (sw_if_index == ~0)
10324     {
10325       errmsg ("missing interface name or sw_if_index");
10326       return -99;
10327     }
10328   if (!v6_address_set)
10329     {
10330       errmsg ("no address set");
10331       return -99;
10332     }
10333
10334   /* Construct the API message */
10335   M (IP6ND_PROXY_ADD_DEL, mp);
10336
10337   mp->is_del = is_del;
10338   mp->sw_if_index = ntohl (sw_if_index);
10339   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10340
10341   /* send it... */
10342   S (mp);
10343
10344   /* Wait for a reply, return good/bad news  */
10345   W (ret);
10346   return ret;
10347 }
10348
10349 static int
10350 api_ip6nd_proxy_dump (vat_main_t * vam)
10351 {
10352   vl_api_ip6nd_proxy_dump_t *mp;
10353   vl_api_control_ping_t *mp_ping;
10354   int ret;
10355
10356   M (IP6ND_PROXY_DUMP, mp);
10357
10358   S (mp);
10359
10360   /* Use a control ping for synchronization */
10361   MPING (CONTROL_PING, mp_ping);
10362   S (mp_ping);
10363
10364   W (ret);
10365   return ret;
10366 }
10367
10368 static void vl_api_ip6nd_proxy_details_t_handler
10369   (vl_api_ip6nd_proxy_details_t * mp)
10370 {
10371   vat_main_t *vam = &vat_main;
10372
10373   print (vam->ofp, "host %U sw_if_index %d",
10374          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10375 }
10376
10377 static void vl_api_ip6nd_proxy_details_t_handler_json
10378   (vl_api_ip6nd_proxy_details_t * mp)
10379 {
10380   vat_main_t *vam = &vat_main;
10381   struct in6_addr ip6;
10382   vat_json_node_t *node = NULL;
10383
10384   if (VAT_JSON_ARRAY != vam->json_tree.type)
10385     {
10386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10387       vat_json_init_array (&vam->json_tree);
10388     }
10389   node = vat_json_array_add (&vam->json_tree);
10390
10391   vat_json_init_object (node);
10392   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10393
10394   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10395   vat_json_object_add_ip6 (node, "host", ip6);
10396 }
10397
10398 static int
10399 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10400 {
10401   unformat_input_t *i = vam->input;
10402   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10403   u32 sw_if_index;
10404   u8 sw_if_index_set = 0;
10405   u32 address_length = 0;
10406   u8 v6_address_set = 0;
10407   ip6_address_t v6address;
10408   u8 use_default = 0;
10409   u8 no_advertise = 0;
10410   u8 off_link = 0;
10411   u8 no_autoconfig = 0;
10412   u8 no_onlink = 0;
10413   u8 is_no = 0;
10414   u32 val_lifetime = 0;
10415   u32 pref_lifetime = 0;
10416   int ret;
10417
10418   /* Parse args required to build the message */
10419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10420     {
10421       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10422         sw_if_index_set = 1;
10423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10424         sw_if_index_set = 1;
10425       else if (unformat (i, "%U/%d",
10426                          unformat_ip6_address, &v6address, &address_length))
10427         v6_address_set = 1;
10428       else if (unformat (i, "val_life %d", &val_lifetime))
10429         ;
10430       else if (unformat (i, "pref_life %d", &pref_lifetime))
10431         ;
10432       else if (unformat (i, "def"))
10433         use_default = 1;
10434       else if (unformat (i, "noadv"))
10435         no_advertise = 1;
10436       else if (unformat (i, "offl"))
10437         off_link = 1;
10438       else if (unformat (i, "noauto"))
10439         no_autoconfig = 1;
10440       else if (unformat (i, "nolink"))
10441         no_onlink = 1;
10442       else if (unformat (i, "isno"))
10443         is_no = 1;
10444       else
10445         {
10446           clib_warning ("parse error '%U'", format_unformat_error, i);
10447           return -99;
10448         }
10449     }
10450
10451   if (sw_if_index_set == 0)
10452     {
10453       errmsg ("missing interface name or sw_if_index");
10454       return -99;
10455     }
10456   if (!v6_address_set)
10457     {
10458       errmsg ("no address set");
10459       return -99;
10460     }
10461
10462   /* Construct the API message */
10463   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10464
10465   mp->sw_if_index = ntohl (sw_if_index);
10466   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10467   mp->address_length = address_length;
10468   mp->use_default = use_default;
10469   mp->no_advertise = no_advertise;
10470   mp->off_link = off_link;
10471   mp->no_autoconfig = no_autoconfig;
10472   mp->no_onlink = no_onlink;
10473   mp->is_no = is_no;
10474   mp->val_lifetime = ntohl (val_lifetime);
10475   mp->pref_lifetime = ntohl (pref_lifetime);
10476
10477   /* send it... */
10478   S (mp);
10479
10480   /* Wait for a reply, return good/bad news  */
10481   W (ret);
10482   return ret;
10483 }
10484
10485 static int
10486 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10487 {
10488   unformat_input_t *i = vam->input;
10489   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10490   u32 sw_if_index;
10491   u8 sw_if_index_set = 0;
10492   u8 suppress = 0;
10493   u8 managed = 0;
10494   u8 other = 0;
10495   u8 ll_option = 0;
10496   u8 send_unicast = 0;
10497   u8 cease = 0;
10498   u8 is_no = 0;
10499   u8 default_router = 0;
10500   u32 max_interval = 0;
10501   u32 min_interval = 0;
10502   u32 lifetime = 0;
10503   u32 initial_count = 0;
10504   u32 initial_interval = 0;
10505   int ret;
10506
10507
10508   /* Parse args required to build the message */
10509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10510     {
10511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10512         sw_if_index_set = 1;
10513       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10514         sw_if_index_set = 1;
10515       else if (unformat (i, "maxint %d", &max_interval))
10516         ;
10517       else if (unformat (i, "minint %d", &min_interval))
10518         ;
10519       else if (unformat (i, "life %d", &lifetime))
10520         ;
10521       else if (unformat (i, "count %d", &initial_count))
10522         ;
10523       else if (unformat (i, "interval %d", &initial_interval))
10524         ;
10525       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10526         suppress = 1;
10527       else if (unformat (i, "managed"))
10528         managed = 1;
10529       else if (unformat (i, "other"))
10530         other = 1;
10531       else if (unformat (i, "ll"))
10532         ll_option = 1;
10533       else if (unformat (i, "send"))
10534         send_unicast = 1;
10535       else if (unformat (i, "cease"))
10536         cease = 1;
10537       else if (unformat (i, "isno"))
10538         is_no = 1;
10539       else if (unformat (i, "def"))
10540         default_router = 1;
10541       else
10542         {
10543           clib_warning ("parse error '%U'", format_unformat_error, i);
10544           return -99;
10545         }
10546     }
10547
10548   if (sw_if_index_set == 0)
10549     {
10550       errmsg ("missing interface name or sw_if_index");
10551       return -99;
10552     }
10553
10554   /* Construct the API message */
10555   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10556
10557   mp->sw_if_index = ntohl (sw_if_index);
10558   mp->max_interval = ntohl (max_interval);
10559   mp->min_interval = ntohl (min_interval);
10560   mp->lifetime = ntohl (lifetime);
10561   mp->initial_count = ntohl (initial_count);
10562   mp->initial_interval = ntohl (initial_interval);
10563   mp->suppress = suppress;
10564   mp->managed = managed;
10565   mp->other = other;
10566   mp->ll_option = ll_option;
10567   mp->send_unicast = send_unicast;
10568   mp->cease = cease;
10569   mp->is_no = is_no;
10570   mp->default_router = default_router;
10571
10572   /* send it... */
10573   S (mp);
10574
10575   /* Wait for a reply, return good/bad news  */
10576   W (ret);
10577   return ret;
10578 }
10579
10580 static int
10581 api_set_arp_neighbor_limit (vat_main_t * vam)
10582 {
10583   unformat_input_t *i = vam->input;
10584   vl_api_set_arp_neighbor_limit_t *mp;
10585   u32 arp_nbr_limit;
10586   u8 limit_set = 0;
10587   u8 is_ipv6 = 0;
10588   int ret;
10589
10590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10591     {
10592       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10593         limit_set = 1;
10594       else if (unformat (i, "ipv6"))
10595         is_ipv6 = 1;
10596       else
10597         {
10598           clib_warning ("parse error '%U'", format_unformat_error, i);
10599           return -99;
10600         }
10601     }
10602
10603   if (limit_set == 0)
10604     {
10605       errmsg ("missing limit value");
10606       return -99;
10607     }
10608
10609   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10610
10611   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10612   mp->is_ipv6 = is_ipv6;
10613
10614   S (mp);
10615   W (ret);
10616   return ret;
10617 }
10618
10619 static int
10620 api_l2_patch_add_del (vat_main_t * vam)
10621 {
10622   unformat_input_t *i = vam->input;
10623   vl_api_l2_patch_add_del_t *mp;
10624   u32 rx_sw_if_index;
10625   u8 rx_sw_if_index_set = 0;
10626   u32 tx_sw_if_index;
10627   u8 tx_sw_if_index_set = 0;
10628   u8 is_add = 1;
10629   int ret;
10630
10631   /* Parse args required to build the message */
10632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10633     {
10634       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10635         rx_sw_if_index_set = 1;
10636       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10637         tx_sw_if_index_set = 1;
10638       else if (unformat (i, "rx"))
10639         {
10640           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10641             {
10642               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10643                             &rx_sw_if_index))
10644                 rx_sw_if_index_set = 1;
10645             }
10646           else
10647             break;
10648         }
10649       else if (unformat (i, "tx"))
10650         {
10651           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10652             {
10653               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10654                             &tx_sw_if_index))
10655                 tx_sw_if_index_set = 1;
10656             }
10657           else
10658             break;
10659         }
10660       else if (unformat (i, "del"))
10661         is_add = 0;
10662       else
10663         break;
10664     }
10665
10666   if (rx_sw_if_index_set == 0)
10667     {
10668       errmsg ("missing rx interface name or rx_sw_if_index");
10669       return -99;
10670     }
10671
10672   if (tx_sw_if_index_set == 0)
10673     {
10674       errmsg ("missing tx interface name or tx_sw_if_index");
10675       return -99;
10676     }
10677
10678   M (L2_PATCH_ADD_DEL, mp);
10679
10680   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10681   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10682   mp->is_add = is_add;
10683
10684   S (mp);
10685   W (ret);
10686   return ret;
10687 }
10688
10689 u8 is_del;
10690 u8 localsid_addr[16];
10691 u8 end_psp;
10692 u8 behavior;
10693 u32 sw_if_index;
10694 u32 vlan_index;
10695 u32 fib_table;
10696 u8 nh_addr[16];
10697
10698 static int
10699 api_sr_localsid_add_del (vat_main_t * vam)
10700 {
10701   unformat_input_t *i = vam->input;
10702   vl_api_sr_localsid_add_del_t *mp;
10703
10704   u8 is_del;
10705   ip6_address_t localsid;
10706   u8 end_psp = 0;
10707   u8 behavior = ~0;
10708   u32 sw_if_index;
10709   u32 fib_table = ~(u32) 0;
10710   ip6_address_t next_hop;
10711
10712   bool nexthop_set = 0;
10713
10714   int ret;
10715
10716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10717     {
10718       if (unformat (i, "del"))
10719         is_del = 1;
10720       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10721       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10722         nexthop_set = 1;
10723       else if (unformat (i, "behavior %u", &behavior));
10724       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10725       else if (unformat (i, "fib-table %u", &fib_table));
10726       else if (unformat (i, "end.psp %u", &behavior));
10727       else
10728         break;
10729     }
10730
10731   M (SR_LOCALSID_ADD_DEL, mp);
10732
10733   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10734   if (nexthop_set)
10735     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10736   mp->behavior = behavior;
10737   mp->sw_if_index = ntohl (sw_if_index);
10738   mp->fib_table = ntohl (fib_table);
10739   mp->end_psp = end_psp;
10740   mp->is_del = is_del;
10741
10742   S (mp);
10743   W (ret);
10744   return ret;
10745 }
10746
10747 static int
10748 api_ioam_enable (vat_main_t * vam)
10749 {
10750   unformat_input_t *input = vam->input;
10751   vl_api_ioam_enable_t *mp;
10752   u32 id = 0;
10753   int has_trace_option = 0;
10754   int has_pot_option = 0;
10755   int has_seqno_option = 0;
10756   int has_analyse_option = 0;
10757   int ret;
10758
10759   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10760     {
10761       if (unformat (input, "trace"))
10762         has_trace_option = 1;
10763       else if (unformat (input, "pot"))
10764         has_pot_option = 1;
10765       else if (unformat (input, "seqno"))
10766         has_seqno_option = 1;
10767       else if (unformat (input, "analyse"))
10768         has_analyse_option = 1;
10769       else
10770         break;
10771     }
10772   M (IOAM_ENABLE, mp);
10773   mp->id = htons (id);
10774   mp->seqno = has_seqno_option;
10775   mp->analyse = has_analyse_option;
10776   mp->pot_enable = has_pot_option;
10777   mp->trace_enable = has_trace_option;
10778
10779   S (mp);
10780   W (ret);
10781   return ret;
10782 }
10783
10784
10785 static int
10786 api_ioam_disable (vat_main_t * vam)
10787 {
10788   vl_api_ioam_disable_t *mp;
10789   int ret;
10790
10791   M (IOAM_DISABLE, mp);
10792   S (mp);
10793   W (ret);
10794   return ret;
10795 }
10796
10797 #define foreach_tcp_proto_field                 \
10798 _(src_port)                                     \
10799 _(dst_port)
10800
10801 #define foreach_udp_proto_field                 \
10802 _(src_port)                                     \
10803 _(dst_port)
10804
10805 #define foreach_ip4_proto_field                 \
10806 _(src_address)                                  \
10807 _(dst_address)                                  \
10808 _(tos)                                          \
10809 _(length)                                       \
10810 _(fragment_id)                                  \
10811 _(ttl)                                          \
10812 _(protocol)                                     \
10813 _(checksum)
10814
10815 typedef struct
10816 {
10817   u16 src_port, dst_port;
10818 } tcpudp_header_t;
10819
10820 #if VPP_API_TEST_BUILTIN == 0
10821 uword
10822 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10823 {
10824   u8 **maskp = va_arg (*args, u8 **);
10825   u8 *mask = 0;
10826   u8 found_something = 0;
10827   tcp_header_t *tcp;
10828
10829 #define _(a) u8 a=0;
10830   foreach_tcp_proto_field;
10831 #undef _
10832
10833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10834     {
10835       if (0);
10836 #define _(a) else if (unformat (input, #a)) a=1;
10837       foreach_tcp_proto_field
10838 #undef _
10839         else
10840         break;
10841     }
10842
10843 #define _(a) found_something += a;
10844   foreach_tcp_proto_field;
10845 #undef _
10846
10847   if (found_something == 0)
10848     return 0;
10849
10850   vec_validate (mask, sizeof (*tcp) - 1);
10851
10852   tcp = (tcp_header_t *) mask;
10853
10854 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10855   foreach_tcp_proto_field;
10856 #undef _
10857
10858   *maskp = mask;
10859   return 1;
10860 }
10861
10862 uword
10863 unformat_udp_mask (unformat_input_t * input, va_list * args)
10864 {
10865   u8 **maskp = va_arg (*args, u8 **);
10866   u8 *mask = 0;
10867   u8 found_something = 0;
10868   udp_header_t *udp;
10869
10870 #define _(a) u8 a=0;
10871   foreach_udp_proto_field;
10872 #undef _
10873
10874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10875     {
10876       if (0);
10877 #define _(a) else if (unformat (input, #a)) a=1;
10878       foreach_udp_proto_field
10879 #undef _
10880         else
10881         break;
10882     }
10883
10884 #define _(a) found_something += a;
10885   foreach_udp_proto_field;
10886 #undef _
10887
10888   if (found_something == 0)
10889     return 0;
10890
10891   vec_validate (mask, sizeof (*udp) - 1);
10892
10893   udp = (udp_header_t *) mask;
10894
10895 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10896   foreach_udp_proto_field;
10897 #undef _
10898
10899   *maskp = mask;
10900   return 1;
10901 }
10902
10903 uword
10904 unformat_l4_mask (unformat_input_t * input, va_list * args)
10905 {
10906   u8 **maskp = va_arg (*args, u8 **);
10907   u16 src_port = 0, dst_port = 0;
10908   tcpudp_header_t *tcpudp;
10909
10910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10911     {
10912       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10913         return 1;
10914       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10915         return 1;
10916       else if (unformat (input, "src_port"))
10917         src_port = 0xFFFF;
10918       else if (unformat (input, "dst_port"))
10919         dst_port = 0xFFFF;
10920       else
10921         return 0;
10922     }
10923
10924   if (!src_port && !dst_port)
10925     return 0;
10926
10927   u8 *mask = 0;
10928   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10929
10930   tcpudp = (tcpudp_header_t *) mask;
10931   tcpudp->src_port = src_port;
10932   tcpudp->dst_port = dst_port;
10933
10934   *maskp = mask;
10935
10936   return 1;
10937 }
10938
10939 uword
10940 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10941 {
10942   u8 **maskp = va_arg (*args, u8 **);
10943   u8 *mask = 0;
10944   u8 found_something = 0;
10945   ip4_header_t *ip;
10946
10947 #define _(a) u8 a=0;
10948   foreach_ip4_proto_field;
10949 #undef _
10950   u8 version = 0;
10951   u8 hdr_length = 0;
10952
10953
10954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10955     {
10956       if (unformat (input, "version"))
10957         version = 1;
10958       else if (unformat (input, "hdr_length"))
10959         hdr_length = 1;
10960       else if (unformat (input, "src"))
10961         src_address = 1;
10962       else if (unformat (input, "dst"))
10963         dst_address = 1;
10964       else if (unformat (input, "proto"))
10965         protocol = 1;
10966
10967 #define _(a) else if (unformat (input, #a)) a=1;
10968       foreach_ip4_proto_field
10969 #undef _
10970         else
10971         break;
10972     }
10973
10974 #define _(a) found_something += a;
10975   foreach_ip4_proto_field;
10976 #undef _
10977
10978   if (found_something == 0)
10979     return 0;
10980
10981   vec_validate (mask, sizeof (*ip) - 1);
10982
10983   ip = (ip4_header_t *) mask;
10984
10985 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10986   foreach_ip4_proto_field;
10987 #undef _
10988
10989   ip->ip_version_and_header_length = 0;
10990
10991   if (version)
10992     ip->ip_version_and_header_length |= 0xF0;
10993
10994   if (hdr_length)
10995     ip->ip_version_and_header_length |= 0x0F;
10996
10997   *maskp = mask;
10998   return 1;
10999 }
11000
11001 #define foreach_ip6_proto_field                 \
11002 _(src_address)                                  \
11003 _(dst_address)                                  \
11004 _(payload_length)                               \
11005 _(hop_limit)                                    \
11006 _(protocol)
11007
11008 uword
11009 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11010 {
11011   u8 **maskp = va_arg (*args, u8 **);
11012   u8 *mask = 0;
11013   u8 found_something = 0;
11014   ip6_header_t *ip;
11015   u32 ip_version_traffic_class_and_flow_label;
11016
11017 #define _(a) u8 a=0;
11018   foreach_ip6_proto_field;
11019 #undef _
11020   u8 version = 0;
11021   u8 traffic_class = 0;
11022   u8 flow_label = 0;
11023
11024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11025     {
11026       if (unformat (input, "version"))
11027         version = 1;
11028       else if (unformat (input, "traffic-class"))
11029         traffic_class = 1;
11030       else if (unformat (input, "flow-label"))
11031         flow_label = 1;
11032       else if (unformat (input, "src"))
11033         src_address = 1;
11034       else if (unformat (input, "dst"))
11035         dst_address = 1;
11036       else if (unformat (input, "proto"))
11037         protocol = 1;
11038
11039 #define _(a) else if (unformat (input, #a)) a=1;
11040       foreach_ip6_proto_field
11041 #undef _
11042         else
11043         break;
11044     }
11045
11046 #define _(a) found_something += a;
11047   foreach_ip6_proto_field;
11048 #undef _
11049
11050   if (found_something == 0)
11051     return 0;
11052
11053   vec_validate (mask, sizeof (*ip) - 1);
11054
11055   ip = (ip6_header_t *) mask;
11056
11057 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11058   foreach_ip6_proto_field;
11059 #undef _
11060
11061   ip_version_traffic_class_and_flow_label = 0;
11062
11063   if (version)
11064     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11065
11066   if (traffic_class)
11067     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11068
11069   if (flow_label)
11070     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11071
11072   ip->ip_version_traffic_class_and_flow_label =
11073     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11074
11075   *maskp = mask;
11076   return 1;
11077 }
11078
11079 uword
11080 unformat_l3_mask (unformat_input_t * input, va_list * args)
11081 {
11082   u8 **maskp = va_arg (*args, u8 **);
11083
11084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11085     {
11086       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11087         return 1;
11088       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11089         return 1;
11090       else
11091         break;
11092     }
11093   return 0;
11094 }
11095
11096 uword
11097 unformat_l2_mask (unformat_input_t * input, va_list * args)
11098 {
11099   u8 **maskp = va_arg (*args, u8 **);
11100   u8 *mask = 0;
11101   u8 src = 0;
11102   u8 dst = 0;
11103   u8 proto = 0;
11104   u8 tag1 = 0;
11105   u8 tag2 = 0;
11106   u8 ignore_tag1 = 0;
11107   u8 ignore_tag2 = 0;
11108   u8 cos1 = 0;
11109   u8 cos2 = 0;
11110   u8 dot1q = 0;
11111   u8 dot1ad = 0;
11112   int len = 14;
11113
11114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11115     {
11116       if (unformat (input, "src"))
11117         src = 1;
11118       else if (unformat (input, "dst"))
11119         dst = 1;
11120       else if (unformat (input, "proto"))
11121         proto = 1;
11122       else if (unformat (input, "tag1"))
11123         tag1 = 1;
11124       else if (unformat (input, "tag2"))
11125         tag2 = 1;
11126       else if (unformat (input, "ignore-tag1"))
11127         ignore_tag1 = 1;
11128       else if (unformat (input, "ignore-tag2"))
11129         ignore_tag2 = 1;
11130       else if (unformat (input, "cos1"))
11131         cos1 = 1;
11132       else if (unformat (input, "cos2"))
11133         cos2 = 1;
11134       else if (unformat (input, "dot1q"))
11135         dot1q = 1;
11136       else if (unformat (input, "dot1ad"))
11137         dot1ad = 1;
11138       else
11139         break;
11140     }
11141   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11142        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11143     return 0;
11144
11145   if (tag1 || ignore_tag1 || cos1 || dot1q)
11146     len = 18;
11147   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11148     len = 22;
11149
11150   vec_validate (mask, len - 1);
11151
11152   if (dst)
11153     memset (mask, 0xff, 6);
11154
11155   if (src)
11156     memset (mask + 6, 0xff, 6);
11157
11158   if (tag2 || dot1ad)
11159     {
11160       /* inner vlan tag */
11161       if (tag2)
11162         {
11163           mask[19] = 0xff;
11164           mask[18] = 0x0f;
11165         }
11166       if (cos2)
11167         mask[18] |= 0xe0;
11168       if (proto)
11169         mask[21] = mask[20] = 0xff;
11170       if (tag1)
11171         {
11172           mask[15] = 0xff;
11173           mask[14] = 0x0f;
11174         }
11175       if (cos1)
11176         mask[14] |= 0xe0;
11177       *maskp = mask;
11178       return 1;
11179     }
11180   if (tag1 | dot1q)
11181     {
11182       if (tag1)
11183         {
11184           mask[15] = 0xff;
11185           mask[14] = 0x0f;
11186         }
11187       if (cos1)
11188         mask[14] |= 0xe0;
11189       if (proto)
11190         mask[16] = mask[17] = 0xff;
11191
11192       *maskp = mask;
11193       return 1;
11194     }
11195   if (cos2)
11196     mask[18] |= 0xe0;
11197   if (cos1)
11198     mask[14] |= 0xe0;
11199   if (proto)
11200     mask[12] = mask[13] = 0xff;
11201
11202   *maskp = mask;
11203   return 1;
11204 }
11205
11206 uword
11207 unformat_classify_mask (unformat_input_t * input, va_list * args)
11208 {
11209   u8 **maskp = va_arg (*args, u8 **);
11210   u32 *skipp = va_arg (*args, u32 *);
11211   u32 *matchp = va_arg (*args, u32 *);
11212   u32 match;
11213   u8 *mask = 0;
11214   u8 *l2 = 0;
11215   u8 *l3 = 0;
11216   u8 *l4 = 0;
11217   int i;
11218
11219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11222         ;
11223       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11224         ;
11225       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11226         ;
11227       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11228         ;
11229       else
11230         break;
11231     }
11232
11233   if (l4 && !l3)
11234     {
11235       vec_free (mask);
11236       vec_free (l2);
11237       vec_free (l4);
11238       return 0;
11239     }
11240
11241   if (mask || l2 || l3 || l4)
11242     {
11243       if (l2 || l3 || l4)
11244         {
11245           /* "With a free Ethernet header in every package" */
11246           if (l2 == 0)
11247             vec_validate (l2, 13);
11248           mask = l2;
11249           if (vec_len (l3))
11250             {
11251               vec_append (mask, l3);
11252               vec_free (l3);
11253             }
11254           if (vec_len (l4))
11255             {
11256               vec_append (mask, l4);
11257               vec_free (l4);
11258             }
11259         }
11260
11261       /* Scan forward looking for the first significant mask octet */
11262       for (i = 0; i < vec_len (mask); i++)
11263         if (mask[i])
11264           break;
11265
11266       /* compute (skip, match) params */
11267       *skipp = i / sizeof (u32x4);
11268       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11269
11270       /* Pad mask to an even multiple of the vector size */
11271       while (vec_len (mask) % sizeof (u32x4))
11272         vec_add1 (mask, 0);
11273
11274       match = vec_len (mask) / sizeof (u32x4);
11275
11276       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11277         {
11278           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11279           if (*tmp || *(tmp + 1))
11280             break;
11281           match--;
11282         }
11283       if (match == 0)
11284         clib_warning ("BUG: match 0");
11285
11286       _vec_len (mask) = match * sizeof (u32x4);
11287
11288       *matchp = match;
11289       *maskp = mask;
11290
11291       return 1;
11292     }
11293
11294   return 0;
11295 }
11296 #endif /* VPP_API_TEST_BUILTIN */
11297
11298 #define foreach_l2_next                         \
11299 _(drop, DROP)                                   \
11300 _(ethernet, ETHERNET_INPUT)                     \
11301 _(ip4, IP4_INPUT)                               \
11302 _(ip6, IP6_INPUT)
11303
11304 uword
11305 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11306 {
11307   u32 *miss_next_indexp = va_arg (*args, u32 *);
11308   u32 next_index = 0;
11309   u32 tmp;
11310
11311 #define _(n,N) \
11312   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11313   foreach_l2_next;
11314 #undef _
11315
11316   if (unformat (input, "%d", &tmp))
11317     {
11318       next_index = tmp;
11319       goto out;
11320     }
11321
11322   return 0;
11323
11324 out:
11325   *miss_next_indexp = next_index;
11326   return 1;
11327 }
11328
11329 #define foreach_ip_next                         \
11330 _(drop, DROP)                                   \
11331 _(local, LOCAL)                                 \
11332 _(rewrite, REWRITE)
11333
11334 uword
11335 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11336 {
11337   u32 *miss_next_indexp = va_arg (*args, u32 *);
11338   u32 next_index = 0;
11339   u32 tmp;
11340
11341 #define _(n,N) \
11342   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11343   foreach_ip_next;
11344 #undef _
11345
11346   if (unformat (input, "%d", &tmp))
11347     {
11348       next_index = tmp;
11349       goto out;
11350     }
11351
11352   return 0;
11353
11354 out:
11355   *miss_next_indexp = next_index;
11356   return 1;
11357 }
11358
11359 #define foreach_acl_next                        \
11360 _(deny, DENY)
11361
11362 uword
11363 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11364 {
11365   u32 *miss_next_indexp = va_arg (*args, u32 *);
11366   u32 next_index = 0;
11367   u32 tmp;
11368
11369 #define _(n,N) \
11370   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11371   foreach_acl_next;
11372 #undef _
11373
11374   if (unformat (input, "permit"))
11375     {
11376       next_index = ~0;
11377       goto out;
11378     }
11379   else if (unformat (input, "%d", &tmp))
11380     {
11381       next_index = tmp;
11382       goto out;
11383     }
11384
11385   return 0;
11386
11387 out:
11388   *miss_next_indexp = next_index;
11389   return 1;
11390 }
11391
11392 uword
11393 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11394 {
11395   u32 *r = va_arg (*args, u32 *);
11396
11397   if (unformat (input, "conform-color"))
11398     *r = POLICE_CONFORM;
11399   else if (unformat (input, "exceed-color"))
11400     *r = POLICE_EXCEED;
11401   else
11402     return 0;
11403
11404   return 1;
11405 }
11406
11407 static int
11408 api_classify_add_del_table (vat_main_t * vam)
11409 {
11410   unformat_input_t *i = vam->input;
11411   vl_api_classify_add_del_table_t *mp;
11412
11413   u32 nbuckets = 2;
11414   u32 skip = ~0;
11415   u32 match = ~0;
11416   int is_add = 1;
11417   int del_chain = 0;
11418   u32 table_index = ~0;
11419   u32 next_table_index = ~0;
11420   u32 miss_next_index = ~0;
11421   u32 memory_size = 32 << 20;
11422   u8 *mask = 0;
11423   u32 current_data_flag = 0;
11424   int current_data_offset = 0;
11425   int ret;
11426
11427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11428     {
11429       if (unformat (i, "del"))
11430         is_add = 0;
11431       else if (unformat (i, "del-chain"))
11432         {
11433           is_add = 0;
11434           del_chain = 1;
11435         }
11436       else if (unformat (i, "buckets %d", &nbuckets))
11437         ;
11438       else if (unformat (i, "memory_size %d", &memory_size))
11439         ;
11440       else if (unformat (i, "skip %d", &skip))
11441         ;
11442       else if (unformat (i, "match %d", &match))
11443         ;
11444       else if (unformat (i, "table %d", &table_index))
11445         ;
11446       else if (unformat (i, "mask %U", unformat_classify_mask,
11447                          &mask, &skip, &match))
11448         ;
11449       else if (unformat (i, "next-table %d", &next_table_index))
11450         ;
11451       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11452                          &miss_next_index))
11453         ;
11454       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11455                          &miss_next_index))
11456         ;
11457       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11458                          &miss_next_index))
11459         ;
11460       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11461         ;
11462       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11463         ;
11464       else
11465         break;
11466     }
11467
11468   if (is_add && mask == 0)
11469     {
11470       errmsg ("Mask required");
11471       return -99;
11472     }
11473
11474   if (is_add && skip == ~0)
11475     {
11476       errmsg ("skip count required");
11477       return -99;
11478     }
11479
11480   if (is_add && match == ~0)
11481     {
11482       errmsg ("match count required");
11483       return -99;
11484     }
11485
11486   if (!is_add && table_index == ~0)
11487     {
11488       errmsg ("table index required for delete");
11489       return -99;
11490     }
11491
11492   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11493
11494   mp->is_add = is_add;
11495   mp->del_chain = del_chain;
11496   mp->table_index = ntohl (table_index);
11497   mp->nbuckets = ntohl (nbuckets);
11498   mp->memory_size = ntohl (memory_size);
11499   mp->skip_n_vectors = ntohl (skip);
11500   mp->match_n_vectors = ntohl (match);
11501   mp->next_table_index = ntohl (next_table_index);
11502   mp->miss_next_index = ntohl (miss_next_index);
11503   mp->current_data_flag = ntohl (current_data_flag);
11504   mp->current_data_offset = ntohl (current_data_offset);
11505   clib_memcpy (mp->mask, mask, vec_len (mask));
11506
11507   vec_free (mask);
11508
11509   S (mp);
11510   W (ret);
11511   return ret;
11512 }
11513
11514 #if VPP_API_TEST_BUILTIN == 0
11515 uword
11516 unformat_l4_match (unformat_input_t * input, va_list * args)
11517 {
11518   u8 **matchp = va_arg (*args, u8 **);
11519
11520   u8 *proto_header = 0;
11521   int src_port = 0;
11522   int dst_port = 0;
11523
11524   tcpudp_header_t h;
11525
11526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11527     {
11528       if (unformat (input, "src_port %d", &src_port))
11529         ;
11530       else if (unformat (input, "dst_port %d", &dst_port))
11531         ;
11532       else
11533         return 0;
11534     }
11535
11536   h.src_port = clib_host_to_net_u16 (src_port);
11537   h.dst_port = clib_host_to_net_u16 (dst_port);
11538   vec_validate (proto_header, sizeof (h) - 1);
11539   memcpy (proto_header, &h, sizeof (h));
11540
11541   *matchp = proto_header;
11542
11543   return 1;
11544 }
11545
11546 uword
11547 unformat_ip4_match (unformat_input_t * input, va_list * args)
11548 {
11549   u8 **matchp = va_arg (*args, u8 **);
11550   u8 *match = 0;
11551   ip4_header_t *ip;
11552   int version = 0;
11553   u32 version_val;
11554   int hdr_length = 0;
11555   u32 hdr_length_val;
11556   int src = 0, dst = 0;
11557   ip4_address_t src_val, dst_val;
11558   int proto = 0;
11559   u32 proto_val;
11560   int tos = 0;
11561   u32 tos_val;
11562   int length = 0;
11563   u32 length_val;
11564   int fragment_id = 0;
11565   u32 fragment_id_val;
11566   int ttl = 0;
11567   int ttl_val;
11568   int checksum = 0;
11569   u32 checksum_val;
11570
11571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11572     {
11573       if (unformat (input, "version %d", &version_val))
11574         version = 1;
11575       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11576         hdr_length = 1;
11577       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11578         src = 1;
11579       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11580         dst = 1;
11581       else if (unformat (input, "proto %d", &proto_val))
11582         proto = 1;
11583       else if (unformat (input, "tos %d", &tos_val))
11584         tos = 1;
11585       else if (unformat (input, "length %d", &length_val))
11586         length = 1;
11587       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11588         fragment_id = 1;
11589       else if (unformat (input, "ttl %d", &ttl_val))
11590         ttl = 1;
11591       else if (unformat (input, "checksum %d", &checksum_val))
11592         checksum = 1;
11593       else
11594         break;
11595     }
11596
11597   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11598       + ttl + checksum == 0)
11599     return 0;
11600
11601   /*
11602    * Aligned because we use the real comparison functions
11603    */
11604   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11605
11606   ip = (ip4_header_t *) match;
11607
11608   /* These are realistically matched in practice */
11609   if (src)
11610     ip->src_address.as_u32 = src_val.as_u32;
11611
11612   if (dst)
11613     ip->dst_address.as_u32 = dst_val.as_u32;
11614
11615   if (proto)
11616     ip->protocol = proto_val;
11617
11618
11619   /* These are not, but they're included for completeness */
11620   if (version)
11621     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11622
11623   if (hdr_length)
11624     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11625
11626   if (tos)
11627     ip->tos = tos_val;
11628
11629   if (length)
11630     ip->length = clib_host_to_net_u16 (length_val);
11631
11632   if (ttl)
11633     ip->ttl = ttl_val;
11634
11635   if (checksum)
11636     ip->checksum = clib_host_to_net_u16 (checksum_val);
11637
11638   *matchp = match;
11639   return 1;
11640 }
11641
11642 uword
11643 unformat_ip6_match (unformat_input_t * input, va_list * args)
11644 {
11645   u8 **matchp = va_arg (*args, u8 **);
11646   u8 *match = 0;
11647   ip6_header_t *ip;
11648   int version = 0;
11649   u32 version_val;
11650   u8 traffic_class = 0;
11651   u32 traffic_class_val = 0;
11652   u8 flow_label = 0;
11653   u8 flow_label_val;
11654   int src = 0, dst = 0;
11655   ip6_address_t src_val, dst_val;
11656   int proto = 0;
11657   u32 proto_val;
11658   int payload_length = 0;
11659   u32 payload_length_val;
11660   int hop_limit = 0;
11661   int hop_limit_val;
11662   u32 ip_version_traffic_class_and_flow_label;
11663
11664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11665     {
11666       if (unformat (input, "version %d", &version_val))
11667         version = 1;
11668       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11669         traffic_class = 1;
11670       else if (unformat (input, "flow_label %d", &flow_label_val))
11671         flow_label = 1;
11672       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11673         src = 1;
11674       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11675         dst = 1;
11676       else if (unformat (input, "proto %d", &proto_val))
11677         proto = 1;
11678       else if (unformat (input, "payload_length %d", &payload_length_val))
11679         payload_length = 1;
11680       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11681         hop_limit = 1;
11682       else
11683         break;
11684     }
11685
11686   if (version + traffic_class + flow_label + src + dst + proto +
11687       payload_length + hop_limit == 0)
11688     return 0;
11689
11690   /*
11691    * Aligned because we use the real comparison functions
11692    */
11693   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11694
11695   ip = (ip6_header_t *) match;
11696
11697   if (src)
11698     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11699
11700   if (dst)
11701     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11702
11703   if (proto)
11704     ip->protocol = proto_val;
11705
11706   ip_version_traffic_class_and_flow_label = 0;
11707
11708   if (version)
11709     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11710
11711   if (traffic_class)
11712     ip_version_traffic_class_and_flow_label |=
11713       (traffic_class_val & 0xFF) << 20;
11714
11715   if (flow_label)
11716     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11717
11718   ip->ip_version_traffic_class_and_flow_label =
11719     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11720
11721   if (payload_length)
11722     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11723
11724   if (hop_limit)
11725     ip->hop_limit = hop_limit_val;
11726
11727   *matchp = match;
11728   return 1;
11729 }
11730
11731 uword
11732 unformat_l3_match (unformat_input_t * input, va_list * args)
11733 {
11734   u8 **matchp = va_arg (*args, u8 **);
11735
11736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11737     {
11738       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11739         return 1;
11740       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11741         return 1;
11742       else
11743         break;
11744     }
11745   return 0;
11746 }
11747
11748 uword
11749 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11750 {
11751   u8 *tagp = va_arg (*args, u8 *);
11752   u32 tag;
11753
11754   if (unformat (input, "%d", &tag))
11755     {
11756       tagp[0] = (tag >> 8) & 0x0F;
11757       tagp[1] = tag & 0xFF;
11758       return 1;
11759     }
11760
11761   return 0;
11762 }
11763
11764 uword
11765 unformat_l2_match (unformat_input_t * input, va_list * args)
11766 {
11767   u8 **matchp = va_arg (*args, u8 **);
11768   u8 *match = 0;
11769   u8 src = 0;
11770   u8 src_val[6];
11771   u8 dst = 0;
11772   u8 dst_val[6];
11773   u8 proto = 0;
11774   u16 proto_val;
11775   u8 tag1 = 0;
11776   u8 tag1_val[2];
11777   u8 tag2 = 0;
11778   u8 tag2_val[2];
11779   int len = 14;
11780   u8 ignore_tag1 = 0;
11781   u8 ignore_tag2 = 0;
11782   u8 cos1 = 0;
11783   u8 cos2 = 0;
11784   u32 cos1_val = 0;
11785   u32 cos2_val = 0;
11786
11787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11790         src = 1;
11791       else
11792         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11793         dst = 1;
11794       else if (unformat (input, "proto %U",
11795                          unformat_ethernet_type_host_byte_order, &proto_val))
11796         proto = 1;
11797       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11798         tag1 = 1;
11799       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11800         tag2 = 1;
11801       else if (unformat (input, "ignore-tag1"))
11802         ignore_tag1 = 1;
11803       else if (unformat (input, "ignore-tag2"))
11804         ignore_tag2 = 1;
11805       else if (unformat (input, "cos1 %d", &cos1_val))
11806         cos1 = 1;
11807       else if (unformat (input, "cos2 %d", &cos2_val))
11808         cos2 = 1;
11809       else
11810         break;
11811     }
11812   if ((src + dst + proto + tag1 + tag2 +
11813        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11814     return 0;
11815
11816   if (tag1 || ignore_tag1 || cos1)
11817     len = 18;
11818   if (tag2 || ignore_tag2 || cos2)
11819     len = 22;
11820
11821   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11822
11823   if (dst)
11824     clib_memcpy (match, dst_val, 6);
11825
11826   if (src)
11827     clib_memcpy (match + 6, src_val, 6);
11828
11829   if (tag2)
11830     {
11831       /* inner vlan tag */
11832       match[19] = tag2_val[1];
11833       match[18] = tag2_val[0];
11834       if (cos2)
11835         match[18] |= (cos2_val & 0x7) << 5;
11836       if (proto)
11837         {
11838           match[21] = proto_val & 0xff;
11839           match[20] = proto_val >> 8;
11840         }
11841       if (tag1)
11842         {
11843           match[15] = tag1_val[1];
11844           match[14] = tag1_val[0];
11845         }
11846       if (cos1)
11847         match[14] |= (cos1_val & 0x7) << 5;
11848       *matchp = match;
11849       return 1;
11850     }
11851   if (tag1)
11852     {
11853       match[15] = tag1_val[1];
11854       match[14] = tag1_val[0];
11855       if (proto)
11856         {
11857           match[17] = proto_val & 0xff;
11858           match[16] = proto_val >> 8;
11859         }
11860       if (cos1)
11861         match[14] |= (cos1_val & 0x7) << 5;
11862
11863       *matchp = match;
11864       return 1;
11865     }
11866   if (cos2)
11867     match[18] |= (cos2_val & 0x7) << 5;
11868   if (cos1)
11869     match[14] |= (cos1_val & 0x7) << 5;
11870   if (proto)
11871     {
11872       match[13] = proto_val & 0xff;
11873       match[12] = proto_val >> 8;
11874     }
11875
11876   *matchp = match;
11877   return 1;
11878 }
11879
11880 uword
11881 unformat_qos_source (unformat_input_t * input, va_list * args)
11882 {
11883   int *qs = va_arg (*args, int *);
11884
11885   if (unformat (input, "ip"))
11886     *qs = QOS_SOURCE_IP;
11887   else if (unformat (input, "mpls"))
11888     *qs = QOS_SOURCE_MPLS;
11889   else if (unformat (input, "ext"))
11890     *qs = QOS_SOURCE_EXT;
11891   else if (unformat (input, "vlan"))
11892     *qs = QOS_SOURCE_VLAN;
11893   else
11894     return 0;
11895
11896   return 1;
11897 }
11898 #endif
11899
11900 uword
11901 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11902 {
11903   u8 **matchp = va_arg (*args, u8 **);
11904   u32 skip_n_vectors = va_arg (*args, u32);
11905   u32 match_n_vectors = va_arg (*args, u32);
11906
11907   u8 *match = 0;
11908   u8 *l2 = 0;
11909   u8 *l3 = 0;
11910   u8 *l4 = 0;
11911
11912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11913     {
11914       if (unformat (input, "hex %U", unformat_hex_string, &match))
11915         ;
11916       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11917         ;
11918       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11919         ;
11920       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11921         ;
11922       else
11923         break;
11924     }
11925
11926   if (l4 && !l3)
11927     {
11928       vec_free (match);
11929       vec_free (l2);
11930       vec_free (l4);
11931       return 0;
11932     }
11933
11934   if (match || l2 || l3 || l4)
11935     {
11936       if (l2 || l3 || l4)
11937         {
11938           /* "Win a free Ethernet header in every packet" */
11939           if (l2 == 0)
11940             vec_validate_aligned (l2, 13, sizeof (u32x4));
11941           match = l2;
11942           if (vec_len (l3))
11943             {
11944               vec_append_aligned (match, l3, sizeof (u32x4));
11945               vec_free (l3);
11946             }
11947           if (vec_len (l4))
11948             {
11949               vec_append_aligned (match, l4, sizeof (u32x4));
11950               vec_free (l4);
11951             }
11952         }
11953
11954       /* Make sure the vector is big enough even if key is all 0's */
11955       vec_validate_aligned
11956         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11957          sizeof (u32x4));
11958
11959       /* Set size, include skipped vectors */
11960       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11961
11962       *matchp = match;
11963
11964       return 1;
11965     }
11966
11967   return 0;
11968 }
11969
11970 static int
11971 api_classify_add_del_session (vat_main_t * vam)
11972 {
11973   unformat_input_t *i = vam->input;
11974   vl_api_classify_add_del_session_t *mp;
11975   int is_add = 1;
11976   u32 table_index = ~0;
11977   u32 hit_next_index = ~0;
11978   u32 opaque_index = ~0;
11979   u8 *match = 0;
11980   i32 advance = 0;
11981   u32 skip_n_vectors = 0;
11982   u32 match_n_vectors = 0;
11983   u32 action = 0;
11984   u32 metadata = 0;
11985   int ret;
11986
11987   /*
11988    * Warning: you have to supply skip_n and match_n
11989    * because the API client cant simply look at the classify
11990    * table object.
11991    */
11992
11993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11994     {
11995       if (unformat (i, "del"))
11996         is_add = 0;
11997       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11998                          &hit_next_index))
11999         ;
12000       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12001                          &hit_next_index))
12002         ;
12003       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12004                          &hit_next_index))
12005         ;
12006       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12007         ;
12008       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12009         ;
12010       else if (unformat (i, "opaque-index %d", &opaque_index))
12011         ;
12012       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12013         ;
12014       else if (unformat (i, "match_n %d", &match_n_vectors))
12015         ;
12016       else if (unformat (i, "match %U", api_unformat_classify_match,
12017                          &match, skip_n_vectors, match_n_vectors))
12018         ;
12019       else if (unformat (i, "advance %d", &advance))
12020         ;
12021       else if (unformat (i, "table-index %d", &table_index))
12022         ;
12023       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12024         action = 1;
12025       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12026         action = 2;
12027       else if (unformat (i, "action %d", &action))
12028         ;
12029       else if (unformat (i, "metadata %d", &metadata))
12030         ;
12031       else
12032         break;
12033     }
12034
12035   if (table_index == ~0)
12036     {
12037       errmsg ("Table index required");
12038       return -99;
12039     }
12040
12041   if (is_add && match == 0)
12042     {
12043       errmsg ("Match value required");
12044       return -99;
12045     }
12046
12047   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12048
12049   mp->is_add = is_add;
12050   mp->table_index = ntohl (table_index);
12051   mp->hit_next_index = ntohl (hit_next_index);
12052   mp->opaque_index = ntohl (opaque_index);
12053   mp->advance = ntohl (advance);
12054   mp->action = action;
12055   mp->metadata = ntohl (metadata);
12056   clib_memcpy (mp->match, match, vec_len (match));
12057   vec_free (match);
12058
12059   S (mp);
12060   W (ret);
12061   return ret;
12062 }
12063
12064 static int
12065 api_classify_set_interface_ip_table (vat_main_t * vam)
12066 {
12067   unformat_input_t *i = vam->input;
12068   vl_api_classify_set_interface_ip_table_t *mp;
12069   u32 sw_if_index;
12070   int sw_if_index_set;
12071   u32 table_index = ~0;
12072   u8 is_ipv6 = 0;
12073   int ret;
12074
12075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12076     {
12077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12078         sw_if_index_set = 1;
12079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12080         sw_if_index_set = 1;
12081       else if (unformat (i, "table %d", &table_index))
12082         ;
12083       else
12084         {
12085           clib_warning ("parse error '%U'", format_unformat_error, i);
12086           return -99;
12087         }
12088     }
12089
12090   if (sw_if_index_set == 0)
12091     {
12092       errmsg ("missing interface name or sw_if_index");
12093       return -99;
12094     }
12095
12096
12097   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12098
12099   mp->sw_if_index = ntohl (sw_if_index);
12100   mp->table_index = ntohl (table_index);
12101   mp->is_ipv6 = is_ipv6;
12102
12103   S (mp);
12104   W (ret);
12105   return ret;
12106 }
12107
12108 static int
12109 api_classify_set_interface_l2_tables (vat_main_t * vam)
12110 {
12111   unformat_input_t *i = vam->input;
12112   vl_api_classify_set_interface_l2_tables_t *mp;
12113   u32 sw_if_index;
12114   int sw_if_index_set;
12115   u32 ip4_table_index = ~0;
12116   u32 ip6_table_index = ~0;
12117   u32 other_table_index = ~0;
12118   u32 is_input = 1;
12119   int ret;
12120
12121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12122     {
12123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12124         sw_if_index_set = 1;
12125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12126         sw_if_index_set = 1;
12127       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12128         ;
12129       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12130         ;
12131       else if (unformat (i, "other-table %d", &other_table_index))
12132         ;
12133       else if (unformat (i, "is-input %d", &is_input))
12134         ;
12135       else
12136         {
12137           clib_warning ("parse error '%U'", format_unformat_error, i);
12138           return -99;
12139         }
12140     }
12141
12142   if (sw_if_index_set == 0)
12143     {
12144       errmsg ("missing interface name or sw_if_index");
12145       return -99;
12146     }
12147
12148
12149   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12150
12151   mp->sw_if_index = ntohl (sw_if_index);
12152   mp->ip4_table_index = ntohl (ip4_table_index);
12153   mp->ip6_table_index = ntohl (ip6_table_index);
12154   mp->other_table_index = ntohl (other_table_index);
12155   mp->is_input = (u8) is_input;
12156
12157   S (mp);
12158   W (ret);
12159   return ret;
12160 }
12161
12162 static int
12163 api_set_ipfix_exporter (vat_main_t * vam)
12164 {
12165   unformat_input_t *i = vam->input;
12166   vl_api_set_ipfix_exporter_t *mp;
12167   ip4_address_t collector_address;
12168   u8 collector_address_set = 0;
12169   u32 collector_port = ~0;
12170   ip4_address_t src_address;
12171   u8 src_address_set = 0;
12172   u32 vrf_id = ~0;
12173   u32 path_mtu = ~0;
12174   u32 template_interval = ~0;
12175   u8 udp_checksum = 0;
12176   int ret;
12177
12178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12179     {
12180       if (unformat (i, "collector_address %U", unformat_ip4_address,
12181                     &collector_address))
12182         collector_address_set = 1;
12183       else if (unformat (i, "collector_port %d", &collector_port))
12184         ;
12185       else if (unformat (i, "src_address %U", unformat_ip4_address,
12186                          &src_address))
12187         src_address_set = 1;
12188       else if (unformat (i, "vrf_id %d", &vrf_id))
12189         ;
12190       else if (unformat (i, "path_mtu %d", &path_mtu))
12191         ;
12192       else if (unformat (i, "template_interval %d", &template_interval))
12193         ;
12194       else if (unformat (i, "udp_checksum"))
12195         udp_checksum = 1;
12196       else
12197         break;
12198     }
12199
12200   if (collector_address_set == 0)
12201     {
12202       errmsg ("collector_address required");
12203       return -99;
12204     }
12205
12206   if (src_address_set == 0)
12207     {
12208       errmsg ("src_address required");
12209       return -99;
12210     }
12211
12212   M (SET_IPFIX_EXPORTER, mp);
12213
12214   memcpy (mp->collector_address, collector_address.data,
12215           sizeof (collector_address.data));
12216   mp->collector_port = htons ((u16) collector_port);
12217   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12218   mp->vrf_id = htonl (vrf_id);
12219   mp->path_mtu = htonl (path_mtu);
12220   mp->template_interval = htonl (template_interval);
12221   mp->udp_checksum = udp_checksum;
12222
12223   S (mp);
12224   W (ret);
12225   return ret;
12226 }
12227
12228 static int
12229 api_set_ipfix_classify_stream (vat_main_t * vam)
12230 {
12231   unformat_input_t *i = vam->input;
12232   vl_api_set_ipfix_classify_stream_t *mp;
12233   u32 domain_id = 0;
12234   u32 src_port = UDP_DST_PORT_ipfix;
12235   int ret;
12236
12237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12238     {
12239       if (unformat (i, "domain %d", &domain_id))
12240         ;
12241       else if (unformat (i, "src_port %d", &src_port))
12242         ;
12243       else
12244         {
12245           errmsg ("unknown input `%U'", format_unformat_error, i);
12246           return -99;
12247         }
12248     }
12249
12250   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12251
12252   mp->domain_id = htonl (domain_id);
12253   mp->src_port = htons ((u16) src_port);
12254
12255   S (mp);
12256   W (ret);
12257   return ret;
12258 }
12259
12260 static int
12261 api_ipfix_classify_table_add_del (vat_main_t * vam)
12262 {
12263   unformat_input_t *i = vam->input;
12264   vl_api_ipfix_classify_table_add_del_t *mp;
12265   int is_add = -1;
12266   u32 classify_table_index = ~0;
12267   u8 ip_version = 0;
12268   u8 transport_protocol = 255;
12269   int ret;
12270
12271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12272     {
12273       if (unformat (i, "add"))
12274         is_add = 1;
12275       else if (unformat (i, "del"))
12276         is_add = 0;
12277       else if (unformat (i, "table %d", &classify_table_index))
12278         ;
12279       else if (unformat (i, "ip4"))
12280         ip_version = 4;
12281       else if (unformat (i, "ip6"))
12282         ip_version = 6;
12283       else if (unformat (i, "tcp"))
12284         transport_protocol = 6;
12285       else if (unformat (i, "udp"))
12286         transport_protocol = 17;
12287       else
12288         {
12289           errmsg ("unknown input `%U'", format_unformat_error, i);
12290           return -99;
12291         }
12292     }
12293
12294   if (is_add == -1)
12295     {
12296       errmsg ("expecting: add|del");
12297       return -99;
12298     }
12299   if (classify_table_index == ~0)
12300     {
12301       errmsg ("classifier table not specified");
12302       return -99;
12303     }
12304   if (ip_version == 0)
12305     {
12306       errmsg ("IP version not specified");
12307       return -99;
12308     }
12309
12310   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12311
12312   mp->is_add = is_add;
12313   mp->table_id = htonl (classify_table_index);
12314   mp->ip_version = ip_version;
12315   mp->transport_protocol = transport_protocol;
12316
12317   S (mp);
12318   W (ret);
12319   return ret;
12320 }
12321
12322 static int
12323 api_get_node_index (vat_main_t * vam)
12324 {
12325   unformat_input_t *i = vam->input;
12326   vl_api_get_node_index_t *mp;
12327   u8 *name = 0;
12328   int ret;
12329
12330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (i, "node %s", &name))
12333         ;
12334       else
12335         break;
12336     }
12337   if (name == 0)
12338     {
12339       errmsg ("node name required");
12340       return -99;
12341     }
12342   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12343     {
12344       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12345       return -99;
12346     }
12347
12348   M (GET_NODE_INDEX, mp);
12349   clib_memcpy (mp->node_name, name, vec_len (name));
12350   vec_free (name);
12351
12352   S (mp);
12353   W (ret);
12354   return ret;
12355 }
12356
12357 static int
12358 api_get_next_index (vat_main_t * vam)
12359 {
12360   unformat_input_t *i = vam->input;
12361   vl_api_get_next_index_t *mp;
12362   u8 *node_name = 0, *next_node_name = 0;
12363   int ret;
12364
12365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12366     {
12367       if (unformat (i, "node-name %s", &node_name))
12368         ;
12369       else if (unformat (i, "next-node-name %s", &next_node_name))
12370         break;
12371     }
12372
12373   if (node_name == 0)
12374     {
12375       errmsg ("node name required");
12376       return -99;
12377     }
12378   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12379     {
12380       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12381       return -99;
12382     }
12383
12384   if (next_node_name == 0)
12385     {
12386       errmsg ("next node name required");
12387       return -99;
12388     }
12389   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12390     {
12391       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12392       return -99;
12393     }
12394
12395   M (GET_NEXT_INDEX, mp);
12396   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12397   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12398   vec_free (node_name);
12399   vec_free (next_node_name);
12400
12401   S (mp);
12402   W (ret);
12403   return ret;
12404 }
12405
12406 static int
12407 api_add_node_next (vat_main_t * vam)
12408 {
12409   unformat_input_t *i = vam->input;
12410   vl_api_add_node_next_t *mp;
12411   u8 *name = 0;
12412   u8 *next = 0;
12413   int ret;
12414
12415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12416     {
12417       if (unformat (i, "node %s", &name))
12418         ;
12419       else if (unformat (i, "next %s", &next))
12420         ;
12421       else
12422         break;
12423     }
12424   if (name == 0)
12425     {
12426       errmsg ("node name required");
12427       return -99;
12428     }
12429   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12430     {
12431       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12432       return -99;
12433     }
12434   if (next == 0)
12435     {
12436       errmsg ("next node required");
12437       return -99;
12438     }
12439   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12440     {
12441       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12442       return -99;
12443     }
12444
12445   M (ADD_NODE_NEXT, mp);
12446   clib_memcpy (mp->node_name, name, vec_len (name));
12447   clib_memcpy (mp->next_name, next, vec_len (next));
12448   vec_free (name);
12449   vec_free (next);
12450
12451   S (mp);
12452   W (ret);
12453   return ret;
12454 }
12455
12456 static int
12457 api_l2tpv3_create_tunnel (vat_main_t * vam)
12458 {
12459   unformat_input_t *i = vam->input;
12460   ip6_address_t client_address, our_address;
12461   int client_address_set = 0;
12462   int our_address_set = 0;
12463   u32 local_session_id = 0;
12464   u32 remote_session_id = 0;
12465   u64 local_cookie = 0;
12466   u64 remote_cookie = 0;
12467   u8 l2_sublayer_present = 0;
12468   vl_api_l2tpv3_create_tunnel_t *mp;
12469   int ret;
12470
12471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12472     {
12473       if (unformat (i, "client_address %U", unformat_ip6_address,
12474                     &client_address))
12475         client_address_set = 1;
12476       else if (unformat (i, "our_address %U", unformat_ip6_address,
12477                          &our_address))
12478         our_address_set = 1;
12479       else if (unformat (i, "local_session_id %d", &local_session_id))
12480         ;
12481       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12482         ;
12483       else if (unformat (i, "local_cookie %lld", &local_cookie))
12484         ;
12485       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12486         ;
12487       else if (unformat (i, "l2-sublayer-present"))
12488         l2_sublayer_present = 1;
12489       else
12490         break;
12491     }
12492
12493   if (client_address_set == 0)
12494     {
12495       errmsg ("client_address required");
12496       return -99;
12497     }
12498
12499   if (our_address_set == 0)
12500     {
12501       errmsg ("our_address required");
12502       return -99;
12503     }
12504
12505   M (L2TPV3_CREATE_TUNNEL, mp);
12506
12507   clib_memcpy (mp->client_address, client_address.as_u8,
12508                sizeof (mp->client_address));
12509
12510   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12511
12512   mp->local_session_id = ntohl (local_session_id);
12513   mp->remote_session_id = ntohl (remote_session_id);
12514   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12515   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12516   mp->l2_sublayer_present = l2_sublayer_present;
12517   mp->is_ipv6 = 1;
12518
12519   S (mp);
12520   W (ret);
12521   return ret;
12522 }
12523
12524 static int
12525 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12526 {
12527   unformat_input_t *i = vam->input;
12528   u32 sw_if_index;
12529   u8 sw_if_index_set = 0;
12530   u64 new_local_cookie = 0;
12531   u64 new_remote_cookie = 0;
12532   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12533   int ret;
12534
12535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12536     {
12537       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12538         sw_if_index_set = 1;
12539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12540         sw_if_index_set = 1;
12541       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12542         ;
12543       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12544         ;
12545       else
12546         break;
12547     }
12548
12549   if (sw_if_index_set == 0)
12550     {
12551       errmsg ("missing interface name or sw_if_index");
12552       return -99;
12553     }
12554
12555   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12556
12557   mp->sw_if_index = ntohl (sw_if_index);
12558   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12559   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12560
12561   S (mp);
12562   W (ret);
12563   return ret;
12564 }
12565
12566 static int
12567 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12568 {
12569   unformat_input_t *i = vam->input;
12570   vl_api_l2tpv3_interface_enable_disable_t *mp;
12571   u32 sw_if_index;
12572   u8 sw_if_index_set = 0;
12573   u8 enable_disable = 1;
12574   int ret;
12575
12576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12577     {
12578       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12579         sw_if_index_set = 1;
12580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12581         sw_if_index_set = 1;
12582       else if (unformat (i, "enable"))
12583         enable_disable = 1;
12584       else if (unformat (i, "disable"))
12585         enable_disable = 0;
12586       else
12587         break;
12588     }
12589
12590   if (sw_if_index_set == 0)
12591     {
12592       errmsg ("missing interface name or sw_if_index");
12593       return -99;
12594     }
12595
12596   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12597
12598   mp->sw_if_index = ntohl (sw_if_index);
12599   mp->enable_disable = enable_disable;
12600
12601   S (mp);
12602   W (ret);
12603   return ret;
12604 }
12605
12606 static int
12607 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12608 {
12609   unformat_input_t *i = vam->input;
12610   vl_api_l2tpv3_set_lookup_key_t *mp;
12611   u8 key = ~0;
12612   int ret;
12613
12614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12615     {
12616       if (unformat (i, "lookup_v6_src"))
12617         key = L2T_LOOKUP_SRC_ADDRESS;
12618       else if (unformat (i, "lookup_v6_dst"))
12619         key = L2T_LOOKUP_DST_ADDRESS;
12620       else if (unformat (i, "lookup_session_id"))
12621         key = L2T_LOOKUP_SESSION_ID;
12622       else
12623         break;
12624     }
12625
12626   if (key == (u8) ~ 0)
12627     {
12628       errmsg ("l2tp session lookup key unset");
12629       return -99;
12630     }
12631
12632   M (L2TPV3_SET_LOOKUP_KEY, mp);
12633
12634   mp->key = key;
12635
12636   S (mp);
12637   W (ret);
12638   return ret;
12639 }
12640
12641 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12642   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12643 {
12644   vat_main_t *vam = &vat_main;
12645
12646   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12647          format_ip6_address, mp->our_address,
12648          format_ip6_address, mp->client_address,
12649          clib_net_to_host_u32 (mp->sw_if_index));
12650
12651   print (vam->ofp,
12652          "   local cookies %016llx %016llx remote cookie %016llx",
12653          clib_net_to_host_u64 (mp->local_cookie[0]),
12654          clib_net_to_host_u64 (mp->local_cookie[1]),
12655          clib_net_to_host_u64 (mp->remote_cookie));
12656
12657   print (vam->ofp, "   local session-id %d remote session-id %d",
12658          clib_net_to_host_u32 (mp->local_session_id),
12659          clib_net_to_host_u32 (mp->remote_session_id));
12660
12661   print (vam->ofp, "   l2 specific sublayer %s\n",
12662          mp->l2_sublayer_present ? "preset" : "absent");
12663
12664 }
12665
12666 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12667   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12668 {
12669   vat_main_t *vam = &vat_main;
12670   vat_json_node_t *node = NULL;
12671   struct in6_addr addr;
12672
12673   if (VAT_JSON_ARRAY != vam->json_tree.type)
12674     {
12675       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12676       vat_json_init_array (&vam->json_tree);
12677     }
12678   node = vat_json_array_add (&vam->json_tree);
12679
12680   vat_json_init_object (node);
12681
12682   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12683   vat_json_object_add_ip6 (node, "our_address", addr);
12684   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12685   vat_json_object_add_ip6 (node, "client_address", addr);
12686
12687   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12688   vat_json_init_array (lc);
12689   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12690   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12691   vat_json_object_add_uint (node, "remote_cookie",
12692                             clib_net_to_host_u64 (mp->remote_cookie));
12693
12694   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12695   vat_json_object_add_uint (node, "local_session_id",
12696                             clib_net_to_host_u32 (mp->local_session_id));
12697   vat_json_object_add_uint (node, "remote_session_id",
12698                             clib_net_to_host_u32 (mp->remote_session_id));
12699   vat_json_object_add_string_copy (node, "l2_sublayer",
12700                                    mp->l2_sublayer_present ? (u8 *) "present"
12701                                    : (u8 *) "absent");
12702 }
12703
12704 static int
12705 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12706 {
12707   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12708   vl_api_control_ping_t *mp_ping;
12709   int ret;
12710
12711   /* Get list of l2tpv3-tunnel interfaces */
12712   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12713   S (mp);
12714
12715   /* Use a control ping for synchronization */
12716   MPING (CONTROL_PING, mp_ping);
12717   S (mp_ping);
12718
12719   W (ret);
12720   return ret;
12721 }
12722
12723
12724 static void vl_api_sw_interface_tap_details_t_handler
12725   (vl_api_sw_interface_tap_details_t * mp)
12726 {
12727   vat_main_t *vam = &vat_main;
12728
12729   print (vam->ofp, "%-16s %d",
12730          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12731 }
12732
12733 static void vl_api_sw_interface_tap_details_t_handler_json
12734   (vl_api_sw_interface_tap_details_t * mp)
12735 {
12736   vat_main_t *vam = &vat_main;
12737   vat_json_node_t *node = NULL;
12738
12739   if (VAT_JSON_ARRAY != vam->json_tree.type)
12740     {
12741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12742       vat_json_init_array (&vam->json_tree);
12743     }
12744   node = vat_json_array_add (&vam->json_tree);
12745
12746   vat_json_init_object (node);
12747   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12748   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12749 }
12750
12751 static int
12752 api_sw_interface_tap_dump (vat_main_t * vam)
12753 {
12754   vl_api_sw_interface_tap_dump_t *mp;
12755   vl_api_control_ping_t *mp_ping;
12756   int ret;
12757
12758   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12759   /* Get list of tap interfaces */
12760   M (SW_INTERFACE_TAP_DUMP, mp);
12761   S (mp);
12762
12763   /* Use a control ping for synchronization */
12764   MPING (CONTROL_PING, mp_ping);
12765   S (mp_ping);
12766
12767   W (ret);
12768   return ret;
12769 }
12770
12771 static void vl_api_sw_interface_tap_v2_details_t_handler
12772   (vl_api_sw_interface_tap_v2_details_t * mp)
12773 {
12774   vat_main_t *vam = &vat_main;
12775
12776   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12777                     mp->host_ip4_prefix_len);
12778   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12779                     mp->host_ip6_prefix_len);
12780
12781   print (vam->ofp,
12782          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12783          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12784          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12785          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12786          mp->host_bridge, ip4, ip6);
12787
12788   vec_free (ip4);
12789   vec_free (ip6);
12790 }
12791
12792 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12793   (vl_api_sw_interface_tap_v2_details_t * mp)
12794 {
12795   vat_main_t *vam = &vat_main;
12796   vat_json_node_t *node = NULL;
12797
12798   if (VAT_JSON_ARRAY != vam->json_tree.type)
12799     {
12800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12801       vat_json_init_array (&vam->json_tree);
12802     }
12803   node = vat_json_array_add (&vam->json_tree);
12804
12805   vat_json_init_object (node);
12806   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12807   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12808   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12809   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12810   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12811   vat_json_object_add_string_copy (node, "host_mac_addr",
12812                                    format (0, "%U", format_ethernet_address,
12813                                            &mp->host_mac_addr));
12814   vat_json_object_add_string_copy (node, "host_namespace",
12815                                    mp->host_namespace);
12816   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12817   vat_json_object_add_string_copy (node, "host_ip4_addr",
12818                                    format (0, "%U/%d", format_ip4_address,
12819                                            mp->host_ip4_addr,
12820                                            mp->host_ip4_prefix_len));
12821   vat_json_object_add_string_copy (node, "host_ip6_addr",
12822                                    format (0, "%U/%d", format_ip6_address,
12823                                            mp->host_ip6_addr,
12824                                            mp->host_ip6_prefix_len));
12825
12826 }
12827
12828 static int
12829 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12830 {
12831   vl_api_sw_interface_tap_v2_dump_t *mp;
12832   vl_api_control_ping_t *mp_ping;
12833   int ret;
12834
12835   print (vam->ofp,
12836          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12837          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12838          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12839          "host_ip6_addr");
12840
12841   /* Get list of tap interfaces */
12842   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12843   S (mp);
12844
12845   /* Use a control ping for synchronization */
12846   MPING (CONTROL_PING, mp_ping);
12847   S (mp_ping);
12848
12849   W (ret);
12850   return ret;
12851 }
12852
12853 static uword unformat_vxlan_decap_next
12854   (unformat_input_t * input, va_list * args)
12855 {
12856   u32 *result = va_arg (*args, u32 *);
12857   u32 tmp;
12858
12859   if (unformat (input, "l2"))
12860     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12861   else if (unformat (input, "%d", &tmp))
12862     *result = tmp;
12863   else
12864     return 0;
12865   return 1;
12866 }
12867
12868 static int
12869 api_vxlan_add_del_tunnel (vat_main_t * vam)
12870 {
12871   unformat_input_t *line_input = vam->input;
12872   vl_api_vxlan_add_del_tunnel_t *mp;
12873   ip46_address_t src, dst;
12874   u8 is_add = 1;
12875   u8 ipv4_set = 0, ipv6_set = 0;
12876   u8 src_set = 0;
12877   u8 dst_set = 0;
12878   u8 grp_set = 0;
12879   u32 instance = ~0;
12880   u32 mcast_sw_if_index = ~0;
12881   u32 encap_vrf_id = 0;
12882   u32 decap_next_index = ~0;
12883   u32 vni = 0;
12884   int ret;
12885
12886   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12887   memset (&src, 0, sizeof src);
12888   memset (&dst, 0, sizeof dst);
12889
12890   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12891     {
12892       if (unformat (line_input, "del"))
12893         is_add = 0;
12894       else if (unformat (line_input, "instance %d", &instance))
12895         ;
12896       else
12897         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12898         {
12899           ipv4_set = 1;
12900           src_set = 1;
12901         }
12902       else
12903         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12904         {
12905           ipv4_set = 1;
12906           dst_set = 1;
12907         }
12908       else
12909         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12910         {
12911           ipv6_set = 1;
12912           src_set = 1;
12913         }
12914       else
12915         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12916         {
12917           ipv6_set = 1;
12918           dst_set = 1;
12919         }
12920       else if (unformat (line_input, "group %U %U",
12921                          unformat_ip4_address, &dst.ip4,
12922                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12923         {
12924           grp_set = dst_set = 1;
12925           ipv4_set = 1;
12926         }
12927       else if (unformat (line_input, "group %U",
12928                          unformat_ip4_address, &dst.ip4))
12929         {
12930           grp_set = dst_set = 1;
12931           ipv4_set = 1;
12932         }
12933       else if (unformat (line_input, "group %U %U",
12934                          unformat_ip6_address, &dst.ip6,
12935                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12936         {
12937           grp_set = dst_set = 1;
12938           ipv6_set = 1;
12939         }
12940       else if (unformat (line_input, "group %U",
12941                          unformat_ip6_address, &dst.ip6))
12942         {
12943           grp_set = dst_set = 1;
12944           ipv6_set = 1;
12945         }
12946       else
12947         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12948         ;
12949       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12950         ;
12951       else if (unformat (line_input, "decap-next %U",
12952                          unformat_vxlan_decap_next, &decap_next_index))
12953         ;
12954       else if (unformat (line_input, "vni %d", &vni))
12955         ;
12956       else
12957         {
12958           errmsg ("parse error '%U'", format_unformat_error, line_input);
12959           return -99;
12960         }
12961     }
12962
12963   if (src_set == 0)
12964     {
12965       errmsg ("tunnel src address not specified");
12966       return -99;
12967     }
12968   if (dst_set == 0)
12969     {
12970       errmsg ("tunnel dst address not specified");
12971       return -99;
12972     }
12973
12974   if (grp_set && !ip46_address_is_multicast (&dst))
12975     {
12976       errmsg ("tunnel group address not multicast");
12977       return -99;
12978     }
12979   if (grp_set && mcast_sw_if_index == ~0)
12980     {
12981       errmsg ("tunnel nonexistent multicast device");
12982       return -99;
12983     }
12984   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12985     {
12986       errmsg ("tunnel dst address must be unicast");
12987       return -99;
12988     }
12989
12990
12991   if (ipv4_set && ipv6_set)
12992     {
12993       errmsg ("both IPv4 and IPv6 addresses specified");
12994       return -99;
12995     }
12996
12997   if ((vni == 0) || (vni >> 24))
12998     {
12999       errmsg ("vni not specified or out of range");
13000       return -99;
13001     }
13002
13003   M (VXLAN_ADD_DEL_TUNNEL, mp);
13004
13005   if (ipv6_set)
13006     {
13007       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13008       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13009     }
13010   else
13011     {
13012       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13013       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13014     }
13015
13016   mp->instance = htonl (instance);
13017   mp->encap_vrf_id = ntohl (encap_vrf_id);
13018   mp->decap_next_index = ntohl (decap_next_index);
13019   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13020   mp->vni = ntohl (vni);
13021   mp->is_add = is_add;
13022   mp->is_ipv6 = ipv6_set;
13023
13024   S (mp);
13025   W (ret);
13026   return ret;
13027 }
13028
13029 static void vl_api_vxlan_tunnel_details_t_handler
13030   (vl_api_vxlan_tunnel_details_t * mp)
13031 {
13032   vat_main_t *vam = &vat_main;
13033   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13034   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13035
13036   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13037          ntohl (mp->sw_if_index),
13038          ntohl (mp->instance),
13039          format_ip46_address, &src, IP46_TYPE_ANY,
13040          format_ip46_address, &dst, IP46_TYPE_ANY,
13041          ntohl (mp->encap_vrf_id),
13042          ntohl (mp->decap_next_index), ntohl (mp->vni),
13043          ntohl (mp->mcast_sw_if_index));
13044 }
13045
13046 static void vl_api_vxlan_tunnel_details_t_handler_json
13047   (vl_api_vxlan_tunnel_details_t * mp)
13048 {
13049   vat_main_t *vam = &vat_main;
13050   vat_json_node_t *node = NULL;
13051
13052   if (VAT_JSON_ARRAY != vam->json_tree.type)
13053     {
13054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13055       vat_json_init_array (&vam->json_tree);
13056     }
13057   node = vat_json_array_add (&vam->json_tree);
13058
13059   vat_json_init_object (node);
13060   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13061
13062   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13063
13064   if (mp->is_ipv6)
13065     {
13066       struct in6_addr ip6;
13067
13068       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13069       vat_json_object_add_ip6 (node, "src_address", ip6);
13070       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13071       vat_json_object_add_ip6 (node, "dst_address", ip6);
13072     }
13073   else
13074     {
13075       struct in_addr ip4;
13076
13077       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13078       vat_json_object_add_ip4 (node, "src_address", ip4);
13079       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13080       vat_json_object_add_ip4 (node, "dst_address", ip4);
13081     }
13082   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13083   vat_json_object_add_uint (node, "decap_next_index",
13084                             ntohl (mp->decap_next_index));
13085   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13086   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13087   vat_json_object_add_uint (node, "mcast_sw_if_index",
13088                             ntohl (mp->mcast_sw_if_index));
13089 }
13090
13091 static int
13092 api_vxlan_tunnel_dump (vat_main_t * vam)
13093 {
13094   unformat_input_t *i = vam->input;
13095   vl_api_vxlan_tunnel_dump_t *mp;
13096   vl_api_control_ping_t *mp_ping;
13097   u32 sw_if_index;
13098   u8 sw_if_index_set = 0;
13099   int ret;
13100
13101   /* Parse args required to build the message */
13102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13103     {
13104       if (unformat (i, "sw_if_index %d", &sw_if_index))
13105         sw_if_index_set = 1;
13106       else
13107         break;
13108     }
13109
13110   if (sw_if_index_set == 0)
13111     {
13112       sw_if_index = ~0;
13113     }
13114
13115   if (!vam->json_output)
13116     {
13117       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13118              "sw_if_index", "instance", "src_address", "dst_address",
13119              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13120     }
13121
13122   /* Get list of vxlan-tunnel interfaces */
13123   M (VXLAN_TUNNEL_DUMP, mp);
13124
13125   mp->sw_if_index = htonl (sw_if_index);
13126
13127   S (mp);
13128
13129   /* Use a control ping for synchronization */
13130   MPING (CONTROL_PING, mp_ping);
13131   S (mp_ping);
13132
13133   W (ret);
13134   return ret;
13135 }
13136
13137 static uword unformat_geneve_decap_next
13138   (unformat_input_t * input, va_list * args)
13139 {
13140   u32 *result = va_arg (*args, u32 *);
13141   u32 tmp;
13142
13143   if (unformat (input, "l2"))
13144     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13145   else if (unformat (input, "%d", &tmp))
13146     *result = tmp;
13147   else
13148     return 0;
13149   return 1;
13150 }
13151
13152 static int
13153 api_geneve_add_del_tunnel (vat_main_t * vam)
13154 {
13155   unformat_input_t *line_input = vam->input;
13156   vl_api_geneve_add_del_tunnel_t *mp;
13157   ip46_address_t src, dst;
13158   u8 is_add = 1;
13159   u8 ipv4_set = 0, ipv6_set = 0;
13160   u8 src_set = 0;
13161   u8 dst_set = 0;
13162   u8 grp_set = 0;
13163   u32 mcast_sw_if_index = ~0;
13164   u32 encap_vrf_id = 0;
13165   u32 decap_next_index = ~0;
13166   u32 vni = 0;
13167   int ret;
13168
13169   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13170   memset (&src, 0, sizeof src);
13171   memset (&dst, 0, sizeof dst);
13172
13173   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13174     {
13175       if (unformat (line_input, "del"))
13176         is_add = 0;
13177       else
13178         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13179         {
13180           ipv4_set = 1;
13181           src_set = 1;
13182         }
13183       else
13184         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13185         {
13186           ipv4_set = 1;
13187           dst_set = 1;
13188         }
13189       else
13190         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13191         {
13192           ipv6_set = 1;
13193           src_set = 1;
13194         }
13195       else
13196         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13197         {
13198           ipv6_set = 1;
13199           dst_set = 1;
13200         }
13201       else if (unformat (line_input, "group %U %U",
13202                          unformat_ip4_address, &dst.ip4,
13203                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13204         {
13205           grp_set = dst_set = 1;
13206           ipv4_set = 1;
13207         }
13208       else if (unformat (line_input, "group %U",
13209                          unformat_ip4_address, &dst.ip4))
13210         {
13211           grp_set = dst_set = 1;
13212           ipv4_set = 1;
13213         }
13214       else if (unformat (line_input, "group %U %U",
13215                          unformat_ip6_address, &dst.ip6,
13216                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13217         {
13218           grp_set = dst_set = 1;
13219           ipv6_set = 1;
13220         }
13221       else if (unformat (line_input, "group %U",
13222                          unformat_ip6_address, &dst.ip6))
13223         {
13224           grp_set = dst_set = 1;
13225           ipv6_set = 1;
13226         }
13227       else
13228         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13229         ;
13230       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13231         ;
13232       else if (unformat (line_input, "decap-next %U",
13233                          unformat_geneve_decap_next, &decap_next_index))
13234         ;
13235       else if (unformat (line_input, "vni %d", &vni))
13236         ;
13237       else
13238         {
13239           errmsg ("parse error '%U'", format_unformat_error, line_input);
13240           return -99;
13241         }
13242     }
13243
13244   if (src_set == 0)
13245     {
13246       errmsg ("tunnel src address not specified");
13247       return -99;
13248     }
13249   if (dst_set == 0)
13250     {
13251       errmsg ("tunnel dst address not specified");
13252       return -99;
13253     }
13254
13255   if (grp_set && !ip46_address_is_multicast (&dst))
13256     {
13257       errmsg ("tunnel group address not multicast");
13258       return -99;
13259     }
13260   if (grp_set && mcast_sw_if_index == ~0)
13261     {
13262       errmsg ("tunnel nonexistent multicast device");
13263       return -99;
13264     }
13265   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13266     {
13267       errmsg ("tunnel dst address must be unicast");
13268       return -99;
13269     }
13270
13271
13272   if (ipv4_set && ipv6_set)
13273     {
13274       errmsg ("both IPv4 and IPv6 addresses specified");
13275       return -99;
13276     }
13277
13278   if ((vni == 0) || (vni >> 24))
13279     {
13280       errmsg ("vni not specified or out of range");
13281       return -99;
13282     }
13283
13284   M (GENEVE_ADD_DEL_TUNNEL, mp);
13285
13286   if (ipv6_set)
13287     {
13288       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13289       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13290     }
13291   else
13292     {
13293       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13294       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13295     }
13296   mp->encap_vrf_id = ntohl (encap_vrf_id);
13297   mp->decap_next_index = ntohl (decap_next_index);
13298   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13299   mp->vni = ntohl (vni);
13300   mp->is_add = is_add;
13301   mp->is_ipv6 = ipv6_set;
13302
13303   S (mp);
13304   W (ret);
13305   return ret;
13306 }
13307
13308 static void vl_api_geneve_tunnel_details_t_handler
13309   (vl_api_geneve_tunnel_details_t * mp)
13310 {
13311   vat_main_t *vam = &vat_main;
13312   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13313   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13314
13315   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13316          ntohl (mp->sw_if_index),
13317          format_ip46_address, &src, IP46_TYPE_ANY,
13318          format_ip46_address, &dst, IP46_TYPE_ANY,
13319          ntohl (mp->encap_vrf_id),
13320          ntohl (mp->decap_next_index), ntohl (mp->vni),
13321          ntohl (mp->mcast_sw_if_index));
13322 }
13323
13324 static void vl_api_geneve_tunnel_details_t_handler_json
13325   (vl_api_geneve_tunnel_details_t * mp)
13326 {
13327   vat_main_t *vam = &vat_main;
13328   vat_json_node_t *node = NULL;
13329
13330   if (VAT_JSON_ARRAY != vam->json_tree.type)
13331     {
13332       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13333       vat_json_init_array (&vam->json_tree);
13334     }
13335   node = vat_json_array_add (&vam->json_tree);
13336
13337   vat_json_init_object (node);
13338   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13339   if (mp->is_ipv6)
13340     {
13341       struct in6_addr ip6;
13342
13343       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13344       vat_json_object_add_ip6 (node, "src_address", ip6);
13345       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13346       vat_json_object_add_ip6 (node, "dst_address", ip6);
13347     }
13348   else
13349     {
13350       struct in_addr ip4;
13351
13352       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13353       vat_json_object_add_ip4 (node, "src_address", ip4);
13354       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13355       vat_json_object_add_ip4 (node, "dst_address", ip4);
13356     }
13357   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13358   vat_json_object_add_uint (node, "decap_next_index",
13359                             ntohl (mp->decap_next_index));
13360   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13361   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13362   vat_json_object_add_uint (node, "mcast_sw_if_index",
13363                             ntohl (mp->mcast_sw_if_index));
13364 }
13365
13366 static int
13367 api_geneve_tunnel_dump (vat_main_t * vam)
13368 {
13369   unformat_input_t *i = vam->input;
13370   vl_api_geneve_tunnel_dump_t *mp;
13371   vl_api_control_ping_t *mp_ping;
13372   u32 sw_if_index;
13373   u8 sw_if_index_set = 0;
13374   int ret;
13375
13376   /* Parse args required to build the message */
13377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13378     {
13379       if (unformat (i, "sw_if_index %d", &sw_if_index))
13380         sw_if_index_set = 1;
13381       else
13382         break;
13383     }
13384
13385   if (sw_if_index_set == 0)
13386     {
13387       sw_if_index = ~0;
13388     }
13389
13390   if (!vam->json_output)
13391     {
13392       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13393              "sw_if_index", "local_address", "remote_address",
13394              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13395     }
13396
13397   /* Get list of geneve-tunnel interfaces */
13398   M (GENEVE_TUNNEL_DUMP, mp);
13399
13400   mp->sw_if_index = htonl (sw_if_index);
13401
13402   S (mp);
13403
13404   /* Use a control ping for synchronization */
13405   M (CONTROL_PING, mp_ping);
13406   S (mp_ping);
13407
13408   W (ret);
13409   return ret;
13410 }
13411
13412 static int
13413 api_gre_add_del_tunnel (vat_main_t * vam)
13414 {
13415   unformat_input_t *line_input = vam->input;
13416   vl_api_gre_add_del_tunnel_t *mp;
13417   ip4_address_t src4, dst4;
13418   ip6_address_t src6, dst6;
13419   u8 is_add = 1;
13420   u8 ipv4_set = 0;
13421   u8 ipv6_set = 0;
13422   u8 t_type = GRE_TUNNEL_TYPE_L3;
13423   u8 src_set = 0;
13424   u8 dst_set = 0;
13425   u32 outer_fib_id = 0;
13426   u32 session_id = 0;
13427   u32 instance = ~0;
13428   int ret;
13429
13430   memset (&src4, 0, sizeof src4);
13431   memset (&dst4, 0, sizeof dst4);
13432   memset (&src6, 0, sizeof src6);
13433   memset (&dst6, 0, sizeof dst6);
13434
13435   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13436     {
13437       if (unformat (line_input, "del"))
13438         is_add = 0;
13439       else if (unformat (line_input, "instance %d", &instance))
13440         ;
13441       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13442         {
13443           src_set = 1;
13444           ipv4_set = 1;
13445         }
13446       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13447         {
13448           dst_set = 1;
13449           ipv4_set = 1;
13450         }
13451       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13452         {
13453           src_set = 1;
13454           ipv6_set = 1;
13455         }
13456       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13457         {
13458           dst_set = 1;
13459           ipv6_set = 1;
13460         }
13461       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13462         ;
13463       else if (unformat (line_input, "teb"))
13464         t_type = GRE_TUNNEL_TYPE_TEB;
13465       else if (unformat (line_input, "erspan %d", &session_id))
13466         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13467       else
13468         {
13469           errmsg ("parse error '%U'", format_unformat_error, line_input);
13470           return -99;
13471         }
13472     }
13473
13474   if (src_set == 0)
13475     {
13476       errmsg ("tunnel src address not specified");
13477       return -99;
13478     }
13479   if (dst_set == 0)
13480     {
13481       errmsg ("tunnel dst address not specified");
13482       return -99;
13483     }
13484   if (ipv4_set && ipv6_set)
13485     {
13486       errmsg ("both IPv4 and IPv6 addresses specified");
13487       return -99;
13488     }
13489
13490
13491   M (GRE_ADD_DEL_TUNNEL, mp);
13492
13493   if (ipv4_set)
13494     {
13495       clib_memcpy (&mp->src_address, &src4, 4);
13496       clib_memcpy (&mp->dst_address, &dst4, 4);
13497     }
13498   else
13499     {
13500       clib_memcpy (&mp->src_address, &src6, 16);
13501       clib_memcpy (&mp->dst_address, &dst6, 16);
13502     }
13503   mp->instance = htonl (instance);
13504   mp->outer_fib_id = htonl (outer_fib_id);
13505   mp->is_add = is_add;
13506   mp->session_id = htons ((u16) session_id);
13507   mp->tunnel_type = t_type;
13508   mp->is_ipv6 = ipv6_set;
13509
13510   S (mp);
13511   W (ret);
13512   return ret;
13513 }
13514
13515 static void vl_api_gre_tunnel_details_t_handler
13516   (vl_api_gre_tunnel_details_t * mp)
13517 {
13518   vat_main_t *vam = &vat_main;
13519   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13520   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13521
13522   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13523          ntohl (mp->sw_if_index),
13524          ntohl (mp->instance),
13525          format_ip46_address, &src, IP46_TYPE_ANY,
13526          format_ip46_address, &dst, IP46_TYPE_ANY,
13527          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13528 }
13529
13530 static void vl_api_gre_tunnel_details_t_handler_json
13531   (vl_api_gre_tunnel_details_t * mp)
13532 {
13533   vat_main_t *vam = &vat_main;
13534   vat_json_node_t *node = NULL;
13535   struct in_addr ip4;
13536   struct in6_addr ip6;
13537
13538   if (VAT_JSON_ARRAY != vam->json_tree.type)
13539     {
13540       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13541       vat_json_init_array (&vam->json_tree);
13542     }
13543   node = vat_json_array_add (&vam->json_tree);
13544
13545   vat_json_init_object (node);
13546   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13547   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13548   if (!mp->is_ipv6)
13549     {
13550       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13551       vat_json_object_add_ip4 (node, "src_address", ip4);
13552       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13553       vat_json_object_add_ip4 (node, "dst_address", ip4);
13554     }
13555   else
13556     {
13557       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13558       vat_json_object_add_ip6 (node, "src_address", ip6);
13559       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13560       vat_json_object_add_ip6 (node, "dst_address", ip6);
13561     }
13562   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13563   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13564   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13565   vat_json_object_add_uint (node, "session_id", mp->session_id);
13566 }
13567
13568 static int
13569 api_gre_tunnel_dump (vat_main_t * vam)
13570 {
13571   unformat_input_t *i = vam->input;
13572   vl_api_gre_tunnel_dump_t *mp;
13573   vl_api_control_ping_t *mp_ping;
13574   u32 sw_if_index;
13575   u8 sw_if_index_set = 0;
13576   int ret;
13577
13578   /* Parse args required to build the message */
13579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13580     {
13581       if (unformat (i, "sw_if_index %d", &sw_if_index))
13582         sw_if_index_set = 1;
13583       else
13584         break;
13585     }
13586
13587   if (sw_if_index_set == 0)
13588     {
13589       sw_if_index = ~0;
13590     }
13591
13592   if (!vam->json_output)
13593     {
13594       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13595              "sw_if_index", "instance", "src_address", "dst_address",
13596              "tunnel_type", "outer_fib_id", "session_id");
13597     }
13598
13599   /* Get list of gre-tunnel interfaces */
13600   M (GRE_TUNNEL_DUMP, mp);
13601
13602   mp->sw_if_index = htonl (sw_if_index);
13603
13604   S (mp);
13605
13606   /* Use a control ping for synchronization */
13607   MPING (CONTROL_PING, mp_ping);
13608   S (mp_ping);
13609
13610   W (ret);
13611   return ret;
13612 }
13613
13614 static int
13615 api_l2_fib_clear_table (vat_main_t * vam)
13616 {
13617 //  unformat_input_t * i = vam->input;
13618   vl_api_l2_fib_clear_table_t *mp;
13619   int ret;
13620
13621   M (L2_FIB_CLEAR_TABLE, mp);
13622
13623   S (mp);
13624   W (ret);
13625   return ret;
13626 }
13627
13628 static int
13629 api_l2_interface_efp_filter (vat_main_t * vam)
13630 {
13631   unformat_input_t *i = vam->input;
13632   vl_api_l2_interface_efp_filter_t *mp;
13633   u32 sw_if_index;
13634   u8 enable = 1;
13635   u8 sw_if_index_set = 0;
13636   int ret;
13637
13638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13639     {
13640       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13641         sw_if_index_set = 1;
13642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13643         sw_if_index_set = 1;
13644       else if (unformat (i, "enable"))
13645         enable = 1;
13646       else if (unformat (i, "disable"))
13647         enable = 0;
13648       else
13649         {
13650           clib_warning ("parse error '%U'", format_unformat_error, i);
13651           return -99;
13652         }
13653     }
13654
13655   if (sw_if_index_set == 0)
13656     {
13657       errmsg ("missing sw_if_index");
13658       return -99;
13659     }
13660
13661   M (L2_INTERFACE_EFP_FILTER, mp);
13662
13663   mp->sw_if_index = ntohl (sw_if_index);
13664   mp->enable_disable = enable;
13665
13666   S (mp);
13667   W (ret);
13668   return ret;
13669 }
13670
13671 #define foreach_vtr_op                          \
13672 _("disable",  L2_VTR_DISABLED)                  \
13673 _("push-1",  L2_VTR_PUSH_1)                     \
13674 _("push-2",  L2_VTR_PUSH_2)                     \
13675 _("pop-1",  L2_VTR_POP_1)                       \
13676 _("pop-2",  L2_VTR_POP_2)                       \
13677 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13678 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13679 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13680 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13681
13682 static int
13683 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13684 {
13685   unformat_input_t *i = vam->input;
13686   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13687   u32 sw_if_index;
13688   u8 sw_if_index_set = 0;
13689   u8 vtr_op_set = 0;
13690   u32 vtr_op = 0;
13691   u32 push_dot1q = 1;
13692   u32 tag1 = ~0;
13693   u32 tag2 = ~0;
13694   int ret;
13695
13696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13697     {
13698       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13699         sw_if_index_set = 1;
13700       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13701         sw_if_index_set = 1;
13702       else if (unformat (i, "vtr_op %d", &vtr_op))
13703         vtr_op_set = 1;
13704 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13705       foreach_vtr_op
13706 #undef _
13707         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13708         ;
13709       else if (unformat (i, "tag1 %d", &tag1))
13710         ;
13711       else if (unformat (i, "tag2 %d", &tag2))
13712         ;
13713       else
13714         {
13715           clib_warning ("parse error '%U'", format_unformat_error, i);
13716           return -99;
13717         }
13718     }
13719
13720   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13721     {
13722       errmsg ("missing vtr operation or sw_if_index");
13723       return -99;
13724     }
13725
13726   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13727   mp->sw_if_index = ntohl (sw_if_index);
13728   mp->vtr_op = ntohl (vtr_op);
13729   mp->push_dot1q = ntohl (push_dot1q);
13730   mp->tag1 = ntohl (tag1);
13731   mp->tag2 = ntohl (tag2);
13732
13733   S (mp);
13734   W (ret);
13735   return ret;
13736 }
13737
13738 static int
13739 api_create_vhost_user_if (vat_main_t * vam)
13740 {
13741   unformat_input_t *i = vam->input;
13742   vl_api_create_vhost_user_if_t *mp;
13743   u8 *file_name;
13744   u8 is_server = 0;
13745   u8 file_name_set = 0;
13746   u32 custom_dev_instance = ~0;
13747   u8 hwaddr[6];
13748   u8 use_custom_mac = 0;
13749   u8 *tag = 0;
13750   int ret;
13751
13752   /* Shut up coverity */
13753   memset (hwaddr, 0, sizeof (hwaddr));
13754
13755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13756     {
13757       if (unformat (i, "socket %s", &file_name))
13758         {
13759           file_name_set = 1;
13760         }
13761       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13762         ;
13763       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13764         use_custom_mac = 1;
13765       else if (unformat (i, "server"))
13766         is_server = 1;
13767       else if (unformat (i, "tag %s", &tag))
13768         ;
13769       else
13770         break;
13771     }
13772
13773   if (file_name_set == 0)
13774     {
13775       errmsg ("missing socket file name");
13776       return -99;
13777     }
13778
13779   if (vec_len (file_name) > 255)
13780     {
13781       errmsg ("socket file name too long");
13782       return -99;
13783     }
13784   vec_add1 (file_name, 0);
13785
13786   M (CREATE_VHOST_USER_IF, mp);
13787
13788   mp->is_server = is_server;
13789   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13790   vec_free (file_name);
13791   if (custom_dev_instance != ~0)
13792     {
13793       mp->renumber = 1;
13794       mp->custom_dev_instance = ntohl (custom_dev_instance);
13795     }
13796   mp->use_custom_mac = use_custom_mac;
13797   clib_memcpy (mp->mac_address, hwaddr, 6);
13798   if (tag)
13799     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13800   vec_free (tag);
13801
13802   S (mp);
13803   W (ret);
13804   return ret;
13805 }
13806
13807 static int
13808 api_modify_vhost_user_if (vat_main_t * vam)
13809 {
13810   unformat_input_t *i = vam->input;
13811   vl_api_modify_vhost_user_if_t *mp;
13812   u8 *file_name;
13813   u8 is_server = 0;
13814   u8 file_name_set = 0;
13815   u32 custom_dev_instance = ~0;
13816   u8 sw_if_index_set = 0;
13817   u32 sw_if_index = (u32) ~ 0;
13818   int ret;
13819
13820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13821     {
13822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13823         sw_if_index_set = 1;
13824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13825         sw_if_index_set = 1;
13826       else if (unformat (i, "socket %s", &file_name))
13827         {
13828           file_name_set = 1;
13829         }
13830       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13831         ;
13832       else if (unformat (i, "server"))
13833         is_server = 1;
13834       else
13835         break;
13836     }
13837
13838   if (sw_if_index_set == 0)
13839     {
13840       errmsg ("missing sw_if_index or interface name");
13841       return -99;
13842     }
13843
13844   if (file_name_set == 0)
13845     {
13846       errmsg ("missing socket file name");
13847       return -99;
13848     }
13849
13850   if (vec_len (file_name) > 255)
13851     {
13852       errmsg ("socket file name too long");
13853       return -99;
13854     }
13855   vec_add1 (file_name, 0);
13856
13857   M (MODIFY_VHOST_USER_IF, mp);
13858
13859   mp->sw_if_index = ntohl (sw_if_index);
13860   mp->is_server = is_server;
13861   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13862   vec_free (file_name);
13863   if (custom_dev_instance != ~0)
13864     {
13865       mp->renumber = 1;
13866       mp->custom_dev_instance = ntohl (custom_dev_instance);
13867     }
13868
13869   S (mp);
13870   W (ret);
13871   return ret;
13872 }
13873
13874 static int
13875 api_delete_vhost_user_if (vat_main_t * vam)
13876 {
13877   unformat_input_t *i = vam->input;
13878   vl_api_delete_vhost_user_if_t *mp;
13879   u32 sw_if_index = ~0;
13880   u8 sw_if_index_set = 0;
13881   int ret;
13882
13883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13884     {
13885       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13886         sw_if_index_set = 1;
13887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13888         sw_if_index_set = 1;
13889       else
13890         break;
13891     }
13892
13893   if (sw_if_index_set == 0)
13894     {
13895       errmsg ("missing sw_if_index or interface name");
13896       return -99;
13897     }
13898
13899
13900   M (DELETE_VHOST_USER_IF, mp);
13901
13902   mp->sw_if_index = ntohl (sw_if_index);
13903
13904   S (mp);
13905   W (ret);
13906   return ret;
13907 }
13908
13909 static void vl_api_sw_interface_vhost_user_details_t_handler
13910   (vl_api_sw_interface_vhost_user_details_t * mp)
13911 {
13912   vat_main_t *vam = &vat_main;
13913
13914   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13915          (char *) mp->interface_name,
13916          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13917          clib_net_to_host_u64 (mp->features), mp->is_server,
13918          ntohl (mp->num_regions), (char *) mp->sock_filename);
13919   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13920 }
13921
13922 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13923   (vl_api_sw_interface_vhost_user_details_t * mp)
13924 {
13925   vat_main_t *vam = &vat_main;
13926   vat_json_node_t *node = NULL;
13927
13928   if (VAT_JSON_ARRAY != vam->json_tree.type)
13929     {
13930       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13931       vat_json_init_array (&vam->json_tree);
13932     }
13933   node = vat_json_array_add (&vam->json_tree);
13934
13935   vat_json_init_object (node);
13936   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13937   vat_json_object_add_string_copy (node, "interface_name",
13938                                    mp->interface_name);
13939   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13940                             ntohl (mp->virtio_net_hdr_sz));
13941   vat_json_object_add_uint (node, "features",
13942                             clib_net_to_host_u64 (mp->features));
13943   vat_json_object_add_uint (node, "is_server", mp->is_server);
13944   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13945   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13946   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13947 }
13948
13949 static int
13950 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13951 {
13952   vl_api_sw_interface_vhost_user_dump_t *mp;
13953   vl_api_control_ping_t *mp_ping;
13954   int ret;
13955   print (vam->ofp,
13956          "Interface name            idx hdr_sz features server regions filename");
13957
13958   /* Get list of vhost-user interfaces */
13959   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13960   S (mp);
13961
13962   /* Use a control ping for synchronization */
13963   MPING (CONTROL_PING, mp_ping);
13964   S (mp_ping);
13965
13966   W (ret);
13967   return ret;
13968 }
13969
13970 static int
13971 api_show_version (vat_main_t * vam)
13972 {
13973   vl_api_show_version_t *mp;
13974   int ret;
13975
13976   M (SHOW_VERSION, mp);
13977
13978   S (mp);
13979   W (ret);
13980   return ret;
13981 }
13982
13983
13984 static int
13985 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13986 {
13987   unformat_input_t *line_input = vam->input;
13988   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13989   ip4_address_t local4, remote4;
13990   ip6_address_t local6, remote6;
13991   u8 is_add = 1;
13992   u8 ipv4_set = 0, ipv6_set = 0;
13993   u8 local_set = 0;
13994   u8 remote_set = 0;
13995   u8 grp_set = 0;
13996   u32 mcast_sw_if_index = ~0;
13997   u32 encap_vrf_id = 0;
13998   u32 decap_vrf_id = 0;
13999   u8 protocol = ~0;
14000   u32 vni;
14001   u8 vni_set = 0;
14002   int ret;
14003
14004   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14005   memset (&local4, 0, sizeof local4);
14006   memset (&remote4, 0, sizeof remote4);
14007   memset (&local6, 0, sizeof local6);
14008   memset (&remote6, 0, sizeof remote6);
14009
14010   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14011     {
14012       if (unformat (line_input, "del"))
14013         is_add = 0;
14014       else if (unformat (line_input, "local %U",
14015                          unformat_ip4_address, &local4))
14016         {
14017           local_set = 1;
14018           ipv4_set = 1;
14019         }
14020       else if (unformat (line_input, "remote %U",
14021                          unformat_ip4_address, &remote4))
14022         {
14023           remote_set = 1;
14024           ipv4_set = 1;
14025         }
14026       else if (unformat (line_input, "local %U",
14027                          unformat_ip6_address, &local6))
14028         {
14029           local_set = 1;
14030           ipv6_set = 1;
14031         }
14032       else if (unformat (line_input, "remote %U",
14033                          unformat_ip6_address, &remote6))
14034         {
14035           remote_set = 1;
14036           ipv6_set = 1;
14037         }
14038       else if (unformat (line_input, "group %U %U",
14039                          unformat_ip4_address, &remote4,
14040                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14041         {
14042           grp_set = remote_set = 1;
14043           ipv4_set = 1;
14044         }
14045       else if (unformat (line_input, "group %U",
14046                          unformat_ip4_address, &remote4))
14047         {
14048           grp_set = remote_set = 1;
14049           ipv4_set = 1;
14050         }
14051       else if (unformat (line_input, "group %U %U",
14052                          unformat_ip6_address, &remote6,
14053                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14054         {
14055           grp_set = remote_set = 1;
14056           ipv6_set = 1;
14057         }
14058       else if (unformat (line_input, "group %U",
14059                          unformat_ip6_address, &remote6))
14060         {
14061           grp_set = remote_set = 1;
14062           ipv6_set = 1;
14063         }
14064       else
14065         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14066         ;
14067       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14068         ;
14069       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14070         ;
14071       else if (unformat (line_input, "vni %d", &vni))
14072         vni_set = 1;
14073       else if (unformat (line_input, "next-ip4"))
14074         protocol = 1;
14075       else if (unformat (line_input, "next-ip6"))
14076         protocol = 2;
14077       else if (unformat (line_input, "next-ethernet"))
14078         protocol = 3;
14079       else if (unformat (line_input, "next-nsh"))
14080         protocol = 4;
14081       else
14082         {
14083           errmsg ("parse error '%U'", format_unformat_error, line_input);
14084           return -99;
14085         }
14086     }
14087
14088   if (local_set == 0)
14089     {
14090       errmsg ("tunnel local address not specified");
14091       return -99;
14092     }
14093   if (remote_set == 0)
14094     {
14095       errmsg ("tunnel remote address not specified");
14096       return -99;
14097     }
14098   if (grp_set && mcast_sw_if_index == ~0)
14099     {
14100       errmsg ("tunnel nonexistent multicast device");
14101       return -99;
14102     }
14103   if (ipv4_set && ipv6_set)
14104     {
14105       errmsg ("both IPv4 and IPv6 addresses specified");
14106       return -99;
14107     }
14108
14109   if (vni_set == 0)
14110     {
14111       errmsg ("vni not specified");
14112       return -99;
14113     }
14114
14115   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14116
14117
14118   if (ipv6_set)
14119     {
14120       clib_memcpy (&mp->local, &local6, sizeof (local6));
14121       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14122     }
14123   else
14124     {
14125       clib_memcpy (&mp->local, &local4, sizeof (local4));
14126       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14127     }
14128
14129   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14130   mp->encap_vrf_id = ntohl (encap_vrf_id);
14131   mp->decap_vrf_id = ntohl (decap_vrf_id);
14132   mp->protocol = protocol;
14133   mp->vni = ntohl (vni);
14134   mp->is_add = is_add;
14135   mp->is_ipv6 = ipv6_set;
14136
14137   S (mp);
14138   W (ret);
14139   return ret;
14140 }
14141
14142 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14143   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14144 {
14145   vat_main_t *vam = &vat_main;
14146   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14147   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14148
14149   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14150          ntohl (mp->sw_if_index),
14151          format_ip46_address, &local, IP46_TYPE_ANY,
14152          format_ip46_address, &remote, IP46_TYPE_ANY,
14153          ntohl (mp->vni), mp->protocol,
14154          ntohl (mp->mcast_sw_if_index),
14155          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14156 }
14157
14158
14159 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14160   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14161 {
14162   vat_main_t *vam = &vat_main;
14163   vat_json_node_t *node = NULL;
14164   struct in_addr ip4;
14165   struct in6_addr ip6;
14166
14167   if (VAT_JSON_ARRAY != vam->json_tree.type)
14168     {
14169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14170       vat_json_init_array (&vam->json_tree);
14171     }
14172   node = vat_json_array_add (&vam->json_tree);
14173
14174   vat_json_init_object (node);
14175   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14176   if (mp->is_ipv6)
14177     {
14178       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14179       vat_json_object_add_ip6 (node, "local", ip6);
14180       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14181       vat_json_object_add_ip6 (node, "remote", ip6);
14182     }
14183   else
14184     {
14185       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14186       vat_json_object_add_ip4 (node, "local", ip4);
14187       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14188       vat_json_object_add_ip4 (node, "remote", ip4);
14189     }
14190   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14191   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14192   vat_json_object_add_uint (node, "mcast_sw_if_index",
14193                             ntohl (mp->mcast_sw_if_index));
14194   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14195   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14196   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14197 }
14198
14199 static int
14200 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14201 {
14202   unformat_input_t *i = vam->input;
14203   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14204   vl_api_control_ping_t *mp_ping;
14205   u32 sw_if_index;
14206   u8 sw_if_index_set = 0;
14207   int ret;
14208
14209   /* Parse args required to build the message */
14210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14211     {
14212       if (unformat (i, "sw_if_index %d", &sw_if_index))
14213         sw_if_index_set = 1;
14214       else
14215         break;
14216     }
14217
14218   if (sw_if_index_set == 0)
14219     {
14220       sw_if_index = ~0;
14221     }
14222
14223   if (!vam->json_output)
14224     {
14225       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14226              "sw_if_index", "local", "remote", "vni",
14227              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14228     }
14229
14230   /* Get list of vxlan-tunnel interfaces */
14231   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14232
14233   mp->sw_if_index = htonl (sw_if_index);
14234
14235   S (mp);
14236
14237   /* Use a control ping for synchronization */
14238   MPING (CONTROL_PING, mp_ping);
14239   S (mp_ping);
14240
14241   W (ret);
14242   return ret;
14243 }
14244
14245 static void vl_api_l2_fib_table_details_t_handler
14246   (vl_api_l2_fib_table_details_t * mp)
14247 {
14248   vat_main_t *vam = &vat_main;
14249
14250   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14251          "       %d       %d     %d",
14252          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14253          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14254          mp->bvi_mac);
14255 }
14256
14257 static void vl_api_l2_fib_table_details_t_handler_json
14258   (vl_api_l2_fib_table_details_t * mp)
14259 {
14260   vat_main_t *vam = &vat_main;
14261   vat_json_node_t *node = NULL;
14262
14263   if (VAT_JSON_ARRAY != vam->json_tree.type)
14264     {
14265       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14266       vat_json_init_array (&vam->json_tree);
14267     }
14268   node = vat_json_array_add (&vam->json_tree);
14269
14270   vat_json_init_object (node);
14271   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14272   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14273   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14274   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14275   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14276   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14277 }
14278
14279 static int
14280 api_l2_fib_table_dump (vat_main_t * vam)
14281 {
14282   unformat_input_t *i = vam->input;
14283   vl_api_l2_fib_table_dump_t *mp;
14284   vl_api_control_ping_t *mp_ping;
14285   u32 bd_id;
14286   u8 bd_id_set = 0;
14287   int ret;
14288
14289   /* Parse args required to build the message */
14290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14291     {
14292       if (unformat (i, "bd_id %d", &bd_id))
14293         bd_id_set = 1;
14294       else
14295         break;
14296     }
14297
14298   if (bd_id_set == 0)
14299     {
14300       errmsg ("missing bridge domain");
14301       return -99;
14302     }
14303
14304   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14305
14306   /* Get list of l2 fib entries */
14307   M (L2_FIB_TABLE_DUMP, mp);
14308
14309   mp->bd_id = ntohl (bd_id);
14310   S (mp);
14311
14312   /* Use a control ping for synchronization */
14313   MPING (CONTROL_PING, mp_ping);
14314   S (mp_ping);
14315
14316   W (ret);
14317   return ret;
14318 }
14319
14320
14321 static int
14322 api_interface_name_renumber (vat_main_t * vam)
14323 {
14324   unformat_input_t *line_input = vam->input;
14325   vl_api_interface_name_renumber_t *mp;
14326   u32 sw_if_index = ~0;
14327   u32 new_show_dev_instance = ~0;
14328   int ret;
14329
14330   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14331     {
14332       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14333                     &sw_if_index))
14334         ;
14335       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14336         ;
14337       else if (unformat (line_input, "new_show_dev_instance %d",
14338                          &new_show_dev_instance))
14339         ;
14340       else
14341         break;
14342     }
14343
14344   if (sw_if_index == ~0)
14345     {
14346       errmsg ("missing interface name or sw_if_index");
14347       return -99;
14348     }
14349
14350   if (new_show_dev_instance == ~0)
14351     {
14352       errmsg ("missing new_show_dev_instance");
14353       return -99;
14354     }
14355
14356   M (INTERFACE_NAME_RENUMBER, mp);
14357
14358   mp->sw_if_index = ntohl (sw_if_index);
14359   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14360
14361   S (mp);
14362   W (ret);
14363   return ret;
14364 }
14365
14366 static int
14367 api_ip_probe_neighbor (vat_main_t * vam)
14368 {
14369   unformat_input_t *i = vam->input;
14370   vl_api_ip_probe_neighbor_t *mp;
14371   u8 int_set = 0;
14372   u8 adr_set = 0;
14373   u8 is_ipv6 = 0;
14374   u8 dst_adr[16];
14375   u32 sw_if_index;
14376   int ret;
14377
14378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14379     {
14380       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14381         int_set = 1;
14382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14383         int_set = 1;
14384       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14385         adr_set = 1;
14386       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14387         {
14388           adr_set = 1;
14389           is_ipv6 = 1;
14390         }
14391       else
14392         break;
14393     }
14394
14395   if (int_set == 0)
14396     {
14397       errmsg ("missing interface");
14398       return -99;
14399     }
14400
14401   if (adr_set == 0)
14402     {
14403       errmsg ("missing addresses");
14404       return -99;
14405     }
14406
14407   M (IP_PROBE_NEIGHBOR, mp);
14408
14409   mp->sw_if_index = ntohl (sw_if_index);
14410   mp->is_ipv6 = is_ipv6;
14411   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14412
14413   S (mp);
14414   W (ret);
14415   return ret;
14416 }
14417
14418 static int
14419 api_want_ip4_arp_events (vat_main_t * vam)
14420 {
14421   unformat_input_t *line_input = vam->input;
14422   vl_api_want_ip4_arp_events_t *mp;
14423   ip4_address_t address;
14424   int address_set = 0;
14425   u32 enable_disable = 1;
14426   int ret;
14427
14428   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14429     {
14430       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14431         address_set = 1;
14432       else if (unformat (line_input, "del"))
14433         enable_disable = 0;
14434       else
14435         break;
14436     }
14437
14438   if (address_set == 0)
14439     {
14440       errmsg ("missing addresses");
14441       return -99;
14442     }
14443
14444   M (WANT_IP4_ARP_EVENTS, mp);
14445   mp->enable_disable = enable_disable;
14446   mp->pid = htonl (getpid ());
14447   mp->address = address.as_u32;
14448
14449   S (mp);
14450   W (ret);
14451   return ret;
14452 }
14453
14454 static int
14455 api_want_ip6_nd_events (vat_main_t * vam)
14456 {
14457   unformat_input_t *line_input = vam->input;
14458   vl_api_want_ip6_nd_events_t *mp;
14459   ip6_address_t address;
14460   int address_set = 0;
14461   u32 enable_disable = 1;
14462   int ret;
14463
14464   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14465     {
14466       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14467         address_set = 1;
14468       else if (unformat (line_input, "del"))
14469         enable_disable = 0;
14470       else
14471         break;
14472     }
14473
14474   if (address_set == 0)
14475     {
14476       errmsg ("missing addresses");
14477       return -99;
14478     }
14479
14480   M (WANT_IP6_ND_EVENTS, mp);
14481   mp->enable_disable = enable_disable;
14482   mp->pid = htonl (getpid ());
14483   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14484
14485   S (mp);
14486   W (ret);
14487   return ret;
14488 }
14489
14490 static int
14491 api_want_l2_macs_events (vat_main_t * vam)
14492 {
14493   unformat_input_t *line_input = vam->input;
14494   vl_api_want_l2_macs_events_t *mp;
14495   u8 enable_disable = 1;
14496   u32 scan_delay = 0;
14497   u32 max_macs_in_event = 0;
14498   u32 learn_limit = 0;
14499   int ret;
14500
14501   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14502     {
14503       if (unformat (line_input, "learn-limit %d", &learn_limit))
14504         ;
14505       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14506         ;
14507       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14508         ;
14509       else if (unformat (line_input, "disable"))
14510         enable_disable = 0;
14511       else
14512         break;
14513     }
14514
14515   M (WANT_L2_MACS_EVENTS, mp);
14516   mp->enable_disable = enable_disable;
14517   mp->pid = htonl (getpid ());
14518   mp->learn_limit = htonl (learn_limit);
14519   mp->scan_delay = (u8) scan_delay;
14520   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14521   S (mp);
14522   W (ret);
14523   return ret;
14524 }
14525
14526 static int
14527 api_input_acl_set_interface (vat_main_t * vam)
14528 {
14529   unformat_input_t *i = vam->input;
14530   vl_api_input_acl_set_interface_t *mp;
14531   u32 sw_if_index;
14532   int sw_if_index_set;
14533   u32 ip4_table_index = ~0;
14534   u32 ip6_table_index = ~0;
14535   u32 l2_table_index = ~0;
14536   u8 is_add = 1;
14537   int ret;
14538
14539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14540     {
14541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14542         sw_if_index_set = 1;
14543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14544         sw_if_index_set = 1;
14545       else if (unformat (i, "del"))
14546         is_add = 0;
14547       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14548         ;
14549       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14550         ;
14551       else if (unformat (i, "l2-table %d", &l2_table_index))
14552         ;
14553       else
14554         {
14555           clib_warning ("parse error '%U'", format_unformat_error, i);
14556           return -99;
14557         }
14558     }
14559
14560   if (sw_if_index_set == 0)
14561     {
14562       errmsg ("missing interface name or sw_if_index");
14563       return -99;
14564     }
14565
14566   M (INPUT_ACL_SET_INTERFACE, mp);
14567
14568   mp->sw_if_index = ntohl (sw_if_index);
14569   mp->ip4_table_index = ntohl (ip4_table_index);
14570   mp->ip6_table_index = ntohl (ip6_table_index);
14571   mp->l2_table_index = ntohl (l2_table_index);
14572   mp->is_add = is_add;
14573
14574   S (mp);
14575   W (ret);
14576   return ret;
14577 }
14578
14579 static int
14580 api_output_acl_set_interface (vat_main_t * vam)
14581 {
14582   unformat_input_t *i = vam->input;
14583   vl_api_output_acl_set_interface_t *mp;
14584   u32 sw_if_index;
14585   int sw_if_index_set;
14586   u32 ip4_table_index = ~0;
14587   u32 ip6_table_index = ~0;
14588   u32 l2_table_index = ~0;
14589   u8 is_add = 1;
14590   int ret;
14591
14592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14593     {
14594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14595         sw_if_index_set = 1;
14596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14597         sw_if_index_set = 1;
14598       else if (unformat (i, "del"))
14599         is_add = 0;
14600       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14601         ;
14602       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14603         ;
14604       else if (unformat (i, "l2-table %d", &l2_table_index))
14605         ;
14606       else
14607         {
14608           clib_warning ("parse error '%U'", format_unformat_error, i);
14609           return -99;
14610         }
14611     }
14612
14613   if (sw_if_index_set == 0)
14614     {
14615       errmsg ("missing interface name or sw_if_index");
14616       return -99;
14617     }
14618
14619   M (OUTPUT_ACL_SET_INTERFACE, mp);
14620
14621   mp->sw_if_index = ntohl (sw_if_index);
14622   mp->ip4_table_index = ntohl (ip4_table_index);
14623   mp->ip6_table_index = ntohl (ip6_table_index);
14624   mp->l2_table_index = ntohl (l2_table_index);
14625   mp->is_add = is_add;
14626
14627   S (mp);
14628   W (ret);
14629   return ret;
14630 }
14631
14632 static int
14633 api_ip_address_dump (vat_main_t * vam)
14634 {
14635   unformat_input_t *i = vam->input;
14636   vl_api_ip_address_dump_t *mp;
14637   vl_api_control_ping_t *mp_ping;
14638   u32 sw_if_index = ~0;
14639   u8 sw_if_index_set = 0;
14640   u8 ipv4_set = 0;
14641   u8 ipv6_set = 0;
14642   int ret;
14643
14644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14645     {
14646       if (unformat (i, "sw_if_index %d", &sw_if_index))
14647         sw_if_index_set = 1;
14648       else
14649         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14650         sw_if_index_set = 1;
14651       else if (unformat (i, "ipv4"))
14652         ipv4_set = 1;
14653       else if (unformat (i, "ipv6"))
14654         ipv6_set = 1;
14655       else
14656         break;
14657     }
14658
14659   if (ipv4_set && ipv6_set)
14660     {
14661       errmsg ("ipv4 and ipv6 flags cannot be both set");
14662       return -99;
14663     }
14664
14665   if ((!ipv4_set) && (!ipv6_set))
14666     {
14667       errmsg ("no ipv4 nor ipv6 flag set");
14668       return -99;
14669     }
14670
14671   if (sw_if_index_set == 0)
14672     {
14673       errmsg ("missing interface name or sw_if_index");
14674       return -99;
14675     }
14676
14677   vam->current_sw_if_index = sw_if_index;
14678   vam->is_ipv6 = ipv6_set;
14679
14680   M (IP_ADDRESS_DUMP, mp);
14681   mp->sw_if_index = ntohl (sw_if_index);
14682   mp->is_ipv6 = ipv6_set;
14683   S (mp);
14684
14685   /* Use a control ping for synchronization */
14686   MPING (CONTROL_PING, mp_ping);
14687   S (mp_ping);
14688
14689   W (ret);
14690   return ret;
14691 }
14692
14693 static int
14694 api_ip_dump (vat_main_t * vam)
14695 {
14696   vl_api_ip_dump_t *mp;
14697   vl_api_control_ping_t *mp_ping;
14698   unformat_input_t *in = vam->input;
14699   int ipv4_set = 0;
14700   int ipv6_set = 0;
14701   int is_ipv6;
14702   int i;
14703   int ret;
14704
14705   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14706     {
14707       if (unformat (in, "ipv4"))
14708         ipv4_set = 1;
14709       else if (unformat (in, "ipv6"))
14710         ipv6_set = 1;
14711       else
14712         break;
14713     }
14714
14715   if (ipv4_set && ipv6_set)
14716     {
14717       errmsg ("ipv4 and ipv6 flags cannot be both set");
14718       return -99;
14719     }
14720
14721   if ((!ipv4_set) && (!ipv6_set))
14722     {
14723       errmsg ("no ipv4 nor ipv6 flag set");
14724       return -99;
14725     }
14726
14727   is_ipv6 = ipv6_set;
14728   vam->is_ipv6 = is_ipv6;
14729
14730   /* free old data */
14731   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14732     {
14733       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14734     }
14735   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14736
14737   M (IP_DUMP, mp);
14738   mp->is_ipv6 = ipv6_set;
14739   S (mp);
14740
14741   /* Use a control ping for synchronization */
14742   MPING (CONTROL_PING, mp_ping);
14743   S (mp_ping);
14744
14745   W (ret);
14746   return ret;
14747 }
14748
14749 static int
14750 api_ipsec_spd_add_del (vat_main_t * vam)
14751 {
14752   unformat_input_t *i = vam->input;
14753   vl_api_ipsec_spd_add_del_t *mp;
14754   u32 spd_id = ~0;
14755   u8 is_add = 1;
14756   int ret;
14757
14758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14759     {
14760       if (unformat (i, "spd_id %d", &spd_id))
14761         ;
14762       else if (unformat (i, "del"))
14763         is_add = 0;
14764       else
14765         {
14766           clib_warning ("parse error '%U'", format_unformat_error, i);
14767           return -99;
14768         }
14769     }
14770   if (spd_id == ~0)
14771     {
14772       errmsg ("spd_id must be set");
14773       return -99;
14774     }
14775
14776   M (IPSEC_SPD_ADD_DEL, mp);
14777
14778   mp->spd_id = ntohl (spd_id);
14779   mp->is_add = is_add;
14780
14781   S (mp);
14782   W (ret);
14783   return ret;
14784 }
14785
14786 static int
14787 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14788 {
14789   unformat_input_t *i = vam->input;
14790   vl_api_ipsec_interface_add_del_spd_t *mp;
14791   u32 sw_if_index;
14792   u8 sw_if_index_set = 0;
14793   u32 spd_id = (u32) ~ 0;
14794   u8 is_add = 1;
14795   int ret;
14796
14797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14798     {
14799       if (unformat (i, "del"))
14800         is_add = 0;
14801       else if (unformat (i, "spd_id %d", &spd_id))
14802         ;
14803       else
14804         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14805         sw_if_index_set = 1;
14806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14807         sw_if_index_set = 1;
14808       else
14809         {
14810           clib_warning ("parse error '%U'", format_unformat_error, i);
14811           return -99;
14812         }
14813
14814     }
14815
14816   if (spd_id == (u32) ~ 0)
14817     {
14818       errmsg ("spd_id must be set");
14819       return -99;
14820     }
14821
14822   if (sw_if_index_set == 0)
14823     {
14824       errmsg ("missing interface name or sw_if_index");
14825       return -99;
14826     }
14827
14828   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14829
14830   mp->spd_id = ntohl (spd_id);
14831   mp->sw_if_index = ntohl (sw_if_index);
14832   mp->is_add = is_add;
14833
14834   S (mp);
14835   W (ret);
14836   return ret;
14837 }
14838
14839 static int
14840 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14841 {
14842   unformat_input_t *i = vam->input;
14843   vl_api_ipsec_spd_add_del_entry_t *mp;
14844   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14845   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14846   i32 priority = 0;
14847   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14848   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14849   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14850   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14851   int ret;
14852
14853   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14854   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14855   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14856   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14857   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14858   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14859
14860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14861     {
14862       if (unformat (i, "del"))
14863         is_add = 0;
14864       if (unformat (i, "outbound"))
14865         is_outbound = 1;
14866       if (unformat (i, "inbound"))
14867         is_outbound = 0;
14868       else if (unformat (i, "spd_id %d", &spd_id))
14869         ;
14870       else if (unformat (i, "sa_id %d", &sa_id))
14871         ;
14872       else if (unformat (i, "priority %d", &priority))
14873         ;
14874       else if (unformat (i, "protocol %d", &protocol))
14875         ;
14876       else if (unformat (i, "lport_start %d", &lport_start))
14877         ;
14878       else if (unformat (i, "lport_stop %d", &lport_stop))
14879         ;
14880       else if (unformat (i, "rport_start %d", &rport_start))
14881         ;
14882       else if (unformat (i, "rport_stop %d", &rport_stop))
14883         ;
14884       else
14885         if (unformat
14886             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14887         {
14888           is_ipv6 = 0;
14889           is_ip_any = 0;
14890         }
14891       else
14892         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14893         {
14894           is_ipv6 = 0;
14895           is_ip_any = 0;
14896         }
14897       else
14898         if (unformat
14899             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14900         {
14901           is_ipv6 = 0;
14902           is_ip_any = 0;
14903         }
14904       else
14905         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14906         {
14907           is_ipv6 = 0;
14908           is_ip_any = 0;
14909         }
14910       else
14911         if (unformat
14912             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14913         {
14914           is_ipv6 = 1;
14915           is_ip_any = 0;
14916         }
14917       else
14918         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14919         {
14920           is_ipv6 = 1;
14921           is_ip_any = 0;
14922         }
14923       else
14924         if (unformat
14925             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14926         {
14927           is_ipv6 = 1;
14928           is_ip_any = 0;
14929         }
14930       else
14931         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14932         {
14933           is_ipv6 = 1;
14934           is_ip_any = 0;
14935         }
14936       else
14937         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14938         {
14939           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14940             {
14941               clib_warning ("unsupported action: 'resolve'");
14942               return -99;
14943             }
14944         }
14945       else
14946         {
14947           clib_warning ("parse error '%U'", format_unformat_error, i);
14948           return -99;
14949         }
14950
14951     }
14952
14953   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14954
14955   mp->spd_id = ntohl (spd_id);
14956   mp->priority = ntohl (priority);
14957   mp->is_outbound = is_outbound;
14958
14959   mp->is_ipv6 = is_ipv6;
14960   if (is_ipv6 || is_ip_any)
14961     {
14962       clib_memcpy (mp->remote_address_start, &raddr6_start,
14963                    sizeof (ip6_address_t));
14964       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14965                    sizeof (ip6_address_t));
14966       clib_memcpy (mp->local_address_start, &laddr6_start,
14967                    sizeof (ip6_address_t));
14968       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14969                    sizeof (ip6_address_t));
14970     }
14971   else
14972     {
14973       clib_memcpy (mp->remote_address_start, &raddr4_start,
14974                    sizeof (ip4_address_t));
14975       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14976                    sizeof (ip4_address_t));
14977       clib_memcpy (mp->local_address_start, &laddr4_start,
14978                    sizeof (ip4_address_t));
14979       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14980                    sizeof (ip4_address_t));
14981     }
14982   mp->protocol = (u8) protocol;
14983   mp->local_port_start = ntohs ((u16) lport_start);
14984   mp->local_port_stop = ntohs ((u16) lport_stop);
14985   mp->remote_port_start = ntohs ((u16) rport_start);
14986   mp->remote_port_stop = ntohs ((u16) rport_stop);
14987   mp->policy = (u8) policy;
14988   mp->sa_id = ntohl (sa_id);
14989   mp->is_add = is_add;
14990   mp->is_ip_any = is_ip_any;
14991   S (mp);
14992   W (ret);
14993   return ret;
14994 }
14995
14996 static int
14997 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14998 {
14999   unformat_input_t *i = vam->input;
15000   vl_api_ipsec_sad_add_del_entry_t *mp;
15001   u32 sad_id = 0, spi = 0;
15002   u8 *ck = 0, *ik = 0;
15003   u8 is_add = 1;
15004
15005   u8 protocol = IPSEC_PROTOCOL_AH;
15006   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15007   u32 crypto_alg = 0, integ_alg = 0;
15008   ip4_address_t tun_src4;
15009   ip4_address_t tun_dst4;
15010   ip6_address_t tun_src6;
15011   ip6_address_t tun_dst6;
15012   int ret;
15013
15014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15015     {
15016       if (unformat (i, "del"))
15017         is_add = 0;
15018       else if (unformat (i, "sad_id %d", &sad_id))
15019         ;
15020       else if (unformat (i, "spi %d", &spi))
15021         ;
15022       else if (unformat (i, "esp"))
15023         protocol = IPSEC_PROTOCOL_ESP;
15024       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15025         {
15026           is_tunnel = 1;
15027           is_tunnel_ipv6 = 0;
15028         }
15029       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15030         {
15031           is_tunnel = 1;
15032           is_tunnel_ipv6 = 0;
15033         }
15034       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15035         {
15036           is_tunnel = 1;
15037           is_tunnel_ipv6 = 1;
15038         }
15039       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15040         {
15041           is_tunnel = 1;
15042           is_tunnel_ipv6 = 1;
15043         }
15044       else
15045         if (unformat
15046             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15047         {
15048           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15049               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15050             {
15051               clib_warning ("unsupported crypto-alg: '%U'",
15052                             format_ipsec_crypto_alg, crypto_alg);
15053               return -99;
15054             }
15055         }
15056       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15057         ;
15058       else
15059         if (unformat
15060             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15061         {
15062           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15063               integ_alg >= IPSEC_INTEG_N_ALG)
15064             {
15065               clib_warning ("unsupported integ-alg: '%U'",
15066                             format_ipsec_integ_alg, integ_alg);
15067               return -99;
15068             }
15069         }
15070       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15071         ;
15072       else
15073         {
15074           clib_warning ("parse error '%U'", format_unformat_error, i);
15075           return -99;
15076         }
15077
15078     }
15079
15080   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15081
15082   mp->sad_id = ntohl (sad_id);
15083   mp->is_add = is_add;
15084   mp->protocol = protocol;
15085   mp->spi = ntohl (spi);
15086   mp->is_tunnel = is_tunnel;
15087   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15088   mp->crypto_algorithm = crypto_alg;
15089   mp->integrity_algorithm = integ_alg;
15090   mp->crypto_key_length = vec_len (ck);
15091   mp->integrity_key_length = vec_len (ik);
15092
15093   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15094     mp->crypto_key_length = sizeof (mp->crypto_key);
15095
15096   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15097     mp->integrity_key_length = sizeof (mp->integrity_key);
15098
15099   if (ck)
15100     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15101   if (ik)
15102     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15103
15104   if (is_tunnel)
15105     {
15106       if (is_tunnel_ipv6)
15107         {
15108           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15109                        sizeof (ip6_address_t));
15110           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15111                        sizeof (ip6_address_t));
15112         }
15113       else
15114         {
15115           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15116                        sizeof (ip4_address_t));
15117           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15118                        sizeof (ip4_address_t));
15119         }
15120     }
15121
15122   S (mp);
15123   W (ret);
15124   return ret;
15125 }
15126
15127 static int
15128 api_ipsec_sa_set_key (vat_main_t * vam)
15129 {
15130   unformat_input_t *i = vam->input;
15131   vl_api_ipsec_sa_set_key_t *mp;
15132   u32 sa_id;
15133   u8 *ck = 0, *ik = 0;
15134   int ret;
15135
15136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15137     {
15138       if (unformat (i, "sa_id %d", &sa_id))
15139         ;
15140       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15141         ;
15142       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15143         ;
15144       else
15145         {
15146           clib_warning ("parse error '%U'", format_unformat_error, i);
15147           return -99;
15148         }
15149     }
15150
15151   M (IPSEC_SA_SET_KEY, mp);
15152
15153   mp->sa_id = ntohl (sa_id);
15154   mp->crypto_key_length = vec_len (ck);
15155   mp->integrity_key_length = vec_len (ik);
15156
15157   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15158     mp->crypto_key_length = sizeof (mp->crypto_key);
15159
15160   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15161     mp->integrity_key_length = sizeof (mp->integrity_key);
15162
15163   if (ck)
15164     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15165   if (ik)
15166     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15167
15168   S (mp);
15169   W (ret);
15170   return ret;
15171 }
15172
15173 static int
15174 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15175 {
15176   unformat_input_t *i = vam->input;
15177   vl_api_ipsec_tunnel_if_add_del_t *mp;
15178   u32 local_spi = 0, remote_spi = 0;
15179   u32 crypto_alg = 0, integ_alg = 0;
15180   u8 *lck = NULL, *rck = NULL;
15181   u8 *lik = NULL, *rik = NULL;
15182   ip4_address_t local_ip = { {0} };
15183   ip4_address_t remote_ip = { {0} };
15184   u8 is_add = 1;
15185   u8 esn = 0;
15186   u8 anti_replay = 0;
15187   u8 renumber = 0;
15188   u32 instance = ~0;
15189   int ret;
15190
15191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15192     {
15193       if (unformat (i, "del"))
15194         is_add = 0;
15195       else if (unformat (i, "esn"))
15196         esn = 1;
15197       else if (unformat (i, "anti_replay"))
15198         anti_replay = 1;
15199       else if (unformat (i, "local_spi %d", &local_spi))
15200         ;
15201       else if (unformat (i, "remote_spi %d", &remote_spi))
15202         ;
15203       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15204         ;
15205       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15206         ;
15207       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15208         ;
15209       else
15210         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15211         ;
15212       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15213         ;
15214       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15215         ;
15216       else
15217         if (unformat
15218             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15219         {
15220           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15221               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15222             {
15223               errmsg ("unsupported crypto-alg: '%U'\n",
15224                       format_ipsec_crypto_alg, crypto_alg);
15225               return -99;
15226             }
15227         }
15228       else
15229         if (unformat
15230             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15231         {
15232           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15233               integ_alg >= IPSEC_INTEG_N_ALG)
15234             {
15235               errmsg ("unsupported integ-alg: '%U'\n",
15236                       format_ipsec_integ_alg, integ_alg);
15237               return -99;
15238             }
15239         }
15240       else if (unformat (i, "instance %u", &instance))
15241         renumber = 1;
15242       else
15243         {
15244           errmsg ("parse error '%U'\n", format_unformat_error, i);
15245           return -99;
15246         }
15247     }
15248
15249   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15250
15251   mp->is_add = is_add;
15252   mp->esn = esn;
15253   mp->anti_replay = anti_replay;
15254
15255   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15256   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15257
15258   mp->local_spi = htonl (local_spi);
15259   mp->remote_spi = htonl (remote_spi);
15260   mp->crypto_alg = (u8) crypto_alg;
15261
15262   mp->local_crypto_key_len = 0;
15263   if (lck)
15264     {
15265       mp->local_crypto_key_len = vec_len (lck);
15266       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15267         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15268       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15269     }
15270
15271   mp->remote_crypto_key_len = 0;
15272   if (rck)
15273     {
15274       mp->remote_crypto_key_len = vec_len (rck);
15275       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15276         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15277       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15278     }
15279
15280   mp->integ_alg = (u8) integ_alg;
15281
15282   mp->local_integ_key_len = 0;
15283   if (lik)
15284     {
15285       mp->local_integ_key_len = vec_len (lik);
15286       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15287         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15288       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15289     }
15290
15291   mp->remote_integ_key_len = 0;
15292   if (rik)
15293     {
15294       mp->remote_integ_key_len = vec_len (rik);
15295       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15296         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15297       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15298     }
15299
15300   if (renumber)
15301     {
15302       mp->renumber = renumber;
15303       mp->show_instance = ntohl (instance);
15304     }
15305
15306   S (mp);
15307   W (ret);
15308   return ret;
15309 }
15310
15311 static void
15312 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15313 {
15314   vat_main_t *vam = &vat_main;
15315
15316   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15317          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15318          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15319          "tunnel_src_addr %U tunnel_dst_addr %U "
15320          "salt %u seq_outbound %lu last_seq_inbound %lu "
15321          "replay_window %lu total_data_size %lu\n",
15322          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15323          mp->protocol,
15324          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15325          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15326          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15327          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15328          mp->tunnel_src_addr,
15329          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15330          mp->tunnel_dst_addr,
15331          ntohl (mp->salt),
15332          clib_net_to_host_u64 (mp->seq_outbound),
15333          clib_net_to_host_u64 (mp->last_seq_inbound),
15334          clib_net_to_host_u64 (mp->replay_window),
15335          clib_net_to_host_u64 (mp->total_data_size));
15336 }
15337
15338 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15339 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15340
15341 static void vl_api_ipsec_sa_details_t_handler_json
15342   (vl_api_ipsec_sa_details_t * mp)
15343 {
15344   vat_main_t *vam = &vat_main;
15345   vat_json_node_t *node = NULL;
15346   struct in_addr src_ip4, dst_ip4;
15347   struct in6_addr src_ip6, dst_ip6;
15348
15349   if (VAT_JSON_ARRAY != vam->json_tree.type)
15350     {
15351       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15352       vat_json_init_array (&vam->json_tree);
15353     }
15354   node = vat_json_array_add (&vam->json_tree);
15355
15356   vat_json_init_object (node);
15357   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15358   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15359   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15360   vat_json_object_add_uint (node, "proto", mp->protocol);
15361   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15362   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15363   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15364   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15365   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15366   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15367   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15368                              mp->crypto_key_len);
15369   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15370                              mp->integ_key_len);
15371   if (mp->is_tunnel_ip6)
15372     {
15373       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15374       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15375       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15376       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15377     }
15378   else
15379     {
15380       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15381       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15382       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15383       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15384     }
15385   vat_json_object_add_uint (node, "replay_window",
15386                             clib_net_to_host_u64 (mp->replay_window));
15387   vat_json_object_add_uint (node, "total_data_size",
15388                             clib_net_to_host_u64 (mp->total_data_size));
15389
15390 }
15391
15392 static int
15393 api_ipsec_sa_dump (vat_main_t * vam)
15394 {
15395   unformat_input_t *i = vam->input;
15396   vl_api_ipsec_sa_dump_t *mp;
15397   vl_api_control_ping_t *mp_ping;
15398   u32 sa_id = ~0;
15399   int ret;
15400
15401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15402     {
15403       if (unformat (i, "sa_id %d", &sa_id))
15404         ;
15405       else
15406         {
15407           clib_warning ("parse error '%U'", format_unformat_error, i);
15408           return -99;
15409         }
15410     }
15411
15412   M (IPSEC_SA_DUMP, mp);
15413
15414   mp->sa_id = ntohl (sa_id);
15415
15416   S (mp);
15417
15418   /* Use a control ping for synchronization */
15419   M (CONTROL_PING, mp_ping);
15420   S (mp_ping);
15421
15422   W (ret);
15423   return ret;
15424 }
15425
15426 static int
15427 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15428 {
15429   unformat_input_t *i = vam->input;
15430   vl_api_ipsec_tunnel_if_set_key_t *mp;
15431   u32 sw_if_index = ~0;
15432   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15433   u8 *key = 0;
15434   u32 alg = ~0;
15435   int ret;
15436
15437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15438     {
15439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15440         ;
15441       else
15442         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15443         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15444       else
15445         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15446         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15447       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15448         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15449       else
15450         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15451         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15452       else if (unformat (i, "%U", unformat_hex_string, &key))
15453         ;
15454       else
15455         {
15456           clib_warning ("parse error '%U'", format_unformat_error, i);
15457           return -99;
15458         }
15459     }
15460
15461   if (sw_if_index == ~0)
15462     {
15463       errmsg ("interface must be specified");
15464       return -99;
15465     }
15466
15467   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15468     {
15469       errmsg ("key type must be specified");
15470       return -99;
15471     }
15472
15473   if (alg == ~0)
15474     {
15475       errmsg ("algorithm must be specified");
15476       return -99;
15477     }
15478
15479   if (vec_len (key) == 0)
15480     {
15481       errmsg ("key must be specified");
15482       return -99;
15483     }
15484
15485   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15486
15487   mp->sw_if_index = htonl (sw_if_index);
15488   mp->alg = alg;
15489   mp->key_type = key_type;
15490   mp->key_len = vec_len (key);
15491   clib_memcpy (mp->key, key, vec_len (key));
15492
15493   S (mp);
15494   W (ret);
15495
15496   return ret;
15497 }
15498
15499 static int
15500 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15501 {
15502   unformat_input_t *i = vam->input;
15503   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15504   u32 sw_if_index = ~0;
15505   u32 sa_id = ~0;
15506   u8 is_outbound = (u8) ~ 0;
15507   int ret;
15508
15509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15510     {
15511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15512         ;
15513       else if (unformat (i, "sa_id %d", &sa_id))
15514         ;
15515       else if (unformat (i, "outbound"))
15516         is_outbound = 1;
15517       else if (unformat (i, "inbound"))
15518         is_outbound = 0;
15519       else
15520         {
15521           clib_warning ("parse error '%U'", format_unformat_error, i);
15522           return -99;
15523         }
15524     }
15525
15526   if (sw_if_index == ~0)
15527     {
15528       errmsg ("interface must be specified");
15529       return -99;
15530     }
15531
15532   if (sa_id == ~0)
15533     {
15534       errmsg ("SA ID must be specified");
15535       return -99;
15536     }
15537
15538   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15539
15540   mp->sw_if_index = htonl (sw_if_index);
15541   mp->sa_id = htonl (sa_id);
15542   mp->is_outbound = is_outbound;
15543
15544   S (mp);
15545   W (ret);
15546
15547   return ret;
15548 }
15549
15550 static int
15551 api_ikev2_profile_add_del (vat_main_t * vam)
15552 {
15553   unformat_input_t *i = vam->input;
15554   vl_api_ikev2_profile_add_del_t *mp;
15555   u8 is_add = 1;
15556   u8 *name = 0;
15557   int ret;
15558
15559   const char *valid_chars = "a-zA-Z0-9_";
15560
15561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15562     {
15563       if (unformat (i, "del"))
15564         is_add = 0;
15565       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15566         vec_add1 (name, 0);
15567       else
15568         {
15569           errmsg ("parse error '%U'", format_unformat_error, i);
15570           return -99;
15571         }
15572     }
15573
15574   if (!vec_len (name))
15575     {
15576       errmsg ("profile name must be specified");
15577       return -99;
15578     }
15579
15580   if (vec_len (name) > 64)
15581     {
15582       errmsg ("profile name too long");
15583       return -99;
15584     }
15585
15586   M (IKEV2_PROFILE_ADD_DEL, mp);
15587
15588   clib_memcpy (mp->name, name, vec_len (name));
15589   mp->is_add = is_add;
15590   vec_free (name);
15591
15592   S (mp);
15593   W (ret);
15594   return ret;
15595 }
15596
15597 static int
15598 api_ikev2_profile_set_auth (vat_main_t * vam)
15599 {
15600   unformat_input_t *i = vam->input;
15601   vl_api_ikev2_profile_set_auth_t *mp;
15602   u8 *name = 0;
15603   u8 *data = 0;
15604   u32 auth_method = 0;
15605   u8 is_hex = 0;
15606   int ret;
15607
15608   const char *valid_chars = "a-zA-Z0-9_";
15609
15610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15611     {
15612       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15613         vec_add1 (name, 0);
15614       else if (unformat (i, "auth_method %U",
15615                          unformat_ikev2_auth_method, &auth_method))
15616         ;
15617       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15618         is_hex = 1;
15619       else if (unformat (i, "auth_data %v", &data))
15620         ;
15621       else
15622         {
15623           errmsg ("parse error '%U'", format_unformat_error, i);
15624           return -99;
15625         }
15626     }
15627
15628   if (!vec_len (name))
15629     {
15630       errmsg ("profile name must be specified");
15631       return -99;
15632     }
15633
15634   if (vec_len (name) > 64)
15635     {
15636       errmsg ("profile name too long");
15637       return -99;
15638     }
15639
15640   if (!vec_len (data))
15641     {
15642       errmsg ("auth_data must be specified");
15643       return -99;
15644     }
15645
15646   if (!auth_method)
15647     {
15648       errmsg ("auth_method must be specified");
15649       return -99;
15650     }
15651
15652   M (IKEV2_PROFILE_SET_AUTH, mp);
15653
15654   mp->is_hex = is_hex;
15655   mp->auth_method = (u8) auth_method;
15656   mp->data_len = vec_len (data);
15657   clib_memcpy (mp->name, name, vec_len (name));
15658   clib_memcpy (mp->data, data, vec_len (data));
15659   vec_free (name);
15660   vec_free (data);
15661
15662   S (mp);
15663   W (ret);
15664   return ret;
15665 }
15666
15667 static int
15668 api_ikev2_profile_set_id (vat_main_t * vam)
15669 {
15670   unformat_input_t *i = vam->input;
15671   vl_api_ikev2_profile_set_id_t *mp;
15672   u8 *name = 0;
15673   u8 *data = 0;
15674   u8 is_local = 0;
15675   u32 id_type = 0;
15676   ip4_address_t ip4;
15677   int ret;
15678
15679   const char *valid_chars = "a-zA-Z0-9_";
15680
15681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15682     {
15683       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15684         vec_add1 (name, 0);
15685       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15686         ;
15687       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15688         {
15689           data = vec_new (u8, 4);
15690           clib_memcpy (data, ip4.as_u8, 4);
15691         }
15692       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15693         ;
15694       else if (unformat (i, "id_data %v", &data))
15695         ;
15696       else if (unformat (i, "local"))
15697         is_local = 1;
15698       else if (unformat (i, "remote"))
15699         is_local = 0;
15700       else
15701         {
15702           errmsg ("parse error '%U'", format_unformat_error, i);
15703           return -99;
15704         }
15705     }
15706
15707   if (!vec_len (name))
15708     {
15709       errmsg ("profile name must be specified");
15710       return -99;
15711     }
15712
15713   if (vec_len (name) > 64)
15714     {
15715       errmsg ("profile name too long");
15716       return -99;
15717     }
15718
15719   if (!vec_len (data))
15720     {
15721       errmsg ("id_data must be specified");
15722       return -99;
15723     }
15724
15725   if (!id_type)
15726     {
15727       errmsg ("id_type must be specified");
15728       return -99;
15729     }
15730
15731   M (IKEV2_PROFILE_SET_ID, mp);
15732
15733   mp->is_local = is_local;
15734   mp->id_type = (u8) id_type;
15735   mp->data_len = vec_len (data);
15736   clib_memcpy (mp->name, name, vec_len (name));
15737   clib_memcpy (mp->data, data, vec_len (data));
15738   vec_free (name);
15739   vec_free (data);
15740
15741   S (mp);
15742   W (ret);
15743   return ret;
15744 }
15745
15746 static int
15747 api_ikev2_profile_set_ts (vat_main_t * vam)
15748 {
15749   unformat_input_t *i = vam->input;
15750   vl_api_ikev2_profile_set_ts_t *mp;
15751   u8 *name = 0;
15752   u8 is_local = 0;
15753   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15754   ip4_address_t start_addr, end_addr;
15755
15756   const char *valid_chars = "a-zA-Z0-9_";
15757   int ret;
15758
15759   start_addr.as_u32 = 0;
15760   end_addr.as_u32 = (u32) ~ 0;
15761
15762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15763     {
15764       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15765         vec_add1 (name, 0);
15766       else if (unformat (i, "protocol %d", &proto))
15767         ;
15768       else if (unformat (i, "start_port %d", &start_port))
15769         ;
15770       else if (unformat (i, "end_port %d", &end_port))
15771         ;
15772       else
15773         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15774         ;
15775       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15776         ;
15777       else if (unformat (i, "local"))
15778         is_local = 1;
15779       else if (unformat (i, "remote"))
15780         is_local = 0;
15781       else
15782         {
15783           errmsg ("parse error '%U'", format_unformat_error, i);
15784           return -99;
15785         }
15786     }
15787
15788   if (!vec_len (name))
15789     {
15790       errmsg ("profile name must be specified");
15791       return -99;
15792     }
15793
15794   if (vec_len (name) > 64)
15795     {
15796       errmsg ("profile name too long");
15797       return -99;
15798     }
15799
15800   M (IKEV2_PROFILE_SET_TS, mp);
15801
15802   mp->is_local = is_local;
15803   mp->proto = (u8) proto;
15804   mp->start_port = (u16) start_port;
15805   mp->end_port = (u16) end_port;
15806   mp->start_addr = start_addr.as_u32;
15807   mp->end_addr = end_addr.as_u32;
15808   clib_memcpy (mp->name, name, vec_len (name));
15809   vec_free (name);
15810
15811   S (mp);
15812   W (ret);
15813   return ret;
15814 }
15815
15816 static int
15817 api_ikev2_set_local_key (vat_main_t * vam)
15818 {
15819   unformat_input_t *i = vam->input;
15820   vl_api_ikev2_set_local_key_t *mp;
15821   u8 *file = 0;
15822   int ret;
15823
15824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15825     {
15826       if (unformat (i, "file %v", &file))
15827         vec_add1 (file, 0);
15828       else
15829         {
15830           errmsg ("parse error '%U'", format_unformat_error, i);
15831           return -99;
15832         }
15833     }
15834
15835   if (!vec_len (file))
15836     {
15837       errmsg ("RSA key file must be specified");
15838       return -99;
15839     }
15840
15841   if (vec_len (file) > 256)
15842     {
15843       errmsg ("file name too long");
15844       return -99;
15845     }
15846
15847   M (IKEV2_SET_LOCAL_KEY, mp);
15848
15849   clib_memcpy (mp->key_file, file, vec_len (file));
15850   vec_free (file);
15851
15852   S (mp);
15853   W (ret);
15854   return ret;
15855 }
15856
15857 static int
15858 api_ikev2_set_responder (vat_main_t * vam)
15859 {
15860   unformat_input_t *i = vam->input;
15861   vl_api_ikev2_set_responder_t *mp;
15862   int ret;
15863   u8 *name = 0;
15864   u32 sw_if_index = ~0;
15865   ip4_address_t address;
15866
15867   const char *valid_chars = "a-zA-Z0-9_";
15868
15869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15870     {
15871       if (unformat
15872           (i, "%U interface %d address %U", unformat_token, valid_chars,
15873            &name, &sw_if_index, unformat_ip4_address, &address))
15874         vec_add1 (name, 0);
15875       else
15876         {
15877           errmsg ("parse error '%U'", format_unformat_error, i);
15878           return -99;
15879         }
15880     }
15881
15882   if (!vec_len (name))
15883     {
15884       errmsg ("profile name must be specified");
15885       return -99;
15886     }
15887
15888   if (vec_len (name) > 64)
15889     {
15890       errmsg ("profile name too long");
15891       return -99;
15892     }
15893
15894   M (IKEV2_SET_RESPONDER, mp);
15895
15896   clib_memcpy (mp->name, name, vec_len (name));
15897   vec_free (name);
15898
15899   mp->sw_if_index = sw_if_index;
15900   clib_memcpy (mp->address, &address, sizeof (address));
15901
15902   S (mp);
15903   W (ret);
15904   return ret;
15905 }
15906
15907 static int
15908 api_ikev2_set_ike_transforms (vat_main_t * vam)
15909 {
15910   unformat_input_t *i = vam->input;
15911   vl_api_ikev2_set_ike_transforms_t *mp;
15912   int ret;
15913   u8 *name = 0;
15914   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15915
15916   const char *valid_chars = "a-zA-Z0-9_";
15917
15918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15919     {
15920       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15921                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15922         vec_add1 (name, 0);
15923       else
15924         {
15925           errmsg ("parse error '%U'", format_unformat_error, i);
15926           return -99;
15927         }
15928     }
15929
15930   if (!vec_len (name))
15931     {
15932       errmsg ("profile name must be specified");
15933       return -99;
15934     }
15935
15936   if (vec_len (name) > 64)
15937     {
15938       errmsg ("profile name too long");
15939       return -99;
15940     }
15941
15942   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15943
15944   clib_memcpy (mp->name, name, vec_len (name));
15945   vec_free (name);
15946   mp->crypto_alg = crypto_alg;
15947   mp->crypto_key_size = crypto_key_size;
15948   mp->integ_alg = integ_alg;
15949   mp->dh_group = dh_group;
15950
15951   S (mp);
15952   W (ret);
15953   return ret;
15954 }
15955
15956
15957 static int
15958 api_ikev2_set_esp_transforms (vat_main_t * vam)
15959 {
15960   unformat_input_t *i = vam->input;
15961   vl_api_ikev2_set_esp_transforms_t *mp;
15962   int ret;
15963   u8 *name = 0;
15964   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15965
15966   const char *valid_chars = "a-zA-Z0-9_";
15967
15968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15969     {
15970       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15971                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15972         vec_add1 (name, 0);
15973       else
15974         {
15975           errmsg ("parse error '%U'", format_unformat_error, i);
15976           return -99;
15977         }
15978     }
15979
15980   if (!vec_len (name))
15981     {
15982       errmsg ("profile name must be specified");
15983       return -99;
15984     }
15985
15986   if (vec_len (name) > 64)
15987     {
15988       errmsg ("profile name too long");
15989       return -99;
15990     }
15991
15992   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15993
15994   clib_memcpy (mp->name, name, vec_len (name));
15995   vec_free (name);
15996   mp->crypto_alg = crypto_alg;
15997   mp->crypto_key_size = crypto_key_size;
15998   mp->integ_alg = integ_alg;
15999   mp->dh_group = dh_group;
16000
16001   S (mp);
16002   W (ret);
16003   return ret;
16004 }
16005
16006 static int
16007 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16008 {
16009   unformat_input_t *i = vam->input;
16010   vl_api_ikev2_set_sa_lifetime_t *mp;
16011   int ret;
16012   u8 *name = 0;
16013   u64 lifetime, lifetime_maxdata;
16014   u32 lifetime_jitter, handover;
16015
16016   const char *valid_chars = "a-zA-Z0-9_";
16017
16018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16019     {
16020       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16021                     &lifetime, &lifetime_jitter, &handover,
16022                     &lifetime_maxdata))
16023         vec_add1 (name, 0);
16024       else
16025         {
16026           errmsg ("parse error '%U'", format_unformat_error, i);
16027           return -99;
16028         }
16029     }
16030
16031   if (!vec_len (name))
16032     {
16033       errmsg ("profile name must be specified");
16034       return -99;
16035     }
16036
16037   if (vec_len (name) > 64)
16038     {
16039       errmsg ("profile name too long");
16040       return -99;
16041     }
16042
16043   M (IKEV2_SET_SA_LIFETIME, mp);
16044
16045   clib_memcpy (mp->name, name, vec_len (name));
16046   vec_free (name);
16047   mp->lifetime = lifetime;
16048   mp->lifetime_jitter = lifetime_jitter;
16049   mp->handover = handover;
16050   mp->lifetime_maxdata = lifetime_maxdata;
16051
16052   S (mp);
16053   W (ret);
16054   return ret;
16055 }
16056
16057 static int
16058 api_ikev2_initiate_sa_init (vat_main_t * vam)
16059 {
16060   unformat_input_t *i = vam->input;
16061   vl_api_ikev2_initiate_sa_init_t *mp;
16062   int ret;
16063   u8 *name = 0;
16064
16065   const char *valid_chars = "a-zA-Z0-9_";
16066
16067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16068     {
16069       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16070         vec_add1 (name, 0);
16071       else
16072         {
16073           errmsg ("parse error '%U'", format_unformat_error, i);
16074           return -99;
16075         }
16076     }
16077
16078   if (!vec_len (name))
16079     {
16080       errmsg ("profile name must be specified");
16081       return -99;
16082     }
16083
16084   if (vec_len (name) > 64)
16085     {
16086       errmsg ("profile name too long");
16087       return -99;
16088     }
16089
16090   M (IKEV2_INITIATE_SA_INIT, mp);
16091
16092   clib_memcpy (mp->name, name, vec_len (name));
16093   vec_free (name);
16094
16095   S (mp);
16096   W (ret);
16097   return ret;
16098 }
16099
16100 static int
16101 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16102 {
16103   unformat_input_t *i = vam->input;
16104   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16105   int ret;
16106   u64 ispi;
16107
16108
16109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16110     {
16111       if (unformat (i, "%lx", &ispi))
16112         ;
16113       else
16114         {
16115           errmsg ("parse error '%U'", format_unformat_error, i);
16116           return -99;
16117         }
16118     }
16119
16120   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16121
16122   mp->ispi = ispi;
16123
16124   S (mp);
16125   W (ret);
16126   return ret;
16127 }
16128
16129 static int
16130 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16131 {
16132   unformat_input_t *i = vam->input;
16133   vl_api_ikev2_initiate_del_child_sa_t *mp;
16134   int ret;
16135   u32 ispi;
16136
16137
16138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16139     {
16140       if (unformat (i, "%x", &ispi))
16141         ;
16142       else
16143         {
16144           errmsg ("parse error '%U'", format_unformat_error, i);
16145           return -99;
16146         }
16147     }
16148
16149   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16150
16151   mp->ispi = ispi;
16152
16153   S (mp);
16154   W (ret);
16155   return ret;
16156 }
16157
16158 static int
16159 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16160 {
16161   unformat_input_t *i = vam->input;
16162   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16163   int ret;
16164   u32 ispi;
16165
16166
16167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16168     {
16169       if (unformat (i, "%x", &ispi))
16170         ;
16171       else
16172         {
16173           errmsg ("parse error '%U'", format_unformat_error, i);
16174           return -99;
16175         }
16176     }
16177
16178   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16179
16180   mp->ispi = ispi;
16181
16182   S (mp);
16183   W (ret);
16184   return ret;
16185 }
16186
16187 /*
16188  * MAP
16189  */
16190 static int
16191 api_map_add_domain (vat_main_t * vam)
16192 {
16193   unformat_input_t *i = vam->input;
16194   vl_api_map_add_domain_t *mp;
16195
16196   ip4_address_t ip4_prefix;
16197   ip6_address_t ip6_prefix;
16198   ip6_address_t ip6_src;
16199   u32 num_m_args = 0;
16200   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16201     0, psid_length = 0;
16202   u8 is_translation = 0;
16203   u32 mtu = 0;
16204   u32 ip6_src_len = 128;
16205   int ret;
16206
16207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16208     {
16209       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16210                     &ip4_prefix, &ip4_prefix_len))
16211         num_m_args++;
16212       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16213                          &ip6_prefix, &ip6_prefix_len))
16214         num_m_args++;
16215       else
16216         if (unformat
16217             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16218              &ip6_src_len))
16219         num_m_args++;
16220       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16221         num_m_args++;
16222       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16223         num_m_args++;
16224       else if (unformat (i, "psid-offset %d", &psid_offset))
16225         num_m_args++;
16226       else if (unformat (i, "psid-len %d", &psid_length))
16227         num_m_args++;
16228       else if (unformat (i, "mtu %d", &mtu))
16229         num_m_args++;
16230       else if (unformat (i, "map-t"))
16231         is_translation = 1;
16232       else
16233         {
16234           clib_warning ("parse error '%U'", format_unformat_error, i);
16235           return -99;
16236         }
16237     }
16238
16239   if (num_m_args < 3)
16240     {
16241       errmsg ("mandatory argument(s) missing");
16242       return -99;
16243     }
16244
16245   /* Construct the API message */
16246   M (MAP_ADD_DOMAIN, mp);
16247
16248   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16249   mp->ip4_prefix_len = ip4_prefix_len;
16250
16251   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16252   mp->ip6_prefix_len = ip6_prefix_len;
16253
16254   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16255   mp->ip6_src_prefix_len = ip6_src_len;
16256
16257   mp->ea_bits_len = ea_bits_len;
16258   mp->psid_offset = psid_offset;
16259   mp->psid_length = psid_length;
16260   mp->is_translation = is_translation;
16261   mp->mtu = htons (mtu);
16262
16263   /* send it... */
16264   S (mp);
16265
16266   /* Wait for a reply, return good/bad news  */
16267   W (ret);
16268   return ret;
16269 }
16270
16271 static int
16272 api_map_del_domain (vat_main_t * vam)
16273 {
16274   unformat_input_t *i = vam->input;
16275   vl_api_map_del_domain_t *mp;
16276
16277   u32 num_m_args = 0;
16278   u32 index;
16279   int ret;
16280
16281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16282     {
16283       if (unformat (i, "index %d", &index))
16284         num_m_args++;
16285       else
16286         {
16287           clib_warning ("parse error '%U'", format_unformat_error, i);
16288           return -99;
16289         }
16290     }
16291
16292   if (num_m_args != 1)
16293     {
16294       errmsg ("mandatory argument(s) missing");
16295       return -99;
16296     }
16297
16298   /* Construct the API message */
16299   M (MAP_DEL_DOMAIN, mp);
16300
16301   mp->index = ntohl (index);
16302
16303   /* send it... */
16304   S (mp);
16305
16306   /* Wait for a reply, return good/bad news  */
16307   W (ret);
16308   return ret;
16309 }
16310
16311 static int
16312 api_map_add_del_rule (vat_main_t * vam)
16313 {
16314   unformat_input_t *i = vam->input;
16315   vl_api_map_add_del_rule_t *mp;
16316   u8 is_add = 1;
16317   ip6_address_t ip6_dst;
16318   u32 num_m_args = 0, index, psid = 0;
16319   int ret;
16320
16321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16322     {
16323       if (unformat (i, "index %d", &index))
16324         num_m_args++;
16325       else if (unformat (i, "psid %d", &psid))
16326         num_m_args++;
16327       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16328         num_m_args++;
16329       else if (unformat (i, "del"))
16330         {
16331           is_add = 0;
16332         }
16333       else
16334         {
16335           clib_warning ("parse error '%U'", format_unformat_error, i);
16336           return -99;
16337         }
16338     }
16339
16340   /* Construct the API message */
16341   M (MAP_ADD_DEL_RULE, mp);
16342
16343   mp->index = ntohl (index);
16344   mp->is_add = is_add;
16345   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16346   mp->psid = ntohs (psid);
16347
16348   /* send it... */
16349   S (mp);
16350
16351   /* Wait for a reply, return good/bad news  */
16352   W (ret);
16353   return ret;
16354 }
16355
16356 static int
16357 api_map_domain_dump (vat_main_t * vam)
16358 {
16359   vl_api_map_domain_dump_t *mp;
16360   vl_api_control_ping_t *mp_ping;
16361   int ret;
16362
16363   /* Construct the API message */
16364   M (MAP_DOMAIN_DUMP, mp);
16365
16366   /* send it... */
16367   S (mp);
16368
16369   /* Use a control ping for synchronization */
16370   MPING (CONTROL_PING, mp_ping);
16371   S (mp_ping);
16372
16373   W (ret);
16374   return ret;
16375 }
16376
16377 static int
16378 api_map_rule_dump (vat_main_t * vam)
16379 {
16380   unformat_input_t *i = vam->input;
16381   vl_api_map_rule_dump_t *mp;
16382   vl_api_control_ping_t *mp_ping;
16383   u32 domain_index = ~0;
16384   int ret;
16385
16386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16387     {
16388       if (unformat (i, "index %u", &domain_index))
16389         ;
16390       else
16391         break;
16392     }
16393
16394   if (domain_index == ~0)
16395     {
16396       clib_warning ("parse error: domain index expected");
16397       return -99;
16398     }
16399
16400   /* Construct the API message */
16401   M (MAP_RULE_DUMP, mp);
16402
16403   mp->domain_index = htonl (domain_index);
16404
16405   /* send it... */
16406   S (mp);
16407
16408   /* Use a control ping for synchronization */
16409   MPING (CONTROL_PING, mp_ping);
16410   S (mp_ping);
16411
16412   W (ret);
16413   return ret;
16414 }
16415
16416 static void vl_api_map_add_domain_reply_t_handler
16417   (vl_api_map_add_domain_reply_t * mp)
16418 {
16419   vat_main_t *vam = &vat_main;
16420   i32 retval = ntohl (mp->retval);
16421
16422   if (vam->async_mode)
16423     {
16424       vam->async_errors += (retval < 0);
16425     }
16426   else
16427     {
16428       vam->retval = retval;
16429       vam->result_ready = 1;
16430     }
16431 }
16432
16433 static void vl_api_map_add_domain_reply_t_handler_json
16434   (vl_api_map_add_domain_reply_t * mp)
16435 {
16436   vat_main_t *vam = &vat_main;
16437   vat_json_node_t node;
16438
16439   vat_json_init_object (&node);
16440   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16441   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16442
16443   vat_json_print (vam->ofp, &node);
16444   vat_json_free (&node);
16445
16446   vam->retval = ntohl (mp->retval);
16447   vam->result_ready = 1;
16448 }
16449
16450 static int
16451 api_get_first_msg_id (vat_main_t * vam)
16452 {
16453   vl_api_get_first_msg_id_t *mp;
16454   unformat_input_t *i = vam->input;
16455   u8 *name;
16456   u8 name_set = 0;
16457   int ret;
16458
16459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16460     {
16461       if (unformat (i, "client %s", &name))
16462         name_set = 1;
16463       else
16464         break;
16465     }
16466
16467   if (name_set == 0)
16468     {
16469       errmsg ("missing client name");
16470       return -99;
16471     }
16472   vec_add1 (name, 0);
16473
16474   if (vec_len (name) > 63)
16475     {
16476       errmsg ("client name too long");
16477       return -99;
16478     }
16479
16480   M (GET_FIRST_MSG_ID, mp);
16481   clib_memcpy (mp->name, name, vec_len (name));
16482   S (mp);
16483   W (ret);
16484   return ret;
16485 }
16486
16487 static int
16488 api_cop_interface_enable_disable (vat_main_t * vam)
16489 {
16490   unformat_input_t *line_input = vam->input;
16491   vl_api_cop_interface_enable_disable_t *mp;
16492   u32 sw_if_index = ~0;
16493   u8 enable_disable = 1;
16494   int ret;
16495
16496   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16497     {
16498       if (unformat (line_input, "disable"))
16499         enable_disable = 0;
16500       if (unformat (line_input, "enable"))
16501         enable_disable = 1;
16502       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16503                          vam, &sw_if_index))
16504         ;
16505       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16506         ;
16507       else
16508         break;
16509     }
16510
16511   if (sw_if_index == ~0)
16512     {
16513       errmsg ("missing interface name or sw_if_index");
16514       return -99;
16515     }
16516
16517   /* Construct the API message */
16518   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16519   mp->sw_if_index = ntohl (sw_if_index);
16520   mp->enable_disable = enable_disable;
16521
16522   /* send it... */
16523   S (mp);
16524   /* Wait for the reply */
16525   W (ret);
16526   return ret;
16527 }
16528
16529 static int
16530 api_cop_whitelist_enable_disable (vat_main_t * vam)
16531 {
16532   unformat_input_t *line_input = vam->input;
16533   vl_api_cop_whitelist_enable_disable_t *mp;
16534   u32 sw_if_index = ~0;
16535   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16536   u32 fib_id = 0;
16537   int ret;
16538
16539   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16540     {
16541       if (unformat (line_input, "ip4"))
16542         ip4 = 1;
16543       else if (unformat (line_input, "ip6"))
16544         ip6 = 1;
16545       else if (unformat (line_input, "default"))
16546         default_cop = 1;
16547       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16548                          vam, &sw_if_index))
16549         ;
16550       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16551         ;
16552       else if (unformat (line_input, "fib-id %d", &fib_id))
16553         ;
16554       else
16555         break;
16556     }
16557
16558   if (sw_if_index == ~0)
16559     {
16560       errmsg ("missing interface name or sw_if_index");
16561       return -99;
16562     }
16563
16564   /* Construct the API message */
16565   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16566   mp->sw_if_index = ntohl (sw_if_index);
16567   mp->fib_id = ntohl (fib_id);
16568   mp->ip4 = ip4;
16569   mp->ip6 = ip6;
16570   mp->default_cop = default_cop;
16571
16572   /* send it... */
16573   S (mp);
16574   /* Wait for the reply */
16575   W (ret);
16576   return ret;
16577 }
16578
16579 static int
16580 api_get_node_graph (vat_main_t * vam)
16581 {
16582   vl_api_get_node_graph_t *mp;
16583   int ret;
16584
16585   M (GET_NODE_GRAPH, mp);
16586
16587   /* send it... */
16588   S (mp);
16589   /* Wait for the reply */
16590   W (ret);
16591   return ret;
16592 }
16593
16594 /* *INDENT-OFF* */
16595 /** Used for parsing LISP eids */
16596 typedef CLIB_PACKED(struct{
16597   u8 addr[16];   /**< eid address */
16598   u32 len;       /**< prefix length if IP */
16599   u8 type;      /**< type of eid */
16600 }) lisp_eid_vat_t;
16601 /* *INDENT-ON* */
16602
16603 static uword
16604 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16605 {
16606   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16607
16608   memset (a, 0, sizeof (a[0]));
16609
16610   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16611     {
16612       a->type = 0;              /* ipv4 type */
16613     }
16614   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16615     {
16616       a->type = 1;              /* ipv6 type */
16617     }
16618   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16619     {
16620       a->type = 2;              /* mac type */
16621     }
16622   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16623     {
16624       a->type = 3;              /* NSH type */
16625       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16626       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16627     }
16628   else
16629     {
16630       return 0;
16631     }
16632
16633   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16634     {
16635       return 0;
16636     }
16637
16638   return 1;
16639 }
16640
16641 static int
16642 lisp_eid_size_vat (u8 type)
16643 {
16644   switch (type)
16645     {
16646     case 0:
16647       return 4;
16648     case 1:
16649       return 16;
16650     case 2:
16651       return 6;
16652     case 3:
16653       return 5;
16654     }
16655   return 0;
16656 }
16657
16658 static void
16659 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16660 {
16661   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16662 }
16663
16664 static int
16665 api_one_add_del_locator_set (vat_main_t * vam)
16666 {
16667   unformat_input_t *input = vam->input;
16668   vl_api_one_add_del_locator_set_t *mp;
16669   u8 is_add = 1;
16670   u8 *locator_set_name = NULL;
16671   u8 locator_set_name_set = 0;
16672   vl_api_local_locator_t locator, *locators = 0;
16673   u32 sw_if_index, priority, weight;
16674   u32 data_len = 0;
16675
16676   int ret;
16677   /* Parse args required to build the message */
16678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16679     {
16680       if (unformat (input, "del"))
16681         {
16682           is_add = 0;
16683         }
16684       else if (unformat (input, "locator-set %s", &locator_set_name))
16685         {
16686           locator_set_name_set = 1;
16687         }
16688       else if (unformat (input, "sw_if_index %u p %u w %u",
16689                          &sw_if_index, &priority, &weight))
16690         {
16691           locator.sw_if_index = htonl (sw_if_index);
16692           locator.priority = priority;
16693           locator.weight = weight;
16694           vec_add1 (locators, locator);
16695         }
16696       else
16697         if (unformat
16698             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16699              &sw_if_index, &priority, &weight))
16700         {
16701           locator.sw_if_index = htonl (sw_if_index);
16702           locator.priority = priority;
16703           locator.weight = weight;
16704           vec_add1 (locators, locator);
16705         }
16706       else
16707         break;
16708     }
16709
16710   if (locator_set_name_set == 0)
16711     {
16712       errmsg ("missing locator-set name");
16713       vec_free (locators);
16714       return -99;
16715     }
16716
16717   if (vec_len (locator_set_name) > 64)
16718     {
16719       errmsg ("locator-set name too long");
16720       vec_free (locator_set_name);
16721       vec_free (locators);
16722       return -99;
16723     }
16724   vec_add1 (locator_set_name, 0);
16725
16726   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16727
16728   /* Construct the API message */
16729   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16730
16731   mp->is_add = is_add;
16732   clib_memcpy (mp->locator_set_name, locator_set_name,
16733                vec_len (locator_set_name));
16734   vec_free (locator_set_name);
16735
16736   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16737   if (locators)
16738     clib_memcpy (mp->locators, locators, data_len);
16739   vec_free (locators);
16740
16741   /* send it... */
16742   S (mp);
16743
16744   /* Wait for a reply... */
16745   W (ret);
16746   return ret;
16747 }
16748
16749 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16750
16751 static int
16752 api_one_add_del_locator (vat_main_t * vam)
16753 {
16754   unformat_input_t *input = vam->input;
16755   vl_api_one_add_del_locator_t *mp;
16756   u32 tmp_if_index = ~0;
16757   u32 sw_if_index = ~0;
16758   u8 sw_if_index_set = 0;
16759   u8 sw_if_index_if_name_set = 0;
16760   u32 priority = ~0;
16761   u8 priority_set = 0;
16762   u32 weight = ~0;
16763   u8 weight_set = 0;
16764   u8 is_add = 1;
16765   u8 *locator_set_name = NULL;
16766   u8 locator_set_name_set = 0;
16767   int ret;
16768
16769   /* Parse args required to build the message */
16770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16771     {
16772       if (unformat (input, "del"))
16773         {
16774           is_add = 0;
16775         }
16776       else if (unformat (input, "locator-set %s", &locator_set_name))
16777         {
16778           locator_set_name_set = 1;
16779         }
16780       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16781                          &tmp_if_index))
16782         {
16783           sw_if_index_if_name_set = 1;
16784           sw_if_index = tmp_if_index;
16785         }
16786       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16787         {
16788           sw_if_index_set = 1;
16789           sw_if_index = tmp_if_index;
16790         }
16791       else if (unformat (input, "p %d", &priority))
16792         {
16793           priority_set = 1;
16794         }
16795       else if (unformat (input, "w %d", &weight))
16796         {
16797           weight_set = 1;
16798         }
16799       else
16800         break;
16801     }
16802
16803   if (locator_set_name_set == 0)
16804     {
16805       errmsg ("missing locator-set name");
16806       return -99;
16807     }
16808
16809   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16810     {
16811       errmsg ("missing sw_if_index");
16812       vec_free (locator_set_name);
16813       return -99;
16814     }
16815
16816   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16817     {
16818       errmsg ("cannot use both params interface name and sw_if_index");
16819       vec_free (locator_set_name);
16820       return -99;
16821     }
16822
16823   if (priority_set == 0)
16824     {
16825       errmsg ("missing locator-set priority");
16826       vec_free (locator_set_name);
16827       return -99;
16828     }
16829
16830   if (weight_set == 0)
16831     {
16832       errmsg ("missing locator-set weight");
16833       vec_free (locator_set_name);
16834       return -99;
16835     }
16836
16837   if (vec_len (locator_set_name) > 64)
16838     {
16839       errmsg ("locator-set name too long");
16840       vec_free (locator_set_name);
16841       return -99;
16842     }
16843   vec_add1 (locator_set_name, 0);
16844
16845   /* Construct the API message */
16846   M (ONE_ADD_DEL_LOCATOR, mp);
16847
16848   mp->is_add = is_add;
16849   mp->sw_if_index = ntohl (sw_if_index);
16850   mp->priority = priority;
16851   mp->weight = weight;
16852   clib_memcpy (mp->locator_set_name, locator_set_name,
16853                vec_len (locator_set_name));
16854   vec_free (locator_set_name);
16855
16856   /* send it... */
16857   S (mp);
16858
16859   /* Wait for a reply... */
16860   W (ret);
16861   return ret;
16862 }
16863
16864 #define api_lisp_add_del_locator api_one_add_del_locator
16865
16866 uword
16867 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16868 {
16869   u32 *key_id = va_arg (*args, u32 *);
16870   u8 *s = 0;
16871
16872   if (unformat (input, "%s", &s))
16873     {
16874       if (!strcmp ((char *) s, "sha1"))
16875         key_id[0] = HMAC_SHA_1_96;
16876       else if (!strcmp ((char *) s, "sha256"))
16877         key_id[0] = HMAC_SHA_256_128;
16878       else
16879         {
16880           clib_warning ("invalid key_id: '%s'", s);
16881           key_id[0] = HMAC_NO_KEY;
16882         }
16883     }
16884   else
16885     return 0;
16886
16887   vec_free (s);
16888   return 1;
16889 }
16890
16891 static int
16892 api_one_add_del_local_eid (vat_main_t * vam)
16893 {
16894   unformat_input_t *input = vam->input;
16895   vl_api_one_add_del_local_eid_t *mp;
16896   u8 is_add = 1;
16897   u8 eid_set = 0;
16898   lisp_eid_vat_t _eid, *eid = &_eid;
16899   u8 *locator_set_name = 0;
16900   u8 locator_set_name_set = 0;
16901   u32 vni = 0;
16902   u16 key_id = 0;
16903   u8 *key = 0;
16904   int ret;
16905
16906   /* Parse args required to build the message */
16907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16908     {
16909       if (unformat (input, "del"))
16910         {
16911           is_add = 0;
16912         }
16913       else if (unformat (input, "vni %d", &vni))
16914         {
16915           ;
16916         }
16917       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16918         {
16919           eid_set = 1;
16920         }
16921       else if (unformat (input, "locator-set %s", &locator_set_name))
16922         {
16923           locator_set_name_set = 1;
16924         }
16925       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16926         ;
16927       else if (unformat (input, "secret-key %_%v%_", &key))
16928         ;
16929       else
16930         break;
16931     }
16932
16933   if (locator_set_name_set == 0)
16934     {
16935       errmsg ("missing locator-set name");
16936       return -99;
16937     }
16938
16939   if (0 == eid_set)
16940     {
16941       errmsg ("EID address not set!");
16942       vec_free (locator_set_name);
16943       return -99;
16944     }
16945
16946   if (key && (0 == key_id))
16947     {
16948       errmsg ("invalid key_id!");
16949       return -99;
16950     }
16951
16952   if (vec_len (key) > 64)
16953     {
16954       errmsg ("key too long");
16955       vec_free (key);
16956       return -99;
16957     }
16958
16959   if (vec_len (locator_set_name) > 64)
16960     {
16961       errmsg ("locator-set name too long");
16962       vec_free (locator_set_name);
16963       return -99;
16964     }
16965   vec_add1 (locator_set_name, 0);
16966
16967   /* Construct the API message */
16968   M (ONE_ADD_DEL_LOCAL_EID, mp);
16969
16970   mp->is_add = is_add;
16971   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16972   mp->eid_type = eid->type;
16973   mp->prefix_len = eid->len;
16974   mp->vni = clib_host_to_net_u32 (vni);
16975   mp->key_id = clib_host_to_net_u16 (key_id);
16976   clib_memcpy (mp->locator_set_name, locator_set_name,
16977                vec_len (locator_set_name));
16978   clib_memcpy (mp->key, key, vec_len (key));
16979
16980   vec_free (locator_set_name);
16981   vec_free (key);
16982
16983   /* send it... */
16984   S (mp);
16985
16986   /* Wait for a reply... */
16987   W (ret);
16988   return ret;
16989 }
16990
16991 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16992
16993 static int
16994 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16995 {
16996   u32 dp_table = 0, vni = 0;;
16997   unformat_input_t *input = vam->input;
16998   vl_api_gpe_add_del_fwd_entry_t *mp;
16999   u8 is_add = 1;
17000   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17001   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17002   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17003   u32 action = ~0, w;
17004   ip4_address_t rmt_rloc4, lcl_rloc4;
17005   ip6_address_t rmt_rloc6, lcl_rloc6;
17006   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17007   int ret;
17008
17009   memset (&rloc, 0, sizeof (rloc));
17010
17011   /* Parse args required to build the message */
17012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17013     {
17014       if (unformat (input, "del"))
17015         is_add = 0;
17016       else if (unformat (input, "add"))
17017         is_add = 1;
17018       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17019         {
17020           rmt_eid_set = 1;
17021         }
17022       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17023         {
17024           lcl_eid_set = 1;
17025         }
17026       else if (unformat (input, "vrf %d", &dp_table))
17027         ;
17028       else if (unformat (input, "bd %d", &dp_table))
17029         ;
17030       else if (unformat (input, "vni %d", &vni))
17031         ;
17032       else if (unformat (input, "w %d", &w))
17033         {
17034           if (!curr_rloc)
17035             {
17036               errmsg ("No RLOC configured for setting priority/weight!");
17037               return -99;
17038             }
17039           curr_rloc->weight = w;
17040         }
17041       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17042                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17043         {
17044           rloc.is_ip4 = 1;
17045
17046           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17047           rloc.weight = 0;
17048           vec_add1 (lcl_locs, rloc);
17049
17050           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17051           vec_add1 (rmt_locs, rloc);
17052           /* weight saved in rmt loc */
17053           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17054         }
17055       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17056                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17057         {
17058           rloc.is_ip4 = 0;
17059           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17060           rloc.weight = 0;
17061           vec_add1 (lcl_locs, rloc);
17062
17063           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17064           vec_add1 (rmt_locs, rloc);
17065           /* weight saved in rmt loc */
17066           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17067         }
17068       else if (unformat (input, "action %d", &action))
17069         {
17070           ;
17071         }
17072       else
17073         {
17074           clib_warning ("parse error '%U'", format_unformat_error, input);
17075           return -99;
17076         }
17077     }
17078
17079   if (!rmt_eid_set)
17080     {
17081       errmsg ("remote eid addresses not set");
17082       return -99;
17083     }
17084
17085   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17086     {
17087       errmsg ("eid types don't match");
17088       return -99;
17089     }
17090
17091   if (0 == rmt_locs && (u32) ~ 0 == action)
17092     {
17093       errmsg ("action not set for negative mapping");
17094       return -99;
17095     }
17096
17097   /* Construct the API message */
17098   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17099       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17100
17101   mp->is_add = is_add;
17102   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17103   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17104   mp->eid_type = rmt_eid->type;
17105   mp->dp_table = clib_host_to_net_u32 (dp_table);
17106   mp->vni = clib_host_to_net_u32 (vni);
17107   mp->rmt_len = rmt_eid->len;
17108   mp->lcl_len = lcl_eid->len;
17109   mp->action = action;
17110
17111   if (0 != rmt_locs && 0 != lcl_locs)
17112     {
17113       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17114       clib_memcpy (mp->locs, lcl_locs,
17115                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17116
17117       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17118       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17119                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17120     }
17121   vec_free (lcl_locs);
17122   vec_free (rmt_locs);
17123
17124   /* send it... */
17125   S (mp);
17126
17127   /* Wait for a reply... */
17128   W (ret);
17129   return ret;
17130 }
17131
17132 static int
17133 api_one_add_del_map_server (vat_main_t * vam)
17134 {
17135   unformat_input_t *input = vam->input;
17136   vl_api_one_add_del_map_server_t *mp;
17137   u8 is_add = 1;
17138   u8 ipv4_set = 0;
17139   u8 ipv6_set = 0;
17140   ip4_address_t ipv4;
17141   ip6_address_t ipv6;
17142   int ret;
17143
17144   /* Parse args required to build the message */
17145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17146     {
17147       if (unformat (input, "del"))
17148         {
17149           is_add = 0;
17150         }
17151       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17152         {
17153           ipv4_set = 1;
17154         }
17155       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17156         {
17157           ipv6_set = 1;
17158         }
17159       else
17160         break;
17161     }
17162
17163   if (ipv4_set && ipv6_set)
17164     {
17165       errmsg ("both eid v4 and v6 addresses set");
17166       return -99;
17167     }
17168
17169   if (!ipv4_set && !ipv6_set)
17170     {
17171       errmsg ("eid addresses not set");
17172       return -99;
17173     }
17174
17175   /* Construct the API message */
17176   M (ONE_ADD_DEL_MAP_SERVER, mp);
17177
17178   mp->is_add = is_add;
17179   if (ipv6_set)
17180     {
17181       mp->is_ipv6 = 1;
17182       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17183     }
17184   else
17185     {
17186       mp->is_ipv6 = 0;
17187       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17188     }
17189
17190   /* send it... */
17191   S (mp);
17192
17193   /* Wait for a reply... */
17194   W (ret);
17195   return ret;
17196 }
17197
17198 #define api_lisp_add_del_map_server api_one_add_del_map_server
17199
17200 static int
17201 api_one_add_del_map_resolver (vat_main_t * vam)
17202 {
17203   unformat_input_t *input = vam->input;
17204   vl_api_one_add_del_map_resolver_t *mp;
17205   u8 is_add = 1;
17206   u8 ipv4_set = 0;
17207   u8 ipv6_set = 0;
17208   ip4_address_t ipv4;
17209   ip6_address_t ipv6;
17210   int ret;
17211
17212   /* Parse args required to build the message */
17213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17214     {
17215       if (unformat (input, "del"))
17216         {
17217           is_add = 0;
17218         }
17219       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17220         {
17221           ipv4_set = 1;
17222         }
17223       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17224         {
17225           ipv6_set = 1;
17226         }
17227       else
17228         break;
17229     }
17230
17231   if (ipv4_set && ipv6_set)
17232     {
17233       errmsg ("both eid v4 and v6 addresses set");
17234       return -99;
17235     }
17236
17237   if (!ipv4_set && !ipv6_set)
17238     {
17239       errmsg ("eid addresses not set");
17240       return -99;
17241     }
17242
17243   /* Construct the API message */
17244   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17245
17246   mp->is_add = is_add;
17247   if (ipv6_set)
17248     {
17249       mp->is_ipv6 = 1;
17250       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17251     }
17252   else
17253     {
17254       mp->is_ipv6 = 0;
17255       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17256     }
17257
17258   /* send it... */
17259   S (mp);
17260
17261   /* Wait for a reply... */
17262   W (ret);
17263   return ret;
17264 }
17265
17266 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17267
17268 static int
17269 api_lisp_gpe_enable_disable (vat_main_t * vam)
17270 {
17271   unformat_input_t *input = vam->input;
17272   vl_api_gpe_enable_disable_t *mp;
17273   u8 is_set = 0;
17274   u8 is_en = 1;
17275   int ret;
17276
17277   /* Parse args required to build the message */
17278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17279     {
17280       if (unformat (input, "enable"))
17281         {
17282           is_set = 1;
17283           is_en = 1;
17284         }
17285       else if (unformat (input, "disable"))
17286         {
17287           is_set = 1;
17288           is_en = 0;
17289         }
17290       else
17291         break;
17292     }
17293
17294   if (is_set == 0)
17295     {
17296       errmsg ("Value not set");
17297       return -99;
17298     }
17299
17300   /* Construct the API message */
17301   M (GPE_ENABLE_DISABLE, mp);
17302
17303   mp->is_en = is_en;
17304
17305   /* send it... */
17306   S (mp);
17307
17308   /* Wait for a reply... */
17309   W (ret);
17310   return ret;
17311 }
17312
17313 static int
17314 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17315 {
17316   unformat_input_t *input = vam->input;
17317   vl_api_one_rloc_probe_enable_disable_t *mp;
17318   u8 is_set = 0;
17319   u8 is_en = 0;
17320   int ret;
17321
17322   /* Parse args required to build the message */
17323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17324     {
17325       if (unformat (input, "enable"))
17326         {
17327           is_set = 1;
17328           is_en = 1;
17329         }
17330       else if (unformat (input, "disable"))
17331         is_set = 1;
17332       else
17333         break;
17334     }
17335
17336   if (!is_set)
17337     {
17338       errmsg ("Value not set");
17339       return -99;
17340     }
17341
17342   /* Construct the API message */
17343   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17344
17345   mp->is_enabled = is_en;
17346
17347   /* send it... */
17348   S (mp);
17349
17350   /* Wait for a reply... */
17351   W (ret);
17352   return ret;
17353 }
17354
17355 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17356
17357 static int
17358 api_one_map_register_enable_disable (vat_main_t * vam)
17359 {
17360   unformat_input_t *input = vam->input;
17361   vl_api_one_map_register_enable_disable_t *mp;
17362   u8 is_set = 0;
17363   u8 is_en = 0;
17364   int ret;
17365
17366   /* Parse args required to build the message */
17367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17368     {
17369       if (unformat (input, "enable"))
17370         {
17371           is_set = 1;
17372           is_en = 1;
17373         }
17374       else if (unformat (input, "disable"))
17375         is_set = 1;
17376       else
17377         break;
17378     }
17379
17380   if (!is_set)
17381     {
17382       errmsg ("Value not set");
17383       return -99;
17384     }
17385
17386   /* Construct the API message */
17387   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17388
17389   mp->is_enabled = is_en;
17390
17391   /* send it... */
17392   S (mp);
17393
17394   /* Wait for a reply... */
17395   W (ret);
17396   return ret;
17397 }
17398
17399 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17400
17401 static int
17402 api_one_enable_disable (vat_main_t * vam)
17403 {
17404   unformat_input_t *input = vam->input;
17405   vl_api_one_enable_disable_t *mp;
17406   u8 is_set = 0;
17407   u8 is_en = 0;
17408   int ret;
17409
17410   /* Parse args required to build the message */
17411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17412     {
17413       if (unformat (input, "enable"))
17414         {
17415           is_set = 1;
17416           is_en = 1;
17417         }
17418       else if (unformat (input, "disable"))
17419         {
17420           is_set = 1;
17421         }
17422       else
17423         break;
17424     }
17425
17426   if (!is_set)
17427     {
17428       errmsg ("Value not set");
17429       return -99;
17430     }
17431
17432   /* Construct the API message */
17433   M (ONE_ENABLE_DISABLE, mp);
17434
17435   mp->is_en = is_en;
17436
17437   /* send it... */
17438   S (mp);
17439
17440   /* Wait for a reply... */
17441   W (ret);
17442   return ret;
17443 }
17444
17445 #define api_lisp_enable_disable api_one_enable_disable
17446
17447 static int
17448 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17449 {
17450   unformat_input_t *input = vam->input;
17451   vl_api_one_enable_disable_xtr_mode_t *mp;
17452   u8 is_set = 0;
17453   u8 is_en = 0;
17454   int ret;
17455
17456   /* Parse args required to build the message */
17457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17458     {
17459       if (unformat (input, "enable"))
17460         {
17461           is_set = 1;
17462           is_en = 1;
17463         }
17464       else if (unformat (input, "disable"))
17465         {
17466           is_set = 1;
17467         }
17468       else
17469         break;
17470     }
17471
17472   if (!is_set)
17473     {
17474       errmsg ("Value not set");
17475       return -99;
17476     }
17477
17478   /* Construct the API message */
17479   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17480
17481   mp->is_en = is_en;
17482
17483   /* send it... */
17484   S (mp);
17485
17486   /* Wait for a reply... */
17487   W (ret);
17488   return ret;
17489 }
17490
17491 static int
17492 api_one_show_xtr_mode (vat_main_t * vam)
17493 {
17494   vl_api_one_show_xtr_mode_t *mp;
17495   int ret;
17496
17497   /* Construct the API message */
17498   M (ONE_SHOW_XTR_MODE, mp);
17499
17500   /* send it... */
17501   S (mp);
17502
17503   /* Wait for a reply... */
17504   W (ret);
17505   return ret;
17506 }
17507
17508 static int
17509 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17510 {
17511   unformat_input_t *input = vam->input;
17512   vl_api_one_enable_disable_pitr_mode_t *mp;
17513   u8 is_set = 0;
17514   u8 is_en = 0;
17515   int ret;
17516
17517   /* Parse args required to build the message */
17518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17519     {
17520       if (unformat (input, "enable"))
17521         {
17522           is_set = 1;
17523           is_en = 1;
17524         }
17525       else if (unformat (input, "disable"))
17526         {
17527           is_set = 1;
17528         }
17529       else
17530         break;
17531     }
17532
17533   if (!is_set)
17534     {
17535       errmsg ("Value not set");
17536       return -99;
17537     }
17538
17539   /* Construct the API message */
17540   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17541
17542   mp->is_en = is_en;
17543
17544   /* send it... */
17545   S (mp);
17546
17547   /* Wait for a reply... */
17548   W (ret);
17549   return ret;
17550 }
17551
17552 static int
17553 api_one_show_pitr_mode (vat_main_t * vam)
17554 {
17555   vl_api_one_show_pitr_mode_t *mp;
17556   int ret;
17557
17558   /* Construct the API message */
17559   M (ONE_SHOW_PITR_MODE, mp);
17560
17561   /* send it... */
17562   S (mp);
17563
17564   /* Wait for a reply... */
17565   W (ret);
17566   return ret;
17567 }
17568
17569 static int
17570 api_one_enable_disable_petr_mode (vat_main_t * vam)
17571 {
17572   unformat_input_t *input = vam->input;
17573   vl_api_one_enable_disable_petr_mode_t *mp;
17574   u8 is_set = 0;
17575   u8 is_en = 0;
17576   int ret;
17577
17578   /* Parse args required to build the message */
17579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17580     {
17581       if (unformat (input, "enable"))
17582         {
17583           is_set = 1;
17584           is_en = 1;
17585         }
17586       else if (unformat (input, "disable"))
17587         {
17588           is_set = 1;
17589         }
17590       else
17591         break;
17592     }
17593
17594   if (!is_set)
17595     {
17596       errmsg ("Value not set");
17597       return -99;
17598     }
17599
17600   /* Construct the API message */
17601   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17602
17603   mp->is_en = is_en;
17604
17605   /* send it... */
17606   S (mp);
17607
17608   /* Wait for a reply... */
17609   W (ret);
17610   return ret;
17611 }
17612
17613 static int
17614 api_one_show_petr_mode (vat_main_t * vam)
17615 {
17616   vl_api_one_show_petr_mode_t *mp;
17617   int ret;
17618
17619   /* Construct the API message */
17620   M (ONE_SHOW_PETR_MODE, mp);
17621
17622   /* send it... */
17623   S (mp);
17624
17625   /* Wait for a reply... */
17626   W (ret);
17627   return ret;
17628 }
17629
17630 static int
17631 api_show_one_map_register_state (vat_main_t * vam)
17632 {
17633   vl_api_show_one_map_register_state_t *mp;
17634   int ret;
17635
17636   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17637
17638   /* send */
17639   S (mp);
17640
17641   /* wait for reply */
17642   W (ret);
17643   return ret;
17644 }
17645
17646 #define api_show_lisp_map_register_state api_show_one_map_register_state
17647
17648 static int
17649 api_show_one_rloc_probe_state (vat_main_t * vam)
17650 {
17651   vl_api_show_one_rloc_probe_state_t *mp;
17652   int ret;
17653
17654   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17655
17656   /* send */
17657   S (mp);
17658
17659   /* wait for reply */
17660   W (ret);
17661   return ret;
17662 }
17663
17664 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17665
17666 static int
17667 api_one_add_del_ndp_entry (vat_main_t * vam)
17668 {
17669   vl_api_one_add_del_ndp_entry_t *mp;
17670   unformat_input_t *input = vam->input;
17671   u8 is_add = 1;
17672   u8 mac_set = 0;
17673   u8 bd_set = 0;
17674   u8 ip_set = 0;
17675   u8 mac[6] = { 0, };
17676   u8 ip6[16] = { 0, };
17677   u32 bd = ~0;
17678   int ret;
17679
17680   /* Parse args required to build the message */
17681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17682     {
17683       if (unformat (input, "del"))
17684         is_add = 0;
17685       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17686         mac_set = 1;
17687       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17688         ip_set = 1;
17689       else if (unformat (input, "bd %d", &bd))
17690         bd_set = 1;
17691       else
17692         {
17693           errmsg ("parse error '%U'", format_unformat_error, input);
17694           return -99;
17695         }
17696     }
17697
17698   if (!bd_set || !ip_set || (!mac_set && is_add))
17699     {
17700       errmsg ("Missing BD, IP or MAC!");
17701       return -99;
17702     }
17703
17704   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17705   mp->is_add = is_add;
17706   clib_memcpy (mp->mac, mac, 6);
17707   mp->bd = clib_host_to_net_u32 (bd);
17708   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17709
17710   /* send */
17711   S (mp);
17712
17713   /* wait for reply */
17714   W (ret);
17715   return ret;
17716 }
17717
17718 static int
17719 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17720 {
17721   vl_api_one_add_del_l2_arp_entry_t *mp;
17722   unformat_input_t *input = vam->input;
17723   u8 is_add = 1;
17724   u8 mac_set = 0;
17725   u8 bd_set = 0;
17726   u8 ip_set = 0;
17727   u8 mac[6] = { 0, };
17728   u32 ip4 = 0, bd = ~0;
17729   int ret;
17730
17731   /* Parse args required to build the message */
17732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17733     {
17734       if (unformat (input, "del"))
17735         is_add = 0;
17736       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17737         mac_set = 1;
17738       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17739         ip_set = 1;
17740       else if (unformat (input, "bd %d", &bd))
17741         bd_set = 1;
17742       else
17743         {
17744           errmsg ("parse error '%U'", format_unformat_error, input);
17745           return -99;
17746         }
17747     }
17748
17749   if (!bd_set || !ip_set || (!mac_set && is_add))
17750     {
17751       errmsg ("Missing BD, IP or MAC!");
17752       return -99;
17753     }
17754
17755   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17756   mp->is_add = is_add;
17757   clib_memcpy (mp->mac, mac, 6);
17758   mp->bd = clib_host_to_net_u32 (bd);
17759   mp->ip4 = ip4;
17760
17761   /* send */
17762   S (mp);
17763
17764   /* wait for reply */
17765   W (ret);
17766   return ret;
17767 }
17768
17769 static int
17770 api_one_ndp_bd_get (vat_main_t * vam)
17771 {
17772   vl_api_one_ndp_bd_get_t *mp;
17773   int ret;
17774
17775   M (ONE_NDP_BD_GET, mp);
17776
17777   /* send */
17778   S (mp);
17779
17780   /* wait for reply */
17781   W (ret);
17782   return ret;
17783 }
17784
17785 static int
17786 api_one_ndp_entries_get (vat_main_t * vam)
17787 {
17788   vl_api_one_ndp_entries_get_t *mp;
17789   unformat_input_t *input = vam->input;
17790   u8 bd_set = 0;
17791   u32 bd = ~0;
17792   int ret;
17793
17794   /* Parse args required to build the message */
17795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17796     {
17797       if (unformat (input, "bd %d", &bd))
17798         bd_set = 1;
17799       else
17800         {
17801           errmsg ("parse error '%U'", format_unformat_error, input);
17802           return -99;
17803         }
17804     }
17805
17806   if (!bd_set)
17807     {
17808       errmsg ("Expected bridge domain!");
17809       return -99;
17810     }
17811
17812   M (ONE_NDP_ENTRIES_GET, mp);
17813   mp->bd = clib_host_to_net_u32 (bd);
17814
17815   /* send */
17816   S (mp);
17817
17818   /* wait for reply */
17819   W (ret);
17820   return ret;
17821 }
17822
17823 static int
17824 api_one_l2_arp_bd_get (vat_main_t * vam)
17825 {
17826   vl_api_one_l2_arp_bd_get_t *mp;
17827   int ret;
17828
17829   M (ONE_L2_ARP_BD_GET, mp);
17830
17831   /* send */
17832   S (mp);
17833
17834   /* wait for reply */
17835   W (ret);
17836   return ret;
17837 }
17838
17839 static int
17840 api_one_l2_arp_entries_get (vat_main_t * vam)
17841 {
17842   vl_api_one_l2_arp_entries_get_t *mp;
17843   unformat_input_t *input = vam->input;
17844   u8 bd_set = 0;
17845   u32 bd = ~0;
17846   int ret;
17847
17848   /* Parse args required to build the message */
17849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17850     {
17851       if (unformat (input, "bd %d", &bd))
17852         bd_set = 1;
17853       else
17854         {
17855           errmsg ("parse error '%U'", format_unformat_error, input);
17856           return -99;
17857         }
17858     }
17859
17860   if (!bd_set)
17861     {
17862       errmsg ("Expected bridge domain!");
17863       return -99;
17864     }
17865
17866   M (ONE_L2_ARP_ENTRIES_GET, mp);
17867   mp->bd = clib_host_to_net_u32 (bd);
17868
17869   /* send */
17870   S (mp);
17871
17872   /* wait for reply */
17873   W (ret);
17874   return ret;
17875 }
17876
17877 static int
17878 api_one_stats_enable_disable (vat_main_t * vam)
17879 {
17880   vl_api_one_stats_enable_disable_t *mp;
17881   unformat_input_t *input = vam->input;
17882   u8 is_set = 0;
17883   u8 is_en = 0;
17884   int ret;
17885
17886   /* Parse args required to build the message */
17887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17888     {
17889       if (unformat (input, "enable"))
17890         {
17891           is_set = 1;
17892           is_en = 1;
17893         }
17894       else if (unformat (input, "disable"))
17895         {
17896           is_set = 1;
17897         }
17898       else
17899         break;
17900     }
17901
17902   if (!is_set)
17903     {
17904       errmsg ("Value not set");
17905       return -99;
17906     }
17907
17908   M (ONE_STATS_ENABLE_DISABLE, mp);
17909   mp->is_en = is_en;
17910
17911   /* send */
17912   S (mp);
17913
17914   /* wait for reply */
17915   W (ret);
17916   return ret;
17917 }
17918
17919 static int
17920 api_show_one_stats_enable_disable (vat_main_t * vam)
17921 {
17922   vl_api_show_one_stats_enable_disable_t *mp;
17923   int ret;
17924
17925   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17926
17927   /* send */
17928   S (mp);
17929
17930   /* wait for reply */
17931   W (ret);
17932   return ret;
17933 }
17934
17935 static int
17936 api_show_one_map_request_mode (vat_main_t * vam)
17937 {
17938   vl_api_show_one_map_request_mode_t *mp;
17939   int ret;
17940
17941   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17942
17943   /* send */
17944   S (mp);
17945
17946   /* wait for reply */
17947   W (ret);
17948   return ret;
17949 }
17950
17951 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17952
17953 static int
17954 api_one_map_request_mode (vat_main_t * vam)
17955 {
17956   unformat_input_t *input = vam->input;
17957   vl_api_one_map_request_mode_t *mp;
17958   u8 mode = 0;
17959   int ret;
17960
17961   /* Parse args required to build the message */
17962   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17963     {
17964       if (unformat (input, "dst-only"))
17965         mode = 0;
17966       else if (unformat (input, "src-dst"))
17967         mode = 1;
17968       else
17969         {
17970           errmsg ("parse error '%U'", format_unformat_error, input);
17971           return -99;
17972         }
17973     }
17974
17975   M (ONE_MAP_REQUEST_MODE, mp);
17976
17977   mp->mode = mode;
17978
17979   /* send */
17980   S (mp);
17981
17982   /* wait for reply */
17983   W (ret);
17984   return ret;
17985 }
17986
17987 #define api_lisp_map_request_mode api_one_map_request_mode
17988
17989 /**
17990  * Enable/disable ONE proxy ITR.
17991  *
17992  * @param vam vpp API test context
17993  * @return return code
17994  */
17995 static int
17996 api_one_pitr_set_locator_set (vat_main_t * vam)
17997 {
17998   u8 ls_name_set = 0;
17999   unformat_input_t *input = vam->input;
18000   vl_api_one_pitr_set_locator_set_t *mp;
18001   u8 is_add = 1;
18002   u8 *ls_name = 0;
18003   int ret;
18004
18005   /* Parse args required to build the message */
18006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18007     {
18008       if (unformat (input, "del"))
18009         is_add = 0;
18010       else if (unformat (input, "locator-set %s", &ls_name))
18011         ls_name_set = 1;
18012       else
18013         {
18014           errmsg ("parse error '%U'", format_unformat_error, input);
18015           return -99;
18016         }
18017     }
18018
18019   if (!ls_name_set)
18020     {
18021       errmsg ("locator-set name not set!");
18022       return -99;
18023     }
18024
18025   M (ONE_PITR_SET_LOCATOR_SET, mp);
18026
18027   mp->is_add = is_add;
18028   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18029   vec_free (ls_name);
18030
18031   /* send */
18032   S (mp);
18033
18034   /* wait for reply */
18035   W (ret);
18036   return ret;
18037 }
18038
18039 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18040
18041 static int
18042 api_one_nsh_set_locator_set (vat_main_t * vam)
18043 {
18044   u8 ls_name_set = 0;
18045   unformat_input_t *input = vam->input;
18046   vl_api_one_nsh_set_locator_set_t *mp;
18047   u8 is_add = 1;
18048   u8 *ls_name = 0;
18049   int ret;
18050
18051   /* Parse args required to build the message */
18052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18053     {
18054       if (unformat (input, "del"))
18055         is_add = 0;
18056       else if (unformat (input, "ls %s", &ls_name))
18057         ls_name_set = 1;
18058       else
18059         {
18060           errmsg ("parse error '%U'", format_unformat_error, input);
18061           return -99;
18062         }
18063     }
18064
18065   if (!ls_name_set && is_add)
18066     {
18067       errmsg ("locator-set name not set!");
18068       return -99;
18069     }
18070
18071   M (ONE_NSH_SET_LOCATOR_SET, mp);
18072
18073   mp->is_add = is_add;
18074   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18075   vec_free (ls_name);
18076
18077   /* send */
18078   S (mp);
18079
18080   /* wait for reply */
18081   W (ret);
18082   return ret;
18083 }
18084
18085 static int
18086 api_show_one_pitr (vat_main_t * vam)
18087 {
18088   vl_api_show_one_pitr_t *mp;
18089   int ret;
18090
18091   if (!vam->json_output)
18092     {
18093       print (vam->ofp, "%=20s", "lisp status:");
18094     }
18095
18096   M (SHOW_ONE_PITR, mp);
18097   /* send it... */
18098   S (mp);
18099
18100   /* Wait for a reply... */
18101   W (ret);
18102   return ret;
18103 }
18104
18105 #define api_show_lisp_pitr api_show_one_pitr
18106
18107 static int
18108 api_one_use_petr (vat_main_t * vam)
18109 {
18110   unformat_input_t *input = vam->input;
18111   vl_api_one_use_petr_t *mp;
18112   u8 is_add = 0;
18113   ip_address_t ip;
18114   int ret;
18115
18116   memset (&ip, 0, sizeof (ip));
18117
18118   /* Parse args required to build the message */
18119   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18120     {
18121       if (unformat (input, "disable"))
18122         is_add = 0;
18123       else
18124         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18125         {
18126           is_add = 1;
18127           ip_addr_version (&ip) = IP4;
18128         }
18129       else
18130         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18131         {
18132           is_add = 1;
18133           ip_addr_version (&ip) = IP6;
18134         }
18135       else
18136         {
18137           errmsg ("parse error '%U'", format_unformat_error, input);
18138           return -99;
18139         }
18140     }
18141
18142   M (ONE_USE_PETR, mp);
18143
18144   mp->is_add = is_add;
18145   if (is_add)
18146     {
18147       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18148       if (mp->is_ip4)
18149         clib_memcpy (mp->address, &ip, 4);
18150       else
18151         clib_memcpy (mp->address, &ip, 16);
18152     }
18153
18154   /* send */
18155   S (mp);
18156
18157   /* wait for reply */
18158   W (ret);
18159   return ret;
18160 }
18161
18162 #define api_lisp_use_petr api_one_use_petr
18163
18164 static int
18165 api_show_one_nsh_mapping (vat_main_t * vam)
18166 {
18167   vl_api_show_one_use_petr_t *mp;
18168   int ret;
18169
18170   if (!vam->json_output)
18171     {
18172       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18173     }
18174
18175   M (SHOW_ONE_NSH_MAPPING, mp);
18176   /* send it... */
18177   S (mp);
18178
18179   /* Wait for a reply... */
18180   W (ret);
18181   return ret;
18182 }
18183
18184 static int
18185 api_show_one_use_petr (vat_main_t * vam)
18186 {
18187   vl_api_show_one_use_petr_t *mp;
18188   int ret;
18189
18190   if (!vam->json_output)
18191     {
18192       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18193     }
18194
18195   M (SHOW_ONE_USE_PETR, mp);
18196   /* send it... */
18197   S (mp);
18198
18199   /* Wait for a reply... */
18200   W (ret);
18201   return ret;
18202 }
18203
18204 #define api_show_lisp_use_petr api_show_one_use_petr
18205
18206 /**
18207  * Add/delete mapping between vni and vrf
18208  */
18209 static int
18210 api_one_eid_table_add_del_map (vat_main_t * vam)
18211 {
18212   unformat_input_t *input = vam->input;
18213   vl_api_one_eid_table_add_del_map_t *mp;
18214   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18215   u32 vni, vrf, bd_index;
18216   int ret;
18217
18218   /* Parse args required to build the message */
18219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18220     {
18221       if (unformat (input, "del"))
18222         is_add = 0;
18223       else if (unformat (input, "vrf %d", &vrf))
18224         vrf_set = 1;
18225       else if (unformat (input, "bd_index %d", &bd_index))
18226         bd_index_set = 1;
18227       else if (unformat (input, "vni %d", &vni))
18228         vni_set = 1;
18229       else
18230         break;
18231     }
18232
18233   if (!vni_set || (!vrf_set && !bd_index_set))
18234     {
18235       errmsg ("missing arguments!");
18236       return -99;
18237     }
18238
18239   if (vrf_set && bd_index_set)
18240     {
18241       errmsg ("error: both vrf and bd entered!");
18242       return -99;
18243     }
18244
18245   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18246
18247   mp->is_add = is_add;
18248   mp->vni = htonl (vni);
18249   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18250   mp->is_l2 = bd_index_set;
18251
18252   /* send */
18253   S (mp);
18254
18255   /* wait for reply */
18256   W (ret);
18257   return ret;
18258 }
18259
18260 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18261
18262 uword
18263 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18264 {
18265   u32 *action = va_arg (*args, u32 *);
18266   u8 *s = 0;
18267
18268   if (unformat (input, "%s", &s))
18269     {
18270       if (!strcmp ((char *) s, "no-action"))
18271         action[0] = 0;
18272       else if (!strcmp ((char *) s, "natively-forward"))
18273         action[0] = 1;
18274       else if (!strcmp ((char *) s, "send-map-request"))
18275         action[0] = 2;
18276       else if (!strcmp ((char *) s, "drop"))
18277         action[0] = 3;
18278       else
18279         {
18280           clib_warning ("invalid action: '%s'", s);
18281           action[0] = 3;
18282         }
18283     }
18284   else
18285     return 0;
18286
18287   vec_free (s);
18288   return 1;
18289 }
18290
18291 /**
18292  * Add/del remote mapping to/from ONE control plane
18293  *
18294  * @param vam vpp API test context
18295  * @return return code
18296  */
18297 static int
18298 api_one_add_del_remote_mapping (vat_main_t * vam)
18299 {
18300   unformat_input_t *input = vam->input;
18301   vl_api_one_add_del_remote_mapping_t *mp;
18302   u32 vni = 0;
18303   lisp_eid_vat_t _eid, *eid = &_eid;
18304   lisp_eid_vat_t _seid, *seid = &_seid;
18305   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18306   u32 action = ~0, p, w, data_len;
18307   ip4_address_t rloc4;
18308   ip6_address_t rloc6;
18309   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18310   int ret;
18311
18312   memset (&rloc, 0, sizeof (rloc));
18313
18314   /* Parse args required to build the message */
18315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18316     {
18317       if (unformat (input, "del-all"))
18318         {
18319           del_all = 1;
18320         }
18321       else if (unformat (input, "del"))
18322         {
18323           is_add = 0;
18324         }
18325       else if (unformat (input, "add"))
18326         {
18327           is_add = 1;
18328         }
18329       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18330         {
18331           eid_set = 1;
18332         }
18333       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18334         {
18335           seid_set = 1;
18336         }
18337       else if (unformat (input, "vni %d", &vni))
18338         {
18339           ;
18340         }
18341       else if (unformat (input, "p %d w %d", &p, &w))
18342         {
18343           if (!curr_rloc)
18344             {
18345               errmsg ("No RLOC configured for setting priority/weight!");
18346               return -99;
18347             }
18348           curr_rloc->priority = p;
18349           curr_rloc->weight = w;
18350         }
18351       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18352         {
18353           rloc.is_ip4 = 1;
18354           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18355           vec_add1 (rlocs, rloc);
18356           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18357         }
18358       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18359         {
18360           rloc.is_ip4 = 0;
18361           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18362           vec_add1 (rlocs, rloc);
18363           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18364         }
18365       else if (unformat (input, "action %U",
18366                          unformat_negative_mapping_action, &action))
18367         {
18368           ;
18369         }
18370       else
18371         {
18372           clib_warning ("parse error '%U'", format_unformat_error, input);
18373           return -99;
18374         }
18375     }
18376
18377   if (0 == eid_set)
18378     {
18379       errmsg ("missing params!");
18380       return -99;
18381     }
18382
18383   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18384     {
18385       errmsg ("no action set for negative map-reply!");
18386       return -99;
18387     }
18388
18389   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18390
18391   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18392   mp->is_add = is_add;
18393   mp->vni = htonl (vni);
18394   mp->action = (u8) action;
18395   mp->is_src_dst = seid_set;
18396   mp->eid_len = eid->len;
18397   mp->seid_len = seid->len;
18398   mp->del_all = del_all;
18399   mp->eid_type = eid->type;
18400   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18401   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18402
18403   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18404   clib_memcpy (mp->rlocs, rlocs, data_len);
18405   vec_free (rlocs);
18406
18407   /* send it... */
18408   S (mp);
18409
18410   /* Wait for a reply... */
18411   W (ret);
18412   return ret;
18413 }
18414
18415 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18416
18417 /**
18418  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18419  * forwarding entries in data-plane accordingly.
18420  *
18421  * @param vam vpp API test context
18422  * @return return code
18423  */
18424 static int
18425 api_one_add_del_adjacency (vat_main_t * vam)
18426 {
18427   unformat_input_t *input = vam->input;
18428   vl_api_one_add_del_adjacency_t *mp;
18429   u32 vni = 0;
18430   ip4_address_t leid4, reid4;
18431   ip6_address_t leid6, reid6;
18432   u8 reid_mac[6] = { 0 };
18433   u8 leid_mac[6] = { 0 };
18434   u8 reid_type, leid_type;
18435   u32 leid_len = 0, reid_len = 0, len;
18436   u8 is_add = 1;
18437   int ret;
18438
18439   leid_type = reid_type = (u8) ~ 0;
18440
18441   /* Parse args required to build the message */
18442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18443     {
18444       if (unformat (input, "del"))
18445         {
18446           is_add = 0;
18447         }
18448       else if (unformat (input, "add"))
18449         {
18450           is_add = 1;
18451         }
18452       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18453                          &reid4, &len))
18454         {
18455           reid_type = 0;        /* ipv4 */
18456           reid_len = len;
18457         }
18458       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18459                          &reid6, &len))
18460         {
18461           reid_type = 1;        /* ipv6 */
18462           reid_len = len;
18463         }
18464       else if (unformat (input, "reid %U", unformat_ethernet_address,
18465                          reid_mac))
18466         {
18467           reid_type = 2;        /* mac */
18468         }
18469       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18470                          &leid4, &len))
18471         {
18472           leid_type = 0;        /* ipv4 */
18473           leid_len = len;
18474         }
18475       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18476                          &leid6, &len))
18477         {
18478           leid_type = 1;        /* ipv6 */
18479           leid_len = len;
18480         }
18481       else if (unformat (input, "leid %U", unformat_ethernet_address,
18482                          leid_mac))
18483         {
18484           leid_type = 2;        /* mac */
18485         }
18486       else if (unformat (input, "vni %d", &vni))
18487         {
18488           ;
18489         }
18490       else
18491         {
18492           errmsg ("parse error '%U'", format_unformat_error, input);
18493           return -99;
18494         }
18495     }
18496
18497   if ((u8) ~ 0 == reid_type)
18498     {
18499       errmsg ("missing params!");
18500       return -99;
18501     }
18502
18503   if (leid_type != reid_type)
18504     {
18505       errmsg ("remote and local EIDs are of different types!");
18506       return -99;
18507     }
18508
18509   M (ONE_ADD_DEL_ADJACENCY, mp);
18510   mp->is_add = is_add;
18511   mp->vni = htonl (vni);
18512   mp->leid_len = leid_len;
18513   mp->reid_len = reid_len;
18514   mp->eid_type = reid_type;
18515
18516   switch (mp->eid_type)
18517     {
18518     case 0:
18519       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18520       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18521       break;
18522     case 1:
18523       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18524       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18525       break;
18526     case 2:
18527       clib_memcpy (mp->leid, leid_mac, 6);
18528       clib_memcpy (mp->reid, reid_mac, 6);
18529       break;
18530     default:
18531       errmsg ("unknown EID type %d!", mp->eid_type);
18532       return 0;
18533     }
18534
18535   /* send it... */
18536   S (mp);
18537
18538   /* Wait for a reply... */
18539   W (ret);
18540   return ret;
18541 }
18542
18543 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18544
18545 uword
18546 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18547 {
18548   u32 *mode = va_arg (*args, u32 *);
18549
18550   if (unformat (input, "lisp"))
18551     *mode = 0;
18552   else if (unformat (input, "vxlan"))
18553     *mode = 1;
18554   else
18555     return 0;
18556
18557   return 1;
18558 }
18559
18560 static int
18561 api_gpe_get_encap_mode (vat_main_t * vam)
18562 {
18563   vl_api_gpe_get_encap_mode_t *mp;
18564   int ret;
18565
18566   /* Construct the API message */
18567   M (GPE_GET_ENCAP_MODE, mp);
18568
18569   /* send it... */
18570   S (mp);
18571
18572   /* Wait for a reply... */
18573   W (ret);
18574   return ret;
18575 }
18576
18577 static int
18578 api_gpe_set_encap_mode (vat_main_t * vam)
18579 {
18580   unformat_input_t *input = vam->input;
18581   vl_api_gpe_set_encap_mode_t *mp;
18582   int ret;
18583   u32 mode = 0;
18584
18585   /* Parse args required to build the message */
18586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18587     {
18588       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18589         ;
18590       else
18591         break;
18592     }
18593
18594   /* Construct the API message */
18595   M (GPE_SET_ENCAP_MODE, mp);
18596
18597   mp->mode = mode;
18598
18599   /* send it... */
18600   S (mp);
18601
18602   /* Wait for a reply... */
18603   W (ret);
18604   return ret;
18605 }
18606
18607 static int
18608 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18609 {
18610   unformat_input_t *input = vam->input;
18611   vl_api_gpe_add_del_iface_t *mp;
18612   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18613   u32 dp_table = 0, vni = 0;
18614   int ret;
18615
18616   /* Parse args required to build the message */
18617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18618     {
18619       if (unformat (input, "up"))
18620         {
18621           action_set = 1;
18622           is_add = 1;
18623         }
18624       else if (unformat (input, "down"))
18625         {
18626           action_set = 1;
18627           is_add = 0;
18628         }
18629       else if (unformat (input, "table_id %d", &dp_table))
18630         {
18631           dp_table_set = 1;
18632         }
18633       else if (unformat (input, "bd_id %d", &dp_table))
18634         {
18635           dp_table_set = 1;
18636           is_l2 = 1;
18637         }
18638       else if (unformat (input, "vni %d", &vni))
18639         {
18640           vni_set = 1;
18641         }
18642       else
18643         break;
18644     }
18645
18646   if (action_set == 0)
18647     {
18648       errmsg ("Action not set");
18649       return -99;
18650     }
18651   if (dp_table_set == 0 || vni_set == 0)
18652     {
18653       errmsg ("vni and dp_table must be set");
18654       return -99;
18655     }
18656
18657   /* Construct the API message */
18658   M (GPE_ADD_DEL_IFACE, mp);
18659
18660   mp->is_add = is_add;
18661   mp->dp_table = clib_host_to_net_u32 (dp_table);
18662   mp->is_l2 = is_l2;
18663   mp->vni = clib_host_to_net_u32 (vni);
18664
18665   /* send it... */
18666   S (mp);
18667
18668   /* Wait for a reply... */
18669   W (ret);
18670   return ret;
18671 }
18672
18673 static int
18674 api_one_map_register_fallback_threshold (vat_main_t * vam)
18675 {
18676   unformat_input_t *input = vam->input;
18677   vl_api_one_map_register_fallback_threshold_t *mp;
18678   u32 value = 0;
18679   u8 is_set = 0;
18680   int ret;
18681
18682   /* Parse args required to build the message */
18683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18684     {
18685       if (unformat (input, "%u", &value))
18686         is_set = 1;
18687       else
18688         {
18689           clib_warning ("parse error '%U'", format_unformat_error, input);
18690           return -99;
18691         }
18692     }
18693
18694   if (!is_set)
18695     {
18696       errmsg ("fallback threshold value is missing!");
18697       return -99;
18698     }
18699
18700   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18701   mp->value = clib_host_to_net_u32 (value);
18702
18703   /* send it... */
18704   S (mp);
18705
18706   /* Wait for a reply... */
18707   W (ret);
18708   return ret;
18709 }
18710
18711 static int
18712 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18713 {
18714   vl_api_show_one_map_register_fallback_threshold_t *mp;
18715   int ret;
18716
18717   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18718
18719   /* send it... */
18720   S (mp);
18721
18722   /* Wait for a reply... */
18723   W (ret);
18724   return ret;
18725 }
18726
18727 uword
18728 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18729 {
18730   u32 *proto = va_arg (*args, u32 *);
18731
18732   if (unformat (input, "udp"))
18733     *proto = 1;
18734   else if (unformat (input, "api"))
18735     *proto = 2;
18736   else
18737     return 0;
18738
18739   return 1;
18740 }
18741
18742 static int
18743 api_one_set_transport_protocol (vat_main_t * vam)
18744 {
18745   unformat_input_t *input = vam->input;
18746   vl_api_one_set_transport_protocol_t *mp;
18747   u8 is_set = 0;
18748   u32 protocol = 0;
18749   int ret;
18750
18751   /* Parse args required to build the message */
18752   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18753     {
18754       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18755         is_set = 1;
18756       else
18757         {
18758           clib_warning ("parse error '%U'", format_unformat_error, input);
18759           return -99;
18760         }
18761     }
18762
18763   if (!is_set)
18764     {
18765       errmsg ("Transport protocol missing!");
18766       return -99;
18767     }
18768
18769   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18770   mp->protocol = (u8) protocol;
18771
18772   /* send it... */
18773   S (mp);
18774
18775   /* Wait for a reply... */
18776   W (ret);
18777   return ret;
18778 }
18779
18780 static int
18781 api_one_get_transport_protocol (vat_main_t * vam)
18782 {
18783   vl_api_one_get_transport_protocol_t *mp;
18784   int ret;
18785
18786   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18787
18788   /* send it... */
18789   S (mp);
18790
18791   /* Wait for a reply... */
18792   W (ret);
18793   return ret;
18794 }
18795
18796 static int
18797 api_one_map_register_set_ttl (vat_main_t * vam)
18798 {
18799   unformat_input_t *input = vam->input;
18800   vl_api_one_map_register_set_ttl_t *mp;
18801   u32 ttl = 0;
18802   u8 is_set = 0;
18803   int ret;
18804
18805   /* Parse args required to build the message */
18806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18807     {
18808       if (unformat (input, "%u", &ttl))
18809         is_set = 1;
18810       else
18811         {
18812           clib_warning ("parse error '%U'", format_unformat_error, input);
18813           return -99;
18814         }
18815     }
18816
18817   if (!is_set)
18818     {
18819       errmsg ("TTL value missing!");
18820       return -99;
18821     }
18822
18823   M (ONE_MAP_REGISTER_SET_TTL, mp);
18824   mp->ttl = clib_host_to_net_u32 (ttl);
18825
18826   /* send it... */
18827   S (mp);
18828
18829   /* Wait for a reply... */
18830   W (ret);
18831   return ret;
18832 }
18833
18834 static int
18835 api_show_one_map_register_ttl (vat_main_t * vam)
18836 {
18837   vl_api_show_one_map_register_ttl_t *mp;
18838   int ret;
18839
18840   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18841
18842   /* send it... */
18843   S (mp);
18844
18845   /* Wait for a reply... */
18846   W (ret);
18847   return ret;
18848 }
18849
18850 /**
18851  * Add/del map request itr rlocs from ONE control plane and updates
18852  *
18853  * @param vam vpp API test context
18854  * @return return code
18855  */
18856 static int
18857 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18858 {
18859   unformat_input_t *input = vam->input;
18860   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18861   u8 *locator_set_name = 0;
18862   u8 locator_set_name_set = 0;
18863   u8 is_add = 1;
18864   int ret;
18865
18866   /* Parse args required to build the message */
18867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18868     {
18869       if (unformat (input, "del"))
18870         {
18871           is_add = 0;
18872         }
18873       else if (unformat (input, "%_%v%_", &locator_set_name))
18874         {
18875           locator_set_name_set = 1;
18876         }
18877       else
18878         {
18879           clib_warning ("parse error '%U'", format_unformat_error, input);
18880           return -99;
18881         }
18882     }
18883
18884   if (is_add && !locator_set_name_set)
18885     {
18886       errmsg ("itr-rloc is not set!");
18887       return -99;
18888     }
18889
18890   if (is_add && vec_len (locator_set_name) > 64)
18891     {
18892       errmsg ("itr-rloc locator-set name too long");
18893       vec_free (locator_set_name);
18894       return -99;
18895     }
18896
18897   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18898   mp->is_add = is_add;
18899   if (is_add)
18900     {
18901       clib_memcpy (mp->locator_set_name, locator_set_name,
18902                    vec_len (locator_set_name));
18903     }
18904   else
18905     {
18906       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18907     }
18908   vec_free (locator_set_name);
18909
18910   /* send it... */
18911   S (mp);
18912
18913   /* Wait for a reply... */
18914   W (ret);
18915   return ret;
18916 }
18917
18918 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18919
18920 static int
18921 api_one_locator_dump (vat_main_t * vam)
18922 {
18923   unformat_input_t *input = vam->input;
18924   vl_api_one_locator_dump_t *mp;
18925   vl_api_control_ping_t *mp_ping;
18926   u8 is_index_set = 0, is_name_set = 0;
18927   u8 *ls_name = 0;
18928   u32 ls_index = ~0;
18929   int ret;
18930
18931   /* Parse args required to build the message */
18932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18933     {
18934       if (unformat (input, "ls_name %_%v%_", &ls_name))
18935         {
18936           is_name_set = 1;
18937         }
18938       else if (unformat (input, "ls_index %d", &ls_index))
18939         {
18940           is_index_set = 1;
18941         }
18942       else
18943         {
18944           errmsg ("parse error '%U'", format_unformat_error, input);
18945           return -99;
18946         }
18947     }
18948
18949   if (!is_index_set && !is_name_set)
18950     {
18951       errmsg ("error: expected one of index or name!");
18952       return -99;
18953     }
18954
18955   if (is_index_set && is_name_set)
18956     {
18957       errmsg ("error: only one param expected!");
18958       return -99;
18959     }
18960
18961   if (vec_len (ls_name) > 62)
18962     {
18963       errmsg ("error: locator set name too long!");
18964       return -99;
18965     }
18966
18967   if (!vam->json_output)
18968     {
18969       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18970     }
18971
18972   M (ONE_LOCATOR_DUMP, mp);
18973   mp->is_index_set = is_index_set;
18974
18975   if (is_index_set)
18976     mp->ls_index = clib_host_to_net_u32 (ls_index);
18977   else
18978     {
18979       vec_add1 (ls_name, 0);
18980       strncpy ((char *) mp->ls_name, (char *) ls_name,
18981                sizeof (mp->ls_name) - 1);
18982     }
18983
18984   /* send it... */
18985   S (mp);
18986
18987   /* Use a control ping for synchronization */
18988   MPING (CONTROL_PING, mp_ping);
18989   S (mp_ping);
18990
18991   /* Wait for a reply... */
18992   W (ret);
18993   return ret;
18994 }
18995
18996 #define api_lisp_locator_dump api_one_locator_dump
18997
18998 static int
18999 api_one_locator_set_dump (vat_main_t * vam)
19000 {
19001   vl_api_one_locator_set_dump_t *mp;
19002   vl_api_control_ping_t *mp_ping;
19003   unformat_input_t *input = vam->input;
19004   u8 filter = 0;
19005   int ret;
19006
19007   /* Parse args required to build the message */
19008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19009     {
19010       if (unformat (input, "local"))
19011         {
19012           filter = 1;
19013         }
19014       else if (unformat (input, "remote"))
19015         {
19016           filter = 2;
19017         }
19018       else
19019         {
19020           errmsg ("parse error '%U'", format_unformat_error, input);
19021           return -99;
19022         }
19023     }
19024
19025   if (!vam->json_output)
19026     {
19027       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19028     }
19029
19030   M (ONE_LOCATOR_SET_DUMP, mp);
19031
19032   mp->filter = filter;
19033
19034   /* send it... */
19035   S (mp);
19036
19037   /* Use a control ping for synchronization */
19038   MPING (CONTROL_PING, mp_ping);
19039   S (mp_ping);
19040
19041   /* Wait for a reply... */
19042   W (ret);
19043   return ret;
19044 }
19045
19046 #define api_lisp_locator_set_dump api_one_locator_set_dump
19047
19048 static int
19049 api_one_eid_table_map_dump (vat_main_t * vam)
19050 {
19051   u8 is_l2 = 0;
19052   u8 mode_set = 0;
19053   unformat_input_t *input = vam->input;
19054   vl_api_one_eid_table_map_dump_t *mp;
19055   vl_api_control_ping_t *mp_ping;
19056   int ret;
19057
19058   /* Parse args required to build the message */
19059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19060     {
19061       if (unformat (input, "l2"))
19062         {
19063           is_l2 = 1;
19064           mode_set = 1;
19065         }
19066       else if (unformat (input, "l3"))
19067         {
19068           is_l2 = 0;
19069           mode_set = 1;
19070         }
19071       else
19072         {
19073           errmsg ("parse error '%U'", format_unformat_error, input);
19074           return -99;
19075         }
19076     }
19077
19078   if (!mode_set)
19079     {
19080       errmsg ("expected one of 'l2' or 'l3' parameter!");
19081       return -99;
19082     }
19083
19084   if (!vam->json_output)
19085     {
19086       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19087     }
19088
19089   M (ONE_EID_TABLE_MAP_DUMP, mp);
19090   mp->is_l2 = is_l2;
19091
19092   /* send it... */
19093   S (mp);
19094
19095   /* Use a control ping for synchronization */
19096   MPING (CONTROL_PING, mp_ping);
19097   S (mp_ping);
19098
19099   /* Wait for a reply... */
19100   W (ret);
19101   return ret;
19102 }
19103
19104 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19105
19106 static int
19107 api_one_eid_table_vni_dump (vat_main_t * vam)
19108 {
19109   vl_api_one_eid_table_vni_dump_t *mp;
19110   vl_api_control_ping_t *mp_ping;
19111   int ret;
19112
19113   if (!vam->json_output)
19114     {
19115       print (vam->ofp, "VNI");
19116     }
19117
19118   M (ONE_EID_TABLE_VNI_DUMP, mp);
19119
19120   /* send it... */
19121   S (mp);
19122
19123   /* Use a control ping for synchronization */
19124   MPING (CONTROL_PING, mp_ping);
19125   S (mp_ping);
19126
19127   /* Wait for a reply... */
19128   W (ret);
19129   return ret;
19130 }
19131
19132 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19133
19134 static int
19135 api_one_eid_table_dump (vat_main_t * vam)
19136 {
19137   unformat_input_t *i = vam->input;
19138   vl_api_one_eid_table_dump_t *mp;
19139   vl_api_control_ping_t *mp_ping;
19140   struct in_addr ip4;
19141   struct in6_addr ip6;
19142   u8 mac[6];
19143   u8 eid_type = ~0, eid_set = 0;
19144   u32 prefix_length = ~0, t, vni = 0;
19145   u8 filter = 0;
19146   int ret;
19147   lisp_nsh_api_t nsh;
19148
19149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19150     {
19151       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19152         {
19153           eid_set = 1;
19154           eid_type = 0;
19155           prefix_length = t;
19156         }
19157       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19158         {
19159           eid_set = 1;
19160           eid_type = 1;
19161           prefix_length = t;
19162         }
19163       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19164         {
19165           eid_set = 1;
19166           eid_type = 2;
19167         }
19168       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19169         {
19170           eid_set = 1;
19171           eid_type = 3;
19172         }
19173       else if (unformat (i, "vni %d", &t))
19174         {
19175           vni = t;
19176         }
19177       else if (unformat (i, "local"))
19178         {
19179           filter = 1;
19180         }
19181       else if (unformat (i, "remote"))
19182         {
19183           filter = 2;
19184         }
19185       else
19186         {
19187           errmsg ("parse error '%U'", format_unformat_error, i);
19188           return -99;
19189         }
19190     }
19191
19192   if (!vam->json_output)
19193     {
19194       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19195              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19196     }
19197
19198   M (ONE_EID_TABLE_DUMP, mp);
19199
19200   mp->filter = filter;
19201   if (eid_set)
19202     {
19203       mp->eid_set = 1;
19204       mp->vni = htonl (vni);
19205       mp->eid_type = eid_type;
19206       switch (eid_type)
19207         {
19208         case 0:
19209           mp->prefix_length = prefix_length;
19210           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19211           break;
19212         case 1:
19213           mp->prefix_length = prefix_length;
19214           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19215           break;
19216         case 2:
19217           clib_memcpy (mp->eid, mac, sizeof (mac));
19218           break;
19219         case 3:
19220           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19221           break;
19222         default:
19223           errmsg ("unknown EID type %d!", eid_type);
19224           return -99;
19225         }
19226     }
19227
19228   /* send it... */
19229   S (mp);
19230
19231   /* Use a control ping for synchronization */
19232   MPING (CONTROL_PING, mp_ping);
19233   S (mp_ping);
19234
19235   /* Wait for a reply... */
19236   W (ret);
19237   return ret;
19238 }
19239
19240 #define api_lisp_eid_table_dump api_one_eid_table_dump
19241
19242 static int
19243 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19244 {
19245   unformat_input_t *i = vam->input;
19246   vl_api_gpe_fwd_entries_get_t *mp;
19247   u8 vni_set = 0;
19248   u32 vni = ~0;
19249   int ret;
19250
19251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19252     {
19253       if (unformat (i, "vni %d", &vni))
19254         {
19255           vni_set = 1;
19256         }
19257       else
19258         {
19259           errmsg ("parse error '%U'", format_unformat_error, i);
19260           return -99;
19261         }
19262     }
19263
19264   if (!vni_set)
19265     {
19266       errmsg ("vni not set!");
19267       return -99;
19268     }
19269
19270   if (!vam->json_output)
19271     {
19272       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19273              "leid", "reid");
19274     }
19275
19276   M (GPE_FWD_ENTRIES_GET, mp);
19277   mp->vni = clib_host_to_net_u32 (vni);
19278
19279   /* send it... */
19280   S (mp);
19281
19282   /* Wait for a reply... */
19283   W (ret);
19284   return ret;
19285 }
19286
19287 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19288 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19289 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19290 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19291 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19292 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19293 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19294 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19295
19296 static int
19297 api_one_adjacencies_get (vat_main_t * vam)
19298 {
19299   unformat_input_t *i = vam->input;
19300   vl_api_one_adjacencies_get_t *mp;
19301   u8 vni_set = 0;
19302   u32 vni = ~0;
19303   int ret;
19304
19305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19306     {
19307       if (unformat (i, "vni %d", &vni))
19308         {
19309           vni_set = 1;
19310         }
19311       else
19312         {
19313           errmsg ("parse error '%U'", format_unformat_error, i);
19314           return -99;
19315         }
19316     }
19317
19318   if (!vni_set)
19319     {
19320       errmsg ("vni not set!");
19321       return -99;
19322     }
19323
19324   if (!vam->json_output)
19325     {
19326       print (vam->ofp, "%s %40s", "leid", "reid");
19327     }
19328
19329   M (ONE_ADJACENCIES_GET, mp);
19330   mp->vni = clib_host_to_net_u32 (vni);
19331
19332   /* send it... */
19333   S (mp);
19334
19335   /* Wait for a reply... */
19336   W (ret);
19337   return ret;
19338 }
19339
19340 #define api_lisp_adjacencies_get api_one_adjacencies_get
19341
19342 static int
19343 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19344 {
19345   unformat_input_t *i = vam->input;
19346   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19347   int ret;
19348   u8 ip_family_set = 0, is_ip4 = 1;
19349
19350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19351     {
19352       if (unformat (i, "ip4"))
19353         {
19354           ip_family_set = 1;
19355           is_ip4 = 1;
19356         }
19357       else if (unformat (i, "ip6"))
19358         {
19359           ip_family_set = 1;
19360           is_ip4 = 0;
19361         }
19362       else
19363         {
19364           errmsg ("parse error '%U'", format_unformat_error, i);
19365           return -99;
19366         }
19367     }
19368
19369   if (!ip_family_set)
19370     {
19371       errmsg ("ip family not set!");
19372       return -99;
19373     }
19374
19375   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19376   mp->is_ip4 = is_ip4;
19377
19378   /* send it... */
19379   S (mp);
19380
19381   /* Wait for a reply... */
19382   W (ret);
19383   return ret;
19384 }
19385
19386 static int
19387 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19388 {
19389   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19390   int ret;
19391
19392   if (!vam->json_output)
19393     {
19394       print (vam->ofp, "VNIs");
19395     }
19396
19397   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19398
19399   /* send it... */
19400   S (mp);
19401
19402   /* Wait for a reply... */
19403   W (ret);
19404   return ret;
19405 }
19406
19407 static int
19408 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19409 {
19410   unformat_input_t *i = vam->input;
19411   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19412   int ret = 0;
19413   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19414   struct in_addr ip4;
19415   struct in6_addr ip6;
19416   u32 table_id = 0, nh_sw_if_index = ~0;
19417
19418   memset (&ip4, 0, sizeof (ip4));
19419   memset (&ip6, 0, sizeof (ip6));
19420
19421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19422     {
19423       if (unformat (i, "del"))
19424         is_add = 0;
19425       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19426                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19427         {
19428           ip_set = 1;
19429           is_ip4 = 1;
19430         }
19431       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19432                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19433         {
19434           ip_set = 1;
19435           is_ip4 = 0;
19436         }
19437       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19438         {
19439           ip_set = 1;
19440           is_ip4 = 1;
19441           nh_sw_if_index = ~0;
19442         }
19443       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19444         {
19445           ip_set = 1;
19446           is_ip4 = 0;
19447           nh_sw_if_index = ~0;
19448         }
19449       else if (unformat (i, "table %d", &table_id))
19450         ;
19451       else
19452         {
19453           errmsg ("parse error '%U'", format_unformat_error, i);
19454           return -99;
19455         }
19456     }
19457
19458   if (!ip_set)
19459     {
19460       errmsg ("nh addr not set!");
19461       return -99;
19462     }
19463
19464   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19465   mp->is_add = is_add;
19466   mp->table_id = clib_host_to_net_u32 (table_id);
19467   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19468   mp->is_ip4 = is_ip4;
19469   if (is_ip4)
19470     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19471   else
19472     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19473
19474   /* send it... */
19475   S (mp);
19476
19477   /* Wait for a reply... */
19478   W (ret);
19479   return ret;
19480 }
19481
19482 static int
19483 api_one_map_server_dump (vat_main_t * vam)
19484 {
19485   vl_api_one_map_server_dump_t *mp;
19486   vl_api_control_ping_t *mp_ping;
19487   int ret;
19488
19489   if (!vam->json_output)
19490     {
19491       print (vam->ofp, "%=20s", "Map server");
19492     }
19493
19494   M (ONE_MAP_SERVER_DUMP, mp);
19495   /* send it... */
19496   S (mp);
19497
19498   /* Use a control ping for synchronization */
19499   MPING (CONTROL_PING, mp_ping);
19500   S (mp_ping);
19501
19502   /* Wait for a reply... */
19503   W (ret);
19504   return ret;
19505 }
19506
19507 #define api_lisp_map_server_dump api_one_map_server_dump
19508
19509 static int
19510 api_one_map_resolver_dump (vat_main_t * vam)
19511 {
19512   vl_api_one_map_resolver_dump_t *mp;
19513   vl_api_control_ping_t *mp_ping;
19514   int ret;
19515
19516   if (!vam->json_output)
19517     {
19518       print (vam->ofp, "%=20s", "Map resolver");
19519     }
19520
19521   M (ONE_MAP_RESOLVER_DUMP, mp);
19522   /* send it... */
19523   S (mp);
19524
19525   /* Use a control ping for synchronization */
19526   MPING (CONTROL_PING, mp_ping);
19527   S (mp_ping);
19528
19529   /* Wait for a reply... */
19530   W (ret);
19531   return ret;
19532 }
19533
19534 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19535
19536 static int
19537 api_one_stats_flush (vat_main_t * vam)
19538 {
19539   vl_api_one_stats_flush_t *mp;
19540   int ret = 0;
19541
19542   M (ONE_STATS_FLUSH, mp);
19543   S (mp);
19544   W (ret);
19545   return ret;
19546 }
19547
19548 static int
19549 api_one_stats_dump (vat_main_t * vam)
19550 {
19551   vl_api_one_stats_dump_t *mp;
19552   vl_api_control_ping_t *mp_ping;
19553   int ret;
19554
19555   M (ONE_STATS_DUMP, mp);
19556   /* send it... */
19557   S (mp);
19558
19559   /* Use a control ping for synchronization */
19560   MPING (CONTROL_PING, mp_ping);
19561   S (mp_ping);
19562
19563   /* Wait for a reply... */
19564   W (ret);
19565   return ret;
19566 }
19567
19568 static int
19569 api_show_one_status (vat_main_t * vam)
19570 {
19571   vl_api_show_one_status_t *mp;
19572   int ret;
19573
19574   if (!vam->json_output)
19575     {
19576       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19577     }
19578
19579   M (SHOW_ONE_STATUS, mp);
19580   /* send it... */
19581   S (mp);
19582   /* Wait for a reply... */
19583   W (ret);
19584   return ret;
19585 }
19586
19587 #define api_show_lisp_status api_show_one_status
19588
19589 static int
19590 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19591 {
19592   vl_api_gpe_fwd_entry_path_dump_t *mp;
19593   vl_api_control_ping_t *mp_ping;
19594   unformat_input_t *i = vam->input;
19595   u32 fwd_entry_index = ~0;
19596   int ret;
19597
19598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19599     {
19600       if (unformat (i, "index %d", &fwd_entry_index))
19601         ;
19602       else
19603         break;
19604     }
19605
19606   if (~0 == fwd_entry_index)
19607     {
19608       errmsg ("no index specified!");
19609       return -99;
19610     }
19611
19612   if (!vam->json_output)
19613     {
19614       print (vam->ofp, "first line");
19615     }
19616
19617   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19618
19619   /* send it... */
19620   S (mp);
19621   /* Use a control ping for synchronization */
19622   MPING (CONTROL_PING, mp_ping);
19623   S (mp_ping);
19624
19625   /* Wait for a reply... */
19626   W (ret);
19627   return ret;
19628 }
19629
19630 static int
19631 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19632 {
19633   vl_api_one_get_map_request_itr_rlocs_t *mp;
19634   int ret;
19635
19636   if (!vam->json_output)
19637     {
19638       print (vam->ofp, "%=20s", "itr-rlocs:");
19639     }
19640
19641   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19642   /* send it... */
19643   S (mp);
19644   /* Wait for a reply... */
19645   W (ret);
19646   return ret;
19647 }
19648
19649 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19650
19651 static int
19652 api_af_packet_create (vat_main_t * vam)
19653 {
19654   unformat_input_t *i = vam->input;
19655   vl_api_af_packet_create_t *mp;
19656   u8 *host_if_name = 0;
19657   u8 hw_addr[6];
19658   u8 random_hw_addr = 1;
19659   int ret;
19660
19661   memset (hw_addr, 0, sizeof (hw_addr));
19662
19663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19664     {
19665       if (unformat (i, "name %s", &host_if_name))
19666         vec_add1 (host_if_name, 0);
19667       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19668         random_hw_addr = 0;
19669       else
19670         break;
19671     }
19672
19673   if (!vec_len (host_if_name))
19674     {
19675       errmsg ("host-interface name must be specified");
19676       return -99;
19677     }
19678
19679   if (vec_len (host_if_name) > 64)
19680     {
19681       errmsg ("host-interface name too long");
19682       return -99;
19683     }
19684
19685   M (AF_PACKET_CREATE, mp);
19686
19687   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19688   clib_memcpy (mp->hw_addr, hw_addr, 6);
19689   mp->use_random_hw_addr = random_hw_addr;
19690   vec_free (host_if_name);
19691
19692   S (mp);
19693
19694   /* *INDENT-OFF* */
19695   W2 (ret,
19696       ({
19697         if (ret == 0)
19698           fprintf (vam->ofp ? vam->ofp : stderr,
19699                    " new sw_if_index = %d\n", vam->sw_if_index);
19700       }));
19701   /* *INDENT-ON* */
19702   return ret;
19703 }
19704
19705 static int
19706 api_af_packet_delete (vat_main_t * vam)
19707 {
19708   unformat_input_t *i = vam->input;
19709   vl_api_af_packet_delete_t *mp;
19710   u8 *host_if_name = 0;
19711   int ret;
19712
19713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19714     {
19715       if (unformat (i, "name %s", &host_if_name))
19716         vec_add1 (host_if_name, 0);
19717       else
19718         break;
19719     }
19720
19721   if (!vec_len (host_if_name))
19722     {
19723       errmsg ("host-interface name must be specified");
19724       return -99;
19725     }
19726
19727   if (vec_len (host_if_name) > 64)
19728     {
19729       errmsg ("host-interface name too long");
19730       return -99;
19731     }
19732
19733   M (AF_PACKET_DELETE, mp);
19734
19735   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19736   vec_free (host_if_name);
19737
19738   S (mp);
19739   W (ret);
19740   return ret;
19741 }
19742
19743 static int
19744 api_policer_add_del (vat_main_t * vam)
19745 {
19746   unformat_input_t *i = vam->input;
19747   vl_api_policer_add_del_t *mp;
19748   u8 is_add = 1;
19749   u8 *name = 0;
19750   u32 cir = 0;
19751   u32 eir = 0;
19752   u64 cb = 0;
19753   u64 eb = 0;
19754   u8 rate_type = 0;
19755   u8 round_type = 0;
19756   u8 type = 0;
19757   u8 color_aware = 0;
19758   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19759   int ret;
19760
19761   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19762   conform_action.dscp = 0;
19763   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19764   exceed_action.dscp = 0;
19765   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19766   violate_action.dscp = 0;
19767
19768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19769     {
19770       if (unformat (i, "del"))
19771         is_add = 0;
19772       else if (unformat (i, "name %s", &name))
19773         vec_add1 (name, 0);
19774       else if (unformat (i, "cir %u", &cir))
19775         ;
19776       else if (unformat (i, "eir %u", &eir))
19777         ;
19778       else if (unformat (i, "cb %u", &cb))
19779         ;
19780       else if (unformat (i, "eb %u", &eb))
19781         ;
19782       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19783                          &rate_type))
19784         ;
19785       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19786                          &round_type))
19787         ;
19788       else if (unformat (i, "type %U", unformat_policer_type, &type))
19789         ;
19790       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19791                          &conform_action))
19792         ;
19793       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19794                          &exceed_action))
19795         ;
19796       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19797                          &violate_action))
19798         ;
19799       else if (unformat (i, "color-aware"))
19800         color_aware = 1;
19801       else
19802         break;
19803     }
19804
19805   if (!vec_len (name))
19806     {
19807       errmsg ("policer name must be specified");
19808       return -99;
19809     }
19810
19811   if (vec_len (name) > 64)
19812     {
19813       errmsg ("policer name too long");
19814       return -99;
19815     }
19816
19817   M (POLICER_ADD_DEL, mp);
19818
19819   clib_memcpy (mp->name, name, vec_len (name));
19820   vec_free (name);
19821   mp->is_add = is_add;
19822   mp->cir = ntohl (cir);
19823   mp->eir = ntohl (eir);
19824   mp->cb = clib_net_to_host_u64 (cb);
19825   mp->eb = clib_net_to_host_u64 (eb);
19826   mp->rate_type = rate_type;
19827   mp->round_type = round_type;
19828   mp->type = type;
19829   mp->conform_action_type = conform_action.action_type;
19830   mp->conform_dscp = conform_action.dscp;
19831   mp->exceed_action_type = exceed_action.action_type;
19832   mp->exceed_dscp = exceed_action.dscp;
19833   mp->violate_action_type = violate_action.action_type;
19834   mp->violate_dscp = violate_action.dscp;
19835   mp->color_aware = color_aware;
19836
19837   S (mp);
19838   W (ret);
19839   return ret;
19840 }
19841
19842 static int
19843 api_policer_dump (vat_main_t * vam)
19844 {
19845   unformat_input_t *i = vam->input;
19846   vl_api_policer_dump_t *mp;
19847   vl_api_control_ping_t *mp_ping;
19848   u8 *match_name = 0;
19849   u8 match_name_valid = 0;
19850   int ret;
19851
19852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19853     {
19854       if (unformat (i, "name %s", &match_name))
19855         {
19856           vec_add1 (match_name, 0);
19857           match_name_valid = 1;
19858         }
19859       else
19860         break;
19861     }
19862
19863   M (POLICER_DUMP, mp);
19864   mp->match_name_valid = match_name_valid;
19865   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19866   vec_free (match_name);
19867   /* send it... */
19868   S (mp);
19869
19870   /* Use a control ping for synchronization */
19871   MPING (CONTROL_PING, mp_ping);
19872   S (mp_ping);
19873
19874   /* Wait for a reply... */
19875   W (ret);
19876   return ret;
19877 }
19878
19879 static int
19880 api_policer_classify_set_interface (vat_main_t * vam)
19881 {
19882   unformat_input_t *i = vam->input;
19883   vl_api_policer_classify_set_interface_t *mp;
19884   u32 sw_if_index;
19885   int sw_if_index_set;
19886   u32 ip4_table_index = ~0;
19887   u32 ip6_table_index = ~0;
19888   u32 l2_table_index = ~0;
19889   u8 is_add = 1;
19890   int ret;
19891
19892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19893     {
19894       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19895         sw_if_index_set = 1;
19896       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19897         sw_if_index_set = 1;
19898       else if (unformat (i, "del"))
19899         is_add = 0;
19900       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19901         ;
19902       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19903         ;
19904       else if (unformat (i, "l2-table %d", &l2_table_index))
19905         ;
19906       else
19907         {
19908           clib_warning ("parse error '%U'", format_unformat_error, i);
19909           return -99;
19910         }
19911     }
19912
19913   if (sw_if_index_set == 0)
19914     {
19915       errmsg ("missing interface name or sw_if_index");
19916       return -99;
19917     }
19918
19919   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19920
19921   mp->sw_if_index = ntohl (sw_if_index);
19922   mp->ip4_table_index = ntohl (ip4_table_index);
19923   mp->ip6_table_index = ntohl (ip6_table_index);
19924   mp->l2_table_index = ntohl (l2_table_index);
19925   mp->is_add = is_add;
19926
19927   S (mp);
19928   W (ret);
19929   return ret;
19930 }
19931
19932 static int
19933 api_policer_classify_dump (vat_main_t * vam)
19934 {
19935   unformat_input_t *i = vam->input;
19936   vl_api_policer_classify_dump_t *mp;
19937   vl_api_control_ping_t *mp_ping;
19938   u8 type = POLICER_CLASSIFY_N_TABLES;
19939   int ret;
19940
19941   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19942     ;
19943   else
19944     {
19945       errmsg ("classify table type must be specified");
19946       return -99;
19947     }
19948
19949   if (!vam->json_output)
19950     {
19951       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19952     }
19953
19954   M (POLICER_CLASSIFY_DUMP, mp);
19955   mp->type = type;
19956   /* send it... */
19957   S (mp);
19958
19959   /* Use a control ping for synchronization */
19960   MPING (CONTROL_PING, mp_ping);
19961   S (mp_ping);
19962
19963   /* Wait for a reply... */
19964   W (ret);
19965   return ret;
19966 }
19967
19968 static int
19969 api_netmap_create (vat_main_t * vam)
19970 {
19971   unformat_input_t *i = vam->input;
19972   vl_api_netmap_create_t *mp;
19973   u8 *if_name = 0;
19974   u8 hw_addr[6];
19975   u8 random_hw_addr = 1;
19976   u8 is_pipe = 0;
19977   u8 is_master = 0;
19978   int ret;
19979
19980   memset (hw_addr, 0, sizeof (hw_addr));
19981
19982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19983     {
19984       if (unformat (i, "name %s", &if_name))
19985         vec_add1 (if_name, 0);
19986       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19987         random_hw_addr = 0;
19988       else if (unformat (i, "pipe"))
19989         is_pipe = 1;
19990       else if (unformat (i, "master"))
19991         is_master = 1;
19992       else if (unformat (i, "slave"))
19993         is_master = 0;
19994       else
19995         break;
19996     }
19997
19998   if (!vec_len (if_name))
19999     {
20000       errmsg ("interface name must be specified");
20001       return -99;
20002     }
20003
20004   if (vec_len (if_name) > 64)
20005     {
20006       errmsg ("interface name too long");
20007       return -99;
20008     }
20009
20010   M (NETMAP_CREATE, mp);
20011
20012   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20013   clib_memcpy (mp->hw_addr, hw_addr, 6);
20014   mp->use_random_hw_addr = random_hw_addr;
20015   mp->is_pipe = is_pipe;
20016   mp->is_master = is_master;
20017   vec_free (if_name);
20018
20019   S (mp);
20020   W (ret);
20021   return ret;
20022 }
20023
20024 static int
20025 api_netmap_delete (vat_main_t * vam)
20026 {
20027   unformat_input_t *i = vam->input;
20028   vl_api_netmap_delete_t *mp;
20029   u8 *if_name = 0;
20030   int ret;
20031
20032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20033     {
20034       if (unformat (i, "name %s", &if_name))
20035         vec_add1 (if_name, 0);
20036       else
20037         break;
20038     }
20039
20040   if (!vec_len (if_name))
20041     {
20042       errmsg ("interface name must be specified");
20043       return -99;
20044     }
20045
20046   if (vec_len (if_name) > 64)
20047     {
20048       errmsg ("interface name too long");
20049       return -99;
20050     }
20051
20052   M (NETMAP_DELETE, mp);
20053
20054   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20055   vec_free (if_name);
20056
20057   S (mp);
20058   W (ret);
20059   return ret;
20060 }
20061
20062 static void
20063 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20064 {
20065   if (fp->afi == IP46_TYPE_IP6)
20066     print (vam->ofp,
20067            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20068            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20069            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20070            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20071            format_ip6_address, fp->next_hop);
20072   else if (fp->afi == IP46_TYPE_IP4)
20073     print (vam->ofp,
20074            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20075            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20076            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20077            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20078            format_ip4_address, fp->next_hop);
20079 }
20080
20081 static void
20082 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20083                                  vl_api_fib_path_t * fp)
20084 {
20085   struct in_addr ip4;
20086   struct in6_addr ip6;
20087
20088   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20089   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20090   vat_json_object_add_uint (node, "is_local", fp->is_local);
20091   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20092   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20093   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20094   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20095   if (fp->afi == IP46_TYPE_IP4)
20096     {
20097       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20098       vat_json_object_add_ip4 (node, "next_hop", ip4);
20099     }
20100   else if (fp->afi == IP46_TYPE_IP6)
20101     {
20102       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20103       vat_json_object_add_ip6 (node, "next_hop", ip6);
20104     }
20105 }
20106
20107 static void
20108 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20109 {
20110   vat_main_t *vam = &vat_main;
20111   int count = ntohl (mp->mt_count);
20112   vl_api_fib_path_t *fp;
20113   i32 i;
20114
20115   print (vam->ofp, "[%d]: sw_if_index %d via:",
20116          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20117   fp = mp->mt_paths;
20118   for (i = 0; i < count; i++)
20119     {
20120       vl_api_mpls_fib_path_print (vam, fp);
20121       fp++;
20122     }
20123
20124   print (vam->ofp, "");
20125 }
20126
20127 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20128 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20129
20130 static void
20131 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20132 {
20133   vat_main_t *vam = &vat_main;
20134   vat_json_node_t *node = NULL;
20135   int count = ntohl (mp->mt_count);
20136   vl_api_fib_path_t *fp;
20137   i32 i;
20138
20139   if (VAT_JSON_ARRAY != vam->json_tree.type)
20140     {
20141       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20142       vat_json_init_array (&vam->json_tree);
20143     }
20144   node = vat_json_array_add (&vam->json_tree);
20145
20146   vat_json_init_object (node);
20147   vat_json_object_add_uint (node, "tunnel_index",
20148                             ntohl (mp->mt_tunnel_index));
20149   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20150
20151   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20152
20153   fp = mp->mt_paths;
20154   for (i = 0; i < count; i++)
20155     {
20156       vl_api_mpls_fib_path_json_print (node, fp);
20157       fp++;
20158     }
20159 }
20160
20161 static int
20162 api_mpls_tunnel_dump (vat_main_t * vam)
20163 {
20164   vl_api_mpls_tunnel_dump_t *mp;
20165   vl_api_control_ping_t *mp_ping;
20166   i32 index = -1;
20167   int ret;
20168
20169   /* Parse args required to build the message */
20170   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20171     {
20172       if (!unformat (vam->input, "tunnel_index %d", &index))
20173         {
20174           index = -1;
20175           break;
20176         }
20177     }
20178
20179   print (vam->ofp, "  tunnel_index %d", index);
20180
20181   M (MPLS_TUNNEL_DUMP, mp);
20182   mp->tunnel_index = htonl (index);
20183   S (mp);
20184
20185   /* Use a control ping for synchronization */
20186   MPING (CONTROL_PING, mp_ping);
20187   S (mp_ping);
20188
20189   W (ret);
20190   return ret;
20191 }
20192
20193 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20194 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20195
20196
20197 static void
20198 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20199 {
20200   vat_main_t *vam = &vat_main;
20201   int count = ntohl (mp->count);
20202   vl_api_fib_path_t *fp;
20203   int i;
20204
20205   print (vam->ofp,
20206          "table-id %d, label %u, ess_bit %u",
20207          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20208   fp = mp->path;
20209   for (i = 0; i < count; i++)
20210     {
20211       vl_api_mpls_fib_path_print (vam, fp);
20212       fp++;
20213     }
20214 }
20215
20216 static void vl_api_mpls_fib_details_t_handler_json
20217   (vl_api_mpls_fib_details_t * mp)
20218 {
20219   vat_main_t *vam = &vat_main;
20220   int count = ntohl (mp->count);
20221   vat_json_node_t *node = NULL;
20222   vl_api_fib_path_t *fp;
20223   int i;
20224
20225   if (VAT_JSON_ARRAY != vam->json_tree.type)
20226     {
20227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20228       vat_json_init_array (&vam->json_tree);
20229     }
20230   node = vat_json_array_add (&vam->json_tree);
20231
20232   vat_json_init_object (node);
20233   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20234   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20235   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20236   vat_json_object_add_uint (node, "path_count", count);
20237   fp = mp->path;
20238   for (i = 0; i < count; i++)
20239     {
20240       vl_api_mpls_fib_path_json_print (node, fp);
20241       fp++;
20242     }
20243 }
20244
20245 static int
20246 api_mpls_fib_dump (vat_main_t * vam)
20247 {
20248   vl_api_mpls_fib_dump_t *mp;
20249   vl_api_control_ping_t *mp_ping;
20250   int ret;
20251
20252   M (MPLS_FIB_DUMP, mp);
20253   S (mp);
20254
20255   /* Use a control ping for synchronization */
20256   MPING (CONTROL_PING, mp_ping);
20257   S (mp_ping);
20258
20259   W (ret);
20260   return ret;
20261 }
20262
20263 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20264 #define vl_api_ip_fib_details_t_print vl_noop_handler
20265
20266 static void
20267 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20268 {
20269   vat_main_t *vam = &vat_main;
20270   int count = ntohl (mp->count);
20271   vl_api_fib_path_t *fp;
20272   int i;
20273
20274   print (vam->ofp,
20275          "table-id %d, prefix %U/%d",
20276          ntohl (mp->table_id), format_ip4_address, mp->address,
20277          mp->address_length);
20278   fp = mp->path;
20279   for (i = 0; i < count; i++)
20280     {
20281       if (fp->afi == IP46_TYPE_IP6)
20282         print (vam->ofp,
20283                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20284                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20285                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20286                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20287                format_ip6_address, fp->next_hop);
20288       else if (fp->afi == IP46_TYPE_IP4)
20289         print (vam->ofp,
20290                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20291                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20292                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20293                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20294                format_ip4_address, fp->next_hop);
20295       fp++;
20296     }
20297 }
20298
20299 static void vl_api_ip_fib_details_t_handler_json
20300   (vl_api_ip_fib_details_t * mp)
20301 {
20302   vat_main_t *vam = &vat_main;
20303   int count = ntohl (mp->count);
20304   vat_json_node_t *node = NULL;
20305   struct in_addr ip4;
20306   struct in6_addr ip6;
20307   vl_api_fib_path_t *fp;
20308   int i;
20309
20310   if (VAT_JSON_ARRAY != vam->json_tree.type)
20311     {
20312       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20313       vat_json_init_array (&vam->json_tree);
20314     }
20315   node = vat_json_array_add (&vam->json_tree);
20316
20317   vat_json_init_object (node);
20318   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20319   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20320   vat_json_object_add_ip4 (node, "prefix", ip4);
20321   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20322   vat_json_object_add_uint (node, "path_count", count);
20323   fp = mp->path;
20324   for (i = 0; i < count; i++)
20325     {
20326       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20327       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20328       vat_json_object_add_uint (node, "is_local", fp->is_local);
20329       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20330       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20331       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20332       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20333       if (fp->afi == IP46_TYPE_IP4)
20334         {
20335           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20336           vat_json_object_add_ip4 (node, "next_hop", ip4);
20337         }
20338       else if (fp->afi == IP46_TYPE_IP6)
20339         {
20340           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20341           vat_json_object_add_ip6 (node, "next_hop", ip6);
20342         }
20343     }
20344 }
20345
20346 static int
20347 api_ip_fib_dump (vat_main_t * vam)
20348 {
20349   vl_api_ip_fib_dump_t *mp;
20350   vl_api_control_ping_t *mp_ping;
20351   int ret;
20352
20353   M (IP_FIB_DUMP, mp);
20354   S (mp);
20355
20356   /* Use a control ping for synchronization */
20357   MPING (CONTROL_PING, mp_ping);
20358   S (mp_ping);
20359
20360   W (ret);
20361   return ret;
20362 }
20363
20364 static int
20365 api_ip_mfib_dump (vat_main_t * vam)
20366 {
20367   vl_api_ip_mfib_dump_t *mp;
20368   vl_api_control_ping_t *mp_ping;
20369   int ret;
20370
20371   M (IP_MFIB_DUMP, mp);
20372   S (mp);
20373
20374   /* Use a control ping for synchronization */
20375   MPING (CONTROL_PING, mp_ping);
20376   S (mp_ping);
20377
20378   W (ret);
20379   return ret;
20380 }
20381
20382 static void vl_api_ip_neighbor_details_t_handler
20383   (vl_api_ip_neighbor_details_t * mp)
20384 {
20385   vat_main_t *vam = &vat_main;
20386
20387   print (vam->ofp, "%c %U %U",
20388          (mp->is_static) ? 'S' : 'D',
20389          format_ethernet_address, &mp->mac_address,
20390          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20391          &mp->ip_address);
20392 }
20393
20394 static void vl_api_ip_neighbor_details_t_handler_json
20395   (vl_api_ip_neighbor_details_t * mp)
20396 {
20397
20398   vat_main_t *vam = &vat_main;
20399   vat_json_node_t *node;
20400   struct in_addr ip4;
20401   struct in6_addr ip6;
20402
20403   if (VAT_JSON_ARRAY != vam->json_tree.type)
20404     {
20405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20406       vat_json_init_array (&vam->json_tree);
20407     }
20408   node = vat_json_array_add (&vam->json_tree);
20409
20410   vat_json_init_object (node);
20411   vat_json_object_add_string_copy (node, "flag",
20412                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20413                                    "dynamic");
20414
20415   vat_json_object_add_string_copy (node, "link_layer",
20416                                    format (0, "%U", format_ethernet_address,
20417                                            &mp->mac_address));
20418
20419   if (mp->is_ipv6)
20420     {
20421       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20422       vat_json_object_add_ip6 (node, "ip_address", ip6);
20423     }
20424   else
20425     {
20426       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20427       vat_json_object_add_ip4 (node, "ip_address", ip4);
20428     }
20429 }
20430
20431 static int
20432 api_ip_neighbor_dump (vat_main_t * vam)
20433 {
20434   unformat_input_t *i = vam->input;
20435   vl_api_ip_neighbor_dump_t *mp;
20436   vl_api_control_ping_t *mp_ping;
20437   u8 is_ipv6 = 0;
20438   u32 sw_if_index = ~0;
20439   int ret;
20440
20441   /* Parse args required to build the message */
20442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20443     {
20444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20445         ;
20446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20447         ;
20448       else if (unformat (i, "ip6"))
20449         is_ipv6 = 1;
20450       else
20451         break;
20452     }
20453
20454   if (sw_if_index == ~0)
20455     {
20456       errmsg ("missing interface name or sw_if_index");
20457       return -99;
20458     }
20459
20460   M (IP_NEIGHBOR_DUMP, mp);
20461   mp->is_ipv6 = (u8) is_ipv6;
20462   mp->sw_if_index = ntohl (sw_if_index);
20463   S (mp);
20464
20465   /* Use a control ping for synchronization */
20466   MPING (CONTROL_PING, mp_ping);
20467   S (mp_ping);
20468
20469   W (ret);
20470   return ret;
20471 }
20472
20473 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20474 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20475
20476 static void
20477 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20478 {
20479   vat_main_t *vam = &vat_main;
20480   int count = ntohl (mp->count);
20481   vl_api_fib_path_t *fp;
20482   int i;
20483
20484   print (vam->ofp,
20485          "table-id %d, prefix %U/%d",
20486          ntohl (mp->table_id), format_ip6_address, mp->address,
20487          mp->address_length);
20488   fp = mp->path;
20489   for (i = 0; i < count; i++)
20490     {
20491       if (fp->afi == IP46_TYPE_IP6)
20492         print (vam->ofp,
20493                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20494                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20495                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20496                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20497                format_ip6_address, fp->next_hop);
20498       else if (fp->afi == IP46_TYPE_IP4)
20499         print (vam->ofp,
20500                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20501                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20502                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20503                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20504                format_ip4_address, fp->next_hop);
20505       fp++;
20506     }
20507 }
20508
20509 static void vl_api_ip6_fib_details_t_handler_json
20510   (vl_api_ip6_fib_details_t * mp)
20511 {
20512   vat_main_t *vam = &vat_main;
20513   int count = ntohl (mp->count);
20514   vat_json_node_t *node = NULL;
20515   struct in_addr ip4;
20516   struct in6_addr ip6;
20517   vl_api_fib_path_t *fp;
20518   int i;
20519
20520   if (VAT_JSON_ARRAY != vam->json_tree.type)
20521     {
20522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20523       vat_json_init_array (&vam->json_tree);
20524     }
20525   node = vat_json_array_add (&vam->json_tree);
20526
20527   vat_json_init_object (node);
20528   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20529   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20530   vat_json_object_add_ip6 (node, "prefix", ip6);
20531   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20532   vat_json_object_add_uint (node, "path_count", count);
20533   fp = mp->path;
20534   for (i = 0; i < count; i++)
20535     {
20536       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20537       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20538       vat_json_object_add_uint (node, "is_local", fp->is_local);
20539       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20540       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20541       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20542       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20543       if (fp->afi == IP46_TYPE_IP4)
20544         {
20545           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20546           vat_json_object_add_ip4 (node, "next_hop", ip4);
20547         }
20548       else if (fp->afi == IP46_TYPE_IP6)
20549         {
20550           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20551           vat_json_object_add_ip6 (node, "next_hop", ip6);
20552         }
20553     }
20554 }
20555
20556 static int
20557 api_ip6_fib_dump (vat_main_t * vam)
20558 {
20559   vl_api_ip6_fib_dump_t *mp;
20560   vl_api_control_ping_t *mp_ping;
20561   int ret;
20562
20563   M (IP6_FIB_DUMP, mp);
20564   S (mp);
20565
20566   /* Use a control ping for synchronization */
20567   MPING (CONTROL_PING, mp_ping);
20568   S (mp_ping);
20569
20570   W (ret);
20571   return ret;
20572 }
20573
20574 static int
20575 api_ip6_mfib_dump (vat_main_t * vam)
20576 {
20577   vl_api_ip6_mfib_dump_t *mp;
20578   vl_api_control_ping_t *mp_ping;
20579   int ret;
20580
20581   M (IP6_MFIB_DUMP, mp);
20582   S (mp);
20583
20584   /* Use a control ping for synchronization */
20585   MPING (CONTROL_PING, mp_ping);
20586   S (mp_ping);
20587
20588   W (ret);
20589   return ret;
20590 }
20591
20592 int
20593 api_classify_table_ids (vat_main_t * vam)
20594 {
20595   vl_api_classify_table_ids_t *mp;
20596   int ret;
20597
20598   /* Construct the API message */
20599   M (CLASSIFY_TABLE_IDS, mp);
20600   mp->context = 0;
20601
20602   S (mp);
20603   W (ret);
20604   return ret;
20605 }
20606
20607 int
20608 api_classify_table_by_interface (vat_main_t * vam)
20609 {
20610   unformat_input_t *input = vam->input;
20611   vl_api_classify_table_by_interface_t *mp;
20612
20613   u32 sw_if_index = ~0;
20614   int ret;
20615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20616     {
20617       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20618         ;
20619       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20620         ;
20621       else
20622         break;
20623     }
20624   if (sw_if_index == ~0)
20625     {
20626       errmsg ("missing interface name or sw_if_index");
20627       return -99;
20628     }
20629
20630   /* Construct the API message */
20631   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20632   mp->context = 0;
20633   mp->sw_if_index = ntohl (sw_if_index);
20634
20635   S (mp);
20636   W (ret);
20637   return ret;
20638 }
20639
20640 int
20641 api_classify_table_info (vat_main_t * vam)
20642 {
20643   unformat_input_t *input = vam->input;
20644   vl_api_classify_table_info_t *mp;
20645
20646   u32 table_id = ~0;
20647   int ret;
20648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20649     {
20650       if (unformat (input, "table_id %d", &table_id))
20651         ;
20652       else
20653         break;
20654     }
20655   if (table_id == ~0)
20656     {
20657       errmsg ("missing table id");
20658       return -99;
20659     }
20660
20661   /* Construct the API message */
20662   M (CLASSIFY_TABLE_INFO, mp);
20663   mp->context = 0;
20664   mp->table_id = ntohl (table_id);
20665
20666   S (mp);
20667   W (ret);
20668   return ret;
20669 }
20670
20671 int
20672 api_classify_session_dump (vat_main_t * vam)
20673 {
20674   unformat_input_t *input = vam->input;
20675   vl_api_classify_session_dump_t *mp;
20676   vl_api_control_ping_t *mp_ping;
20677
20678   u32 table_id = ~0;
20679   int ret;
20680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20681     {
20682       if (unformat (input, "table_id %d", &table_id))
20683         ;
20684       else
20685         break;
20686     }
20687   if (table_id == ~0)
20688     {
20689       errmsg ("missing table id");
20690       return -99;
20691     }
20692
20693   /* Construct the API message */
20694   M (CLASSIFY_SESSION_DUMP, mp);
20695   mp->context = 0;
20696   mp->table_id = ntohl (table_id);
20697   S (mp);
20698
20699   /* Use a control ping for synchronization */
20700   MPING (CONTROL_PING, mp_ping);
20701   S (mp_ping);
20702
20703   W (ret);
20704   return ret;
20705 }
20706
20707 static void
20708 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20709 {
20710   vat_main_t *vam = &vat_main;
20711
20712   print (vam->ofp, "collector_address %U, collector_port %d, "
20713          "src_address %U, vrf_id %d, path_mtu %u, "
20714          "template_interval %u, udp_checksum %d",
20715          format_ip4_address, mp->collector_address,
20716          ntohs (mp->collector_port),
20717          format_ip4_address, mp->src_address,
20718          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20719          ntohl (mp->template_interval), mp->udp_checksum);
20720
20721   vam->retval = 0;
20722   vam->result_ready = 1;
20723 }
20724
20725 static void
20726   vl_api_ipfix_exporter_details_t_handler_json
20727   (vl_api_ipfix_exporter_details_t * mp)
20728 {
20729   vat_main_t *vam = &vat_main;
20730   vat_json_node_t node;
20731   struct in_addr collector_address;
20732   struct in_addr src_address;
20733
20734   vat_json_init_object (&node);
20735   clib_memcpy (&collector_address, &mp->collector_address,
20736                sizeof (collector_address));
20737   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20738   vat_json_object_add_uint (&node, "collector_port",
20739                             ntohs (mp->collector_port));
20740   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20741   vat_json_object_add_ip4 (&node, "src_address", src_address);
20742   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20743   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20744   vat_json_object_add_uint (&node, "template_interval",
20745                             ntohl (mp->template_interval));
20746   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20747
20748   vat_json_print (vam->ofp, &node);
20749   vat_json_free (&node);
20750   vam->retval = 0;
20751   vam->result_ready = 1;
20752 }
20753
20754 int
20755 api_ipfix_exporter_dump (vat_main_t * vam)
20756 {
20757   vl_api_ipfix_exporter_dump_t *mp;
20758   int ret;
20759
20760   /* Construct the API message */
20761   M (IPFIX_EXPORTER_DUMP, mp);
20762   mp->context = 0;
20763
20764   S (mp);
20765   W (ret);
20766   return ret;
20767 }
20768
20769 static int
20770 api_ipfix_classify_stream_dump (vat_main_t * vam)
20771 {
20772   vl_api_ipfix_classify_stream_dump_t *mp;
20773   int ret;
20774
20775   /* Construct the API message */
20776   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20777   mp->context = 0;
20778
20779   S (mp);
20780   W (ret);
20781   return ret;
20782   /* NOTREACHED */
20783   return 0;
20784 }
20785
20786 static void
20787   vl_api_ipfix_classify_stream_details_t_handler
20788   (vl_api_ipfix_classify_stream_details_t * mp)
20789 {
20790   vat_main_t *vam = &vat_main;
20791   print (vam->ofp, "domain_id %d, src_port %d",
20792          ntohl (mp->domain_id), ntohs (mp->src_port));
20793   vam->retval = 0;
20794   vam->result_ready = 1;
20795 }
20796
20797 static void
20798   vl_api_ipfix_classify_stream_details_t_handler_json
20799   (vl_api_ipfix_classify_stream_details_t * mp)
20800 {
20801   vat_main_t *vam = &vat_main;
20802   vat_json_node_t node;
20803
20804   vat_json_init_object (&node);
20805   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20806   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20807
20808   vat_json_print (vam->ofp, &node);
20809   vat_json_free (&node);
20810   vam->retval = 0;
20811   vam->result_ready = 1;
20812 }
20813
20814 static int
20815 api_ipfix_classify_table_dump (vat_main_t * vam)
20816 {
20817   vl_api_ipfix_classify_table_dump_t *mp;
20818   vl_api_control_ping_t *mp_ping;
20819   int ret;
20820
20821   if (!vam->json_output)
20822     {
20823       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20824              "transport_protocol");
20825     }
20826
20827   /* Construct the API message */
20828   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20829
20830   /* send it... */
20831   S (mp);
20832
20833   /* Use a control ping for synchronization */
20834   MPING (CONTROL_PING, mp_ping);
20835   S (mp_ping);
20836
20837   W (ret);
20838   return ret;
20839 }
20840
20841 static void
20842   vl_api_ipfix_classify_table_details_t_handler
20843   (vl_api_ipfix_classify_table_details_t * mp)
20844 {
20845   vat_main_t *vam = &vat_main;
20846   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20847          mp->transport_protocol);
20848 }
20849
20850 static void
20851   vl_api_ipfix_classify_table_details_t_handler_json
20852   (vl_api_ipfix_classify_table_details_t * mp)
20853 {
20854   vat_json_node_t *node = NULL;
20855   vat_main_t *vam = &vat_main;
20856
20857   if (VAT_JSON_ARRAY != vam->json_tree.type)
20858     {
20859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20860       vat_json_init_array (&vam->json_tree);
20861     }
20862
20863   node = vat_json_array_add (&vam->json_tree);
20864   vat_json_init_object (node);
20865
20866   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20867   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20868   vat_json_object_add_uint (node, "transport_protocol",
20869                             mp->transport_protocol);
20870 }
20871
20872 static int
20873 api_sw_interface_span_enable_disable (vat_main_t * vam)
20874 {
20875   unformat_input_t *i = vam->input;
20876   vl_api_sw_interface_span_enable_disable_t *mp;
20877   u32 src_sw_if_index = ~0;
20878   u32 dst_sw_if_index = ~0;
20879   u8 state = 3;
20880   int ret;
20881   u8 is_l2 = 0;
20882
20883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20884     {
20885       if (unformat
20886           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20887         ;
20888       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20889         ;
20890       else
20891         if (unformat
20892             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20893         ;
20894       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20895         ;
20896       else if (unformat (i, "disable"))
20897         state = 0;
20898       else if (unformat (i, "rx"))
20899         state = 1;
20900       else if (unformat (i, "tx"))
20901         state = 2;
20902       else if (unformat (i, "both"))
20903         state = 3;
20904       else if (unformat (i, "l2"))
20905         is_l2 = 1;
20906       else
20907         break;
20908     }
20909
20910   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20911
20912   mp->sw_if_index_from = htonl (src_sw_if_index);
20913   mp->sw_if_index_to = htonl (dst_sw_if_index);
20914   mp->state = state;
20915   mp->is_l2 = is_l2;
20916
20917   S (mp);
20918   W (ret);
20919   return ret;
20920 }
20921
20922 static void
20923 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20924                                             * mp)
20925 {
20926   vat_main_t *vam = &vat_main;
20927   u8 *sw_if_from_name = 0;
20928   u8 *sw_if_to_name = 0;
20929   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20930   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20931   char *states[] = { "none", "rx", "tx", "both" };
20932   hash_pair_t *p;
20933
20934   /* *INDENT-OFF* */
20935   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20936   ({
20937     if ((u32) p->value[0] == sw_if_index_from)
20938       {
20939         sw_if_from_name = (u8 *)(p->key);
20940         if (sw_if_to_name)
20941           break;
20942       }
20943     if ((u32) p->value[0] == sw_if_index_to)
20944       {
20945         sw_if_to_name = (u8 *)(p->key);
20946         if (sw_if_from_name)
20947           break;
20948       }
20949   }));
20950   /* *INDENT-ON* */
20951   print (vam->ofp, "%20s => %20s (%s) %s",
20952          sw_if_from_name, sw_if_to_name, states[mp->state],
20953          mp->is_l2 ? "l2" : "device");
20954 }
20955
20956 static void
20957   vl_api_sw_interface_span_details_t_handler_json
20958   (vl_api_sw_interface_span_details_t * mp)
20959 {
20960   vat_main_t *vam = &vat_main;
20961   vat_json_node_t *node = NULL;
20962   u8 *sw_if_from_name = 0;
20963   u8 *sw_if_to_name = 0;
20964   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20965   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20966   hash_pair_t *p;
20967
20968   /* *INDENT-OFF* */
20969   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20970   ({
20971     if ((u32) p->value[0] == sw_if_index_from)
20972       {
20973         sw_if_from_name = (u8 *)(p->key);
20974         if (sw_if_to_name)
20975           break;
20976       }
20977     if ((u32) p->value[0] == sw_if_index_to)
20978       {
20979         sw_if_to_name = (u8 *)(p->key);
20980         if (sw_if_from_name)
20981           break;
20982       }
20983   }));
20984   /* *INDENT-ON* */
20985
20986   if (VAT_JSON_ARRAY != vam->json_tree.type)
20987     {
20988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20989       vat_json_init_array (&vam->json_tree);
20990     }
20991   node = vat_json_array_add (&vam->json_tree);
20992
20993   vat_json_init_object (node);
20994   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20995   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20996   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20997   if (0 != sw_if_to_name)
20998     {
20999       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21000     }
21001   vat_json_object_add_uint (node, "state", mp->state);
21002   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21003 }
21004
21005 static int
21006 api_sw_interface_span_dump (vat_main_t * vam)
21007 {
21008   unformat_input_t *input = vam->input;
21009   vl_api_sw_interface_span_dump_t *mp;
21010   vl_api_control_ping_t *mp_ping;
21011   u8 is_l2 = 0;
21012   int ret;
21013
21014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21015     {
21016       if (unformat (input, "l2"))
21017         is_l2 = 1;
21018       else
21019         break;
21020     }
21021
21022   M (SW_INTERFACE_SPAN_DUMP, mp);
21023   mp->is_l2 = is_l2;
21024   S (mp);
21025
21026   /* Use a control ping for synchronization */
21027   MPING (CONTROL_PING, mp_ping);
21028   S (mp_ping);
21029
21030   W (ret);
21031   return ret;
21032 }
21033
21034 int
21035 api_pg_create_interface (vat_main_t * vam)
21036 {
21037   unformat_input_t *input = vam->input;
21038   vl_api_pg_create_interface_t *mp;
21039
21040   u32 if_id = ~0;
21041   int ret;
21042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21043     {
21044       if (unformat (input, "if_id %d", &if_id))
21045         ;
21046       else
21047         break;
21048     }
21049   if (if_id == ~0)
21050     {
21051       errmsg ("missing pg interface index");
21052       return -99;
21053     }
21054
21055   /* Construct the API message */
21056   M (PG_CREATE_INTERFACE, mp);
21057   mp->context = 0;
21058   mp->interface_id = ntohl (if_id);
21059
21060   S (mp);
21061   W (ret);
21062   return ret;
21063 }
21064
21065 int
21066 api_pg_capture (vat_main_t * vam)
21067 {
21068   unformat_input_t *input = vam->input;
21069   vl_api_pg_capture_t *mp;
21070
21071   u32 if_id = ~0;
21072   u8 enable = 1;
21073   u32 count = 1;
21074   u8 pcap_file_set = 0;
21075   u8 *pcap_file = 0;
21076   int ret;
21077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21078     {
21079       if (unformat (input, "if_id %d", &if_id))
21080         ;
21081       else if (unformat (input, "pcap %s", &pcap_file))
21082         pcap_file_set = 1;
21083       else if (unformat (input, "count %d", &count))
21084         ;
21085       else if (unformat (input, "disable"))
21086         enable = 0;
21087       else
21088         break;
21089     }
21090   if (if_id == ~0)
21091     {
21092       errmsg ("missing pg interface index");
21093       return -99;
21094     }
21095   if (pcap_file_set > 0)
21096     {
21097       if (vec_len (pcap_file) > 255)
21098         {
21099           errmsg ("pcap file name is too long");
21100           return -99;
21101         }
21102     }
21103
21104   u32 name_len = vec_len (pcap_file);
21105   /* Construct the API message */
21106   M (PG_CAPTURE, mp);
21107   mp->context = 0;
21108   mp->interface_id = ntohl (if_id);
21109   mp->is_enabled = enable;
21110   mp->count = ntohl (count);
21111   mp->pcap_name_length = ntohl (name_len);
21112   if (pcap_file_set != 0)
21113     {
21114       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21115     }
21116   vec_free (pcap_file);
21117
21118   S (mp);
21119   W (ret);
21120   return ret;
21121 }
21122
21123 int
21124 api_pg_enable_disable (vat_main_t * vam)
21125 {
21126   unformat_input_t *input = vam->input;
21127   vl_api_pg_enable_disable_t *mp;
21128
21129   u8 enable = 1;
21130   u8 stream_name_set = 0;
21131   u8 *stream_name = 0;
21132   int ret;
21133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21134     {
21135       if (unformat (input, "stream %s", &stream_name))
21136         stream_name_set = 1;
21137       else if (unformat (input, "disable"))
21138         enable = 0;
21139       else
21140         break;
21141     }
21142
21143   if (stream_name_set > 0)
21144     {
21145       if (vec_len (stream_name) > 255)
21146         {
21147           errmsg ("stream name too long");
21148           return -99;
21149         }
21150     }
21151
21152   u32 name_len = vec_len (stream_name);
21153   /* Construct the API message */
21154   M (PG_ENABLE_DISABLE, mp);
21155   mp->context = 0;
21156   mp->is_enabled = enable;
21157   if (stream_name_set != 0)
21158     {
21159       mp->stream_name_length = ntohl (name_len);
21160       clib_memcpy (mp->stream_name, stream_name, name_len);
21161     }
21162   vec_free (stream_name);
21163
21164   S (mp);
21165   W (ret);
21166   return ret;
21167 }
21168
21169 int
21170 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21171 {
21172   unformat_input_t *input = vam->input;
21173   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21174
21175   u16 *low_ports = 0;
21176   u16 *high_ports = 0;
21177   u16 this_low;
21178   u16 this_hi;
21179   ip4_address_t ip4_addr;
21180   ip6_address_t ip6_addr;
21181   u32 length;
21182   u32 tmp, tmp2;
21183   u8 prefix_set = 0;
21184   u32 vrf_id = ~0;
21185   u8 is_add = 1;
21186   u8 is_ipv6 = 0;
21187   int ret;
21188
21189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21190     {
21191       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21192         {
21193           prefix_set = 1;
21194         }
21195       else
21196         if (unformat
21197             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21198         {
21199           prefix_set = 1;
21200           is_ipv6 = 1;
21201         }
21202       else if (unformat (input, "vrf %d", &vrf_id))
21203         ;
21204       else if (unformat (input, "del"))
21205         is_add = 0;
21206       else if (unformat (input, "port %d", &tmp))
21207         {
21208           if (tmp == 0 || tmp > 65535)
21209             {
21210               errmsg ("port %d out of range", tmp);
21211               return -99;
21212             }
21213           this_low = tmp;
21214           this_hi = this_low + 1;
21215           vec_add1 (low_ports, this_low);
21216           vec_add1 (high_ports, this_hi);
21217         }
21218       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21219         {
21220           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21221             {
21222               errmsg ("incorrect range parameters");
21223               return -99;
21224             }
21225           this_low = tmp;
21226           /* Note: in debug CLI +1 is added to high before
21227              passing to real fn that does "the work"
21228              (ip_source_and_port_range_check_add_del).
21229              This fn is a wrapper around the binary API fn a
21230              control plane will call, which expects this increment
21231              to have occurred. Hence letting the binary API control
21232              plane fn do the increment for consistency between VAT
21233              and other control planes.
21234            */
21235           this_hi = tmp2;
21236           vec_add1 (low_ports, this_low);
21237           vec_add1 (high_ports, this_hi);
21238         }
21239       else
21240         break;
21241     }
21242
21243   if (prefix_set == 0)
21244     {
21245       errmsg ("<address>/<mask> not specified");
21246       return -99;
21247     }
21248
21249   if (vrf_id == ~0)
21250     {
21251       errmsg ("VRF ID required, not specified");
21252       return -99;
21253     }
21254
21255   if (vrf_id == 0)
21256     {
21257       errmsg
21258         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21259       return -99;
21260     }
21261
21262   if (vec_len (low_ports) == 0)
21263     {
21264       errmsg ("At least one port or port range required");
21265       return -99;
21266     }
21267
21268   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21269
21270   mp->is_add = is_add;
21271
21272   if (is_ipv6)
21273     {
21274       mp->is_ipv6 = 1;
21275       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21276     }
21277   else
21278     {
21279       mp->is_ipv6 = 0;
21280       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21281     }
21282
21283   mp->mask_length = length;
21284   mp->number_of_ranges = vec_len (low_ports);
21285
21286   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21287   vec_free (low_ports);
21288
21289   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21290   vec_free (high_ports);
21291
21292   mp->vrf_id = ntohl (vrf_id);
21293
21294   S (mp);
21295   W (ret);
21296   return ret;
21297 }
21298
21299 int
21300 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21301 {
21302   unformat_input_t *input = vam->input;
21303   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21304   u32 sw_if_index = ~0;
21305   int vrf_set = 0;
21306   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21307   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21308   u8 is_add = 1;
21309   int ret;
21310
21311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21312     {
21313       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21314         ;
21315       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21316         ;
21317       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21318         vrf_set = 1;
21319       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21320         vrf_set = 1;
21321       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21322         vrf_set = 1;
21323       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21324         vrf_set = 1;
21325       else if (unformat (input, "del"))
21326         is_add = 0;
21327       else
21328         break;
21329     }
21330
21331   if (sw_if_index == ~0)
21332     {
21333       errmsg ("Interface required but not specified");
21334       return -99;
21335     }
21336
21337   if (vrf_set == 0)
21338     {
21339       errmsg ("VRF ID required but not specified");
21340       return -99;
21341     }
21342
21343   if (tcp_out_vrf_id == 0
21344       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21345     {
21346       errmsg
21347         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21348       return -99;
21349     }
21350
21351   /* Construct the API message */
21352   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21353
21354   mp->sw_if_index = ntohl (sw_if_index);
21355   mp->is_add = is_add;
21356   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21357   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21358   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21359   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21360
21361   /* send it... */
21362   S (mp);
21363
21364   /* Wait for a reply... */
21365   W (ret);
21366   return ret;
21367 }
21368
21369 static int
21370 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21371 {
21372   unformat_input_t *i = vam->input;
21373   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21374   u32 local_sa_id = 0;
21375   u32 remote_sa_id = 0;
21376   ip4_address_t src_address;
21377   ip4_address_t dst_address;
21378   u8 is_add = 1;
21379   int ret;
21380
21381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21382     {
21383       if (unformat (i, "local_sa %d", &local_sa_id))
21384         ;
21385       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21386         ;
21387       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21388         ;
21389       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21390         ;
21391       else if (unformat (i, "del"))
21392         is_add = 0;
21393       else
21394         {
21395           clib_warning ("parse error '%U'", format_unformat_error, i);
21396           return -99;
21397         }
21398     }
21399
21400   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21401
21402   mp->local_sa_id = ntohl (local_sa_id);
21403   mp->remote_sa_id = ntohl (remote_sa_id);
21404   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21405   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21406   mp->is_add = is_add;
21407
21408   S (mp);
21409   W (ret);
21410   return ret;
21411 }
21412
21413 static int
21414 api_punt (vat_main_t * vam)
21415 {
21416   unformat_input_t *i = vam->input;
21417   vl_api_punt_t *mp;
21418   u32 ipv = ~0;
21419   u32 protocol = ~0;
21420   u32 port = ~0;
21421   int is_add = 1;
21422   int ret;
21423
21424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21425     {
21426       if (unformat (i, "ip %d", &ipv))
21427         ;
21428       else if (unformat (i, "protocol %d", &protocol))
21429         ;
21430       else if (unformat (i, "port %d", &port))
21431         ;
21432       else if (unformat (i, "del"))
21433         is_add = 0;
21434       else
21435         {
21436           clib_warning ("parse error '%U'", format_unformat_error, i);
21437           return -99;
21438         }
21439     }
21440
21441   M (PUNT, mp);
21442
21443   mp->is_add = (u8) is_add;
21444   mp->ipv = (u8) ipv;
21445   mp->l4_protocol = (u8) protocol;
21446   mp->l4_port = htons ((u16) port);
21447
21448   S (mp);
21449   W (ret);
21450   return ret;
21451 }
21452
21453 static void vl_api_ipsec_gre_tunnel_details_t_handler
21454   (vl_api_ipsec_gre_tunnel_details_t * mp)
21455 {
21456   vat_main_t *vam = &vat_main;
21457
21458   print (vam->ofp, "%11d%15U%15U%14d%14d",
21459          ntohl (mp->sw_if_index),
21460          format_ip4_address, &mp->src_address,
21461          format_ip4_address, &mp->dst_address,
21462          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21463 }
21464
21465 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21466   (vl_api_ipsec_gre_tunnel_details_t * mp)
21467 {
21468   vat_main_t *vam = &vat_main;
21469   vat_json_node_t *node = NULL;
21470   struct in_addr ip4;
21471
21472   if (VAT_JSON_ARRAY != vam->json_tree.type)
21473     {
21474       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21475       vat_json_init_array (&vam->json_tree);
21476     }
21477   node = vat_json_array_add (&vam->json_tree);
21478
21479   vat_json_init_object (node);
21480   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21481   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21482   vat_json_object_add_ip4 (node, "src_address", ip4);
21483   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21484   vat_json_object_add_ip4 (node, "dst_address", ip4);
21485   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21486   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21487 }
21488
21489 static int
21490 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21491 {
21492   unformat_input_t *i = vam->input;
21493   vl_api_ipsec_gre_tunnel_dump_t *mp;
21494   vl_api_control_ping_t *mp_ping;
21495   u32 sw_if_index;
21496   u8 sw_if_index_set = 0;
21497   int ret;
21498
21499   /* Parse args required to build the message */
21500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21501     {
21502       if (unformat (i, "sw_if_index %d", &sw_if_index))
21503         sw_if_index_set = 1;
21504       else
21505         break;
21506     }
21507
21508   if (sw_if_index_set == 0)
21509     {
21510       sw_if_index = ~0;
21511     }
21512
21513   if (!vam->json_output)
21514     {
21515       print (vam->ofp, "%11s%15s%15s%14s%14s",
21516              "sw_if_index", "src_address", "dst_address",
21517              "local_sa_id", "remote_sa_id");
21518     }
21519
21520   /* Get list of gre-tunnel interfaces */
21521   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21522
21523   mp->sw_if_index = htonl (sw_if_index);
21524
21525   S (mp);
21526
21527   /* Use a control ping for synchronization */
21528   MPING (CONTROL_PING, mp_ping);
21529   S (mp_ping);
21530
21531   W (ret);
21532   return ret;
21533 }
21534
21535 static int
21536 api_delete_subif (vat_main_t * vam)
21537 {
21538   unformat_input_t *i = vam->input;
21539   vl_api_delete_subif_t *mp;
21540   u32 sw_if_index = ~0;
21541   int ret;
21542
21543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21544     {
21545       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21546         ;
21547       if (unformat (i, "sw_if_index %d", &sw_if_index))
21548         ;
21549       else
21550         break;
21551     }
21552
21553   if (sw_if_index == ~0)
21554     {
21555       errmsg ("missing sw_if_index");
21556       return -99;
21557     }
21558
21559   /* Construct the API message */
21560   M (DELETE_SUBIF, mp);
21561   mp->sw_if_index = ntohl (sw_if_index);
21562
21563   S (mp);
21564   W (ret);
21565   return ret;
21566 }
21567
21568 #define foreach_pbb_vtr_op      \
21569 _("disable",  L2_VTR_DISABLED)  \
21570 _("pop",  L2_VTR_POP_2)         \
21571 _("push",  L2_VTR_PUSH_2)
21572
21573 static int
21574 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21575 {
21576   unformat_input_t *i = vam->input;
21577   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21578   u32 sw_if_index = ~0, vtr_op = ~0;
21579   u16 outer_tag = ~0;
21580   u8 dmac[6], smac[6];
21581   u8 dmac_set = 0, smac_set = 0;
21582   u16 vlanid = 0;
21583   u32 sid = ~0;
21584   u32 tmp;
21585   int ret;
21586
21587   /* Shut up coverity */
21588   memset (dmac, 0, sizeof (dmac));
21589   memset (smac, 0, sizeof (smac));
21590
21591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21592     {
21593       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21594         ;
21595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21596         ;
21597       else if (unformat (i, "vtr_op %d", &vtr_op))
21598         ;
21599 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21600       foreach_pbb_vtr_op
21601 #undef _
21602         else if (unformat (i, "translate_pbb_stag"))
21603         {
21604           if (unformat (i, "%d", &tmp))
21605             {
21606               vtr_op = L2_VTR_TRANSLATE_2_1;
21607               outer_tag = tmp;
21608             }
21609           else
21610             {
21611               errmsg
21612                 ("translate_pbb_stag operation requires outer tag definition");
21613               return -99;
21614             }
21615         }
21616       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21617         dmac_set++;
21618       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21619         smac_set++;
21620       else if (unformat (i, "sid %d", &sid))
21621         ;
21622       else if (unformat (i, "vlanid %d", &tmp))
21623         vlanid = tmp;
21624       else
21625         {
21626           clib_warning ("parse error '%U'", format_unformat_error, i);
21627           return -99;
21628         }
21629     }
21630
21631   if ((sw_if_index == ~0) || (vtr_op == ~0))
21632     {
21633       errmsg ("missing sw_if_index or vtr operation");
21634       return -99;
21635     }
21636   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21637       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21638     {
21639       errmsg
21640         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21641       return -99;
21642     }
21643
21644   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21645   mp->sw_if_index = ntohl (sw_if_index);
21646   mp->vtr_op = ntohl (vtr_op);
21647   mp->outer_tag = ntohs (outer_tag);
21648   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21649   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21650   mp->b_vlanid = ntohs (vlanid);
21651   mp->i_sid = ntohl (sid);
21652
21653   S (mp);
21654   W (ret);
21655   return ret;
21656 }
21657
21658 static int
21659 api_flow_classify_set_interface (vat_main_t * vam)
21660 {
21661   unformat_input_t *i = vam->input;
21662   vl_api_flow_classify_set_interface_t *mp;
21663   u32 sw_if_index;
21664   int sw_if_index_set;
21665   u32 ip4_table_index = ~0;
21666   u32 ip6_table_index = ~0;
21667   u8 is_add = 1;
21668   int ret;
21669
21670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21671     {
21672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21673         sw_if_index_set = 1;
21674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21675         sw_if_index_set = 1;
21676       else if (unformat (i, "del"))
21677         is_add = 0;
21678       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21679         ;
21680       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21681         ;
21682       else
21683         {
21684           clib_warning ("parse error '%U'", format_unformat_error, i);
21685           return -99;
21686         }
21687     }
21688
21689   if (sw_if_index_set == 0)
21690     {
21691       errmsg ("missing interface name or sw_if_index");
21692       return -99;
21693     }
21694
21695   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21696
21697   mp->sw_if_index = ntohl (sw_if_index);
21698   mp->ip4_table_index = ntohl (ip4_table_index);
21699   mp->ip6_table_index = ntohl (ip6_table_index);
21700   mp->is_add = is_add;
21701
21702   S (mp);
21703   W (ret);
21704   return ret;
21705 }
21706
21707 static int
21708 api_flow_classify_dump (vat_main_t * vam)
21709 {
21710   unformat_input_t *i = vam->input;
21711   vl_api_flow_classify_dump_t *mp;
21712   vl_api_control_ping_t *mp_ping;
21713   u8 type = FLOW_CLASSIFY_N_TABLES;
21714   int ret;
21715
21716   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21717     ;
21718   else
21719     {
21720       errmsg ("classify table type must be specified");
21721       return -99;
21722     }
21723
21724   if (!vam->json_output)
21725     {
21726       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21727     }
21728
21729   M (FLOW_CLASSIFY_DUMP, mp);
21730   mp->type = type;
21731   /* send it... */
21732   S (mp);
21733
21734   /* Use a control ping for synchronization */
21735   MPING (CONTROL_PING, mp_ping);
21736   S (mp_ping);
21737
21738   /* Wait for a reply... */
21739   W (ret);
21740   return ret;
21741 }
21742
21743 static int
21744 api_feature_enable_disable (vat_main_t * vam)
21745 {
21746   unformat_input_t *i = vam->input;
21747   vl_api_feature_enable_disable_t *mp;
21748   u8 *arc_name = 0;
21749   u8 *feature_name = 0;
21750   u32 sw_if_index = ~0;
21751   u8 enable = 1;
21752   int ret;
21753
21754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21755     {
21756       if (unformat (i, "arc_name %s", &arc_name))
21757         ;
21758       else if (unformat (i, "feature_name %s", &feature_name))
21759         ;
21760       else
21761         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21762         ;
21763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21764         ;
21765       else if (unformat (i, "disable"))
21766         enable = 0;
21767       else
21768         break;
21769     }
21770
21771   if (arc_name == 0)
21772     {
21773       errmsg ("missing arc name");
21774       return -99;
21775     }
21776   if (vec_len (arc_name) > 63)
21777     {
21778       errmsg ("arc name too long");
21779     }
21780
21781   if (feature_name == 0)
21782     {
21783       errmsg ("missing feature name");
21784       return -99;
21785     }
21786   if (vec_len (feature_name) > 63)
21787     {
21788       errmsg ("feature name too long");
21789     }
21790
21791   if (sw_if_index == ~0)
21792     {
21793       errmsg ("missing interface name or sw_if_index");
21794       return -99;
21795     }
21796
21797   /* Construct the API message */
21798   M (FEATURE_ENABLE_DISABLE, mp);
21799   mp->sw_if_index = ntohl (sw_if_index);
21800   mp->enable = enable;
21801   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21802   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21803   vec_free (arc_name);
21804   vec_free (feature_name);
21805
21806   S (mp);
21807   W (ret);
21808   return ret;
21809 }
21810
21811 static int
21812 api_sw_interface_tag_add_del (vat_main_t * vam)
21813 {
21814   unformat_input_t *i = vam->input;
21815   vl_api_sw_interface_tag_add_del_t *mp;
21816   u32 sw_if_index = ~0;
21817   u8 *tag = 0;
21818   u8 enable = 1;
21819   int ret;
21820
21821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21822     {
21823       if (unformat (i, "tag %s", &tag))
21824         ;
21825       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21826         ;
21827       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21828         ;
21829       else if (unformat (i, "del"))
21830         enable = 0;
21831       else
21832         break;
21833     }
21834
21835   if (sw_if_index == ~0)
21836     {
21837       errmsg ("missing interface name or sw_if_index");
21838       return -99;
21839     }
21840
21841   if (enable && (tag == 0))
21842     {
21843       errmsg ("no tag specified");
21844       return -99;
21845     }
21846
21847   /* Construct the API message */
21848   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21849   mp->sw_if_index = ntohl (sw_if_index);
21850   mp->is_add = enable;
21851   if (enable)
21852     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21853   vec_free (tag);
21854
21855   S (mp);
21856   W (ret);
21857   return ret;
21858 }
21859
21860 static void vl_api_l2_xconnect_details_t_handler
21861   (vl_api_l2_xconnect_details_t * mp)
21862 {
21863   vat_main_t *vam = &vat_main;
21864
21865   print (vam->ofp, "%15d%15d",
21866          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21867 }
21868
21869 static void vl_api_l2_xconnect_details_t_handler_json
21870   (vl_api_l2_xconnect_details_t * mp)
21871 {
21872   vat_main_t *vam = &vat_main;
21873   vat_json_node_t *node = NULL;
21874
21875   if (VAT_JSON_ARRAY != vam->json_tree.type)
21876     {
21877       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21878       vat_json_init_array (&vam->json_tree);
21879     }
21880   node = vat_json_array_add (&vam->json_tree);
21881
21882   vat_json_init_object (node);
21883   vat_json_object_add_uint (node, "rx_sw_if_index",
21884                             ntohl (mp->rx_sw_if_index));
21885   vat_json_object_add_uint (node, "tx_sw_if_index",
21886                             ntohl (mp->tx_sw_if_index));
21887 }
21888
21889 static int
21890 api_l2_xconnect_dump (vat_main_t * vam)
21891 {
21892   vl_api_l2_xconnect_dump_t *mp;
21893   vl_api_control_ping_t *mp_ping;
21894   int ret;
21895
21896   if (!vam->json_output)
21897     {
21898       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21899     }
21900
21901   M (L2_XCONNECT_DUMP, mp);
21902
21903   S (mp);
21904
21905   /* Use a control ping for synchronization */
21906   MPING (CONTROL_PING, mp_ping);
21907   S (mp_ping);
21908
21909   W (ret);
21910   return ret;
21911 }
21912
21913 static int
21914 api_sw_interface_set_mtu (vat_main_t * vam)
21915 {
21916   unformat_input_t *i = vam->input;
21917   vl_api_sw_interface_set_mtu_t *mp;
21918   u32 sw_if_index = ~0;
21919   u32 mtu = 0;
21920   int ret;
21921
21922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21923     {
21924       if (unformat (i, "mtu %d", &mtu))
21925         ;
21926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21927         ;
21928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21929         ;
21930       else
21931         break;
21932     }
21933
21934   if (sw_if_index == ~0)
21935     {
21936       errmsg ("missing interface name or sw_if_index");
21937       return -99;
21938     }
21939
21940   if (mtu == 0)
21941     {
21942       errmsg ("no mtu specified");
21943       return -99;
21944     }
21945
21946   /* Construct the API message */
21947   M (SW_INTERFACE_SET_MTU, mp);
21948   mp->sw_if_index = ntohl (sw_if_index);
21949   mp->mtu = ntohs ((u16) mtu);
21950
21951   S (mp);
21952   W (ret);
21953   return ret;
21954 }
21955
21956 static int
21957 api_p2p_ethernet_add (vat_main_t * vam)
21958 {
21959   unformat_input_t *i = vam->input;
21960   vl_api_p2p_ethernet_add_t *mp;
21961   u32 parent_if_index = ~0;
21962   u32 sub_id = ~0;
21963   u8 remote_mac[6];
21964   u8 mac_set = 0;
21965   int ret;
21966
21967   memset (remote_mac, 0, sizeof (remote_mac));
21968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21969     {
21970       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21971         ;
21972       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21973         ;
21974       else
21975         if (unformat
21976             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21977         mac_set++;
21978       else if (unformat (i, "sub_id %d", &sub_id))
21979         ;
21980       else
21981         {
21982           clib_warning ("parse error '%U'", format_unformat_error, i);
21983           return -99;
21984         }
21985     }
21986
21987   if (parent_if_index == ~0)
21988     {
21989       errmsg ("missing interface name or sw_if_index");
21990       return -99;
21991     }
21992   if (mac_set == 0)
21993     {
21994       errmsg ("missing remote mac address");
21995       return -99;
21996     }
21997   if (sub_id == ~0)
21998     {
21999       errmsg ("missing sub-interface id");
22000       return -99;
22001     }
22002
22003   M (P2P_ETHERNET_ADD, mp);
22004   mp->parent_if_index = ntohl (parent_if_index);
22005   mp->subif_id = ntohl (sub_id);
22006   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22007
22008   S (mp);
22009   W (ret);
22010   return ret;
22011 }
22012
22013 static int
22014 api_p2p_ethernet_del (vat_main_t * vam)
22015 {
22016   unformat_input_t *i = vam->input;
22017   vl_api_p2p_ethernet_del_t *mp;
22018   u32 parent_if_index = ~0;
22019   u8 remote_mac[6];
22020   u8 mac_set = 0;
22021   int ret;
22022
22023   memset (remote_mac, 0, sizeof (remote_mac));
22024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22025     {
22026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22027         ;
22028       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22029         ;
22030       else
22031         if (unformat
22032             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22033         mac_set++;
22034       else
22035         {
22036           clib_warning ("parse error '%U'", format_unformat_error, i);
22037           return -99;
22038         }
22039     }
22040
22041   if (parent_if_index == ~0)
22042     {
22043       errmsg ("missing interface name or sw_if_index");
22044       return -99;
22045     }
22046   if (mac_set == 0)
22047     {
22048       errmsg ("missing remote mac address");
22049       return -99;
22050     }
22051
22052   M (P2P_ETHERNET_DEL, mp);
22053   mp->parent_if_index = ntohl (parent_if_index);
22054   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22055
22056   S (mp);
22057   W (ret);
22058   return ret;
22059 }
22060
22061 static int
22062 api_lldp_config (vat_main_t * vam)
22063 {
22064   unformat_input_t *i = vam->input;
22065   vl_api_lldp_config_t *mp;
22066   int tx_hold = 0;
22067   int tx_interval = 0;
22068   u8 *sys_name = NULL;
22069   int ret;
22070
22071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22072     {
22073       if (unformat (i, "system-name %s", &sys_name))
22074         ;
22075       else if (unformat (i, "tx-hold %d", &tx_hold))
22076         ;
22077       else if (unformat (i, "tx-interval %d", &tx_interval))
22078         ;
22079       else
22080         {
22081           clib_warning ("parse error '%U'", format_unformat_error, i);
22082           return -99;
22083         }
22084     }
22085
22086   vec_add1 (sys_name, 0);
22087
22088   M (LLDP_CONFIG, mp);
22089   mp->tx_hold = htonl (tx_hold);
22090   mp->tx_interval = htonl (tx_interval);
22091   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22092   vec_free (sys_name);
22093
22094   S (mp);
22095   W (ret);
22096   return ret;
22097 }
22098
22099 static int
22100 api_sw_interface_set_lldp (vat_main_t * vam)
22101 {
22102   unformat_input_t *i = vam->input;
22103   vl_api_sw_interface_set_lldp_t *mp;
22104   u32 sw_if_index = ~0;
22105   u32 enable = 1;
22106   u8 *port_desc = NULL, *mgmt_oid = NULL;
22107   ip4_address_t ip4_addr;
22108   ip6_address_t ip6_addr;
22109   int ret;
22110
22111   memset (&ip4_addr, 0, sizeof (ip4_addr));
22112   memset (&ip6_addr, 0, sizeof (ip6_addr));
22113
22114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22115     {
22116       if (unformat (i, "disable"))
22117         enable = 0;
22118       else
22119         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22120         ;
22121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22122         ;
22123       else if (unformat (i, "port-desc %s", &port_desc))
22124         ;
22125       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22126         ;
22127       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22128         ;
22129       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22130         ;
22131       else
22132         break;
22133     }
22134
22135   if (sw_if_index == ~0)
22136     {
22137       errmsg ("missing interface name or sw_if_index");
22138       return -99;
22139     }
22140
22141   /* Construct the API message */
22142   vec_add1 (port_desc, 0);
22143   vec_add1 (mgmt_oid, 0);
22144   M (SW_INTERFACE_SET_LLDP, mp);
22145   mp->sw_if_index = ntohl (sw_if_index);
22146   mp->enable = enable;
22147   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22148   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22149   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22150   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22151   vec_free (port_desc);
22152   vec_free (mgmt_oid);
22153
22154   S (mp);
22155   W (ret);
22156   return ret;
22157 }
22158
22159 static int
22160 api_tcp_configure_src_addresses (vat_main_t * vam)
22161 {
22162   vl_api_tcp_configure_src_addresses_t *mp;
22163   unformat_input_t *i = vam->input;
22164   ip4_address_t v4first, v4last;
22165   ip6_address_t v6first, v6last;
22166   u8 range_set = 0;
22167   u32 vrf_id = 0;
22168   int ret;
22169
22170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22171     {
22172       if (unformat (i, "%U - %U",
22173                     unformat_ip4_address, &v4first,
22174                     unformat_ip4_address, &v4last))
22175         {
22176           if (range_set)
22177             {
22178               errmsg ("one range per message (range already set)");
22179               return -99;
22180             }
22181           range_set = 1;
22182         }
22183       else if (unformat (i, "%U - %U",
22184                          unformat_ip6_address, &v6first,
22185                          unformat_ip6_address, &v6last))
22186         {
22187           if (range_set)
22188             {
22189               errmsg ("one range per message (range already set)");
22190               return -99;
22191             }
22192           range_set = 2;
22193         }
22194       else if (unformat (i, "vrf %d", &vrf_id))
22195         ;
22196       else
22197         break;
22198     }
22199
22200   if (range_set == 0)
22201     {
22202       errmsg ("address range not set");
22203       return -99;
22204     }
22205
22206   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22207   mp->vrf_id = ntohl (vrf_id);
22208   /* ipv6? */
22209   if (range_set == 2)
22210     {
22211       mp->is_ipv6 = 1;
22212       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22213       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22214     }
22215   else
22216     {
22217       mp->is_ipv6 = 0;
22218       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22219       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22220     }
22221   S (mp);
22222   W (ret);
22223   return ret;
22224 }
22225
22226 static void vl_api_app_namespace_add_del_reply_t_handler
22227   (vl_api_app_namespace_add_del_reply_t * mp)
22228 {
22229   vat_main_t *vam = &vat_main;
22230   i32 retval = ntohl (mp->retval);
22231   if (vam->async_mode)
22232     {
22233       vam->async_errors += (retval < 0);
22234     }
22235   else
22236     {
22237       vam->retval = retval;
22238       if (retval == 0)
22239         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22240       vam->result_ready = 1;
22241     }
22242 }
22243
22244 static void vl_api_app_namespace_add_del_reply_t_handler_json
22245   (vl_api_app_namespace_add_del_reply_t * mp)
22246 {
22247   vat_main_t *vam = &vat_main;
22248   vat_json_node_t node;
22249
22250   vat_json_init_object (&node);
22251   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22252   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22253
22254   vat_json_print (vam->ofp, &node);
22255   vat_json_free (&node);
22256
22257   vam->retval = ntohl (mp->retval);
22258   vam->result_ready = 1;
22259 }
22260
22261 static int
22262 api_app_namespace_add_del (vat_main_t * vam)
22263 {
22264   vl_api_app_namespace_add_del_t *mp;
22265   unformat_input_t *i = vam->input;
22266   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22267   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22268   u64 secret;
22269   int ret;
22270
22271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22272     {
22273       if (unformat (i, "id %_%v%_", &ns_id))
22274         ;
22275       else if (unformat (i, "secret %lu", &secret))
22276         secret_set = 1;
22277       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22278         sw_if_index_set = 1;
22279       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22280         ;
22281       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22282         ;
22283       else
22284         break;
22285     }
22286   if (!ns_id || !secret_set || !sw_if_index_set)
22287     {
22288       errmsg ("namespace id, secret and sw_if_index must be set");
22289       return -99;
22290     }
22291   if (vec_len (ns_id) > 64)
22292     {
22293       errmsg ("namespace id too long");
22294       return -99;
22295     }
22296   M (APP_NAMESPACE_ADD_DEL, mp);
22297
22298   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22299   mp->namespace_id_len = vec_len (ns_id);
22300   mp->secret = clib_host_to_net_u64 (secret);
22301   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22302   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22303   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22304   vec_free (ns_id);
22305   S (mp);
22306   W (ret);
22307   return ret;
22308 }
22309
22310 static int
22311 api_sock_init_shm (vat_main_t * vam)
22312 {
22313 #if VPP_API_TEST_BUILTIN == 0
22314   unformat_input_t *i = vam->input;
22315   vl_api_shm_elem_config_t *config = 0;
22316   u64 size = 64 << 20;
22317   int rv;
22318
22319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22320     {
22321       if (unformat (i, "size %U", unformat_memory_size, &size))
22322         ;
22323       else
22324         break;
22325     }
22326
22327   /*
22328    * Canned custom ring allocator config.
22329    * Should probably parse all of this
22330    */
22331   vec_validate (config, 6);
22332   config[0].type = VL_API_VLIB_RING;
22333   config[0].size = 256;
22334   config[0].count = 32;
22335
22336   config[1].type = VL_API_VLIB_RING;
22337   config[1].size = 1024;
22338   config[1].count = 16;
22339
22340   config[2].type = VL_API_VLIB_RING;
22341   config[2].size = 4096;
22342   config[2].count = 2;
22343
22344   config[3].type = VL_API_CLIENT_RING;
22345   config[3].size = 256;
22346   config[3].count = 32;
22347
22348   config[4].type = VL_API_CLIENT_RING;
22349   config[4].size = 1024;
22350   config[4].count = 16;
22351
22352   config[5].type = VL_API_CLIENT_RING;
22353   config[5].size = 4096;
22354   config[5].count = 2;
22355
22356   config[6].type = VL_API_QUEUE;
22357   config[6].count = 128;
22358   config[6].size = sizeof (uword);
22359
22360   rv = vl_socket_client_init_shm (config);
22361   if (!rv)
22362     vam->client_index_invalid = 1;
22363   return rv;
22364 #else
22365   return -99;
22366 #endif
22367 }
22368
22369 static int
22370 api_dns_enable_disable (vat_main_t * vam)
22371 {
22372   unformat_input_t *line_input = vam->input;
22373   vl_api_dns_enable_disable_t *mp;
22374   u8 enable_disable = 1;
22375   int ret;
22376
22377   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22378     {
22379       if (unformat (line_input, "disable"))
22380         enable_disable = 0;
22381       if (unformat (line_input, "enable"))
22382         enable_disable = 1;
22383       else
22384         break;
22385     }
22386
22387   /* Construct the API message */
22388   M (DNS_ENABLE_DISABLE, mp);
22389   mp->enable = enable_disable;
22390
22391   /* send it... */
22392   S (mp);
22393   /* Wait for the reply */
22394   W (ret);
22395   return ret;
22396 }
22397
22398 static int
22399 api_dns_resolve_name (vat_main_t * vam)
22400 {
22401   unformat_input_t *line_input = vam->input;
22402   vl_api_dns_resolve_name_t *mp;
22403   u8 *name = 0;
22404   int ret;
22405
22406   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22407     {
22408       if (unformat (line_input, "%s", &name))
22409         ;
22410       else
22411         break;
22412     }
22413
22414   if (vec_len (name) > 127)
22415     {
22416       errmsg ("name too long");
22417       return -99;
22418     }
22419
22420   /* Construct the API message */
22421   M (DNS_RESOLVE_NAME, mp);
22422   memcpy (mp->name, name, vec_len (name));
22423   vec_free (name);
22424
22425   /* send it... */
22426   S (mp);
22427   /* Wait for the reply */
22428   W (ret);
22429   return ret;
22430 }
22431
22432 static int
22433 api_dns_resolve_ip (vat_main_t * vam)
22434 {
22435   unformat_input_t *line_input = vam->input;
22436   vl_api_dns_resolve_ip_t *mp;
22437   int is_ip6 = -1;
22438   ip4_address_t addr4;
22439   ip6_address_t addr6;
22440   int ret;
22441
22442   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22443     {
22444       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22445         is_ip6 = 1;
22446       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22447         is_ip6 = 0;
22448       else
22449         break;
22450     }
22451
22452   if (is_ip6 == -1)
22453     {
22454       errmsg ("missing address");
22455       return -99;
22456     }
22457
22458   /* Construct the API message */
22459   M (DNS_RESOLVE_IP, mp);
22460   mp->is_ip6 = is_ip6;
22461   if (is_ip6)
22462     memcpy (mp->address, &addr6, sizeof (addr6));
22463   else
22464     memcpy (mp->address, &addr4, sizeof (addr4));
22465
22466   /* send it... */
22467   S (mp);
22468   /* Wait for the reply */
22469   W (ret);
22470   return ret;
22471 }
22472
22473 static int
22474 api_dns_name_server_add_del (vat_main_t * vam)
22475 {
22476   unformat_input_t *i = vam->input;
22477   vl_api_dns_name_server_add_del_t *mp;
22478   u8 is_add = 1;
22479   ip6_address_t ip6_server;
22480   ip4_address_t ip4_server;
22481   int ip6_set = 0;
22482   int ip4_set = 0;
22483   int ret = 0;
22484
22485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22486     {
22487       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22488         ip6_set = 1;
22489       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22490         ip4_set = 1;
22491       else if (unformat (i, "del"))
22492         is_add = 0;
22493       else
22494         {
22495           clib_warning ("parse error '%U'", format_unformat_error, i);
22496           return -99;
22497         }
22498     }
22499
22500   if (ip4_set && ip6_set)
22501     {
22502       errmsg ("Only one server address allowed per message");
22503       return -99;
22504     }
22505   if ((ip4_set + ip6_set) == 0)
22506     {
22507       errmsg ("Server address required");
22508       return -99;
22509     }
22510
22511   /* Construct the API message */
22512   M (DNS_NAME_SERVER_ADD_DEL, mp);
22513
22514   if (ip6_set)
22515     {
22516       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22517       mp->is_ip6 = 1;
22518     }
22519   else
22520     {
22521       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22522       mp->is_ip6 = 0;
22523     }
22524
22525   mp->is_add = is_add;
22526
22527   /* send it... */
22528   S (mp);
22529
22530   /* Wait for a reply, return good/bad news  */
22531   W (ret);
22532   return ret;
22533 }
22534
22535 static void
22536 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22537 {
22538   vat_main_t *vam = &vat_main;
22539
22540   if (mp->is_ip4)
22541     {
22542       print (vam->ofp,
22543              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22544              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22545              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22546              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22547              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22548              clib_net_to_host_u32 (mp->action_index), mp->tag);
22549     }
22550   else
22551     {
22552       print (vam->ofp,
22553              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22554              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22555              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22556              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22557              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22558              clib_net_to_host_u32 (mp->action_index), mp->tag);
22559     }
22560 }
22561
22562 static void
22563 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22564                                              mp)
22565 {
22566   vat_main_t *vam = &vat_main;
22567   vat_json_node_t *node = NULL;
22568   struct in6_addr ip6;
22569   struct in_addr ip4;
22570
22571   if (VAT_JSON_ARRAY != vam->json_tree.type)
22572     {
22573       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22574       vat_json_init_array (&vam->json_tree);
22575     }
22576   node = vat_json_array_add (&vam->json_tree);
22577   vat_json_init_object (node);
22578
22579   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22580   vat_json_object_add_uint (node, "appns_index",
22581                             clib_net_to_host_u32 (mp->appns_index));
22582   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22583   vat_json_object_add_uint (node, "scope", mp->scope);
22584   vat_json_object_add_uint (node, "action_index",
22585                             clib_net_to_host_u32 (mp->action_index));
22586   vat_json_object_add_uint (node, "lcl_port",
22587                             clib_net_to_host_u16 (mp->lcl_port));
22588   vat_json_object_add_uint (node, "rmt_port",
22589                             clib_net_to_host_u16 (mp->rmt_port));
22590   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22591   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22592   vat_json_object_add_string_copy (node, "tag", mp->tag);
22593   if (mp->is_ip4)
22594     {
22595       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22596       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22597       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22598       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22599     }
22600   else
22601     {
22602       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22603       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22604       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22605       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22606     }
22607 }
22608
22609 static int
22610 api_session_rule_add_del (vat_main_t * vam)
22611 {
22612   vl_api_session_rule_add_del_t *mp;
22613   unformat_input_t *i = vam->input;
22614   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22615   u32 appns_index = 0, scope = 0;
22616   ip4_address_t lcl_ip4, rmt_ip4;
22617   ip6_address_t lcl_ip6, rmt_ip6;
22618   u8 is_ip4 = 1, conn_set = 0;
22619   u8 is_add = 1, *tag = 0;
22620   int ret;
22621
22622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22623     {
22624       if (unformat (i, "del"))
22625         is_add = 0;
22626       else if (unformat (i, "add"))
22627         ;
22628       else if (unformat (i, "proto tcp"))
22629         proto = 0;
22630       else if (unformat (i, "proto udp"))
22631         proto = 1;
22632       else if (unformat (i, "appns %d", &appns_index))
22633         ;
22634       else if (unformat (i, "scope %d", &scope))
22635         ;
22636       else if (unformat (i, "tag %_%v%_", &tag))
22637         ;
22638       else
22639         if (unformat
22640             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22641              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22642              &rmt_port))
22643         {
22644           is_ip4 = 1;
22645           conn_set = 1;
22646         }
22647       else
22648         if (unformat
22649             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22650              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22651              &rmt_port))
22652         {
22653           is_ip4 = 0;
22654           conn_set = 1;
22655         }
22656       else if (unformat (i, "action %d", &action))
22657         ;
22658       else
22659         break;
22660     }
22661   if (proto == ~0 || !conn_set || action == ~0)
22662     {
22663       errmsg ("transport proto, connection and action must be set");
22664       return -99;
22665     }
22666
22667   if (scope > 3)
22668     {
22669       errmsg ("scope should be 0-3");
22670       return -99;
22671     }
22672
22673   M (SESSION_RULE_ADD_DEL, mp);
22674
22675   mp->is_ip4 = is_ip4;
22676   mp->transport_proto = proto;
22677   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22678   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22679   mp->lcl_plen = lcl_plen;
22680   mp->rmt_plen = rmt_plen;
22681   mp->action_index = clib_host_to_net_u32 (action);
22682   mp->appns_index = clib_host_to_net_u32 (appns_index);
22683   mp->scope = scope;
22684   mp->is_add = is_add;
22685   if (is_ip4)
22686     {
22687       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22688       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22689     }
22690   else
22691     {
22692       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22693       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22694     }
22695   if (tag)
22696     {
22697       clib_memcpy (mp->tag, tag, vec_len (tag));
22698       vec_free (tag);
22699     }
22700
22701   S (mp);
22702   W (ret);
22703   return ret;
22704 }
22705
22706 static int
22707 api_session_rules_dump (vat_main_t * vam)
22708 {
22709   vl_api_session_rules_dump_t *mp;
22710   vl_api_control_ping_t *mp_ping;
22711   int ret;
22712
22713   if (!vam->json_output)
22714     {
22715       print (vam->ofp, "%=20s", "Session Rules");
22716     }
22717
22718   M (SESSION_RULES_DUMP, mp);
22719   /* send it... */
22720   S (mp);
22721
22722   /* Use a control ping for synchronization */
22723   MPING (CONTROL_PING, mp_ping);
22724   S (mp_ping);
22725
22726   /* Wait for a reply... */
22727   W (ret);
22728   return ret;
22729 }
22730
22731 static int
22732 api_ip_container_proxy_add_del (vat_main_t * vam)
22733 {
22734   vl_api_ip_container_proxy_add_del_t *mp;
22735   unformat_input_t *i = vam->input;
22736   u32 plen = ~0, sw_if_index = ~0;
22737   ip4_address_t ip4;
22738   ip6_address_t ip6;
22739   u8 is_ip4 = 1;
22740   u8 is_add = 1;
22741   int ret;
22742
22743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22744     {
22745       if (unformat (i, "del"))
22746         is_add = 0;
22747       else if (unformat (i, "add"))
22748         ;
22749       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22750         {
22751           is_ip4 = 1;
22752           plen = 32;
22753         }
22754       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22755         {
22756           is_ip4 = 0;
22757           plen = 128;
22758         }
22759       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22760         ;
22761       else
22762         break;
22763     }
22764   if (sw_if_index == ~0 || plen == ~0)
22765     {
22766       errmsg ("address and sw_if_index must be set");
22767       return -99;
22768     }
22769
22770   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22771
22772   mp->is_ip4 = is_ip4;
22773   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22774   mp->plen = plen;
22775   mp->is_add = is_add;
22776   if (is_ip4)
22777     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22778   else
22779     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22780
22781   S (mp);
22782   W (ret);
22783   return ret;
22784 }
22785
22786 static int
22787 api_qos_record_enable_disable (vat_main_t * vam)
22788 {
22789   unformat_input_t *i = vam->input;
22790   vl_api_qos_record_enable_disable_t *mp;
22791   u32 sw_if_index, qs = 0xff;
22792   u8 sw_if_index_set = 0;
22793   u8 enable = 1;
22794   int ret;
22795
22796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22797     {
22798       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22799         sw_if_index_set = 1;
22800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22801         sw_if_index_set = 1;
22802       else if (unformat (i, "%U", unformat_qos_source, &qs))
22803         ;
22804       else if (unformat (i, "disable"))
22805         enable = 0;
22806       else
22807         {
22808           clib_warning ("parse error '%U'", format_unformat_error, i);
22809           return -99;
22810         }
22811     }
22812
22813   if (sw_if_index_set == 0)
22814     {
22815       errmsg ("missing interface name or sw_if_index");
22816       return -99;
22817     }
22818   if (qs == 0xff)
22819     {
22820       errmsg ("input location must be specified");
22821       return -99;
22822     }
22823
22824   M (QOS_RECORD_ENABLE_DISABLE, mp);
22825
22826   mp->sw_if_index = ntohl (sw_if_index);
22827   mp->input_source = qs;
22828   mp->enable = enable;
22829
22830   S (mp);
22831   W (ret);
22832   return ret;
22833 }
22834
22835 static int
22836 q_or_quit (vat_main_t * vam)
22837 {
22838 #if VPP_API_TEST_BUILTIN == 0
22839   longjmp (vam->jump_buf, 1);
22840 #endif
22841   return 0;                     /* not so much */
22842 }
22843
22844 static int
22845 q (vat_main_t * vam)
22846 {
22847   return q_or_quit (vam);
22848 }
22849
22850 static int
22851 quit (vat_main_t * vam)
22852 {
22853   return q_or_quit (vam);
22854 }
22855
22856 static int
22857 comment (vat_main_t * vam)
22858 {
22859   return 0;
22860 }
22861
22862 static int
22863 cmd_cmp (void *a1, void *a2)
22864 {
22865   u8 **c1 = a1;
22866   u8 **c2 = a2;
22867
22868   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22869 }
22870
22871 static int
22872 help (vat_main_t * vam)
22873 {
22874   u8 **cmds = 0;
22875   u8 *name = 0;
22876   hash_pair_t *p;
22877   unformat_input_t *i = vam->input;
22878   int j;
22879
22880   if (unformat (i, "%s", &name))
22881     {
22882       uword *hs;
22883
22884       vec_add1 (name, 0);
22885
22886       hs = hash_get_mem (vam->help_by_name, name);
22887       if (hs)
22888         print (vam->ofp, "usage: %s %s", name, hs[0]);
22889       else
22890         print (vam->ofp, "No such msg / command '%s'", name);
22891       vec_free (name);
22892       return 0;
22893     }
22894
22895   print (vam->ofp, "Help is available for the following:");
22896
22897     /* *INDENT-OFF* */
22898     hash_foreach_pair (p, vam->function_by_name,
22899     ({
22900       vec_add1 (cmds, (u8 *)(p->key));
22901     }));
22902     /* *INDENT-ON* */
22903
22904   vec_sort_with_function (cmds, cmd_cmp);
22905
22906   for (j = 0; j < vec_len (cmds); j++)
22907     print (vam->ofp, "%s", cmds[j]);
22908
22909   vec_free (cmds);
22910   return 0;
22911 }
22912
22913 static int
22914 set (vat_main_t * vam)
22915 {
22916   u8 *name = 0, *value = 0;
22917   unformat_input_t *i = vam->input;
22918
22919   if (unformat (i, "%s", &name))
22920     {
22921       /* The input buffer is a vector, not a string. */
22922       value = vec_dup (i->buffer);
22923       vec_delete (value, i->index, 0);
22924       /* Almost certainly has a trailing newline */
22925       if (value[vec_len (value) - 1] == '\n')
22926         value[vec_len (value) - 1] = 0;
22927       /* Make sure it's a proper string, one way or the other */
22928       vec_add1 (value, 0);
22929       (void) clib_macro_set_value (&vam->macro_main,
22930                                    (char *) name, (char *) value);
22931     }
22932   else
22933     errmsg ("usage: set <name> <value>");
22934
22935   vec_free (name);
22936   vec_free (value);
22937   return 0;
22938 }
22939
22940 static int
22941 unset (vat_main_t * vam)
22942 {
22943   u8 *name = 0;
22944
22945   if (unformat (vam->input, "%s", &name))
22946     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22947       errmsg ("unset: %s wasn't set", name);
22948   vec_free (name);
22949   return 0;
22950 }
22951
22952 typedef struct
22953 {
22954   u8 *name;
22955   u8 *value;
22956 } macro_sort_t;
22957
22958
22959 static int
22960 macro_sort_cmp (void *a1, void *a2)
22961 {
22962   macro_sort_t *s1 = a1;
22963   macro_sort_t *s2 = a2;
22964
22965   return strcmp ((char *) (s1->name), (char *) (s2->name));
22966 }
22967
22968 static int
22969 dump_macro_table (vat_main_t * vam)
22970 {
22971   macro_sort_t *sort_me = 0, *sm;
22972   int i;
22973   hash_pair_t *p;
22974
22975     /* *INDENT-OFF* */
22976     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22977     ({
22978       vec_add2 (sort_me, sm, 1);
22979       sm->name = (u8 *)(p->key);
22980       sm->value = (u8 *) (p->value[0]);
22981     }));
22982     /* *INDENT-ON* */
22983
22984   vec_sort_with_function (sort_me, macro_sort_cmp);
22985
22986   if (vec_len (sort_me))
22987     print (vam->ofp, "%-15s%s", "Name", "Value");
22988   else
22989     print (vam->ofp, "The macro table is empty...");
22990
22991   for (i = 0; i < vec_len (sort_me); i++)
22992     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22993   return 0;
22994 }
22995
22996 static int
22997 dump_node_table (vat_main_t * vam)
22998 {
22999   int i, j;
23000   vlib_node_t *node, *next_node;
23001
23002   if (vec_len (vam->graph_nodes) == 0)
23003     {
23004       print (vam->ofp, "Node table empty, issue get_node_graph...");
23005       return 0;
23006     }
23007
23008   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23009     {
23010       node = vam->graph_nodes[i];
23011       print (vam->ofp, "[%d] %s", i, node->name);
23012       for (j = 0; j < vec_len (node->next_nodes); j++)
23013         {
23014           if (node->next_nodes[j] != ~0)
23015             {
23016               next_node = vam->graph_nodes[node->next_nodes[j]];
23017               print (vam->ofp, "  [%d] %s", j, next_node->name);
23018             }
23019         }
23020     }
23021   return 0;
23022 }
23023
23024 static int
23025 value_sort_cmp (void *a1, void *a2)
23026 {
23027   name_sort_t *n1 = a1;
23028   name_sort_t *n2 = a2;
23029
23030   if (n1->value < n2->value)
23031     return -1;
23032   if (n1->value > n2->value)
23033     return 1;
23034   return 0;
23035 }
23036
23037
23038 static int
23039 dump_msg_api_table (vat_main_t * vam)
23040 {
23041   api_main_t *am = &api_main;
23042   name_sort_t *nses = 0, *ns;
23043   hash_pair_t *hp;
23044   int i;
23045
23046   /* *INDENT-OFF* */
23047   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23048   ({
23049     vec_add2 (nses, ns, 1);
23050     ns->name = (u8 *)(hp->key);
23051     ns->value = (u32) hp->value[0];
23052   }));
23053   /* *INDENT-ON* */
23054
23055   vec_sort_with_function (nses, value_sort_cmp);
23056
23057   for (i = 0; i < vec_len (nses); i++)
23058     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23059   vec_free (nses);
23060   return 0;
23061 }
23062
23063 static int
23064 get_msg_id (vat_main_t * vam)
23065 {
23066   u8 *name_and_crc;
23067   u32 message_index;
23068
23069   if (unformat (vam->input, "%s", &name_and_crc))
23070     {
23071       message_index = vl_msg_api_get_msg_index (name_and_crc);
23072       if (message_index == ~0)
23073         {
23074           print (vam->ofp, " '%s' not found", name_and_crc);
23075           return 0;
23076         }
23077       print (vam->ofp, " '%s' has message index %d",
23078              name_and_crc, message_index);
23079       return 0;
23080     }
23081   errmsg ("name_and_crc required...");
23082   return 0;
23083 }
23084
23085 static int
23086 search_node_table (vat_main_t * vam)
23087 {
23088   unformat_input_t *line_input = vam->input;
23089   u8 *node_to_find;
23090   int j;
23091   vlib_node_t *node, *next_node;
23092   uword *p;
23093
23094   if (vam->graph_node_index_by_name == 0)
23095     {
23096       print (vam->ofp, "Node table empty, issue get_node_graph...");
23097       return 0;
23098     }
23099
23100   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23101     {
23102       if (unformat (line_input, "%s", &node_to_find))
23103         {
23104           vec_add1 (node_to_find, 0);
23105           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23106           if (p == 0)
23107             {
23108               print (vam->ofp, "%s not found...", node_to_find);
23109               goto out;
23110             }
23111           node = vam->graph_nodes[p[0]];
23112           print (vam->ofp, "[%d] %s", p[0], node->name);
23113           for (j = 0; j < vec_len (node->next_nodes); j++)
23114             {
23115               if (node->next_nodes[j] != ~0)
23116                 {
23117                   next_node = vam->graph_nodes[node->next_nodes[j]];
23118                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23119                 }
23120             }
23121         }
23122
23123       else
23124         {
23125           clib_warning ("parse error '%U'", format_unformat_error,
23126                         line_input);
23127           return -99;
23128         }
23129
23130     out:
23131       vec_free (node_to_find);
23132
23133     }
23134
23135   return 0;
23136 }
23137
23138
23139 static int
23140 script (vat_main_t * vam)
23141 {
23142 #if (VPP_API_TEST_BUILTIN==0)
23143   u8 *s = 0;
23144   char *save_current_file;
23145   unformat_input_t save_input;
23146   jmp_buf save_jump_buf;
23147   u32 save_line_number;
23148
23149   FILE *new_fp, *save_ifp;
23150
23151   if (unformat (vam->input, "%s", &s))
23152     {
23153       new_fp = fopen ((char *) s, "r");
23154       if (new_fp == 0)
23155         {
23156           errmsg ("Couldn't open script file %s", s);
23157           vec_free (s);
23158           return -99;
23159         }
23160     }
23161   else
23162     {
23163       errmsg ("Missing script name");
23164       return -99;
23165     }
23166
23167   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23168   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23169   save_ifp = vam->ifp;
23170   save_line_number = vam->input_line_number;
23171   save_current_file = (char *) vam->current_file;
23172
23173   vam->input_line_number = 0;
23174   vam->ifp = new_fp;
23175   vam->current_file = s;
23176   do_one_file (vam);
23177
23178   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
23179   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23180   vam->ifp = save_ifp;
23181   vam->input_line_number = save_line_number;
23182   vam->current_file = (u8 *) save_current_file;
23183   vec_free (s);
23184
23185   return 0;
23186 #else
23187   clib_warning ("use the exec command...");
23188   return -99;
23189 #endif
23190 }
23191
23192 static int
23193 echo (vat_main_t * vam)
23194 {
23195   print (vam->ofp, "%v", vam->input->buffer);
23196   return 0;
23197 }
23198
23199 /* List of API message constructors, CLI names map to api_xxx */
23200 #define foreach_vpe_api_msg                                             \
23201 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23202 _(sw_interface_dump,"")                                                 \
23203 _(sw_interface_set_flags,                                               \
23204   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23205 _(sw_interface_add_del_address,                                         \
23206   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23207 _(sw_interface_set_rx_mode,                                             \
23208   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23209 _(sw_interface_set_table,                                               \
23210   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23211 _(sw_interface_set_mpls_enable,                                         \
23212   "<intfc> | sw_if_index [disable | dis]")                              \
23213 _(sw_interface_set_vpath,                                               \
23214   "<intfc> | sw_if_index <id> enable | disable")                        \
23215 _(sw_interface_set_vxlan_bypass,                                        \
23216   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23217 _(sw_interface_set_geneve_bypass,                                       \
23218   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23219 _(sw_interface_set_l2_xconnect,                                         \
23220   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23221   "enable | disable")                                                   \
23222 _(sw_interface_set_l2_bridge,                                           \
23223   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23224   "[shg <split-horizon-group>] [bvi]\n"                                 \
23225   "enable | disable")                                                   \
23226 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23227 _(bridge_domain_add_del,                                                \
23228   "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") \
23229 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23230 _(l2fib_add_del,                                                        \
23231   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23232 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23233 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23234 _(l2_flags,                                                             \
23235   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23236 _(bridge_flags,                                                         \
23237   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23238 _(tap_connect,                                                          \
23239   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23240 _(tap_modify,                                                           \
23241   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23242 _(tap_delete,                                                           \
23243   "<vpp-if-name> | sw_if_index <id>")                                   \
23244 _(sw_interface_tap_dump, "")                                            \
23245 _(tap_create_v2,                                                        \
23246   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23247 _(tap_delete_v2,                                                        \
23248   "<vpp-if-name> | sw_if_index <id>")                                   \
23249 _(sw_interface_tap_v2_dump, "")                                         \
23250 _(bond_create,                                                          \
23251   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23252   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23253 _(bond_delete,                                                          \
23254   "<vpp-if-name> | sw_if_index <id>")                                   \
23255 _(bond_enslave,                                                         \
23256   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23257 _(bond_detach_slave,                                                    \
23258   "sw_if_index <n>")                                                    \
23259 _(sw_interface_bond_dump, "")                                           \
23260 _(sw_interface_slave_dump,                                              \
23261   "<vpp-if-name> | sw_if_index <id>")                                   \
23262 _(ip_table_add_del,                                                     \
23263   "table-id <n> [ipv6]\n")                                              \
23264 _(ip_add_del_route,                                                     \
23265   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23266   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23267   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23268   "[multipath] [count <n>]")                                            \
23269 _(ip_mroute_add_del,                                                    \
23270   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23271   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23272 _(mpls_table_add_del,                                                   \
23273   "table-id <n>\n")                                                     \
23274 _(mpls_route_add_del,                                                   \
23275   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23276   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23277   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23278   "[multipath] [count <n>]")                                            \
23279 _(mpls_ip_bind_unbind,                                                  \
23280   "<label> <addr/len>")                                                 \
23281 _(mpls_tunnel_add_del,                                                  \
23282   " via <addr> [table-id <n>]\n"                                        \
23283   "sw_if_index <id>] [l2]  [del]")                                      \
23284 _(bier_table_add_del,                                                   \
23285   "<label> <sub-domain> <set> <bsl> [del]")                             \
23286 _(bier_route_add_del,                                                   \
23287   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23288   "[<intfc> | sw_if_index <id>]"                                        \
23289   "[weight <n>] [del] [multipath]")                                     \
23290 _(proxy_arp_add_del,                                                    \
23291   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23292 _(proxy_arp_intfc_enable_disable,                                       \
23293   "<intfc> | sw_if_index <id> enable | disable")                        \
23294 _(sw_interface_set_unnumbered,                                          \
23295   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23296 _(ip_neighbor_add_del,                                                  \
23297   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23298   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23299 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23300 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23301   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23302   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23303   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23304 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23305 _(reset_fib, "vrf <n> [ipv6]")                                          \
23306 _(dhcp_proxy_config,                                                    \
23307   "svr <v46-address> src <v46-address>\n"                               \
23308    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23309 _(dhcp_proxy_set_vss,                                                   \
23310   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23311 _(dhcp_proxy_dump, "ip6")                                               \
23312 _(dhcp_client_config,                                                   \
23313   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23314 _(set_ip_flow_hash,                                                     \
23315   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23316 _(sw_interface_ip6_enable_disable,                                      \
23317   "<intfc> | sw_if_index <id> enable | disable")                        \
23318 _(sw_interface_ip6_set_link_local_address,                              \
23319   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23320 _(ip6nd_proxy_add_del,                                                  \
23321   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23322 _(ip6nd_proxy_dump, "")                                                 \
23323 _(sw_interface_ip6nd_ra_prefix,                                         \
23324   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23325   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23326   "[nolink] [isno]")                                                    \
23327 _(sw_interface_ip6nd_ra_config,                                         \
23328   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23329   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23330   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23331 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23332 _(l2_patch_add_del,                                                     \
23333   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23334   "enable | disable")                                                   \
23335 _(sr_localsid_add_del,                                                  \
23336   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23337   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23338 _(classify_add_del_table,                                               \
23339   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23340   " [del] [del-chain] mask <mask-value>\n"                              \
23341   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23342   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23343 _(classify_add_del_session,                                             \
23344   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23345   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23346   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23347   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23348 _(classify_set_interface_ip_table,                                      \
23349   "<intfc> | sw_if_index <nn> table <nn>")                              \
23350 _(classify_set_interface_l2_tables,                                     \
23351   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23352   "  [other-table <nn>]")                                               \
23353 _(get_node_index, "node <node-name")                                    \
23354 _(add_node_next, "node <node-name> next <next-node-name>")              \
23355 _(l2tpv3_create_tunnel,                                                 \
23356   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23357   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23358   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23359 _(l2tpv3_set_tunnel_cookies,                                            \
23360   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23361   "[new_remote_cookie <nn>]\n")                                         \
23362 _(l2tpv3_interface_enable_disable,                                      \
23363   "<intfc> | sw_if_index <nn> enable | disable")                        \
23364 _(l2tpv3_set_lookup_key,                                                \
23365   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23366 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23367 _(vxlan_add_del_tunnel,                                                 \
23368   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23369   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23370   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23371 _(geneve_add_del_tunnel,                                                \
23372   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23373   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23374   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23375 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23376 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23377 _(gre_add_del_tunnel,                                                   \
23378   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23379   "[teb | erspan <session-id>] [del]")                                  \
23380 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23381 _(l2_fib_clear_table, "")                                               \
23382 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23383 _(l2_interface_vlan_tag_rewrite,                                        \
23384   "<intfc> | sw_if_index <nn> \n"                                       \
23385   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23386   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23387 _(create_vhost_user_if,                                                 \
23388         "socket <filename> [server] [renumber <dev_instance>] "         \
23389         "[mac <mac_address>]")                                          \
23390 _(modify_vhost_user_if,                                                 \
23391         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23392         "[server] [renumber <dev_instance>]")                           \
23393 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23394 _(sw_interface_vhost_user_dump, "")                                     \
23395 _(show_version, "")                                                     \
23396 _(vxlan_gpe_add_del_tunnel,                                             \
23397   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23398   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23399   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23400   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23401 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23402 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23403 _(interface_name_renumber,                                              \
23404   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23405 _(input_acl_set_interface,                                              \
23406   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23407   "  [l2-table <nn>] [del]")                                            \
23408 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23409 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23410 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23411 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23412 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23413 _(ip_dump, "ipv4 | ipv6")                                               \
23414 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23415 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23416   "  spid_id <n> ")                                                     \
23417 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23418   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23419   "  integ_alg <alg> integ_key <hex>")                                  \
23420 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23421   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23422   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23423   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23424 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23425 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23426   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23427   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23428   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23429   "  [instance <n>]")     \
23430 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23431 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23432   "  <alg> <hex>\n")                                                    \
23433 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23434 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23435 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23436   "(auth_data 0x<data> | auth_data <data>)")                            \
23437 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23438   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23439 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23440   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23441   "(local|remote)")                                                     \
23442 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23443 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23444 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23445 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23446 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23447 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23448 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23449 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23450 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23451 _(delete_loopback,"sw_if_index <nn>")                                   \
23452 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23453 _(map_add_domain,                                                       \
23454   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23455   "ip6-src <ip6addr> "                                                  \
23456   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23457 _(map_del_domain, "index <n>")                                          \
23458 _(map_add_del_rule,                                                     \
23459   "index <n> psid <n> dst <ip6addr> [del]")                             \
23460 _(map_domain_dump, "")                                                  \
23461 _(map_rule_dump, "index <map-domain>")                                  \
23462 _(want_interface_events,  "enable|disable")                             \
23463 _(want_stats,"enable|disable")                                          \
23464 _(get_first_msg_id, "client <name>")                                    \
23465 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23466 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23467   "fib-id <nn> [ip4][ip6][default]")                                    \
23468 _(get_node_graph, " ")                                                  \
23469 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23470 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23471 _(ioam_disable, "")                                                     \
23472 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23473                             " sw_if_index <sw_if_index> p <priority> "  \
23474                             "w <weight>] [del]")                        \
23475 _(one_add_del_locator, "locator-set <locator_name> "                    \
23476                         "iface <intf> | sw_if_index <sw_if_index> "     \
23477                         "p <priority> w <weight> [del]")                \
23478 _(one_add_del_local_eid,"vni <vni> eid "                                \
23479                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23480                          "locator-set <locator_name> [del]"             \
23481                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23482 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23483 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23484 _(one_enable_disable, "enable|disable")                                 \
23485 _(one_map_register_enable_disable, "enable|disable")                    \
23486 _(one_map_register_fallback_threshold, "<value>")                       \
23487 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23488 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23489                                "[seid <seid>] "                         \
23490                                "rloc <locator> p <prio> "               \
23491                                "w <weight> [rloc <loc> ... ] "          \
23492                                "action <action> [del-all]")             \
23493 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23494                           "<local-eid>")                                \
23495 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23496 _(one_use_petr, "ip-address> | disable")                                \
23497 _(one_map_request_mode, "src-dst|dst-only")                             \
23498 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23499 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23500 _(one_locator_set_dump, "[local | remote]")                             \
23501 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23502 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23503                        "[local] | [remote]")                            \
23504 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23505 _(one_ndp_bd_get, "")                                                   \
23506 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23507 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23508 _(one_l2_arp_bd_get, "")                                                \
23509 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23510 _(one_stats_enable_disable, "enable|disalbe")                           \
23511 _(show_one_stats_enable_disable, "")                                    \
23512 _(one_eid_table_vni_dump, "")                                           \
23513 _(one_eid_table_map_dump, "l2|l3")                                      \
23514 _(one_map_resolver_dump, "")                                            \
23515 _(one_map_server_dump, "")                                              \
23516 _(one_adjacencies_get, "vni <vni>")                                     \
23517 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23518 _(show_one_rloc_probe_state, "")                                        \
23519 _(show_one_map_register_state, "")                                      \
23520 _(show_one_status, "")                                                  \
23521 _(one_stats_dump, "")                                                   \
23522 _(one_stats_flush, "")                                                  \
23523 _(one_get_map_request_itr_rlocs, "")                                    \
23524 _(one_map_register_set_ttl, "<ttl>")                                    \
23525 _(one_set_transport_protocol, "udp|api")                                \
23526 _(one_get_transport_protocol, "")                                       \
23527 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23528 _(one_show_xtr_mode, "")                                                \
23529 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23530 _(one_show_pitr_mode, "")                                               \
23531 _(one_enable_disable_petr_mode, "enable|disable")                       \
23532 _(one_show_petr_mode, "")                                               \
23533 _(show_one_nsh_mapping, "")                                             \
23534 _(show_one_pitr, "")                                                    \
23535 _(show_one_use_petr, "")                                                \
23536 _(show_one_map_request_mode, "")                                        \
23537 _(show_one_map_register_ttl, "")                                        \
23538 _(show_one_map_register_fallback_threshold, "")                         \
23539 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23540                             " sw_if_index <sw_if_index> p <priority> "  \
23541                             "w <weight>] [del]")                        \
23542 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23543                         "iface <intf> | sw_if_index <sw_if_index> "     \
23544                         "p <priority> w <weight> [del]")                \
23545 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23546                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23547                          "locator-set <locator_name> [del]"             \
23548                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23549 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23550 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23551 _(lisp_enable_disable, "enable|disable")                                \
23552 _(lisp_map_register_enable_disable, "enable|disable")                   \
23553 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23554 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23555                                "[seid <seid>] "                         \
23556                                "rloc <locator> p <prio> "               \
23557                                "w <weight> [rloc <loc> ... ] "          \
23558                                "action <action> [del-all]")             \
23559 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23560                           "<local-eid>")                                \
23561 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23562 _(lisp_use_petr, "<ip-address> | disable")                              \
23563 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23564 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23565 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23566 _(lisp_locator_set_dump, "[local | remote]")                            \
23567 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23568 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23569                        "[local] | [remote]")                            \
23570 _(lisp_eid_table_vni_dump, "")                                          \
23571 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23572 _(lisp_map_resolver_dump, "")                                           \
23573 _(lisp_map_server_dump, "")                                             \
23574 _(lisp_adjacencies_get, "vni <vni>")                                    \
23575 _(gpe_fwd_entry_vnis_get, "")                                           \
23576 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23577 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23578                                 "[table <table-id>]")                   \
23579 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23580 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23581 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23582 _(gpe_get_encap_mode, "")                                               \
23583 _(lisp_gpe_add_del_iface, "up|down")                                    \
23584 _(lisp_gpe_enable_disable, "enable|disable")                            \
23585 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23586   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23587 _(show_lisp_rloc_probe_state, "")                                       \
23588 _(show_lisp_map_register_state, "")                                     \
23589 _(show_lisp_status, "")                                                 \
23590 _(lisp_get_map_request_itr_rlocs, "")                                   \
23591 _(show_lisp_pitr, "")                                                   \
23592 _(show_lisp_use_petr, "")                                               \
23593 _(show_lisp_map_request_mode, "")                                       \
23594 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23595 _(af_packet_delete, "name <host interface name>")                       \
23596 _(policer_add_del, "name <policer name> <params> [del]")                \
23597 _(policer_dump, "[name <policer name>]")                                \
23598 _(policer_classify_set_interface,                                       \
23599   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23600   "  [l2-table <nn>] [del]")                                            \
23601 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23602 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23603     "[master|slave]")                                                   \
23604 _(netmap_delete, "name <interface name>")                               \
23605 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23606 _(mpls_fib_dump, "")                                                    \
23607 _(classify_table_ids, "")                                               \
23608 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23609 _(classify_table_info, "table_id <nn>")                                 \
23610 _(classify_session_dump, "table_id <nn>")                               \
23611 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23612     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23613     "[template_interval <nn>] [udp_checksum]")                          \
23614 _(ipfix_exporter_dump, "")                                              \
23615 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23616 _(ipfix_classify_stream_dump, "")                                       \
23617 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23618 _(ipfix_classify_table_dump, "")                                        \
23619 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23620 _(sw_interface_span_dump, "[l2]")                                           \
23621 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23622 _(pg_create_interface, "if_id <nn>")                                    \
23623 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23624 _(pg_enable_disable, "[stream <id>] disable")                           \
23625 _(ip_source_and_port_range_check_add_del,                               \
23626   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23627 _(ip_source_and_port_range_check_interface_add_del,                     \
23628   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23629   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23630 _(ipsec_gre_add_del_tunnel,                                             \
23631   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23632 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23633 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23634 _(l2_interface_pbb_tag_rewrite,                                         \
23635   "<intfc> | sw_if_index <nn> \n"                                       \
23636   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23637   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23638 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23639 _(flow_classify_set_interface,                                          \
23640   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23641 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23642 _(ip_fib_dump, "")                                                      \
23643 _(ip_mfib_dump, "")                                                     \
23644 _(ip6_fib_dump, "")                                                     \
23645 _(ip6_mfib_dump, "")                                                    \
23646 _(feature_enable_disable, "arc_name <arc_name> "                        \
23647   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23648 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23649 "[disable]")                                                            \
23650 _(l2_xconnect_dump, "")                                                 \
23651 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23652 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23653 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23654 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23655 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23656 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23657 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23658   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23659 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23660 _(sock_init_shm, "size <nnn>")                                          \
23661 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23662 _(dns_enable_disable, "[enable][disable]")                              \
23663 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23664 _(dns_resolve_name, "<hostname>")                                       \
23665 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23666 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23667 _(dns_resolve_name, "<hostname>")                                       \
23668 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23669   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23670 _(session_rules_dump, "")                                               \
23671 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23672 _(output_acl_set_interface,                                             \
23673   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23674   "  [l2-table <nn>] [del]")                                            \
23675 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23676
23677 /* List of command functions, CLI names map directly to functions */
23678 #define foreach_cli_function                                    \
23679 _(comment, "usage: comment <ignore-rest-of-line>")              \
23680 _(dump_interface_table, "usage: dump_interface_table")          \
23681 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23682 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23683 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23684 _(dump_stats_table, "usage: dump_stats_table")                  \
23685 _(dump_macro_table, "usage: dump_macro_table ")                 \
23686 _(dump_node_table, "usage: dump_node_table")                    \
23687 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23688 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23689 _(echo, "usage: echo <message>")                                \
23690 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23691 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23692 _(help, "usage: help")                                          \
23693 _(q, "usage: quit")                                             \
23694 _(quit, "usage: quit")                                          \
23695 _(search_node_table, "usage: search_node_table <name>...")      \
23696 _(set, "usage: set <variable-name> <value>")                    \
23697 _(script, "usage: script <file-name>")                          \
23698 _(unset, "usage: unset <variable-name>")
23699 #define _(N,n)                                  \
23700     static void vl_api_##n##_t_handler_uni      \
23701     (vl_api_##n##_t * mp)                       \
23702     {                                           \
23703         vat_main_t * vam = &vat_main;           \
23704         if (vam->json_output) {                 \
23705             vl_api_##n##_t_handler_json(mp);    \
23706         } else {                                \
23707             vl_api_##n##_t_handler(mp);         \
23708         }                                       \
23709     }
23710 foreach_vpe_api_reply_msg;
23711 #if VPP_API_TEST_BUILTIN == 0
23712 foreach_standalone_reply_msg;
23713 #endif
23714 #undef _
23715
23716 void
23717 vat_api_hookup (vat_main_t * vam)
23718 {
23719 #define _(N,n)                                                  \
23720     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23721                            vl_api_##n##_t_handler_uni,          \
23722                            vl_noop_handler,                     \
23723                            vl_api_##n##_t_endian,               \
23724                            vl_api_##n##_t_print,                \
23725                            sizeof(vl_api_##n##_t), 1);
23726   foreach_vpe_api_reply_msg;
23727 #if VPP_API_TEST_BUILTIN == 0
23728   foreach_standalone_reply_msg;
23729 #endif
23730 #undef _
23731
23732 #if (VPP_API_TEST_BUILTIN==0)
23733   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23734
23735   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23736
23737   vam->function_by_name = hash_create_string (0, sizeof (uword));
23738
23739   vam->help_by_name = hash_create_string (0, sizeof (uword));
23740 #endif
23741
23742   /* API messages we can send */
23743 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23744   foreach_vpe_api_msg;
23745 #undef _
23746
23747   /* Help strings */
23748 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23749   foreach_vpe_api_msg;
23750 #undef _
23751
23752   /* CLI functions */
23753 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23754   foreach_cli_function;
23755 #undef _
23756
23757   /* Help strings */
23758 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23759   foreach_cli_function;
23760 #undef _
23761 }
23762
23763 #if VPP_API_TEST_BUILTIN
23764 static clib_error_t *
23765 vat_api_hookup_shim (vlib_main_t * vm)
23766 {
23767   vat_api_hookup (&vat_main);
23768   return 0;
23769 }
23770
23771 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23772 #endif
23773
23774 /*
23775  * fd.io coding-style-patch-verification: ON
23776  *
23777  * Local Variables:
23778  * eval: (c-set-style "gnu")
23779  * End:
23780  */