LISP: add NSH support
[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 <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/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/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
1289 /*
1290  * Special-case: build the bridge domain table, maintain
1291  * the next bd id vbl.
1292  */
1293 static void vl_api_bridge_domain_details_t_handler
1294   (vl_api_bridge_domain_details_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1298   int i;
1299
1300   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304          ntohl (mp->bd_id), mp->learn, mp->forward,
1305          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307   if (n_sw_ifs)
1308     {
1309       vl_api_bridge_domain_sw_if_t *sw_ifs;
1310       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1311              "Interface Name");
1312
1313       sw_ifs = mp->sw_if_details;
1314       for (i = 0; i < n_sw_ifs; i++)
1315         {
1316           u8 *sw_if_name = 0;
1317           u32 sw_if_index;
1318           hash_pair_t *p;
1319
1320           sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322           /* *INDENT-OFF* */
1323           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324                              ({
1325                                if ((u32) p->value[0] == sw_if_index)
1326                                  {
1327                                    sw_if_name = (u8 *)(p->key);
1328                                    break;
1329                                  }
1330                              }));
1331           /* *INDENT-ON* */
1332           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1333                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334                  "sw_if_index not found!");
1335
1336           sw_ifs++;
1337         }
1338     }
1339 }
1340
1341 static void vl_api_bridge_domain_details_t_handler_json
1342   (vl_api_bridge_domain_details_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   vat_json_node_t *node, *array = NULL;
1346   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1347
1348   if (VAT_JSON_ARRAY != vam->json_tree.type)
1349     {
1350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351       vat_json_init_array (&vam->json_tree);
1352     }
1353   node = vat_json_array_add (&vam->json_tree);
1354
1355   vat_json_init_object (node);
1356   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357   vat_json_object_add_uint (node, "flood", mp->flood);
1358   vat_json_object_add_uint (node, "forward", mp->forward);
1359   vat_json_object_add_uint (node, "learn", mp->learn);
1360   vat_json_object_add_uint (node, "bvi_sw_if_index",
1361                             ntohl (mp->bvi_sw_if_index));
1362   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1363   array = vat_json_object_add (node, "sw_if");
1364   vat_json_init_array (array);
1365
1366
1367
1368   if (n_sw_ifs)
1369     {
1370       vl_api_bridge_domain_sw_if_t *sw_ifs;
1371       int i;
1372
1373       sw_ifs = mp->sw_if_details;
1374       for (i = 0; i < n_sw_ifs; i++)
1375         {
1376           node = vat_json_array_add (array);
1377           vat_json_init_object (node);
1378           vat_json_object_add_uint (node, "sw_if_index",
1379                                     ntohl (sw_ifs->sw_if_index));
1380           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381           sw_ifs++;
1382         }
1383     }
1384 }
1385
1386 static void vl_api_control_ping_reply_t_handler
1387   (vl_api_control_ping_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->result_ready = 1;
1399     }
1400 }
1401
1402 static void vl_api_control_ping_reply_t_handler_json
1403   (vl_api_control_ping_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   i32 retval = ntohl (mp->retval);
1407
1408   if (VAT_JSON_NONE != vam->json_tree.type)
1409     {
1410       vat_json_print (vam->ofp, &vam->json_tree);
1411       vat_json_free (&vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414   else
1415     {
1416       /* just print [] */
1417       vat_json_init_array (&vam->json_tree);
1418       vat_json_print (vam->ofp, &vam->json_tree);
1419       vam->json_tree.type = VAT_JSON_NONE;
1420     }
1421
1422   vam->retval = retval;
1423   vam->result_ready = 1;
1424 }
1425
1426 static void
1427   vl_api_bridge_domain_set_mac_age_reply_t_handler
1428   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   i32 retval = ntohl (mp->retval);
1432   if (vam->async_mode)
1433     {
1434       vam->async_errors += (retval < 0);
1435     }
1436   else
1437     {
1438       vam->retval = retval;
1439       vam->result_ready = 1;
1440     }
1441 }
1442
1443 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   vat_json_node_t node;
1448
1449   vat_json_init_object (&node);
1450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452   vat_json_print (vam->ofp, &node);
1453   vat_json_free (&node);
1454
1455   vam->retval = ntohl (mp->retval);
1456   vam->result_ready = 1;
1457 }
1458
1459 static void
1460 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   i32 retval = ntohl (mp->retval);
1464   if (vam->async_mode)
1465     {
1466       vam->async_errors += (retval < 0);
1467     }
1468   else
1469     {
1470       vam->retval = retval;
1471       vam->result_ready = 1;
1472     }
1473 }
1474
1475 static void vl_api_l2_flags_reply_t_handler_json
1476   (vl_api_l2_flags_reply_t * mp)
1477 {
1478   vat_main_t *vam = &vat_main;
1479   vat_json_node_t node;
1480
1481   vat_json_init_object (&node);
1482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484                             ntohl (mp->resulting_feature_bitmap));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491 }
1492
1493 static void vl_api_bridge_flags_reply_t_handler
1494   (vl_api_bridge_flags_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_flags_reply_t_handler_json
1510   (vl_api_bridge_flags_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518                             ntohl (mp->resulting_feature_bitmap));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void vl_api_tap_connect_reply_t_handler
1528   (vl_api_tap_connect_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->sw_if_index = ntohl (mp->sw_if_index);
1540       vam->result_ready = 1;
1541     }
1542
1543 }
1544
1545 static void vl_api_tap_connect_reply_t_handler_json
1546   (vl_api_tap_connect_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t node;
1550
1551   vat_json_init_object (&node);
1552   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560
1561 }
1562
1563 static void
1564 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565 {
1566   vat_main_t *vam = &vat_main;
1567   i32 retval = ntohl (mp->retval);
1568   if (vam->async_mode)
1569     {
1570       vam->async_errors += (retval < 0);
1571     }
1572   else
1573     {
1574       vam->retval = retval;
1575       vam->sw_if_index = ntohl (mp->sw_if_index);
1576       vam->result_ready = 1;
1577     }
1578 }
1579
1580 static void vl_api_tap_modify_reply_t_handler_json
1581   (vl_api_tap_modify_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595 }
1596
1597 static void
1598 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_tap_delete_reply_t_handler_json
1614   (vl_api_tap_delete_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627 }
1628
1629 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654                             ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->sw_if_index = ntohl (mp->sw_if_index);
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1698   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1714   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "fwd_entry_index",
1722                             clib_net_to_host_u32 (mp->fwd_entry_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_one_add_del_locator_set_reply_t_handler
1732   (vl_api_one_add_del_locator_set_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1748   (vl_api_one_add_del_locator_set_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1765   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->sw_if_index = ntohl (mp->sw_if_index);
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1782   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void vl_api_gre_add_del_tunnel_reply_t_handler
1799   (vl_api_gre_add_del_tunnel_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->sw_if_index = ntohl (mp->sw_if_index);
1811       vam->result_ready = 1;
1812     }
1813 }
1814
1815 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1816   (vl_api_gre_add_del_tunnel_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   vat_json_node_t node;
1820
1821   vat_json_init_object (&node);
1822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1823   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1824
1825   vat_json_print (vam->ofp, &node);
1826   vat_json_free (&node);
1827
1828   vam->retval = ntohl (mp->retval);
1829   vam->result_ready = 1;
1830 }
1831
1832 static void vl_api_create_vhost_user_if_reply_t_handler
1833   (vl_api_create_vhost_user_if_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->sw_if_index = ntohl (mp->sw_if_index);
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_create_vhost_user_if_reply_t_handler_json
1850   (vl_api_create_vhost_user_if_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void vl_api_ip_address_details_t_handler
1867   (vl_api_ip_address_details_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   static ip_address_details_t empty_ip_address_details = { {0} };
1871   ip_address_details_t *address = NULL;
1872   ip_details_t *current_ip_details = NULL;
1873   ip_details_t *details = NULL;
1874
1875   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1876
1877   if (!details || vam->current_sw_if_index >= vec_len (details)
1878       || !details[vam->current_sw_if_index].present)
1879     {
1880       errmsg ("ip address details arrived but not stored");
1881       errmsg ("ip_dump should be called first");
1882       return;
1883     }
1884
1885   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1886
1887 #define addresses (current_ip_details->addr)
1888
1889   vec_validate_init_empty (addresses, vec_len (addresses),
1890                            empty_ip_address_details);
1891
1892   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1893
1894   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1895   address->prefix_length = mp->prefix_length;
1896 #undef addresses
1897 }
1898
1899 static void vl_api_ip_address_details_t_handler_json
1900   (vl_api_ip_address_details_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   vat_json_node_t *node = NULL;
1904   struct in6_addr ip6;
1905   struct in_addr ip4;
1906
1907   if (VAT_JSON_ARRAY != vam->json_tree.type)
1908     {
1909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1910       vat_json_init_array (&vam->json_tree);
1911     }
1912   node = vat_json_array_add (&vam->json_tree);
1913
1914   vat_json_init_object (node);
1915   if (vam->is_ipv6)
1916     {
1917       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1918       vat_json_object_add_ip6 (node, "ip", ip6);
1919     }
1920   else
1921     {
1922       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1923       vat_json_object_add_ip4 (node, "ip", ip4);
1924     }
1925   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1926 }
1927
1928 static void
1929 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1930 {
1931   vat_main_t *vam = &vat_main;
1932   static ip_details_t empty_ip_details = { 0 };
1933   ip_details_t *ip = NULL;
1934   u32 sw_if_index = ~0;
1935
1936   sw_if_index = ntohl (mp->sw_if_index);
1937
1938   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1939                            sw_if_index, empty_ip_details);
1940
1941   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1942                          sw_if_index);
1943
1944   ip->present = 1;
1945 }
1946
1947 static void
1948 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1949 {
1950   vat_main_t *vam = &vat_main;
1951
1952   if (VAT_JSON_ARRAY != vam->json_tree.type)
1953     {
1954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1955       vat_json_init_array (&vam->json_tree);
1956     }
1957   vat_json_array_add_uint (&vam->json_tree,
1958                            clib_net_to_host_u32 (mp->sw_if_index));
1959 }
1960
1961 static void vl_api_map_domain_details_t_handler_json
1962   (vl_api_map_domain_details_t * mp)
1963 {
1964   vat_json_node_t *node = NULL;
1965   vat_main_t *vam = &vat_main;
1966   struct in6_addr ip6;
1967   struct in_addr ip4;
1968
1969   if (VAT_JSON_ARRAY != vam->json_tree.type)
1970     {
1971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1972       vat_json_init_array (&vam->json_tree);
1973     }
1974
1975   node = vat_json_array_add (&vam->json_tree);
1976   vat_json_init_object (node);
1977
1978   vat_json_object_add_uint (node, "domain_index",
1979                             clib_net_to_host_u32 (mp->domain_index));
1980   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1981   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1982   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1983   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1984   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1985   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1986   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1987   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1988   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1989   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1990   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1991   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1992   vat_json_object_add_uint (node, "flags", mp->flags);
1993   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1994   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1995 }
1996
1997 static void vl_api_map_domain_details_t_handler
1998   (vl_api_map_domain_details_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001
2002   if (mp->is_translation)
2003     {
2004       print (vam->ofp,
2005              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2006              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2007              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2008              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2009              clib_net_to_host_u32 (mp->domain_index));
2010     }
2011   else
2012     {
2013       print (vam->ofp,
2014              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2015              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2016              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2017              format_ip6_address, mp->ip6_src,
2018              clib_net_to_host_u32 (mp->domain_index));
2019     }
2020   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2021          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2022          mp->is_translation ? "map-t" : "");
2023 }
2024
2025 static void vl_api_map_rule_details_t_handler_json
2026   (vl_api_map_rule_details_t * mp)
2027 {
2028   struct in6_addr ip6;
2029   vat_json_node_t *node = NULL;
2030   vat_main_t *vam = &vat_main;
2031
2032   if (VAT_JSON_ARRAY != vam->json_tree.type)
2033     {
2034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2035       vat_json_init_array (&vam->json_tree);
2036     }
2037
2038   node = vat_json_array_add (&vam->json_tree);
2039   vat_json_init_object (node);
2040
2041   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2042   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2043   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2044 }
2045
2046 static void
2047 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2048 {
2049   vat_main_t *vam = &vat_main;
2050   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2051          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2052 }
2053
2054 static void
2055 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2056 {
2057   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2058           "router_addr %U host_mac %U",
2059           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2060           format_ip4_address, &mp->host_address,
2061           format_ip4_address, &mp->router_address,
2062           format_ethernet_address, mp->host_mac);
2063 }
2064
2065 static void vl_api_dhcp_compl_event_t_handler_json
2066   (vl_api_dhcp_compl_event_t * mp)
2067 {
2068   /* JSON output not supported */
2069 }
2070
2071 static void
2072 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2073                               u32 counter)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   static u64 default_counter = 0;
2077
2078   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2079                            NULL);
2080   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2081                            sw_if_index, default_counter);
2082   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2083 }
2084
2085 static void
2086 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2087                                 interface_counter_t counter)
2088 {
2089   vat_main_t *vam = &vat_main;
2090   static interface_counter_t default_counter = { 0, };
2091
2092   vec_validate_init_empty (vam->combined_interface_counters,
2093                            vnet_counter_type, NULL);
2094   vec_validate_init_empty (vam->combined_interface_counters
2095                            [vnet_counter_type], sw_if_index, default_counter);
2096   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2097 }
2098
2099 static void vl_api_vnet_interface_simple_counters_t_handler
2100   (vl_api_vnet_interface_simple_counters_t * mp)
2101 {
2102   /* not supported */
2103 }
2104
2105 static void vl_api_vnet_interface_combined_counters_t_handler
2106   (vl_api_vnet_interface_combined_counters_t * mp)
2107 {
2108   /* not supported */
2109 }
2110
2111 static void vl_api_vnet_interface_simple_counters_t_handler_json
2112   (vl_api_vnet_interface_simple_counters_t * mp)
2113 {
2114   u64 *v_packets;
2115   u64 packets;
2116   u32 count;
2117   u32 first_sw_if_index;
2118   int i;
2119
2120   count = ntohl (mp->count);
2121   first_sw_if_index = ntohl (mp->first_sw_if_index);
2122
2123   v_packets = (u64 *) & mp->data;
2124   for (i = 0; i < count; i++)
2125     {
2126       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2127       set_simple_interface_counter (mp->vnet_counter_type,
2128                                     first_sw_if_index + i, packets);
2129       v_packets++;
2130     }
2131 }
2132
2133 static void vl_api_vnet_interface_combined_counters_t_handler_json
2134   (vl_api_vnet_interface_combined_counters_t * mp)
2135 {
2136   interface_counter_t counter;
2137   vlib_counter_t *v;
2138   u32 first_sw_if_index;
2139   int i;
2140   u32 count;
2141
2142   count = ntohl (mp->count);
2143   first_sw_if_index = ntohl (mp->first_sw_if_index);
2144
2145   v = (vlib_counter_t *) & mp->data;
2146   for (i = 0; i < count; i++)
2147     {
2148       counter.packets =
2149         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2150       counter.bytes =
2151         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2152       set_combined_interface_counter (mp->vnet_counter_type,
2153                                       first_sw_if_index + i, counter);
2154       v++;
2155     }
2156 }
2157
2158 static u32
2159 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2160 {
2161   vat_main_t *vam = &vat_main;
2162   u32 i;
2163
2164   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2165     {
2166       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2167         {
2168           return i;
2169         }
2170     }
2171   return ~0;
2172 }
2173
2174 static u32
2175 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2176 {
2177   vat_main_t *vam = &vat_main;
2178   u32 i;
2179
2180   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2181     {
2182       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2183         {
2184           return i;
2185         }
2186     }
2187   return ~0;
2188 }
2189
2190 static void vl_api_vnet_ip4_fib_counters_t_handler
2191   (vl_api_vnet_ip4_fib_counters_t * mp)
2192 {
2193   /* not supported */
2194 }
2195
2196 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2197   (vl_api_vnet_ip4_fib_counters_t * mp)
2198 {
2199   vat_main_t *vam = &vat_main;
2200   vl_api_ip4_fib_counter_t *v;
2201   ip4_fib_counter_t *counter;
2202   struct in_addr ip4;
2203   u32 vrf_id;
2204   u32 vrf_index;
2205   u32 count;
2206   int i;
2207
2208   vrf_id = ntohl (mp->vrf_id);
2209   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2210   if (~0 == vrf_index)
2211     {
2212       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2213       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2214       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2215       vec_validate (vam->ip4_fib_counters, vrf_index);
2216       vam->ip4_fib_counters[vrf_index] = NULL;
2217     }
2218
2219   vec_free (vam->ip4_fib_counters[vrf_index]);
2220   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2221   count = ntohl (mp->count);
2222   for (i = 0; i < count; i++)
2223     {
2224       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2225       counter = &vam->ip4_fib_counters[vrf_index][i];
2226       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2227       counter->address = ip4;
2228       counter->address_length = v->address_length;
2229       counter->packets = clib_net_to_host_u64 (v->packets);
2230       counter->bytes = clib_net_to_host_u64 (v->bytes);
2231       v++;
2232     }
2233 }
2234
2235 static void vl_api_vnet_ip4_nbr_counters_t_handler
2236   (vl_api_vnet_ip4_nbr_counters_t * mp)
2237 {
2238   /* not supported */
2239 }
2240
2241 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2242   (vl_api_vnet_ip4_nbr_counters_t * mp)
2243 {
2244   vat_main_t *vam = &vat_main;
2245   vl_api_ip4_nbr_counter_t *v;
2246   ip4_nbr_counter_t *counter;
2247   u32 sw_if_index;
2248   u32 count;
2249   int i;
2250
2251   sw_if_index = ntohl (mp->sw_if_index);
2252   count = ntohl (mp->count);
2253   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2254
2255   if (mp->begin)
2256     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2257
2258   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2259   for (i = 0; i < count; i++)
2260     {
2261       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2262       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2263       counter->address.s_addr = v->address;
2264       counter->packets = clib_net_to_host_u64 (v->packets);
2265       counter->bytes = clib_net_to_host_u64 (v->bytes);
2266       counter->linkt = v->link_type;
2267       v++;
2268     }
2269 }
2270
2271 static void vl_api_vnet_ip6_fib_counters_t_handler
2272   (vl_api_vnet_ip6_fib_counters_t * mp)
2273 {
2274   /* not supported */
2275 }
2276
2277 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2278   (vl_api_vnet_ip6_fib_counters_t * mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   vl_api_ip6_fib_counter_t *v;
2282   ip6_fib_counter_t *counter;
2283   struct in6_addr ip6;
2284   u32 vrf_id;
2285   u32 vrf_index;
2286   u32 count;
2287   int i;
2288
2289   vrf_id = ntohl (mp->vrf_id);
2290   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2291   if (~0 == vrf_index)
2292     {
2293       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2294       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2295       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2296       vec_validate (vam->ip6_fib_counters, vrf_index);
2297       vam->ip6_fib_counters[vrf_index] = NULL;
2298     }
2299
2300   vec_free (vam->ip6_fib_counters[vrf_index]);
2301   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2302   count = ntohl (mp->count);
2303   for (i = 0; i < count; i++)
2304     {
2305       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2306       counter = &vam->ip6_fib_counters[vrf_index][i];
2307       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2308       counter->address = ip6;
2309       counter->address_length = v->address_length;
2310       counter->packets = clib_net_to_host_u64 (v->packets);
2311       counter->bytes = clib_net_to_host_u64 (v->bytes);
2312       v++;
2313     }
2314 }
2315
2316 static void vl_api_vnet_ip6_nbr_counters_t_handler
2317   (vl_api_vnet_ip6_nbr_counters_t * mp)
2318 {
2319   /* not supported */
2320 }
2321
2322 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2323   (vl_api_vnet_ip6_nbr_counters_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   vl_api_ip6_nbr_counter_t *v;
2327   ip6_nbr_counter_t *counter;
2328   struct in6_addr ip6;
2329   u32 sw_if_index;
2330   u32 count;
2331   int i;
2332
2333   sw_if_index = ntohl (mp->sw_if_index);
2334   count = ntohl (mp->count);
2335   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2336
2337   if (mp->begin)
2338     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2339
2340   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2341   for (i = 0; i < count; i++)
2342     {
2343       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2344       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2345       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2346       counter->address = ip6;
2347       counter->packets = clib_net_to_host_u64 (v->packets);
2348       counter->bytes = clib_net_to_host_u64 (v->bytes);
2349       v++;
2350     }
2351 }
2352
2353 static void vl_api_get_first_msg_id_reply_t_handler
2354   (vl_api_get_first_msg_id_reply_t * mp)
2355 {
2356   vat_main_t *vam = &vat_main;
2357   i32 retval = ntohl (mp->retval);
2358
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->result_ready = 1;
2367     }
2368   if (retval >= 0)
2369     {
2370       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2371     }
2372 }
2373
2374 static void vl_api_get_first_msg_id_reply_t_handler_json
2375   (vl_api_get_first_msg_id_reply_t * mp)
2376 {
2377   vat_main_t *vam = &vat_main;
2378   vat_json_node_t node;
2379
2380   vat_json_init_object (&node);
2381   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2382   vat_json_object_add_uint (&node, "first_msg_id",
2383                             (uint) ntohs (mp->first_msg_id));
2384
2385   vat_json_print (vam->ofp, &node);
2386   vat_json_free (&node);
2387
2388   vam->retval = ntohl (mp->retval);
2389   vam->result_ready = 1;
2390 }
2391
2392 static void vl_api_get_node_graph_reply_t_handler
2393   (vl_api_get_node_graph_reply_t * mp)
2394 {
2395   vat_main_t *vam = &vat_main;
2396   api_main_t *am = &api_main;
2397   i32 retval = ntohl (mp->retval);
2398   u8 *pvt_copy, *reply;
2399   void *oldheap;
2400   vlib_node_t *node;
2401   int i;
2402
2403   if (vam->async_mode)
2404     {
2405       vam->async_errors += (retval < 0);
2406     }
2407   else
2408     {
2409       vam->retval = retval;
2410       vam->result_ready = 1;
2411     }
2412
2413   /* "Should never happen..." */
2414   if (retval != 0)
2415     return;
2416
2417   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2418   pvt_copy = vec_dup (reply);
2419
2420   /* Toss the shared-memory original... */
2421   pthread_mutex_lock (&am->vlib_rp->mutex);
2422   oldheap = svm_push_data_heap (am->vlib_rp);
2423
2424   vec_free (reply);
2425
2426   svm_pop_heap (oldheap);
2427   pthread_mutex_unlock (&am->vlib_rp->mutex);
2428
2429   if (vam->graph_nodes)
2430     {
2431       hash_free (vam->graph_node_index_by_name);
2432
2433       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2434         {
2435           node = vam->graph_nodes[i];
2436           vec_free (node->name);
2437           vec_free (node->next_nodes);
2438           vec_free (node);
2439         }
2440       vec_free (vam->graph_nodes);
2441     }
2442
2443   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2444   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2445   vec_free (pvt_copy);
2446
2447   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2448     {
2449       node = vam->graph_nodes[i];
2450       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2451     }
2452 }
2453
2454 static void vl_api_get_node_graph_reply_t_handler_json
2455   (vl_api_get_node_graph_reply_t * mp)
2456 {
2457   vat_main_t *vam = &vat_main;
2458   api_main_t *am = &api_main;
2459   void *oldheap;
2460   vat_json_node_t node;
2461   u8 *reply;
2462
2463   /* $$$$ make this real? */
2464   vat_json_init_object (&node);
2465   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2466   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2467
2468   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2469
2470   /* Toss the shared-memory original... */
2471   pthread_mutex_lock (&am->vlib_rp->mutex);
2472   oldheap = svm_push_data_heap (am->vlib_rp);
2473
2474   vec_free (reply);
2475
2476   svm_pop_heap (oldheap);
2477   pthread_mutex_unlock (&am->vlib_rp->mutex);
2478
2479   vat_json_print (vam->ofp, &node);
2480   vat_json_free (&node);
2481
2482   vam->retval = ntohl (mp->retval);
2483   vam->result_ready = 1;
2484 }
2485
2486 static void
2487 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   u8 *s = 0;
2491
2492   if (mp->local)
2493     {
2494       s = format (s, "%=16d%=16d%=16d",
2495                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2496     }
2497   else
2498     {
2499       s = format (s, "%=16U%=16d%=16d",
2500                   mp->is_ipv6 ? format_ip6_address :
2501                   format_ip4_address,
2502                   mp->ip_address, mp->priority, mp->weight);
2503     }
2504
2505   print (vam->ofp, "%v", s);
2506   vec_free (s);
2507 }
2508
2509 static void
2510 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   vat_json_node_t *node = NULL;
2514   struct in6_addr ip6;
2515   struct in_addr ip4;
2516
2517   if (VAT_JSON_ARRAY != vam->json_tree.type)
2518     {
2519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2520       vat_json_init_array (&vam->json_tree);
2521     }
2522   node = vat_json_array_add (&vam->json_tree);
2523   vat_json_init_object (node);
2524
2525   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2526   vat_json_object_add_uint (node, "priority", mp->priority);
2527   vat_json_object_add_uint (node, "weight", mp->weight);
2528
2529   if (mp->local)
2530     vat_json_object_add_uint (node, "sw_if_index",
2531                               clib_net_to_host_u32 (mp->sw_if_index));
2532   else
2533     {
2534       if (mp->is_ipv6)
2535         {
2536           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2537           vat_json_object_add_ip6 (node, "address", ip6);
2538         }
2539       else
2540         {
2541           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2542           vat_json_object_add_ip4 (node, "address", ip4);
2543         }
2544     }
2545 }
2546
2547 static void
2548 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2549                                           mp)
2550 {
2551   vat_main_t *vam = &vat_main;
2552   u8 *ls_name = 0;
2553
2554   ls_name = format (0, "%s", mp->ls_name);
2555
2556   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2557          ls_name);
2558   vec_free (ls_name);
2559 }
2560
2561 static void
2562   vl_api_one_locator_set_details_t_handler_json
2563   (vl_api_one_locator_set_details_t * mp)
2564 {
2565   vat_main_t *vam = &vat_main;
2566   vat_json_node_t *node = 0;
2567   u8 *ls_name = 0;
2568
2569   ls_name = format (0, "%s", mp->ls_name);
2570   vec_add1 (ls_name, 0);
2571
2572   if (VAT_JSON_ARRAY != vam->json_tree.type)
2573     {
2574       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2575       vat_json_init_array (&vam->json_tree);
2576     }
2577   node = vat_json_array_add (&vam->json_tree);
2578
2579   vat_json_init_object (node);
2580   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2581   vat_json_object_add_uint (node, "ls_index",
2582                             clib_net_to_host_u32 (mp->ls_index));
2583   vec_free (ls_name);
2584 }
2585
2586 typedef struct
2587 {
2588   u32 spi;
2589   u8 si;
2590 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2591
2592 uword
2593 unformat_nsh_address (unformat_input_t * input, va_list * args)
2594 {
2595   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2596   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2597 }
2598
2599 u8 *
2600 format_nsh_address_vat (u8 * s, va_list * args)
2601 {
2602   nsh_t *a = va_arg (*args, nsh_t *);
2603   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2604 }
2605
2606 static u8 *
2607 format_lisp_flat_eid (u8 * s, va_list * args)
2608 {
2609   u32 type = va_arg (*args, u32);
2610   u8 *eid = va_arg (*args, u8 *);
2611   u32 eid_len = va_arg (*args, u32);
2612
2613   switch (type)
2614     {
2615     case 0:
2616       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2617     case 1:
2618       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2619     case 2:
2620       return format (s, "%U", format_ethernet_address, eid);
2621     case 3:
2622       return format (s, "%U", format_nsh_address_vat, eid);
2623     }
2624   return 0;
2625 }
2626
2627 static u8 *
2628 format_lisp_eid_vat (u8 * s, va_list * args)
2629 {
2630   u32 type = va_arg (*args, u32);
2631   u8 *eid = va_arg (*args, u8 *);
2632   u32 eid_len = va_arg (*args, u32);
2633   u8 *seid = va_arg (*args, u8 *);
2634   u32 seid_len = va_arg (*args, u32);
2635   u32 is_src_dst = va_arg (*args, u32);
2636
2637   if (is_src_dst)
2638     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2639
2640   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2641
2642   return s;
2643 }
2644
2645 static void
2646 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2647 {
2648   vat_main_t *vam = &vat_main;
2649   u8 *s = 0, *eid = 0;
2650
2651   if (~0 == mp->locator_set_index)
2652     s = format (0, "action: %d", mp->action);
2653   else
2654     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2655
2656   eid = format (0, "%U", format_lisp_eid_vat,
2657                 mp->eid_type,
2658                 mp->eid,
2659                 mp->eid_prefix_len,
2660                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2661   vec_add1 (eid, 0);
2662
2663   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2664          clib_net_to_host_u32 (mp->vni),
2665          eid,
2666          mp->is_local ? "local" : "remote",
2667          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2668          clib_net_to_host_u16 (mp->key_id), mp->key);
2669
2670   vec_free (s);
2671   vec_free (eid);
2672 }
2673
2674 static void
2675 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2676                                              * mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679   vat_json_node_t *node = 0;
2680   u8 *eid = 0;
2681
2682   if (VAT_JSON_ARRAY != vam->json_tree.type)
2683     {
2684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2685       vat_json_init_array (&vam->json_tree);
2686     }
2687   node = vat_json_array_add (&vam->json_tree);
2688
2689   vat_json_init_object (node);
2690   if (~0 == mp->locator_set_index)
2691     vat_json_object_add_uint (node, "action", mp->action);
2692   else
2693     vat_json_object_add_uint (node, "locator_set_index",
2694                               clib_net_to_host_u32 (mp->locator_set_index));
2695
2696   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2697   if (mp->eid_type == 3)
2698     {
2699       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2700       vat_json_init_object (nsh_json);
2701       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2702       vat_json_object_add_uint (nsh_json, "spi",
2703                                 clib_net_to_host_u32 (nsh->spi));
2704       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2705     }
2706   else
2707     {
2708       eid = format (0, "%U", format_lisp_eid_vat,
2709                     mp->eid_type,
2710                     mp->eid,
2711                     mp->eid_prefix_len,
2712                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2713       vec_add1 (eid, 0);
2714       vat_json_object_add_string_copy (node, "eid", eid);
2715       vec_free (eid);
2716     }
2717   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2718   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2719   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2720
2721   if (mp->key_id)
2722     {
2723       vat_json_object_add_uint (node, "key_id",
2724                                 clib_net_to_host_u16 (mp->key_id));
2725       vat_json_object_add_string_copy (node, "key", mp->key);
2726     }
2727 }
2728
2729 static void
2730 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2731 {
2732   vat_main_t *vam = &vat_main;
2733   u8 *seid = 0, *deid = 0;
2734   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2735
2736   deid = format (0, "%U", format_lisp_eid_vat,
2737                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2738
2739   seid = format (0, "%U", format_lisp_eid_vat,
2740                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2741
2742   vec_add1 (deid, 0);
2743   vec_add1 (seid, 0);
2744
2745   if (mp->is_ip4)
2746     format_ip_address_fcn = format_ip4_address;
2747   else
2748     format_ip_address_fcn = format_ip6_address;
2749
2750
2751   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2752          clib_net_to_host_u32 (mp->vni),
2753          seid, deid,
2754          format_ip_address_fcn, mp->lloc,
2755          format_ip_address_fcn, mp->rloc,
2756          clib_net_to_host_u32 (mp->pkt_count),
2757          clib_net_to_host_u32 (mp->bytes));
2758
2759   vec_free (deid);
2760   vec_free (seid);
2761 }
2762
2763 static void
2764 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2765 {
2766   struct in6_addr ip6;
2767   struct in_addr ip4;
2768   vat_main_t *vam = &vat_main;
2769   vat_json_node_t *node = 0;
2770   u8 *deid = 0, *seid = 0;
2771
2772   if (VAT_JSON_ARRAY != vam->json_tree.type)
2773     {
2774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2775       vat_json_init_array (&vam->json_tree);
2776     }
2777   node = vat_json_array_add (&vam->json_tree);
2778
2779   vat_json_init_object (node);
2780   deid = format (0, "%U", format_lisp_eid_vat,
2781                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2782
2783   seid = format (0, "%U", format_lisp_eid_vat,
2784                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2785
2786   vec_add1 (deid, 0);
2787   vec_add1 (seid, 0);
2788
2789   vat_json_object_add_string_copy (node, "seid", seid);
2790   vat_json_object_add_string_copy (node, "deid", deid);
2791   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2792
2793   if (mp->is_ip4)
2794     {
2795       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2796       vat_json_object_add_ip4 (node, "lloc", ip4);
2797       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2798       vat_json_object_add_ip4 (node, "rloc", ip4);
2799     }
2800   else
2801     {
2802       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2803       vat_json_object_add_ip6 (node, "lloc", ip6);
2804       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2805       vat_json_object_add_ip6 (node, "rloc", ip6);
2806     }
2807   vat_json_object_add_uint (node, "pkt_count",
2808                             clib_net_to_host_u32 (mp->pkt_count));
2809   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2810
2811   vec_free (deid);
2812   vec_free (seid);
2813 }
2814
2815 static void
2816   vl_api_one_eid_table_map_details_t_handler
2817   (vl_api_one_eid_table_map_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820
2821   u8 *line = format (0, "%=10d%=10d",
2822                      clib_net_to_host_u32 (mp->vni),
2823                      clib_net_to_host_u32 (mp->dp_table));
2824   print (vam->ofp, "%v", line);
2825   vec_free (line);
2826 }
2827
2828 static void
2829   vl_api_one_eid_table_map_details_t_handler_json
2830   (vl_api_one_eid_table_map_details_t * mp)
2831 {
2832   vat_main_t *vam = &vat_main;
2833   vat_json_node_t *node = NULL;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842   vat_json_object_add_uint (node, "dp_table",
2843                             clib_net_to_host_u32 (mp->dp_table));
2844   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2845 }
2846
2847 static void
2848   vl_api_one_eid_table_vni_details_t_handler
2849   (vl_api_one_eid_table_vni_details_t * mp)
2850 {
2851   vat_main_t *vam = &vat_main;
2852
2853   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2854   print (vam->ofp, "%v", line);
2855   vec_free (line);
2856 }
2857
2858 static void
2859   vl_api_one_eid_table_vni_details_t_handler_json
2860   (vl_api_one_eid_table_vni_details_t * mp)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   vat_json_node_t *node = NULL;
2864
2865   if (VAT_JSON_ARRAY != vam->json_tree.type)
2866     {
2867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2868       vat_json_init_array (&vam->json_tree);
2869     }
2870   node = vat_json_array_add (&vam->json_tree);
2871   vat_json_init_object (node);
2872   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2873 }
2874
2875 static void
2876   vl_api_show_one_map_register_state_reply_t_handler
2877   (vl_api_show_one_map_register_state_reply_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   int retval = clib_net_to_host_u32 (mp->retval);
2881
2882   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2883
2884   vam->retval = retval;
2885   vam->result_ready = 1;
2886 }
2887
2888 static void
2889   vl_api_show_one_map_register_state_reply_t_handler_json
2890   (vl_api_show_one_map_register_state_reply_t * mp)
2891 {
2892   vat_main_t *vam = &vat_main;
2893   vat_json_node_t _node, *node = &_node;
2894   int retval = clib_net_to_host_u32 (mp->retval);
2895
2896   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2897
2898   vat_json_init_object (node);
2899   vat_json_object_add_string_copy (node, "state", s);
2900
2901   vat_json_print (vam->ofp, node);
2902   vat_json_free (node);
2903
2904   vam->retval = retval;
2905   vam->result_ready = 1;
2906   vec_free (s);
2907 }
2908
2909 static void
2910   vl_api_show_one_rloc_probe_state_reply_t_handler
2911   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2912 {
2913   vat_main_t *vam = &vat_main;
2914   int retval = clib_net_to_host_u32 (mp->retval);
2915
2916   if (retval)
2917     goto end;
2918
2919   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2920 end:
2921   vam->retval = retval;
2922   vam->result_ready = 1;
2923 }
2924
2925 static void
2926   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2927   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   vat_json_node_t _node, *node = &_node;
2931   int retval = clib_net_to_host_u32 (mp->retval);
2932
2933   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2934   vat_json_init_object (node);
2935   vat_json_object_add_string_copy (node, "state", s);
2936
2937   vat_json_print (vam->ofp, node);
2938   vat_json_free (node);
2939
2940   vam->retval = retval;
2941   vam->result_ready = 1;
2942   vec_free (s);
2943 }
2944
2945 static void
2946   vl_api_show_one_stats_enable_disable_reply_t_handler
2947   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   int retval = clib_net_to_host_u32 (mp->retval);
2951
2952   if (retval)
2953     goto end;
2954
2955   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2956 end:
2957   vam->retval = retval;
2958   vam->result_ready = 1;
2959 }
2960
2961 static void
2962   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2963   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   vat_json_node_t _node, *node = &_node;
2967   int retval = clib_net_to_host_u32 (mp->retval);
2968
2969   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2970   vat_json_init_object (node);
2971   vat_json_object_add_string_copy (node, "state", s);
2972
2973   vat_json_print (vam->ofp, node);
2974   vat_json_free (node);
2975
2976   vam->retval = retval;
2977   vam->result_ready = 1;
2978   vec_free (s);
2979 }
2980
2981 static void
2982 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2983 {
2984   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2985   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2986   e->vni = clib_net_to_host_u32 (e->vni);
2987 }
2988
2989 static void
2990   gpe_fwd_entries_get_reply_t_net_to_host
2991   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2992 {
2993   u32 i;
2994
2995   mp->count = clib_net_to_host_u32 (mp->count);
2996   for (i = 0; i < mp->count; i++)
2997     {
2998       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2999     }
3000 }
3001
3002 static u8 *
3003 format_gpe_encap_mode (u8 * s, va_list * args)
3004 {
3005   u32 mode = va_arg (*args, u32);
3006
3007   switch (mode)
3008     {
3009     case 0:
3010       return format (s, "lisp");
3011     case 1:
3012       return format (s, "vxlan");
3013     }
3014   return 0;
3015 }
3016
3017 static void
3018   vl_api_gpe_get_encap_mode_reply_t_handler
3019   (vl_api_gpe_get_encap_mode_reply_t * mp)
3020 {
3021   vat_main_t *vam = &vat_main;
3022
3023   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3024   vam->retval = ntohl (mp->retval);
3025   vam->result_ready = 1;
3026 }
3027
3028 static void
3029   vl_api_gpe_get_encap_mode_reply_t_handler_json
3030   (vl_api_gpe_get_encap_mode_reply_t * mp)
3031 {
3032   vat_main_t *vam = &vat_main;
3033   vat_json_node_t node;
3034
3035   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3036   vec_add1 (encap_mode, 0);
3037
3038   vat_json_init_object (&node);
3039   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3040
3041   vec_free (encap_mode);
3042   vat_json_print (vam->ofp, &node);
3043   vat_json_free (&node);
3044
3045   vam->retval = ntohl (mp->retval);
3046   vam->result_ready = 1;
3047 }
3048
3049 static void
3050   vl_api_gpe_fwd_entry_path_details_t_handler
3051   (vl_api_gpe_fwd_entry_path_details_t * mp)
3052 {
3053   vat_main_t *vam = &vat_main;
3054   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3055
3056   if (mp->lcl_loc.is_ip4)
3057     format_ip_address_fcn = format_ip4_address;
3058   else
3059     format_ip_address_fcn = format_ip6_address;
3060
3061   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3062          format_ip_address_fcn, &mp->lcl_loc,
3063          format_ip_address_fcn, &mp->rmt_loc);
3064 }
3065
3066 static void
3067 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3068 {
3069   struct in6_addr ip6;
3070   struct in_addr ip4;
3071
3072   if (loc->is_ip4)
3073     {
3074       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3075       vat_json_object_add_ip4 (n, "address", ip4);
3076     }
3077   else
3078     {
3079       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3080       vat_json_object_add_ip6 (n, "address", ip6);
3081     }
3082   vat_json_object_add_uint (n, "weight", loc->weight);
3083 }
3084
3085 static void
3086   vl_api_gpe_fwd_entry_path_details_t_handler_json
3087   (vl_api_gpe_fwd_entry_path_details_t * mp)
3088 {
3089   vat_main_t *vam = &vat_main;
3090   vat_json_node_t *node = NULL;
3091   vat_json_node_t *loc_node;
3092
3093   if (VAT_JSON_ARRAY != vam->json_tree.type)
3094     {
3095       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3096       vat_json_init_array (&vam->json_tree);
3097     }
3098   node = vat_json_array_add (&vam->json_tree);
3099   vat_json_init_object (node);
3100
3101   loc_node = vat_json_object_add (node, "local_locator");
3102   vat_json_init_object (loc_node);
3103   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3104
3105   loc_node = vat_json_object_add (node, "remote_locator");
3106   vat_json_init_object (loc_node);
3107   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3108 }
3109
3110 static void
3111   vl_api_gpe_fwd_entries_get_reply_t_handler
3112   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3113 {
3114   vat_main_t *vam = &vat_main;
3115   u32 i;
3116   int retval = clib_net_to_host_u32 (mp->retval);
3117   vl_api_gpe_fwd_entry_t *e;
3118
3119   if (retval)
3120     goto end;
3121
3122   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3123
3124   for (i = 0; i < mp->count; i++)
3125     {
3126       e = &mp->entries[i];
3127       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3128              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3129              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3130     }
3131
3132 end:
3133   vam->retval = retval;
3134   vam->result_ready = 1;
3135 }
3136
3137 static void
3138   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3139   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3140 {
3141   u8 *s = 0;
3142   vat_main_t *vam = &vat_main;
3143   vat_json_node_t *e = 0, root;
3144   u32 i;
3145   int retval = clib_net_to_host_u32 (mp->retval);
3146   vl_api_gpe_fwd_entry_t *fwd;
3147
3148   if (retval)
3149     goto end;
3150
3151   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3152   vat_json_init_array (&root);
3153
3154   for (i = 0; i < mp->count; i++)
3155     {
3156       e = vat_json_array_add (&root);
3157       fwd = &mp->entries[i];
3158
3159       vat_json_init_object (e);
3160       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3161       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3162       vat_json_object_add_int (e, "vni", fwd->vni);
3163       vat_json_object_add_int (e, "action", fwd->action);
3164
3165       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3166                   fwd->leid_prefix_len);
3167       vec_add1 (s, 0);
3168       vat_json_object_add_string_copy (e, "leid", s);
3169       vec_free (s);
3170
3171       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3172                   fwd->reid_prefix_len);
3173       vec_add1 (s, 0);
3174       vat_json_object_add_string_copy (e, "reid", s);
3175       vec_free (s);
3176     }
3177
3178   vat_json_print (vam->ofp, &root);
3179   vat_json_free (&root);
3180
3181 end:
3182   vam->retval = retval;
3183   vam->result_ready = 1;
3184 }
3185
3186 static void
3187   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3188   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3189 {
3190   vat_main_t *vam = &vat_main;
3191   u32 i, n;
3192   int retval = clib_net_to_host_u32 (mp->retval);
3193
3194   if (retval)
3195     goto end;
3196
3197   n = clib_net_to_host_u32 (mp->count);
3198
3199   for (i = 0; i < n; i++)
3200     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3201
3202 end:
3203   vam->retval = retval;
3204   vam->result_ready = 1;
3205 }
3206
3207 static void
3208   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3209   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t root;
3213   u32 i, n;
3214   int retval = clib_net_to_host_u32 (mp->retval);
3215
3216   if (retval)
3217     goto end;
3218
3219   n = clib_net_to_host_u32 (mp->count);
3220   vat_json_init_array (&root);
3221
3222   for (i = 0; i < n; i++)
3223     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3224
3225   vat_json_print (vam->ofp, &root);
3226   vat_json_free (&root);
3227
3228 end:
3229   vam->retval = retval;
3230   vam->result_ready = 1;
3231 }
3232
3233 static void
3234   vl_api_one_l2_arp_entries_get_reply_t_handler
3235   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3236 {
3237   vat_main_t *vam = &vat_main;
3238   u32 i, n;
3239   int retval = clib_net_to_host_u32 (mp->retval);
3240
3241   if (retval)
3242     goto end;
3243
3244   n = clib_net_to_host_u32 (mp->count);
3245
3246   for (i = 0; i < n; i++)
3247     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3248            format_ethernet_address, mp->entries[i].mac);
3249
3250 end:
3251   vam->retval = retval;
3252   vam->result_ready = 1;
3253 }
3254
3255 static void
3256   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3257   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3258 {
3259   u8 *s = 0;
3260   vat_main_t *vam = &vat_main;
3261   vat_json_node_t *e = 0, root;
3262   u32 i, n;
3263   int retval = clib_net_to_host_u32 (mp->retval);
3264   vl_api_one_l2_arp_entry_t *arp_entry;
3265
3266   if (retval)
3267     goto end;
3268
3269   n = clib_net_to_host_u32 (mp->count);
3270   vat_json_init_array (&root);
3271
3272   for (i = 0; i < n; i++)
3273     {
3274       e = vat_json_array_add (&root);
3275       arp_entry = &mp->entries[i];
3276
3277       vat_json_init_object (e);
3278       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3279       vec_add1 (s, 0);
3280
3281       vat_json_object_add_string_copy (e, "mac", s);
3282       vec_free (s);
3283
3284       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3285       vec_add1 (s, 0);
3286       vat_json_object_add_string_copy (e, "ip4", s);
3287       vec_free (s);
3288     }
3289
3290   vat_json_print (vam->ofp, &root);
3291   vat_json_free (&root);
3292
3293 end:
3294   vam->retval = retval;
3295   vam->result_ready = 1;
3296 }
3297
3298 static void
3299   vl_api_one_l2_arp_bd_get_reply_t_handler
3300   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3301 {
3302   vat_main_t *vam = &vat_main;
3303   u32 i, n;
3304   int retval = clib_net_to_host_u32 (mp->retval);
3305
3306   if (retval)
3307     goto end;
3308
3309   n = clib_net_to_host_u32 (mp->count);
3310
3311   for (i = 0; i < n; i++)
3312     {
3313       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3314     }
3315
3316 end:
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319 }
3320
3321 static void
3322   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3323   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   vat_json_node_t root;
3327   u32 i, n;
3328   int retval = clib_net_to_host_u32 (mp->retval);
3329
3330   if (retval)
3331     goto end;
3332
3333   n = clib_net_to_host_u32 (mp->count);
3334   vat_json_init_array (&root);
3335
3336   for (i = 0; i < n; i++)
3337     {
3338       vat_json_array_add_uint (&root,
3339                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3340     }
3341
3342   vat_json_print (vam->ofp, &root);
3343   vat_json_free (&root);
3344
3345 end:
3346   vam->retval = retval;
3347   vam->result_ready = 1;
3348 }
3349
3350 static void
3351   vl_api_one_adjacencies_get_reply_t_handler
3352   (vl_api_one_adjacencies_get_reply_t * mp)
3353 {
3354   vat_main_t *vam = &vat_main;
3355   u32 i, n;
3356   int retval = clib_net_to_host_u32 (mp->retval);
3357   vl_api_one_adjacency_t *a;
3358
3359   if (retval)
3360     goto end;
3361
3362   n = clib_net_to_host_u32 (mp->count);
3363
3364   for (i = 0; i < n; i++)
3365     {
3366       a = &mp->adjacencies[i];
3367       print (vam->ofp, "%U %40U",
3368              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3369              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3370     }
3371
3372 end:
3373   vam->retval = retval;
3374   vam->result_ready = 1;
3375 }
3376
3377 static void
3378   vl_api_one_adjacencies_get_reply_t_handler_json
3379   (vl_api_one_adjacencies_get_reply_t * mp)
3380 {
3381   u8 *s = 0;
3382   vat_main_t *vam = &vat_main;
3383   vat_json_node_t *e = 0, root;
3384   u32 i, n;
3385   int retval = clib_net_to_host_u32 (mp->retval);
3386   vl_api_one_adjacency_t *a;
3387
3388   if (retval)
3389     goto end;
3390
3391   n = clib_net_to_host_u32 (mp->count);
3392   vat_json_init_array (&root);
3393
3394   for (i = 0; i < n; i++)
3395     {
3396       e = vat_json_array_add (&root);
3397       a = &mp->adjacencies[i];
3398
3399       vat_json_init_object (e);
3400       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3401                   a->leid_prefix_len);
3402       vec_add1 (s, 0);
3403       vat_json_object_add_string_copy (e, "leid", s);
3404       vec_free (s);
3405
3406       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3407                   a->reid_prefix_len);
3408       vec_add1 (s, 0);
3409       vat_json_object_add_string_copy (e, "reid", s);
3410       vec_free (s);
3411     }
3412
3413   vat_json_print (vam->ofp, &root);
3414   vat_json_free (&root);
3415
3416 end:
3417   vam->retval = retval;
3418   vam->result_ready = 1;
3419 }
3420
3421 static void
3422 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425
3426   print (vam->ofp, "%=20U",
3427          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3428          mp->ip_address);
3429 }
3430
3431 static void
3432   vl_api_one_map_server_details_t_handler_json
3433   (vl_api_one_map_server_details_t * mp)
3434 {
3435   vat_main_t *vam = &vat_main;
3436   vat_json_node_t *node = NULL;
3437   struct in6_addr ip6;
3438   struct in_addr ip4;
3439
3440   if (VAT_JSON_ARRAY != vam->json_tree.type)
3441     {
3442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3443       vat_json_init_array (&vam->json_tree);
3444     }
3445   node = vat_json_array_add (&vam->json_tree);
3446
3447   vat_json_init_object (node);
3448   if (mp->is_ipv6)
3449     {
3450       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3451       vat_json_object_add_ip6 (node, "map-server", ip6);
3452     }
3453   else
3454     {
3455       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3456       vat_json_object_add_ip4 (node, "map-server", ip4);
3457     }
3458 }
3459
3460 static void
3461 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3462                                            * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465
3466   print (vam->ofp, "%=20U",
3467          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3468          mp->ip_address);
3469 }
3470
3471 static void
3472   vl_api_one_map_resolver_details_t_handler_json
3473   (vl_api_one_map_resolver_details_t * mp)
3474 {
3475   vat_main_t *vam = &vat_main;
3476   vat_json_node_t *node = NULL;
3477   struct in6_addr ip6;
3478   struct in_addr ip4;
3479
3480   if (VAT_JSON_ARRAY != vam->json_tree.type)
3481     {
3482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3483       vat_json_init_array (&vam->json_tree);
3484     }
3485   node = vat_json_array_add (&vam->json_tree);
3486
3487   vat_json_init_object (node);
3488   if (mp->is_ipv6)
3489     {
3490       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3491       vat_json_object_add_ip6 (node, "map resolver", ip6);
3492     }
3493   else
3494     {
3495       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3496       vat_json_object_add_ip4 (node, "map resolver", ip4);
3497     }
3498 }
3499
3500 static void
3501 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3502 {
3503   vat_main_t *vam = &vat_main;
3504   i32 retval = ntohl (mp->retval);
3505
3506   if (0 <= retval)
3507     {
3508       print (vam->ofp, "feature: %s\ngpe: %s",
3509              mp->feature_status ? "enabled" : "disabled",
3510              mp->gpe_status ? "enabled" : "disabled");
3511     }
3512
3513   vam->retval = retval;
3514   vam->result_ready = 1;
3515 }
3516
3517 static void
3518   vl_api_show_one_status_reply_t_handler_json
3519   (vl_api_show_one_status_reply_t * mp)
3520 {
3521   vat_main_t *vam = &vat_main;
3522   vat_json_node_t node;
3523   u8 *gpe_status = NULL;
3524   u8 *feature_status = NULL;
3525
3526   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3527   feature_status = format (0, "%s",
3528                            mp->feature_status ? "enabled" : "disabled");
3529   vec_add1 (gpe_status, 0);
3530   vec_add1 (feature_status, 0);
3531
3532   vat_json_init_object (&node);
3533   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3534   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3535
3536   vec_free (gpe_status);
3537   vec_free (feature_status);
3538
3539   vat_json_print (vam->ofp, &node);
3540   vat_json_free (&node);
3541
3542   vam->retval = ntohl (mp->retval);
3543   vam->result_ready = 1;
3544 }
3545
3546 static void
3547   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3548   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3549 {
3550   vat_main_t *vam = &vat_main;
3551   i32 retval = ntohl (mp->retval);
3552
3553   if (retval >= 0)
3554     {
3555       print (vam->ofp, "%=20s", mp->locator_set_name);
3556     }
3557
3558   vam->retval = retval;
3559   vam->result_ready = 1;
3560 }
3561
3562 static void
3563   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3564   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3565 {
3566   vat_main_t *vam = &vat_main;
3567   vat_json_node_t *node = NULL;
3568
3569   if (VAT_JSON_ARRAY != vam->json_tree.type)
3570     {
3571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3572       vat_json_init_array (&vam->json_tree);
3573     }
3574   node = vat_json_array_add (&vam->json_tree);
3575
3576   vat_json_init_object (node);
3577   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3578
3579   vat_json_print (vam->ofp, node);
3580   vat_json_free (node);
3581
3582   vam->retval = ntohl (mp->retval);
3583   vam->result_ready = 1;
3584 }
3585
3586 static u8 *
3587 format_lisp_map_request_mode (u8 * s, va_list * args)
3588 {
3589   u32 mode = va_arg (*args, u32);
3590
3591   switch (mode)
3592     {
3593     case 0:
3594       return format (0, "dst-only");
3595     case 1:
3596       return format (0, "src-dst");
3597     }
3598   return 0;
3599 }
3600
3601 static void
3602   vl_api_show_one_map_request_mode_reply_t_handler
3603   (vl_api_show_one_map_request_mode_reply_t * mp)
3604 {
3605   vat_main_t *vam = &vat_main;
3606   i32 retval = ntohl (mp->retval);
3607
3608   if (0 <= retval)
3609     {
3610       u32 mode = mp->mode;
3611       print (vam->ofp, "map_request_mode: %U",
3612              format_lisp_map_request_mode, mode);
3613     }
3614
3615   vam->retval = retval;
3616   vam->result_ready = 1;
3617 }
3618
3619 static void
3620   vl_api_show_one_map_request_mode_reply_t_handler_json
3621   (vl_api_show_one_map_request_mode_reply_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   vat_json_node_t node;
3625   u8 *s = 0;
3626   u32 mode;
3627
3628   mode = mp->mode;
3629   s = format (0, "%U", format_lisp_map_request_mode, mode);
3630   vec_add1 (s, 0);
3631
3632   vat_json_init_object (&node);
3633   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3634   vat_json_print (vam->ofp, &node);
3635   vat_json_free (&node);
3636
3637   vec_free (s);
3638   vam->retval = ntohl (mp->retval);
3639   vam->result_ready = 1;
3640 }
3641
3642 static void
3643   vl_api_show_one_use_petr_reply_t_handler
3644   (vl_api_show_one_use_petr_reply_t * mp)
3645 {
3646   vat_main_t *vam = &vat_main;
3647   i32 retval = ntohl (mp->retval);
3648
3649   if (0 <= retval)
3650     {
3651       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3652       if (mp->status)
3653         {
3654           print (vam->ofp, "Proxy-ETR address; %U",
3655                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3656                  mp->address);
3657         }
3658     }
3659
3660   vam->retval = retval;
3661   vam->result_ready = 1;
3662 }
3663
3664 static void
3665   vl_api_show_one_use_petr_reply_t_handler_json
3666   (vl_api_show_one_use_petr_reply_t * mp)
3667 {
3668   vat_main_t *vam = &vat_main;
3669   vat_json_node_t node;
3670   u8 *status = 0;
3671   struct in_addr ip4;
3672   struct in6_addr ip6;
3673
3674   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3675   vec_add1 (status, 0);
3676
3677   vat_json_init_object (&node);
3678   vat_json_object_add_string_copy (&node, "status", status);
3679   if (mp->status)
3680     {
3681       if (mp->is_ip4)
3682         {
3683           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3684           vat_json_object_add_ip6 (&node, "address", ip6);
3685         }
3686       else
3687         {
3688           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3689           vat_json_object_add_ip4 (&node, "address", ip4);
3690         }
3691     }
3692
3693   vec_free (status);
3694
3695   vat_json_print (vam->ofp, &node);
3696   vat_json_free (&node);
3697
3698   vam->retval = ntohl (mp->retval);
3699   vam->result_ready = 1;
3700 }
3701
3702 static void
3703   vl_api_show_one_nsh_mapping_reply_t_handler
3704   (vl_api_show_one_nsh_mapping_reply_t * mp)
3705 {
3706   vat_main_t *vam = &vat_main;
3707   i32 retval = ntohl (mp->retval);
3708
3709   if (0 <= retval)
3710     {
3711       print (vam->ofp, "%-20s%-16s",
3712              mp->is_set ? "set" : "not-set",
3713              mp->is_set ? (char *) mp->locator_set_name : "");
3714     }
3715
3716   vam->retval = retval;
3717   vam->result_ready = 1;
3718 }
3719
3720 static void
3721   vl_api_show_one_nsh_mapping_reply_t_handler_json
3722   (vl_api_show_one_nsh_mapping_reply_t * mp)
3723 {
3724   vat_main_t *vam = &vat_main;
3725   vat_json_node_t node;
3726   u8 *status = 0;
3727
3728   status = format (0, "%s", mp->is_set ? "yes" : "no");
3729   vec_add1 (status, 0);
3730
3731   vat_json_init_object (&node);
3732   vat_json_object_add_string_copy (&node, "is_set", status);
3733   if (mp->is_set)
3734     {
3735       vat_json_object_add_string_copy (&node, "locator_set",
3736                                        mp->locator_set_name);
3737     }
3738
3739   vec_free (status);
3740
3741   vat_json_print (vam->ofp, &node);
3742   vat_json_free (&node);
3743
3744   vam->retval = ntohl (mp->retval);
3745   vam->result_ready = 1;
3746 }
3747
3748 static void
3749 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3750 {
3751   vat_main_t *vam = &vat_main;
3752   i32 retval = ntohl (mp->retval);
3753
3754   if (0 <= retval)
3755     {
3756       print (vam->ofp, "%-20s%-16s",
3757              mp->status ? "enabled" : "disabled",
3758              mp->status ? (char *) mp->locator_set_name : "");
3759     }
3760
3761   vam->retval = retval;
3762   vam->result_ready = 1;
3763 }
3764
3765 static void
3766 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3767 {
3768   vat_main_t *vam = &vat_main;
3769   vat_json_node_t node;
3770   u8 *status = 0;
3771
3772   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3773   vec_add1 (status, 0);
3774
3775   vat_json_init_object (&node);
3776   vat_json_object_add_string_copy (&node, "status", status);
3777   if (mp->status)
3778     {
3779       vat_json_object_add_string_copy (&node, "locator_set",
3780                                        mp->locator_set_name);
3781     }
3782
3783   vec_free (status);
3784
3785   vat_json_print (vam->ofp, &node);
3786   vat_json_free (&node);
3787
3788   vam->retval = ntohl (mp->retval);
3789   vam->result_ready = 1;
3790 }
3791
3792 static u8 *
3793 format_policer_type (u8 * s, va_list * va)
3794 {
3795   u32 i = va_arg (*va, u32);
3796
3797   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3798     s = format (s, "1r2c");
3799   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3800     s = format (s, "1r3c");
3801   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3802     s = format (s, "2r3c-2698");
3803   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3804     s = format (s, "2r3c-4115");
3805   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3806     s = format (s, "2r3c-mef5cf1");
3807   else
3808     s = format (s, "ILLEGAL");
3809   return s;
3810 }
3811
3812 static u8 *
3813 format_policer_rate_type (u8 * s, va_list * va)
3814 {
3815   u32 i = va_arg (*va, u32);
3816
3817   if (i == SSE2_QOS_RATE_KBPS)
3818     s = format (s, "kbps");
3819   else if (i == SSE2_QOS_RATE_PPS)
3820     s = format (s, "pps");
3821   else
3822     s = format (s, "ILLEGAL");
3823   return s;
3824 }
3825
3826 static u8 *
3827 format_policer_round_type (u8 * s, va_list * va)
3828 {
3829   u32 i = va_arg (*va, u32);
3830
3831   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3832     s = format (s, "closest");
3833   else if (i == SSE2_QOS_ROUND_TO_UP)
3834     s = format (s, "up");
3835   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3836     s = format (s, "down");
3837   else
3838     s = format (s, "ILLEGAL");
3839   return s;
3840 }
3841
3842 static u8 *
3843 format_policer_action_type (u8 * s, va_list * va)
3844 {
3845   u32 i = va_arg (*va, u32);
3846
3847   if (i == SSE2_QOS_ACTION_DROP)
3848     s = format (s, "drop");
3849   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3850     s = format (s, "transmit");
3851   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3852     s = format (s, "mark-and-transmit");
3853   else
3854     s = format (s, "ILLEGAL");
3855   return s;
3856 }
3857
3858 static u8 *
3859 format_dscp (u8 * s, va_list * va)
3860 {
3861   u32 i = va_arg (*va, u32);
3862   char *t = 0;
3863
3864   switch (i)
3865     {
3866 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3867       foreach_vnet_dscp
3868 #undef _
3869     default:
3870       return format (s, "ILLEGAL");
3871     }
3872   s = format (s, "%s", t);
3873   return s;
3874 }
3875
3876 static void
3877 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3878 {
3879   vat_main_t *vam = &vat_main;
3880   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3881
3882   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3883     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3884   else
3885     conform_dscp_str = format (0, "");
3886
3887   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3888     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3889   else
3890     exceed_dscp_str = format (0, "");
3891
3892   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3893     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3894   else
3895     violate_dscp_str = format (0, "");
3896
3897   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3898          "rate type %U, round type %U, %s rate, %s color-aware, "
3899          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3900          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3901          "conform action %U%s, exceed action %U%s, violate action %U%s",
3902          mp->name,
3903          format_policer_type, mp->type,
3904          ntohl (mp->cir),
3905          ntohl (mp->eir),
3906          clib_net_to_host_u64 (mp->cb),
3907          clib_net_to_host_u64 (mp->eb),
3908          format_policer_rate_type, mp->rate_type,
3909          format_policer_round_type, mp->round_type,
3910          mp->single_rate ? "single" : "dual",
3911          mp->color_aware ? "is" : "not",
3912          ntohl (mp->cir_tokens_per_period),
3913          ntohl (mp->pir_tokens_per_period),
3914          ntohl (mp->scale),
3915          ntohl (mp->current_limit),
3916          ntohl (mp->current_bucket),
3917          ntohl (mp->extended_limit),
3918          ntohl (mp->extended_bucket),
3919          clib_net_to_host_u64 (mp->last_update_time),
3920          format_policer_action_type, mp->conform_action_type,
3921          conform_dscp_str,
3922          format_policer_action_type, mp->exceed_action_type,
3923          exceed_dscp_str,
3924          format_policer_action_type, mp->violate_action_type,
3925          violate_dscp_str);
3926
3927   vec_free (conform_dscp_str);
3928   vec_free (exceed_dscp_str);
3929   vec_free (violate_dscp_str);
3930 }
3931
3932 static void vl_api_policer_details_t_handler_json
3933   (vl_api_policer_details_t * mp)
3934 {
3935   vat_main_t *vam = &vat_main;
3936   vat_json_node_t *node;
3937   u8 *rate_type_str, *round_type_str, *type_str;
3938   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3939
3940   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3941   round_type_str =
3942     format (0, "%U", format_policer_round_type, mp->round_type);
3943   type_str = format (0, "%U", format_policer_type, mp->type);
3944   conform_action_str = format (0, "%U", format_policer_action_type,
3945                                mp->conform_action_type);
3946   exceed_action_str = format (0, "%U", format_policer_action_type,
3947                               mp->exceed_action_type);
3948   violate_action_str = format (0, "%U", format_policer_action_type,
3949                                mp->violate_action_type);
3950
3951   if (VAT_JSON_ARRAY != vam->json_tree.type)
3952     {
3953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3954       vat_json_init_array (&vam->json_tree);
3955     }
3956   node = vat_json_array_add (&vam->json_tree);
3957
3958   vat_json_init_object (node);
3959   vat_json_object_add_string_copy (node, "name", mp->name);
3960   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3961   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3962   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3963   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3964   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3965   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3966   vat_json_object_add_string_copy (node, "type", type_str);
3967   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3968   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3969   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3970   vat_json_object_add_uint (node, "cir_tokens_per_period",
3971                             ntohl (mp->cir_tokens_per_period));
3972   vat_json_object_add_uint (node, "eir_tokens_per_period",
3973                             ntohl (mp->pir_tokens_per_period));
3974   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3975   vat_json_object_add_uint (node, "current_bucket",
3976                             ntohl (mp->current_bucket));
3977   vat_json_object_add_uint (node, "extended_limit",
3978                             ntohl (mp->extended_limit));
3979   vat_json_object_add_uint (node, "extended_bucket",
3980                             ntohl (mp->extended_bucket));
3981   vat_json_object_add_uint (node, "last_update_time",
3982                             ntohl (mp->last_update_time));
3983   vat_json_object_add_string_copy (node, "conform_action",
3984                                    conform_action_str);
3985   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3986     {
3987       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3988       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3989       vec_free (dscp_str);
3990     }
3991   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3992   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3993     {
3994       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3995       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3996       vec_free (dscp_str);
3997     }
3998   vat_json_object_add_string_copy (node, "violate_action",
3999                                    violate_action_str);
4000   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4001     {
4002       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4003       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4004       vec_free (dscp_str);
4005     }
4006
4007   vec_free (rate_type_str);
4008   vec_free (round_type_str);
4009   vec_free (type_str);
4010   vec_free (conform_action_str);
4011   vec_free (exceed_action_str);
4012   vec_free (violate_action_str);
4013 }
4014
4015 static void
4016 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4017                                            mp)
4018 {
4019   vat_main_t *vam = &vat_main;
4020   int i, count = ntohl (mp->count);
4021
4022   if (count > 0)
4023     print (vam->ofp, "classify table ids (%d) : ", count);
4024   for (i = 0; i < count; i++)
4025     {
4026       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4027       print (vam->ofp, (i < count - 1) ? "," : "");
4028     }
4029   vam->retval = ntohl (mp->retval);
4030   vam->result_ready = 1;
4031 }
4032
4033 static void
4034   vl_api_classify_table_ids_reply_t_handler_json
4035   (vl_api_classify_table_ids_reply_t * mp)
4036 {
4037   vat_main_t *vam = &vat_main;
4038   int i, count = ntohl (mp->count);
4039
4040   if (count > 0)
4041     {
4042       vat_json_node_t node;
4043
4044       vat_json_init_object (&node);
4045       for (i = 0; i < count; i++)
4046         {
4047           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4048         }
4049       vat_json_print (vam->ofp, &node);
4050       vat_json_free (&node);
4051     }
4052   vam->retval = ntohl (mp->retval);
4053   vam->result_ready = 1;
4054 }
4055
4056 static void
4057   vl_api_classify_table_by_interface_reply_t_handler
4058   (vl_api_classify_table_by_interface_reply_t * mp)
4059 {
4060   vat_main_t *vam = &vat_main;
4061   u32 table_id;
4062
4063   table_id = ntohl (mp->l2_table_id);
4064   if (table_id != ~0)
4065     print (vam->ofp, "l2 table id : %d", table_id);
4066   else
4067     print (vam->ofp, "l2 table id : No input ACL tables configured");
4068   table_id = ntohl (mp->ip4_table_id);
4069   if (table_id != ~0)
4070     print (vam->ofp, "ip4 table id : %d", table_id);
4071   else
4072     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4073   table_id = ntohl (mp->ip6_table_id);
4074   if (table_id != ~0)
4075     print (vam->ofp, "ip6 table id : %d", table_id);
4076   else
4077     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4078   vam->retval = ntohl (mp->retval);
4079   vam->result_ready = 1;
4080 }
4081
4082 static void
4083   vl_api_classify_table_by_interface_reply_t_handler_json
4084   (vl_api_classify_table_by_interface_reply_t * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087   vat_json_node_t node;
4088
4089   vat_json_init_object (&node);
4090
4091   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4092   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4093   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4094
4095   vat_json_print (vam->ofp, &node);
4096   vat_json_free (&node);
4097
4098   vam->retval = ntohl (mp->retval);
4099   vam->result_ready = 1;
4100 }
4101
4102 static void vl_api_policer_add_del_reply_t_handler
4103   (vl_api_policer_add_del_reply_t * mp)
4104 {
4105   vat_main_t *vam = &vat_main;
4106   i32 retval = ntohl (mp->retval);
4107   if (vam->async_mode)
4108     {
4109       vam->async_errors += (retval < 0);
4110     }
4111   else
4112     {
4113       vam->retval = retval;
4114       vam->result_ready = 1;
4115       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4116         /*
4117          * Note: this is just barely thread-safe, depends on
4118          * the main thread spinning waiting for an answer...
4119          */
4120         errmsg ("policer index %d", ntohl (mp->policer_index));
4121     }
4122 }
4123
4124 static void vl_api_policer_add_del_reply_t_handler_json
4125   (vl_api_policer_add_del_reply_t * mp)
4126 {
4127   vat_main_t *vam = &vat_main;
4128   vat_json_node_t node;
4129
4130   vat_json_init_object (&node);
4131   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4132   vat_json_object_add_uint (&node, "policer_index",
4133                             ntohl (mp->policer_index));
4134
4135   vat_json_print (vam->ofp, &node);
4136   vat_json_free (&node);
4137
4138   vam->retval = ntohl (mp->retval);
4139   vam->result_ready = 1;
4140 }
4141
4142 /* Format hex dump. */
4143 u8 *
4144 format_hex_bytes (u8 * s, va_list * va)
4145 {
4146   u8 *bytes = va_arg (*va, u8 *);
4147   int n_bytes = va_arg (*va, int);
4148   uword i;
4149
4150   /* Print short or long form depending on byte count. */
4151   uword short_form = n_bytes <= 32;
4152   uword indent = format_get_indent (s);
4153
4154   if (n_bytes == 0)
4155     return s;
4156
4157   for (i = 0; i < n_bytes; i++)
4158     {
4159       if (!short_form && (i % 32) == 0)
4160         s = format (s, "%08x: ", i);
4161       s = format (s, "%02x", bytes[i]);
4162       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4163         s = format (s, "\n%U", format_white_space, indent);
4164     }
4165
4166   return s;
4167 }
4168
4169 static void
4170 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4171                                             * mp)
4172 {
4173   vat_main_t *vam = &vat_main;
4174   i32 retval = ntohl (mp->retval);
4175   if (retval == 0)
4176     {
4177       print (vam->ofp, "classify table info :");
4178       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4179              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4180              ntohl (mp->miss_next_index));
4181       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4182              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4183              ntohl (mp->match_n_vectors));
4184       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4185              ntohl (mp->mask_length));
4186     }
4187   vam->retval = retval;
4188   vam->result_ready = 1;
4189 }
4190
4191 static void
4192   vl_api_classify_table_info_reply_t_handler_json
4193   (vl_api_classify_table_info_reply_t * mp)
4194 {
4195   vat_main_t *vam = &vat_main;
4196   vat_json_node_t node;
4197
4198   i32 retval = ntohl (mp->retval);
4199   if (retval == 0)
4200     {
4201       vat_json_init_object (&node);
4202
4203       vat_json_object_add_int (&node, "sessions",
4204                                ntohl (mp->active_sessions));
4205       vat_json_object_add_int (&node, "nexttbl",
4206                                ntohl (mp->next_table_index));
4207       vat_json_object_add_int (&node, "nextnode",
4208                                ntohl (mp->miss_next_index));
4209       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4210       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4211       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4212       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4213                       ntohl (mp->mask_length), 0);
4214       vat_json_object_add_string_copy (&node, "mask", s);
4215
4216       vat_json_print (vam->ofp, &node);
4217       vat_json_free (&node);
4218     }
4219   vam->retval = ntohl (mp->retval);
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4225                                            mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228
4229   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4230          ntohl (mp->hit_next_index), ntohl (mp->advance),
4231          ntohl (mp->opaque_index));
4232   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4233          ntohl (mp->match_length));
4234 }
4235
4236 static void
4237   vl_api_classify_session_details_t_handler_json
4238   (vl_api_classify_session_details_t * mp)
4239 {
4240   vat_main_t *vam = &vat_main;
4241   vat_json_node_t *node = NULL;
4242
4243   if (VAT_JSON_ARRAY != vam->json_tree.type)
4244     {
4245       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4246       vat_json_init_array (&vam->json_tree);
4247     }
4248   node = vat_json_array_add (&vam->json_tree);
4249
4250   vat_json_init_object (node);
4251   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4252   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4253   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4254   u8 *s =
4255     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4256             0);
4257   vat_json_object_add_string_copy (node, "match", s);
4258 }
4259
4260 static void vl_api_pg_create_interface_reply_t_handler
4261   (vl_api_pg_create_interface_reply_t * mp)
4262 {
4263   vat_main_t *vam = &vat_main;
4264
4265   vam->retval = ntohl (mp->retval);
4266   vam->result_ready = 1;
4267 }
4268
4269 static void vl_api_pg_create_interface_reply_t_handler_json
4270   (vl_api_pg_create_interface_reply_t * mp)
4271 {
4272   vat_main_t *vam = &vat_main;
4273   vat_json_node_t node;
4274
4275   i32 retval = ntohl (mp->retval);
4276   if (retval == 0)
4277     {
4278       vat_json_init_object (&node);
4279
4280       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4281
4282       vat_json_print (vam->ofp, &node);
4283       vat_json_free (&node);
4284     }
4285   vam->retval = ntohl (mp->retval);
4286   vam->result_ready = 1;
4287 }
4288
4289 static void vl_api_policer_classify_details_t_handler
4290   (vl_api_policer_classify_details_t * mp)
4291 {
4292   vat_main_t *vam = &vat_main;
4293
4294   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4295          ntohl (mp->table_index));
4296 }
4297
4298 static void vl_api_policer_classify_details_t_handler_json
4299   (vl_api_policer_classify_details_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   vat_json_node_t *node;
4303
4304   if (VAT_JSON_ARRAY != vam->json_tree.type)
4305     {
4306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4307       vat_json_init_array (&vam->json_tree);
4308     }
4309   node = vat_json_array_add (&vam->json_tree);
4310
4311   vat_json_init_object (node);
4312   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4313   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4314 }
4315
4316 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4317   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4318 {
4319   vat_main_t *vam = &vat_main;
4320   i32 retval = ntohl (mp->retval);
4321   if (vam->async_mode)
4322     {
4323       vam->async_errors += (retval < 0);
4324     }
4325   else
4326     {
4327       vam->retval = retval;
4328       vam->sw_if_index = ntohl (mp->sw_if_index);
4329       vam->result_ready = 1;
4330     }
4331 }
4332
4333 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4334   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4335 {
4336   vat_main_t *vam = &vat_main;
4337   vat_json_node_t node;
4338
4339   vat_json_init_object (&node);
4340   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4341   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4342
4343   vat_json_print (vam->ofp, &node);
4344   vat_json_free (&node);
4345
4346   vam->retval = ntohl (mp->retval);
4347   vam->result_ready = 1;
4348 }
4349
4350 static void vl_api_flow_classify_details_t_handler
4351   (vl_api_flow_classify_details_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354
4355   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4356          ntohl (mp->table_index));
4357 }
4358
4359 static void vl_api_flow_classify_details_t_handler_json
4360   (vl_api_flow_classify_details_t * mp)
4361 {
4362   vat_main_t *vam = &vat_main;
4363   vat_json_node_t *node;
4364
4365   if (VAT_JSON_ARRAY != vam->json_tree.type)
4366     {
4367       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4368       vat_json_init_array (&vam->json_tree);
4369     }
4370   node = vat_json_array_add (&vam->json_tree);
4371
4372   vat_json_init_object (node);
4373   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4374   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4375 }
4376
4377 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4378 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4379 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4380 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4381 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4382 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4383 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4384 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4385 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4386 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4387 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4388 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4389 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4390 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4391 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4392 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4393 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4394 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4395
4396 /*
4397  * Generate boilerplate reply handlers, which
4398  * dig the return value out of the xxx_reply_t API message,
4399  * stick it into vam->retval, and set vam->result_ready
4400  *
4401  * Could also do this by pointing N message decode slots at
4402  * a single function, but that could break in subtle ways.
4403  */
4404
4405 #define foreach_standard_reply_retval_handler           \
4406 _(sw_interface_set_flags_reply)                         \
4407 _(sw_interface_add_del_address_reply)                   \
4408 _(sw_interface_set_table_reply)                         \
4409 _(sw_interface_set_mpls_enable_reply)                   \
4410 _(sw_interface_set_vpath_reply)                         \
4411 _(sw_interface_set_vxlan_bypass_reply)                  \
4412 _(sw_interface_set_l2_bridge_reply)                     \
4413 _(bridge_domain_add_del_reply)                          \
4414 _(sw_interface_set_l2_xconnect_reply)                   \
4415 _(l2fib_add_del_reply)                                  \
4416 _(l2fib_flush_int_reply)                                \
4417 _(l2fib_flush_bd_reply)                                 \
4418 _(ip_add_del_route_reply)                               \
4419 _(ip_mroute_add_del_reply)                              \
4420 _(mpls_route_add_del_reply)                             \
4421 _(mpls_ip_bind_unbind_reply)                            \
4422 _(proxy_arp_add_del_reply)                              \
4423 _(proxy_arp_intfc_enable_disable_reply)                 \
4424 _(sw_interface_set_unnumbered_reply)                    \
4425 _(ip_neighbor_add_del_reply)                            \
4426 _(reset_vrf_reply)                                      \
4427 _(oam_add_del_reply)                                    \
4428 _(reset_fib_reply)                                      \
4429 _(dhcp_proxy_config_reply)                              \
4430 _(dhcp_proxy_set_vss_reply)                             \
4431 _(dhcp_client_config_reply)                             \
4432 _(set_ip_flow_hash_reply)                               \
4433 _(sw_interface_ip6_enable_disable_reply)                \
4434 _(sw_interface_ip6_set_link_local_address_reply)        \
4435 _(ip6nd_proxy_add_del_reply)                            \
4436 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4437 _(sw_interface_ip6nd_ra_config_reply)                   \
4438 _(set_arp_neighbor_limit_reply)                         \
4439 _(l2_patch_add_del_reply)                               \
4440 _(sr_policy_add_reply)                                  \
4441 _(sr_policy_mod_reply)                                  \
4442 _(sr_policy_del_reply)                                  \
4443 _(sr_localsid_add_del_reply)                            \
4444 _(sr_steering_add_del_reply)                            \
4445 _(classify_add_del_session_reply)                       \
4446 _(classify_set_interface_ip_table_reply)                \
4447 _(classify_set_interface_l2_tables_reply)               \
4448 _(l2tpv3_set_tunnel_cookies_reply)                      \
4449 _(l2tpv3_interface_enable_disable_reply)                \
4450 _(l2tpv3_set_lookup_key_reply)                          \
4451 _(l2_fib_clear_table_reply)                             \
4452 _(l2_interface_efp_filter_reply)                        \
4453 _(l2_interface_vlan_tag_rewrite_reply)                  \
4454 _(modify_vhost_user_if_reply)                           \
4455 _(delete_vhost_user_if_reply)                           \
4456 _(want_ip4_arp_events_reply)                            \
4457 _(want_ip6_nd_events_reply)                             \
4458 _(input_acl_set_interface_reply)                        \
4459 _(ipsec_spd_add_del_reply)                              \
4460 _(ipsec_interface_add_del_spd_reply)                    \
4461 _(ipsec_spd_add_del_entry_reply)                        \
4462 _(ipsec_sad_add_del_entry_reply)                        \
4463 _(ipsec_sa_set_key_reply)                               \
4464 _(ipsec_tunnel_if_add_del_reply)                        \
4465 _(ikev2_profile_add_del_reply)                          \
4466 _(ikev2_profile_set_auth_reply)                         \
4467 _(ikev2_profile_set_id_reply)                           \
4468 _(ikev2_profile_set_ts_reply)                           \
4469 _(ikev2_set_local_key_reply)                            \
4470 _(ikev2_set_responder_reply)                            \
4471 _(ikev2_set_ike_transforms_reply)                       \
4472 _(ikev2_set_esp_transforms_reply)                       \
4473 _(ikev2_set_sa_lifetime_reply)                          \
4474 _(ikev2_initiate_sa_init_reply)                         \
4475 _(ikev2_initiate_del_ike_sa_reply)                      \
4476 _(ikev2_initiate_del_child_sa_reply)                    \
4477 _(ikev2_initiate_rekey_child_sa_reply)                  \
4478 _(delete_loopback_reply)                                \
4479 _(bd_ip_mac_add_del_reply)                              \
4480 _(map_del_domain_reply)                                 \
4481 _(map_add_del_rule_reply)                               \
4482 _(want_interface_events_reply)                          \
4483 _(want_stats_reply)                                     \
4484 _(cop_interface_enable_disable_reply)                   \
4485 _(cop_whitelist_enable_disable_reply)                   \
4486 _(sw_interface_clear_stats_reply)                       \
4487 _(ioam_enable_reply)                              \
4488 _(ioam_disable_reply)                              \
4489 _(one_add_del_locator_reply)                            \
4490 _(one_add_del_local_eid_reply)                          \
4491 _(one_add_del_remote_mapping_reply)                     \
4492 _(one_add_del_adjacency_reply)                          \
4493 _(one_add_del_map_resolver_reply)                       \
4494 _(one_add_del_map_server_reply)                         \
4495 _(one_enable_disable_reply)                             \
4496 _(one_rloc_probe_enable_disable_reply)                  \
4497 _(one_map_register_enable_disable_reply)                \
4498 _(one_pitr_set_locator_set_reply)                       \
4499 _(one_map_request_mode_reply)                           \
4500 _(one_add_del_map_request_itr_rlocs_reply)              \
4501 _(one_eid_table_add_del_map_reply)                      \
4502 _(one_use_petr_reply)                                   \
4503 _(one_stats_enable_disable_reply)                       \
4504 _(one_add_del_l2_arp_entry_reply)                       \
4505 _(one_stats_flush_reply)                                \
4506 _(gpe_enable_disable_reply)                             \
4507 _(gpe_set_encap_mode_reply)                             \
4508 _(gpe_add_del_iface_reply)                              \
4509 _(vxlan_gpe_add_del_tunnel_reply)                       \
4510 _(af_packet_delete_reply)                               \
4511 _(policer_classify_set_interface_reply)                 \
4512 _(netmap_create_reply)                                  \
4513 _(netmap_delete_reply)                                  \
4514 _(set_ipfix_exporter_reply)                             \
4515 _(set_ipfix_classify_stream_reply)                      \
4516 _(ipfix_classify_table_add_del_reply)                   \
4517 _(flow_classify_set_interface_reply)                    \
4518 _(sw_interface_span_enable_disable_reply)               \
4519 _(pg_capture_reply)                                     \
4520 _(pg_enable_disable_reply)                              \
4521 _(ip_source_and_port_range_check_add_del_reply)         \
4522 _(ip_source_and_port_range_check_interface_add_del_reply)\
4523 _(delete_subif_reply)                                   \
4524 _(l2_interface_pbb_tag_rewrite_reply)                   \
4525 _(punt_reply)                                           \
4526 _(feature_enable_disable_reply)                         \
4527 _(sw_interface_tag_add_del_reply)                       \
4528 _(sw_interface_set_mtu_reply)                           \
4529 _(p2p_ethernet_add_reply)                               \
4530 _(p2p_ethernet_del_reply)
4531
4532 #define _(n)                                    \
4533     static void vl_api_##n##_t_handler          \
4534     (vl_api_##n##_t * mp)                       \
4535     {                                           \
4536         vat_main_t * vam = &vat_main;           \
4537         i32 retval = ntohl(mp->retval);         \
4538         if (vam->async_mode) {                  \
4539             vam->async_errors += (retval < 0);  \
4540         } else {                                \
4541             vam->retval = retval;               \
4542             vam->result_ready = 1;              \
4543         }                                       \
4544     }
4545 foreach_standard_reply_retval_handler;
4546 #undef _
4547
4548 #define _(n)                                    \
4549     static void vl_api_##n##_t_handler_json     \
4550     (vl_api_##n##_t * mp)                       \
4551     {                                           \
4552         vat_main_t * vam = &vat_main;           \
4553         vat_json_node_t node;                   \
4554         vat_json_init_object(&node);            \
4555         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4556         vat_json_print(vam->ofp, &node);        \
4557         vam->retval = ntohl(mp->retval);        \
4558         vam->result_ready = 1;                  \
4559     }
4560 foreach_standard_reply_retval_handler;
4561 #undef _
4562
4563 /*
4564  * Table of message reply handlers, must include boilerplate handlers
4565  * we just generated
4566  */
4567
4568 #define foreach_vpe_api_reply_msg                                       \
4569 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4570 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4571 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4572 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4573 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4574 _(CLI_REPLY, cli_reply)                                                 \
4575 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4576 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4577   sw_interface_add_del_address_reply)                                   \
4578 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4579 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4580 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4581 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4582 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4583   sw_interface_set_l2_xconnect_reply)                                   \
4584 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4585   sw_interface_set_l2_bridge_reply)                                     \
4586 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4587 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4588 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4589 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4590 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4591 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4592 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4593 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4594 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4595 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4596 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4597 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4598 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4599 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4600 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4601 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4602 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4603 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4604   proxy_arp_intfc_enable_disable_reply)                                 \
4605 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4606 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4607   sw_interface_set_unnumbered_reply)                                    \
4608 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4609 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4610 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4611 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4612 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4613 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4614 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4615 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4616 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4617 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4618 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4619 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4620   sw_interface_ip6_enable_disable_reply)                                \
4621 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4622   sw_interface_ip6_set_link_local_address_reply)                        \
4623 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4624 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4625 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4626   sw_interface_ip6nd_ra_prefix_reply)                                   \
4627 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4628   sw_interface_ip6nd_ra_config_reply)                                   \
4629 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4630 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4631 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4632 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4633 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4634 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4635 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4636 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4637 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4638 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4639 classify_set_interface_ip_table_reply)                                  \
4640 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4641   classify_set_interface_l2_tables_reply)                               \
4642 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4643 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4644 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4645 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4646 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4647   l2tpv3_interface_enable_disable_reply)                                \
4648 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4649 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4650 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4651 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4652 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4653 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4654 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4655 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4656 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4657 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4658 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4659 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4660 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4661 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4662 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4663 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4664 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4665 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4666 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4667 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4668 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4669 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4670 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4671 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4672 _(IP_DETAILS, ip_details)                                               \
4673 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4674 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4675 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4676 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4677 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4678 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4679 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4680 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4681 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4682 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4683 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4684 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4685 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4686 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4687 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4688 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4689 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4690 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4691 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4692 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4693 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4694 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4695 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4696 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4697 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4698 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4699 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4700 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4701 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4702 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4703 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4704 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4705 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4706 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4707 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4708 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4709 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4710 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4711 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4712 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4713 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4714 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4715 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4716 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4717 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4718   one_map_register_enable_disable_reply)                                \
4719 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4720   one_rloc_probe_enable_disable_reply)                                  \
4721 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4722 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4723 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4724 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4725 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4726 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4727 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4728 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4729 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4730 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4731 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4732 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4733 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4734 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4735 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4736 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4737   show_one_stats_enable_disable_reply)                                  \
4738 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4739 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4740 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4741 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4742 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4743 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4744 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4745 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4746 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4747 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4748 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4749   gpe_fwd_entry_path_details)                                           \
4750 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4751 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4752   one_add_del_map_request_itr_rlocs_reply)                              \
4753 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4754   one_get_map_request_itr_rlocs_reply)                                  \
4755 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4756 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4757 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4758 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4759 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4760 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4761   show_one_map_register_state_reply)                                    \
4762 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4763 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4764 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4765 _(POLICER_DETAILS, policer_details)                                     \
4766 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4767 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4768 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4769 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4770 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4771 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4772 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4773 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4774 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4775 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4776 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4777 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4778 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4779 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4780 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4781 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4782 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4783 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4784 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4785 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4786 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4787 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4788 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4789 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4790 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4791  ip_source_and_port_range_check_add_del_reply)                          \
4792 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4793  ip_source_and_port_range_check_interface_add_del_reply)                \
4794 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4795 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4796 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4797 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4798 _(PUNT_REPLY, punt_reply)                                               \
4799 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4800 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4801 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4802 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4803 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4804 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4805 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4806 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
4807 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
4808 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)
4809
4810 #define foreach_standalone_reply_msg                                    \
4811 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4812 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4813 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4814 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4815 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4816 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4817 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4818
4819 typedef struct
4820 {
4821   u8 *name;
4822   u32 value;
4823 } name_sort_t;
4824
4825
4826 #define STR_VTR_OP_CASE(op)     \
4827     case L2_VTR_ ## op:         \
4828         return "" # op;
4829
4830 static const char *
4831 str_vtr_op (u32 vtr_op)
4832 {
4833   switch (vtr_op)
4834     {
4835       STR_VTR_OP_CASE (DISABLED);
4836       STR_VTR_OP_CASE (PUSH_1);
4837       STR_VTR_OP_CASE (PUSH_2);
4838       STR_VTR_OP_CASE (POP_1);
4839       STR_VTR_OP_CASE (POP_2);
4840       STR_VTR_OP_CASE (TRANSLATE_1_1);
4841       STR_VTR_OP_CASE (TRANSLATE_1_2);
4842       STR_VTR_OP_CASE (TRANSLATE_2_1);
4843       STR_VTR_OP_CASE (TRANSLATE_2_2);
4844     }
4845
4846   return "UNKNOWN";
4847 }
4848
4849 static int
4850 dump_sub_interface_table (vat_main_t * vam)
4851 {
4852   const sw_interface_subif_t *sub = NULL;
4853
4854   if (vam->json_output)
4855     {
4856       clib_warning
4857         ("JSON output supported only for VPE API calls and dump_stats_table");
4858       return -99;
4859     }
4860
4861   print (vam->ofp,
4862          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4863          "Interface", "sw_if_index",
4864          "sub id", "dot1ad", "tags", "outer id",
4865          "inner id", "exact", "default", "outer any", "inner any");
4866
4867   vec_foreach (sub, vam->sw_if_subif_table)
4868   {
4869     print (vam->ofp,
4870            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4871            sub->interface_name,
4872            sub->sw_if_index,
4873            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4874            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4875            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4876            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4877     if (sub->vtr_op != L2_VTR_DISABLED)
4878       {
4879         print (vam->ofp,
4880                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4881                "tag1: %d tag2: %d ]",
4882                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4883                sub->vtr_tag1, sub->vtr_tag2);
4884       }
4885   }
4886
4887   return 0;
4888 }
4889
4890 static int
4891 name_sort_cmp (void *a1, void *a2)
4892 {
4893   name_sort_t *n1 = a1;
4894   name_sort_t *n2 = a2;
4895
4896   return strcmp ((char *) n1->name, (char *) n2->name);
4897 }
4898
4899 static int
4900 dump_interface_table (vat_main_t * vam)
4901 {
4902   hash_pair_t *p;
4903   name_sort_t *nses = 0, *ns;
4904
4905   if (vam->json_output)
4906     {
4907       clib_warning
4908         ("JSON output supported only for VPE API calls and dump_stats_table");
4909       return -99;
4910     }
4911
4912   /* *INDENT-OFF* */
4913   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4914   ({
4915     vec_add2 (nses, ns, 1);
4916     ns->name = (u8 *)(p->key);
4917     ns->value = (u32) p->value[0];
4918   }));
4919   /* *INDENT-ON* */
4920
4921   vec_sort_with_function (nses, name_sort_cmp);
4922
4923   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4924   vec_foreach (ns, nses)
4925   {
4926     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4927   }
4928   vec_free (nses);
4929   return 0;
4930 }
4931
4932 static int
4933 dump_ip_table (vat_main_t * vam, int is_ipv6)
4934 {
4935   const ip_details_t *det = NULL;
4936   const ip_address_details_t *address = NULL;
4937   u32 i = ~0;
4938
4939   print (vam->ofp, "%-12s", "sw_if_index");
4940
4941   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4942   {
4943     i++;
4944     if (!det->present)
4945       {
4946         continue;
4947       }
4948     print (vam->ofp, "%-12d", i);
4949     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4950     if (!det->addr)
4951       {
4952         continue;
4953       }
4954     vec_foreach (address, det->addr)
4955     {
4956       print (vam->ofp,
4957              "            %-30U%-13d",
4958              is_ipv6 ? format_ip6_address : format_ip4_address,
4959              address->ip, address->prefix_length);
4960     }
4961   }
4962
4963   return 0;
4964 }
4965
4966 static int
4967 dump_ipv4_table (vat_main_t * vam)
4968 {
4969   if (vam->json_output)
4970     {
4971       clib_warning
4972         ("JSON output supported only for VPE API calls and dump_stats_table");
4973       return -99;
4974     }
4975
4976   return dump_ip_table (vam, 0);
4977 }
4978
4979 static int
4980 dump_ipv6_table (vat_main_t * vam)
4981 {
4982   if (vam->json_output)
4983     {
4984       clib_warning
4985         ("JSON output supported only for VPE API calls and dump_stats_table");
4986       return -99;
4987     }
4988
4989   return dump_ip_table (vam, 1);
4990 }
4991
4992 static char *
4993 counter_type_to_str (u8 counter_type, u8 is_combined)
4994 {
4995   if (!is_combined)
4996     {
4997       switch (counter_type)
4998         {
4999         case VNET_INTERFACE_COUNTER_DROP:
5000           return "drop";
5001         case VNET_INTERFACE_COUNTER_PUNT:
5002           return "punt";
5003         case VNET_INTERFACE_COUNTER_IP4:
5004           return "ip4";
5005         case VNET_INTERFACE_COUNTER_IP6:
5006           return "ip6";
5007         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5008           return "rx-no-buf";
5009         case VNET_INTERFACE_COUNTER_RX_MISS:
5010           return "rx-miss";
5011         case VNET_INTERFACE_COUNTER_RX_ERROR:
5012           return "rx-error";
5013         case VNET_INTERFACE_COUNTER_TX_ERROR:
5014           return "tx-error";
5015         default:
5016           return "INVALID-COUNTER-TYPE";
5017         }
5018     }
5019   else
5020     {
5021       switch (counter_type)
5022         {
5023         case VNET_INTERFACE_COUNTER_RX:
5024           return "rx";
5025         case VNET_INTERFACE_COUNTER_TX:
5026           return "tx";
5027         default:
5028           return "INVALID-COUNTER-TYPE";
5029         }
5030     }
5031 }
5032
5033 static int
5034 dump_stats_table (vat_main_t * vam)
5035 {
5036   vat_json_node_t node;
5037   vat_json_node_t *msg_array;
5038   vat_json_node_t *msg;
5039   vat_json_node_t *counter_array;
5040   vat_json_node_t *counter;
5041   interface_counter_t c;
5042   u64 packets;
5043   ip4_fib_counter_t *c4;
5044   ip6_fib_counter_t *c6;
5045   ip4_nbr_counter_t *n4;
5046   ip6_nbr_counter_t *n6;
5047   int i, j;
5048
5049   if (!vam->json_output)
5050     {
5051       clib_warning ("dump_stats_table supported only in JSON format");
5052       return -99;
5053     }
5054
5055   vat_json_init_object (&node);
5056
5057   /* interface counters */
5058   msg_array = vat_json_object_add (&node, "interface_counters");
5059   vat_json_init_array (msg_array);
5060   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5061     {
5062       msg = vat_json_array_add (msg_array);
5063       vat_json_init_object (msg);
5064       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5065                                        (u8 *) counter_type_to_str (i, 0));
5066       vat_json_object_add_int (msg, "is_combined", 0);
5067       counter_array = vat_json_object_add (msg, "data");
5068       vat_json_init_array (counter_array);
5069       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5070         {
5071           packets = vam->simple_interface_counters[i][j];
5072           vat_json_array_add_uint (counter_array, packets);
5073         }
5074     }
5075   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5076     {
5077       msg = vat_json_array_add (msg_array);
5078       vat_json_init_object (msg);
5079       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5080                                        (u8 *) counter_type_to_str (i, 1));
5081       vat_json_object_add_int (msg, "is_combined", 1);
5082       counter_array = vat_json_object_add (msg, "data");
5083       vat_json_init_array (counter_array);
5084       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5085         {
5086           c = vam->combined_interface_counters[i][j];
5087           counter = vat_json_array_add (counter_array);
5088           vat_json_init_object (counter);
5089           vat_json_object_add_uint (counter, "packets", c.packets);
5090           vat_json_object_add_uint (counter, "bytes", c.bytes);
5091         }
5092     }
5093
5094   /* ip4 fib counters */
5095   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5096   vat_json_init_array (msg_array);
5097   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5098     {
5099       msg = vat_json_array_add (msg_array);
5100       vat_json_init_object (msg);
5101       vat_json_object_add_uint (msg, "vrf_id",
5102                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5103       counter_array = vat_json_object_add (msg, "c");
5104       vat_json_init_array (counter_array);
5105       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5106         {
5107           counter = vat_json_array_add (counter_array);
5108           vat_json_init_object (counter);
5109           c4 = &vam->ip4_fib_counters[i][j];
5110           vat_json_object_add_ip4 (counter, "address", c4->address);
5111           vat_json_object_add_uint (counter, "address_length",
5112                                     c4->address_length);
5113           vat_json_object_add_uint (counter, "packets", c4->packets);
5114           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5115         }
5116     }
5117
5118   /* ip6 fib counters */
5119   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5120   vat_json_init_array (msg_array);
5121   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5122     {
5123       msg = vat_json_array_add (msg_array);
5124       vat_json_init_object (msg);
5125       vat_json_object_add_uint (msg, "vrf_id",
5126                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5127       counter_array = vat_json_object_add (msg, "c");
5128       vat_json_init_array (counter_array);
5129       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5130         {
5131           counter = vat_json_array_add (counter_array);
5132           vat_json_init_object (counter);
5133           c6 = &vam->ip6_fib_counters[i][j];
5134           vat_json_object_add_ip6 (counter, "address", c6->address);
5135           vat_json_object_add_uint (counter, "address_length",
5136                                     c6->address_length);
5137           vat_json_object_add_uint (counter, "packets", c6->packets);
5138           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5139         }
5140     }
5141
5142   /* ip4 nbr counters */
5143   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5144   vat_json_init_array (msg_array);
5145   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5146     {
5147       msg = vat_json_array_add (msg_array);
5148       vat_json_init_object (msg);
5149       vat_json_object_add_uint (msg, "sw_if_index", i);
5150       counter_array = vat_json_object_add (msg, "c");
5151       vat_json_init_array (counter_array);
5152       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5153         {
5154           counter = vat_json_array_add (counter_array);
5155           vat_json_init_object (counter);
5156           n4 = &vam->ip4_nbr_counters[i][j];
5157           vat_json_object_add_ip4 (counter, "address", n4->address);
5158           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5159           vat_json_object_add_uint (counter, "packets", n4->packets);
5160           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5161         }
5162     }
5163
5164   /* ip6 nbr counters */
5165   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5166   vat_json_init_array (msg_array);
5167   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5168     {
5169       msg = vat_json_array_add (msg_array);
5170       vat_json_init_object (msg);
5171       vat_json_object_add_uint (msg, "sw_if_index", i);
5172       counter_array = vat_json_object_add (msg, "c");
5173       vat_json_init_array (counter_array);
5174       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5175         {
5176           counter = vat_json_array_add (counter_array);
5177           vat_json_init_object (counter);
5178           n6 = &vam->ip6_nbr_counters[i][j];
5179           vat_json_object_add_ip6 (counter, "address", n6->address);
5180           vat_json_object_add_uint (counter, "packets", n6->packets);
5181           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5182         }
5183     }
5184
5185   vat_json_print (vam->ofp, &node);
5186   vat_json_free (&node);
5187
5188   return 0;
5189 }
5190
5191 int
5192 exec (vat_main_t * vam)
5193 {
5194   api_main_t *am = &api_main;
5195   vl_api_cli_t *mp;
5196   f64 timeout;
5197   void *oldheap;
5198   u8 *cmd = 0;
5199   unformat_input_t *i = vam->input;
5200
5201   if (vec_len (i->buffer) == 0)
5202     return -1;
5203
5204   if (vam->exec_mode == 0 && unformat (i, "mode"))
5205     {
5206       vam->exec_mode = 1;
5207       return 0;
5208     }
5209   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5210     {
5211       vam->exec_mode = 0;
5212       return 0;
5213     }
5214
5215
5216   M (CLI, mp);
5217
5218   /*
5219    * Copy cmd into shared memory.
5220    * In order for the CLI command to work, it
5221    * must be a vector ending in \n, not a C-string ending
5222    * in \n\0.
5223    */
5224   pthread_mutex_lock (&am->vlib_rp->mutex);
5225   oldheap = svm_push_data_heap (am->vlib_rp);
5226
5227   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5228   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5229
5230   svm_pop_heap (oldheap);
5231   pthread_mutex_unlock (&am->vlib_rp->mutex);
5232
5233   mp->cmd_in_shmem = pointer_to_uword (cmd);
5234   S (mp);
5235   timeout = vat_time_now (vam) + 10.0;
5236
5237   while (vat_time_now (vam) < timeout)
5238     {
5239       if (vam->result_ready == 1)
5240         {
5241           u8 *free_me;
5242           if (vam->shmem_result != NULL)
5243             print (vam->ofp, "%s", vam->shmem_result);
5244           pthread_mutex_lock (&am->vlib_rp->mutex);
5245           oldheap = svm_push_data_heap (am->vlib_rp);
5246
5247           free_me = (u8 *) vam->shmem_result;
5248           vec_free (free_me);
5249
5250           svm_pop_heap (oldheap);
5251           pthread_mutex_unlock (&am->vlib_rp->mutex);
5252           return 0;
5253         }
5254     }
5255   return -99;
5256 }
5257
5258 /*
5259  * Future replacement of exec() that passes CLI buffers directly in
5260  * the API messages instead of an additional shared memory area.
5261  */
5262 static int
5263 exec_inband (vat_main_t * vam)
5264 {
5265   vl_api_cli_inband_t *mp;
5266   unformat_input_t *i = vam->input;
5267   int ret;
5268
5269   if (vec_len (i->buffer) == 0)
5270     return -1;
5271
5272   if (vam->exec_mode == 0 && unformat (i, "mode"))
5273     {
5274       vam->exec_mode = 1;
5275       return 0;
5276     }
5277   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5278     {
5279       vam->exec_mode = 0;
5280       return 0;
5281     }
5282
5283   /*
5284    * In order for the CLI command to work, it
5285    * must be a vector ending in \n, not a C-string ending
5286    * in \n\0.
5287    */
5288   u32 len = vec_len (vam->input->buffer);
5289   M2 (CLI_INBAND, mp, len);
5290   clib_memcpy (mp->cmd, vam->input->buffer, len);
5291   mp->length = htonl (len);
5292
5293   S (mp);
5294   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5295   return ret;
5296 }
5297
5298 static int
5299 api_create_loopback (vat_main_t * vam)
5300 {
5301   unformat_input_t *i = vam->input;
5302   vl_api_create_loopback_t *mp;
5303   vl_api_create_loopback_instance_t *mp_lbi;
5304   u8 mac_address[6];
5305   u8 mac_set = 0;
5306   u8 is_specified = 0;
5307   u32 user_instance = 0;
5308   int ret;
5309
5310   memset (mac_address, 0, sizeof (mac_address));
5311
5312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5313     {
5314       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5315         mac_set = 1;
5316       if (unformat (i, "instance %d", &user_instance))
5317         is_specified = 1;
5318       else
5319         break;
5320     }
5321
5322   if (is_specified)
5323     {
5324       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5325       mp_lbi->is_specified = is_specified;
5326       if (is_specified)
5327         mp_lbi->user_instance = htonl (user_instance);
5328       if (mac_set)
5329         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5330       S (mp_lbi);
5331     }
5332   else
5333     {
5334       /* Construct the API message */
5335       M (CREATE_LOOPBACK, mp);
5336       if (mac_set)
5337         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5338       S (mp);
5339     }
5340
5341   W (ret);
5342   return ret;
5343 }
5344
5345 static int
5346 api_delete_loopback (vat_main_t * vam)
5347 {
5348   unformat_input_t *i = vam->input;
5349   vl_api_delete_loopback_t *mp;
5350   u32 sw_if_index = ~0;
5351   int ret;
5352
5353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5354     {
5355       if (unformat (i, "sw_if_index %d", &sw_if_index))
5356         ;
5357       else
5358         break;
5359     }
5360
5361   if (sw_if_index == ~0)
5362     {
5363       errmsg ("missing sw_if_index");
5364       return -99;
5365     }
5366
5367   /* Construct the API message */
5368   M (DELETE_LOOPBACK, mp);
5369   mp->sw_if_index = ntohl (sw_if_index);
5370
5371   S (mp);
5372   W (ret);
5373   return ret;
5374 }
5375
5376 static int
5377 api_want_stats (vat_main_t * vam)
5378 {
5379   unformat_input_t *i = vam->input;
5380   vl_api_want_stats_t *mp;
5381   int enable = -1;
5382   int ret;
5383
5384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5385     {
5386       if (unformat (i, "enable"))
5387         enable = 1;
5388       else if (unformat (i, "disable"))
5389         enable = 0;
5390       else
5391         break;
5392     }
5393
5394   if (enable == -1)
5395     {
5396       errmsg ("missing enable|disable");
5397       return -99;
5398     }
5399
5400   M (WANT_STATS, mp);
5401   mp->enable_disable = enable;
5402
5403   S (mp);
5404   W (ret);
5405   return ret;
5406 }
5407
5408 static int
5409 api_want_interface_events (vat_main_t * vam)
5410 {
5411   unformat_input_t *i = vam->input;
5412   vl_api_want_interface_events_t *mp;
5413   int enable = -1;
5414   int ret;
5415
5416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5417     {
5418       if (unformat (i, "enable"))
5419         enable = 1;
5420       else if (unformat (i, "disable"))
5421         enable = 0;
5422       else
5423         break;
5424     }
5425
5426   if (enable == -1)
5427     {
5428       errmsg ("missing enable|disable");
5429       return -99;
5430     }
5431
5432   M (WANT_INTERFACE_EVENTS, mp);
5433   mp->enable_disable = enable;
5434
5435   vam->interface_event_display = enable;
5436
5437   S (mp);
5438   W (ret);
5439   return ret;
5440 }
5441
5442
5443 /* Note: non-static, called once to set up the initial intfc table */
5444 int
5445 api_sw_interface_dump (vat_main_t * vam)
5446 {
5447   vl_api_sw_interface_dump_t *mp;
5448   vl_api_control_ping_t *mp_ping;
5449   hash_pair_t *p;
5450   name_sort_t *nses = 0, *ns;
5451   sw_interface_subif_t *sub = NULL;
5452   int ret;
5453
5454   /* Toss the old name table */
5455   /* *INDENT-OFF* */
5456   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5457   ({
5458     vec_add2 (nses, ns, 1);
5459     ns->name = (u8 *)(p->key);
5460     ns->value = (u32) p->value[0];
5461   }));
5462   /* *INDENT-ON* */
5463
5464   hash_free (vam->sw_if_index_by_interface_name);
5465
5466   vec_foreach (ns, nses) vec_free (ns->name);
5467
5468   vec_free (nses);
5469
5470   vec_foreach (sub, vam->sw_if_subif_table)
5471   {
5472     vec_free (sub->interface_name);
5473   }
5474   vec_free (vam->sw_if_subif_table);
5475
5476   /* recreate the interface name hash table */
5477   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5478
5479   /* Get list of ethernets */
5480   M (SW_INTERFACE_DUMP, mp);
5481   mp->name_filter_valid = 1;
5482   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5483   S (mp);
5484
5485   /* and local / loopback interfaces */
5486   M (SW_INTERFACE_DUMP, mp);
5487   mp->name_filter_valid = 1;
5488   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5489   S (mp);
5490
5491   /* and packet-generator interfaces */
5492   M (SW_INTERFACE_DUMP, mp);
5493   mp->name_filter_valid = 1;
5494   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5495   S (mp);
5496
5497   /* and vxlan-gpe tunnel interfaces */
5498   M (SW_INTERFACE_DUMP, mp);
5499   mp->name_filter_valid = 1;
5500   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5501            sizeof (mp->name_filter) - 1);
5502   S (mp);
5503
5504   /* and vxlan tunnel interfaces */
5505   M (SW_INTERFACE_DUMP, mp);
5506   mp->name_filter_valid = 1;
5507   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5508   S (mp);
5509
5510   /* and host (af_packet) interfaces */
5511   M (SW_INTERFACE_DUMP, mp);
5512   mp->name_filter_valid = 1;
5513   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5514   S (mp);
5515
5516   /* and l2tpv3 tunnel interfaces */
5517   M (SW_INTERFACE_DUMP, mp);
5518   mp->name_filter_valid = 1;
5519   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5520            sizeof (mp->name_filter) - 1);
5521   S (mp);
5522
5523   /* and GRE tunnel interfaces */
5524   M (SW_INTERFACE_DUMP, mp);
5525   mp->name_filter_valid = 1;
5526   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5527   S (mp);
5528
5529   /* and LISP-GPE interfaces */
5530   M (SW_INTERFACE_DUMP, mp);
5531   mp->name_filter_valid = 1;
5532   strncpy ((char *) mp->name_filter, "lisp_gpe",
5533            sizeof (mp->name_filter) - 1);
5534   S (mp);
5535
5536   /* and IPSEC tunnel interfaces */
5537   M (SW_INTERFACE_DUMP, mp);
5538   mp->name_filter_valid = 1;
5539   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5540   S (mp);
5541
5542   /* Use a control ping for synchronization */
5543   M (CONTROL_PING, mp_ping);
5544   S (mp_ping);
5545
5546   W (ret);
5547   return ret;
5548 }
5549
5550 static int
5551 api_sw_interface_set_flags (vat_main_t * vam)
5552 {
5553   unformat_input_t *i = vam->input;
5554   vl_api_sw_interface_set_flags_t *mp;
5555   u32 sw_if_index;
5556   u8 sw_if_index_set = 0;
5557   u8 admin_up = 0, link_up = 0;
5558   int ret;
5559
5560   /* Parse args required to build the message */
5561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5562     {
5563       if (unformat (i, "admin-up"))
5564         admin_up = 1;
5565       else if (unformat (i, "admin-down"))
5566         admin_up = 0;
5567       else if (unformat (i, "link-up"))
5568         link_up = 1;
5569       else if (unformat (i, "link-down"))
5570         link_up = 0;
5571       else
5572         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5573         sw_if_index_set = 1;
5574       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5575         sw_if_index_set = 1;
5576       else
5577         break;
5578     }
5579
5580   if (sw_if_index_set == 0)
5581     {
5582       errmsg ("missing interface name or sw_if_index");
5583       return -99;
5584     }
5585
5586   /* Construct the API message */
5587   M (SW_INTERFACE_SET_FLAGS, mp);
5588   mp->sw_if_index = ntohl (sw_if_index);
5589   mp->admin_up_down = admin_up;
5590   mp->link_up_down = link_up;
5591
5592   /* send it... */
5593   S (mp);
5594
5595   /* Wait for a reply, return the good/bad news... */
5596   W (ret);
5597   return ret;
5598 }
5599
5600 static int
5601 api_sw_interface_clear_stats (vat_main_t * vam)
5602 {
5603   unformat_input_t *i = vam->input;
5604   vl_api_sw_interface_clear_stats_t *mp;
5605   u32 sw_if_index;
5606   u8 sw_if_index_set = 0;
5607   int ret;
5608
5609   /* Parse args required to build the message */
5610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5611     {
5612       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5613         sw_if_index_set = 1;
5614       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5615         sw_if_index_set = 1;
5616       else
5617         break;
5618     }
5619
5620   /* Construct the API message */
5621   M (SW_INTERFACE_CLEAR_STATS, mp);
5622
5623   if (sw_if_index_set == 1)
5624     mp->sw_if_index = ntohl (sw_if_index);
5625   else
5626     mp->sw_if_index = ~0;
5627
5628   /* send it... */
5629   S (mp);
5630
5631   /* Wait for a reply, return the good/bad news... */
5632   W (ret);
5633   return ret;
5634 }
5635
5636 static int
5637 api_sw_interface_add_del_address (vat_main_t * vam)
5638 {
5639   unformat_input_t *i = vam->input;
5640   vl_api_sw_interface_add_del_address_t *mp;
5641   u32 sw_if_index;
5642   u8 sw_if_index_set = 0;
5643   u8 is_add = 1, del_all = 0;
5644   u32 address_length = 0;
5645   u8 v4_address_set = 0;
5646   u8 v6_address_set = 0;
5647   ip4_address_t v4address;
5648   ip6_address_t v6address;
5649   int ret;
5650
5651   /* Parse args required to build the message */
5652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5653     {
5654       if (unformat (i, "del-all"))
5655         del_all = 1;
5656       else if (unformat (i, "del"))
5657         is_add = 0;
5658       else
5659         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5660         sw_if_index_set = 1;
5661       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5662         sw_if_index_set = 1;
5663       else if (unformat (i, "%U/%d",
5664                          unformat_ip4_address, &v4address, &address_length))
5665         v4_address_set = 1;
5666       else if (unformat (i, "%U/%d",
5667                          unformat_ip6_address, &v6address, &address_length))
5668         v6_address_set = 1;
5669       else
5670         break;
5671     }
5672
5673   if (sw_if_index_set == 0)
5674     {
5675       errmsg ("missing interface name or sw_if_index");
5676       return -99;
5677     }
5678   if (v4_address_set && v6_address_set)
5679     {
5680       errmsg ("both v4 and v6 addresses set");
5681       return -99;
5682     }
5683   if (!v4_address_set && !v6_address_set && !del_all)
5684     {
5685       errmsg ("no addresses set");
5686       return -99;
5687     }
5688
5689   /* Construct the API message */
5690   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5691
5692   mp->sw_if_index = ntohl (sw_if_index);
5693   mp->is_add = is_add;
5694   mp->del_all = del_all;
5695   if (v6_address_set)
5696     {
5697       mp->is_ipv6 = 1;
5698       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5699     }
5700   else
5701     {
5702       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5703     }
5704   mp->address_length = address_length;
5705
5706   /* send it... */
5707   S (mp);
5708
5709   /* Wait for a reply, return good/bad news  */
5710   W (ret);
5711   return ret;
5712 }
5713
5714 static int
5715 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5716 {
5717   unformat_input_t *i = vam->input;
5718   vl_api_sw_interface_set_mpls_enable_t *mp;
5719   u32 sw_if_index;
5720   u8 sw_if_index_set = 0;
5721   u8 enable = 1;
5722   int ret;
5723
5724   /* Parse args required to build the message */
5725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5726     {
5727       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5728         sw_if_index_set = 1;
5729       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5730         sw_if_index_set = 1;
5731       else if (unformat (i, "disable"))
5732         enable = 0;
5733       else if (unformat (i, "dis"))
5734         enable = 0;
5735       else
5736         break;
5737     }
5738
5739   if (sw_if_index_set == 0)
5740     {
5741       errmsg ("missing interface name or sw_if_index");
5742       return -99;
5743     }
5744
5745   /* Construct the API message */
5746   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5747
5748   mp->sw_if_index = ntohl (sw_if_index);
5749   mp->enable = enable;
5750
5751   /* send it... */
5752   S (mp);
5753
5754   /* Wait for a reply... */
5755   W (ret);
5756   return ret;
5757 }
5758
5759 static int
5760 api_sw_interface_set_table (vat_main_t * vam)
5761 {
5762   unformat_input_t *i = vam->input;
5763   vl_api_sw_interface_set_table_t *mp;
5764   u32 sw_if_index, vrf_id = 0;
5765   u8 sw_if_index_set = 0;
5766   u8 is_ipv6 = 0;
5767   int ret;
5768
5769   /* Parse args required to build the message */
5770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5771     {
5772       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5773         sw_if_index_set = 1;
5774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5775         sw_if_index_set = 1;
5776       else if (unformat (i, "vrf %d", &vrf_id))
5777         ;
5778       else if (unformat (i, "ipv6"))
5779         is_ipv6 = 1;
5780       else
5781         break;
5782     }
5783
5784   if (sw_if_index_set == 0)
5785     {
5786       errmsg ("missing interface name or sw_if_index");
5787       return -99;
5788     }
5789
5790   /* Construct the API message */
5791   M (SW_INTERFACE_SET_TABLE, mp);
5792
5793   mp->sw_if_index = ntohl (sw_if_index);
5794   mp->is_ipv6 = is_ipv6;
5795   mp->vrf_id = ntohl (vrf_id);
5796
5797   /* send it... */
5798   S (mp);
5799
5800   /* Wait for a reply... */
5801   W (ret);
5802   return ret;
5803 }
5804
5805 static void vl_api_sw_interface_get_table_reply_t_handler
5806   (vl_api_sw_interface_get_table_reply_t * mp)
5807 {
5808   vat_main_t *vam = &vat_main;
5809
5810   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5811
5812   vam->retval = ntohl (mp->retval);
5813   vam->result_ready = 1;
5814
5815 }
5816
5817 static void vl_api_sw_interface_get_table_reply_t_handler_json
5818   (vl_api_sw_interface_get_table_reply_t * mp)
5819 {
5820   vat_main_t *vam = &vat_main;
5821   vat_json_node_t node;
5822
5823   vat_json_init_object (&node);
5824   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5825   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5826
5827   vat_json_print (vam->ofp, &node);
5828   vat_json_free (&node);
5829
5830   vam->retval = ntohl (mp->retval);
5831   vam->result_ready = 1;
5832 }
5833
5834 static int
5835 api_sw_interface_get_table (vat_main_t * vam)
5836 {
5837   unformat_input_t *i = vam->input;
5838   vl_api_sw_interface_get_table_t *mp;
5839   u32 sw_if_index;
5840   u8 sw_if_index_set = 0;
5841   u8 is_ipv6 = 0;
5842   int ret;
5843
5844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5845     {
5846       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5847         sw_if_index_set = 1;
5848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5849         sw_if_index_set = 1;
5850       else if (unformat (i, "ipv6"))
5851         is_ipv6 = 1;
5852       else
5853         break;
5854     }
5855
5856   if (sw_if_index_set == 0)
5857     {
5858       errmsg ("missing interface name or sw_if_index");
5859       return -99;
5860     }
5861
5862   M (SW_INTERFACE_GET_TABLE, mp);
5863   mp->sw_if_index = htonl (sw_if_index);
5864   mp->is_ipv6 = is_ipv6;
5865
5866   S (mp);
5867   W (ret);
5868   return ret;
5869 }
5870
5871 static int
5872 api_sw_interface_set_vpath (vat_main_t * vam)
5873 {
5874   unformat_input_t *i = vam->input;
5875   vl_api_sw_interface_set_vpath_t *mp;
5876   u32 sw_if_index = 0;
5877   u8 sw_if_index_set = 0;
5878   u8 is_enable = 0;
5879   int ret;
5880
5881   /* Parse args required to build the message */
5882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5883     {
5884       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5885         sw_if_index_set = 1;
5886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5887         sw_if_index_set = 1;
5888       else if (unformat (i, "enable"))
5889         is_enable = 1;
5890       else if (unformat (i, "disable"))
5891         is_enable = 0;
5892       else
5893         break;
5894     }
5895
5896   if (sw_if_index_set == 0)
5897     {
5898       errmsg ("missing interface name or sw_if_index");
5899       return -99;
5900     }
5901
5902   /* Construct the API message */
5903   M (SW_INTERFACE_SET_VPATH, mp);
5904
5905   mp->sw_if_index = ntohl (sw_if_index);
5906   mp->enable = is_enable;
5907
5908   /* send it... */
5909   S (mp);
5910
5911   /* Wait for a reply... */
5912   W (ret);
5913   return ret;
5914 }
5915
5916 static int
5917 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5918 {
5919   unformat_input_t *i = vam->input;
5920   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5921   u32 sw_if_index = 0;
5922   u8 sw_if_index_set = 0;
5923   u8 is_enable = 1;
5924   u8 is_ipv6 = 0;
5925   int ret;
5926
5927   /* Parse args required to build the message */
5928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5929     {
5930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5931         sw_if_index_set = 1;
5932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5933         sw_if_index_set = 1;
5934       else if (unformat (i, "enable"))
5935         is_enable = 1;
5936       else if (unformat (i, "disable"))
5937         is_enable = 0;
5938       else if (unformat (i, "ip4"))
5939         is_ipv6 = 0;
5940       else if (unformat (i, "ip6"))
5941         is_ipv6 = 1;
5942       else
5943         break;
5944     }
5945
5946   if (sw_if_index_set == 0)
5947     {
5948       errmsg ("missing interface name or sw_if_index");
5949       return -99;
5950     }
5951
5952   /* Construct the API message */
5953   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5954
5955   mp->sw_if_index = ntohl (sw_if_index);
5956   mp->enable = is_enable;
5957   mp->is_ipv6 = is_ipv6;
5958
5959   /* send it... */
5960   S (mp);
5961
5962   /* Wait for a reply... */
5963   W (ret);
5964   return ret;
5965 }
5966
5967 static int
5968 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5969 {
5970   unformat_input_t *i = vam->input;
5971   vl_api_sw_interface_set_l2_xconnect_t *mp;
5972   u32 rx_sw_if_index;
5973   u8 rx_sw_if_index_set = 0;
5974   u32 tx_sw_if_index;
5975   u8 tx_sw_if_index_set = 0;
5976   u8 enable = 1;
5977   int ret;
5978
5979   /* Parse args required to build the message */
5980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5981     {
5982       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5983         rx_sw_if_index_set = 1;
5984       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5985         tx_sw_if_index_set = 1;
5986       else if (unformat (i, "rx"))
5987         {
5988           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5989             {
5990               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5991                             &rx_sw_if_index))
5992                 rx_sw_if_index_set = 1;
5993             }
5994           else
5995             break;
5996         }
5997       else if (unformat (i, "tx"))
5998         {
5999           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6000             {
6001               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6002                             &tx_sw_if_index))
6003                 tx_sw_if_index_set = 1;
6004             }
6005           else
6006             break;
6007         }
6008       else if (unformat (i, "enable"))
6009         enable = 1;
6010       else if (unformat (i, "disable"))
6011         enable = 0;
6012       else
6013         break;
6014     }
6015
6016   if (rx_sw_if_index_set == 0)
6017     {
6018       errmsg ("missing rx interface name or rx_sw_if_index");
6019       return -99;
6020     }
6021
6022   if (enable && (tx_sw_if_index_set == 0))
6023     {
6024       errmsg ("missing tx interface name or tx_sw_if_index");
6025       return -99;
6026     }
6027
6028   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6029
6030   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6031   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6032   mp->enable = enable;
6033
6034   S (mp);
6035   W (ret);
6036   return ret;
6037 }
6038
6039 static int
6040 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6041 {
6042   unformat_input_t *i = vam->input;
6043   vl_api_sw_interface_set_l2_bridge_t *mp;
6044   u32 rx_sw_if_index;
6045   u8 rx_sw_if_index_set = 0;
6046   u32 bd_id;
6047   u8 bd_id_set = 0;
6048   u8 bvi = 0;
6049   u32 shg = 0;
6050   u8 enable = 1;
6051   int ret;
6052
6053   /* Parse args required to build the message */
6054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6055     {
6056       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6057         rx_sw_if_index_set = 1;
6058       else if (unformat (i, "bd_id %d", &bd_id))
6059         bd_id_set = 1;
6060       else
6061         if (unformat
6062             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6063         rx_sw_if_index_set = 1;
6064       else if (unformat (i, "shg %d", &shg))
6065         ;
6066       else if (unformat (i, "bvi"))
6067         bvi = 1;
6068       else if (unformat (i, "enable"))
6069         enable = 1;
6070       else if (unformat (i, "disable"))
6071         enable = 0;
6072       else
6073         break;
6074     }
6075
6076   if (rx_sw_if_index_set == 0)
6077     {
6078       errmsg ("missing rx interface name or sw_if_index");
6079       return -99;
6080     }
6081
6082   if (enable && (bd_id_set == 0))
6083     {
6084       errmsg ("missing bridge domain");
6085       return -99;
6086     }
6087
6088   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6089
6090   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6091   mp->bd_id = ntohl (bd_id);
6092   mp->shg = (u8) shg;
6093   mp->bvi = bvi;
6094   mp->enable = enable;
6095
6096   S (mp);
6097   W (ret);
6098   return ret;
6099 }
6100
6101 static int
6102 api_bridge_domain_dump (vat_main_t * vam)
6103 {
6104   unformat_input_t *i = vam->input;
6105   vl_api_bridge_domain_dump_t *mp;
6106   vl_api_control_ping_t *mp_ping;
6107   u32 bd_id = ~0;
6108   int ret;
6109
6110   /* Parse args required to build the message */
6111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6112     {
6113       if (unformat (i, "bd_id %d", &bd_id))
6114         ;
6115       else
6116         break;
6117     }
6118
6119   M (BRIDGE_DOMAIN_DUMP, mp);
6120   mp->bd_id = ntohl (bd_id);
6121   S (mp);
6122
6123   /* Use a control ping for synchronization */
6124   M (CONTROL_PING, mp_ping);
6125   S (mp_ping);
6126
6127   W (ret);
6128   return ret;
6129 }
6130
6131 static int
6132 api_bridge_domain_add_del (vat_main_t * vam)
6133 {
6134   unformat_input_t *i = vam->input;
6135   vl_api_bridge_domain_add_del_t *mp;
6136   u32 bd_id = ~0;
6137   u8 is_add = 1;
6138   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6139   u32 mac_age = 0;
6140   int ret;
6141
6142   /* Parse args required to build the message */
6143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6144     {
6145       if (unformat (i, "bd_id %d", &bd_id))
6146         ;
6147       else if (unformat (i, "flood %d", &flood))
6148         ;
6149       else if (unformat (i, "uu-flood %d", &uu_flood))
6150         ;
6151       else if (unformat (i, "forward %d", &forward))
6152         ;
6153       else if (unformat (i, "learn %d", &learn))
6154         ;
6155       else if (unformat (i, "arp-term %d", &arp_term))
6156         ;
6157       else if (unformat (i, "mac-age %d", &mac_age))
6158         ;
6159       else if (unformat (i, "del"))
6160         {
6161           is_add = 0;
6162           flood = uu_flood = forward = learn = 0;
6163         }
6164       else
6165         break;
6166     }
6167
6168   if (bd_id == ~0)
6169     {
6170       errmsg ("missing bridge domain");
6171       return -99;
6172     }
6173
6174   if (mac_age > 255)
6175     {
6176       errmsg ("mac age must be less than 256 ");
6177       return -99;
6178     }
6179
6180   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6181
6182   mp->bd_id = ntohl (bd_id);
6183   mp->flood = flood;
6184   mp->uu_flood = uu_flood;
6185   mp->forward = forward;
6186   mp->learn = learn;
6187   mp->arp_term = arp_term;
6188   mp->is_add = is_add;
6189   mp->mac_age = (u8) mac_age;
6190
6191   S (mp);
6192   W (ret);
6193   return ret;
6194 }
6195
6196 static int
6197 api_l2fib_flush_bd (vat_main_t * vam)
6198 {
6199   unformat_input_t *i = vam->input;
6200   vl_api_l2fib_flush_bd_t *mp;
6201   u32 bd_id = ~0;
6202   int ret;
6203
6204   /* Parse args required to build the message */
6205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6206     {
6207       if (unformat (i, "bd_id %d", &bd_id));
6208       else
6209         break;
6210     }
6211
6212   if (bd_id == ~0)
6213     {
6214       errmsg ("missing bridge domain");
6215       return -99;
6216     }
6217
6218   M (L2FIB_FLUSH_BD, mp);
6219
6220   mp->bd_id = htonl (bd_id);
6221
6222   S (mp);
6223   W (ret);
6224   return ret;
6225 }
6226
6227 static int
6228 api_l2fib_flush_int (vat_main_t * vam)
6229 {
6230   unformat_input_t *i = vam->input;
6231   vl_api_l2fib_flush_int_t *mp;
6232   u32 sw_if_index = ~0;
6233   int ret;
6234
6235   /* Parse args required to build the message */
6236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6237     {
6238       if (unformat (i, "sw_if_index %d", &sw_if_index));
6239       else
6240         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6241       else
6242         break;
6243     }
6244
6245   if (sw_if_index == ~0)
6246     {
6247       errmsg ("missing interface name or sw_if_index");
6248       return -99;
6249     }
6250
6251   M (L2FIB_FLUSH_INT, mp);
6252
6253   mp->sw_if_index = ntohl (sw_if_index);
6254
6255   S (mp);
6256   W (ret);
6257   return ret;
6258 }
6259
6260 static int
6261 api_l2fib_add_del (vat_main_t * vam)
6262 {
6263   unformat_input_t *i = vam->input;
6264   vl_api_l2fib_add_del_t *mp;
6265   f64 timeout;
6266   u64 mac = 0;
6267   u8 mac_set = 0;
6268   u32 bd_id;
6269   u8 bd_id_set = 0;
6270   u32 sw_if_index = ~0;
6271   u8 sw_if_index_set = 0;
6272   u8 is_add = 1;
6273   u8 static_mac = 0;
6274   u8 filter_mac = 0;
6275   u8 bvi_mac = 0;
6276   int count = 1;
6277   f64 before = 0;
6278   int j;
6279
6280   /* Parse args required to build the message */
6281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6282     {
6283       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6284         mac_set = 1;
6285       else if (unformat (i, "bd_id %d", &bd_id))
6286         bd_id_set = 1;
6287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6288         sw_if_index_set = 1;
6289       else if (unformat (i, "sw_if"))
6290         {
6291           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6292             {
6293               if (unformat
6294                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6295                 sw_if_index_set = 1;
6296             }
6297           else
6298             break;
6299         }
6300       else if (unformat (i, "static"))
6301         static_mac = 1;
6302       else if (unformat (i, "filter"))
6303         {
6304           filter_mac = 1;
6305           static_mac = 1;
6306         }
6307       else if (unformat (i, "bvi"))
6308         {
6309           bvi_mac = 1;
6310           static_mac = 1;
6311         }
6312       else if (unformat (i, "del"))
6313         is_add = 0;
6314       else if (unformat (i, "count %d", &count))
6315         ;
6316       else
6317         break;
6318     }
6319
6320   if (mac_set == 0)
6321     {
6322       errmsg ("missing mac address");
6323       return -99;
6324     }
6325
6326   if (bd_id_set == 0)
6327     {
6328       errmsg ("missing bridge domain");
6329       return -99;
6330     }
6331
6332   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6333     {
6334       errmsg ("missing interface name or sw_if_index");
6335       return -99;
6336     }
6337
6338   if (count > 1)
6339     {
6340       /* Turn on async mode */
6341       vam->async_mode = 1;
6342       vam->async_errors = 0;
6343       before = vat_time_now (vam);
6344     }
6345
6346   for (j = 0; j < count; j++)
6347     {
6348       M (L2FIB_ADD_DEL, mp);
6349
6350       mp->mac = mac;
6351       mp->bd_id = ntohl (bd_id);
6352       mp->is_add = is_add;
6353
6354       if (is_add)
6355         {
6356           mp->sw_if_index = ntohl (sw_if_index);
6357           mp->static_mac = static_mac;
6358           mp->filter_mac = filter_mac;
6359           mp->bvi_mac = bvi_mac;
6360         }
6361       increment_mac_address (&mac);
6362       /* send it... */
6363       S (mp);
6364     }
6365
6366   if (count > 1)
6367     {
6368       vl_api_control_ping_t *mp_ping;
6369       f64 after;
6370
6371       /* Shut off async mode */
6372       vam->async_mode = 0;
6373
6374       M (CONTROL_PING, mp_ping);
6375       S (mp_ping);
6376
6377       timeout = vat_time_now (vam) + 1.0;
6378       while (vat_time_now (vam) < timeout)
6379         if (vam->result_ready == 1)
6380           goto out;
6381       vam->retval = -99;
6382
6383     out:
6384       if (vam->retval == -99)
6385         errmsg ("timeout");
6386
6387       if (vam->async_errors > 0)
6388         {
6389           errmsg ("%d asynchronous errors", vam->async_errors);
6390           vam->retval = -98;
6391         }
6392       vam->async_errors = 0;
6393       after = vat_time_now (vam);
6394
6395       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6396              count, after - before, count / (after - before));
6397     }
6398   else
6399     {
6400       int ret;
6401
6402       /* Wait for a reply... */
6403       W (ret);
6404       return ret;
6405     }
6406   /* Return the good/bad news */
6407   return (vam->retval);
6408 }
6409
6410 static int
6411 api_bridge_domain_set_mac_age (vat_main_t * vam)
6412 {
6413   unformat_input_t *i = vam->input;
6414   vl_api_bridge_domain_set_mac_age_t *mp;
6415   u32 bd_id = ~0;
6416   u32 mac_age = 0;
6417   int ret;
6418
6419   /* Parse args required to build the message */
6420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6421     {
6422       if (unformat (i, "bd_id %d", &bd_id));
6423       else if (unformat (i, "mac-age %d", &mac_age));
6424       else
6425         break;
6426     }
6427
6428   if (bd_id == ~0)
6429     {
6430       errmsg ("missing bridge domain");
6431       return -99;
6432     }
6433
6434   if (mac_age > 255)
6435     {
6436       errmsg ("mac age must be less than 256 ");
6437       return -99;
6438     }
6439
6440   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6441
6442   mp->bd_id = htonl (bd_id);
6443   mp->mac_age = (u8) mac_age;
6444
6445   S (mp);
6446   W (ret);
6447   return ret;
6448 }
6449
6450 static int
6451 api_l2_flags (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_l2_flags_t *mp;
6455   u32 sw_if_index;
6456   u32 feature_bitmap = 0;
6457   u8 sw_if_index_set = 0;
6458   int ret;
6459
6460   /* Parse args required to build the message */
6461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6462     {
6463       if (unformat (i, "sw_if_index %d", &sw_if_index))
6464         sw_if_index_set = 1;
6465       else if (unformat (i, "sw_if"))
6466         {
6467           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6468             {
6469               if (unformat
6470                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6471                 sw_if_index_set = 1;
6472             }
6473           else
6474             break;
6475         }
6476       else if (unformat (i, "learn"))
6477         feature_bitmap |= L2INPUT_FEAT_LEARN;
6478       else if (unformat (i, "forward"))
6479         feature_bitmap |= L2INPUT_FEAT_FWD;
6480       else if (unformat (i, "flood"))
6481         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6482       else if (unformat (i, "uu-flood"))
6483         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6484       else
6485         break;
6486     }
6487
6488   if (sw_if_index_set == 0)
6489     {
6490       errmsg ("missing interface name or sw_if_index");
6491       return -99;
6492     }
6493
6494   M (L2_FLAGS, mp);
6495
6496   mp->sw_if_index = ntohl (sw_if_index);
6497   mp->feature_bitmap = ntohl (feature_bitmap);
6498
6499   S (mp);
6500   W (ret);
6501   return ret;
6502 }
6503
6504 static int
6505 api_bridge_flags (vat_main_t * vam)
6506 {
6507   unformat_input_t *i = vam->input;
6508   vl_api_bridge_flags_t *mp;
6509   u32 bd_id;
6510   u8 bd_id_set = 0;
6511   u8 is_set = 1;
6512   u32 flags = 0;
6513   int ret;
6514
6515   /* Parse args required to build the message */
6516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6517     {
6518       if (unformat (i, "bd_id %d", &bd_id))
6519         bd_id_set = 1;
6520       else if (unformat (i, "learn"))
6521         flags |= L2_LEARN;
6522       else if (unformat (i, "forward"))
6523         flags |= L2_FWD;
6524       else if (unformat (i, "flood"))
6525         flags |= L2_FLOOD;
6526       else if (unformat (i, "uu-flood"))
6527         flags |= L2_UU_FLOOD;
6528       else if (unformat (i, "arp-term"))
6529         flags |= L2_ARP_TERM;
6530       else if (unformat (i, "off"))
6531         is_set = 0;
6532       else if (unformat (i, "disable"))
6533         is_set = 0;
6534       else
6535         break;
6536     }
6537
6538   if (bd_id_set == 0)
6539     {
6540       errmsg ("missing bridge domain");
6541       return -99;
6542     }
6543
6544   M (BRIDGE_FLAGS, mp);
6545
6546   mp->bd_id = ntohl (bd_id);
6547   mp->feature_bitmap = ntohl (flags);
6548   mp->is_set = is_set;
6549
6550   S (mp);
6551   W (ret);
6552   return ret;
6553 }
6554
6555 static int
6556 api_bd_ip_mac_add_del (vat_main_t * vam)
6557 {
6558   unformat_input_t *i = vam->input;
6559   vl_api_bd_ip_mac_add_del_t *mp;
6560   u32 bd_id;
6561   u8 is_ipv6 = 0;
6562   u8 is_add = 1;
6563   u8 bd_id_set = 0;
6564   u8 ip_set = 0;
6565   u8 mac_set = 0;
6566   ip4_address_t v4addr;
6567   ip6_address_t v6addr;
6568   u8 macaddr[6];
6569   int ret;
6570
6571
6572   /* Parse args required to build the message */
6573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6574     {
6575       if (unformat (i, "bd_id %d", &bd_id))
6576         {
6577           bd_id_set++;
6578         }
6579       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6580         {
6581           ip_set++;
6582         }
6583       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6584         {
6585           ip_set++;
6586           is_ipv6++;
6587         }
6588       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6589         {
6590           mac_set++;
6591         }
6592       else if (unformat (i, "del"))
6593         is_add = 0;
6594       else
6595         break;
6596     }
6597
6598   if (bd_id_set == 0)
6599     {
6600       errmsg ("missing bridge domain");
6601       return -99;
6602     }
6603   else if (ip_set == 0)
6604     {
6605       errmsg ("missing IP address");
6606       return -99;
6607     }
6608   else if (mac_set == 0)
6609     {
6610       errmsg ("missing MAC address");
6611       return -99;
6612     }
6613
6614   M (BD_IP_MAC_ADD_DEL, mp);
6615
6616   mp->bd_id = ntohl (bd_id);
6617   mp->is_ipv6 = is_ipv6;
6618   mp->is_add = is_add;
6619   if (is_ipv6)
6620     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6621   else
6622     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6623   clib_memcpy (mp->mac_address, macaddr, 6);
6624   S (mp);
6625   W (ret);
6626   return ret;
6627 }
6628
6629 static int
6630 api_tap_connect (vat_main_t * vam)
6631 {
6632   unformat_input_t *i = vam->input;
6633   vl_api_tap_connect_t *mp;
6634   u8 mac_address[6];
6635   u8 random_mac = 1;
6636   u8 name_set = 0;
6637   u8 *tap_name;
6638   u8 *tag = 0;
6639   ip4_address_t ip4_address;
6640   u32 ip4_mask_width;
6641   int ip4_address_set = 0;
6642   ip6_address_t ip6_address;
6643   u32 ip6_mask_width;
6644   int ip6_address_set = 0;
6645   int ret;
6646
6647   memset (mac_address, 0, sizeof (mac_address));
6648
6649   /* Parse args required to build the message */
6650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6651     {
6652       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6653         {
6654           random_mac = 0;
6655         }
6656       else if (unformat (i, "random-mac"))
6657         random_mac = 1;
6658       else if (unformat (i, "tapname %s", &tap_name))
6659         name_set = 1;
6660       else if (unformat (i, "tag %s", &tag))
6661         ;
6662       else if (unformat (i, "address %U/%d",
6663                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6664         ip4_address_set = 1;
6665       else if (unformat (i, "address %U/%d",
6666                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6667         ip6_address_set = 1;
6668       else
6669         break;
6670     }
6671
6672   if (name_set == 0)
6673     {
6674       errmsg ("missing tap name");
6675       return -99;
6676     }
6677   if (vec_len (tap_name) > 63)
6678     {
6679       errmsg ("tap name too long");
6680       return -99;
6681     }
6682   vec_add1 (tap_name, 0);
6683
6684   if (vec_len (tag) > 63)
6685     {
6686       errmsg ("tag too long");
6687       return -99;
6688     }
6689
6690   /* Construct the API message */
6691   M (TAP_CONNECT, mp);
6692
6693   mp->use_random_mac = random_mac;
6694   clib_memcpy (mp->mac_address, mac_address, 6);
6695   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6696   if (tag)
6697     clib_memcpy (mp->tag, tag, vec_len (tag));
6698
6699   if (ip4_address_set)
6700     {
6701       mp->ip4_address_set = 1;
6702       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6703       mp->ip4_mask_width = ip4_mask_width;
6704     }
6705   if (ip6_address_set)
6706     {
6707       mp->ip6_address_set = 1;
6708       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6709       mp->ip6_mask_width = ip6_mask_width;
6710     }
6711
6712   vec_free (tap_name);
6713   vec_free (tag);
6714
6715   /* send it... */
6716   S (mp);
6717
6718   /* Wait for a reply... */
6719   W (ret);
6720   return ret;
6721 }
6722
6723 static int
6724 api_tap_modify (vat_main_t * vam)
6725 {
6726   unformat_input_t *i = vam->input;
6727   vl_api_tap_modify_t *mp;
6728   u8 mac_address[6];
6729   u8 random_mac = 1;
6730   u8 name_set = 0;
6731   u8 *tap_name;
6732   u32 sw_if_index = ~0;
6733   u8 sw_if_index_set = 0;
6734   int ret;
6735
6736   memset (mac_address, 0, sizeof (mac_address));
6737
6738   /* Parse args required to build the message */
6739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6740     {
6741       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6742         sw_if_index_set = 1;
6743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6744         sw_if_index_set = 1;
6745       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6746         {
6747           random_mac = 0;
6748         }
6749       else if (unformat (i, "random-mac"))
6750         random_mac = 1;
6751       else if (unformat (i, "tapname %s", &tap_name))
6752         name_set = 1;
6753       else
6754         break;
6755     }
6756
6757   if (sw_if_index_set == 0)
6758     {
6759       errmsg ("missing vpp interface name");
6760       return -99;
6761     }
6762   if (name_set == 0)
6763     {
6764       errmsg ("missing tap name");
6765       return -99;
6766     }
6767   if (vec_len (tap_name) > 63)
6768     {
6769       errmsg ("tap name too long");
6770     }
6771   vec_add1 (tap_name, 0);
6772
6773   /* Construct the API message */
6774   M (TAP_MODIFY, mp);
6775
6776   mp->use_random_mac = random_mac;
6777   mp->sw_if_index = ntohl (sw_if_index);
6778   clib_memcpy (mp->mac_address, mac_address, 6);
6779   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6780   vec_free (tap_name);
6781
6782   /* send it... */
6783   S (mp);
6784
6785   /* Wait for a reply... */
6786   W (ret);
6787   return ret;
6788 }
6789
6790 static int
6791 api_tap_delete (vat_main_t * vam)
6792 {
6793   unformat_input_t *i = vam->input;
6794   vl_api_tap_delete_t *mp;
6795   u32 sw_if_index = ~0;
6796   u8 sw_if_index_set = 0;
6797   int ret;
6798
6799   /* Parse args required to build the message */
6800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6801     {
6802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6803         sw_if_index_set = 1;
6804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6805         sw_if_index_set = 1;
6806       else
6807         break;
6808     }
6809
6810   if (sw_if_index_set == 0)
6811     {
6812       errmsg ("missing vpp interface name");
6813       return -99;
6814     }
6815
6816   /* Construct the API message */
6817   M (TAP_DELETE, mp);
6818
6819   mp->sw_if_index = ntohl (sw_if_index);
6820
6821   /* send it... */
6822   S (mp);
6823
6824   /* Wait for a reply... */
6825   W (ret);
6826   return ret;
6827 }
6828
6829 static int
6830 api_ip_add_del_route (vat_main_t * vam)
6831 {
6832   unformat_input_t *i = vam->input;
6833   vl_api_ip_add_del_route_t *mp;
6834   u32 sw_if_index = ~0, vrf_id = 0;
6835   u8 is_ipv6 = 0;
6836   u8 is_local = 0, is_drop = 0;
6837   u8 is_unreach = 0, is_prohibit = 0;
6838   u8 create_vrf_if_needed = 0;
6839   u8 is_add = 1;
6840   u32 next_hop_weight = 1;
6841   u8 not_last = 0;
6842   u8 is_multipath = 0;
6843   u8 address_set = 0;
6844   u8 address_length_set = 0;
6845   u32 next_hop_table_id = 0;
6846   u32 resolve_attempts = 0;
6847   u32 dst_address_length = 0;
6848   u8 next_hop_set = 0;
6849   ip4_address_t v4_dst_address, v4_next_hop_address;
6850   ip6_address_t v6_dst_address, v6_next_hop_address;
6851   int count = 1;
6852   int j;
6853   f64 before = 0;
6854   u32 random_add_del = 0;
6855   u32 *random_vector = 0;
6856   uword *random_hash;
6857   u32 random_seed = 0xdeaddabe;
6858   u32 classify_table_index = ~0;
6859   u8 is_classify = 0;
6860   u8 resolve_host = 0, resolve_attached = 0;
6861   mpls_label_t *next_hop_out_label_stack = NULL;
6862   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6863   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6864
6865   /* Parse args required to build the message */
6866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6867     {
6868       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6869         ;
6870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6871         ;
6872       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6873         {
6874           address_set = 1;
6875           is_ipv6 = 0;
6876         }
6877       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6878         {
6879           address_set = 1;
6880           is_ipv6 = 1;
6881         }
6882       else if (unformat (i, "/%d", &dst_address_length))
6883         {
6884           address_length_set = 1;
6885         }
6886
6887       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6888                                          &v4_next_hop_address))
6889         {
6890           next_hop_set = 1;
6891         }
6892       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6893                                          &v6_next_hop_address))
6894         {
6895           next_hop_set = 1;
6896         }
6897       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6898         ;
6899       else if (unformat (i, "weight %d", &next_hop_weight))
6900         ;
6901       else if (unformat (i, "drop"))
6902         {
6903           is_drop = 1;
6904         }
6905       else if (unformat (i, "null-send-unreach"))
6906         {
6907           is_unreach = 1;
6908         }
6909       else if (unformat (i, "null-send-prohibit"))
6910         {
6911           is_prohibit = 1;
6912         }
6913       else if (unformat (i, "local"))
6914         {
6915           is_local = 1;
6916         }
6917       else if (unformat (i, "classify %d", &classify_table_index))
6918         {
6919           is_classify = 1;
6920         }
6921       else if (unformat (i, "del"))
6922         is_add = 0;
6923       else if (unformat (i, "add"))
6924         is_add = 1;
6925       else if (unformat (i, "not-last"))
6926         not_last = 1;
6927       else if (unformat (i, "resolve-via-host"))
6928         resolve_host = 1;
6929       else if (unformat (i, "resolve-via-attached"))
6930         resolve_attached = 1;
6931       else if (unformat (i, "multipath"))
6932         is_multipath = 1;
6933       else if (unformat (i, "vrf %d", &vrf_id))
6934         ;
6935       else if (unformat (i, "create-vrf"))
6936         create_vrf_if_needed = 1;
6937       else if (unformat (i, "count %d", &count))
6938         ;
6939       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6940         ;
6941       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6942         ;
6943       else if (unformat (i, "out-label %d", &next_hop_out_label))
6944         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6945       else if (unformat (i, "via-label %d", &next_hop_via_label))
6946         ;
6947       else if (unformat (i, "random"))
6948         random_add_del = 1;
6949       else if (unformat (i, "seed %d", &random_seed))
6950         ;
6951       else
6952         {
6953           clib_warning ("parse error '%U'", format_unformat_error, i);
6954           return -99;
6955         }
6956     }
6957
6958   if (!next_hop_set && !is_drop && !is_local &&
6959       !is_classify && !is_unreach && !is_prohibit &&
6960       MPLS_LABEL_INVALID == next_hop_via_label)
6961     {
6962       errmsg
6963         ("next hop / local / drop / unreach / prohibit / classify not set");
6964       return -99;
6965     }
6966
6967   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6968     {
6969       errmsg ("next hop and next-hop via label set");
6970       return -99;
6971     }
6972   if (address_set == 0)
6973     {
6974       errmsg ("missing addresses");
6975       return -99;
6976     }
6977
6978   if (address_length_set == 0)
6979     {
6980       errmsg ("missing address length");
6981       return -99;
6982     }
6983
6984   /* Generate a pile of unique, random routes */
6985   if (random_add_del)
6986     {
6987       u32 this_random_address;
6988       random_hash = hash_create (count, sizeof (uword));
6989
6990       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6991       for (j = 0; j <= count; j++)
6992         {
6993           do
6994             {
6995               this_random_address = random_u32 (&random_seed);
6996               this_random_address =
6997                 clib_host_to_net_u32 (this_random_address);
6998             }
6999           while (hash_get (random_hash, this_random_address));
7000           vec_add1 (random_vector, this_random_address);
7001           hash_set (random_hash, this_random_address, 1);
7002         }
7003       hash_free (random_hash);
7004       v4_dst_address.as_u32 = random_vector[0];
7005     }
7006
7007   if (count > 1)
7008     {
7009       /* Turn on async mode */
7010       vam->async_mode = 1;
7011       vam->async_errors = 0;
7012       before = vat_time_now (vam);
7013     }
7014
7015   for (j = 0; j < count; j++)
7016     {
7017       /* Construct the API message */
7018       M2 (IP_ADD_DEL_ROUTE, mp,
7019           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7020
7021       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7022       mp->table_id = ntohl (vrf_id);
7023       mp->create_vrf_if_needed = create_vrf_if_needed;
7024
7025       mp->is_add = is_add;
7026       mp->is_drop = is_drop;
7027       mp->is_unreach = is_unreach;
7028       mp->is_prohibit = is_prohibit;
7029       mp->is_ipv6 = is_ipv6;
7030       mp->is_local = is_local;
7031       mp->is_classify = is_classify;
7032       mp->is_multipath = is_multipath;
7033       mp->is_resolve_host = resolve_host;
7034       mp->is_resolve_attached = resolve_attached;
7035       mp->not_last = not_last;
7036       mp->next_hop_weight = next_hop_weight;
7037       mp->dst_address_length = dst_address_length;
7038       mp->next_hop_table_id = ntohl (next_hop_table_id);
7039       mp->classify_table_index = ntohl (classify_table_index);
7040       mp->next_hop_via_label = ntohl (next_hop_via_label);
7041       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7042       if (0 != mp->next_hop_n_out_labels)
7043         {
7044           memcpy (mp->next_hop_out_label_stack,
7045                   next_hop_out_label_stack,
7046                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7047           vec_free (next_hop_out_label_stack);
7048         }
7049
7050       if (is_ipv6)
7051         {
7052           clib_memcpy (mp->dst_address, &v6_dst_address,
7053                        sizeof (v6_dst_address));
7054           if (next_hop_set)
7055             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7056                          sizeof (v6_next_hop_address));
7057           increment_v6_address (&v6_dst_address);
7058         }
7059       else
7060         {
7061           clib_memcpy (mp->dst_address, &v4_dst_address,
7062                        sizeof (v4_dst_address));
7063           if (next_hop_set)
7064             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7065                          sizeof (v4_next_hop_address));
7066           if (random_add_del)
7067             v4_dst_address.as_u32 = random_vector[j + 1];
7068           else
7069             increment_v4_address (&v4_dst_address);
7070         }
7071       /* send it... */
7072       S (mp);
7073       /* If we receive SIGTERM, stop now... */
7074       if (vam->do_exit)
7075         break;
7076     }
7077
7078   /* When testing multiple add/del ops, use a control-ping to sync */
7079   if (count > 1)
7080     {
7081       vl_api_control_ping_t *mp_ping;
7082       f64 after;
7083       f64 timeout;
7084
7085       /* Shut off async mode */
7086       vam->async_mode = 0;
7087
7088       M (CONTROL_PING, mp_ping);
7089       S (mp_ping);
7090
7091       timeout = vat_time_now (vam) + 1.0;
7092       while (vat_time_now (vam) < timeout)
7093         if (vam->result_ready == 1)
7094           goto out;
7095       vam->retval = -99;
7096
7097     out:
7098       if (vam->retval == -99)
7099         errmsg ("timeout");
7100
7101       if (vam->async_errors > 0)
7102         {
7103           errmsg ("%d asynchronous errors", vam->async_errors);
7104           vam->retval = -98;
7105         }
7106       vam->async_errors = 0;
7107       after = vat_time_now (vam);
7108
7109       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7110       if (j > 0)
7111         count = j;
7112
7113       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7114              count, after - before, count / (after - before));
7115     }
7116   else
7117     {
7118       int ret;
7119
7120       /* Wait for a reply... */
7121       W (ret);
7122       return ret;
7123     }
7124
7125   /* Return the good/bad news */
7126   return (vam->retval);
7127 }
7128
7129 static int
7130 api_ip_mroute_add_del (vat_main_t * vam)
7131 {
7132   unformat_input_t *i = vam->input;
7133   vl_api_ip_mroute_add_del_t *mp;
7134   u32 sw_if_index = ~0, vrf_id = 0;
7135   u8 is_ipv6 = 0;
7136   u8 is_local = 0;
7137   u8 create_vrf_if_needed = 0;
7138   u8 is_add = 1;
7139   u8 address_set = 0;
7140   u32 grp_address_length = 0;
7141   ip4_address_t v4_grp_address, v4_src_address;
7142   ip6_address_t v6_grp_address, v6_src_address;
7143   mfib_itf_flags_t iflags = 0;
7144   mfib_entry_flags_t eflags = 0;
7145   int ret;
7146
7147   /* Parse args required to build the message */
7148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7149     {
7150       if (unformat (i, "sw_if_index %d", &sw_if_index))
7151         ;
7152       else if (unformat (i, "%U %U",
7153                          unformat_ip4_address, &v4_src_address,
7154                          unformat_ip4_address, &v4_grp_address))
7155         {
7156           grp_address_length = 64;
7157           address_set = 1;
7158           is_ipv6 = 0;
7159         }
7160       else if (unformat (i, "%U %U",
7161                          unformat_ip6_address, &v6_src_address,
7162                          unformat_ip6_address, &v6_grp_address))
7163         {
7164           grp_address_length = 256;
7165           address_set = 1;
7166           is_ipv6 = 1;
7167         }
7168       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7169         {
7170           memset (&v4_src_address, 0, sizeof (v4_src_address));
7171           grp_address_length = 32;
7172           address_set = 1;
7173           is_ipv6 = 0;
7174         }
7175       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7176         {
7177           memset (&v6_src_address, 0, sizeof (v6_src_address));
7178           grp_address_length = 128;
7179           address_set = 1;
7180           is_ipv6 = 1;
7181         }
7182       else if (unformat (i, "/%d", &grp_address_length))
7183         ;
7184       else if (unformat (i, "local"))
7185         {
7186           is_local = 1;
7187         }
7188       else if (unformat (i, "del"))
7189         is_add = 0;
7190       else if (unformat (i, "add"))
7191         is_add = 1;
7192       else if (unformat (i, "vrf %d", &vrf_id))
7193         ;
7194       else if (unformat (i, "create-vrf"))
7195         create_vrf_if_needed = 1;
7196       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7197         ;
7198       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7199         ;
7200       else
7201         {
7202           clib_warning ("parse error '%U'", format_unformat_error, i);
7203           return -99;
7204         }
7205     }
7206
7207   if (address_set == 0)
7208     {
7209       errmsg ("missing addresses\n");
7210       return -99;
7211     }
7212
7213   /* Construct the API message */
7214   M (IP_MROUTE_ADD_DEL, mp);
7215
7216   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7217   mp->table_id = ntohl (vrf_id);
7218   mp->create_vrf_if_needed = create_vrf_if_needed;
7219
7220   mp->is_add = is_add;
7221   mp->is_ipv6 = is_ipv6;
7222   mp->is_local = is_local;
7223   mp->itf_flags = ntohl (iflags);
7224   mp->entry_flags = ntohl (eflags);
7225   mp->grp_address_length = grp_address_length;
7226   mp->grp_address_length = ntohs (mp->grp_address_length);
7227
7228   if (is_ipv6)
7229     {
7230       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7231       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7232     }
7233   else
7234     {
7235       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7236       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7237
7238     }
7239
7240   /* send it... */
7241   S (mp);
7242   /* Wait for a reply... */
7243   W (ret);
7244   return ret;
7245 }
7246
7247 static int
7248 api_mpls_route_add_del (vat_main_t * vam)
7249 {
7250   unformat_input_t *i = vam->input;
7251   vl_api_mpls_route_add_del_t *mp;
7252   u32 sw_if_index = ~0, table_id = 0;
7253   u8 create_table_if_needed = 0;
7254   u8 is_add = 1;
7255   u32 next_hop_weight = 1;
7256   u8 is_multipath = 0;
7257   u32 next_hop_table_id = 0;
7258   u8 next_hop_set = 0;
7259   ip4_address_t v4_next_hop_address = {
7260     .as_u32 = 0,
7261   };
7262   ip6_address_t v6_next_hop_address = { {0} };
7263   int count = 1;
7264   int j;
7265   f64 before = 0;
7266   u32 classify_table_index = ~0;
7267   u8 is_classify = 0;
7268   u8 resolve_host = 0, resolve_attached = 0;
7269   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7270   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7271   mpls_label_t *next_hop_out_label_stack = NULL;
7272   mpls_label_t local_label = MPLS_LABEL_INVALID;
7273   u8 is_eos = 0;
7274   u8 next_hop_proto_is_ip4 = 1;
7275
7276   /* Parse args required to build the message */
7277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7278     {
7279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7280         ;
7281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7282         ;
7283       else if (unformat (i, "%d", &local_label))
7284         ;
7285       else if (unformat (i, "eos"))
7286         is_eos = 1;
7287       else if (unformat (i, "non-eos"))
7288         is_eos = 0;
7289       else if (unformat (i, "via %U", unformat_ip4_address,
7290                          &v4_next_hop_address))
7291         {
7292           next_hop_set = 1;
7293           next_hop_proto_is_ip4 = 1;
7294         }
7295       else if (unformat (i, "via %U", unformat_ip6_address,
7296                          &v6_next_hop_address))
7297         {
7298           next_hop_set = 1;
7299           next_hop_proto_is_ip4 = 0;
7300         }
7301       else if (unformat (i, "weight %d", &next_hop_weight))
7302         ;
7303       else if (unformat (i, "create-table"))
7304         create_table_if_needed = 1;
7305       else if (unformat (i, "classify %d", &classify_table_index))
7306         {
7307           is_classify = 1;
7308         }
7309       else if (unformat (i, "del"))
7310         is_add = 0;
7311       else if (unformat (i, "add"))
7312         is_add = 1;
7313       else if (unformat (i, "resolve-via-host"))
7314         resolve_host = 1;
7315       else if (unformat (i, "resolve-via-attached"))
7316         resolve_attached = 1;
7317       else if (unformat (i, "multipath"))
7318         is_multipath = 1;
7319       else if (unformat (i, "count %d", &count))
7320         ;
7321       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7322         {
7323           next_hop_set = 1;
7324           next_hop_proto_is_ip4 = 1;
7325         }
7326       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7327         {
7328           next_hop_set = 1;
7329           next_hop_proto_is_ip4 = 0;
7330         }
7331       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7332         ;
7333       else if (unformat (i, "via-label %d", &next_hop_via_label))
7334         ;
7335       else if (unformat (i, "out-label %d", &next_hop_out_label))
7336         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7337       else
7338         {
7339           clib_warning ("parse error '%U'", format_unformat_error, i);
7340           return -99;
7341         }
7342     }
7343
7344   if (!next_hop_set && !is_classify)
7345     {
7346       errmsg ("next hop / classify not set");
7347       return -99;
7348     }
7349
7350   if (MPLS_LABEL_INVALID == local_label)
7351     {
7352       errmsg ("missing label");
7353       return -99;
7354     }
7355
7356   if (count > 1)
7357     {
7358       /* Turn on async mode */
7359       vam->async_mode = 1;
7360       vam->async_errors = 0;
7361       before = vat_time_now (vam);
7362     }
7363
7364   for (j = 0; j < count; j++)
7365     {
7366       /* Construct the API message */
7367       M2 (MPLS_ROUTE_ADD_DEL, mp,
7368           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7369
7370       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7371       mp->mr_table_id = ntohl (table_id);
7372       mp->mr_create_table_if_needed = create_table_if_needed;
7373
7374       mp->mr_is_add = is_add;
7375       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7376       mp->mr_is_classify = is_classify;
7377       mp->mr_is_multipath = is_multipath;
7378       mp->mr_is_resolve_host = resolve_host;
7379       mp->mr_is_resolve_attached = resolve_attached;
7380       mp->mr_next_hop_weight = next_hop_weight;
7381       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7382       mp->mr_classify_table_index = ntohl (classify_table_index);
7383       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7384       mp->mr_label = ntohl (local_label);
7385       mp->mr_eos = is_eos;
7386
7387       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7388       if (0 != mp->mr_next_hop_n_out_labels)
7389         {
7390           memcpy (mp->mr_next_hop_out_label_stack,
7391                   next_hop_out_label_stack,
7392                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7393           vec_free (next_hop_out_label_stack);
7394         }
7395
7396       if (next_hop_set)
7397         {
7398           if (next_hop_proto_is_ip4)
7399             {
7400               clib_memcpy (mp->mr_next_hop,
7401                            &v4_next_hop_address,
7402                            sizeof (v4_next_hop_address));
7403             }
7404           else
7405             {
7406               clib_memcpy (mp->mr_next_hop,
7407                            &v6_next_hop_address,
7408                            sizeof (v6_next_hop_address));
7409             }
7410         }
7411       local_label++;
7412
7413       /* send it... */
7414       S (mp);
7415       /* If we receive SIGTERM, stop now... */
7416       if (vam->do_exit)
7417         break;
7418     }
7419
7420   /* When testing multiple add/del ops, use a control-ping to sync */
7421   if (count > 1)
7422     {
7423       vl_api_control_ping_t *mp_ping;
7424       f64 after;
7425       f64 timeout;
7426
7427       /* Shut off async mode */
7428       vam->async_mode = 0;
7429
7430       M (CONTROL_PING, mp_ping);
7431       S (mp_ping);
7432
7433       timeout = vat_time_now (vam) + 1.0;
7434       while (vat_time_now (vam) < timeout)
7435         if (vam->result_ready == 1)
7436           goto out;
7437       vam->retval = -99;
7438
7439     out:
7440       if (vam->retval == -99)
7441         errmsg ("timeout");
7442
7443       if (vam->async_errors > 0)
7444         {
7445           errmsg ("%d asynchronous errors", vam->async_errors);
7446           vam->retval = -98;
7447         }
7448       vam->async_errors = 0;
7449       after = vat_time_now (vam);
7450
7451       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7452       if (j > 0)
7453         count = j;
7454
7455       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7456              count, after - before, count / (after - before));
7457     }
7458   else
7459     {
7460       int ret;
7461
7462       /* Wait for a reply... */
7463       W (ret);
7464       return ret;
7465     }
7466
7467   /* Return the good/bad news */
7468   return (vam->retval);
7469 }
7470
7471 static int
7472 api_mpls_ip_bind_unbind (vat_main_t * vam)
7473 {
7474   unformat_input_t *i = vam->input;
7475   vl_api_mpls_ip_bind_unbind_t *mp;
7476   u32 ip_table_id = 0;
7477   u8 create_table_if_needed = 0;
7478   u8 is_bind = 1;
7479   u8 is_ip4 = 1;
7480   ip4_address_t v4_address;
7481   ip6_address_t v6_address;
7482   u32 address_length;
7483   u8 address_set = 0;
7484   mpls_label_t local_label = MPLS_LABEL_INVALID;
7485   int ret;
7486
7487   /* Parse args required to build the message */
7488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7489     {
7490       if (unformat (i, "%U/%d", unformat_ip4_address,
7491                     &v4_address, &address_length))
7492         {
7493           is_ip4 = 1;
7494           address_set = 1;
7495         }
7496       else if (unformat (i, "%U/%d", unformat_ip6_address,
7497                          &v6_address, &address_length))
7498         {
7499           is_ip4 = 0;
7500           address_set = 1;
7501         }
7502       else if (unformat (i, "%d", &local_label))
7503         ;
7504       else if (unformat (i, "create-table"))
7505         create_table_if_needed = 1;
7506       else if (unformat (i, "table-id %d", &ip_table_id))
7507         ;
7508       else if (unformat (i, "unbind"))
7509         is_bind = 0;
7510       else if (unformat (i, "bind"))
7511         is_bind = 1;
7512       else
7513         {
7514           clib_warning ("parse error '%U'", format_unformat_error, i);
7515           return -99;
7516         }
7517     }
7518
7519   if (!address_set)
7520     {
7521       errmsg ("IP addres not set");
7522       return -99;
7523     }
7524
7525   if (MPLS_LABEL_INVALID == local_label)
7526     {
7527       errmsg ("missing label");
7528       return -99;
7529     }
7530
7531   /* Construct the API message */
7532   M (MPLS_IP_BIND_UNBIND, mp);
7533
7534   mp->mb_create_table_if_needed = create_table_if_needed;
7535   mp->mb_is_bind = is_bind;
7536   mp->mb_is_ip4 = is_ip4;
7537   mp->mb_ip_table_id = ntohl (ip_table_id);
7538   mp->mb_mpls_table_id = 0;
7539   mp->mb_label = ntohl (local_label);
7540   mp->mb_address_length = address_length;
7541
7542   if (is_ip4)
7543     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7544   else
7545     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7546
7547   /* send it... */
7548   S (mp);
7549
7550   /* Wait for a reply... */
7551   W (ret);
7552   return ret;
7553 }
7554
7555 static int
7556 api_proxy_arp_add_del (vat_main_t * vam)
7557 {
7558   unformat_input_t *i = vam->input;
7559   vl_api_proxy_arp_add_del_t *mp;
7560   u32 vrf_id = 0;
7561   u8 is_add = 1;
7562   ip4_address_t lo, hi;
7563   u8 range_set = 0;
7564   int ret;
7565
7566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7567     {
7568       if (unformat (i, "vrf %d", &vrf_id))
7569         ;
7570       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7571                          unformat_ip4_address, &hi))
7572         range_set = 1;
7573       else if (unformat (i, "del"))
7574         is_add = 0;
7575       else
7576         {
7577           clib_warning ("parse error '%U'", format_unformat_error, i);
7578           return -99;
7579         }
7580     }
7581
7582   if (range_set == 0)
7583     {
7584       errmsg ("address range not set");
7585       return -99;
7586     }
7587
7588   M (PROXY_ARP_ADD_DEL, mp);
7589
7590   mp->vrf_id = ntohl (vrf_id);
7591   mp->is_add = is_add;
7592   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7593   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7594
7595   S (mp);
7596   W (ret);
7597   return ret;
7598 }
7599
7600 static int
7601 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7602 {
7603   unformat_input_t *i = vam->input;
7604   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7605   u32 sw_if_index;
7606   u8 enable = 1;
7607   u8 sw_if_index_set = 0;
7608   int ret;
7609
7610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7611     {
7612       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7613         sw_if_index_set = 1;
7614       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7615         sw_if_index_set = 1;
7616       else if (unformat (i, "enable"))
7617         enable = 1;
7618       else if (unformat (i, "disable"))
7619         enable = 0;
7620       else
7621         {
7622           clib_warning ("parse error '%U'", format_unformat_error, i);
7623           return -99;
7624         }
7625     }
7626
7627   if (sw_if_index_set == 0)
7628     {
7629       errmsg ("missing interface name or sw_if_index");
7630       return -99;
7631     }
7632
7633   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7634
7635   mp->sw_if_index = ntohl (sw_if_index);
7636   mp->enable_disable = enable;
7637
7638   S (mp);
7639   W (ret);
7640   return ret;
7641 }
7642
7643 static int
7644 api_mpls_tunnel_add_del (vat_main_t * vam)
7645 {
7646   unformat_input_t *i = vam->input;
7647   vl_api_mpls_tunnel_add_del_t *mp;
7648
7649   u8 is_add = 1;
7650   u8 l2_only = 0;
7651   u32 sw_if_index = ~0;
7652   u32 next_hop_sw_if_index = ~0;
7653   u32 next_hop_proto_is_ip4 = 1;
7654
7655   u32 next_hop_table_id = 0;
7656   ip4_address_t v4_next_hop_address = {
7657     .as_u32 = 0,
7658   };
7659   ip6_address_t v6_next_hop_address = { {0} };
7660   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7661   int ret;
7662
7663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7664     {
7665       if (unformat (i, "add"))
7666         is_add = 1;
7667       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7668         is_add = 0;
7669       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7670         ;
7671       else if (unformat (i, "via %U",
7672                          unformat_ip4_address, &v4_next_hop_address))
7673         {
7674           next_hop_proto_is_ip4 = 1;
7675         }
7676       else if (unformat (i, "via %U",
7677                          unformat_ip6_address, &v6_next_hop_address))
7678         {
7679           next_hop_proto_is_ip4 = 0;
7680         }
7681       else if (unformat (i, "l2-only"))
7682         l2_only = 1;
7683       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7684         ;
7685       else if (unformat (i, "out-label %d", &next_hop_out_label))
7686         vec_add1 (labels, ntohl (next_hop_out_label));
7687       else
7688         {
7689           clib_warning ("parse error '%U'", format_unformat_error, i);
7690           return -99;
7691         }
7692     }
7693
7694   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7695
7696   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7697   mp->mt_sw_if_index = ntohl (sw_if_index);
7698   mp->mt_is_add = is_add;
7699   mp->mt_l2_only = l2_only;
7700   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7701   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7702
7703   mp->mt_next_hop_n_out_labels = vec_len (labels);
7704
7705   if (0 != mp->mt_next_hop_n_out_labels)
7706     {
7707       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7708                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7709       vec_free (labels);
7710     }
7711
7712   if (next_hop_proto_is_ip4)
7713     {
7714       clib_memcpy (mp->mt_next_hop,
7715                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7716     }
7717   else
7718     {
7719       clib_memcpy (mp->mt_next_hop,
7720                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7721     }
7722
7723   S (mp);
7724   W (ret);
7725   return ret;
7726 }
7727
7728 static int
7729 api_sw_interface_set_unnumbered (vat_main_t * vam)
7730 {
7731   unformat_input_t *i = vam->input;
7732   vl_api_sw_interface_set_unnumbered_t *mp;
7733   u32 sw_if_index;
7734   u32 unnum_sw_index = ~0;
7735   u8 is_add = 1;
7736   u8 sw_if_index_set = 0;
7737   int ret;
7738
7739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7740     {
7741       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7742         sw_if_index_set = 1;
7743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7744         sw_if_index_set = 1;
7745       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7746         ;
7747       else if (unformat (i, "del"))
7748         is_add = 0;
7749       else
7750         {
7751           clib_warning ("parse error '%U'", format_unformat_error, i);
7752           return -99;
7753         }
7754     }
7755
7756   if (sw_if_index_set == 0)
7757     {
7758       errmsg ("missing interface name or sw_if_index");
7759       return -99;
7760     }
7761
7762   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7763
7764   mp->sw_if_index = ntohl (sw_if_index);
7765   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7766   mp->is_add = is_add;
7767
7768   S (mp);
7769   W (ret);
7770   return ret;
7771 }
7772
7773 static int
7774 api_ip_neighbor_add_del (vat_main_t * vam)
7775 {
7776   unformat_input_t *i = vam->input;
7777   vl_api_ip_neighbor_add_del_t *mp;
7778   u32 sw_if_index;
7779   u8 sw_if_index_set = 0;
7780   u8 is_add = 1;
7781   u8 is_static = 0;
7782   u8 is_no_fib_entry = 0;
7783   u8 mac_address[6];
7784   u8 mac_set = 0;
7785   u8 v4_address_set = 0;
7786   u8 v6_address_set = 0;
7787   ip4_address_t v4address;
7788   ip6_address_t v6address;
7789   int ret;
7790
7791   memset (mac_address, 0, sizeof (mac_address));
7792
7793   /* Parse args required to build the message */
7794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7795     {
7796       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7797         {
7798           mac_set = 1;
7799         }
7800       else if (unformat (i, "del"))
7801         is_add = 0;
7802       else
7803         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7804         sw_if_index_set = 1;
7805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7806         sw_if_index_set = 1;
7807       else if (unformat (i, "is_static"))
7808         is_static = 1;
7809       else if (unformat (i, "no-fib-entry"))
7810         is_no_fib_entry = 1;
7811       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7812         v4_address_set = 1;
7813       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7814         v6_address_set = 1;
7815       else
7816         {
7817           clib_warning ("parse error '%U'", format_unformat_error, i);
7818           return -99;
7819         }
7820     }
7821
7822   if (sw_if_index_set == 0)
7823     {
7824       errmsg ("missing interface name or sw_if_index");
7825       return -99;
7826     }
7827   if (v4_address_set && v6_address_set)
7828     {
7829       errmsg ("both v4 and v6 addresses set");
7830       return -99;
7831     }
7832   if (!v4_address_set && !v6_address_set)
7833     {
7834       errmsg ("no address set");
7835       return -99;
7836     }
7837
7838   /* Construct the API message */
7839   M (IP_NEIGHBOR_ADD_DEL, mp);
7840
7841   mp->sw_if_index = ntohl (sw_if_index);
7842   mp->is_add = is_add;
7843   mp->is_static = is_static;
7844   mp->is_no_adj_fib = is_no_fib_entry;
7845   if (mac_set)
7846     clib_memcpy (mp->mac_address, mac_address, 6);
7847   if (v6_address_set)
7848     {
7849       mp->is_ipv6 = 1;
7850       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7851     }
7852   else
7853     {
7854       /* mp->is_ipv6 = 0; via memset in M macro above */
7855       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7856     }
7857
7858   /* send it... */
7859   S (mp);
7860
7861   /* Wait for a reply, return good/bad news  */
7862   W (ret);
7863   return ret;
7864 }
7865
7866 static int
7867 api_reset_vrf (vat_main_t * vam)
7868 {
7869   unformat_input_t *i = vam->input;
7870   vl_api_reset_vrf_t *mp;
7871   u32 vrf_id = 0;
7872   u8 is_ipv6 = 0;
7873   u8 vrf_id_set = 0;
7874   int ret;
7875
7876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7877     {
7878       if (unformat (i, "vrf %d", &vrf_id))
7879         vrf_id_set = 1;
7880       else if (unformat (i, "ipv6"))
7881         is_ipv6 = 1;
7882       else
7883         {
7884           clib_warning ("parse error '%U'", format_unformat_error, i);
7885           return -99;
7886         }
7887     }
7888
7889   if (vrf_id_set == 0)
7890     {
7891       errmsg ("missing vrf id");
7892       return -99;
7893     }
7894
7895   M (RESET_VRF, mp);
7896
7897   mp->vrf_id = ntohl (vrf_id);
7898   mp->is_ipv6 = is_ipv6;
7899
7900   S (mp);
7901   W (ret);
7902   return ret;
7903 }
7904
7905 static int
7906 api_create_vlan_subif (vat_main_t * vam)
7907 {
7908   unformat_input_t *i = vam->input;
7909   vl_api_create_vlan_subif_t *mp;
7910   u32 sw_if_index;
7911   u8 sw_if_index_set = 0;
7912   u32 vlan_id;
7913   u8 vlan_id_set = 0;
7914   int ret;
7915
7916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7917     {
7918       if (unformat (i, "sw_if_index %d", &sw_if_index))
7919         sw_if_index_set = 1;
7920       else
7921         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7922         sw_if_index_set = 1;
7923       else if (unformat (i, "vlan %d", &vlan_id))
7924         vlan_id_set = 1;
7925       else
7926         {
7927           clib_warning ("parse error '%U'", format_unformat_error, i);
7928           return -99;
7929         }
7930     }
7931
7932   if (sw_if_index_set == 0)
7933     {
7934       errmsg ("missing interface name or sw_if_index");
7935       return -99;
7936     }
7937
7938   if (vlan_id_set == 0)
7939     {
7940       errmsg ("missing vlan_id");
7941       return -99;
7942     }
7943   M (CREATE_VLAN_SUBIF, mp);
7944
7945   mp->sw_if_index = ntohl (sw_if_index);
7946   mp->vlan_id = ntohl (vlan_id);
7947
7948   S (mp);
7949   W (ret);
7950   return ret;
7951 }
7952
7953 #define foreach_create_subif_bit                \
7954 _(no_tags)                                      \
7955 _(one_tag)                                      \
7956 _(two_tags)                                     \
7957 _(dot1ad)                                       \
7958 _(exact_match)                                  \
7959 _(default_sub)                                  \
7960 _(outer_vlan_id_any)                            \
7961 _(inner_vlan_id_any)
7962
7963 static int
7964 api_create_subif (vat_main_t * vam)
7965 {
7966   unformat_input_t *i = vam->input;
7967   vl_api_create_subif_t *mp;
7968   u32 sw_if_index;
7969   u8 sw_if_index_set = 0;
7970   u32 sub_id;
7971   u8 sub_id_set = 0;
7972   u32 no_tags = 0;
7973   u32 one_tag = 0;
7974   u32 two_tags = 0;
7975   u32 dot1ad = 0;
7976   u32 exact_match = 0;
7977   u32 default_sub = 0;
7978   u32 outer_vlan_id_any = 0;
7979   u32 inner_vlan_id_any = 0;
7980   u32 tmp;
7981   u16 outer_vlan_id = 0;
7982   u16 inner_vlan_id = 0;
7983   int ret;
7984
7985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7986     {
7987       if (unformat (i, "sw_if_index %d", &sw_if_index))
7988         sw_if_index_set = 1;
7989       else
7990         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7991         sw_if_index_set = 1;
7992       else if (unformat (i, "sub_id %d", &sub_id))
7993         sub_id_set = 1;
7994       else if (unformat (i, "outer_vlan_id %d", &tmp))
7995         outer_vlan_id = tmp;
7996       else if (unformat (i, "inner_vlan_id %d", &tmp))
7997         inner_vlan_id = tmp;
7998
7999 #define _(a) else if (unformat (i, #a)) a = 1 ;
8000       foreach_create_subif_bit
8001 #undef _
8002         else
8003         {
8004           clib_warning ("parse error '%U'", format_unformat_error, i);
8005           return -99;
8006         }
8007     }
8008
8009   if (sw_if_index_set == 0)
8010     {
8011       errmsg ("missing interface name or sw_if_index");
8012       return -99;
8013     }
8014
8015   if (sub_id_set == 0)
8016     {
8017       errmsg ("missing sub_id");
8018       return -99;
8019     }
8020   M (CREATE_SUBIF, mp);
8021
8022   mp->sw_if_index = ntohl (sw_if_index);
8023   mp->sub_id = ntohl (sub_id);
8024
8025 #define _(a) mp->a = a;
8026   foreach_create_subif_bit;
8027 #undef _
8028
8029   mp->outer_vlan_id = ntohs (outer_vlan_id);
8030   mp->inner_vlan_id = ntohs (inner_vlan_id);
8031
8032   S (mp);
8033   W (ret);
8034   return ret;
8035 }
8036
8037 static int
8038 api_oam_add_del (vat_main_t * vam)
8039 {
8040   unformat_input_t *i = vam->input;
8041   vl_api_oam_add_del_t *mp;
8042   u32 vrf_id = 0;
8043   u8 is_add = 1;
8044   ip4_address_t src, dst;
8045   u8 src_set = 0;
8046   u8 dst_set = 0;
8047   int ret;
8048
8049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8050     {
8051       if (unformat (i, "vrf %d", &vrf_id))
8052         ;
8053       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8054         src_set = 1;
8055       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8056         dst_set = 1;
8057       else if (unformat (i, "del"))
8058         is_add = 0;
8059       else
8060         {
8061           clib_warning ("parse error '%U'", format_unformat_error, i);
8062           return -99;
8063         }
8064     }
8065
8066   if (src_set == 0)
8067     {
8068       errmsg ("missing src addr");
8069       return -99;
8070     }
8071
8072   if (dst_set == 0)
8073     {
8074       errmsg ("missing dst addr");
8075       return -99;
8076     }
8077
8078   M (OAM_ADD_DEL, mp);
8079
8080   mp->vrf_id = ntohl (vrf_id);
8081   mp->is_add = is_add;
8082   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8083   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8084
8085   S (mp);
8086   W (ret);
8087   return ret;
8088 }
8089
8090 static int
8091 api_reset_fib (vat_main_t * vam)
8092 {
8093   unformat_input_t *i = vam->input;
8094   vl_api_reset_fib_t *mp;
8095   u32 vrf_id = 0;
8096   u8 is_ipv6 = 0;
8097   u8 vrf_id_set = 0;
8098
8099   int ret;
8100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8101     {
8102       if (unformat (i, "vrf %d", &vrf_id))
8103         vrf_id_set = 1;
8104       else if (unformat (i, "ipv6"))
8105         is_ipv6 = 1;
8106       else
8107         {
8108           clib_warning ("parse error '%U'", format_unformat_error, i);
8109           return -99;
8110         }
8111     }
8112
8113   if (vrf_id_set == 0)
8114     {
8115       errmsg ("missing vrf id");
8116       return -99;
8117     }
8118
8119   M (RESET_FIB, mp);
8120
8121   mp->vrf_id = ntohl (vrf_id);
8122   mp->is_ipv6 = is_ipv6;
8123
8124   S (mp);
8125   W (ret);
8126   return ret;
8127 }
8128
8129 static int
8130 api_dhcp_proxy_config (vat_main_t * vam)
8131 {
8132   unformat_input_t *i = vam->input;
8133   vl_api_dhcp_proxy_config_t *mp;
8134   u32 rx_vrf_id = 0;
8135   u32 server_vrf_id = 0;
8136   u8 is_add = 1;
8137   u8 v4_address_set = 0;
8138   u8 v6_address_set = 0;
8139   ip4_address_t v4address;
8140   ip6_address_t v6address;
8141   u8 v4_src_address_set = 0;
8142   u8 v6_src_address_set = 0;
8143   ip4_address_t v4srcaddress;
8144   ip6_address_t v6srcaddress;
8145   int ret;
8146
8147   /* Parse args required to build the message */
8148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8149     {
8150       if (unformat (i, "del"))
8151         is_add = 0;
8152       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8153         ;
8154       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8155         ;
8156       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8157         v4_address_set = 1;
8158       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8159         v6_address_set = 1;
8160       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8161         v4_src_address_set = 1;
8162       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8163         v6_src_address_set = 1;
8164       else
8165         break;
8166     }
8167
8168   if (v4_address_set && v6_address_set)
8169     {
8170       errmsg ("both v4 and v6 server addresses set");
8171       return -99;
8172     }
8173   if (!v4_address_set && !v6_address_set)
8174     {
8175       errmsg ("no server addresses set");
8176       return -99;
8177     }
8178
8179   if (v4_src_address_set && v6_src_address_set)
8180     {
8181       errmsg ("both v4 and v6  src addresses set");
8182       return -99;
8183     }
8184   if (!v4_src_address_set && !v6_src_address_set)
8185     {
8186       errmsg ("no src addresses set");
8187       return -99;
8188     }
8189
8190   if (!(v4_src_address_set && v4_address_set) &&
8191       !(v6_src_address_set && v6_address_set))
8192     {
8193       errmsg ("no matching server and src addresses set");
8194       return -99;
8195     }
8196
8197   /* Construct the API message */
8198   M (DHCP_PROXY_CONFIG, mp);
8199
8200   mp->is_add = is_add;
8201   mp->rx_vrf_id = ntohl (rx_vrf_id);
8202   mp->server_vrf_id = ntohl (server_vrf_id);
8203   if (v6_address_set)
8204     {
8205       mp->is_ipv6 = 1;
8206       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8207       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8208     }
8209   else
8210     {
8211       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8212       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8213     }
8214
8215   /* send it... */
8216   S (mp);
8217
8218   /* Wait for a reply, return good/bad news  */
8219   W (ret);
8220   return ret;
8221 }
8222
8223 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8224 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8225
8226 static void
8227 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8228 {
8229   vat_main_t *vam = &vat_main;
8230   u32 i, count = mp->count;
8231   vl_api_dhcp_server_t *s;
8232
8233   if (mp->is_ipv6)
8234     print (vam->ofp,
8235            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8236            ntohl (mp->rx_vrf_id),
8237            format_ip6_address, mp->dhcp_src_address,
8238            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8239   else
8240     print (vam->ofp,
8241            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8242            ntohl (mp->rx_vrf_id),
8243            format_ip4_address, mp->dhcp_src_address,
8244            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8245
8246   for (i = 0; i < count; i++)
8247     {
8248       s = &mp->servers[i];
8249
8250       if (mp->is_ipv6)
8251         print (vam->ofp,
8252                " Server Table-ID %d, Server Address %U",
8253                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8254       else
8255         print (vam->ofp,
8256                " Server Table-ID %d, Server Address %U",
8257                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8258     }
8259 }
8260
8261 static void vl_api_dhcp_proxy_details_t_handler_json
8262   (vl_api_dhcp_proxy_details_t * mp)
8263 {
8264   vat_main_t *vam = &vat_main;
8265   vat_json_node_t *node = NULL;
8266   u32 i, count = mp->count;
8267   struct in_addr ip4;
8268   struct in6_addr ip6;
8269   vl_api_dhcp_server_t *s;
8270
8271   if (VAT_JSON_ARRAY != vam->json_tree.type)
8272     {
8273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8274       vat_json_init_array (&vam->json_tree);
8275     }
8276   node = vat_json_array_add (&vam->json_tree);
8277
8278   vat_json_init_object (node);
8279   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8280   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8281   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8282
8283   if (mp->is_ipv6)
8284     {
8285       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8286       vat_json_object_add_ip6 (node, "src_address", ip6);
8287     }
8288   else
8289     {
8290       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8291       vat_json_object_add_ip4 (node, "src_address", ip4);
8292     }
8293
8294   for (i = 0; i < count; i++)
8295     {
8296       s = &mp->servers[i];
8297
8298       vat_json_object_add_uint (node, "server-table-id",
8299                                 ntohl (s->server_vrf_id));
8300
8301       if (mp->is_ipv6)
8302         {
8303           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8304           vat_json_object_add_ip4 (node, "src_address", ip4);
8305         }
8306       else
8307         {
8308           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8309           vat_json_object_add_ip6 (node, "server_address", ip6);
8310         }
8311     }
8312 }
8313
8314 static int
8315 api_dhcp_proxy_dump (vat_main_t * vam)
8316 {
8317   unformat_input_t *i = vam->input;
8318   vl_api_control_ping_t *mp_ping;
8319   vl_api_dhcp_proxy_dump_t *mp;
8320   u8 is_ipv6 = 0;
8321   int ret;
8322
8323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8324     {
8325       if (unformat (i, "ipv6"))
8326         is_ipv6 = 1;
8327       else
8328         {
8329           clib_warning ("parse error '%U'", format_unformat_error, i);
8330           return -99;
8331         }
8332     }
8333
8334   M (DHCP_PROXY_DUMP, mp);
8335
8336   mp->is_ip6 = is_ipv6;
8337   S (mp);
8338
8339   /* Use a control ping for synchronization */
8340   M (CONTROL_PING, mp_ping);
8341   S (mp_ping);
8342
8343   W (ret);
8344   return ret;
8345 }
8346
8347 static int
8348 api_dhcp_proxy_set_vss (vat_main_t * vam)
8349 {
8350   unformat_input_t *i = vam->input;
8351   vl_api_dhcp_proxy_set_vss_t *mp;
8352   u8 is_ipv6 = 0;
8353   u8 is_add = 1;
8354   u32 tbl_id;
8355   u8 tbl_id_set = 0;
8356   u32 oui;
8357   u8 oui_set = 0;
8358   u32 fib_id;
8359   u8 fib_id_set = 0;
8360   int ret;
8361
8362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8363     {
8364       if (unformat (i, "tbl_id %d", &tbl_id))
8365         tbl_id_set = 1;
8366       if (unformat (i, "fib_id %d", &fib_id))
8367         fib_id_set = 1;
8368       if (unformat (i, "oui %d", &oui))
8369         oui_set = 1;
8370       else if (unformat (i, "ipv6"))
8371         is_ipv6 = 1;
8372       else if (unformat (i, "del"))
8373         is_add = 0;
8374       else
8375         {
8376           clib_warning ("parse error '%U'", format_unformat_error, i);
8377           return -99;
8378         }
8379     }
8380
8381   if (tbl_id_set == 0)
8382     {
8383       errmsg ("missing tbl id");
8384       return -99;
8385     }
8386
8387   if (fib_id_set == 0)
8388     {
8389       errmsg ("missing fib id");
8390       return -99;
8391     }
8392   if (oui_set == 0)
8393     {
8394       errmsg ("missing oui");
8395       return -99;
8396     }
8397
8398   M (DHCP_PROXY_SET_VSS, mp);
8399   mp->tbl_id = ntohl (tbl_id);
8400   mp->fib_id = ntohl (fib_id);
8401   mp->oui = ntohl (oui);
8402   mp->is_ipv6 = is_ipv6;
8403   mp->is_add = is_add;
8404
8405   S (mp);
8406   W (ret);
8407   return ret;
8408 }
8409
8410 static int
8411 api_dhcp_client_config (vat_main_t * vam)
8412 {
8413   unformat_input_t *i = vam->input;
8414   vl_api_dhcp_client_config_t *mp;
8415   u32 sw_if_index;
8416   u8 sw_if_index_set = 0;
8417   u8 is_add = 1;
8418   u8 *hostname = 0;
8419   u8 disable_event = 0;
8420   int ret;
8421
8422   /* Parse args required to build the message */
8423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8424     {
8425       if (unformat (i, "del"))
8426         is_add = 0;
8427       else
8428         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8429         sw_if_index_set = 1;
8430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8431         sw_if_index_set = 1;
8432       else if (unformat (i, "hostname %s", &hostname))
8433         ;
8434       else if (unformat (i, "disable_event"))
8435         disable_event = 1;
8436       else
8437         break;
8438     }
8439
8440   if (sw_if_index_set == 0)
8441     {
8442       errmsg ("missing interface name or sw_if_index");
8443       return -99;
8444     }
8445
8446   if (vec_len (hostname) > 63)
8447     {
8448       errmsg ("hostname too long");
8449     }
8450   vec_add1 (hostname, 0);
8451
8452   /* Construct the API message */
8453   M (DHCP_CLIENT_CONFIG, mp);
8454
8455   mp->sw_if_index = htonl (sw_if_index);
8456   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8457   vec_free (hostname);
8458   mp->is_add = is_add;
8459   mp->want_dhcp_event = disable_event ? 0 : 1;
8460   mp->pid = htonl (getpid ());
8461
8462   /* send it... */
8463   S (mp);
8464
8465   /* Wait for a reply, return good/bad news  */
8466   W (ret);
8467   return ret;
8468 }
8469
8470 static int
8471 api_set_ip_flow_hash (vat_main_t * vam)
8472 {
8473   unformat_input_t *i = vam->input;
8474   vl_api_set_ip_flow_hash_t *mp;
8475   u32 vrf_id = 0;
8476   u8 is_ipv6 = 0;
8477   u8 vrf_id_set = 0;
8478   u8 src = 0;
8479   u8 dst = 0;
8480   u8 sport = 0;
8481   u8 dport = 0;
8482   u8 proto = 0;
8483   u8 reverse = 0;
8484   int ret;
8485
8486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8487     {
8488       if (unformat (i, "vrf %d", &vrf_id))
8489         vrf_id_set = 1;
8490       else if (unformat (i, "ipv6"))
8491         is_ipv6 = 1;
8492       else if (unformat (i, "src"))
8493         src = 1;
8494       else if (unformat (i, "dst"))
8495         dst = 1;
8496       else if (unformat (i, "sport"))
8497         sport = 1;
8498       else if (unformat (i, "dport"))
8499         dport = 1;
8500       else if (unformat (i, "proto"))
8501         proto = 1;
8502       else if (unformat (i, "reverse"))
8503         reverse = 1;
8504
8505       else
8506         {
8507           clib_warning ("parse error '%U'", format_unformat_error, i);
8508           return -99;
8509         }
8510     }
8511
8512   if (vrf_id_set == 0)
8513     {
8514       errmsg ("missing vrf id");
8515       return -99;
8516     }
8517
8518   M (SET_IP_FLOW_HASH, mp);
8519   mp->src = src;
8520   mp->dst = dst;
8521   mp->sport = sport;
8522   mp->dport = dport;
8523   mp->proto = proto;
8524   mp->reverse = reverse;
8525   mp->vrf_id = ntohl (vrf_id);
8526   mp->is_ipv6 = is_ipv6;
8527
8528   S (mp);
8529   W (ret);
8530   return ret;
8531 }
8532
8533 static int
8534 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8535 {
8536   unformat_input_t *i = vam->input;
8537   vl_api_sw_interface_ip6_enable_disable_t *mp;
8538   u32 sw_if_index;
8539   u8 sw_if_index_set = 0;
8540   u8 enable = 0;
8541   int ret;
8542
8543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8544     {
8545       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8546         sw_if_index_set = 1;
8547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8548         sw_if_index_set = 1;
8549       else if (unformat (i, "enable"))
8550         enable = 1;
8551       else if (unformat (i, "disable"))
8552         enable = 0;
8553       else
8554         {
8555           clib_warning ("parse error '%U'", format_unformat_error, i);
8556           return -99;
8557         }
8558     }
8559
8560   if (sw_if_index_set == 0)
8561     {
8562       errmsg ("missing interface name or sw_if_index");
8563       return -99;
8564     }
8565
8566   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8567
8568   mp->sw_if_index = ntohl (sw_if_index);
8569   mp->enable = enable;
8570
8571   S (mp);
8572   W (ret);
8573   return ret;
8574 }
8575
8576 static int
8577 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8578 {
8579   unformat_input_t *i = vam->input;
8580   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8581   u32 sw_if_index;
8582   u8 sw_if_index_set = 0;
8583   u8 v6_address_set = 0;
8584   ip6_address_t v6address;
8585   int ret;
8586
8587   /* Parse args required to build the message */
8588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8589     {
8590       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8591         sw_if_index_set = 1;
8592       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8593         sw_if_index_set = 1;
8594       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8595         v6_address_set = 1;
8596       else
8597         break;
8598     }
8599
8600   if (sw_if_index_set == 0)
8601     {
8602       errmsg ("missing interface name or sw_if_index");
8603       return -99;
8604     }
8605   if (!v6_address_set)
8606     {
8607       errmsg ("no address set");
8608       return -99;
8609     }
8610
8611   /* Construct the API message */
8612   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8613
8614   mp->sw_if_index = ntohl (sw_if_index);
8615   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8616
8617   /* send it... */
8618   S (mp);
8619
8620   /* Wait for a reply, return good/bad news  */
8621   W (ret);
8622   return ret;
8623 }
8624
8625 static int
8626 api_ip6nd_proxy_add_del (vat_main_t * vam)
8627 {
8628   unformat_input_t *i = vam->input;
8629   vl_api_ip6nd_proxy_add_del_t *mp;
8630   u32 sw_if_index = ~0;
8631   u8 v6_address_set = 0;
8632   ip6_address_t v6address;
8633   u8 is_del = 0;
8634   int ret;
8635
8636   /* Parse args required to build the message */
8637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8638     {
8639       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8640         ;
8641       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8642         ;
8643       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8644         v6_address_set = 1;
8645       if (unformat (i, "del"))
8646         is_del = 1;
8647       else
8648         {
8649           clib_warning ("parse error '%U'", format_unformat_error, i);
8650           return -99;
8651         }
8652     }
8653
8654   if (sw_if_index == ~0)
8655     {
8656       errmsg ("missing interface name or sw_if_index");
8657       return -99;
8658     }
8659   if (!v6_address_set)
8660     {
8661       errmsg ("no address set");
8662       return -99;
8663     }
8664
8665   /* Construct the API message */
8666   M (IP6ND_PROXY_ADD_DEL, mp);
8667
8668   mp->is_del = is_del;
8669   mp->sw_if_index = ntohl (sw_if_index);
8670   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8671
8672   /* send it... */
8673   S (mp);
8674
8675   /* Wait for a reply, return good/bad news  */
8676   W (ret);
8677   return ret;
8678 }
8679
8680 static int
8681 api_ip6nd_proxy_dump (vat_main_t * vam)
8682 {
8683   vl_api_ip6nd_proxy_dump_t *mp;
8684   vl_api_control_ping_t *mp_ping;
8685   int ret;
8686
8687   M (IP6ND_PROXY_DUMP, mp);
8688
8689   S (mp);
8690
8691   /* Use a control ping for synchronization */
8692   M (CONTROL_PING, mp_ping);
8693   S (mp_ping);
8694
8695   W (ret);
8696   return ret;
8697 }
8698
8699 static void vl_api_ip6nd_proxy_details_t_handler
8700   (vl_api_ip6nd_proxy_details_t * mp)
8701 {
8702   vat_main_t *vam = &vat_main;
8703
8704   print (vam->ofp, "host %U sw_if_index %d",
8705          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8706 }
8707
8708 static void vl_api_ip6nd_proxy_details_t_handler_json
8709   (vl_api_ip6nd_proxy_details_t * mp)
8710 {
8711   vat_main_t *vam = &vat_main;
8712   struct in6_addr ip6;
8713   vat_json_node_t *node = NULL;
8714
8715   if (VAT_JSON_ARRAY != vam->json_tree.type)
8716     {
8717       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8718       vat_json_init_array (&vam->json_tree);
8719     }
8720   node = vat_json_array_add (&vam->json_tree);
8721
8722   vat_json_init_object (node);
8723   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8724
8725   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8726   vat_json_object_add_ip6 (node, "host", ip6);
8727 }
8728
8729 static int
8730 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8731 {
8732   unformat_input_t *i = vam->input;
8733   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8734   u32 sw_if_index;
8735   u8 sw_if_index_set = 0;
8736   u32 address_length = 0;
8737   u8 v6_address_set = 0;
8738   ip6_address_t v6address;
8739   u8 use_default = 0;
8740   u8 no_advertise = 0;
8741   u8 off_link = 0;
8742   u8 no_autoconfig = 0;
8743   u8 no_onlink = 0;
8744   u8 is_no = 0;
8745   u32 val_lifetime = 0;
8746   u32 pref_lifetime = 0;
8747   int ret;
8748
8749   /* Parse args required to build the message */
8750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8751     {
8752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8753         sw_if_index_set = 1;
8754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8755         sw_if_index_set = 1;
8756       else if (unformat (i, "%U/%d",
8757                          unformat_ip6_address, &v6address, &address_length))
8758         v6_address_set = 1;
8759       else if (unformat (i, "val_life %d", &val_lifetime))
8760         ;
8761       else if (unformat (i, "pref_life %d", &pref_lifetime))
8762         ;
8763       else if (unformat (i, "def"))
8764         use_default = 1;
8765       else if (unformat (i, "noadv"))
8766         no_advertise = 1;
8767       else if (unformat (i, "offl"))
8768         off_link = 1;
8769       else if (unformat (i, "noauto"))
8770         no_autoconfig = 1;
8771       else if (unformat (i, "nolink"))
8772         no_onlink = 1;
8773       else if (unformat (i, "isno"))
8774         is_no = 1;
8775       else
8776         {
8777           clib_warning ("parse error '%U'", format_unformat_error, i);
8778           return -99;
8779         }
8780     }
8781
8782   if (sw_if_index_set == 0)
8783     {
8784       errmsg ("missing interface name or sw_if_index");
8785       return -99;
8786     }
8787   if (!v6_address_set)
8788     {
8789       errmsg ("no address set");
8790       return -99;
8791     }
8792
8793   /* Construct the API message */
8794   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8795
8796   mp->sw_if_index = ntohl (sw_if_index);
8797   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8798   mp->address_length = address_length;
8799   mp->use_default = use_default;
8800   mp->no_advertise = no_advertise;
8801   mp->off_link = off_link;
8802   mp->no_autoconfig = no_autoconfig;
8803   mp->no_onlink = no_onlink;
8804   mp->is_no = is_no;
8805   mp->val_lifetime = ntohl (val_lifetime);
8806   mp->pref_lifetime = ntohl (pref_lifetime);
8807
8808   /* send it... */
8809   S (mp);
8810
8811   /* Wait for a reply, return good/bad news  */
8812   W (ret);
8813   return ret;
8814 }
8815
8816 static int
8817 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8818 {
8819   unformat_input_t *i = vam->input;
8820   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8821   u32 sw_if_index;
8822   u8 sw_if_index_set = 0;
8823   u8 suppress = 0;
8824   u8 managed = 0;
8825   u8 other = 0;
8826   u8 ll_option = 0;
8827   u8 send_unicast = 0;
8828   u8 cease = 0;
8829   u8 is_no = 0;
8830   u8 default_router = 0;
8831   u32 max_interval = 0;
8832   u32 min_interval = 0;
8833   u32 lifetime = 0;
8834   u32 initial_count = 0;
8835   u32 initial_interval = 0;
8836   int ret;
8837
8838
8839   /* Parse args required to build the message */
8840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8841     {
8842       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8843         sw_if_index_set = 1;
8844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8845         sw_if_index_set = 1;
8846       else if (unformat (i, "maxint %d", &max_interval))
8847         ;
8848       else if (unformat (i, "minint %d", &min_interval))
8849         ;
8850       else if (unformat (i, "life %d", &lifetime))
8851         ;
8852       else if (unformat (i, "count %d", &initial_count))
8853         ;
8854       else if (unformat (i, "interval %d", &initial_interval))
8855         ;
8856       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8857         suppress = 1;
8858       else if (unformat (i, "managed"))
8859         managed = 1;
8860       else if (unformat (i, "other"))
8861         other = 1;
8862       else if (unformat (i, "ll"))
8863         ll_option = 1;
8864       else if (unformat (i, "send"))
8865         send_unicast = 1;
8866       else if (unformat (i, "cease"))
8867         cease = 1;
8868       else if (unformat (i, "isno"))
8869         is_no = 1;
8870       else if (unformat (i, "def"))
8871         default_router = 1;
8872       else
8873         {
8874           clib_warning ("parse error '%U'", format_unformat_error, i);
8875           return -99;
8876         }
8877     }
8878
8879   if (sw_if_index_set == 0)
8880     {
8881       errmsg ("missing interface name or sw_if_index");
8882       return -99;
8883     }
8884
8885   /* Construct the API message */
8886   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8887
8888   mp->sw_if_index = ntohl (sw_if_index);
8889   mp->max_interval = ntohl (max_interval);
8890   mp->min_interval = ntohl (min_interval);
8891   mp->lifetime = ntohl (lifetime);
8892   mp->initial_count = ntohl (initial_count);
8893   mp->initial_interval = ntohl (initial_interval);
8894   mp->suppress = suppress;
8895   mp->managed = managed;
8896   mp->other = other;
8897   mp->ll_option = ll_option;
8898   mp->send_unicast = send_unicast;
8899   mp->cease = cease;
8900   mp->is_no = is_no;
8901   mp->default_router = default_router;
8902
8903   /* send it... */
8904   S (mp);
8905
8906   /* Wait for a reply, return good/bad news  */
8907   W (ret);
8908   return ret;
8909 }
8910
8911 static int
8912 api_set_arp_neighbor_limit (vat_main_t * vam)
8913 {
8914   unformat_input_t *i = vam->input;
8915   vl_api_set_arp_neighbor_limit_t *mp;
8916   u32 arp_nbr_limit;
8917   u8 limit_set = 0;
8918   u8 is_ipv6 = 0;
8919   int ret;
8920
8921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8922     {
8923       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8924         limit_set = 1;
8925       else if (unformat (i, "ipv6"))
8926         is_ipv6 = 1;
8927       else
8928         {
8929           clib_warning ("parse error '%U'", format_unformat_error, i);
8930           return -99;
8931         }
8932     }
8933
8934   if (limit_set == 0)
8935     {
8936       errmsg ("missing limit value");
8937       return -99;
8938     }
8939
8940   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8941
8942   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8943   mp->is_ipv6 = is_ipv6;
8944
8945   S (mp);
8946   W (ret);
8947   return ret;
8948 }
8949
8950 static int
8951 api_l2_patch_add_del (vat_main_t * vam)
8952 {
8953   unformat_input_t *i = vam->input;
8954   vl_api_l2_patch_add_del_t *mp;
8955   u32 rx_sw_if_index;
8956   u8 rx_sw_if_index_set = 0;
8957   u32 tx_sw_if_index;
8958   u8 tx_sw_if_index_set = 0;
8959   u8 is_add = 1;
8960   int ret;
8961
8962   /* Parse args required to build the message */
8963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8964     {
8965       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8966         rx_sw_if_index_set = 1;
8967       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8968         tx_sw_if_index_set = 1;
8969       else if (unformat (i, "rx"))
8970         {
8971           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8972             {
8973               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8974                             &rx_sw_if_index))
8975                 rx_sw_if_index_set = 1;
8976             }
8977           else
8978             break;
8979         }
8980       else if (unformat (i, "tx"))
8981         {
8982           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8983             {
8984               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8985                             &tx_sw_if_index))
8986                 tx_sw_if_index_set = 1;
8987             }
8988           else
8989             break;
8990         }
8991       else if (unformat (i, "del"))
8992         is_add = 0;
8993       else
8994         break;
8995     }
8996
8997   if (rx_sw_if_index_set == 0)
8998     {
8999       errmsg ("missing rx interface name or rx_sw_if_index");
9000       return -99;
9001     }
9002
9003   if (tx_sw_if_index_set == 0)
9004     {
9005       errmsg ("missing tx interface name or tx_sw_if_index");
9006       return -99;
9007     }
9008
9009   M (L2_PATCH_ADD_DEL, mp);
9010
9011   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9012   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9013   mp->is_add = is_add;
9014
9015   S (mp);
9016   W (ret);
9017   return ret;
9018 }
9019
9020 u8 is_del;
9021 u8 localsid_addr[16];
9022 u8 end_psp;
9023 u8 behavior;
9024 u32 sw_if_index;
9025 u32 vlan_index;
9026 u32 fib_table;
9027 u8 nh_addr[16];
9028
9029 static int
9030 api_sr_localsid_add_del (vat_main_t * vam)
9031 {
9032   unformat_input_t *i = vam->input;
9033   vl_api_sr_localsid_add_del_t *mp;
9034
9035   u8 is_del;
9036   ip6_address_t localsid;
9037   u8 end_psp = 0;
9038   u8 behavior = ~0;
9039   u32 sw_if_index;
9040   u32 fib_table = ~(u32) 0;
9041   ip6_address_t next_hop;
9042
9043   bool nexthop_set = 0;
9044
9045   int ret;
9046
9047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9048     {
9049       if (unformat (i, "del"))
9050         is_del = 1;
9051       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9052       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9053         nexthop_set = 1;
9054       else if (unformat (i, "behavior %u", &behavior));
9055       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9056       else if (unformat (i, "fib-table %u", &fib_table));
9057       else if (unformat (i, "end.psp %u", &behavior));
9058       else
9059         break;
9060     }
9061
9062   M (SR_LOCALSID_ADD_DEL, mp);
9063
9064   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9065   if (nexthop_set)
9066     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9067   mp->behavior = behavior;
9068   mp->sw_if_index = ntohl (sw_if_index);
9069   mp->fib_table = ntohl (fib_table);
9070   mp->end_psp = end_psp;
9071   mp->is_del = is_del;
9072
9073   S (mp);
9074   W (ret);
9075   return ret;
9076 }
9077
9078 static int
9079 api_ioam_enable (vat_main_t * vam)
9080 {
9081   unformat_input_t *input = vam->input;
9082   vl_api_ioam_enable_t *mp;
9083   u32 id = 0;
9084   int has_trace_option = 0;
9085   int has_pot_option = 0;
9086   int has_seqno_option = 0;
9087   int has_analyse_option = 0;
9088   int ret;
9089
9090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9091     {
9092       if (unformat (input, "trace"))
9093         has_trace_option = 1;
9094       else if (unformat (input, "pot"))
9095         has_pot_option = 1;
9096       else if (unformat (input, "seqno"))
9097         has_seqno_option = 1;
9098       else if (unformat (input, "analyse"))
9099         has_analyse_option = 1;
9100       else
9101         break;
9102     }
9103   M (IOAM_ENABLE, mp);
9104   mp->id = htons (id);
9105   mp->seqno = has_seqno_option;
9106   mp->analyse = has_analyse_option;
9107   mp->pot_enable = has_pot_option;
9108   mp->trace_enable = has_trace_option;
9109
9110   S (mp);
9111   W (ret);
9112   return ret;
9113 }
9114
9115
9116 static int
9117 api_ioam_disable (vat_main_t * vam)
9118 {
9119   vl_api_ioam_disable_t *mp;
9120   int ret;
9121
9122   M (IOAM_DISABLE, mp);
9123   S (mp);
9124   W (ret);
9125   return ret;
9126 }
9127
9128 #define foreach_tcp_proto_field                 \
9129 _(src_port)                                     \
9130 _(dst_port)
9131
9132 #define foreach_udp_proto_field                 \
9133 _(src_port)                                     \
9134 _(dst_port)
9135
9136 #define foreach_ip4_proto_field                 \
9137 _(src_address)                                  \
9138 _(dst_address)                                  \
9139 _(tos)                                          \
9140 _(length)                                       \
9141 _(fragment_id)                                  \
9142 _(ttl)                                          \
9143 _(protocol)                                     \
9144 _(checksum)
9145
9146 typedef struct
9147 {
9148   u16 src_port, dst_port;
9149 } tcpudp_header_t;
9150
9151 #if VPP_API_TEST_BUILTIN == 0
9152 uword
9153 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9154 {
9155   u8 **maskp = va_arg (*args, u8 **);
9156   u8 *mask = 0;
9157   u8 found_something = 0;
9158   tcp_header_t *tcp;
9159
9160 #define _(a) u8 a=0;
9161   foreach_tcp_proto_field;
9162 #undef _
9163
9164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9165     {
9166       if (0);
9167 #define _(a) else if (unformat (input, #a)) a=1;
9168       foreach_tcp_proto_field
9169 #undef _
9170         else
9171         break;
9172     }
9173
9174 #define _(a) found_something += a;
9175   foreach_tcp_proto_field;
9176 #undef _
9177
9178   if (found_something == 0)
9179     return 0;
9180
9181   vec_validate (mask, sizeof (*tcp) - 1);
9182
9183   tcp = (tcp_header_t *) mask;
9184
9185 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9186   foreach_tcp_proto_field;
9187 #undef _
9188
9189   *maskp = mask;
9190   return 1;
9191 }
9192
9193 uword
9194 unformat_udp_mask (unformat_input_t * input, va_list * args)
9195 {
9196   u8 **maskp = va_arg (*args, u8 **);
9197   u8 *mask = 0;
9198   u8 found_something = 0;
9199   udp_header_t *udp;
9200
9201 #define _(a) u8 a=0;
9202   foreach_udp_proto_field;
9203 #undef _
9204
9205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9206     {
9207       if (0);
9208 #define _(a) else if (unformat (input, #a)) a=1;
9209       foreach_udp_proto_field
9210 #undef _
9211         else
9212         break;
9213     }
9214
9215 #define _(a) found_something += a;
9216   foreach_udp_proto_field;
9217 #undef _
9218
9219   if (found_something == 0)
9220     return 0;
9221
9222   vec_validate (mask, sizeof (*udp) - 1);
9223
9224   udp = (udp_header_t *) mask;
9225
9226 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9227   foreach_udp_proto_field;
9228 #undef _
9229
9230   *maskp = mask;
9231   return 1;
9232 }
9233
9234 uword
9235 unformat_l4_mask (unformat_input_t * input, va_list * args)
9236 {
9237   u8 **maskp = va_arg (*args, u8 **);
9238   u16 src_port = 0, dst_port = 0;
9239   tcpudp_header_t *tcpudp;
9240
9241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9242     {
9243       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9244         return 1;
9245       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9246         return 1;
9247       else if (unformat (input, "src_port"))
9248         src_port = 0xFFFF;
9249       else if (unformat (input, "dst_port"))
9250         dst_port = 0xFFFF;
9251       else
9252         return 0;
9253     }
9254
9255   if (!src_port && !dst_port)
9256     return 0;
9257
9258   u8 *mask = 0;
9259   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9260
9261   tcpudp = (tcpudp_header_t *) mask;
9262   tcpudp->src_port = src_port;
9263   tcpudp->dst_port = dst_port;
9264
9265   *maskp = mask;
9266
9267   return 1;
9268 }
9269
9270 uword
9271 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9272 {
9273   u8 **maskp = va_arg (*args, u8 **);
9274   u8 *mask = 0;
9275   u8 found_something = 0;
9276   ip4_header_t *ip;
9277
9278 #define _(a) u8 a=0;
9279   foreach_ip4_proto_field;
9280 #undef _
9281   u8 version = 0;
9282   u8 hdr_length = 0;
9283
9284
9285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9286     {
9287       if (unformat (input, "version"))
9288         version = 1;
9289       else if (unformat (input, "hdr_length"))
9290         hdr_length = 1;
9291       else if (unformat (input, "src"))
9292         src_address = 1;
9293       else if (unformat (input, "dst"))
9294         dst_address = 1;
9295       else if (unformat (input, "proto"))
9296         protocol = 1;
9297
9298 #define _(a) else if (unformat (input, #a)) a=1;
9299       foreach_ip4_proto_field
9300 #undef _
9301         else
9302         break;
9303     }
9304
9305 #define _(a) found_something += a;
9306   foreach_ip4_proto_field;
9307 #undef _
9308
9309   if (found_something == 0)
9310     return 0;
9311
9312   vec_validate (mask, sizeof (*ip) - 1);
9313
9314   ip = (ip4_header_t *) mask;
9315
9316 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9317   foreach_ip4_proto_field;
9318 #undef _
9319
9320   ip->ip_version_and_header_length = 0;
9321
9322   if (version)
9323     ip->ip_version_and_header_length |= 0xF0;
9324
9325   if (hdr_length)
9326     ip->ip_version_and_header_length |= 0x0F;
9327
9328   *maskp = mask;
9329   return 1;
9330 }
9331
9332 #define foreach_ip6_proto_field                 \
9333 _(src_address)                                  \
9334 _(dst_address)                                  \
9335 _(payload_length)                               \
9336 _(hop_limit)                                    \
9337 _(protocol)
9338
9339 uword
9340 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9341 {
9342   u8 **maskp = va_arg (*args, u8 **);
9343   u8 *mask = 0;
9344   u8 found_something = 0;
9345   ip6_header_t *ip;
9346   u32 ip_version_traffic_class_and_flow_label;
9347
9348 #define _(a) u8 a=0;
9349   foreach_ip6_proto_field;
9350 #undef _
9351   u8 version = 0;
9352   u8 traffic_class = 0;
9353   u8 flow_label = 0;
9354
9355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9356     {
9357       if (unformat (input, "version"))
9358         version = 1;
9359       else if (unformat (input, "traffic-class"))
9360         traffic_class = 1;
9361       else if (unformat (input, "flow-label"))
9362         flow_label = 1;
9363       else if (unformat (input, "src"))
9364         src_address = 1;
9365       else if (unformat (input, "dst"))
9366         dst_address = 1;
9367       else if (unformat (input, "proto"))
9368         protocol = 1;
9369
9370 #define _(a) else if (unformat (input, #a)) a=1;
9371       foreach_ip6_proto_field
9372 #undef _
9373         else
9374         break;
9375     }
9376
9377 #define _(a) found_something += a;
9378   foreach_ip6_proto_field;
9379 #undef _
9380
9381   if (found_something == 0)
9382     return 0;
9383
9384   vec_validate (mask, sizeof (*ip) - 1);
9385
9386   ip = (ip6_header_t *) mask;
9387
9388 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9389   foreach_ip6_proto_field;
9390 #undef _
9391
9392   ip_version_traffic_class_and_flow_label = 0;
9393
9394   if (version)
9395     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9396
9397   if (traffic_class)
9398     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9399
9400   if (flow_label)
9401     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9402
9403   ip->ip_version_traffic_class_and_flow_label =
9404     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9405
9406   *maskp = mask;
9407   return 1;
9408 }
9409
9410 uword
9411 unformat_l3_mask (unformat_input_t * input, va_list * args)
9412 {
9413   u8 **maskp = va_arg (*args, u8 **);
9414
9415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9418         return 1;
9419       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9420         return 1;
9421       else
9422         break;
9423     }
9424   return 0;
9425 }
9426
9427 uword
9428 unformat_l2_mask (unformat_input_t * input, va_list * args)
9429 {
9430   u8 **maskp = va_arg (*args, u8 **);
9431   u8 *mask = 0;
9432   u8 src = 0;
9433   u8 dst = 0;
9434   u8 proto = 0;
9435   u8 tag1 = 0;
9436   u8 tag2 = 0;
9437   u8 ignore_tag1 = 0;
9438   u8 ignore_tag2 = 0;
9439   u8 cos1 = 0;
9440   u8 cos2 = 0;
9441   u8 dot1q = 0;
9442   u8 dot1ad = 0;
9443   int len = 14;
9444
9445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9446     {
9447       if (unformat (input, "src"))
9448         src = 1;
9449       else if (unformat (input, "dst"))
9450         dst = 1;
9451       else if (unformat (input, "proto"))
9452         proto = 1;
9453       else if (unformat (input, "tag1"))
9454         tag1 = 1;
9455       else if (unformat (input, "tag2"))
9456         tag2 = 1;
9457       else if (unformat (input, "ignore-tag1"))
9458         ignore_tag1 = 1;
9459       else if (unformat (input, "ignore-tag2"))
9460         ignore_tag2 = 1;
9461       else if (unformat (input, "cos1"))
9462         cos1 = 1;
9463       else if (unformat (input, "cos2"))
9464         cos2 = 1;
9465       else if (unformat (input, "dot1q"))
9466         dot1q = 1;
9467       else if (unformat (input, "dot1ad"))
9468         dot1ad = 1;
9469       else
9470         break;
9471     }
9472   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9473        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9474     return 0;
9475
9476   if (tag1 || ignore_tag1 || cos1 || dot1q)
9477     len = 18;
9478   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9479     len = 22;
9480
9481   vec_validate (mask, len - 1);
9482
9483   if (dst)
9484     memset (mask, 0xff, 6);
9485
9486   if (src)
9487     memset (mask + 6, 0xff, 6);
9488
9489   if (tag2 || dot1ad)
9490     {
9491       /* inner vlan tag */
9492       if (tag2)
9493         {
9494           mask[19] = 0xff;
9495           mask[18] = 0x0f;
9496         }
9497       if (cos2)
9498         mask[18] |= 0xe0;
9499       if (proto)
9500         mask[21] = mask[20] = 0xff;
9501       if (tag1)
9502         {
9503           mask[15] = 0xff;
9504           mask[14] = 0x0f;
9505         }
9506       if (cos1)
9507         mask[14] |= 0xe0;
9508       *maskp = mask;
9509       return 1;
9510     }
9511   if (tag1 | dot1q)
9512     {
9513       if (tag1)
9514         {
9515           mask[15] = 0xff;
9516           mask[14] = 0x0f;
9517         }
9518       if (cos1)
9519         mask[14] |= 0xe0;
9520       if (proto)
9521         mask[16] = mask[17] = 0xff;
9522
9523       *maskp = mask;
9524       return 1;
9525     }
9526   if (cos2)
9527     mask[18] |= 0xe0;
9528   if (cos1)
9529     mask[14] |= 0xe0;
9530   if (proto)
9531     mask[12] = mask[13] = 0xff;
9532
9533   *maskp = mask;
9534   return 1;
9535 }
9536
9537 uword
9538 unformat_classify_mask (unformat_input_t * input, va_list * args)
9539 {
9540   u8 **maskp = va_arg (*args, u8 **);
9541   u32 *skipp = va_arg (*args, u32 *);
9542   u32 *matchp = va_arg (*args, u32 *);
9543   u32 match;
9544   u8 *mask = 0;
9545   u8 *l2 = 0;
9546   u8 *l3 = 0;
9547   u8 *l4 = 0;
9548   int i;
9549
9550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9551     {
9552       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9553         ;
9554       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9555         ;
9556       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9557         ;
9558       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9559         ;
9560       else
9561         break;
9562     }
9563
9564   if (l4 && !l3)
9565     {
9566       vec_free (mask);
9567       vec_free (l2);
9568       vec_free (l4);
9569       return 0;
9570     }
9571
9572   if (mask || l2 || l3 || l4)
9573     {
9574       if (l2 || l3 || l4)
9575         {
9576           /* "With a free Ethernet header in every package" */
9577           if (l2 == 0)
9578             vec_validate (l2, 13);
9579           mask = l2;
9580           if (vec_len (l3))
9581             {
9582               vec_append (mask, l3);
9583               vec_free (l3);
9584             }
9585           if (vec_len (l4))
9586             {
9587               vec_append (mask, l4);
9588               vec_free (l4);
9589             }
9590         }
9591
9592       /* Scan forward looking for the first significant mask octet */
9593       for (i = 0; i < vec_len (mask); i++)
9594         if (mask[i])
9595           break;
9596
9597       /* compute (skip, match) params */
9598       *skipp = i / sizeof (u32x4);
9599       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9600
9601       /* Pad mask to an even multiple of the vector size */
9602       while (vec_len (mask) % sizeof (u32x4))
9603         vec_add1 (mask, 0);
9604
9605       match = vec_len (mask) / sizeof (u32x4);
9606
9607       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9608         {
9609           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9610           if (*tmp || *(tmp + 1))
9611             break;
9612           match--;
9613         }
9614       if (match == 0)
9615         clib_warning ("BUG: match 0");
9616
9617       _vec_len (mask) = match * sizeof (u32x4);
9618
9619       *matchp = match;
9620       *maskp = mask;
9621
9622       return 1;
9623     }
9624
9625   return 0;
9626 }
9627 #endif /* VPP_API_TEST_BUILTIN */
9628
9629 #define foreach_l2_next                         \
9630 _(drop, DROP)                                   \
9631 _(ethernet, ETHERNET_INPUT)                     \
9632 _(ip4, IP4_INPUT)                               \
9633 _(ip6, IP6_INPUT)
9634
9635 uword
9636 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9637 {
9638   u32 *miss_next_indexp = va_arg (*args, u32 *);
9639   u32 next_index = 0;
9640   u32 tmp;
9641
9642 #define _(n,N) \
9643   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9644   foreach_l2_next;
9645 #undef _
9646
9647   if (unformat (input, "%d", &tmp))
9648     {
9649       next_index = tmp;
9650       goto out;
9651     }
9652
9653   return 0;
9654
9655 out:
9656   *miss_next_indexp = next_index;
9657   return 1;
9658 }
9659
9660 #define foreach_ip_next                         \
9661 _(drop, DROP)                                   \
9662 _(local, LOCAL)                                 \
9663 _(rewrite, REWRITE)
9664
9665 uword
9666 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9667 {
9668   u32 *miss_next_indexp = va_arg (*args, u32 *);
9669   u32 next_index = 0;
9670   u32 tmp;
9671
9672 #define _(n,N) \
9673   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9674   foreach_ip_next;
9675 #undef _
9676
9677   if (unformat (input, "%d", &tmp))
9678     {
9679       next_index = tmp;
9680       goto out;
9681     }
9682
9683   return 0;
9684
9685 out:
9686   *miss_next_indexp = next_index;
9687   return 1;
9688 }
9689
9690 #define foreach_acl_next                        \
9691 _(deny, DENY)
9692
9693 uword
9694 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9695 {
9696   u32 *miss_next_indexp = va_arg (*args, u32 *);
9697   u32 next_index = 0;
9698   u32 tmp;
9699
9700 #define _(n,N) \
9701   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9702   foreach_acl_next;
9703 #undef _
9704
9705   if (unformat (input, "permit"))
9706     {
9707       next_index = ~0;
9708       goto out;
9709     }
9710   else if (unformat (input, "%d", &tmp))
9711     {
9712       next_index = tmp;
9713       goto out;
9714     }
9715
9716   return 0;
9717
9718 out:
9719   *miss_next_indexp = next_index;
9720   return 1;
9721 }
9722
9723 uword
9724 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9725 {
9726   u32 *r = va_arg (*args, u32 *);
9727
9728   if (unformat (input, "conform-color"))
9729     *r = POLICE_CONFORM;
9730   else if (unformat (input, "exceed-color"))
9731     *r = POLICE_EXCEED;
9732   else
9733     return 0;
9734
9735   return 1;
9736 }
9737
9738 static int
9739 api_classify_add_del_table (vat_main_t * vam)
9740 {
9741   unformat_input_t *i = vam->input;
9742   vl_api_classify_add_del_table_t *mp;
9743
9744   u32 nbuckets = 2;
9745   u32 skip = ~0;
9746   u32 match = ~0;
9747   int is_add = 1;
9748   int del_chain = 0;
9749   u32 table_index = ~0;
9750   u32 next_table_index = ~0;
9751   u32 miss_next_index = ~0;
9752   u32 memory_size = 32 << 20;
9753   u8 *mask = 0;
9754   u32 current_data_flag = 0;
9755   int current_data_offset = 0;
9756   int ret;
9757
9758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9759     {
9760       if (unformat (i, "del"))
9761         is_add = 0;
9762       else if (unformat (i, "del-chain"))
9763         {
9764           is_add = 0;
9765           del_chain = 1;
9766         }
9767       else if (unformat (i, "buckets %d", &nbuckets))
9768         ;
9769       else if (unformat (i, "memory_size %d", &memory_size))
9770         ;
9771       else if (unformat (i, "skip %d", &skip))
9772         ;
9773       else if (unformat (i, "match %d", &match))
9774         ;
9775       else if (unformat (i, "table %d", &table_index))
9776         ;
9777       else if (unformat (i, "mask %U", unformat_classify_mask,
9778                          &mask, &skip, &match))
9779         ;
9780       else if (unformat (i, "next-table %d", &next_table_index))
9781         ;
9782       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9783                          &miss_next_index))
9784         ;
9785       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9786                          &miss_next_index))
9787         ;
9788       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9789                          &miss_next_index))
9790         ;
9791       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9792         ;
9793       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9794         ;
9795       else
9796         break;
9797     }
9798
9799   if (is_add && mask == 0)
9800     {
9801       errmsg ("Mask required");
9802       return -99;
9803     }
9804
9805   if (is_add && skip == ~0)
9806     {
9807       errmsg ("skip count required");
9808       return -99;
9809     }
9810
9811   if (is_add && match == ~0)
9812     {
9813       errmsg ("match count required");
9814       return -99;
9815     }
9816
9817   if (!is_add && table_index == ~0)
9818     {
9819       errmsg ("table index required for delete");
9820       return -99;
9821     }
9822
9823   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9824
9825   mp->is_add = is_add;
9826   mp->del_chain = del_chain;
9827   mp->table_index = ntohl (table_index);
9828   mp->nbuckets = ntohl (nbuckets);
9829   mp->memory_size = ntohl (memory_size);
9830   mp->skip_n_vectors = ntohl (skip);
9831   mp->match_n_vectors = ntohl (match);
9832   mp->next_table_index = ntohl (next_table_index);
9833   mp->miss_next_index = ntohl (miss_next_index);
9834   mp->current_data_flag = ntohl (current_data_flag);
9835   mp->current_data_offset = ntohl (current_data_offset);
9836   clib_memcpy (mp->mask, mask, vec_len (mask));
9837
9838   vec_free (mask);
9839
9840   S (mp);
9841   W (ret);
9842   return ret;
9843 }
9844
9845 #if VPP_API_TEST_BUILTIN == 0
9846 uword
9847 unformat_l4_match (unformat_input_t * input, va_list * args)
9848 {
9849   u8 **matchp = va_arg (*args, u8 **);
9850
9851   u8 *proto_header = 0;
9852   int src_port = 0;
9853   int dst_port = 0;
9854
9855   tcpudp_header_t h;
9856
9857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9858     {
9859       if (unformat (input, "src_port %d", &src_port))
9860         ;
9861       else if (unformat (input, "dst_port %d", &dst_port))
9862         ;
9863       else
9864         return 0;
9865     }
9866
9867   h.src_port = clib_host_to_net_u16 (src_port);
9868   h.dst_port = clib_host_to_net_u16 (dst_port);
9869   vec_validate (proto_header, sizeof (h) - 1);
9870   memcpy (proto_header, &h, sizeof (h));
9871
9872   *matchp = proto_header;
9873
9874   return 1;
9875 }
9876
9877 uword
9878 unformat_ip4_match (unformat_input_t * input, va_list * args)
9879 {
9880   u8 **matchp = va_arg (*args, u8 **);
9881   u8 *match = 0;
9882   ip4_header_t *ip;
9883   int version = 0;
9884   u32 version_val;
9885   int hdr_length = 0;
9886   u32 hdr_length_val;
9887   int src = 0, dst = 0;
9888   ip4_address_t src_val, dst_val;
9889   int proto = 0;
9890   u32 proto_val;
9891   int tos = 0;
9892   u32 tos_val;
9893   int length = 0;
9894   u32 length_val;
9895   int fragment_id = 0;
9896   u32 fragment_id_val;
9897   int ttl = 0;
9898   int ttl_val;
9899   int checksum = 0;
9900   u32 checksum_val;
9901
9902   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9903     {
9904       if (unformat (input, "version %d", &version_val))
9905         version = 1;
9906       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9907         hdr_length = 1;
9908       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9909         src = 1;
9910       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9911         dst = 1;
9912       else if (unformat (input, "proto %d", &proto_val))
9913         proto = 1;
9914       else if (unformat (input, "tos %d", &tos_val))
9915         tos = 1;
9916       else if (unformat (input, "length %d", &length_val))
9917         length = 1;
9918       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9919         fragment_id = 1;
9920       else if (unformat (input, "ttl %d", &ttl_val))
9921         ttl = 1;
9922       else if (unformat (input, "checksum %d", &checksum_val))
9923         checksum = 1;
9924       else
9925         break;
9926     }
9927
9928   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9929       + ttl + checksum == 0)
9930     return 0;
9931
9932   /*
9933    * Aligned because we use the real comparison functions
9934    */
9935   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9936
9937   ip = (ip4_header_t *) match;
9938
9939   /* These are realistically matched in practice */
9940   if (src)
9941     ip->src_address.as_u32 = src_val.as_u32;
9942
9943   if (dst)
9944     ip->dst_address.as_u32 = dst_val.as_u32;
9945
9946   if (proto)
9947     ip->protocol = proto_val;
9948
9949
9950   /* These are not, but they're included for completeness */
9951   if (version)
9952     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9953
9954   if (hdr_length)
9955     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9956
9957   if (tos)
9958     ip->tos = tos_val;
9959
9960   if (length)
9961     ip->length = clib_host_to_net_u16 (length_val);
9962
9963   if (ttl)
9964     ip->ttl = ttl_val;
9965
9966   if (checksum)
9967     ip->checksum = clib_host_to_net_u16 (checksum_val);
9968
9969   *matchp = match;
9970   return 1;
9971 }
9972
9973 uword
9974 unformat_ip6_match (unformat_input_t * input, va_list * args)
9975 {
9976   u8 **matchp = va_arg (*args, u8 **);
9977   u8 *match = 0;
9978   ip6_header_t *ip;
9979   int version = 0;
9980   u32 version_val;
9981   u8 traffic_class = 0;
9982   u32 traffic_class_val = 0;
9983   u8 flow_label = 0;
9984   u8 flow_label_val;
9985   int src = 0, dst = 0;
9986   ip6_address_t src_val, dst_val;
9987   int proto = 0;
9988   u32 proto_val;
9989   int payload_length = 0;
9990   u32 payload_length_val;
9991   int hop_limit = 0;
9992   int hop_limit_val;
9993   u32 ip_version_traffic_class_and_flow_label;
9994
9995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9996     {
9997       if (unformat (input, "version %d", &version_val))
9998         version = 1;
9999       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10000         traffic_class = 1;
10001       else if (unformat (input, "flow_label %d", &flow_label_val))
10002         flow_label = 1;
10003       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10004         src = 1;
10005       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10006         dst = 1;
10007       else if (unformat (input, "proto %d", &proto_val))
10008         proto = 1;
10009       else if (unformat (input, "payload_length %d", &payload_length_val))
10010         payload_length = 1;
10011       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10012         hop_limit = 1;
10013       else
10014         break;
10015     }
10016
10017   if (version + traffic_class + flow_label + src + dst + proto +
10018       payload_length + hop_limit == 0)
10019     return 0;
10020
10021   /*
10022    * Aligned because we use the real comparison functions
10023    */
10024   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10025
10026   ip = (ip6_header_t *) match;
10027
10028   if (src)
10029     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10030
10031   if (dst)
10032     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10033
10034   if (proto)
10035     ip->protocol = proto_val;
10036
10037   ip_version_traffic_class_and_flow_label = 0;
10038
10039   if (version)
10040     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10041
10042   if (traffic_class)
10043     ip_version_traffic_class_and_flow_label |=
10044       (traffic_class_val & 0xFF) << 20;
10045
10046   if (flow_label)
10047     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10048
10049   ip->ip_version_traffic_class_and_flow_label =
10050     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10051
10052   if (payload_length)
10053     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10054
10055   if (hop_limit)
10056     ip->hop_limit = hop_limit_val;
10057
10058   *matchp = match;
10059   return 1;
10060 }
10061
10062 uword
10063 unformat_l3_match (unformat_input_t * input, va_list * args)
10064 {
10065   u8 **matchp = va_arg (*args, u8 **);
10066
10067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10068     {
10069       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10070         return 1;
10071       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10072         return 1;
10073       else
10074         break;
10075     }
10076   return 0;
10077 }
10078
10079 uword
10080 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10081 {
10082   u8 *tagp = va_arg (*args, u8 *);
10083   u32 tag;
10084
10085   if (unformat (input, "%d", &tag))
10086     {
10087       tagp[0] = (tag >> 8) & 0x0F;
10088       tagp[1] = tag & 0xFF;
10089       return 1;
10090     }
10091
10092   return 0;
10093 }
10094
10095 uword
10096 unformat_l2_match (unformat_input_t * input, va_list * args)
10097 {
10098   u8 **matchp = va_arg (*args, u8 **);
10099   u8 *match = 0;
10100   u8 src = 0;
10101   u8 src_val[6];
10102   u8 dst = 0;
10103   u8 dst_val[6];
10104   u8 proto = 0;
10105   u16 proto_val;
10106   u8 tag1 = 0;
10107   u8 tag1_val[2];
10108   u8 tag2 = 0;
10109   u8 tag2_val[2];
10110   int len = 14;
10111   u8 ignore_tag1 = 0;
10112   u8 ignore_tag2 = 0;
10113   u8 cos1 = 0;
10114   u8 cos2 = 0;
10115   u32 cos1_val = 0;
10116   u32 cos2_val = 0;
10117
10118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10119     {
10120       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10121         src = 1;
10122       else
10123         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10124         dst = 1;
10125       else if (unformat (input, "proto %U",
10126                          unformat_ethernet_type_host_byte_order, &proto_val))
10127         proto = 1;
10128       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10129         tag1 = 1;
10130       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10131         tag2 = 1;
10132       else if (unformat (input, "ignore-tag1"))
10133         ignore_tag1 = 1;
10134       else if (unformat (input, "ignore-tag2"))
10135         ignore_tag2 = 1;
10136       else if (unformat (input, "cos1 %d", &cos1_val))
10137         cos1 = 1;
10138       else if (unformat (input, "cos2 %d", &cos2_val))
10139         cos2 = 1;
10140       else
10141         break;
10142     }
10143   if ((src + dst + proto + tag1 + tag2 +
10144        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10145     return 0;
10146
10147   if (tag1 || ignore_tag1 || cos1)
10148     len = 18;
10149   if (tag2 || ignore_tag2 || cos2)
10150     len = 22;
10151
10152   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10153
10154   if (dst)
10155     clib_memcpy (match, dst_val, 6);
10156
10157   if (src)
10158     clib_memcpy (match + 6, src_val, 6);
10159
10160   if (tag2)
10161     {
10162       /* inner vlan tag */
10163       match[19] = tag2_val[1];
10164       match[18] = tag2_val[0];
10165       if (cos2)
10166         match[18] |= (cos2_val & 0x7) << 5;
10167       if (proto)
10168         {
10169           match[21] = proto_val & 0xff;
10170           match[20] = proto_val >> 8;
10171         }
10172       if (tag1)
10173         {
10174           match[15] = tag1_val[1];
10175           match[14] = tag1_val[0];
10176         }
10177       if (cos1)
10178         match[14] |= (cos1_val & 0x7) << 5;
10179       *matchp = match;
10180       return 1;
10181     }
10182   if (tag1)
10183     {
10184       match[15] = tag1_val[1];
10185       match[14] = tag1_val[0];
10186       if (proto)
10187         {
10188           match[17] = proto_val & 0xff;
10189           match[16] = proto_val >> 8;
10190         }
10191       if (cos1)
10192         match[14] |= (cos1_val & 0x7) << 5;
10193
10194       *matchp = match;
10195       return 1;
10196     }
10197   if (cos2)
10198     match[18] |= (cos2_val & 0x7) << 5;
10199   if (cos1)
10200     match[14] |= (cos1_val & 0x7) << 5;
10201   if (proto)
10202     {
10203       match[13] = proto_val & 0xff;
10204       match[12] = proto_val >> 8;
10205     }
10206
10207   *matchp = match;
10208   return 1;
10209 }
10210 #endif
10211
10212 uword
10213 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10214 {
10215   u8 **matchp = va_arg (*args, u8 **);
10216   u32 skip_n_vectors = va_arg (*args, u32);
10217   u32 match_n_vectors = va_arg (*args, u32);
10218
10219   u8 *match = 0;
10220   u8 *l2 = 0;
10221   u8 *l3 = 0;
10222   u8 *l4 = 0;
10223
10224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10225     {
10226       if (unformat (input, "hex %U", unformat_hex_string, &match))
10227         ;
10228       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10229         ;
10230       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10231         ;
10232       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10233         ;
10234       else
10235         break;
10236     }
10237
10238   if (l4 && !l3)
10239     {
10240       vec_free (match);
10241       vec_free (l2);
10242       vec_free (l4);
10243       return 0;
10244     }
10245
10246   if (match || l2 || l3 || l4)
10247     {
10248       if (l2 || l3 || l4)
10249         {
10250           /* "Win a free Ethernet header in every packet" */
10251           if (l2 == 0)
10252             vec_validate_aligned (l2, 13, sizeof (u32x4));
10253           match = l2;
10254           if (vec_len (l3))
10255             {
10256               vec_append_aligned (match, l3, sizeof (u32x4));
10257               vec_free (l3);
10258             }
10259           if (vec_len (l4))
10260             {
10261               vec_append_aligned (match, l4, sizeof (u32x4));
10262               vec_free (l4);
10263             }
10264         }
10265
10266       /* Make sure the vector is big enough even if key is all 0's */
10267       vec_validate_aligned
10268         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10269          sizeof (u32x4));
10270
10271       /* Set size, include skipped vectors */
10272       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10273
10274       *matchp = match;
10275
10276       return 1;
10277     }
10278
10279   return 0;
10280 }
10281
10282 static int
10283 api_classify_add_del_session (vat_main_t * vam)
10284 {
10285   unformat_input_t *i = vam->input;
10286   vl_api_classify_add_del_session_t *mp;
10287   int is_add = 1;
10288   u32 table_index = ~0;
10289   u32 hit_next_index = ~0;
10290   u32 opaque_index = ~0;
10291   u8 *match = 0;
10292   i32 advance = 0;
10293   u32 skip_n_vectors = 0;
10294   u32 match_n_vectors = 0;
10295   u32 action = 0;
10296   u32 metadata = 0;
10297   int ret;
10298
10299   /*
10300    * Warning: you have to supply skip_n and match_n
10301    * because the API client cant simply look at the classify
10302    * table object.
10303    */
10304
10305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10306     {
10307       if (unformat (i, "del"))
10308         is_add = 0;
10309       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10310                          &hit_next_index))
10311         ;
10312       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10313                          &hit_next_index))
10314         ;
10315       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10316                          &hit_next_index))
10317         ;
10318       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10319         ;
10320       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10321         ;
10322       else if (unformat (i, "opaque-index %d", &opaque_index))
10323         ;
10324       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10325         ;
10326       else if (unformat (i, "match_n %d", &match_n_vectors))
10327         ;
10328       else if (unformat (i, "match %U", api_unformat_classify_match,
10329                          &match, skip_n_vectors, match_n_vectors))
10330         ;
10331       else if (unformat (i, "advance %d", &advance))
10332         ;
10333       else if (unformat (i, "table-index %d", &table_index))
10334         ;
10335       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10336         action = 1;
10337       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10338         action = 2;
10339       else if (unformat (i, "action %d", &action))
10340         ;
10341       else if (unformat (i, "metadata %d", &metadata))
10342         ;
10343       else
10344         break;
10345     }
10346
10347   if (table_index == ~0)
10348     {
10349       errmsg ("Table index required");
10350       return -99;
10351     }
10352
10353   if (is_add && match == 0)
10354     {
10355       errmsg ("Match value required");
10356       return -99;
10357     }
10358
10359   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10360
10361   mp->is_add = is_add;
10362   mp->table_index = ntohl (table_index);
10363   mp->hit_next_index = ntohl (hit_next_index);
10364   mp->opaque_index = ntohl (opaque_index);
10365   mp->advance = ntohl (advance);
10366   mp->action = action;
10367   mp->metadata = ntohl (metadata);
10368   clib_memcpy (mp->match, match, vec_len (match));
10369   vec_free (match);
10370
10371   S (mp);
10372   W (ret);
10373   return ret;
10374 }
10375
10376 static int
10377 api_classify_set_interface_ip_table (vat_main_t * vam)
10378 {
10379   unformat_input_t *i = vam->input;
10380   vl_api_classify_set_interface_ip_table_t *mp;
10381   u32 sw_if_index;
10382   int sw_if_index_set;
10383   u32 table_index = ~0;
10384   u8 is_ipv6 = 0;
10385   int ret;
10386
10387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10388     {
10389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10390         sw_if_index_set = 1;
10391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10392         sw_if_index_set = 1;
10393       else if (unformat (i, "table %d", &table_index))
10394         ;
10395       else
10396         {
10397           clib_warning ("parse error '%U'", format_unformat_error, i);
10398           return -99;
10399         }
10400     }
10401
10402   if (sw_if_index_set == 0)
10403     {
10404       errmsg ("missing interface name or sw_if_index");
10405       return -99;
10406     }
10407
10408
10409   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10410
10411   mp->sw_if_index = ntohl (sw_if_index);
10412   mp->table_index = ntohl (table_index);
10413   mp->is_ipv6 = is_ipv6;
10414
10415   S (mp);
10416   W (ret);
10417   return ret;
10418 }
10419
10420 static int
10421 api_classify_set_interface_l2_tables (vat_main_t * vam)
10422 {
10423   unformat_input_t *i = vam->input;
10424   vl_api_classify_set_interface_l2_tables_t *mp;
10425   u32 sw_if_index;
10426   int sw_if_index_set;
10427   u32 ip4_table_index = ~0;
10428   u32 ip6_table_index = ~0;
10429   u32 other_table_index = ~0;
10430   u32 is_input = 1;
10431   int ret;
10432
10433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10434     {
10435       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10436         sw_if_index_set = 1;
10437       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10438         sw_if_index_set = 1;
10439       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10440         ;
10441       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10442         ;
10443       else if (unformat (i, "other-table %d", &other_table_index))
10444         ;
10445       else if (unformat (i, "is-input %d", &is_input))
10446         ;
10447       else
10448         {
10449           clib_warning ("parse error '%U'", format_unformat_error, i);
10450           return -99;
10451         }
10452     }
10453
10454   if (sw_if_index_set == 0)
10455     {
10456       errmsg ("missing interface name or sw_if_index");
10457       return -99;
10458     }
10459
10460
10461   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10462
10463   mp->sw_if_index = ntohl (sw_if_index);
10464   mp->ip4_table_index = ntohl (ip4_table_index);
10465   mp->ip6_table_index = ntohl (ip6_table_index);
10466   mp->other_table_index = ntohl (other_table_index);
10467   mp->is_input = (u8) is_input;
10468
10469   S (mp);
10470   W (ret);
10471   return ret;
10472 }
10473
10474 static int
10475 api_set_ipfix_exporter (vat_main_t * vam)
10476 {
10477   unformat_input_t *i = vam->input;
10478   vl_api_set_ipfix_exporter_t *mp;
10479   ip4_address_t collector_address;
10480   u8 collector_address_set = 0;
10481   u32 collector_port = ~0;
10482   ip4_address_t src_address;
10483   u8 src_address_set = 0;
10484   u32 vrf_id = ~0;
10485   u32 path_mtu = ~0;
10486   u32 template_interval = ~0;
10487   u8 udp_checksum = 0;
10488   int ret;
10489
10490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10491     {
10492       if (unformat (i, "collector_address %U", unformat_ip4_address,
10493                     &collector_address))
10494         collector_address_set = 1;
10495       else if (unformat (i, "collector_port %d", &collector_port))
10496         ;
10497       else if (unformat (i, "src_address %U", unformat_ip4_address,
10498                          &src_address))
10499         src_address_set = 1;
10500       else if (unformat (i, "vrf_id %d", &vrf_id))
10501         ;
10502       else if (unformat (i, "path_mtu %d", &path_mtu))
10503         ;
10504       else if (unformat (i, "template_interval %d", &template_interval))
10505         ;
10506       else if (unformat (i, "udp_checksum"))
10507         udp_checksum = 1;
10508       else
10509         break;
10510     }
10511
10512   if (collector_address_set == 0)
10513     {
10514       errmsg ("collector_address required");
10515       return -99;
10516     }
10517
10518   if (src_address_set == 0)
10519     {
10520       errmsg ("src_address required");
10521       return -99;
10522     }
10523
10524   M (SET_IPFIX_EXPORTER, mp);
10525
10526   memcpy (mp->collector_address, collector_address.data,
10527           sizeof (collector_address.data));
10528   mp->collector_port = htons ((u16) collector_port);
10529   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10530   mp->vrf_id = htonl (vrf_id);
10531   mp->path_mtu = htonl (path_mtu);
10532   mp->template_interval = htonl (template_interval);
10533   mp->udp_checksum = udp_checksum;
10534
10535   S (mp);
10536   W (ret);
10537   return ret;
10538 }
10539
10540 static int
10541 api_set_ipfix_classify_stream (vat_main_t * vam)
10542 {
10543   unformat_input_t *i = vam->input;
10544   vl_api_set_ipfix_classify_stream_t *mp;
10545   u32 domain_id = 0;
10546   u32 src_port = UDP_DST_PORT_ipfix;
10547   int ret;
10548
10549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10550     {
10551       if (unformat (i, "domain %d", &domain_id))
10552         ;
10553       else if (unformat (i, "src_port %d", &src_port))
10554         ;
10555       else
10556         {
10557           errmsg ("unknown input `%U'", format_unformat_error, i);
10558           return -99;
10559         }
10560     }
10561
10562   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10563
10564   mp->domain_id = htonl (domain_id);
10565   mp->src_port = htons ((u16) src_port);
10566
10567   S (mp);
10568   W (ret);
10569   return ret;
10570 }
10571
10572 static int
10573 api_ipfix_classify_table_add_del (vat_main_t * vam)
10574 {
10575   unformat_input_t *i = vam->input;
10576   vl_api_ipfix_classify_table_add_del_t *mp;
10577   int is_add = -1;
10578   u32 classify_table_index = ~0;
10579   u8 ip_version = 0;
10580   u8 transport_protocol = 255;
10581   int ret;
10582
10583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10584     {
10585       if (unformat (i, "add"))
10586         is_add = 1;
10587       else if (unformat (i, "del"))
10588         is_add = 0;
10589       else if (unformat (i, "table %d", &classify_table_index))
10590         ;
10591       else if (unformat (i, "ip4"))
10592         ip_version = 4;
10593       else if (unformat (i, "ip6"))
10594         ip_version = 6;
10595       else if (unformat (i, "tcp"))
10596         transport_protocol = 6;
10597       else if (unformat (i, "udp"))
10598         transport_protocol = 17;
10599       else
10600         {
10601           errmsg ("unknown input `%U'", format_unformat_error, i);
10602           return -99;
10603         }
10604     }
10605
10606   if (is_add == -1)
10607     {
10608       errmsg ("expecting: add|del");
10609       return -99;
10610     }
10611   if (classify_table_index == ~0)
10612     {
10613       errmsg ("classifier table not specified");
10614       return -99;
10615     }
10616   if (ip_version == 0)
10617     {
10618       errmsg ("IP version not specified");
10619       return -99;
10620     }
10621
10622   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10623
10624   mp->is_add = is_add;
10625   mp->table_id = htonl (classify_table_index);
10626   mp->ip_version = ip_version;
10627   mp->transport_protocol = transport_protocol;
10628
10629   S (mp);
10630   W (ret);
10631   return ret;
10632 }
10633
10634 static int
10635 api_get_node_index (vat_main_t * vam)
10636 {
10637   unformat_input_t *i = vam->input;
10638   vl_api_get_node_index_t *mp;
10639   u8 *name = 0;
10640   int ret;
10641
10642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10643     {
10644       if (unformat (i, "node %s", &name))
10645         ;
10646       else
10647         break;
10648     }
10649   if (name == 0)
10650     {
10651       errmsg ("node name required");
10652       return -99;
10653     }
10654   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10655     {
10656       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10657       return -99;
10658     }
10659
10660   M (GET_NODE_INDEX, mp);
10661   clib_memcpy (mp->node_name, name, vec_len (name));
10662   vec_free (name);
10663
10664   S (mp);
10665   W (ret);
10666   return ret;
10667 }
10668
10669 static int
10670 api_get_next_index (vat_main_t * vam)
10671 {
10672   unformat_input_t *i = vam->input;
10673   vl_api_get_next_index_t *mp;
10674   u8 *node_name = 0, *next_node_name = 0;
10675   int ret;
10676
10677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10678     {
10679       if (unformat (i, "node-name %s", &node_name))
10680         ;
10681       else if (unformat (i, "next-node-name %s", &next_node_name))
10682         break;
10683     }
10684
10685   if (node_name == 0)
10686     {
10687       errmsg ("node name required");
10688       return -99;
10689     }
10690   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10691     {
10692       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10693       return -99;
10694     }
10695
10696   if (next_node_name == 0)
10697     {
10698       errmsg ("next node name required");
10699       return -99;
10700     }
10701   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10702     {
10703       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10704       return -99;
10705     }
10706
10707   M (GET_NEXT_INDEX, mp);
10708   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10709   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10710   vec_free (node_name);
10711   vec_free (next_node_name);
10712
10713   S (mp);
10714   W (ret);
10715   return ret;
10716 }
10717
10718 static int
10719 api_add_node_next (vat_main_t * vam)
10720 {
10721   unformat_input_t *i = vam->input;
10722   vl_api_add_node_next_t *mp;
10723   u8 *name = 0;
10724   u8 *next = 0;
10725   int ret;
10726
10727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10728     {
10729       if (unformat (i, "node %s", &name))
10730         ;
10731       else if (unformat (i, "next %s", &next))
10732         ;
10733       else
10734         break;
10735     }
10736   if (name == 0)
10737     {
10738       errmsg ("node name required");
10739       return -99;
10740     }
10741   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10742     {
10743       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10744       return -99;
10745     }
10746   if (next == 0)
10747     {
10748       errmsg ("next node required");
10749       return -99;
10750     }
10751   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10752     {
10753       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10754       return -99;
10755     }
10756
10757   M (ADD_NODE_NEXT, mp);
10758   clib_memcpy (mp->node_name, name, vec_len (name));
10759   clib_memcpy (mp->next_name, next, vec_len (next));
10760   vec_free (name);
10761   vec_free (next);
10762
10763   S (mp);
10764   W (ret);
10765   return ret;
10766 }
10767
10768 static int
10769 api_l2tpv3_create_tunnel (vat_main_t * vam)
10770 {
10771   unformat_input_t *i = vam->input;
10772   ip6_address_t client_address, our_address;
10773   int client_address_set = 0;
10774   int our_address_set = 0;
10775   u32 local_session_id = 0;
10776   u32 remote_session_id = 0;
10777   u64 local_cookie = 0;
10778   u64 remote_cookie = 0;
10779   u8 l2_sublayer_present = 0;
10780   vl_api_l2tpv3_create_tunnel_t *mp;
10781   int ret;
10782
10783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10784     {
10785       if (unformat (i, "client_address %U", unformat_ip6_address,
10786                     &client_address))
10787         client_address_set = 1;
10788       else if (unformat (i, "our_address %U", unformat_ip6_address,
10789                          &our_address))
10790         our_address_set = 1;
10791       else if (unformat (i, "local_session_id %d", &local_session_id))
10792         ;
10793       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10794         ;
10795       else if (unformat (i, "local_cookie %lld", &local_cookie))
10796         ;
10797       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10798         ;
10799       else if (unformat (i, "l2-sublayer-present"))
10800         l2_sublayer_present = 1;
10801       else
10802         break;
10803     }
10804
10805   if (client_address_set == 0)
10806     {
10807       errmsg ("client_address required");
10808       return -99;
10809     }
10810
10811   if (our_address_set == 0)
10812     {
10813       errmsg ("our_address required");
10814       return -99;
10815     }
10816
10817   M (L2TPV3_CREATE_TUNNEL, mp);
10818
10819   clib_memcpy (mp->client_address, client_address.as_u8,
10820                sizeof (mp->client_address));
10821
10822   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10823
10824   mp->local_session_id = ntohl (local_session_id);
10825   mp->remote_session_id = ntohl (remote_session_id);
10826   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10827   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10828   mp->l2_sublayer_present = l2_sublayer_present;
10829   mp->is_ipv6 = 1;
10830
10831   S (mp);
10832   W (ret);
10833   return ret;
10834 }
10835
10836 static int
10837 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10838 {
10839   unformat_input_t *i = vam->input;
10840   u32 sw_if_index;
10841   u8 sw_if_index_set = 0;
10842   u64 new_local_cookie = 0;
10843   u64 new_remote_cookie = 0;
10844   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10845   int ret;
10846
10847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10848     {
10849       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10850         sw_if_index_set = 1;
10851       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10852         sw_if_index_set = 1;
10853       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10854         ;
10855       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10856         ;
10857       else
10858         break;
10859     }
10860
10861   if (sw_if_index_set == 0)
10862     {
10863       errmsg ("missing interface name or sw_if_index");
10864       return -99;
10865     }
10866
10867   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10868
10869   mp->sw_if_index = ntohl (sw_if_index);
10870   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10871   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10872
10873   S (mp);
10874   W (ret);
10875   return ret;
10876 }
10877
10878 static int
10879 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10880 {
10881   unformat_input_t *i = vam->input;
10882   vl_api_l2tpv3_interface_enable_disable_t *mp;
10883   u32 sw_if_index;
10884   u8 sw_if_index_set = 0;
10885   u8 enable_disable = 1;
10886   int ret;
10887
10888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10889     {
10890       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10891         sw_if_index_set = 1;
10892       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10893         sw_if_index_set = 1;
10894       else if (unformat (i, "enable"))
10895         enable_disable = 1;
10896       else if (unformat (i, "disable"))
10897         enable_disable = 0;
10898       else
10899         break;
10900     }
10901
10902   if (sw_if_index_set == 0)
10903     {
10904       errmsg ("missing interface name or sw_if_index");
10905       return -99;
10906     }
10907
10908   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10909
10910   mp->sw_if_index = ntohl (sw_if_index);
10911   mp->enable_disable = enable_disable;
10912
10913   S (mp);
10914   W (ret);
10915   return ret;
10916 }
10917
10918 static int
10919 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10920 {
10921   unformat_input_t *i = vam->input;
10922   vl_api_l2tpv3_set_lookup_key_t *mp;
10923   u8 key = ~0;
10924   int ret;
10925
10926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10927     {
10928       if (unformat (i, "lookup_v6_src"))
10929         key = L2T_LOOKUP_SRC_ADDRESS;
10930       else if (unformat (i, "lookup_v6_dst"))
10931         key = L2T_LOOKUP_DST_ADDRESS;
10932       else if (unformat (i, "lookup_session_id"))
10933         key = L2T_LOOKUP_SESSION_ID;
10934       else
10935         break;
10936     }
10937
10938   if (key == (u8) ~ 0)
10939     {
10940       errmsg ("l2tp session lookup key unset");
10941       return -99;
10942     }
10943
10944   M (L2TPV3_SET_LOOKUP_KEY, mp);
10945
10946   mp->key = key;
10947
10948   S (mp);
10949   W (ret);
10950   return ret;
10951 }
10952
10953 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10954   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10955 {
10956   vat_main_t *vam = &vat_main;
10957
10958   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10959          format_ip6_address, mp->our_address,
10960          format_ip6_address, mp->client_address,
10961          clib_net_to_host_u32 (mp->sw_if_index));
10962
10963   print (vam->ofp,
10964          "   local cookies %016llx %016llx remote cookie %016llx",
10965          clib_net_to_host_u64 (mp->local_cookie[0]),
10966          clib_net_to_host_u64 (mp->local_cookie[1]),
10967          clib_net_to_host_u64 (mp->remote_cookie));
10968
10969   print (vam->ofp, "   local session-id %d remote session-id %d",
10970          clib_net_to_host_u32 (mp->local_session_id),
10971          clib_net_to_host_u32 (mp->remote_session_id));
10972
10973   print (vam->ofp, "   l2 specific sublayer %s\n",
10974          mp->l2_sublayer_present ? "preset" : "absent");
10975
10976 }
10977
10978 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10979   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10980 {
10981   vat_main_t *vam = &vat_main;
10982   vat_json_node_t *node = NULL;
10983   struct in6_addr addr;
10984
10985   if (VAT_JSON_ARRAY != vam->json_tree.type)
10986     {
10987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10988       vat_json_init_array (&vam->json_tree);
10989     }
10990   node = vat_json_array_add (&vam->json_tree);
10991
10992   vat_json_init_object (node);
10993
10994   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10995   vat_json_object_add_ip6 (node, "our_address", addr);
10996   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10997   vat_json_object_add_ip6 (node, "client_address", addr);
10998
10999   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11000   vat_json_init_array (lc);
11001   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11002   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11003   vat_json_object_add_uint (node, "remote_cookie",
11004                             clib_net_to_host_u64 (mp->remote_cookie));
11005
11006   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11007   vat_json_object_add_uint (node, "local_session_id",
11008                             clib_net_to_host_u32 (mp->local_session_id));
11009   vat_json_object_add_uint (node, "remote_session_id",
11010                             clib_net_to_host_u32 (mp->remote_session_id));
11011   vat_json_object_add_string_copy (node, "l2_sublayer",
11012                                    mp->l2_sublayer_present ? (u8 *) "present"
11013                                    : (u8 *) "absent");
11014 }
11015
11016 static int
11017 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11018 {
11019   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11020   vl_api_control_ping_t *mp_ping;
11021   int ret;
11022
11023   /* Get list of l2tpv3-tunnel interfaces */
11024   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11025   S (mp);
11026
11027   /* Use a control ping for synchronization */
11028   M (CONTROL_PING, mp_ping);
11029   S (mp_ping);
11030
11031   W (ret);
11032   return ret;
11033 }
11034
11035
11036 static void vl_api_sw_interface_tap_details_t_handler
11037   (vl_api_sw_interface_tap_details_t * mp)
11038 {
11039   vat_main_t *vam = &vat_main;
11040
11041   print (vam->ofp, "%-16s %d",
11042          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11043 }
11044
11045 static void vl_api_sw_interface_tap_details_t_handler_json
11046   (vl_api_sw_interface_tap_details_t * mp)
11047 {
11048   vat_main_t *vam = &vat_main;
11049   vat_json_node_t *node = NULL;
11050
11051   if (VAT_JSON_ARRAY != vam->json_tree.type)
11052     {
11053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11054       vat_json_init_array (&vam->json_tree);
11055     }
11056   node = vat_json_array_add (&vam->json_tree);
11057
11058   vat_json_init_object (node);
11059   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11060   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11061 }
11062
11063 static int
11064 api_sw_interface_tap_dump (vat_main_t * vam)
11065 {
11066   vl_api_sw_interface_tap_dump_t *mp;
11067   vl_api_control_ping_t *mp_ping;
11068   int ret;
11069
11070   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11071   /* Get list of tap interfaces */
11072   M (SW_INTERFACE_TAP_DUMP, mp);
11073   S (mp);
11074
11075   /* Use a control ping for synchronization */
11076   M (CONTROL_PING, mp_ping);
11077   S (mp_ping);
11078
11079   W (ret);
11080   return ret;
11081 }
11082
11083 static uword unformat_vxlan_decap_next
11084   (unformat_input_t * input, va_list * args)
11085 {
11086   u32 *result = va_arg (*args, u32 *);
11087   u32 tmp;
11088
11089   if (unformat (input, "l2"))
11090     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11091   else if (unformat (input, "%d", &tmp))
11092     *result = tmp;
11093   else
11094     return 0;
11095   return 1;
11096 }
11097
11098 static int
11099 api_vxlan_add_del_tunnel (vat_main_t * vam)
11100 {
11101   unformat_input_t *line_input = vam->input;
11102   vl_api_vxlan_add_del_tunnel_t *mp;
11103   ip46_address_t src, dst;
11104   u8 is_add = 1;
11105   u8 ipv4_set = 0, ipv6_set = 0;
11106   u8 src_set = 0;
11107   u8 dst_set = 0;
11108   u8 grp_set = 0;
11109   u32 mcast_sw_if_index = ~0;
11110   u32 encap_vrf_id = 0;
11111   u32 decap_next_index = ~0;
11112   u32 vni = 0;
11113   int ret;
11114
11115   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11116   memset (&src, 0, sizeof src);
11117   memset (&dst, 0, sizeof dst);
11118
11119   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11120     {
11121       if (unformat (line_input, "del"))
11122         is_add = 0;
11123       else
11124         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11125         {
11126           ipv4_set = 1;
11127           src_set = 1;
11128         }
11129       else
11130         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11131         {
11132           ipv4_set = 1;
11133           dst_set = 1;
11134         }
11135       else
11136         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11137         {
11138           ipv6_set = 1;
11139           src_set = 1;
11140         }
11141       else
11142         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11143         {
11144           ipv6_set = 1;
11145           dst_set = 1;
11146         }
11147       else if (unformat (line_input, "group %U %U",
11148                          unformat_ip4_address, &dst.ip4,
11149                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11150         {
11151           grp_set = dst_set = 1;
11152           ipv4_set = 1;
11153         }
11154       else if (unformat (line_input, "group %U",
11155                          unformat_ip4_address, &dst.ip4))
11156         {
11157           grp_set = dst_set = 1;
11158           ipv4_set = 1;
11159         }
11160       else if (unformat (line_input, "group %U %U",
11161                          unformat_ip6_address, &dst.ip6,
11162                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11163         {
11164           grp_set = dst_set = 1;
11165           ipv6_set = 1;
11166         }
11167       else if (unformat (line_input, "group %U",
11168                          unformat_ip6_address, &dst.ip6))
11169         {
11170           grp_set = dst_set = 1;
11171           ipv6_set = 1;
11172         }
11173       else
11174         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11175         ;
11176       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11177         ;
11178       else if (unformat (line_input, "decap-next %U",
11179                          unformat_vxlan_decap_next, &decap_next_index))
11180         ;
11181       else if (unformat (line_input, "vni %d", &vni))
11182         ;
11183       else
11184         {
11185           errmsg ("parse error '%U'", format_unformat_error, line_input);
11186           return -99;
11187         }
11188     }
11189
11190   if (src_set == 0)
11191     {
11192       errmsg ("tunnel src address not specified");
11193       return -99;
11194     }
11195   if (dst_set == 0)
11196     {
11197       errmsg ("tunnel dst address not specified");
11198       return -99;
11199     }
11200
11201   if (grp_set && !ip46_address_is_multicast (&dst))
11202     {
11203       errmsg ("tunnel group address not multicast");
11204       return -99;
11205     }
11206   if (grp_set && mcast_sw_if_index == ~0)
11207     {
11208       errmsg ("tunnel nonexistent multicast device");
11209       return -99;
11210     }
11211   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11212     {
11213       errmsg ("tunnel dst address must be unicast");
11214       return -99;
11215     }
11216
11217
11218   if (ipv4_set && ipv6_set)
11219     {
11220       errmsg ("both IPv4 and IPv6 addresses specified");
11221       return -99;
11222     }
11223
11224   if ((vni == 0) || (vni >> 24))
11225     {
11226       errmsg ("vni not specified or out of range");
11227       return -99;
11228     }
11229
11230   M (VXLAN_ADD_DEL_TUNNEL, mp);
11231
11232   if (ipv6_set)
11233     {
11234       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11235       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11236     }
11237   else
11238     {
11239       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11240       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11241     }
11242   mp->encap_vrf_id = ntohl (encap_vrf_id);
11243   mp->decap_next_index = ntohl (decap_next_index);
11244   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11245   mp->vni = ntohl (vni);
11246   mp->is_add = is_add;
11247   mp->is_ipv6 = ipv6_set;
11248
11249   S (mp);
11250   W (ret);
11251   return ret;
11252 }
11253
11254 static void vl_api_vxlan_tunnel_details_t_handler
11255   (vl_api_vxlan_tunnel_details_t * mp)
11256 {
11257   vat_main_t *vam = &vat_main;
11258   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11259   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11260
11261   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11262          ntohl (mp->sw_if_index),
11263          format_ip46_address, &src, IP46_TYPE_ANY,
11264          format_ip46_address, &dst, IP46_TYPE_ANY,
11265          ntohl (mp->encap_vrf_id),
11266          ntohl (mp->decap_next_index), ntohl (mp->vni),
11267          ntohl (mp->mcast_sw_if_index));
11268 }
11269
11270 static void vl_api_vxlan_tunnel_details_t_handler_json
11271   (vl_api_vxlan_tunnel_details_t * mp)
11272 {
11273   vat_main_t *vam = &vat_main;
11274   vat_json_node_t *node = NULL;
11275
11276   if (VAT_JSON_ARRAY != vam->json_tree.type)
11277     {
11278       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11279       vat_json_init_array (&vam->json_tree);
11280     }
11281   node = vat_json_array_add (&vam->json_tree);
11282
11283   vat_json_init_object (node);
11284   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11285   if (mp->is_ipv6)
11286     {
11287       struct in6_addr ip6;
11288
11289       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11290       vat_json_object_add_ip6 (node, "src_address", ip6);
11291       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11292       vat_json_object_add_ip6 (node, "dst_address", ip6);
11293     }
11294   else
11295     {
11296       struct in_addr ip4;
11297
11298       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11299       vat_json_object_add_ip4 (node, "src_address", ip4);
11300       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11301       vat_json_object_add_ip4 (node, "dst_address", ip4);
11302     }
11303   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11304   vat_json_object_add_uint (node, "decap_next_index",
11305                             ntohl (mp->decap_next_index));
11306   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11307   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11308   vat_json_object_add_uint (node, "mcast_sw_if_index",
11309                             ntohl (mp->mcast_sw_if_index));
11310 }
11311
11312 static int
11313 api_vxlan_tunnel_dump (vat_main_t * vam)
11314 {
11315   unformat_input_t *i = vam->input;
11316   vl_api_vxlan_tunnel_dump_t *mp;
11317   vl_api_control_ping_t *mp_ping;
11318   u32 sw_if_index;
11319   u8 sw_if_index_set = 0;
11320   int ret;
11321
11322   /* Parse args required to build the message */
11323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11324     {
11325       if (unformat (i, "sw_if_index %d", &sw_if_index))
11326         sw_if_index_set = 1;
11327       else
11328         break;
11329     }
11330
11331   if (sw_if_index_set == 0)
11332     {
11333       sw_if_index = ~0;
11334     }
11335
11336   if (!vam->json_output)
11337     {
11338       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11339              "sw_if_index", "src_address", "dst_address",
11340              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11341     }
11342
11343   /* Get list of vxlan-tunnel interfaces */
11344   M (VXLAN_TUNNEL_DUMP, mp);
11345
11346   mp->sw_if_index = htonl (sw_if_index);
11347
11348   S (mp);
11349
11350   /* Use a control ping for synchronization */
11351   M (CONTROL_PING, mp_ping);
11352   S (mp_ping);
11353
11354   W (ret);
11355   return ret;
11356 }
11357
11358 static int
11359 api_gre_add_del_tunnel (vat_main_t * vam)
11360 {
11361   unformat_input_t *line_input = vam->input;
11362   vl_api_gre_add_del_tunnel_t *mp;
11363   ip4_address_t src4, dst4;
11364   ip6_address_t src6, dst6;
11365   u8 is_add = 1;
11366   u8 ipv4_set = 0;
11367   u8 ipv6_set = 0;
11368   u8 teb = 0;
11369   u8 src_set = 0;
11370   u8 dst_set = 0;
11371   u32 outer_fib_id = 0;
11372   int ret;
11373
11374   memset (&src4, 0, sizeof src4);
11375   memset (&dst4, 0, sizeof dst4);
11376   memset (&src6, 0, sizeof src6);
11377   memset (&dst6, 0, sizeof dst6);
11378
11379   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11380     {
11381       if (unformat (line_input, "del"))
11382         is_add = 0;
11383       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11384         {
11385           src_set = 1;
11386           ipv4_set = 1;
11387         }
11388       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11389         {
11390           dst_set = 1;
11391           ipv4_set = 1;
11392         }
11393       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11394         {
11395           src_set = 1;
11396           ipv6_set = 1;
11397         }
11398       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11399         {
11400           dst_set = 1;
11401           ipv6_set = 1;
11402         }
11403       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11404         ;
11405       else if (unformat (line_input, "teb"))
11406         teb = 1;
11407       else
11408         {
11409           errmsg ("parse error '%U'", format_unformat_error, line_input);
11410           return -99;
11411         }
11412     }
11413
11414   if (src_set == 0)
11415     {
11416       errmsg ("tunnel src address not specified");
11417       return -99;
11418     }
11419   if (dst_set == 0)
11420     {
11421       errmsg ("tunnel dst address not specified");
11422       return -99;
11423     }
11424   if (ipv4_set && ipv6_set)
11425     {
11426       errmsg ("both IPv4 and IPv6 addresses specified");
11427       return -99;
11428     }
11429
11430
11431   M (GRE_ADD_DEL_TUNNEL, mp);
11432
11433   if (ipv4_set)
11434     {
11435       clib_memcpy (&mp->src_address, &src4, 4);
11436       clib_memcpy (&mp->dst_address, &dst4, 4);
11437     }
11438   else
11439     {
11440       clib_memcpy (&mp->src_address, &src6, 16);
11441       clib_memcpy (&mp->dst_address, &dst6, 16);
11442     }
11443   mp->outer_fib_id = ntohl (outer_fib_id);
11444   mp->is_add = is_add;
11445   mp->teb = teb;
11446   mp->is_ipv6 = ipv6_set;
11447
11448   S (mp);
11449   W (ret);
11450   return ret;
11451 }
11452
11453 static void vl_api_gre_tunnel_details_t_handler
11454   (vl_api_gre_tunnel_details_t * mp)
11455 {
11456   vat_main_t *vam = &vat_main;
11457   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11458   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11459
11460   print (vam->ofp, "%11d%24U%24U%6d%14d",
11461          ntohl (mp->sw_if_index),
11462          format_ip46_address, &src, IP46_TYPE_ANY,
11463          format_ip46_address, &dst, IP46_TYPE_ANY,
11464          mp->teb, ntohl (mp->outer_fib_id));
11465 }
11466
11467 static void vl_api_gre_tunnel_details_t_handler_json
11468   (vl_api_gre_tunnel_details_t * mp)
11469 {
11470   vat_main_t *vam = &vat_main;
11471   vat_json_node_t *node = NULL;
11472   struct in_addr ip4;
11473   struct in6_addr ip6;
11474
11475   if (VAT_JSON_ARRAY != vam->json_tree.type)
11476     {
11477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11478       vat_json_init_array (&vam->json_tree);
11479     }
11480   node = vat_json_array_add (&vam->json_tree);
11481
11482   vat_json_init_object (node);
11483   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11484   if (!mp->is_ipv6)
11485     {
11486       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11487       vat_json_object_add_ip4 (node, "src_address", ip4);
11488       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11489       vat_json_object_add_ip4 (node, "dst_address", ip4);
11490     }
11491   else
11492     {
11493       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11494       vat_json_object_add_ip6 (node, "src_address", ip6);
11495       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11496       vat_json_object_add_ip6 (node, "dst_address", ip6);
11497     }
11498   vat_json_object_add_uint (node, "teb", mp->teb);
11499   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11500   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11501 }
11502
11503 static int
11504 api_gre_tunnel_dump (vat_main_t * vam)
11505 {
11506   unformat_input_t *i = vam->input;
11507   vl_api_gre_tunnel_dump_t *mp;
11508   vl_api_control_ping_t *mp_ping;
11509   u32 sw_if_index;
11510   u8 sw_if_index_set = 0;
11511   int ret;
11512
11513   /* Parse args required to build the message */
11514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11515     {
11516       if (unformat (i, "sw_if_index %d", &sw_if_index))
11517         sw_if_index_set = 1;
11518       else
11519         break;
11520     }
11521
11522   if (sw_if_index_set == 0)
11523     {
11524       sw_if_index = ~0;
11525     }
11526
11527   if (!vam->json_output)
11528     {
11529       print (vam->ofp, "%11s%24s%24s%6s%14s",
11530              "sw_if_index", "src_address", "dst_address", "teb",
11531              "outer_fib_id");
11532     }
11533
11534   /* Get list of gre-tunnel interfaces */
11535   M (GRE_TUNNEL_DUMP, mp);
11536
11537   mp->sw_if_index = htonl (sw_if_index);
11538
11539   S (mp);
11540
11541   /* Use a control ping for synchronization */
11542   M (CONTROL_PING, mp_ping);
11543   S (mp_ping);
11544
11545   W (ret);
11546   return ret;
11547 }
11548
11549 static int
11550 api_l2_fib_clear_table (vat_main_t * vam)
11551 {
11552 //  unformat_input_t * i = vam->input;
11553   vl_api_l2_fib_clear_table_t *mp;
11554   int ret;
11555
11556   M (L2_FIB_CLEAR_TABLE, mp);
11557
11558   S (mp);
11559   W (ret);
11560   return ret;
11561 }
11562
11563 static int
11564 api_l2_interface_efp_filter (vat_main_t * vam)
11565 {
11566   unformat_input_t *i = vam->input;
11567   vl_api_l2_interface_efp_filter_t *mp;
11568   u32 sw_if_index;
11569   u8 enable = 1;
11570   u8 sw_if_index_set = 0;
11571   int ret;
11572
11573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11574     {
11575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11576         sw_if_index_set = 1;
11577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11578         sw_if_index_set = 1;
11579       else if (unformat (i, "enable"))
11580         enable = 1;
11581       else if (unformat (i, "disable"))
11582         enable = 0;
11583       else
11584         {
11585           clib_warning ("parse error '%U'", format_unformat_error, i);
11586           return -99;
11587         }
11588     }
11589
11590   if (sw_if_index_set == 0)
11591     {
11592       errmsg ("missing sw_if_index");
11593       return -99;
11594     }
11595
11596   M (L2_INTERFACE_EFP_FILTER, mp);
11597
11598   mp->sw_if_index = ntohl (sw_if_index);
11599   mp->enable_disable = enable;
11600
11601   S (mp);
11602   W (ret);
11603   return ret;
11604 }
11605
11606 #define foreach_vtr_op                          \
11607 _("disable",  L2_VTR_DISABLED)                  \
11608 _("push-1",  L2_VTR_PUSH_1)                     \
11609 _("push-2",  L2_VTR_PUSH_2)                     \
11610 _("pop-1",  L2_VTR_POP_1)                       \
11611 _("pop-2",  L2_VTR_POP_2)                       \
11612 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11613 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11614 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11615 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11616
11617 static int
11618 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11619 {
11620   unformat_input_t *i = vam->input;
11621   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11622   u32 sw_if_index;
11623   u8 sw_if_index_set = 0;
11624   u8 vtr_op_set = 0;
11625   u32 vtr_op = 0;
11626   u32 push_dot1q = 1;
11627   u32 tag1 = ~0;
11628   u32 tag2 = ~0;
11629   int ret;
11630
11631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11632     {
11633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11634         sw_if_index_set = 1;
11635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11636         sw_if_index_set = 1;
11637       else if (unformat (i, "vtr_op %d", &vtr_op))
11638         vtr_op_set = 1;
11639 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11640       foreach_vtr_op
11641 #undef _
11642         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11643         ;
11644       else if (unformat (i, "tag1 %d", &tag1))
11645         ;
11646       else if (unformat (i, "tag2 %d", &tag2))
11647         ;
11648       else
11649         {
11650           clib_warning ("parse error '%U'", format_unformat_error, i);
11651           return -99;
11652         }
11653     }
11654
11655   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11656     {
11657       errmsg ("missing vtr operation or sw_if_index");
11658       return -99;
11659     }
11660
11661   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11662   mp->sw_if_index = ntohl (sw_if_index);
11663   mp->vtr_op = ntohl (vtr_op);
11664   mp->push_dot1q = ntohl (push_dot1q);
11665   mp->tag1 = ntohl (tag1);
11666   mp->tag2 = ntohl (tag2);
11667
11668   S (mp);
11669   W (ret);
11670   return ret;
11671 }
11672
11673 static int
11674 api_create_vhost_user_if (vat_main_t * vam)
11675 {
11676   unformat_input_t *i = vam->input;
11677   vl_api_create_vhost_user_if_t *mp;
11678   u8 *file_name;
11679   u8 is_server = 0;
11680   u8 file_name_set = 0;
11681   u32 custom_dev_instance = ~0;
11682   u8 hwaddr[6];
11683   u8 use_custom_mac = 0;
11684   u8 *tag = 0;
11685   int ret;
11686
11687   /* Shut up coverity */
11688   memset (hwaddr, 0, sizeof (hwaddr));
11689
11690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11691     {
11692       if (unformat (i, "socket %s", &file_name))
11693         {
11694           file_name_set = 1;
11695         }
11696       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11697         ;
11698       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11699         use_custom_mac = 1;
11700       else if (unformat (i, "server"))
11701         is_server = 1;
11702       else if (unformat (i, "tag %s", &tag))
11703         ;
11704       else
11705         break;
11706     }
11707
11708   if (file_name_set == 0)
11709     {
11710       errmsg ("missing socket file name");
11711       return -99;
11712     }
11713
11714   if (vec_len (file_name) > 255)
11715     {
11716       errmsg ("socket file name too long");
11717       return -99;
11718     }
11719   vec_add1 (file_name, 0);
11720
11721   M (CREATE_VHOST_USER_IF, mp);
11722
11723   mp->is_server = is_server;
11724   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11725   vec_free (file_name);
11726   if (custom_dev_instance != ~0)
11727     {
11728       mp->renumber = 1;
11729       mp->custom_dev_instance = ntohl (custom_dev_instance);
11730     }
11731   mp->use_custom_mac = use_custom_mac;
11732   clib_memcpy (mp->mac_address, hwaddr, 6);
11733   if (tag)
11734     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11735   vec_free (tag);
11736
11737   S (mp);
11738   W (ret);
11739   return ret;
11740 }
11741
11742 static int
11743 api_modify_vhost_user_if (vat_main_t * vam)
11744 {
11745   unformat_input_t *i = vam->input;
11746   vl_api_modify_vhost_user_if_t *mp;
11747   u8 *file_name;
11748   u8 is_server = 0;
11749   u8 file_name_set = 0;
11750   u32 custom_dev_instance = ~0;
11751   u8 sw_if_index_set = 0;
11752   u32 sw_if_index = (u32) ~ 0;
11753   int ret;
11754
11755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11756     {
11757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11758         sw_if_index_set = 1;
11759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11760         sw_if_index_set = 1;
11761       else if (unformat (i, "socket %s", &file_name))
11762         {
11763           file_name_set = 1;
11764         }
11765       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11766         ;
11767       else if (unformat (i, "server"))
11768         is_server = 1;
11769       else
11770         break;
11771     }
11772
11773   if (sw_if_index_set == 0)
11774     {
11775       errmsg ("missing sw_if_index or interface name");
11776       return -99;
11777     }
11778
11779   if (file_name_set == 0)
11780     {
11781       errmsg ("missing socket file name");
11782       return -99;
11783     }
11784
11785   if (vec_len (file_name) > 255)
11786     {
11787       errmsg ("socket file name too long");
11788       return -99;
11789     }
11790   vec_add1 (file_name, 0);
11791
11792   M (MODIFY_VHOST_USER_IF, mp);
11793
11794   mp->sw_if_index = ntohl (sw_if_index);
11795   mp->is_server = is_server;
11796   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11797   vec_free (file_name);
11798   if (custom_dev_instance != ~0)
11799     {
11800       mp->renumber = 1;
11801       mp->custom_dev_instance = ntohl (custom_dev_instance);
11802     }
11803
11804   S (mp);
11805   W (ret);
11806   return ret;
11807 }
11808
11809 static int
11810 api_delete_vhost_user_if (vat_main_t * vam)
11811 {
11812   unformat_input_t *i = vam->input;
11813   vl_api_delete_vhost_user_if_t *mp;
11814   u32 sw_if_index = ~0;
11815   u8 sw_if_index_set = 0;
11816   int ret;
11817
11818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11819     {
11820       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11821         sw_if_index_set = 1;
11822       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11823         sw_if_index_set = 1;
11824       else
11825         break;
11826     }
11827
11828   if (sw_if_index_set == 0)
11829     {
11830       errmsg ("missing sw_if_index or interface name");
11831       return -99;
11832     }
11833
11834
11835   M (DELETE_VHOST_USER_IF, mp);
11836
11837   mp->sw_if_index = ntohl (sw_if_index);
11838
11839   S (mp);
11840   W (ret);
11841   return ret;
11842 }
11843
11844 static void vl_api_sw_interface_vhost_user_details_t_handler
11845   (vl_api_sw_interface_vhost_user_details_t * mp)
11846 {
11847   vat_main_t *vam = &vat_main;
11848
11849   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11850          (char *) mp->interface_name,
11851          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11852          clib_net_to_host_u64 (mp->features), mp->is_server,
11853          ntohl (mp->num_regions), (char *) mp->sock_filename);
11854   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11855 }
11856
11857 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11858   (vl_api_sw_interface_vhost_user_details_t * mp)
11859 {
11860   vat_main_t *vam = &vat_main;
11861   vat_json_node_t *node = NULL;
11862
11863   if (VAT_JSON_ARRAY != vam->json_tree.type)
11864     {
11865       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11866       vat_json_init_array (&vam->json_tree);
11867     }
11868   node = vat_json_array_add (&vam->json_tree);
11869
11870   vat_json_init_object (node);
11871   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11872   vat_json_object_add_string_copy (node, "interface_name",
11873                                    mp->interface_name);
11874   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11875                             ntohl (mp->virtio_net_hdr_sz));
11876   vat_json_object_add_uint (node, "features",
11877                             clib_net_to_host_u64 (mp->features));
11878   vat_json_object_add_uint (node, "is_server", mp->is_server);
11879   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11880   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11881   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11882 }
11883
11884 static int
11885 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11886 {
11887   vl_api_sw_interface_vhost_user_dump_t *mp;
11888   vl_api_control_ping_t *mp_ping;
11889   int ret;
11890   print (vam->ofp,
11891          "Interface name            idx hdr_sz features server regions filename");
11892
11893   /* Get list of vhost-user interfaces */
11894   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11895   S (mp);
11896
11897   /* Use a control ping for synchronization */
11898   M (CONTROL_PING, mp_ping);
11899   S (mp_ping);
11900
11901   W (ret);
11902   return ret;
11903 }
11904
11905 static int
11906 api_show_version (vat_main_t * vam)
11907 {
11908   vl_api_show_version_t *mp;
11909   int ret;
11910
11911   M (SHOW_VERSION, mp);
11912
11913   S (mp);
11914   W (ret);
11915   return ret;
11916 }
11917
11918
11919 static int
11920 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11921 {
11922   unformat_input_t *line_input = vam->input;
11923   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11924   ip4_address_t local4, remote4;
11925   ip6_address_t local6, remote6;
11926   u8 is_add = 1;
11927   u8 ipv4_set = 0, ipv6_set = 0;
11928   u8 local_set = 0;
11929   u8 remote_set = 0;
11930   u32 encap_vrf_id = 0;
11931   u32 decap_vrf_id = 0;
11932   u8 protocol = ~0;
11933   u32 vni;
11934   u8 vni_set = 0;
11935   int ret;
11936
11937   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11938     {
11939       if (unformat (line_input, "del"))
11940         is_add = 0;
11941       else if (unformat (line_input, "local %U",
11942                          unformat_ip4_address, &local4))
11943         {
11944           local_set = 1;
11945           ipv4_set = 1;
11946         }
11947       else if (unformat (line_input, "remote %U",
11948                          unformat_ip4_address, &remote4))
11949         {
11950           remote_set = 1;
11951           ipv4_set = 1;
11952         }
11953       else if (unformat (line_input, "local %U",
11954                          unformat_ip6_address, &local6))
11955         {
11956           local_set = 1;
11957           ipv6_set = 1;
11958         }
11959       else if (unformat (line_input, "remote %U",
11960                          unformat_ip6_address, &remote6))
11961         {
11962           remote_set = 1;
11963           ipv6_set = 1;
11964         }
11965       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11966         ;
11967       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11968         ;
11969       else if (unformat (line_input, "vni %d", &vni))
11970         vni_set = 1;
11971       else if (unformat (line_input, "next-ip4"))
11972         protocol = 1;
11973       else if (unformat (line_input, "next-ip6"))
11974         protocol = 2;
11975       else if (unformat (line_input, "next-ethernet"))
11976         protocol = 3;
11977       else if (unformat (line_input, "next-nsh"))
11978         protocol = 4;
11979       else
11980         {
11981           errmsg ("parse error '%U'", format_unformat_error, line_input);
11982           return -99;
11983         }
11984     }
11985
11986   if (local_set == 0)
11987     {
11988       errmsg ("tunnel local address not specified");
11989       return -99;
11990     }
11991   if (remote_set == 0)
11992     {
11993       errmsg ("tunnel remote address not specified");
11994       return -99;
11995     }
11996   if (ipv4_set && ipv6_set)
11997     {
11998       errmsg ("both IPv4 and IPv6 addresses specified");
11999       return -99;
12000     }
12001
12002   if (vni_set == 0)
12003     {
12004       errmsg ("vni not specified");
12005       return -99;
12006     }
12007
12008   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12009
12010
12011   if (ipv6_set)
12012     {
12013       clib_memcpy (&mp->local, &local6, sizeof (local6));
12014       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12015     }
12016   else
12017     {
12018       clib_memcpy (&mp->local, &local4, sizeof (local4));
12019       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12020     }
12021
12022   mp->encap_vrf_id = ntohl (encap_vrf_id);
12023   mp->decap_vrf_id = ntohl (decap_vrf_id);
12024   mp->protocol = protocol;
12025   mp->vni = ntohl (vni);
12026   mp->is_add = is_add;
12027   mp->is_ipv6 = ipv6_set;
12028
12029   S (mp);
12030   W (ret);
12031   return ret;
12032 }
12033
12034 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12035   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12036 {
12037   vat_main_t *vam = &vat_main;
12038
12039   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
12040          ntohl (mp->sw_if_index),
12041          format_ip46_address, &(mp->local[0]),
12042          format_ip46_address, &(mp->remote[0]),
12043          ntohl (mp->vni),
12044          ntohl (mp->protocol),
12045          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12046 }
12047
12048 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12049   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12050 {
12051   vat_main_t *vam = &vat_main;
12052   vat_json_node_t *node = NULL;
12053   struct in_addr ip4;
12054   struct in6_addr ip6;
12055
12056   if (VAT_JSON_ARRAY != vam->json_tree.type)
12057     {
12058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12059       vat_json_init_array (&vam->json_tree);
12060     }
12061   node = vat_json_array_add (&vam->json_tree);
12062
12063   vat_json_init_object (node);
12064   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12065   if (mp->is_ipv6)
12066     {
12067       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12068       vat_json_object_add_ip6 (node, "local", ip6);
12069       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12070       vat_json_object_add_ip6 (node, "remote", ip6);
12071     }
12072   else
12073     {
12074       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12075       vat_json_object_add_ip4 (node, "local", ip4);
12076       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12077       vat_json_object_add_ip4 (node, "remote", ip4);
12078     }
12079   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12080   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12081   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12082   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12083   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12084 }
12085
12086 static int
12087 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12088 {
12089   unformat_input_t *i = vam->input;
12090   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12091   vl_api_control_ping_t *mp_ping;
12092   u32 sw_if_index;
12093   u8 sw_if_index_set = 0;
12094   int ret;
12095
12096   /* Parse args required to build the message */
12097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12098     {
12099       if (unformat (i, "sw_if_index %d", &sw_if_index))
12100         sw_if_index_set = 1;
12101       else
12102         break;
12103     }
12104
12105   if (sw_if_index_set == 0)
12106     {
12107       sw_if_index = ~0;
12108     }
12109
12110   if (!vam->json_output)
12111     {
12112       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
12113              "sw_if_index", "local", "remote", "vni",
12114              "protocol", "encap_vrf_id", "decap_vrf_id");
12115     }
12116
12117   /* Get list of vxlan-tunnel interfaces */
12118   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12119
12120   mp->sw_if_index = htonl (sw_if_index);
12121
12122   S (mp);
12123
12124   /* Use a control ping for synchronization */
12125   M (CONTROL_PING, mp_ping);
12126   S (mp_ping);
12127
12128   W (ret);
12129   return ret;
12130 }
12131
12132 u8 *
12133 format_l2_fib_mac_address (u8 * s, va_list * args)
12134 {
12135   u8 *a = va_arg (*args, u8 *);
12136
12137   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12138                  a[2], a[3], a[4], a[5], a[6], a[7]);
12139 }
12140
12141 static void vl_api_l2_fib_table_details_t_handler
12142   (vl_api_l2_fib_table_details_t * mp)
12143 {
12144   vat_main_t *vam = &vat_main;
12145
12146   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12147          "       %d       %d     %d",
12148          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12149          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12150          mp->bvi_mac);
12151 }
12152
12153 static void vl_api_l2_fib_table_details_t_handler_json
12154   (vl_api_l2_fib_table_details_t * mp)
12155 {
12156   vat_main_t *vam = &vat_main;
12157   vat_json_node_t *node = NULL;
12158
12159   if (VAT_JSON_ARRAY != vam->json_tree.type)
12160     {
12161       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12162       vat_json_init_array (&vam->json_tree);
12163     }
12164   node = vat_json_array_add (&vam->json_tree);
12165
12166   vat_json_init_object (node);
12167   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12168   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12169   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12170   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12171   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12172   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12173 }
12174
12175 static int
12176 api_l2_fib_table_dump (vat_main_t * vam)
12177 {
12178   unformat_input_t *i = vam->input;
12179   vl_api_l2_fib_table_dump_t *mp;
12180   vl_api_control_ping_t *mp_ping;
12181   u32 bd_id;
12182   u8 bd_id_set = 0;
12183   int ret;
12184
12185   /* Parse args required to build the message */
12186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12187     {
12188       if (unformat (i, "bd_id %d", &bd_id))
12189         bd_id_set = 1;
12190       else
12191         break;
12192     }
12193
12194   if (bd_id_set == 0)
12195     {
12196       errmsg ("missing bridge domain");
12197       return -99;
12198     }
12199
12200   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12201
12202   /* Get list of l2 fib entries */
12203   M (L2_FIB_TABLE_DUMP, mp);
12204
12205   mp->bd_id = ntohl (bd_id);
12206   S (mp);
12207
12208   /* Use a control ping for synchronization */
12209   M (CONTROL_PING, mp_ping);
12210   S (mp_ping);
12211
12212   W (ret);
12213   return ret;
12214 }
12215
12216
12217 static int
12218 api_interface_name_renumber (vat_main_t * vam)
12219 {
12220   unformat_input_t *line_input = vam->input;
12221   vl_api_interface_name_renumber_t *mp;
12222   u32 sw_if_index = ~0;
12223   u32 new_show_dev_instance = ~0;
12224   int ret;
12225
12226   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12227     {
12228       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12229                     &sw_if_index))
12230         ;
12231       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12232         ;
12233       else if (unformat (line_input, "new_show_dev_instance %d",
12234                          &new_show_dev_instance))
12235         ;
12236       else
12237         break;
12238     }
12239
12240   if (sw_if_index == ~0)
12241     {
12242       errmsg ("missing interface name or sw_if_index");
12243       return -99;
12244     }
12245
12246   if (new_show_dev_instance == ~0)
12247     {
12248       errmsg ("missing new_show_dev_instance");
12249       return -99;
12250     }
12251
12252   M (INTERFACE_NAME_RENUMBER, mp);
12253
12254   mp->sw_if_index = ntohl (sw_if_index);
12255   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12256
12257   S (mp);
12258   W (ret);
12259   return ret;
12260 }
12261
12262 static int
12263 api_want_ip4_arp_events (vat_main_t * vam)
12264 {
12265   unformat_input_t *line_input = vam->input;
12266   vl_api_want_ip4_arp_events_t *mp;
12267   ip4_address_t address;
12268   int address_set = 0;
12269   u32 enable_disable = 1;
12270   int ret;
12271
12272   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12273     {
12274       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12275         address_set = 1;
12276       else if (unformat (line_input, "del"))
12277         enable_disable = 0;
12278       else
12279         break;
12280     }
12281
12282   if (address_set == 0)
12283     {
12284       errmsg ("missing addresses");
12285       return -99;
12286     }
12287
12288   M (WANT_IP4_ARP_EVENTS, mp);
12289   mp->enable_disable = enable_disable;
12290   mp->pid = htonl (getpid ());
12291   mp->address = address.as_u32;
12292
12293   S (mp);
12294   W (ret);
12295   return ret;
12296 }
12297
12298 static int
12299 api_want_ip6_nd_events (vat_main_t * vam)
12300 {
12301   unformat_input_t *line_input = vam->input;
12302   vl_api_want_ip6_nd_events_t *mp;
12303   ip6_address_t address;
12304   int address_set = 0;
12305   u32 enable_disable = 1;
12306   int ret;
12307
12308   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12309     {
12310       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12311         address_set = 1;
12312       else if (unformat (line_input, "del"))
12313         enable_disable = 0;
12314       else
12315         break;
12316     }
12317
12318   if (address_set == 0)
12319     {
12320       errmsg ("missing addresses");
12321       return -99;
12322     }
12323
12324   M (WANT_IP6_ND_EVENTS, mp);
12325   mp->enable_disable = enable_disable;
12326   mp->pid = htonl (getpid ());
12327   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12328
12329   S (mp);
12330   W (ret);
12331   return ret;
12332 }
12333
12334 static int
12335 api_input_acl_set_interface (vat_main_t * vam)
12336 {
12337   unformat_input_t *i = vam->input;
12338   vl_api_input_acl_set_interface_t *mp;
12339   u32 sw_if_index;
12340   int sw_if_index_set;
12341   u32 ip4_table_index = ~0;
12342   u32 ip6_table_index = ~0;
12343   u32 l2_table_index = ~0;
12344   u8 is_add = 1;
12345   int ret;
12346
12347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12348     {
12349       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12350         sw_if_index_set = 1;
12351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12352         sw_if_index_set = 1;
12353       else if (unformat (i, "del"))
12354         is_add = 0;
12355       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12356         ;
12357       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12358         ;
12359       else if (unformat (i, "l2-table %d", &l2_table_index))
12360         ;
12361       else
12362         {
12363           clib_warning ("parse error '%U'", format_unformat_error, i);
12364           return -99;
12365         }
12366     }
12367
12368   if (sw_if_index_set == 0)
12369     {
12370       errmsg ("missing interface name or sw_if_index");
12371       return -99;
12372     }
12373
12374   M (INPUT_ACL_SET_INTERFACE, mp);
12375
12376   mp->sw_if_index = ntohl (sw_if_index);
12377   mp->ip4_table_index = ntohl (ip4_table_index);
12378   mp->ip6_table_index = ntohl (ip6_table_index);
12379   mp->l2_table_index = ntohl (l2_table_index);
12380   mp->is_add = is_add;
12381
12382   S (mp);
12383   W (ret);
12384   return ret;
12385 }
12386
12387 static int
12388 api_ip_address_dump (vat_main_t * vam)
12389 {
12390   unformat_input_t *i = vam->input;
12391   vl_api_ip_address_dump_t *mp;
12392   vl_api_control_ping_t *mp_ping;
12393   u32 sw_if_index = ~0;
12394   u8 sw_if_index_set = 0;
12395   u8 ipv4_set = 0;
12396   u8 ipv6_set = 0;
12397   int ret;
12398
12399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12400     {
12401       if (unformat (i, "sw_if_index %d", &sw_if_index))
12402         sw_if_index_set = 1;
12403       else
12404         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12405         sw_if_index_set = 1;
12406       else if (unformat (i, "ipv4"))
12407         ipv4_set = 1;
12408       else if (unformat (i, "ipv6"))
12409         ipv6_set = 1;
12410       else
12411         break;
12412     }
12413
12414   if (ipv4_set && ipv6_set)
12415     {
12416       errmsg ("ipv4 and ipv6 flags cannot be both set");
12417       return -99;
12418     }
12419
12420   if ((!ipv4_set) && (!ipv6_set))
12421     {
12422       errmsg ("no ipv4 nor ipv6 flag set");
12423       return -99;
12424     }
12425
12426   if (sw_if_index_set == 0)
12427     {
12428       errmsg ("missing interface name or sw_if_index");
12429       return -99;
12430     }
12431
12432   vam->current_sw_if_index = sw_if_index;
12433   vam->is_ipv6 = ipv6_set;
12434
12435   M (IP_ADDRESS_DUMP, mp);
12436   mp->sw_if_index = ntohl (sw_if_index);
12437   mp->is_ipv6 = ipv6_set;
12438   S (mp);
12439
12440   /* Use a control ping for synchronization */
12441   M (CONTROL_PING, mp_ping);
12442   S (mp_ping);
12443
12444   W (ret);
12445   return ret;
12446 }
12447
12448 static int
12449 api_ip_dump (vat_main_t * vam)
12450 {
12451   vl_api_ip_dump_t *mp;
12452   vl_api_control_ping_t *mp_ping;
12453   unformat_input_t *in = vam->input;
12454   int ipv4_set = 0;
12455   int ipv6_set = 0;
12456   int is_ipv6;
12457   int i;
12458   int ret;
12459
12460   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12461     {
12462       if (unformat (in, "ipv4"))
12463         ipv4_set = 1;
12464       else if (unformat (in, "ipv6"))
12465         ipv6_set = 1;
12466       else
12467         break;
12468     }
12469
12470   if (ipv4_set && ipv6_set)
12471     {
12472       errmsg ("ipv4 and ipv6 flags cannot be both set");
12473       return -99;
12474     }
12475
12476   if ((!ipv4_set) && (!ipv6_set))
12477     {
12478       errmsg ("no ipv4 nor ipv6 flag set");
12479       return -99;
12480     }
12481
12482   is_ipv6 = ipv6_set;
12483   vam->is_ipv6 = is_ipv6;
12484
12485   /* free old data */
12486   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12487     {
12488       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12489     }
12490   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12491
12492   M (IP_DUMP, mp);
12493   mp->is_ipv6 = ipv6_set;
12494   S (mp);
12495
12496   /* Use a control ping for synchronization */
12497   M (CONTROL_PING, mp_ping);
12498   S (mp_ping);
12499
12500   W (ret);
12501   return ret;
12502 }
12503
12504 static int
12505 api_ipsec_spd_add_del (vat_main_t * vam)
12506 {
12507   unformat_input_t *i = vam->input;
12508   vl_api_ipsec_spd_add_del_t *mp;
12509   u32 spd_id = ~0;
12510   u8 is_add = 1;
12511   int ret;
12512
12513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12514     {
12515       if (unformat (i, "spd_id %d", &spd_id))
12516         ;
12517       else if (unformat (i, "del"))
12518         is_add = 0;
12519       else
12520         {
12521           clib_warning ("parse error '%U'", format_unformat_error, i);
12522           return -99;
12523         }
12524     }
12525   if (spd_id == ~0)
12526     {
12527       errmsg ("spd_id must be set");
12528       return -99;
12529     }
12530
12531   M (IPSEC_SPD_ADD_DEL, mp);
12532
12533   mp->spd_id = ntohl (spd_id);
12534   mp->is_add = is_add;
12535
12536   S (mp);
12537   W (ret);
12538   return ret;
12539 }
12540
12541 static int
12542 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12543 {
12544   unformat_input_t *i = vam->input;
12545   vl_api_ipsec_interface_add_del_spd_t *mp;
12546   u32 sw_if_index;
12547   u8 sw_if_index_set = 0;
12548   u32 spd_id = (u32) ~ 0;
12549   u8 is_add = 1;
12550   int ret;
12551
12552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12553     {
12554       if (unformat (i, "del"))
12555         is_add = 0;
12556       else if (unformat (i, "spd_id %d", &spd_id))
12557         ;
12558       else
12559         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12560         sw_if_index_set = 1;
12561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12562         sw_if_index_set = 1;
12563       else
12564         {
12565           clib_warning ("parse error '%U'", format_unformat_error, i);
12566           return -99;
12567         }
12568
12569     }
12570
12571   if (spd_id == (u32) ~ 0)
12572     {
12573       errmsg ("spd_id must be set");
12574       return -99;
12575     }
12576
12577   if (sw_if_index_set == 0)
12578     {
12579       errmsg ("missing interface name or sw_if_index");
12580       return -99;
12581     }
12582
12583   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12584
12585   mp->spd_id = ntohl (spd_id);
12586   mp->sw_if_index = ntohl (sw_if_index);
12587   mp->is_add = is_add;
12588
12589   S (mp);
12590   W (ret);
12591   return ret;
12592 }
12593
12594 static int
12595 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12596 {
12597   unformat_input_t *i = vam->input;
12598   vl_api_ipsec_spd_add_del_entry_t *mp;
12599   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12600   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12601   i32 priority = 0;
12602   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12603   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12604   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12605   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12606   int ret;
12607
12608   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12609   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12610   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12611   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12612   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12613   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12614
12615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12616     {
12617       if (unformat (i, "del"))
12618         is_add = 0;
12619       if (unformat (i, "outbound"))
12620         is_outbound = 1;
12621       if (unformat (i, "inbound"))
12622         is_outbound = 0;
12623       else if (unformat (i, "spd_id %d", &spd_id))
12624         ;
12625       else if (unformat (i, "sa_id %d", &sa_id))
12626         ;
12627       else if (unformat (i, "priority %d", &priority))
12628         ;
12629       else if (unformat (i, "protocol %d", &protocol))
12630         ;
12631       else if (unformat (i, "lport_start %d", &lport_start))
12632         ;
12633       else if (unformat (i, "lport_stop %d", &lport_stop))
12634         ;
12635       else if (unformat (i, "rport_start %d", &rport_start))
12636         ;
12637       else if (unformat (i, "rport_stop %d", &rport_stop))
12638         ;
12639       else
12640         if (unformat
12641             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12642         {
12643           is_ipv6 = 0;
12644           is_ip_any = 0;
12645         }
12646       else
12647         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12648         {
12649           is_ipv6 = 0;
12650           is_ip_any = 0;
12651         }
12652       else
12653         if (unformat
12654             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12655         {
12656           is_ipv6 = 0;
12657           is_ip_any = 0;
12658         }
12659       else
12660         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12661         {
12662           is_ipv6 = 0;
12663           is_ip_any = 0;
12664         }
12665       else
12666         if (unformat
12667             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12668         {
12669           is_ipv6 = 1;
12670           is_ip_any = 0;
12671         }
12672       else
12673         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12674         {
12675           is_ipv6 = 1;
12676           is_ip_any = 0;
12677         }
12678       else
12679         if (unformat
12680             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12681         {
12682           is_ipv6 = 1;
12683           is_ip_any = 0;
12684         }
12685       else
12686         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12687         {
12688           is_ipv6 = 1;
12689           is_ip_any = 0;
12690         }
12691       else
12692         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12693         {
12694           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12695             {
12696               clib_warning ("unsupported action: 'resolve'");
12697               return -99;
12698             }
12699         }
12700       else
12701         {
12702           clib_warning ("parse error '%U'", format_unformat_error, i);
12703           return -99;
12704         }
12705
12706     }
12707
12708   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12709
12710   mp->spd_id = ntohl (spd_id);
12711   mp->priority = ntohl (priority);
12712   mp->is_outbound = is_outbound;
12713
12714   mp->is_ipv6 = is_ipv6;
12715   if (is_ipv6 || is_ip_any)
12716     {
12717       clib_memcpy (mp->remote_address_start, &raddr6_start,
12718                    sizeof (ip6_address_t));
12719       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12720                    sizeof (ip6_address_t));
12721       clib_memcpy (mp->local_address_start, &laddr6_start,
12722                    sizeof (ip6_address_t));
12723       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12724                    sizeof (ip6_address_t));
12725     }
12726   else
12727     {
12728       clib_memcpy (mp->remote_address_start, &raddr4_start,
12729                    sizeof (ip4_address_t));
12730       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12731                    sizeof (ip4_address_t));
12732       clib_memcpy (mp->local_address_start, &laddr4_start,
12733                    sizeof (ip4_address_t));
12734       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12735                    sizeof (ip4_address_t));
12736     }
12737   mp->protocol = (u8) protocol;
12738   mp->local_port_start = ntohs ((u16) lport_start);
12739   mp->local_port_stop = ntohs ((u16) lport_stop);
12740   mp->remote_port_start = ntohs ((u16) rport_start);
12741   mp->remote_port_stop = ntohs ((u16) rport_stop);
12742   mp->policy = (u8) policy;
12743   mp->sa_id = ntohl (sa_id);
12744   mp->is_add = is_add;
12745   mp->is_ip_any = is_ip_any;
12746   S (mp);
12747   W (ret);
12748   return ret;
12749 }
12750
12751 static int
12752 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12753 {
12754   unformat_input_t *i = vam->input;
12755   vl_api_ipsec_sad_add_del_entry_t *mp;
12756   u32 sad_id = 0, spi = 0;
12757   u8 *ck = 0, *ik = 0;
12758   u8 is_add = 1;
12759
12760   u8 protocol = IPSEC_PROTOCOL_AH;
12761   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12762   u32 crypto_alg = 0, integ_alg = 0;
12763   ip4_address_t tun_src4;
12764   ip4_address_t tun_dst4;
12765   ip6_address_t tun_src6;
12766   ip6_address_t tun_dst6;
12767   int ret;
12768
12769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12770     {
12771       if (unformat (i, "del"))
12772         is_add = 0;
12773       else if (unformat (i, "sad_id %d", &sad_id))
12774         ;
12775       else if (unformat (i, "spi %d", &spi))
12776         ;
12777       else if (unformat (i, "esp"))
12778         protocol = IPSEC_PROTOCOL_ESP;
12779       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12780         {
12781           is_tunnel = 1;
12782           is_tunnel_ipv6 = 0;
12783         }
12784       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12785         {
12786           is_tunnel = 1;
12787           is_tunnel_ipv6 = 0;
12788         }
12789       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12790         {
12791           is_tunnel = 1;
12792           is_tunnel_ipv6 = 1;
12793         }
12794       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12795         {
12796           is_tunnel = 1;
12797           is_tunnel_ipv6 = 1;
12798         }
12799       else
12800         if (unformat
12801             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12802         {
12803           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12804               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12805             {
12806               clib_warning ("unsupported crypto-alg: '%U'",
12807                             format_ipsec_crypto_alg, crypto_alg);
12808               return -99;
12809             }
12810         }
12811       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12812         ;
12813       else
12814         if (unformat
12815             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12816         {
12817           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12818               integ_alg >= IPSEC_INTEG_N_ALG)
12819             {
12820               clib_warning ("unsupported integ-alg: '%U'",
12821                             format_ipsec_integ_alg, integ_alg);
12822               return -99;
12823             }
12824         }
12825       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12826         ;
12827       else
12828         {
12829           clib_warning ("parse error '%U'", format_unformat_error, i);
12830           return -99;
12831         }
12832
12833     }
12834
12835   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12836
12837   mp->sad_id = ntohl (sad_id);
12838   mp->is_add = is_add;
12839   mp->protocol = protocol;
12840   mp->spi = ntohl (spi);
12841   mp->is_tunnel = is_tunnel;
12842   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12843   mp->crypto_algorithm = crypto_alg;
12844   mp->integrity_algorithm = integ_alg;
12845   mp->crypto_key_length = vec_len (ck);
12846   mp->integrity_key_length = vec_len (ik);
12847
12848   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12849     mp->crypto_key_length = sizeof (mp->crypto_key);
12850
12851   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12852     mp->integrity_key_length = sizeof (mp->integrity_key);
12853
12854   if (ck)
12855     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12856   if (ik)
12857     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12858
12859   if (is_tunnel)
12860     {
12861       if (is_tunnel_ipv6)
12862         {
12863           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12864                        sizeof (ip6_address_t));
12865           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12866                        sizeof (ip6_address_t));
12867         }
12868       else
12869         {
12870           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12871                        sizeof (ip4_address_t));
12872           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12873                        sizeof (ip4_address_t));
12874         }
12875     }
12876
12877   S (mp);
12878   W (ret);
12879   return ret;
12880 }
12881
12882 static int
12883 api_ipsec_sa_set_key (vat_main_t * vam)
12884 {
12885   unformat_input_t *i = vam->input;
12886   vl_api_ipsec_sa_set_key_t *mp;
12887   u32 sa_id;
12888   u8 *ck = 0, *ik = 0;
12889   int ret;
12890
12891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12892     {
12893       if (unformat (i, "sa_id %d", &sa_id))
12894         ;
12895       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12896         ;
12897       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12898         ;
12899       else
12900         {
12901           clib_warning ("parse error '%U'", format_unformat_error, i);
12902           return -99;
12903         }
12904     }
12905
12906   M (IPSEC_SA_SET_KEY, mp);
12907
12908   mp->sa_id = ntohl (sa_id);
12909   mp->crypto_key_length = vec_len (ck);
12910   mp->integrity_key_length = vec_len (ik);
12911
12912   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12913     mp->crypto_key_length = sizeof (mp->crypto_key);
12914
12915   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12916     mp->integrity_key_length = sizeof (mp->integrity_key);
12917
12918   if (ck)
12919     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12920   if (ik)
12921     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12922
12923   S (mp);
12924   W (ret);
12925   return ret;
12926 }
12927
12928 static int
12929 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12930 {
12931   unformat_input_t *i = vam->input;
12932   vl_api_ipsec_tunnel_if_add_del_t *mp;
12933   u32 local_spi = 0, remote_spi = 0;
12934   u32 crypto_alg = 0, integ_alg = 0;
12935   u8 *lck = NULL, *rck = NULL;
12936   u8 *lik = NULL, *rik = NULL;
12937   ip4_address_t local_ip = { {0} };
12938   ip4_address_t remote_ip = { {0} };
12939   u8 is_add = 1;
12940   u8 esn = 0;
12941   u8 anti_replay = 0;
12942   int ret;
12943
12944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12945     {
12946       if (unformat (i, "del"))
12947         is_add = 0;
12948       else if (unformat (i, "esn"))
12949         esn = 1;
12950       else if (unformat (i, "anti_replay"))
12951         anti_replay = 1;
12952       else if (unformat (i, "local_spi %d", &local_spi))
12953         ;
12954       else if (unformat (i, "remote_spi %d", &remote_spi))
12955         ;
12956       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12957         ;
12958       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12959         ;
12960       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12961         ;
12962       else
12963         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12964         ;
12965       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12966         ;
12967       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12968         ;
12969       else
12970         if (unformat
12971             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12972         {
12973           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12974               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12975             {
12976               errmsg ("unsupported crypto-alg: '%U'\n",
12977                       format_ipsec_crypto_alg, crypto_alg);
12978               return -99;
12979             }
12980         }
12981       else
12982         if (unformat
12983             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12984         {
12985           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12986               integ_alg >= IPSEC_INTEG_N_ALG)
12987             {
12988               errmsg ("unsupported integ-alg: '%U'\n",
12989                       format_ipsec_integ_alg, integ_alg);
12990               return -99;
12991             }
12992         }
12993       else
12994         {
12995           errmsg ("parse error '%U'\n", format_unformat_error, i);
12996           return -99;
12997         }
12998     }
12999
13000   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13001
13002   mp->is_add = is_add;
13003   mp->esn = esn;
13004   mp->anti_replay = anti_replay;
13005
13006   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13007   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13008
13009   mp->local_spi = htonl (local_spi);
13010   mp->remote_spi = htonl (remote_spi);
13011   mp->crypto_alg = (u8) crypto_alg;
13012
13013   mp->local_crypto_key_len = 0;
13014   if (lck)
13015     {
13016       mp->local_crypto_key_len = vec_len (lck);
13017       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13018         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13019       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13020     }
13021
13022   mp->remote_crypto_key_len = 0;
13023   if (rck)
13024     {
13025       mp->remote_crypto_key_len = vec_len (rck);
13026       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13027         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13028       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13029     }
13030
13031   mp->integ_alg = (u8) integ_alg;
13032
13033   mp->local_integ_key_len = 0;
13034   if (lik)
13035     {
13036       mp->local_integ_key_len = vec_len (lik);
13037       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13038         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13039       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13040     }
13041
13042   mp->remote_integ_key_len = 0;
13043   if (rik)
13044     {
13045       mp->remote_integ_key_len = vec_len (rik);
13046       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13047         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13048       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13049     }
13050
13051   S (mp);
13052   W (ret);
13053   return ret;
13054 }
13055
13056 static int
13057 api_ikev2_profile_add_del (vat_main_t * vam)
13058 {
13059   unformat_input_t *i = vam->input;
13060   vl_api_ikev2_profile_add_del_t *mp;
13061   u8 is_add = 1;
13062   u8 *name = 0;
13063   int ret;
13064
13065   const char *valid_chars = "a-zA-Z0-9_";
13066
13067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13068     {
13069       if (unformat (i, "del"))
13070         is_add = 0;
13071       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13072         vec_add1 (name, 0);
13073       else
13074         {
13075           errmsg ("parse error '%U'", format_unformat_error, i);
13076           return -99;
13077         }
13078     }
13079
13080   if (!vec_len (name))
13081     {
13082       errmsg ("profile name must be specified");
13083       return -99;
13084     }
13085
13086   if (vec_len (name) > 64)
13087     {
13088       errmsg ("profile name too long");
13089       return -99;
13090     }
13091
13092   M (IKEV2_PROFILE_ADD_DEL, mp);
13093
13094   clib_memcpy (mp->name, name, vec_len (name));
13095   mp->is_add = is_add;
13096   vec_free (name);
13097
13098   S (mp);
13099   W (ret);
13100   return ret;
13101 }
13102
13103 static int
13104 api_ikev2_profile_set_auth (vat_main_t * vam)
13105 {
13106   unformat_input_t *i = vam->input;
13107   vl_api_ikev2_profile_set_auth_t *mp;
13108   u8 *name = 0;
13109   u8 *data = 0;
13110   u32 auth_method = 0;
13111   u8 is_hex = 0;
13112   int ret;
13113
13114   const char *valid_chars = "a-zA-Z0-9_";
13115
13116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13117     {
13118       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13119         vec_add1 (name, 0);
13120       else if (unformat (i, "auth_method %U",
13121                          unformat_ikev2_auth_method, &auth_method))
13122         ;
13123       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13124         is_hex = 1;
13125       else if (unformat (i, "auth_data %v", &data))
13126         ;
13127       else
13128         {
13129           errmsg ("parse error '%U'", format_unformat_error, i);
13130           return -99;
13131         }
13132     }
13133
13134   if (!vec_len (name))
13135     {
13136       errmsg ("profile name must be specified");
13137       return -99;
13138     }
13139
13140   if (vec_len (name) > 64)
13141     {
13142       errmsg ("profile name too long");
13143       return -99;
13144     }
13145
13146   if (!vec_len (data))
13147     {
13148       errmsg ("auth_data must be specified");
13149       return -99;
13150     }
13151
13152   if (!auth_method)
13153     {
13154       errmsg ("auth_method must be specified");
13155       return -99;
13156     }
13157
13158   M (IKEV2_PROFILE_SET_AUTH, mp);
13159
13160   mp->is_hex = is_hex;
13161   mp->auth_method = (u8) auth_method;
13162   mp->data_len = vec_len (data);
13163   clib_memcpy (mp->name, name, vec_len (name));
13164   clib_memcpy (mp->data, data, vec_len (data));
13165   vec_free (name);
13166   vec_free (data);
13167
13168   S (mp);
13169   W (ret);
13170   return ret;
13171 }
13172
13173 static int
13174 api_ikev2_profile_set_id (vat_main_t * vam)
13175 {
13176   unformat_input_t *i = vam->input;
13177   vl_api_ikev2_profile_set_id_t *mp;
13178   u8 *name = 0;
13179   u8 *data = 0;
13180   u8 is_local = 0;
13181   u32 id_type = 0;
13182   ip4_address_t ip4;
13183   int ret;
13184
13185   const char *valid_chars = "a-zA-Z0-9_";
13186
13187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13188     {
13189       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13190         vec_add1 (name, 0);
13191       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13192         ;
13193       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13194         {
13195           data = vec_new (u8, 4);
13196           clib_memcpy (data, ip4.as_u8, 4);
13197         }
13198       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13199         ;
13200       else if (unformat (i, "id_data %v", &data))
13201         ;
13202       else if (unformat (i, "local"))
13203         is_local = 1;
13204       else if (unformat (i, "remote"))
13205         is_local = 0;
13206       else
13207         {
13208           errmsg ("parse error '%U'", format_unformat_error, i);
13209           return -99;
13210         }
13211     }
13212
13213   if (!vec_len (name))
13214     {
13215       errmsg ("profile name must be specified");
13216       return -99;
13217     }
13218
13219   if (vec_len (name) > 64)
13220     {
13221       errmsg ("profile name too long");
13222       return -99;
13223     }
13224
13225   if (!vec_len (data))
13226     {
13227       errmsg ("id_data must be specified");
13228       return -99;
13229     }
13230
13231   if (!id_type)
13232     {
13233       errmsg ("id_type must be specified");
13234       return -99;
13235     }
13236
13237   M (IKEV2_PROFILE_SET_ID, mp);
13238
13239   mp->is_local = is_local;
13240   mp->id_type = (u8) id_type;
13241   mp->data_len = vec_len (data);
13242   clib_memcpy (mp->name, name, vec_len (name));
13243   clib_memcpy (mp->data, data, vec_len (data));
13244   vec_free (name);
13245   vec_free (data);
13246
13247   S (mp);
13248   W (ret);
13249   return ret;
13250 }
13251
13252 static int
13253 api_ikev2_profile_set_ts (vat_main_t * vam)
13254 {
13255   unformat_input_t *i = vam->input;
13256   vl_api_ikev2_profile_set_ts_t *mp;
13257   u8 *name = 0;
13258   u8 is_local = 0;
13259   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13260   ip4_address_t start_addr, end_addr;
13261
13262   const char *valid_chars = "a-zA-Z0-9_";
13263   int ret;
13264
13265   start_addr.as_u32 = 0;
13266   end_addr.as_u32 = (u32) ~ 0;
13267
13268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13269     {
13270       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13271         vec_add1 (name, 0);
13272       else if (unformat (i, "protocol %d", &proto))
13273         ;
13274       else if (unformat (i, "start_port %d", &start_port))
13275         ;
13276       else if (unformat (i, "end_port %d", &end_port))
13277         ;
13278       else
13279         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13280         ;
13281       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13282         ;
13283       else if (unformat (i, "local"))
13284         is_local = 1;
13285       else if (unformat (i, "remote"))
13286         is_local = 0;
13287       else
13288         {
13289           errmsg ("parse error '%U'", format_unformat_error, i);
13290           return -99;
13291         }
13292     }
13293
13294   if (!vec_len (name))
13295     {
13296       errmsg ("profile name must be specified");
13297       return -99;
13298     }
13299
13300   if (vec_len (name) > 64)
13301     {
13302       errmsg ("profile name too long");
13303       return -99;
13304     }
13305
13306   M (IKEV2_PROFILE_SET_TS, mp);
13307
13308   mp->is_local = is_local;
13309   mp->proto = (u8) proto;
13310   mp->start_port = (u16) start_port;
13311   mp->end_port = (u16) end_port;
13312   mp->start_addr = start_addr.as_u32;
13313   mp->end_addr = end_addr.as_u32;
13314   clib_memcpy (mp->name, name, vec_len (name));
13315   vec_free (name);
13316
13317   S (mp);
13318   W (ret);
13319   return ret;
13320 }
13321
13322 static int
13323 api_ikev2_set_local_key (vat_main_t * vam)
13324 {
13325   unformat_input_t *i = vam->input;
13326   vl_api_ikev2_set_local_key_t *mp;
13327   u8 *file = 0;
13328   int ret;
13329
13330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13331     {
13332       if (unformat (i, "file %v", &file))
13333         vec_add1 (file, 0);
13334       else
13335         {
13336           errmsg ("parse error '%U'", format_unformat_error, i);
13337           return -99;
13338         }
13339     }
13340
13341   if (!vec_len (file))
13342     {
13343       errmsg ("RSA key file must be specified");
13344       return -99;
13345     }
13346
13347   if (vec_len (file) > 256)
13348     {
13349       errmsg ("file name too long");
13350       return -99;
13351     }
13352
13353   M (IKEV2_SET_LOCAL_KEY, mp);
13354
13355   clib_memcpy (mp->key_file, file, vec_len (file));
13356   vec_free (file);
13357
13358   S (mp);
13359   W (ret);
13360   return ret;
13361 }
13362
13363 static int
13364 api_ikev2_set_responder (vat_main_t * vam)
13365 {
13366   unformat_input_t *i = vam->input;
13367   vl_api_ikev2_set_responder_t *mp;
13368   int ret;
13369   u8 *name = 0;
13370   u32 sw_if_index = ~0;
13371   ip4_address_t address;
13372
13373   const char *valid_chars = "a-zA-Z0-9_";
13374
13375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13376     {
13377       if (unformat
13378           (i, "%U interface %d address %U", unformat_token, valid_chars,
13379            &name, &sw_if_index, unformat_ip4_address, &address))
13380         vec_add1 (name, 0);
13381       else
13382         {
13383           errmsg ("parse error '%U'", format_unformat_error, i);
13384           return -99;
13385         }
13386     }
13387
13388   if (!vec_len (name))
13389     {
13390       errmsg ("profile name must be specified");
13391       return -99;
13392     }
13393
13394   if (vec_len (name) > 64)
13395     {
13396       errmsg ("profile name too long");
13397       return -99;
13398     }
13399
13400   M (IKEV2_SET_RESPONDER, mp);
13401
13402   clib_memcpy (mp->name, name, vec_len (name));
13403   vec_free (name);
13404
13405   mp->sw_if_index = sw_if_index;
13406   clib_memcpy (mp->address, &address, sizeof (address));
13407
13408   S (mp);
13409   W (ret);
13410   return ret;
13411 }
13412
13413 static int
13414 api_ikev2_set_ike_transforms (vat_main_t * vam)
13415 {
13416   unformat_input_t *i = vam->input;
13417   vl_api_ikev2_set_ike_transforms_t *mp;
13418   int ret;
13419   u8 *name = 0;
13420   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13421
13422   const char *valid_chars = "a-zA-Z0-9_";
13423
13424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13425     {
13426       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13427                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13428         vec_add1 (name, 0);
13429       else
13430         {
13431           errmsg ("parse error '%U'", format_unformat_error, i);
13432           return -99;
13433         }
13434     }
13435
13436   if (!vec_len (name))
13437     {
13438       errmsg ("profile name must be specified");
13439       return -99;
13440     }
13441
13442   if (vec_len (name) > 64)
13443     {
13444       errmsg ("profile name too long");
13445       return -99;
13446     }
13447
13448   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13449
13450   clib_memcpy (mp->name, name, vec_len (name));
13451   vec_free (name);
13452   mp->crypto_alg = crypto_alg;
13453   mp->crypto_key_size = crypto_key_size;
13454   mp->integ_alg = integ_alg;
13455   mp->dh_group = dh_group;
13456
13457   S (mp);
13458   W (ret);
13459   return ret;
13460 }
13461
13462
13463 static int
13464 api_ikev2_set_esp_transforms (vat_main_t * vam)
13465 {
13466   unformat_input_t *i = vam->input;
13467   vl_api_ikev2_set_esp_transforms_t *mp;
13468   int ret;
13469   u8 *name = 0;
13470   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13471
13472   const char *valid_chars = "a-zA-Z0-9_";
13473
13474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13475     {
13476       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13477                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13478         vec_add1 (name, 0);
13479       else
13480         {
13481           errmsg ("parse error '%U'", format_unformat_error, i);
13482           return -99;
13483         }
13484     }
13485
13486   if (!vec_len (name))
13487     {
13488       errmsg ("profile name must be specified");
13489       return -99;
13490     }
13491
13492   if (vec_len (name) > 64)
13493     {
13494       errmsg ("profile name too long");
13495       return -99;
13496     }
13497
13498   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13499
13500   clib_memcpy (mp->name, name, vec_len (name));
13501   vec_free (name);
13502   mp->crypto_alg = crypto_alg;
13503   mp->crypto_key_size = crypto_key_size;
13504   mp->integ_alg = integ_alg;
13505   mp->dh_group = dh_group;
13506
13507   S (mp);
13508   W (ret);
13509   return ret;
13510 }
13511
13512 static int
13513 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13514 {
13515   unformat_input_t *i = vam->input;
13516   vl_api_ikev2_set_sa_lifetime_t *mp;
13517   int ret;
13518   u8 *name = 0;
13519   u64 lifetime, lifetime_maxdata;
13520   u32 lifetime_jitter, handover;
13521
13522   const char *valid_chars = "a-zA-Z0-9_";
13523
13524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13525     {
13526       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13527                     &lifetime, &lifetime_jitter, &handover,
13528                     &lifetime_maxdata))
13529         vec_add1 (name, 0);
13530       else
13531         {
13532           errmsg ("parse error '%U'", format_unformat_error, i);
13533           return -99;
13534         }
13535     }
13536
13537   if (!vec_len (name))
13538     {
13539       errmsg ("profile name must be specified");
13540       return -99;
13541     }
13542
13543   if (vec_len (name) > 64)
13544     {
13545       errmsg ("profile name too long");
13546       return -99;
13547     }
13548
13549   M (IKEV2_SET_SA_LIFETIME, mp);
13550
13551   clib_memcpy (mp->name, name, vec_len (name));
13552   vec_free (name);
13553   mp->lifetime = lifetime;
13554   mp->lifetime_jitter = lifetime_jitter;
13555   mp->handover = handover;
13556   mp->lifetime_maxdata = lifetime_maxdata;
13557
13558   S (mp);
13559   W (ret);
13560   return ret;
13561 }
13562
13563 static int
13564 api_ikev2_initiate_sa_init (vat_main_t * vam)
13565 {
13566   unformat_input_t *i = vam->input;
13567   vl_api_ikev2_initiate_sa_init_t *mp;
13568   int ret;
13569   u8 *name = 0;
13570
13571   const char *valid_chars = "a-zA-Z0-9_";
13572
13573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13574     {
13575       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13576         vec_add1 (name, 0);
13577       else
13578         {
13579           errmsg ("parse error '%U'", format_unformat_error, i);
13580           return -99;
13581         }
13582     }
13583
13584   if (!vec_len (name))
13585     {
13586       errmsg ("profile name must be specified");
13587       return -99;
13588     }
13589
13590   if (vec_len (name) > 64)
13591     {
13592       errmsg ("profile name too long");
13593       return -99;
13594     }
13595
13596   M (IKEV2_INITIATE_SA_INIT, mp);
13597
13598   clib_memcpy (mp->name, name, vec_len (name));
13599   vec_free (name);
13600
13601   S (mp);
13602   W (ret);
13603   return ret;
13604 }
13605
13606 static int
13607 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13608 {
13609   unformat_input_t *i = vam->input;
13610   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13611   int ret;
13612   u64 ispi;
13613
13614
13615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13616     {
13617       if (unformat (i, "%lx", &ispi))
13618         ;
13619       else
13620         {
13621           errmsg ("parse error '%U'", format_unformat_error, i);
13622           return -99;
13623         }
13624     }
13625
13626   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13627
13628   mp->ispi = ispi;
13629
13630   S (mp);
13631   W (ret);
13632   return ret;
13633 }
13634
13635 static int
13636 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13637 {
13638   unformat_input_t *i = vam->input;
13639   vl_api_ikev2_initiate_del_child_sa_t *mp;
13640   int ret;
13641   u32 ispi;
13642
13643
13644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13645     {
13646       if (unformat (i, "%x", &ispi))
13647         ;
13648       else
13649         {
13650           errmsg ("parse error '%U'", format_unformat_error, i);
13651           return -99;
13652         }
13653     }
13654
13655   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13656
13657   mp->ispi = ispi;
13658
13659   S (mp);
13660   W (ret);
13661   return ret;
13662 }
13663
13664 static int
13665 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13666 {
13667   unformat_input_t *i = vam->input;
13668   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13669   int ret;
13670   u32 ispi;
13671
13672
13673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13674     {
13675       if (unformat (i, "%x", &ispi))
13676         ;
13677       else
13678         {
13679           errmsg ("parse error '%U'", format_unformat_error, i);
13680           return -99;
13681         }
13682     }
13683
13684   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13685
13686   mp->ispi = ispi;
13687
13688   S (mp);
13689   W (ret);
13690   return ret;
13691 }
13692
13693 /*
13694  * MAP
13695  */
13696 static int
13697 api_map_add_domain (vat_main_t * vam)
13698 {
13699   unformat_input_t *i = vam->input;
13700   vl_api_map_add_domain_t *mp;
13701
13702   ip4_address_t ip4_prefix;
13703   ip6_address_t ip6_prefix;
13704   ip6_address_t ip6_src;
13705   u32 num_m_args = 0;
13706   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13707     0, psid_length = 0;
13708   u8 is_translation = 0;
13709   u32 mtu = 0;
13710   u32 ip6_src_len = 128;
13711   int ret;
13712
13713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13714     {
13715       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13716                     &ip4_prefix, &ip4_prefix_len))
13717         num_m_args++;
13718       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13719                          &ip6_prefix, &ip6_prefix_len))
13720         num_m_args++;
13721       else
13722         if (unformat
13723             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13724              &ip6_src_len))
13725         num_m_args++;
13726       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13727         num_m_args++;
13728       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13729         num_m_args++;
13730       else if (unformat (i, "psid-offset %d", &psid_offset))
13731         num_m_args++;
13732       else if (unformat (i, "psid-len %d", &psid_length))
13733         num_m_args++;
13734       else if (unformat (i, "mtu %d", &mtu))
13735         num_m_args++;
13736       else if (unformat (i, "map-t"))
13737         is_translation = 1;
13738       else
13739         {
13740           clib_warning ("parse error '%U'", format_unformat_error, i);
13741           return -99;
13742         }
13743     }
13744
13745   if (num_m_args < 3)
13746     {
13747       errmsg ("mandatory argument(s) missing");
13748       return -99;
13749     }
13750
13751   /* Construct the API message */
13752   M (MAP_ADD_DOMAIN, mp);
13753
13754   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13755   mp->ip4_prefix_len = ip4_prefix_len;
13756
13757   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13758   mp->ip6_prefix_len = ip6_prefix_len;
13759
13760   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13761   mp->ip6_src_prefix_len = ip6_src_len;
13762
13763   mp->ea_bits_len = ea_bits_len;
13764   mp->psid_offset = psid_offset;
13765   mp->psid_length = psid_length;
13766   mp->is_translation = is_translation;
13767   mp->mtu = htons (mtu);
13768
13769   /* send it... */
13770   S (mp);
13771
13772   /* Wait for a reply, return good/bad news  */
13773   W (ret);
13774   return ret;
13775 }
13776
13777 static int
13778 api_map_del_domain (vat_main_t * vam)
13779 {
13780   unformat_input_t *i = vam->input;
13781   vl_api_map_del_domain_t *mp;
13782
13783   u32 num_m_args = 0;
13784   u32 index;
13785   int ret;
13786
13787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13788     {
13789       if (unformat (i, "index %d", &index))
13790         num_m_args++;
13791       else
13792         {
13793           clib_warning ("parse error '%U'", format_unformat_error, i);
13794           return -99;
13795         }
13796     }
13797
13798   if (num_m_args != 1)
13799     {
13800       errmsg ("mandatory argument(s) missing");
13801       return -99;
13802     }
13803
13804   /* Construct the API message */
13805   M (MAP_DEL_DOMAIN, mp);
13806
13807   mp->index = ntohl (index);
13808
13809   /* send it... */
13810   S (mp);
13811
13812   /* Wait for a reply, return good/bad news  */
13813   W (ret);
13814   return ret;
13815 }
13816
13817 static int
13818 api_map_add_del_rule (vat_main_t * vam)
13819 {
13820   unformat_input_t *i = vam->input;
13821   vl_api_map_add_del_rule_t *mp;
13822   u8 is_add = 1;
13823   ip6_address_t ip6_dst;
13824   u32 num_m_args = 0, index, psid = 0;
13825   int ret;
13826
13827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13828     {
13829       if (unformat (i, "index %d", &index))
13830         num_m_args++;
13831       else if (unformat (i, "psid %d", &psid))
13832         num_m_args++;
13833       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13834         num_m_args++;
13835       else if (unformat (i, "del"))
13836         {
13837           is_add = 0;
13838         }
13839       else
13840         {
13841           clib_warning ("parse error '%U'", format_unformat_error, i);
13842           return -99;
13843         }
13844     }
13845
13846   /* Construct the API message */
13847   M (MAP_ADD_DEL_RULE, mp);
13848
13849   mp->index = ntohl (index);
13850   mp->is_add = is_add;
13851   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13852   mp->psid = ntohs (psid);
13853
13854   /* send it... */
13855   S (mp);
13856
13857   /* Wait for a reply, return good/bad news  */
13858   W (ret);
13859   return ret;
13860 }
13861
13862 static int
13863 api_map_domain_dump (vat_main_t * vam)
13864 {
13865   vl_api_map_domain_dump_t *mp;
13866   vl_api_control_ping_t *mp_ping;
13867   int ret;
13868
13869   /* Construct the API message */
13870   M (MAP_DOMAIN_DUMP, mp);
13871
13872   /* send it... */
13873   S (mp);
13874
13875   /* Use a control ping for synchronization */
13876   M (CONTROL_PING, mp_ping);
13877   S (mp_ping);
13878
13879   W (ret);
13880   return ret;
13881 }
13882
13883 static int
13884 api_map_rule_dump (vat_main_t * vam)
13885 {
13886   unformat_input_t *i = vam->input;
13887   vl_api_map_rule_dump_t *mp;
13888   vl_api_control_ping_t *mp_ping;
13889   u32 domain_index = ~0;
13890   int ret;
13891
13892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13893     {
13894       if (unformat (i, "index %u", &domain_index))
13895         ;
13896       else
13897         break;
13898     }
13899
13900   if (domain_index == ~0)
13901     {
13902       clib_warning ("parse error: domain index expected");
13903       return -99;
13904     }
13905
13906   /* Construct the API message */
13907   M (MAP_RULE_DUMP, mp);
13908
13909   mp->domain_index = htonl (domain_index);
13910
13911   /* send it... */
13912   S (mp);
13913
13914   /* Use a control ping for synchronization */
13915   M (CONTROL_PING, mp_ping);
13916   S (mp_ping);
13917
13918   W (ret);
13919   return ret;
13920 }
13921
13922 static void vl_api_map_add_domain_reply_t_handler
13923   (vl_api_map_add_domain_reply_t * mp)
13924 {
13925   vat_main_t *vam = &vat_main;
13926   i32 retval = ntohl (mp->retval);
13927
13928   if (vam->async_mode)
13929     {
13930       vam->async_errors += (retval < 0);
13931     }
13932   else
13933     {
13934       vam->retval = retval;
13935       vam->result_ready = 1;
13936     }
13937 }
13938
13939 static void vl_api_map_add_domain_reply_t_handler_json
13940   (vl_api_map_add_domain_reply_t * mp)
13941 {
13942   vat_main_t *vam = &vat_main;
13943   vat_json_node_t node;
13944
13945   vat_json_init_object (&node);
13946   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13947   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13948
13949   vat_json_print (vam->ofp, &node);
13950   vat_json_free (&node);
13951
13952   vam->retval = ntohl (mp->retval);
13953   vam->result_ready = 1;
13954 }
13955
13956 static int
13957 api_get_first_msg_id (vat_main_t * vam)
13958 {
13959   vl_api_get_first_msg_id_t *mp;
13960   unformat_input_t *i = vam->input;
13961   u8 *name;
13962   u8 name_set = 0;
13963   int ret;
13964
13965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13966     {
13967       if (unformat (i, "client %s", &name))
13968         name_set = 1;
13969       else
13970         break;
13971     }
13972
13973   if (name_set == 0)
13974     {
13975       errmsg ("missing client name");
13976       return -99;
13977     }
13978   vec_add1 (name, 0);
13979
13980   if (vec_len (name) > 63)
13981     {
13982       errmsg ("client name too long");
13983       return -99;
13984     }
13985
13986   M (GET_FIRST_MSG_ID, mp);
13987   clib_memcpy (mp->name, name, vec_len (name));
13988   S (mp);
13989   W (ret);
13990   return ret;
13991 }
13992
13993 static int
13994 api_cop_interface_enable_disable (vat_main_t * vam)
13995 {
13996   unformat_input_t *line_input = vam->input;
13997   vl_api_cop_interface_enable_disable_t *mp;
13998   u32 sw_if_index = ~0;
13999   u8 enable_disable = 1;
14000   int ret;
14001
14002   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14003     {
14004       if (unformat (line_input, "disable"))
14005         enable_disable = 0;
14006       if (unformat (line_input, "enable"))
14007         enable_disable = 1;
14008       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14009                          vam, &sw_if_index))
14010         ;
14011       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14012         ;
14013       else
14014         break;
14015     }
14016
14017   if (sw_if_index == ~0)
14018     {
14019       errmsg ("missing interface name or sw_if_index");
14020       return -99;
14021     }
14022
14023   /* Construct the API message */
14024   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14025   mp->sw_if_index = ntohl (sw_if_index);
14026   mp->enable_disable = enable_disable;
14027
14028   /* send it... */
14029   S (mp);
14030   /* Wait for the reply */
14031   W (ret);
14032   return ret;
14033 }
14034
14035 static int
14036 api_cop_whitelist_enable_disable (vat_main_t * vam)
14037 {
14038   unformat_input_t *line_input = vam->input;
14039   vl_api_cop_whitelist_enable_disable_t *mp;
14040   u32 sw_if_index = ~0;
14041   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14042   u32 fib_id = 0;
14043   int ret;
14044
14045   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14046     {
14047       if (unformat (line_input, "ip4"))
14048         ip4 = 1;
14049       else if (unformat (line_input, "ip6"))
14050         ip6 = 1;
14051       else if (unformat (line_input, "default"))
14052         default_cop = 1;
14053       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14054                          vam, &sw_if_index))
14055         ;
14056       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14057         ;
14058       else if (unformat (line_input, "fib-id %d", &fib_id))
14059         ;
14060       else
14061         break;
14062     }
14063
14064   if (sw_if_index == ~0)
14065     {
14066       errmsg ("missing interface name or sw_if_index");
14067       return -99;
14068     }
14069
14070   /* Construct the API message */
14071   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14072   mp->sw_if_index = ntohl (sw_if_index);
14073   mp->fib_id = ntohl (fib_id);
14074   mp->ip4 = ip4;
14075   mp->ip6 = ip6;
14076   mp->default_cop = default_cop;
14077
14078   /* send it... */
14079   S (mp);
14080   /* Wait for the reply */
14081   W (ret);
14082   return ret;
14083 }
14084
14085 static int
14086 api_get_node_graph (vat_main_t * vam)
14087 {
14088   vl_api_get_node_graph_t *mp;
14089   int ret;
14090
14091   M (GET_NODE_GRAPH, mp);
14092
14093   /* send it... */
14094   S (mp);
14095   /* Wait for the reply */
14096   W (ret);
14097   return ret;
14098 }
14099
14100 /* *INDENT-OFF* */
14101 /** Used for parsing LISP eids */
14102 typedef CLIB_PACKED(struct{
14103   u8 addr[16];   /**< eid address */
14104   u32 len;       /**< prefix length if IP */
14105   u8 type;      /**< type of eid */
14106 }) lisp_eid_vat_t;
14107 /* *INDENT-ON* */
14108
14109 static uword
14110 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14111 {
14112   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14113
14114   memset (a, 0, sizeof (a[0]));
14115
14116   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14117     {
14118       a->type = 0;              /* ipv4 type */
14119     }
14120   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14121     {
14122       a->type = 1;              /* ipv6 type */
14123     }
14124   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14125     {
14126       a->type = 2;              /* mac type */
14127     }
14128   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14129     {
14130       a->type = 3;              /* NSH type */
14131       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14132       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14133     }
14134   else
14135     {
14136       return 0;
14137     }
14138
14139   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14140     {
14141       return 0;
14142     }
14143
14144   return 1;
14145 }
14146
14147 static int
14148 lisp_eid_size_vat (u8 type)
14149 {
14150   switch (type)
14151     {
14152     case 0:
14153       return 4;
14154     case 1:
14155       return 16;
14156     case 2:
14157       return 6;
14158     case 3:
14159       return 5;
14160     }
14161   return 0;
14162 }
14163
14164 static void
14165 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14166 {
14167   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14168 }
14169
14170 static int
14171 api_one_add_del_locator_set (vat_main_t * vam)
14172 {
14173   unformat_input_t *input = vam->input;
14174   vl_api_one_add_del_locator_set_t *mp;
14175   u8 is_add = 1;
14176   u8 *locator_set_name = NULL;
14177   u8 locator_set_name_set = 0;
14178   vl_api_local_locator_t locator, *locators = 0;
14179   u32 sw_if_index, priority, weight;
14180   u32 data_len = 0;
14181
14182   int ret;
14183   /* Parse args required to build the message */
14184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14185     {
14186       if (unformat (input, "del"))
14187         {
14188           is_add = 0;
14189         }
14190       else if (unformat (input, "locator-set %s", &locator_set_name))
14191         {
14192           locator_set_name_set = 1;
14193         }
14194       else if (unformat (input, "sw_if_index %u p %u w %u",
14195                          &sw_if_index, &priority, &weight))
14196         {
14197           locator.sw_if_index = htonl (sw_if_index);
14198           locator.priority = priority;
14199           locator.weight = weight;
14200           vec_add1 (locators, locator);
14201         }
14202       else
14203         if (unformat
14204             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14205              &sw_if_index, &priority, &weight))
14206         {
14207           locator.sw_if_index = htonl (sw_if_index);
14208           locator.priority = priority;
14209           locator.weight = weight;
14210           vec_add1 (locators, locator);
14211         }
14212       else
14213         break;
14214     }
14215
14216   if (locator_set_name_set == 0)
14217     {
14218       errmsg ("missing locator-set name");
14219       vec_free (locators);
14220       return -99;
14221     }
14222
14223   if (vec_len (locator_set_name) > 64)
14224     {
14225       errmsg ("locator-set name too long");
14226       vec_free (locator_set_name);
14227       vec_free (locators);
14228       return -99;
14229     }
14230   vec_add1 (locator_set_name, 0);
14231
14232   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14233
14234   /* Construct the API message */
14235   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14236
14237   mp->is_add = is_add;
14238   clib_memcpy (mp->locator_set_name, locator_set_name,
14239                vec_len (locator_set_name));
14240   vec_free (locator_set_name);
14241
14242   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14243   if (locators)
14244     clib_memcpy (mp->locators, locators, data_len);
14245   vec_free (locators);
14246
14247   /* send it... */
14248   S (mp);
14249
14250   /* Wait for a reply... */
14251   W (ret);
14252   return ret;
14253 }
14254
14255 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14256
14257 static int
14258 api_one_add_del_locator (vat_main_t * vam)
14259 {
14260   unformat_input_t *input = vam->input;
14261   vl_api_one_add_del_locator_t *mp;
14262   u32 tmp_if_index = ~0;
14263   u32 sw_if_index = ~0;
14264   u8 sw_if_index_set = 0;
14265   u8 sw_if_index_if_name_set = 0;
14266   u32 priority = ~0;
14267   u8 priority_set = 0;
14268   u32 weight = ~0;
14269   u8 weight_set = 0;
14270   u8 is_add = 1;
14271   u8 *locator_set_name = NULL;
14272   u8 locator_set_name_set = 0;
14273   int ret;
14274
14275   /* Parse args required to build the message */
14276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14277     {
14278       if (unformat (input, "del"))
14279         {
14280           is_add = 0;
14281         }
14282       else if (unformat (input, "locator-set %s", &locator_set_name))
14283         {
14284           locator_set_name_set = 1;
14285         }
14286       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14287                          &tmp_if_index))
14288         {
14289           sw_if_index_if_name_set = 1;
14290           sw_if_index = tmp_if_index;
14291         }
14292       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14293         {
14294           sw_if_index_set = 1;
14295           sw_if_index = tmp_if_index;
14296         }
14297       else if (unformat (input, "p %d", &priority))
14298         {
14299           priority_set = 1;
14300         }
14301       else if (unformat (input, "w %d", &weight))
14302         {
14303           weight_set = 1;
14304         }
14305       else
14306         break;
14307     }
14308
14309   if (locator_set_name_set == 0)
14310     {
14311       errmsg ("missing locator-set name");
14312       return -99;
14313     }
14314
14315   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14316     {
14317       errmsg ("missing sw_if_index");
14318       vec_free (locator_set_name);
14319       return -99;
14320     }
14321
14322   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14323     {
14324       errmsg ("cannot use both params interface name and sw_if_index");
14325       vec_free (locator_set_name);
14326       return -99;
14327     }
14328
14329   if (priority_set == 0)
14330     {
14331       errmsg ("missing locator-set priority");
14332       vec_free (locator_set_name);
14333       return -99;
14334     }
14335
14336   if (weight_set == 0)
14337     {
14338       errmsg ("missing locator-set weight");
14339       vec_free (locator_set_name);
14340       return -99;
14341     }
14342
14343   if (vec_len (locator_set_name) > 64)
14344     {
14345       errmsg ("locator-set name too long");
14346       vec_free (locator_set_name);
14347       return -99;
14348     }
14349   vec_add1 (locator_set_name, 0);
14350
14351   /* Construct the API message */
14352   M (ONE_ADD_DEL_LOCATOR, mp);
14353
14354   mp->is_add = is_add;
14355   mp->sw_if_index = ntohl (sw_if_index);
14356   mp->priority = priority;
14357   mp->weight = weight;
14358   clib_memcpy (mp->locator_set_name, locator_set_name,
14359                vec_len (locator_set_name));
14360   vec_free (locator_set_name);
14361
14362   /* send it... */
14363   S (mp);
14364
14365   /* Wait for a reply... */
14366   W (ret);
14367   return ret;
14368 }
14369
14370 #define api_lisp_add_del_locator api_one_add_del_locator
14371
14372 uword
14373 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14374 {
14375   u32 *key_id = va_arg (*args, u32 *);
14376   u8 *s = 0;
14377
14378   if (unformat (input, "%s", &s))
14379     {
14380       if (!strcmp ((char *) s, "sha1"))
14381         key_id[0] = HMAC_SHA_1_96;
14382       else if (!strcmp ((char *) s, "sha256"))
14383         key_id[0] = HMAC_SHA_256_128;
14384       else
14385         {
14386           clib_warning ("invalid key_id: '%s'", s);
14387           key_id[0] = HMAC_NO_KEY;
14388         }
14389     }
14390   else
14391     return 0;
14392
14393   vec_free (s);
14394   return 1;
14395 }
14396
14397 static int
14398 api_one_add_del_local_eid (vat_main_t * vam)
14399 {
14400   unformat_input_t *input = vam->input;
14401   vl_api_one_add_del_local_eid_t *mp;
14402   u8 is_add = 1;
14403   u8 eid_set = 0;
14404   lisp_eid_vat_t _eid, *eid = &_eid;
14405   u8 *locator_set_name = 0;
14406   u8 locator_set_name_set = 0;
14407   u32 vni = 0;
14408   u16 key_id = 0;
14409   u8 *key = 0;
14410   int ret;
14411
14412   /* Parse args required to build the message */
14413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14414     {
14415       if (unformat (input, "del"))
14416         {
14417           is_add = 0;
14418         }
14419       else if (unformat (input, "vni %d", &vni))
14420         {
14421           ;
14422         }
14423       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14424         {
14425           eid_set = 1;
14426         }
14427       else if (unformat (input, "locator-set %s", &locator_set_name))
14428         {
14429           locator_set_name_set = 1;
14430         }
14431       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14432         ;
14433       else if (unformat (input, "secret-key %_%v%_", &key))
14434         ;
14435       else
14436         break;
14437     }
14438
14439   if (locator_set_name_set == 0)
14440     {
14441       errmsg ("missing locator-set name");
14442       return -99;
14443     }
14444
14445   if (0 == eid_set)
14446     {
14447       errmsg ("EID address not set!");
14448       vec_free (locator_set_name);
14449       return -99;
14450     }
14451
14452   if (key && (0 == key_id))
14453     {
14454       errmsg ("invalid key_id!");
14455       return -99;
14456     }
14457
14458   if (vec_len (key) > 64)
14459     {
14460       errmsg ("key too long");
14461       vec_free (key);
14462       return -99;
14463     }
14464
14465   if (vec_len (locator_set_name) > 64)
14466     {
14467       errmsg ("locator-set name too long");
14468       vec_free (locator_set_name);
14469       return -99;
14470     }
14471   vec_add1 (locator_set_name, 0);
14472
14473   /* Construct the API message */
14474   M (ONE_ADD_DEL_LOCAL_EID, mp);
14475
14476   mp->is_add = is_add;
14477   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14478   mp->eid_type = eid->type;
14479   mp->prefix_len = eid->len;
14480   mp->vni = clib_host_to_net_u32 (vni);
14481   mp->key_id = clib_host_to_net_u16 (key_id);
14482   clib_memcpy (mp->locator_set_name, locator_set_name,
14483                vec_len (locator_set_name));
14484   clib_memcpy (mp->key, key, vec_len (key));
14485
14486   vec_free (locator_set_name);
14487   vec_free (key);
14488
14489   /* send it... */
14490   S (mp);
14491
14492   /* Wait for a reply... */
14493   W (ret);
14494   return ret;
14495 }
14496
14497 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14498
14499 static int
14500 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14501 {
14502   u32 dp_table = 0, vni = 0;;
14503   unformat_input_t *input = vam->input;
14504   vl_api_gpe_add_del_fwd_entry_t *mp;
14505   u8 is_add = 1;
14506   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14507   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14508   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14509   u32 action = ~0, w;
14510   ip4_address_t rmt_rloc4, lcl_rloc4;
14511   ip6_address_t rmt_rloc6, lcl_rloc6;
14512   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14513   int ret;
14514
14515   memset (&rloc, 0, sizeof (rloc));
14516
14517   /* Parse args required to build the message */
14518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14519     {
14520       if (unformat (input, "del"))
14521         is_add = 0;
14522       else if (unformat (input, "add"))
14523         is_add = 1;
14524       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14525         {
14526           rmt_eid_set = 1;
14527         }
14528       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14529         {
14530           lcl_eid_set = 1;
14531         }
14532       else if (unformat (input, "vrf %d", &dp_table))
14533         ;
14534       else if (unformat (input, "bd %d", &dp_table))
14535         ;
14536       else if (unformat (input, "vni %d", &vni))
14537         ;
14538       else if (unformat (input, "w %d", &w))
14539         {
14540           if (!curr_rloc)
14541             {
14542               errmsg ("No RLOC configured for setting priority/weight!");
14543               return -99;
14544             }
14545           curr_rloc->weight = w;
14546         }
14547       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14548                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14549         {
14550           rloc.is_ip4 = 1;
14551
14552           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14553           rloc.weight = 0;
14554           vec_add1 (lcl_locs, rloc);
14555
14556           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14557           vec_add1 (rmt_locs, rloc);
14558           /* weight saved in rmt loc */
14559           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14560         }
14561       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14562                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14563         {
14564           rloc.is_ip4 = 0;
14565           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14566           rloc.weight = 0;
14567           vec_add1 (lcl_locs, rloc);
14568
14569           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14570           vec_add1 (rmt_locs, rloc);
14571           /* weight saved in rmt loc */
14572           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14573         }
14574       else if (unformat (input, "action %d", &action))
14575         {
14576           ;
14577         }
14578       else
14579         {
14580           clib_warning ("parse error '%U'", format_unformat_error, input);
14581           return -99;
14582         }
14583     }
14584
14585   if (!rmt_eid_set)
14586     {
14587       errmsg ("remote eid addresses not set");
14588       return -99;
14589     }
14590
14591   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14592     {
14593       errmsg ("eid types don't match");
14594       return -99;
14595     }
14596
14597   if (0 == rmt_locs && (u32) ~ 0 == action)
14598     {
14599       errmsg ("action not set for negative mapping");
14600       return -99;
14601     }
14602
14603   /* Construct the API message */
14604   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14605       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14606
14607   mp->is_add = is_add;
14608   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14609   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14610   mp->eid_type = rmt_eid->type;
14611   mp->dp_table = clib_host_to_net_u32 (dp_table);
14612   mp->vni = clib_host_to_net_u32 (vni);
14613   mp->rmt_len = rmt_eid->len;
14614   mp->lcl_len = lcl_eid->len;
14615   mp->action = action;
14616
14617   if (0 != rmt_locs && 0 != lcl_locs)
14618     {
14619       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14620       clib_memcpy (mp->locs, lcl_locs,
14621                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14622
14623       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14624       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14625                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14626     }
14627   vec_free (lcl_locs);
14628   vec_free (rmt_locs);
14629
14630   /* send it... */
14631   S (mp);
14632
14633   /* Wait for a reply... */
14634   W (ret);
14635   return ret;
14636 }
14637
14638 static int
14639 api_one_add_del_map_server (vat_main_t * vam)
14640 {
14641   unformat_input_t *input = vam->input;
14642   vl_api_one_add_del_map_server_t *mp;
14643   u8 is_add = 1;
14644   u8 ipv4_set = 0;
14645   u8 ipv6_set = 0;
14646   ip4_address_t ipv4;
14647   ip6_address_t ipv6;
14648   int ret;
14649
14650   /* Parse args required to build the message */
14651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14652     {
14653       if (unformat (input, "del"))
14654         {
14655           is_add = 0;
14656         }
14657       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14658         {
14659           ipv4_set = 1;
14660         }
14661       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14662         {
14663           ipv6_set = 1;
14664         }
14665       else
14666         break;
14667     }
14668
14669   if (ipv4_set && ipv6_set)
14670     {
14671       errmsg ("both eid v4 and v6 addresses set");
14672       return -99;
14673     }
14674
14675   if (!ipv4_set && !ipv6_set)
14676     {
14677       errmsg ("eid addresses not set");
14678       return -99;
14679     }
14680
14681   /* Construct the API message */
14682   M (ONE_ADD_DEL_MAP_SERVER, mp);
14683
14684   mp->is_add = is_add;
14685   if (ipv6_set)
14686     {
14687       mp->is_ipv6 = 1;
14688       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14689     }
14690   else
14691     {
14692       mp->is_ipv6 = 0;
14693       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14694     }
14695
14696   /* send it... */
14697   S (mp);
14698
14699   /* Wait for a reply... */
14700   W (ret);
14701   return ret;
14702 }
14703
14704 #define api_lisp_add_del_map_server api_one_add_del_map_server
14705
14706 static int
14707 api_one_add_del_map_resolver (vat_main_t * vam)
14708 {
14709   unformat_input_t *input = vam->input;
14710   vl_api_one_add_del_map_resolver_t *mp;
14711   u8 is_add = 1;
14712   u8 ipv4_set = 0;
14713   u8 ipv6_set = 0;
14714   ip4_address_t ipv4;
14715   ip6_address_t ipv6;
14716   int ret;
14717
14718   /* Parse args required to build the message */
14719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14720     {
14721       if (unformat (input, "del"))
14722         {
14723           is_add = 0;
14724         }
14725       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14726         {
14727           ipv4_set = 1;
14728         }
14729       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14730         {
14731           ipv6_set = 1;
14732         }
14733       else
14734         break;
14735     }
14736
14737   if (ipv4_set && ipv6_set)
14738     {
14739       errmsg ("both eid v4 and v6 addresses set");
14740       return -99;
14741     }
14742
14743   if (!ipv4_set && !ipv6_set)
14744     {
14745       errmsg ("eid addresses not set");
14746       return -99;
14747     }
14748
14749   /* Construct the API message */
14750   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14751
14752   mp->is_add = is_add;
14753   if (ipv6_set)
14754     {
14755       mp->is_ipv6 = 1;
14756       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14757     }
14758   else
14759     {
14760       mp->is_ipv6 = 0;
14761       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14762     }
14763
14764   /* send it... */
14765   S (mp);
14766
14767   /* Wait for a reply... */
14768   W (ret);
14769   return ret;
14770 }
14771
14772 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14773
14774 static int
14775 api_lisp_gpe_enable_disable (vat_main_t * vam)
14776 {
14777   unformat_input_t *input = vam->input;
14778   vl_api_gpe_enable_disable_t *mp;
14779   u8 is_set = 0;
14780   u8 is_en = 1;
14781   int ret;
14782
14783   /* Parse args required to build the message */
14784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14785     {
14786       if (unformat (input, "enable"))
14787         {
14788           is_set = 1;
14789           is_en = 1;
14790         }
14791       else if (unformat (input, "disable"))
14792         {
14793           is_set = 1;
14794           is_en = 0;
14795         }
14796       else
14797         break;
14798     }
14799
14800   if (is_set == 0)
14801     {
14802       errmsg ("Value not set");
14803       return -99;
14804     }
14805
14806   /* Construct the API message */
14807   M (GPE_ENABLE_DISABLE, mp);
14808
14809   mp->is_en = is_en;
14810
14811   /* send it... */
14812   S (mp);
14813
14814   /* Wait for a reply... */
14815   W (ret);
14816   return ret;
14817 }
14818
14819 static int
14820 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14821 {
14822   unformat_input_t *input = vam->input;
14823   vl_api_one_rloc_probe_enable_disable_t *mp;
14824   u8 is_set = 0;
14825   u8 is_en = 0;
14826   int ret;
14827
14828   /* Parse args required to build the message */
14829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14830     {
14831       if (unformat (input, "enable"))
14832         {
14833           is_set = 1;
14834           is_en = 1;
14835         }
14836       else if (unformat (input, "disable"))
14837         is_set = 1;
14838       else
14839         break;
14840     }
14841
14842   if (!is_set)
14843     {
14844       errmsg ("Value not set");
14845       return -99;
14846     }
14847
14848   /* Construct the API message */
14849   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14850
14851   mp->is_enabled = is_en;
14852
14853   /* send it... */
14854   S (mp);
14855
14856   /* Wait for a reply... */
14857   W (ret);
14858   return ret;
14859 }
14860
14861 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14862
14863 static int
14864 api_one_map_register_enable_disable (vat_main_t * vam)
14865 {
14866   unformat_input_t *input = vam->input;
14867   vl_api_one_map_register_enable_disable_t *mp;
14868   u8 is_set = 0;
14869   u8 is_en = 0;
14870   int ret;
14871
14872   /* Parse args required to build the message */
14873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14874     {
14875       if (unformat (input, "enable"))
14876         {
14877           is_set = 1;
14878           is_en = 1;
14879         }
14880       else if (unformat (input, "disable"))
14881         is_set = 1;
14882       else
14883         break;
14884     }
14885
14886   if (!is_set)
14887     {
14888       errmsg ("Value not set");
14889       return -99;
14890     }
14891
14892   /* Construct the API message */
14893   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14894
14895   mp->is_enabled = is_en;
14896
14897   /* send it... */
14898   S (mp);
14899
14900   /* Wait for a reply... */
14901   W (ret);
14902   return ret;
14903 }
14904
14905 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14906
14907 static int
14908 api_one_enable_disable (vat_main_t * vam)
14909 {
14910   unformat_input_t *input = vam->input;
14911   vl_api_one_enable_disable_t *mp;
14912   u8 is_set = 0;
14913   u8 is_en = 0;
14914   int ret;
14915
14916   /* Parse args required to build the message */
14917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14918     {
14919       if (unformat (input, "enable"))
14920         {
14921           is_set = 1;
14922           is_en = 1;
14923         }
14924       else if (unformat (input, "disable"))
14925         {
14926           is_set = 1;
14927         }
14928       else
14929         break;
14930     }
14931
14932   if (!is_set)
14933     {
14934       errmsg ("Value not set");
14935       return -99;
14936     }
14937
14938   /* Construct the API message */
14939   M (ONE_ENABLE_DISABLE, mp);
14940
14941   mp->is_en = is_en;
14942
14943   /* send it... */
14944   S (mp);
14945
14946   /* Wait for a reply... */
14947   W (ret);
14948   return ret;
14949 }
14950
14951 #define api_lisp_enable_disable api_one_enable_disable
14952
14953 static int
14954 api_show_one_map_register_state (vat_main_t * vam)
14955 {
14956   vl_api_show_one_map_register_state_t *mp;
14957   int ret;
14958
14959   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14960
14961   /* send */
14962   S (mp);
14963
14964   /* wait for reply */
14965   W (ret);
14966   return ret;
14967 }
14968
14969 #define api_show_lisp_map_register_state api_show_one_map_register_state
14970
14971 static int
14972 api_show_one_rloc_probe_state (vat_main_t * vam)
14973 {
14974   vl_api_show_one_rloc_probe_state_t *mp;
14975   int ret;
14976
14977   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14978
14979   /* send */
14980   S (mp);
14981
14982   /* wait for reply */
14983   W (ret);
14984   return ret;
14985 }
14986
14987 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14988
14989 static int
14990 api_one_add_del_l2_arp_entry (vat_main_t * vam)
14991 {
14992   vl_api_one_add_del_l2_arp_entry_t *mp;
14993   unformat_input_t *input = vam->input;
14994   u8 is_add = 1;
14995   u8 mac_set = 0;
14996   u8 bd_set = 0;
14997   u8 ip_set = 0;
14998   u8 mac[6] = { 0, };
14999   u32 ip4 = 0, bd = ~0;
15000   int ret;
15001
15002   /* Parse args required to build the message */
15003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15004     {
15005       if (unformat (input, "del"))
15006         is_add = 0;
15007       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15008         mac_set = 1;
15009       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15010         ip_set = 1;
15011       else if (unformat (input, "bd %d", &bd))
15012         bd_set = 1;
15013       else
15014         {
15015           errmsg ("parse error '%U'", format_unformat_error, input);
15016           return -99;
15017         }
15018     }
15019
15020   if (!bd_set || !ip_set || (!mac_set && is_add))
15021     {
15022       errmsg ("Missing BD, IP or MAC!");
15023       return -99;
15024     }
15025
15026   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15027   mp->is_add = is_add;
15028   clib_memcpy (mp->mac, mac, 6);
15029   mp->bd = clib_host_to_net_u32 (bd);
15030   mp->ip4 = ip4;
15031
15032   /* send */
15033   S (mp);
15034
15035   /* wait for reply */
15036   W (ret);
15037   return ret;
15038 }
15039
15040 static int
15041 api_one_l2_arp_bd_get (vat_main_t * vam)
15042 {
15043   vl_api_one_l2_arp_bd_get_t *mp;
15044   int ret;
15045
15046   M (ONE_L2_ARP_BD_GET, mp);
15047
15048   /* send */
15049   S (mp);
15050
15051   /* wait for reply */
15052   W (ret);
15053   return ret;
15054 }
15055
15056 static int
15057 api_one_l2_arp_entries_get (vat_main_t * vam)
15058 {
15059   vl_api_one_l2_arp_entries_get_t *mp;
15060   unformat_input_t *input = vam->input;
15061   u8 bd_set = 0;
15062   u32 bd = ~0;
15063   int ret;
15064
15065   /* Parse args required to build the message */
15066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15067     {
15068       if (unformat (input, "bd %d", &bd))
15069         bd_set = 1;
15070       else
15071         {
15072           errmsg ("parse error '%U'", format_unformat_error, input);
15073           return -99;
15074         }
15075     }
15076
15077   if (!bd_set)
15078     {
15079       errmsg ("Expected bridge domain!");
15080       return -99;
15081     }
15082
15083   M (ONE_L2_ARP_ENTRIES_GET, mp);
15084   mp->bd = clib_host_to_net_u32 (bd);
15085
15086   /* send */
15087   S (mp);
15088
15089   /* wait for reply */
15090   W (ret);
15091   return ret;
15092 }
15093
15094 static int
15095 api_one_stats_enable_disable (vat_main_t * vam)
15096 {
15097   vl_api_one_stats_enable_disable_t *mp;
15098   unformat_input_t *input = vam->input;
15099   u8 is_set = 0;
15100   u8 is_en = 0;
15101   int ret;
15102
15103   /* Parse args required to build the message */
15104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15105     {
15106       if (unformat (input, "enable"))
15107         {
15108           is_set = 1;
15109           is_en = 1;
15110         }
15111       else if (unformat (input, "disable"))
15112         {
15113           is_set = 1;
15114         }
15115       else
15116         break;
15117     }
15118
15119   if (!is_set)
15120     {
15121       errmsg ("Value not set");
15122       return -99;
15123     }
15124
15125   M (ONE_STATS_ENABLE_DISABLE, mp);
15126   mp->is_en = is_en;
15127
15128   /* send */
15129   S (mp);
15130
15131   /* wait for reply */
15132   W (ret);
15133   return ret;
15134 }
15135
15136 static int
15137 api_show_one_stats_enable_disable (vat_main_t * vam)
15138 {
15139   vl_api_show_one_stats_enable_disable_t *mp;
15140   int ret;
15141
15142   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15143
15144   /* send */
15145   S (mp);
15146
15147   /* wait for reply */
15148   W (ret);
15149   return ret;
15150 }
15151
15152 static int
15153 api_show_one_map_request_mode (vat_main_t * vam)
15154 {
15155   vl_api_show_one_map_request_mode_t *mp;
15156   int ret;
15157
15158   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15159
15160   /* send */
15161   S (mp);
15162
15163   /* wait for reply */
15164   W (ret);
15165   return ret;
15166 }
15167
15168 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15169
15170 static int
15171 api_one_map_request_mode (vat_main_t * vam)
15172 {
15173   unformat_input_t *input = vam->input;
15174   vl_api_one_map_request_mode_t *mp;
15175   u8 mode = 0;
15176   int ret;
15177
15178   /* Parse args required to build the message */
15179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15180     {
15181       if (unformat (input, "dst-only"))
15182         mode = 0;
15183       else if (unformat (input, "src-dst"))
15184         mode = 1;
15185       else
15186         {
15187           errmsg ("parse error '%U'", format_unformat_error, input);
15188           return -99;
15189         }
15190     }
15191
15192   M (ONE_MAP_REQUEST_MODE, mp);
15193
15194   mp->mode = mode;
15195
15196   /* send */
15197   S (mp);
15198
15199   /* wait for reply */
15200   W (ret);
15201   return ret;
15202 }
15203
15204 #define api_lisp_map_request_mode api_one_map_request_mode
15205
15206 /**
15207  * Enable/disable ONE proxy ITR.
15208  *
15209  * @param vam vpp API test context
15210  * @return return code
15211  */
15212 static int
15213 api_one_pitr_set_locator_set (vat_main_t * vam)
15214 {
15215   u8 ls_name_set = 0;
15216   unformat_input_t *input = vam->input;
15217   vl_api_one_pitr_set_locator_set_t *mp;
15218   u8 is_add = 1;
15219   u8 *ls_name = 0;
15220   int ret;
15221
15222   /* Parse args required to build the message */
15223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15224     {
15225       if (unformat (input, "del"))
15226         is_add = 0;
15227       else if (unformat (input, "locator-set %s", &ls_name))
15228         ls_name_set = 1;
15229       else
15230         {
15231           errmsg ("parse error '%U'", format_unformat_error, input);
15232           return -99;
15233         }
15234     }
15235
15236   if (!ls_name_set)
15237     {
15238       errmsg ("locator-set name not set!");
15239       return -99;
15240     }
15241
15242   M (ONE_PITR_SET_LOCATOR_SET, mp);
15243
15244   mp->is_add = is_add;
15245   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15246   vec_free (ls_name);
15247
15248   /* send */
15249   S (mp);
15250
15251   /* wait for reply */
15252   W (ret);
15253   return ret;
15254 }
15255
15256 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15257
15258 static int
15259 api_one_nsh_set_locator_set (vat_main_t * vam)
15260 {
15261   u8 ls_name_set = 0;
15262   unformat_input_t *input = vam->input;
15263   vl_api_one_nsh_set_locator_set_t *mp;
15264   u8 is_add = 1;
15265   u8 *ls_name = 0;
15266   int ret;
15267
15268   /* Parse args required to build the message */
15269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15270     {
15271       if (unformat (input, "del"))
15272         is_add = 0;
15273       else if (unformat (input, "ls %s", &ls_name))
15274         ls_name_set = 1;
15275       else
15276         {
15277           errmsg ("parse error '%U'", format_unformat_error, input);
15278           return -99;
15279         }
15280     }
15281
15282   if (!ls_name_set && is_add)
15283     {
15284       errmsg ("locator-set name not set!");
15285       return -99;
15286     }
15287
15288   M (ONE_NSH_SET_LOCATOR_SET, mp);
15289
15290   mp->is_add = is_add;
15291   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15292   vec_free (ls_name);
15293
15294   /* send */
15295   S (mp);
15296
15297   /* wait for reply */
15298   W (ret);
15299   return ret;
15300 }
15301
15302 static int
15303 api_show_one_pitr (vat_main_t * vam)
15304 {
15305   vl_api_show_one_pitr_t *mp;
15306   int ret;
15307
15308   if (!vam->json_output)
15309     {
15310       print (vam->ofp, "%=20s", "lisp status:");
15311     }
15312
15313   M (SHOW_ONE_PITR, mp);
15314   /* send it... */
15315   S (mp);
15316
15317   /* Wait for a reply... */
15318   W (ret);
15319   return ret;
15320 }
15321
15322 #define api_show_lisp_pitr api_show_one_pitr
15323
15324 static int
15325 api_one_use_petr (vat_main_t * vam)
15326 {
15327   unformat_input_t *input = vam->input;
15328   vl_api_one_use_petr_t *mp;
15329   u8 is_add = 0;
15330   ip_address_t ip;
15331   int ret;
15332
15333   memset (&ip, 0, sizeof (ip));
15334
15335   /* Parse args required to build the message */
15336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15337     {
15338       if (unformat (input, "disable"))
15339         is_add = 0;
15340       else
15341         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15342         {
15343           is_add = 1;
15344           ip_addr_version (&ip) = IP4;
15345         }
15346       else
15347         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15348         {
15349           is_add = 1;
15350           ip_addr_version (&ip) = IP6;
15351         }
15352       else
15353         {
15354           errmsg ("parse error '%U'", format_unformat_error, input);
15355           return -99;
15356         }
15357     }
15358
15359   M (ONE_USE_PETR, mp);
15360
15361   mp->is_add = is_add;
15362   if (is_add)
15363     {
15364       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15365       if (mp->is_ip4)
15366         clib_memcpy (mp->address, &ip, 4);
15367       else
15368         clib_memcpy (mp->address, &ip, 16);
15369     }
15370
15371   /* send */
15372   S (mp);
15373
15374   /* wait for reply */
15375   W (ret);
15376   return ret;
15377 }
15378
15379 #define api_lisp_use_petr api_one_use_petr
15380
15381 static int
15382 api_show_one_nsh_mapping (vat_main_t * vam)
15383 {
15384   vl_api_show_one_use_petr_t *mp;
15385   int ret;
15386
15387   if (!vam->json_output)
15388     {
15389       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15390     }
15391
15392   M (SHOW_ONE_NSH_MAPPING, mp);
15393   /* send it... */
15394   S (mp);
15395
15396   /* Wait for a reply... */
15397   W (ret);
15398   return ret;
15399 }
15400
15401 static int
15402 api_show_one_use_petr (vat_main_t * vam)
15403 {
15404   vl_api_show_one_use_petr_t *mp;
15405   int ret;
15406
15407   if (!vam->json_output)
15408     {
15409       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15410     }
15411
15412   M (SHOW_ONE_USE_PETR, mp);
15413   /* send it... */
15414   S (mp);
15415
15416   /* Wait for a reply... */
15417   W (ret);
15418   return ret;
15419 }
15420
15421 #define api_show_lisp_use_petr api_show_one_use_petr
15422
15423 /**
15424  * Add/delete mapping between vni and vrf
15425  */
15426 static int
15427 api_one_eid_table_add_del_map (vat_main_t * vam)
15428 {
15429   unformat_input_t *input = vam->input;
15430   vl_api_one_eid_table_add_del_map_t *mp;
15431   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15432   u32 vni, vrf, bd_index;
15433   int ret;
15434
15435   /* Parse args required to build the message */
15436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15437     {
15438       if (unformat (input, "del"))
15439         is_add = 0;
15440       else if (unformat (input, "vrf %d", &vrf))
15441         vrf_set = 1;
15442       else if (unformat (input, "bd_index %d", &bd_index))
15443         bd_index_set = 1;
15444       else if (unformat (input, "vni %d", &vni))
15445         vni_set = 1;
15446       else
15447         break;
15448     }
15449
15450   if (!vni_set || (!vrf_set && !bd_index_set))
15451     {
15452       errmsg ("missing arguments!");
15453       return -99;
15454     }
15455
15456   if (vrf_set && bd_index_set)
15457     {
15458       errmsg ("error: both vrf and bd entered!");
15459       return -99;
15460     }
15461
15462   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15463
15464   mp->is_add = is_add;
15465   mp->vni = htonl (vni);
15466   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15467   mp->is_l2 = bd_index_set;
15468
15469   /* send */
15470   S (mp);
15471
15472   /* wait for reply */
15473   W (ret);
15474   return ret;
15475 }
15476
15477 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15478
15479 uword
15480 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15481 {
15482   u32 *action = va_arg (*args, u32 *);
15483   u8 *s = 0;
15484
15485   if (unformat (input, "%s", &s))
15486     {
15487       if (!strcmp ((char *) s, "no-action"))
15488         action[0] = 0;
15489       else if (!strcmp ((char *) s, "natively-forward"))
15490         action[0] = 1;
15491       else if (!strcmp ((char *) s, "send-map-request"))
15492         action[0] = 2;
15493       else if (!strcmp ((char *) s, "drop"))
15494         action[0] = 3;
15495       else
15496         {
15497           clib_warning ("invalid action: '%s'", s);
15498           action[0] = 3;
15499         }
15500     }
15501   else
15502     return 0;
15503
15504   vec_free (s);
15505   return 1;
15506 }
15507
15508 /**
15509  * Add/del remote mapping to/from ONE control plane
15510  *
15511  * @param vam vpp API test context
15512  * @return return code
15513  */
15514 static int
15515 api_one_add_del_remote_mapping (vat_main_t * vam)
15516 {
15517   unformat_input_t *input = vam->input;
15518   vl_api_one_add_del_remote_mapping_t *mp;
15519   u32 vni = 0;
15520   lisp_eid_vat_t _eid, *eid = &_eid;
15521   lisp_eid_vat_t _seid, *seid = &_seid;
15522   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15523   u32 action = ~0, p, w, data_len;
15524   ip4_address_t rloc4;
15525   ip6_address_t rloc6;
15526   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15527   int ret;
15528
15529   memset (&rloc, 0, sizeof (rloc));
15530
15531   /* Parse args required to build the message */
15532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15533     {
15534       if (unformat (input, "del-all"))
15535         {
15536           del_all = 1;
15537         }
15538       else if (unformat (input, "del"))
15539         {
15540           is_add = 0;
15541         }
15542       else if (unformat (input, "add"))
15543         {
15544           is_add = 1;
15545         }
15546       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15547         {
15548           eid_set = 1;
15549         }
15550       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15551         {
15552           seid_set = 1;
15553         }
15554       else if (unformat (input, "vni %d", &vni))
15555         {
15556           ;
15557         }
15558       else if (unformat (input, "p %d w %d", &p, &w))
15559         {
15560           if (!curr_rloc)
15561             {
15562               errmsg ("No RLOC configured for setting priority/weight!");
15563               return -99;
15564             }
15565           curr_rloc->priority = p;
15566           curr_rloc->weight = w;
15567         }
15568       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15569         {
15570           rloc.is_ip4 = 1;
15571           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15572           vec_add1 (rlocs, rloc);
15573           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15574         }
15575       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15576         {
15577           rloc.is_ip4 = 0;
15578           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15579           vec_add1 (rlocs, rloc);
15580           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15581         }
15582       else if (unformat (input, "action %U",
15583                          unformat_negative_mapping_action, &action))
15584         {
15585           ;
15586         }
15587       else
15588         {
15589           clib_warning ("parse error '%U'", format_unformat_error, input);
15590           return -99;
15591         }
15592     }
15593
15594   if (0 == eid_set)
15595     {
15596       errmsg ("missing params!");
15597       return -99;
15598     }
15599
15600   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15601     {
15602       errmsg ("no action set for negative map-reply!");
15603       return -99;
15604     }
15605
15606   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15607
15608   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15609   mp->is_add = is_add;
15610   mp->vni = htonl (vni);
15611   mp->action = (u8) action;
15612   mp->is_src_dst = seid_set;
15613   mp->eid_len = eid->len;
15614   mp->seid_len = seid->len;
15615   mp->del_all = del_all;
15616   mp->eid_type = eid->type;
15617   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15618   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15619
15620   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15621   clib_memcpy (mp->rlocs, rlocs, data_len);
15622   vec_free (rlocs);
15623
15624   /* send it... */
15625   S (mp);
15626
15627   /* Wait for a reply... */
15628   W (ret);
15629   return ret;
15630 }
15631
15632 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15633
15634 /**
15635  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15636  * forwarding entries in data-plane accordingly.
15637  *
15638  * @param vam vpp API test context
15639  * @return return code
15640  */
15641 static int
15642 api_one_add_del_adjacency (vat_main_t * vam)
15643 {
15644   unformat_input_t *input = vam->input;
15645   vl_api_one_add_del_adjacency_t *mp;
15646   u32 vni = 0;
15647   ip4_address_t leid4, reid4;
15648   ip6_address_t leid6, reid6;
15649   u8 reid_mac[6] = { 0 };
15650   u8 leid_mac[6] = { 0 };
15651   u8 reid_type, leid_type;
15652   u32 leid_len = 0, reid_len = 0, len;
15653   u8 is_add = 1;
15654   int ret;
15655
15656   leid_type = reid_type = (u8) ~ 0;
15657
15658   /* Parse args required to build the message */
15659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15660     {
15661       if (unformat (input, "del"))
15662         {
15663           is_add = 0;
15664         }
15665       else if (unformat (input, "add"))
15666         {
15667           is_add = 1;
15668         }
15669       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15670                          &reid4, &len))
15671         {
15672           reid_type = 0;        /* ipv4 */
15673           reid_len = len;
15674         }
15675       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15676                          &reid6, &len))
15677         {
15678           reid_type = 1;        /* ipv6 */
15679           reid_len = len;
15680         }
15681       else if (unformat (input, "reid %U", unformat_ethernet_address,
15682                          reid_mac))
15683         {
15684           reid_type = 2;        /* mac */
15685         }
15686       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15687                          &leid4, &len))
15688         {
15689           leid_type = 0;        /* ipv4 */
15690           leid_len = len;
15691         }
15692       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15693                          &leid6, &len))
15694         {
15695           leid_type = 1;        /* ipv6 */
15696           leid_len = len;
15697         }
15698       else if (unformat (input, "leid %U", unformat_ethernet_address,
15699                          leid_mac))
15700         {
15701           leid_type = 2;        /* mac */
15702         }
15703       else if (unformat (input, "vni %d", &vni))
15704         {
15705           ;
15706         }
15707       else
15708         {
15709           errmsg ("parse error '%U'", format_unformat_error, input);
15710           return -99;
15711         }
15712     }
15713
15714   if ((u8) ~ 0 == reid_type)
15715     {
15716       errmsg ("missing params!");
15717       return -99;
15718     }
15719
15720   if (leid_type != reid_type)
15721     {
15722       errmsg ("remote and local EIDs are of different types!");
15723       return -99;
15724     }
15725
15726   M (ONE_ADD_DEL_ADJACENCY, mp);
15727   mp->is_add = is_add;
15728   mp->vni = htonl (vni);
15729   mp->leid_len = leid_len;
15730   mp->reid_len = reid_len;
15731   mp->eid_type = reid_type;
15732
15733   switch (mp->eid_type)
15734     {
15735     case 0:
15736       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15737       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15738       break;
15739     case 1:
15740       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15741       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15742       break;
15743     case 2:
15744       clib_memcpy (mp->leid, leid_mac, 6);
15745       clib_memcpy (mp->reid, reid_mac, 6);
15746       break;
15747     default:
15748       errmsg ("unknown EID type %d!", mp->eid_type);
15749       return 0;
15750     }
15751
15752   /* send it... */
15753   S (mp);
15754
15755   /* Wait for a reply... */
15756   W (ret);
15757   return ret;
15758 }
15759
15760 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15761
15762 uword
15763 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15764 {
15765   u32 *mode = va_arg (*args, u32 *);
15766
15767   if (unformat (input, "lisp"))
15768     *mode = 0;
15769   else if (unformat (input, "vxlan"))
15770     *mode = 1;
15771   else
15772     return 0;
15773
15774   return 1;
15775 }
15776
15777 static int
15778 api_gpe_get_encap_mode (vat_main_t * vam)
15779 {
15780   vl_api_gpe_get_encap_mode_t *mp;
15781   int ret;
15782
15783   /* Construct the API message */
15784   M (GPE_GET_ENCAP_MODE, mp);
15785
15786   /* send it... */
15787   S (mp);
15788
15789   /* Wait for a reply... */
15790   W (ret);
15791   return ret;
15792 }
15793
15794 static int
15795 api_gpe_set_encap_mode (vat_main_t * vam)
15796 {
15797   unformat_input_t *input = vam->input;
15798   vl_api_gpe_set_encap_mode_t *mp;
15799   int ret;
15800   u32 mode = 0;
15801
15802   /* Parse args required to build the message */
15803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15804     {
15805       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15806         ;
15807       else
15808         break;
15809     }
15810
15811   /* Construct the API message */
15812   M (GPE_SET_ENCAP_MODE, mp);
15813
15814   mp->mode = mode;
15815
15816   /* send it... */
15817   S (mp);
15818
15819   /* Wait for a reply... */
15820   W (ret);
15821   return ret;
15822 }
15823
15824 static int
15825 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15826 {
15827   unformat_input_t *input = vam->input;
15828   vl_api_gpe_add_del_iface_t *mp;
15829   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15830   u32 dp_table = 0, vni = 0;
15831   int ret;
15832
15833   /* Parse args required to build the message */
15834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15835     {
15836       if (unformat (input, "up"))
15837         {
15838           action_set = 1;
15839           is_add = 1;
15840         }
15841       else if (unformat (input, "down"))
15842         {
15843           action_set = 1;
15844           is_add = 0;
15845         }
15846       else if (unformat (input, "table_id %d", &dp_table))
15847         {
15848           dp_table_set = 1;
15849         }
15850       else if (unformat (input, "bd_id %d", &dp_table))
15851         {
15852           dp_table_set = 1;
15853           is_l2 = 1;
15854         }
15855       else if (unformat (input, "vni %d", &vni))
15856         {
15857           vni_set = 1;
15858         }
15859       else
15860         break;
15861     }
15862
15863   if (action_set == 0)
15864     {
15865       errmsg ("Action not set");
15866       return -99;
15867     }
15868   if (dp_table_set == 0 || vni_set == 0)
15869     {
15870       errmsg ("vni and dp_table must be set");
15871       return -99;
15872     }
15873
15874   /* Construct the API message */
15875   M (GPE_ADD_DEL_IFACE, mp);
15876
15877   mp->is_add = is_add;
15878   mp->dp_table = dp_table;
15879   mp->is_l2 = is_l2;
15880   mp->vni = vni;
15881
15882   /* send it... */
15883   S (mp);
15884
15885   /* Wait for a reply... */
15886   W (ret);
15887   return ret;
15888 }
15889
15890 /**
15891  * Add/del map request itr rlocs from ONE control plane and updates
15892  *
15893  * @param vam vpp API test context
15894  * @return return code
15895  */
15896 static int
15897 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15898 {
15899   unformat_input_t *input = vam->input;
15900   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15901   u8 *locator_set_name = 0;
15902   u8 locator_set_name_set = 0;
15903   u8 is_add = 1;
15904   int ret;
15905
15906   /* Parse args required to build the message */
15907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15908     {
15909       if (unformat (input, "del"))
15910         {
15911           is_add = 0;
15912         }
15913       else if (unformat (input, "%_%v%_", &locator_set_name))
15914         {
15915           locator_set_name_set = 1;
15916         }
15917       else
15918         {
15919           clib_warning ("parse error '%U'", format_unformat_error, input);
15920           return -99;
15921         }
15922     }
15923
15924   if (is_add && !locator_set_name_set)
15925     {
15926       errmsg ("itr-rloc is not set!");
15927       return -99;
15928     }
15929
15930   if (is_add && vec_len (locator_set_name) > 64)
15931     {
15932       errmsg ("itr-rloc locator-set name too long");
15933       vec_free (locator_set_name);
15934       return -99;
15935     }
15936
15937   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15938   mp->is_add = is_add;
15939   if (is_add)
15940     {
15941       clib_memcpy (mp->locator_set_name, locator_set_name,
15942                    vec_len (locator_set_name));
15943     }
15944   else
15945     {
15946       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15947     }
15948   vec_free (locator_set_name);
15949
15950   /* send it... */
15951   S (mp);
15952
15953   /* Wait for a reply... */
15954   W (ret);
15955   return ret;
15956 }
15957
15958 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15959
15960 static int
15961 api_one_locator_dump (vat_main_t * vam)
15962 {
15963   unformat_input_t *input = vam->input;
15964   vl_api_one_locator_dump_t *mp;
15965   vl_api_control_ping_t *mp_ping;
15966   u8 is_index_set = 0, is_name_set = 0;
15967   u8 *ls_name = 0;
15968   u32 ls_index = ~0;
15969   int ret;
15970
15971   /* Parse args required to build the message */
15972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15973     {
15974       if (unformat (input, "ls_name %_%v%_", &ls_name))
15975         {
15976           is_name_set = 1;
15977         }
15978       else if (unformat (input, "ls_index %d", &ls_index))
15979         {
15980           is_index_set = 1;
15981         }
15982       else
15983         {
15984           errmsg ("parse error '%U'", format_unformat_error, input);
15985           return -99;
15986         }
15987     }
15988
15989   if (!is_index_set && !is_name_set)
15990     {
15991       errmsg ("error: expected one of index or name!");
15992       return -99;
15993     }
15994
15995   if (is_index_set && is_name_set)
15996     {
15997       errmsg ("error: only one param expected!");
15998       return -99;
15999     }
16000
16001   if (vec_len (ls_name) > 62)
16002     {
16003       errmsg ("error: locator set name too long!");
16004       return -99;
16005     }
16006
16007   if (!vam->json_output)
16008     {
16009       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16010     }
16011
16012   M (ONE_LOCATOR_DUMP, mp);
16013   mp->is_index_set = is_index_set;
16014
16015   if (is_index_set)
16016     mp->ls_index = clib_host_to_net_u32 (ls_index);
16017   else
16018     {
16019       vec_add1 (ls_name, 0);
16020       strncpy ((char *) mp->ls_name, (char *) ls_name,
16021                sizeof (mp->ls_name) - 1);
16022     }
16023
16024   /* send it... */
16025   S (mp);
16026
16027   /* Use a control ping for synchronization */
16028   M (CONTROL_PING, mp_ping);
16029   S (mp_ping);
16030
16031   /* Wait for a reply... */
16032   W (ret);
16033   return ret;
16034 }
16035
16036 #define api_lisp_locator_dump api_one_locator_dump
16037
16038 static int
16039 api_one_locator_set_dump (vat_main_t * vam)
16040 {
16041   vl_api_one_locator_set_dump_t *mp;
16042   vl_api_control_ping_t *mp_ping;
16043   unformat_input_t *input = vam->input;
16044   u8 filter = 0;
16045   int ret;
16046
16047   /* Parse args required to build the message */
16048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16049     {
16050       if (unformat (input, "local"))
16051         {
16052           filter = 1;
16053         }
16054       else if (unformat (input, "remote"))
16055         {
16056           filter = 2;
16057         }
16058       else
16059         {
16060           errmsg ("parse error '%U'", format_unformat_error, input);
16061           return -99;
16062         }
16063     }
16064
16065   if (!vam->json_output)
16066     {
16067       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16068     }
16069
16070   M (ONE_LOCATOR_SET_DUMP, mp);
16071
16072   mp->filter = filter;
16073
16074   /* send it... */
16075   S (mp);
16076
16077   /* Use a control ping for synchronization */
16078   M (CONTROL_PING, mp_ping);
16079   S (mp_ping);
16080
16081   /* Wait for a reply... */
16082   W (ret);
16083   return ret;
16084 }
16085
16086 #define api_lisp_locator_set_dump api_one_locator_set_dump
16087
16088 static int
16089 api_one_eid_table_map_dump (vat_main_t * vam)
16090 {
16091   u8 is_l2 = 0;
16092   u8 mode_set = 0;
16093   unformat_input_t *input = vam->input;
16094   vl_api_one_eid_table_map_dump_t *mp;
16095   vl_api_control_ping_t *mp_ping;
16096   int ret;
16097
16098   /* Parse args required to build the message */
16099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16100     {
16101       if (unformat (input, "l2"))
16102         {
16103           is_l2 = 1;
16104           mode_set = 1;
16105         }
16106       else if (unformat (input, "l3"))
16107         {
16108           is_l2 = 0;
16109           mode_set = 1;
16110         }
16111       else
16112         {
16113           errmsg ("parse error '%U'", format_unformat_error, input);
16114           return -99;
16115         }
16116     }
16117
16118   if (!mode_set)
16119     {
16120       errmsg ("expected one of 'l2' or 'l3' parameter!");
16121       return -99;
16122     }
16123
16124   if (!vam->json_output)
16125     {
16126       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16127     }
16128
16129   M (ONE_EID_TABLE_MAP_DUMP, mp);
16130   mp->is_l2 = is_l2;
16131
16132   /* send it... */
16133   S (mp);
16134
16135   /* Use a control ping for synchronization */
16136   M (CONTROL_PING, mp_ping);
16137   S (mp_ping);
16138
16139   /* Wait for a reply... */
16140   W (ret);
16141   return ret;
16142 }
16143
16144 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16145
16146 static int
16147 api_one_eid_table_vni_dump (vat_main_t * vam)
16148 {
16149   vl_api_one_eid_table_vni_dump_t *mp;
16150   vl_api_control_ping_t *mp_ping;
16151   int ret;
16152
16153   if (!vam->json_output)
16154     {
16155       print (vam->ofp, "VNI");
16156     }
16157
16158   M (ONE_EID_TABLE_VNI_DUMP, mp);
16159
16160   /* send it... */
16161   S (mp);
16162
16163   /* Use a control ping for synchronization */
16164   M (CONTROL_PING, mp_ping);
16165   S (mp_ping);
16166
16167   /* Wait for a reply... */
16168   W (ret);
16169   return ret;
16170 }
16171
16172 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16173
16174 static int
16175 api_one_eid_table_dump (vat_main_t * vam)
16176 {
16177   unformat_input_t *i = vam->input;
16178   vl_api_one_eid_table_dump_t *mp;
16179   vl_api_control_ping_t *mp_ping;
16180   struct in_addr ip4;
16181   struct in6_addr ip6;
16182   u8 mac[6];
16183   u8 eid_type = ~0, eid_set = 0;
16184   u32 prefix_length = ~0, t, vni = 0;
16185   u8 filter = 0;
16186   int ret;
16187   lisp_nsh_api_t nsh;
16188
16189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16190     {
16191       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16192         {
16193           eid_set = 1;
16194           eid_type = 0;
16195           prefix_length = t;
16196         }
16197       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16198         {
16199           eid_set = 1;
16200           eid_type = 1;
16201           prefix_length = t;
16202         }
16203       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16204         {
16205           eid_set = 1;
16206           eid_type = 2;
16207         }
16208       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16209         {
16210           eid_set = 1;
16211           eid_type = 3;
16212         }
16213       else if (unformat (i, "vni %d", &t))
16214         {
16215           vni = t;
16216         }
16217       else if (unformat (i, "local"))
16218         {
16219           filter = 1;
16220         }
16221       else if (unformat (i, "remote"))
16222         {
16223           filter = 2;
16224         }
16225       else
16226         {
16227           errmsg ("parse error '%U'", format_unformat_error, i);
16228           return -99;
16229         }
16230     }
16231
16232   if (!vam->json_output)
16233     {
16234       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16235              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16236     }
16237
16238   M (ONE_EID_TABLE_DUMP, mp);
16239
16240   mp->filter = filter;
16241   if (eid_set)
16242     {
16243       mp->eid_set = 1;
16244       mp->vni = htonl (vni);
16245       mp->eid_type = eid_type;
16246       switch (eid_type)
16247         {
16248         case 0:
16249           mp->prefix_length = prefix_length;
16250           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16251           break;
16252         case 1:
16253           mp->prefix_length = prefix_length;
16254           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16255           break;
16256         case 2:
16257           clib_memcpy (mp->eid, mac, sizeof (mac));
16258           break;
16259         case 3:
16260           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16261           break;
16262         default:
16263           errmsg ("unknown EID type %d!", eid_type);
16264           return -99;
16265         }
16266     }
16267
16268   /* send it... */
16269   S (mp);
16270
16271   /* Use a control ping for synchronization */
16272   M (CONTROL_PING, mp_ping);
16273   S (mp_ping);
16274
16275   /* Wait for a reply... */
16276   W (ret);
16277   return ret;
16278 }
16279
16280 #define api_lisp_eid_table_dump api_one_eid_table_dump
16281
16282 static int
16283 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16284 {
16285   unformat_input_t *i = vam->input;
16286   vl_api_gpe_fwd_entries_get_t *mp;
16287   u8 vni_set = 0;
16288   u32 vni = ~0;
16289   int ret;
16290
16291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16292     {
16293       if (unformat (i, "vni %d", &vni))
16294         {
16295           vni_set = 1;
16296         }
16297       else
16298         {
16299           errmsg ("parse error '%U'", format_unformat_error, i);
16300           return -99;
16301         }
16302     }
16303
16304   if (!vni_set)
16305     {
16306       errmsg ("vni not set!");
16307       return -99;
16308     }
16309
16310   if (!vam->json_output)
16311     {
16312       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16313              "leid", "reid");
16314     }
16315
16316   M (GPE_FWD_ENTRIES_GET, mp);
16317   mp->vni = clib_host_to_net_u32 (vni);
16318
16319   /* send it... */
16320   S (mp);
16321
16322   /* Wait for a reply... */
16323   W (ret);
16324   return ret;
16325 }
16326
16327 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16328 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16329 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16330 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16331 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16332 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16333
16334 static int
16335 api_one_adjacencies_get (vat_main_t * vam)
16336 {
16337   unformat_input_t *i = vam->input;
16338   vl_api_one_adjacencies_get_t *mp;
16339   u8 vni_set = 0;
16340   u32 vni = ~0;
16341   int ret;
16342
16343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16344     {
16345       if (unformat (i, "vni %d", &vni))
16346         {
16347           vni_set = 1;
16348         }
16349       else
16350         {
16351           errmsg ("parse error '%U'", format_unformat_error, i);
16352           return -99;
16353         }
16354     }
16355
16356   if (!vni_set)
16357     {
16358       errmsg ("vni not set!");
16359       return -99;
16360     }
16361
16362   if (!vam->json_output)
16363     {
16364       print (vam->ofp, "%s %40s", "leid", "reid");
16365     }
16366
16367   M (ONE_ADJACENCIES_GET, mp);
16368   mp->vni = clib_host_to_net_u32 (vni);
16369
16370   /* send it... */
16371   S (mp);
16372
16373   /* Wait for a reply... */
16374   W (ret);
16375   return ret;
16376 }
16377
16378 #define api_lisp_adjacencies_get api_one_adjacencies_get
16379
16380 static int
16381 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16382 {
16383   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16384   int ret;
16385
16386   if (!vam->json_output)
16387     {
16388       print (vam->ofp, "VNIs");
16389     }
16390
16391   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16392
16393   /* send it... */
16394   S (mp);
16395
16396   /* Wait for a reply... */
16397   W (ret);
16398   return ret;
16399 }
16400
16401 static int
16402 api_one_map_server_dump (vat_main_t * vam)
16403 {
16404   vl_api_one_map_server_dump_t *mp;
16405   vl_api_control_ping_t *mp_ping;
16406   int ret;
16407
16408   if (!vam->json_output)
16409     {
16410       print (vam->ofp, "%=20s", "Map server");
16411     }
16412
16413   M (ONE_MAP_SERVER_DUMP, mp);
16414   /* send it... */
16415   S (mp);
16416
16417   /* Use a control ping for synchronization */
16418   M (CONTROL_PING, mp_ping);
16419   S (mp_ping);
16420
16421   /* Wait for a reply... */
16422   W (ret);
16423   return ret;
16424 }
16425
16426 #define api_lisp_map_server_dump api_one_map_server_dump
16427
16428 static int
16429 api_one_map_resolver_dump (vat_main_t * vam)
16430 {
16431   vl_api_one_map_resolver_dump_t *mp;
16432   vl_api_control_ping_t *mp_ping;
16433   int ret;
16434
16435   if (!vam->json_output)
16436     {
16437       print (vam->ofp, "%=20s", "Map resolver");
16438     }
16439
16440   M (ONE_MAP_RESOLVER_DUMP, mp);
16441   /* send it... */
16442   S (mp);
16443
16444   /* Use a control ping for synchronization */
16445   M (CONTROL_PING, mp_ping);
16446   S (mp_ping);
16447
16448   /* Wait for a reply... */
16449   W (ret);
16450   return ret;
16451 }
16452
16453 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16454
16455 static int
16456 api_one_stats_flush (vat_main_t * vam)
16457 {
16458   vl_api_one_stats_flush_t *mp;
16459   int ret = 0;
16460
16461   M (ONE_STATS_FLUSH, mp);
16462   S (mp);
16463   W (ret);
16464   return ret;
16465 }
16466
16467 static int
16468 api_one_stats_dump (vat_main_t * vam)
16469 {
16470   vl_api_one_stats_dump_t *mp;
16471   vl_api_control_ping_t *mp_ping;
16472   int ret;
16473
16474   M (ONE_STATS_DUMP, mp);
16475   /* send it... */
16476   S (mp);
16477
16478   /* Use a control ping for synchronization */
16479   M (CONTROL_PING, mp_ping);
16480   S (mp_ping);
16481
16482   /* Wait for a reply... */
16483   W (ret);
16484   return ret;
16485 }
16486
16487 static int
16488 api_show_one_status (vat_main_t * vam)
16489 {
16490   vl_api_show_one_status_t *mp;
16491   int ret;
16492
16493   if (!vam->json_output)
16494     {
16495       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16496     }
16497
16498   M (SHOW_ONE_STATUS, mp);
16499   /* send it... */
16500   S (mp);
16501   /* Wait for a reply... */
16502   W (ret);
16503   return ret;
16504 }
16505
16506 #define api_show_lisp_status api_show_one_status
16507
16508 static int
16509 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16510 {
16511   vl_api_gpe_fwd_entry_path_dump_t *mp;
16512   vl_api_control_ping_t *mp_ping;
16513   unformat_input_t *i = vam->input;
16514   u32 fwd_entry_index = ~0;
16515   int ret;
16516
16517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16518     {
16519       if (unformat (i, "index %d", &fwd_entry_index))
16520         ;
16521       else
16522         break;
16523     }
16524
16525   if (~0 == fwd_entry_index)
16526     {
16527       errmsg ("no index specified!");
16528       return -99;
16529     }
16530
16531   if (!vam->json_output)
16532     {
16533       print (vam->ofp, "first line");
16534     }
16535
16536   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16537
16538   /* send it... */
16539   S (mp);
16540   /* Use a control ping for synchronization */
16541   M (CONTROL_PING, mp_ping);
16542   S (mp_ping);
16543
16544   /* Wait for a reply... */
16545   W (ret);
16546   return ret;
16547 }
16548
16549 static int
16550 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16551 {
16552   vl_api_one_get_map_request_itr_rlocs_t *mp;
16553   int ret;
16554
16555   if (!vam->json_output)
16556     {
16557       print (vam->ofp, "%=20s", "itr-rlocs:");
16558     }
16559
16560   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16561   /* send it... */
16562   S (mp);
16563   /* Wait for a reply... */
16564   W (ret);
16565   return ret;
16566 }
16567
16568 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16569
16570 static int
16571 api_af_packet_create (vat_main_t * vam)
16572 {
16573   unformat_input_t *i = vam->input;
16574   vl_api_af_packet_create_t *mp;
16575   u8 *host_if_name = 0;
16576   u8 hw_addr[6];
16577   u8 random_hw_addr = 1;
16578   int ret;
16579
16580   memset (hw_addr, 0, sizeof (hw_addr));
16581
16582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16583     {
16584       if (unformat (i, "name %s", &host_if_name))
16585         vec_add1 (host_if_name, 0);
16586       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16587         random_hw_addr = 0;
16588       else
16589         break;
16590     }
16591
16592   if (!vec_len (host_if_name))
16593     {
16594       errmsg ("host-interface name must be specified");
16595       return -99;
16596     }
16597
16598   if (vec_len (host_if_name) > 64)
16599     {
16600       errmsg ("host-interface name too long");
16601       return -99;
16602     }
16603
16604   M (AF_PACKET_CREATE, mp);
16605
16606   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16607   clib_memcpy (mp->hw_addr, hw_addr, 6);
16608   mp->use_random_hw_addr = random_hw_addr;
16609   vec_free (host_if_name);
16610
16611   S (mp);
16612
16613   /* *INDENT-OFF* */
16614   W2 (ret,
16615       ({
16616         if (ret == 0)
16617           fprintf (vam->ofp ? vam->ofp : stderr,
16618                    " new sw_if_index = %d\n", vam->sw_if_index);
16619       }));
16620   /* *INDENT-ON* */
16621   return ret;
16622 }
16623
16624 static int
16625 api_af_packet_delete (vat_main_t * vam)
16626 {
16627   unformat_input_t *i = vam->input;
16628   vl_api_af_packet_delete_t *mp;
16629   u8 *host_if_name = 0;
16630   int ret;
16631
16632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16633     {
16634       if (unformat (i, "name %s", &host_if_name))
16635         vec_add1 (host_if_name, 0);
16636       else
16637         break;
16638     }
16639
16640   if (!vec_len (host_if_name))
16641     {
16642       errmsg ("host-interface name must be specified");
16643       return -99;
16644     }
16645
16646   if (vec_len (host_if_name) > 64)
16647     {
16648       errmsg ("host-interface name too long");
16649       return -99;
16650     }
16651
16652   M (AF_PACKET_DELETE, mp);
16653
16654   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16655   vec_free (host_if_name);
16656
16657   S (mp);
16658   W (ret);
16659   return ret;
16660 }
16661
16662 static int
16663 api_policer_add_del (vat_main_t * vam)
16664 {
16665   unformat_input_t *i = vam->input;
16666   vl_api_policer_add_del_t *mp;
16667   u8 is_add = 1;
16668   u8 *name = 0;
16669   u32 cir = 0;
16670   u32 eir = 0;
16671   u64 cb = 0;
16672   u64 eb = 0;
16673   u8 rate_type = 0;
16674   u8 round_type = 0;
16675   u8 type = 0;
16676   u8 color_aware = 0;
16677   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16678   int ret;
16679
16680   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16681   conform_action.dscp = 0;
16682   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16683   exceed_action.dscp = 0;
16684   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16685   violate_action.dscp = 0;
16686
16687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16688     {
16689       if (unformat (i, "del"))
16690         is_add = 0;
16691       else if (unformat (i, "name %s", &name))
16692         vec_add1 (name, 0);
16693       else if (unformat (i, "cir %u", &cir))
16694         ;
16695       else if (unformat (i, "eir %u", &eir))
16696         ;
16697       else if (unformat (i, "cb %u", &cb))
16698         ;
16699       else if (unformat (i, "eb %u", &eb))
16700         ;
16701       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16702                          &rate_type))
16703         ;
16704       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16705                          &round_type))
16706         ;
16707       else if (unformat (i, "type %U", unformat_policer_type, &type))
16708         ;
16709       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16710                          &conform_action))
16711         ;
16712       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16713                          &exceed_action))
16714         ;
16715       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16716                          &violate_action))
16717         ;
16718       else if (unformat (i, "color-aware"))
16719         color_aware = 1;
16720       else
16721         break;
16722     }
16723
16724   if (!vec_len (name))
16725     {
16726       errmsg ("policer name must be specified");
16727       return -99;
16728     }
16729
16730   if (vec_len (name) > 64)
16731     {
16732       errmsg ("policer name too long");
16733       return -99;
16734     }
16735
16736   M (POLICER_ADD_DEL, mp);
16737
16738   clib_memcpy (mp->name, name, vec_len (name));
16739   vec_free (name);
16740   mp->is_add = is_add;
16741   mp->cir = cir;
16742   mp->eir = eir;
16743   mp->cb = cb;
16744   mp->eb = eb;
16745   mp->rate_type = rate_type;
16746   mp->round_type = round_type;
16747   mp->type = type;
16748   mp->conform_action_type = conform_action.action_type;
16749   mp->conform_dscp = conform_action.dscp;
16750   mp->exceed_action_type = exceed_action.action_type;
16751   mp->exceed_dscp = exceed_action.dscp;
16752   mp->violate_action_type = violate_action.action_type;
16753   mp->violate_dscp = violate_action.dscp;
16754   mp->color_aware = color_aware;
16755
16756   S (mp);
16757   W (ret);
16758   return ret;
16759 }
16760
16761 static int
16762 api_policer_dump (vat_main_t * vam)
16763 {
16764   unformat_input_t *i = vam->input;
16765   vl_api_policer_dump_t *mp;
16766   vl_api_control_ping_t *mp_ping;
16767   u8 *match_name = 0;
16768   u8 match_name_valid = 0;
16769   int ret;
16770
16771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16772     {
16773       if (unformat (i, "name %s", &match_name))
16774         {
16775           vec_add1 (match_name, 0);
16776           match_name_valid = 1;
16777         }
16778       else
16779         break;
16780     }
16781
16782   M (POLICER_DUMP, mp);
16783   mp->match_name_valid = match_name_valid;
16784   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16785   vec_free (match_name);
16786   /* send it... */
16787   S (mp);
16788
16789   /* Use a control ping for synchronization */
16790   M (CONTROL_PING, mp_ping);
16791   S (mp_ping);
16792
16793   /* Wait for a reply... */
16794   W (ret);
16795   return ret;
16796 }
16797
16798 static int
16799 api_policer_classify_set_interface (vat_main_t * vam)
16800 {
16801   unformat_input_t *i = vam->input;
16802   vl_api_policer_classify_set_interface_t *mp;
16803   u32 sw_if_index;
16804   int sw_if_index_set;
16805   u32 ip4_table_index = ~0;
16806   u32 ip6_table_index = ~0;
16807   u32 l2_table_index = ~0;
16808   u8 is_add = 1;
16809   int ret;
16810
16811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16812     {
16813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16814         sw_if_index_set = 1;
16815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16816         sw_if_index_set = 1;
16817       else if (unformat (i, "del"))
16818         is_add = 0;
16819       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16820         ;
16821       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16822         ;
16823       else if (unformat (i, "l2-table %d", &l2_table_index))
16824         ;
16825       else
16826         {
16827           clib_warning ("parse error '%U'", format_unformat_error, i);
16828           return -99;
16829         }
16830     }
16831
16832   if (sw_if_index_set == 0)
16833     {
16834       errmsg ("missing interface name or sw_if_index");
16835       return -99;
16836     }
16837
16838   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16839
16840   mp->sw_if_index = ntohl (sw_if_index);
16841   mp->ip4_table_index = ntohl (ip4_table_index);
16842   mp->ip6_table_index = ntohl (ip6_table_index);
16843   mp->l2_table_index = ntohl (l2_table_index);
16844   mp->is_add = is_add;
16845
16846   S (mp);
16847   W (ret);
16848   return ret;
16849 }
16850
16851 static int
16852 api_policer_classify_dump (vat_main_t * vam)
16853 {
16854   unformat_input_t *i = vam->input;
16855   vl_api_policer_classify_dump_t *mp;
16856   vl_api_control_ping_t *mp_ping;
16857   u8 type = POLICER_CLASSIFY_N_TABLES;
16858   int ret;
16859
16860   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16861     ;
16862   else
16863     {
16864       errmsg ("classify table type must be specified");
16865       return -99;
16866     }
16867
16868   if (!vam->json_output)
16869     {
16870       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16871     }
16872
16873   M (POLICER_CLASSIFY_DUMP, mp);
16874   mp->type = type;
16875   /* send it... */
16876   S (mp);
16877
16878   /* Use a control ping for synchronization */
16879   M (CONTROL_PING, mp_ping);
16880   S (mp_ping);
16881
16882   /* Wait for a reply... */
16883   W (ret);
16884   return ret;
16885 }
16886
16887 static int
16888 api_netmap_create (vat_main_t * vam)
16889 {
16890   unformat_input_t *i = vam->input;
16891   vl_api_netmap_create_t *mp;
16892   u8 *if_name = 0;
16893   u8 hw_addr[6];
16894   u8 random_hw_addr = 1;
16895   u8 is_pipe = 0;
16896   u8 is_master = 0;
16897   int ret;
16898
16899   memset (hw_addr, 0, sizeof (hw_addr));
16900
16901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16902     {
16903       if (unformat (i, "name %s", &if_name))
16904         vec_add1 (if_name, 0);
16905       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16906         random_hw_addr = 0;
16907       else if (unformat (i, "pipe"))
16908         is_pipe = 1;
16909       else if (unformat (i, "master"))
16910         is_master = 1;
16911       else if (unformat (i, "slave"))
16912         is_master = 0;
16913       else
16914         break;
16915     }
16916
16917   if (!vec_len (if_name))
16918     {
16919       errmsg ("interface name must be specified");
16920       return -99;
16921     }
16922
16923   if (vec_len (if_name) > 64)
16924     {
16925       errmsg ("interface name too long");
16926       return -99;
16927     }
16928
16929   M (NETMAP_CREATE, mp);
16930
16931   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16932   clib_memcpy (mp->hw_addr, hw_addr, 6);
16933   mp->use_random_hw_addr = random_hw_addr;
16934   mp->is_pipe = is_pipe;
16935   mp->is_master = is_master;
16936   vec_free (if_name);
16937
16938   S (mp);
16939   W (ret);
16940   return ret;
16941 }
16942
16943 static int
16944 api_netmap_delete (vat_main_t * vam)
16945 {
16946   unformat_input_t *i = vam->input;
16947   vl_api_netmap_delete_t *mp;
16948   u8 *if_name = 0;
16949   int ret;
16950
16951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16952     {
16953       if (unformat (i, "name %s", &if_name))
16954         vec_add1 (if_name, 0);
16955       else
16956         break;
16957     }
16958
16959   if (!vec_len (if_name))
16960     {
16961       errmsg ("interface name must be specified");
16962       return -99;
16963     }
16964
16965   if (vec_len (if_name) > 64)
16966     {
16967       errmsg ("interface name too long");
16968       return -99;
16969     }
16970
16971   M (NETMAP_DELETE, mp);
16972
16973   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16974   vec_free (if_name);
16975
16976   S (mp);
16977   W (ret);
16978   return ret;
16979 }
16980
16981 static void
16982 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16983 {
16984   if (fp->afi == IP46_TYPE_IP6)
16985     print (vam->ofp,
16986            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16987            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16988            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16989            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16990            format_ip6_address, fp->next_hop);
16991   else if (fp->afi == IP46_TYPE_IP4)
16992     print (vam->ofp,
16993            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16994            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16995            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16996            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16997            format_ip4_address, fp->next_hop);
16998 }
16999
17000 static void
17001 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17002                                  vl_api_fib_path2_t * fp)
17003 {
17004   struct in_addr ip4;
17005   struct in6_addr ip6;
17006
17007   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17008   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17009   vat_json_object_add_uint (node, "is_local", fp->is_local);
17010   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17011   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17012   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17013   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17014   if (fp->afi == IP46_TYPE_IP4)
17015     {
17016       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17017       vat_json_object_add_ip4 (node, "next_hop", ip4);
17018     }
17019   else if (fp->afi == IP46_TYPE_IP6)
17020     {
17021       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17022       vat_json_object_add_ip6 (node, "next_hop", ip6);
17023     }
17024 }
17025
17026 static void
17027 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17028 {
17029   vat_main_t *vam = &vat_main;
17030   int count = ntohl (mp->mt_count);
17031   vl_api_fib_path2_t *fp;
17032   i32 i;
17033
17034   print (vam->ofp, "[%d]: sw_if_index %d via:",
17035          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17036   fp = mp->mt_paths;
17037   for (i = 0; i < count; i++)
17038     {
17039       vl_api_mpls_fib_path_print (vam, fp);
17040       fp++;
17041     }
17042
17043   print (vam->ofp, "");
17044 }
17045
17046 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17047 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17048
17049 static void
17050 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17051 {
17052   vat_main_t *vam = &vat_main;
17053   vat_json_node_t *node = NULL;
17054   int count = ntohl (mp->mt_count);
17055   vl_api_fib_path2_t *fp;
17056   i32 i;
17057
17058   if (VAT_JSON_ARRAY != vam->json_tree.type)
17059     {
17060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17061       vat_json_init_array (&vam->json_tree);
17062     }
17063   node = vat_json_array_add (&vam->json_tree);
17064
17065   vat_json_init_object (node);
17066   vat_json_object_add_uint (node, "tunnel_index",
17067                             ntohl (mp->mt_tunnel_index));
17068   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17069
17070   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17071
17072   fp = mp->mt_paths;
17073   for (i = 0; i < count; i++)
17074     {
17075       vl_api_mpls_fib_path_json_print (node, fp);
17076       fp++;
17077     }
17078 }
17079
17080 static int
17081 api_mpls_tunnel_dump (vat_main_t * vam)
17082 {
17083   vl_api_mpls_tunnel_dump_t *mp;
17084   vl_api_control_ping_t *mp_ping;
17085   i32 index = -1;
17086   int ret;
17087
17088   /* Parse args required to build the message */
17089   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17090     {
17091       if (!unformat (vam->input, "tunnel_index %d", &index))
17092         {
17093           index = -1;
17094           break;
17095         }
17096     }
17097
17098   print (vam->ofp, "  tunnel_index %d", index);
17099
17100   M (MPLS_TUNNEL_DUMP, mp);
17101   mp->tunnel_index = htonl (index);
17102   S (mp);
17103
17104   /* Use a control ping for synchronization */
17105   M (CONTROL_PING, mp_ping);
17106   S (mp_ping);
17107
17108   W (ret);
17109   return ret;
17110 }
17111
17112 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17113 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17114
17115
17116 static void
17117 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17118 {
17119   vat_main_t *vam = &vat_main;
17120   int count = ntohl (mp->count);
17121   vl_api_fib_path2_t *fp;
17122   int i;
17123
17124   print (vam->ofp,
17125          "table-id %d, label %u, ess_bit %u",
17126          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17127   fp = mp->path;
17128   for (i = 0; i < count; i++)
17129     {
17130       vl_api_mpls_fib_path_print (vam, fp);
17131       fp++;
17132     }
17133 }
17134
17135 static void vl_api_mpls_fib_details_t_handler_json
17136   (vl_api_mpls_fib_details_t * mp)
17137 {
17138   vat_main_t *vam = &vat_main;
17139   int count = ntohl (mp->count);
17140   vat_json_node_t *node = NULL;
17141   vl_api_fib_path2_t *fp;
17142   int i;
17143
17144   if (VAT_JSON_ARRAY != vam->json_tree.type)
17145     {
17146       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17147       vat_json_init_array (&vam->json_tree);
17148     }
17149   node = vat_json_array_add (&vam->json_tree);
17150
17151   vat_json_init_object (node);
17152   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17153   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17154   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17155   vat_json_object_add_uint (node, "path_count", count);
17156   fp = mp->path;
17157   for (i = 0; i < count; i++)
17158     {
17159       vl_api_mpls_fib_path_json_print (node, fp);
17160       fp++;
17161     }
17162 }
17163
17164 static int
17165 api_mpls_fib_dump (vat_main_t * vam)
17166 {
17167   vl_api_mpls_fib_dump_t *mp;
17168   vl_api_control_ping_t *mp_ping;
17169   int ret;
17170
17171   M (MPLS_FIB_DUMP, mp);
17172   S (mp);
17173
17174   /* Use a control ping for synchronization */
17175   M (CONTROL_PING, mp_ping);
17176   S (mp_ping);
17177
17178   W (ret);
17179   return ret;
17180 }
17181
17182 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17183 #define vl_api_ip_fib_details_t_print vl_noop_handler
17184
17185 static void
17186 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17187 {
17188   vat_main_t *vam = &vat_main;
17189   int count = ntohl (mp->count);
17190   vl_api_fib_path_t *fp;
17191   int i;
17192
17193   print (vam->ofp,
17194          "table-id %d, prefix %U/%d",
17195          ntohl (mp->table_id), format_ip4_address, mp->address,
17196          mp->address_length);
17197   fp = mp->path;
17198   for (i = 0; i < count; i++)
17199     {
17200       if (fp->afi == IP46_TYPE_IP6)
17201         print (vam->ofp,
17202                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17203                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17204                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17205                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17206                format_ip6_address, fp->next_hop);
17207       else if (fp->afi == IP46_TYPE_IP4)
17208         print (vam->ofp,
17209                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17210                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17211                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17212                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17213                format_ip4_address, fp->next_hop);
17214       fp++;
17215     }
17216 }
17217
17218 static void vl_api_ip_fib_details_t_handler_json
17219   (vl_api_ip_fib_details_t * mp)
17220 {
17221   vat_main_t *vam = &vat_main;
17222   int count = ntohl (mp->count);
17223   vat_json_node_t *node = NULL;
17224   struct in_addr ip4;
17225   struct in6_addr ip6;
17226   vl_api_fib_path_t *fp;
17227   int i;
17228
17229   if (VAT_JSON_ARRAY != vam->json_tree.type)
17230     {
17231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17232       vat_json_init_array (&vam->json_tree);
17233     }
17234   node = vat_json_array_add (&vam->json_tree);
17235
17236   vat_json_init_object (node);
17237   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17238   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17239   vat_json_object_add_ip4 (node, "prefix", ip4);
17240   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17241   vat_json_object_add_uint (node, "path_count", count);
17242   fp = mp->path;
17243   for (i = 0; i < count; i++)
17244     {
17245       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17246       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17247       vat_json_object_add_uint (node, "is_local", fp->is_local);
17248       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17249       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17250       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17251       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17252       if (fp->afi == IP46_TYPE_IP4)
17253         {
17254           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17255           vat_json_object_add_ip4 (node, "next_hop", ip4);
17256         }
17257       else if (fp->afi == IP46_TYPE_IP6)
17258         {
17259           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17260           vat_json_object_add_ip6 (node, "next_hop", ip6);
17261         }
17262     }
17263 }
17264
17265 static int
17266 api_ip_fib_dump (vat_main_t * vam)
17267 {
17268   vl_api_ip_fib_dump_t *mp;
17269   vl_api_control_ping_t *mp_ping;
17270   int ret;
17271
17272   M (IP_FIB_DUMP, mp);
17273   S (mp);
17274
17275   /* Use a control ping for synchronization */
17276   M (CONTROL_PING, mp_ping);
17277   S (mp_ping);
17278
17279   W (ret);
17280   return ret;
17281 }
17282
17283 static int
17284 api_ip_mfib_dump (vat_main_t * vam)
17285 {
17286   vl_api_ip_mfib_dump_t *mp;
17287   vl_api_control_ping_t *mp_ping;
17288   int ret;
17289
17290   M (IP_MFIB_DUMP, mp);
17291   S (mp);
17292
17293   /* Use a control ping for synchronization */
17294   M (CONTROL_PING, mp_ping);
17295   S (mp_ping);
17296
17297   W (ret);
17298   return ret;
17299 }
17300
17301 static void vl_api_ip_neighbor_details_t_handler
17302   (vl_api_ip_neighbor_details_t * mp)
17303 {
17304   vat_main_t *vam = &vat_main;
17305
17306   print (vam->ofp, "%c %U %U",
17307          (mp->is_static) ? 'S' : 'D',
17308          format_ethernet_address, &mp->mac_address,
17309          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17310          &mp->ip_address);
17311 }
17312
17313 static void vl_api_ip_neighbor_details_t_handler_json
17314   (vl_api_ip_neighbor_details_t * mp)
17315 {
17316
17317   vat_main_t *vam = &vat_main;
17318   vat_json_node_t *node;
17319   struct in_addr ip4;
17320   struct in6_addr ip6;
17321
17322   if (VAT_JSON_ARRAY != vam->json_tree.type)
17323     {
17324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17325       vat_json_init_array (&vam->json_tree);
17326     }
17327   node = vat_json_array_add (&vam->json_tree);
17328
17329   vat_json_init_object (node);
17330   vat_json_object_add_string_copy (node, "flag",
17331                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17332                                    "dynamic");
17333
17334   vat_json_object_add_string_copy (node, "link_layer",
17335                                    format (0, "%U", format_ethernet_address,
17336                                            &mp->mac_address));
17337
17338   if (mp->is_ipv6)
17339     {
17340       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17341       vat_json_object_add_ip6 (node, "ip_address", ip6);
17342     }
17343   else
17344     {
17345       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17346       vat_json_object_add_ip4 (node, "ip_address", ip4);
17347     }
17348 }
17349
17350 static int
17351 api_ip_neighbor_dump (vat_main_t * vam)
17352 {
17353   unformat_input_t *i = vam->input;
17354   vl_api_ip_neighbor_dump_t *mp;
17355   vl_api_control_ping_t *mp_ping;
17356   u8 is_ipv6 = 0;
17357   u32 sw_if_index = ~0;
17358   int ret;
17359
17360   /* Parse args required to build the message */
17361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17362     {
17363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17364         ;
17365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17366         ;
17367       else if (unformat (i, "ip6"))
17368         is_ipv6 = 1;
17369       else
17370         break;
17371     }
17372
17373   if (sw_if_index == ~0)
17374     {
17375       errmsg ("missing interface name or sw_if_index");
17376       return -99;
17377     }
17378
17379   M (IP_NEIGHBOR_DUMP, mp);
17380   mp->is_ipv6 = (u8) is_ipv6;
17381   mp->sw_if_index = ntohl (sw_if_index);
17382   S (mp);
17383
17384   /* Use a control ping for synchronization */
17385   M (CONTROL_PING, mp_ping);
17386   S (mp_ping);
17387
17388   W (ret);
17389   return ret;
17390 }
17391
17392 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17393 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17394
17395 static void
17396 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17397 {
17398   vat_main_t *vam = &vat_main;
17399   int count = ntohl (mp->count);
17400   vl_api_fib_path_t *fp;
17401   int i;
17402
17403   print (vam->ofp,
17404          "table-id %d, prefix %U/%d",
17405          ntohl (mp->table_id), format_ip6_address, mp->address,
17406          mp->address_length);
17407   fp = mp->path;
17408   for (i = 0; i < count; i++)
17409     {
17410       if (fp->afi == IP46_TYPE_IP6)
17411         print (vam->ofp,
17412                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17413                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17414                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17415                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17416                format_ip6_address, fp->next_hop);
17417       else if (fp->afi == IP46_TYPE_IP4)
17418         print (vam->ofp,
17419                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17420                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17421                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17422                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17423                format_ip4_address, fp->next_hop);
17424       fp++;
17425     }
17426 }
17427
17428 static void vl_api_ip6_fib_details_t_handler_json
17429   (vl_api_ip6_fib_details_t * mp)
17430 {
17431   vat_main_t *vam = &vat_main;
17432   int count = ntohl (mp->count);
17433   vat_json_node_t *node = NULL;
17434   struct in_addr ip4;
17435   struct in6_addr ip6;
17436   vl_api_fib_path_t *fp;
17437   int i;
17438
17439   if (VAT_JSON_ARRAY != vam->json_tree.type)
17440     {
17441       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17442       vat_json_init_array (&vam->json_tree);
17443     }
17444   node = vat_json_array_add (&vam->json_tree);
17445
17446   vat_json_init_object (node);
17447   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17448   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17449   vat_json_object_add_ip6 (node, "prefix", ip6);
17450   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17451   vat_json_object_add_uint (node, "path_count", count);
17452   fp = mp->path;
17453   for (i = 0; i < count; i++)
17454     {
17455       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17456       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17457       vat_json_object_add_uint (node, "is_local", fp->is_local);
17458       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17459       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17460       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17461       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17462       if (fp->afi == IP46_TYPE_IP4)
17463         {
17464           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17465           vat_json_object_add_ip4 (node, "next_hop", ip4);
17466         }
17467       else if (fp->afi == IP46_TYPE_IP6)
17468         {
17469           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17470           vat_json_object_add_ip6 (node, "next_hop", ip6);
17471         }
17472     }
17473 }
17474
17475 static int
17476 api_ip6_fib_dump (vat_main_t * vam)
17477 {
17478   vl_api_ip6_fib_dump_t *mp;
17479   vl_api_control_ping_t *mp_ping;
17480   int ret;
17481
17482   M (IP6_FIB_DUMP, mp);
17483   S (mp);
17484
17485   /* Use a control ping for synchronization */
17486   M (CONTROL_PING, mp_ping);
17487   S (mp_ping);
17488
17489   W (ret);
17490   return ret;
17491 }
17492
17493 static int
17494 api_ip6_mfib_dump (vat_main_t * vam)
17495 {
17496   vl_api_ip6_mfib_dump_t *mp;
17497   vl_api_control_ping_t *mp_ping;
17498   int ret;
17499
17500   M (IP6_MFIB_DUMP, mp);
17501   S (mp);
17502
17503   /* Use a control ping for synchronization */
17504   M (CONTROL_PING, mp_ping);
17505   S (mp_ping);
17506
17507   W (ret);
17508   return ret;
17509 }
17510
17511 int
17512 api_classify_table_ids (vat_main_t * vam)
17513 {
17514   vl_api_classify_table_ids_t *mp;
17515   int ret;
17516
17517   /* Construct the API message */
17518   M (CLASSIFY_TABLE_IDS, mp);
17519   mp->context = 0;
17520
17521   S (mp);
17522   W (ret);
17523   return ret;
17524 }
17525
17526 int
17527 api_classify_table_by_interface (vat_main_t * vam)
17528 {
17529   unformat_input_t *input = vam->input;
17530   vl_api_classify_table_by_interface_t *mp;
17531
17532   u32 sw_if_index = ~0;
17533   int ret;
17534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17535     {
17536       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17537         ;
17538       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17539         ;
17540       else
17541         break;
17542     }
17543   if (sw_if_index == ~0)
17544     {
17545       errmsg ("missing interface name or sw_if_index");
17546       return -99;
17547     }
17548
17549   /* Construct the API message */
17550   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17551   mp->context = 0;
17552   mp->sw_if_index = ntohl (sw_if_index);
17553
17554   S (mp);
17555   W (ret);
17556   return ret;
17557 }
17558
17559 int
17560 api_classify_table_info (vat_main_t * vam)
17561 {
17562   unformat_input_t *input = vam->input;
17563   vl_api_classify_table_info_t *mp;
17564
17565   u32 table_id = ~0;
17566   int ret;
17567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17568     {
17569       if (unformat (input, "table_id %d", &table_id))
17570         ;
17571       else
17572         break;
17573     }
17574   if (table_id == ~0)
17575     {
17576       errmsg ("missing table id");
17577       return -99;
17578     }
17579
17580   /* Construct the API message */
17581   M (CLASSIFY_TABLE_INFO, mp);
17582   mp->context = 0;
17583   mp->table_id = ntohl (table_id);
17584
17585   S (mp);
17586   W (ret);
17587   return ret;
17588 }
17589
17590 int
17591 api_classify_session_dump (vat_main_t * vam)
17592 {
17593   unformat_input_t *input = vam->input;
17594   vl_api_classify_session_dump_t *mp;
17595   vl_api_control_ping_t *mp_ping;
17596
17597   u32 table_id = ~0;
17598   int ret;
17599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17600     {
17601       if (unformat (input, "table_id %d", &table_id))
17602         ;
17603       else
17604         break;
17605     }
17606   if (table_id == ~0)
17607     {
17608       errmsg ("missing table id");
17609       return -99;
17610     }
17611
17612   /* Construct the API message */
17613   M (CLASSIFY_SESSION_DUMP, mp);
17614   mp->context = 0;
17615   mp->table_id = ntohl (table_id);
17616   S (mp);
17617
17618   /* Use a control ping for synchronization */
17619   M (CONTROL_PING, mp_ping);
17620   S (mp_ping);
17621
17622   W (ret);
17623   return ret;
17624 }
17625
17626 static void
17627 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17628 {
17629   vat_main_t *vam = &vat_main;
17630
17631   print (vam->ofp, "collector_address %U, collector_port %d, "
17632          "src_address %U, vrf_id %d, path_mtu %u, "
17633          "template_interval %u, udp_checksum %d",
17634          format_ip4_address, mp->collector_address,
17635          ntohs (mp->collector_port),
17636          format_ip4_address, mp->src_address,
17637          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17638          ntohl (mp->template_interval), mp->udp_checksum);
17639
17640   vam->retval = 0;
17641   vam->result_ready = 1;
17642 }
17643
17644 static void
17645   vl_api_ipfix_exporter_details_t_handler_json
17646   (vl_api_ipfix_exporter_details_t * mp)
17647 {
17648   vat_main_t *vam = &vat_main;
17649   vat_json_node_t node;
17650   struct in_addr collector_address;
17651   struct in_addr src_address;
17652
17653   vat_json_init_object (&node);
17654   clib_memcpy (&collector_address, &mp->collector_address,
17655                sizeof (collector_address));
17656   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17657   vat_json_object_add_uint (&node, "collector_port",
17658                             ntohs (mp->collector_port));
17659   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17660   vat_json_object_add_ip4 (&node, "src_address", src_address);
17661   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17662   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17663   vat_json_object_add_uint (&node, "template_interval",
17664                             ntohl (mp->template_interval));
17665   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17666
17667   vat_json_print (vam->ofp, &node);
17668   vat_json_free (&node);
17669   vam->retval = 0;
17670   vam->result_ready = 1;
17671 }
17672
17673 int
17674 api_ipfix_exporter_dump (vat_main_t * vam)
17675 {
17676   vl_api_ipfix_exporter_dump_t *mp;
17677   int ret;
17678
17679   /* Construct the API message */
17680   M (IPFIX_EXPORTER_DUMP, mp);
17681   mp->context = 0;
17682
17683   S (mp);
17684   W (ret);
17685   return ret;
17686 }
17687
17688 static int
17689 api_ipfix_classify_stream_dump (vat_main_t * vam)
17690 {
17691   vl_api_ipfix_classify_stream_dump_t *mp;
17692   int ret;
17693
17694   /* Construct the API message */
17695   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17696   mp->context = 0;
17697
17698   S (mp);
17699   W (ret);
17700   return ret;
17701   /* NOTREACHED */
17702   return 0;
17703 }
17704
17705 static void
17706   vl_api_ipfix_classify_stream_details_t_handler
17707   (vl_api_ipfix_classify_stream_details_t * mp)
17708 {
17709   vat_main_t *vam = &vat_main;
17710   print (vam->ofp, "domain_id %d, src_port %d",
17711          ntohl (mp->domain_id), ntohs (mp->src_port));
17712   vam->retval = 0;
17713   vam->result_ready = 1;
17714 }
17715
17716 static void
17717   vl_api_ipfix_classify_stream_details_t_handler_json
17718   (vl_api_ipfix_classify_stream_details_t * mp)
17719 {
17720   vat_main_t *vam = &vat_main;
17721   vat_json_node_t node;
17722
17723   vat_json_init_object (&node);
17724   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17725   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17726
17727   vat_json_print (vam->ofp, &node);
17728   vat_json_free (&node);
17729   vam->retval = 0;
17730   vam->result_ready = 1;
17731 }
17732
17733 static int
17734 api_ipfix_classify_table_dump (vat_main_t * vam)
17735 {
17736   vl_api_ipfix_classify_table_dump_t *mp;
17737   vl_api_control_ping_t *mp_ping;
17738   int ret;
17739
17740   if (!vam->json_output)
17741     {
17742       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17743              "transport_protocol");
17744     }
17745
17746   /* Construct the API message */
17747   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17748
17749   /* send it... */
17750   S (mp);
17751
17752   /* Use a control ping for synchronization */
17753   M (CONTROL_PING, mp_ping);
17754   S (mp_ping);
17755
17756   W (ret);
17757   return ret;
17758 }
17759
17760 static void
17761   vl_api_ipfix_classify_table_details_t_handler
17762   (vl_api_ipfix_classify_table_details_t * mp)
17763 {
17764   vat_main_t *vam = &vat_main;
17765   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17766          mp->transport_protocol);
17767 }
17768
17769 static void
17770   vl_api_ipfix_classify_table_details_t_handler_json
17771   (vl_api_ipfix_classify_table_details_t * mp)
17772 {
17773   vat_json_node_t *node = NULL;
17774   vat_main_t *vam = &vat_main;
17775
17776   if (VAT_JSON_ARRAY != vam->json_tree.type)
17777     {
17778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17779       vat_json_init_array (&vam->json_tree);
17780     }
17781
17782   node = vat_json_array_add (&vam->json_tree);
17783   vat_json_init_object (node);
17784
17785   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17786   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17787   vat_json_object_add_uint (node, "transport_protocol",
17788                             mp->transport_protocol);
17789 }
17790
17791 static int
17792 api_sw_interface_span_enable_disable (vat_main_t * vam)
17793 {
17794   unformat_input_t *i = vam->input;
17795   vl_api_sw_interface_span_enable_disable_t *mp;
17796   u32 src_sw_if_index = ~0;
17797   u32 dst_sw_if_index = ~0;
17798   u8 state = 3;
17799   int ret;
17800
17801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17802     {
17803       if (unformat
17804           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17805         ;
17806       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17807         ;
17808       else
17809         if (unformat
17810             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17811         ;
17812       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17813         ;
17814       else if (unformat (i, "disable"))
17815         state = 0;
17816       else if (unformat (i, "rx"))
17817         state = 1;
17818       else if (unformat (i, "tx"))
17819         state = 2;
17820       else if (unformat (i, "both"))
17821         state = 3;
17822       else
17823         break;
17824     }
17825
17826   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17827
17828   mp->sw_if_index_from = htonl (src_sw_if_index);
17829   mp->sw_if_index_to = htonl (dst_sw_if_index);
17830   mp->state = state;
17831
17832   S (mp);
17833   W (ret);
17834   return ret;
17835 }
17836
17837 static void
17838 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17839                                             * mp)
17840 {
17841   vat_main_t *vam = &vat_main;
17842   u8 *sw_if_from_name = 0;
17843   u8 *sw_if_to_name = 0;
17844   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17845   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17846   char *states[] = { "none", "rx", "tx", "both" };
17847   hash_pair_t *p;
17848
17849   /* *INDENT-OFF* */
17850   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17851   ({
17852     if ((u32) p->value[0] == sw_if_index_from)
17853       {
17854         sw_if_from_name = (u8 *)(p->key);
17855         if (sw_if_to_name)
17856           break;
17857       }
17858     if ((u32) p->value[0] == sw_if_index_to)
17859       {
17860         sw_if_to_name = (u8 *)(p->key);
17861         if (sw_if_from_name)
17862           break;
17863       }
17864   }));
17865   /* *INDENT-ON* */
17866   print (vam->ofp, "%20s => %20s (%s)",
17867          sw_if_from_name, sw_if_to_name, states[mp->state]);
17868 }
17869
17870 static void
17871   vl_api_sw_interface_span_details_t_handler_json
17872   (vl_api_sw_interface_span_details_t * mp)
17873 {
17874   vat_main_t *vam = &vat_main;
17875   vat_json_node_t *node = NULL;
17876   u8 *sw_if_from_name = 0;
17877   u8 *sw_if_to_name = 0;
17878   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17879   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17880   hash_pair_t *p;
17881
17882   /* *INDENT-OFF* */
17883   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17884   ({
17885     if ((u32) p->value[0] == sw_if_index_from)
17886       {
17887         sw_if_from_name = (u8 *)(p->key);
17888         if (sw_if_to_name)
17889           break;
17890       }
17891     if ((u32) p->value[0] == sw_if_index_to)
17892       {
17893         sw_if_to_name = (u8 *)(p->key);
17894         if (sw_if_from_name)
17895           break;
17896       }
17897   }));
17898   /* *INDENT-ON* */
17899
17900   if (VAT_JSON_ARRAY != vam->json_tree.type)
17901     {
17902       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17903       vat_json_init_array (&vam->json_tree);
17904     }
17905   node = vat_json_array_add (&vam->json_tree);
17906
17907   vat_json_init_object (node);
17908   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17909   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17910   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17911   if (0 != sw_if_to_name)
17912     {
17913       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17914     }
17915   vat_json_object_add_uint (node, "state", mp->state);
17916 }
17917
17918 static int
17919 api_sw_interface_span_dump (vat_main_t * vam)
17920 {
17921   vl_api_sw_interface_span_dump_t *mp;
17922   vl_api_control_ping_t *mp_ping;
17923   int ret;
17924
17925   M (SW_INTERFACE_SPAN_DUMP, mp);
17926   S (mp);
17927
17928   /* Use a control ping for synchronization */
17929   M (CONTROL_PING, mp_ping);
17930   S (mp_ping);
17931
17932   W (ret);
17933   return ret;
17934 }
17935
17936 int
17937 api_pg_create_interface (vat_main_t * vam)
17938 {
17939   unformat_input_t *input = vam->input;
17940   vl_api_pg_create_interface_t *mp;
17941
17942   u32 if_id = ~0;
17943   int ret;
17944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17945     {
17946       if (unformat (input, "if_id %d", &if_id))
17947         ;
17948       else
17949         break;
17950     }
17951   if (if_id == ~0)
17952     {
17953       errmsg ("missing pg interface index");
17954       return -99;
17955     }
17956
17957   /* Construct the API message */
17958   M (PG_CREATE_INTERFACE, mp);
17959   mp->context = 0;
17960   mp->interface_id = ntohl (if_id);
17961
17962   S (mp);
17963   W (ret);
17964   return ret;
17965 }
17966
17967 int
17968 api_pg_capture (vat_main_t * vam)
17969 {
17970   unformat_input_t *input = vam->input;
17971   vl_api_pg_capture_t *mp;
17972
17973   u32 if_id = ~0;
17974   u8 enable = 1;
17975   u32 count = 1;
17976   u8 pcap_file_set = 0;
17977   u8 *pcap_file = 0;
17978   int ret;
17979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17980     {
17981       if (unformat (input, "if_id %d", &if_id))
17982         ;
17983       else if (unformat (input, "pcap %s", &pcap_file))
17984         pcap_file_set = 1;
17985       else if (unformat (input, "count %d", &count))
17986         ;
17987       else if (unformat (input, "disable"))
17988         enable = 0;
17989       else
17990         break;
17991     }
17992   if (if_id == ~0)
17993     {
17994       errmsg ("missing pg interface index");
17995       return -99;
17996     }
17997   if (pcap_file_set > 0)
17998     {
17999       if (vec_len (pcap_file) > 255)
18000         {
18001           errmsg ("pcap file name is too long");
18002           return -99;
18003         }
18004     }
18005
18006   u32 name_len = vec_len (pcap_file);
18007   /* Construct the API message */
18008   M (PG_CAPTURE, mp);
18009   mp->context = 0;
18010   mp->interface_id = ntohl (if_id);
18011   mp->is_enabled = enable;
18012   mp->count = ntohl (count);
18013   mp->pcap_name_length = ntohl (name_len);
18014   if (pcap_file_set != 0)
18015     {
18016       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18017     }
18018   vec_free (pcap_file);
18019
18020   S (mp);
18021   W (ret);
18022   return ret;
18023 }
18024
18025 int
18026 api_pg_enable_disable (vat_main_t * vam)
18027 {
18028   unformat_input_t *input = vam->input;
18029   vl_api_pg_enable_disable_t *mp;
18030
18031   u8 enable = 1;
18032   u8 stream_name_set = 0;
18033   u8 *stream_name = 0;
18034   int ret;
18035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18036     {
18037       if (unformat (input, "stream %s", &stream_name))
18038         stream_name_set = 1;
18039       else if (unformat (input, "disable"))
18040         enable = 0;
18041       else
18042         break;
18043     }
18044
18045   if (stream_name_set > 0)
18046     {
18047       if (vec_len (stream_name) > 255)
18048         {
18049           errmsg ("stream name too long");
18050           return -99;
18051         }
18052     }
18053
18054   u32 name_len = vec_len (stream_name);
18055   /* Construct the API message */
18056   M (PG_ENABLE_DISABLE, mp);
18057   mp->context = 0;
18058   mp->is_enabled = enable;
18059   if (stream_name_set != 0)
18060     {
18061       mp->stream_name_length = ntohl (name_len);
18062       clib_memcpy (mp->stream_name, stream_name, name_len);
18063     }
18064   vec_free (stream_name);
18065
18066   S (mp);
18067   W (ret);
18068   return ret;
18069 }
18070
18071 int
18072 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18073 {
18074   unformat_input_t *input = vam->input;
18075   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18076
18077   u16 *low_ports = 0;
18078   u16 *high_ports = 0;
18079   u16 this_low;
18080   u16 this_hi;
18081   ip4_address_t ip4_addr;
18082   ip6_address_t ip6_addr;
18083   u32 length;
18084   u32 tmp, tmp2;
18085   u8 prefix_set = 0;
18086   u32 vrf_id = ~0;
18087   u8 is_add = 1;
18088   u8 is_ipv6 = 0;
18089   int ret;
18090
18091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18092     {
18093       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18094         {
18095           prefix_set = 1;
18096         }
18097       else
18098         if (unformat
18099             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18100         {
18101           prefix_set = 1;
18102           is_ipv6 = 1;
18103         }
18104       else if (unformat (input, "vrf %d", &vrf_id))
18105         ;
18106       else if (unformat (input, "del"))
18107         is_add = 0;
18108       else if (unformat (input, "port %d", &tmp))
18109         {
18110           if (tmp == 0 || tmp > 65535)
18111             {
18112               errmsg ("port %d out of range", tmp);
18113               return -99;
18114             }
18115           this_low = tmp;
18116           this_hi = this_low + 1;
18117           vec_add1 (low_ports, this_low);
18118           vec_add1 (high_ports, this_hi);
18119         }
18120       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18121         {
18122           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18123             {
18124               errmsg ("incorrect range parameters");
18125               return -99;
18126             }
18127           this_low = tmp;
18128           /* Note: in debug CLI +1 is added to high before
18129              passing to real fn that does "the work"
18130              (ip_source_and_port_range_check_add_del).
18131              This fn is a wrapper around the binary API fn a
18132              control plane will call, which expects this increment
18133              to have occurred. Hence letting the binary API control
18134              plane fn do the increment for consistency between VAT
18135              and other control planes.
18136            */
18137           this_hi = tmp2;
18138           vec_add1 (low_ports, this_low);
18139           vec_add1 (high_ports, this_hi);
18140         }
18141       else
18142         break;
18143     }
18144
18145   if (prefix_set == 0)
18146     {
18147       errmsg ("<address>/<mask> not specified");
18148       return -99;
18149     }
18150
18151   if (vrf_id == ~0)
18152     {
18153       errmsg ("VRF ID required, not specified");
18154       return -99;
18155     }
18156
18157   if (vrf_id == 0)
18158     {
18159       errmsg
18160         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18161       return -99;
18162     }
18163
18164   if (vec_len (low_ports) == 0)
18165     {
18166       errmsg ("At least one port or port range required");
18167       return -99;
18168     }
18169
18170   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18171
18172   mp->is_add = is_add;
18173
18174   if (is_ipv6)
18175     {
18176       mp->is_ipv6 = 1;
18177       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18178     }
18179   else
18180     {
18181       mp->is_ipv6 = 0;
18182       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18183     }
18184
18185   mp->mask_length = length;
18186   mp->number_of_ranges = vec_len (low_ports);
18187
18188   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18189   vec_free (low_ports);
18190
18191   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18192   vec_free (high_ports);
18193
18194   mp->vrf_id = ntohl (vrf_id);
18195
18196   S (mp);
18197   W (ret);
18198   return ret;
18199 }
18200
18201 int
18202 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18203 {
18204   unformat_input_t *input = vam->input;
18205   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18206   u32 sw_if_index = ~0;
18207   int vrf_set = 0;
18208   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18209   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18210   u8 is_add = 1;
18211   int ret;
18212
18213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18214     {
18215       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18216         ;
18217       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18218         ;
18219       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18220         vrf_set = 1;
18221       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18222         vrf_set = 1;
18223       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18224         vrf_set = 1;
18225       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18226         vrf_set = 1;
18227       else if (unformat (input, "del"))
18228         is_add = 0;
18229       else
18230         break;
18231     }
18232
18233   if (sw_if_index == ~0)
18234     {
18235       errmsg ("Interface required but not specified");
18236       return -99;
18237     }
18238
18239   if (vrf_set == 0)
18240     {
18241       errmsg ("VRF ID required but not specified");
18242       return -99;
18243     }
18244
18245   if (tcp_out_vrf_id == 0
18246       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18247     {
18248       errmsg
18249         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18250       return -99;
18251     }
18252
18253   /* Construct the API message */
18254   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18255
18256   mp->sw_if_index = ntohl (sw_if_index);
18257   mp->is_add = is_add;
18258   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18259   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18260   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18261   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18262
18263   /* send it... */
18264   S (mp);
18265
18266   /* Wait for a reply... */
18267   W (ret);
18268   return ret;
18269 }
18270
18271 static int
18272 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18273 {
18274   unformat_input_t *i = vam->input;
18275   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18276   u32 local_sa_id = 0;
18277   u32 remote_sa_id = 0;
18278   ip4_address_t src_address;
18279   ip4_address_t dst_address;
18280   u8 is_add = 1;
18281   int ret;
18282
18283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18284     {
18285       if (unformat (i, "local_sa %d", &local_sa_id))
18286         ;
18287       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18288         ;
18289       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18290         ;
18291       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18292         ;
18293       else if (unformat (i, "del"))
18294         is_add = 0;
18295       else
18296         {
18297           clib_warning ("parse error '%U'", format_unformat_error, i);
18298           return -99;
18299         }
18300     }
18301
18302   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18303
18304   mp->local_sa_id = ntohl (local_sa_id);
18305   mp->remote_sa_id = ntohl (remote_sa_id);
18306   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18307   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18308   mp->is_add = is_add;
18309
18310   S (mp);
18311   W (ret);
18312   return ret;
18313 }
18314
18315 static int
18316 api_punt (vat_main_t * vam)
18317 {
18318   unformat_input_t *i = vam->input;
18319   vl_api_punt_t *mp;
18320   u32 ipv = ~0;
18321   u32 protocol = ~0;
18322   u32 port = ~0;
18323   int is_add = 1;
18324   int ret;
18325
18326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18327     {
18328       if (unformat (i, "ip %d", &ipv))
18329         ;
18330       else if (unformat (i, "protocol %d", &protocol))
18331         ;
18332       else if (unformat (i, "port %d", &port))
18333         ;
18334       else if (unformat (i, "del"))
18335         is_add = 0;
18336       else
18337         {
18338           clib_warning ("parse error '%U'", format_unformat_error, i);
18339           return -99;
18340         }
18341     }
18342
18343   M (PUNT, mp);
18344
18345   mp->is_add = (u8) is_add;
18346   mp->ipv = (u8) ipv;
18347   mp->l4_protocol = (u8) protocol;
18348   mp->l4_port = htons ((u16) port);
18349
18350   S (mp);
18351   W (ret);
18352   return ret;
18353 }
18354
18355 static void vl_api_ipsec_gre_tunnel_details_t_handler
18356   (vl_api_ipsec_gre_tunnel_details_t * mp)
18357 {
18358   vat_main_t *vam = &vat_main;
18359
18360   print (vam->ofp, "%11d%15U%15U%14d%14d",
18361          ntohl (mp->sw_if_index),
18362          format_ip4_address, &mp->src_address,
18363          format_ip4_address, &mp->dst_address,
18364          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18365 }
18366
18367 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18368   (vl_api_ipsec_gre_tunnel_details_t * mp)
18369 {
18370   vat_main_t *vam = &vat_main;
18371   vat_json_node_t *node = NULL;
18372   struct in_addr ip4;
18373
18374   if (VAT_JSON_ARRAY != vam->json_tree.type)
18375     {
18376       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18377       vat_json_init_array (&vam->json_tree);
18378     }
18379   node = vat_json_array_add (&vam->json_tree);
18380
18381   vat_json_init_object (node);
18382   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18383   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18384   vat_json_object_add_ip4 (node, "src_address", ip4);
18385   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18386   vat_json_object_add_ip4 (node, "dst_address", ip4);
18387   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18388   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18389 }
18390
18391 static int
18392 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18393 {
18394   unformat_input_t *i = vam->input;
18395   vl_api_ipsec_gre_tunnel_dump_t *mp;
18396   vl_api_control_ping_t *mp_ping;
18397   u32 sw_if_index;
18398   u8 sw_if_index_set = 0;
18399   int ret;
18400
18401   /* Parse args required to build the message */
18402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18403     {
18404       if (unformat (i, "sw_if_index %d", &sw_if_index))
18405         sw_if_index_set = 1;
18406       else
18407         break;
18408     }
18409
18410   if (sw_if_index_set == 0)
18411     {
18412       sw_if_index = ~0;
18413     }
18414
18415   if (!vam->json_output)
18416     {
18417       print (vam->ofp, "%11s%15s%15s%14s%14s",
18418              "sw_if_index", "src_address", "dst_address",
18419              "local_sa_id", "remote_sa_id");
18420     }
18421
18422   /* Get list of gre-tunnel interfaces */
18423   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18424
18425   mp->sw_if_index = htonl (sw_if_index);
18426
18427   S (mp);
18428
18429   /* Use a control ping for synchronization */
18430   M (CONTROL_PING, mp_ping);
18431   S (mp_ping);
18432
18433   W (ret);
18434   return ret;
18435 }
18436
18437 static int
18438 api_delete_subif (vat_main_t * vam)
18439 {
18440   unformat_input_t *i = vam->input;
18441   vl_api_delete_subif_t *mp;
18442   u32 sw_if_index = ~0;
18443   int ret;
18444
18445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18446     {
18447       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18448         ;
18449       if (unformat (i, "sw_if_index %d", &sw_if_index))
18450         ;
18451       else
18452         break;
18453     }
18454
18455   if (sw_if_index == ~0)
18456     {
18457       errmsg ("missing sw_if_index");
18458       return -99;
18459     }
18460
18461   /* Construct the API message */
18462   M (DELETE_SUBIF, mp);
18463   mp->sw_if_index = ntohl (sw_if_index);
18464
18465   S (mp);
18466   W (ret);
18467   return ret;
18468 }
18469
18470 #define foreach_pbb_vtr_op      \
18471 _("disable",  L2_VTR_DISABLED)  \
18472 _("pop",  L2_VTR_POP_2)         \
18473 _("push",  L2_VTR_PUSH_2)
18474
18475 static int
18476 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18477 {
18478   unformat_input_t *i = vam->input;
18479   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18480   u32 sw_if_index = ~0, vtr_op = ~0;
18481   u16 outer_tag = ~0;
18482   u8 dmac[6], smac[6];
18483   u8 dmac_set = 0, smac_set = 0;
18484   u16 vlanid = 0;
18485   u32 sid = ~0;
18486   u32 tmp;
18487   int ret;
18488
18489   /* Shut up coverity */
18490   memset (dmac, 0, sizeof (dmac));
18491   memset (smac, 0, sizeof (smac));
18492
18493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18494     {
18495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18496         ;
18497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18498         ;
18499       else if (unformat (i, "vtr_op %d", &vtr_op))
18500         ;
18501 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18502       foreach_pbb_vtr_op
18503 #undef _
18504         else if (unformat (i, "translate_pbb_stag"))
18505         {
18506           if (unformat (i, "%d", &tmp))
18507             {
18508               vtr_op = L2_VTR_TRANSLATE_2_1;
18509               outer_tag = tmp;
18510             }
18511           else
18512             {
18513               errmsg
18514                 ("translate_pbb_stag operation requires outer tag definition");
18515               return -99;
18516             }
18517         }
18518       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18519         dmac_set++;
18520       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18521         smac_set++;
18522       else if (unformat (i, "sid %d", &sid))
18523         ;
18524       else if (unformat (i, "vlanid %d", &tmp))
18525         vlanid = tmp;
18526       else
18527         {
18528           clib_warning ("parse error '%U'", format_unformat_error, i);
18529           return -99;
18530         }
18531     }
18532
18533   if ((sw_if_index == ~0) || (vtr_op == ~0))
18534     {
18535       errmsg ("missing sw_if_index or vtr operation");
18536       return -99;
18537     }
18538   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18539       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18540     {
18541       errmsg
18542         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18543       return -99;
18544     }
18545
18546   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18547   mp->sw_if_index = ntohl (sw_if_index);
18548   mp->vtr_op = ntohl (vtr_op);
18549   mp->outer_tag = ntohs (outer_tag);
18550   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18551   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18552   mp->b_vlanid = ntohs (vlanid);
18553   mp->i_sid = ntohl (sid);
18554
18555   S (mp);
18556   W (ret);
18557   return ret;
18558 }
18559
18560 static int
18561 api_flow_classify_set_interface (vat_main_t * vam)
18562 {
18563   unformat_input_t *i = vam->input;
18564   vl_api_flow_classify_set_interface_t *mp;
18565   u32 sw_if_index;
18566   int sw_if_index_set;
18567   u32 ip4_table_index = ~0;
18568   u32 ip6_table_index = ~0;
18569   u8 is_add = 1;
18570   int ret;
18571
18572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18573     {
18574       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18575         sw_if_index_set = 1;
18576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18577         sw_if_index_set = 1;
18578       else if (unformat (i, "del"))
18579         is_add = 0;
18580       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18581         ;
18582       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18583         ;
18584       else
18585         {
18586           clib_warning ("parse error '%U'", format_unformat_error, i);
18587           return -99;
18588         }
18589     }
18590
18591   if (sw_if_index_set == 0)
18592     {
18593       errmsg ("missing interface name or sw_if_index");
18594       return -99;
18595     }
18596
18597   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18598
18599   mp->sw_if_index = ntohl (sw_if_index);
18600   mp->ip4_table_index = ntohl (ip4_table_index);
18601   mp->ip6_table_index = ntohl (ip6_table_index);
18602   mp->is_add = is_add;
18603
18604   S (mp);
18605   W (ret);
18606   return ret;
18607 }
18608
18609 static int
18610 api_flow_classify_dump (vat_main_t * vam)
18611 {
18612   unformat_input_t *i = vam->input;
18613   vl_api_flow_classify_dump_t *mp;
18614   vl_api_control_ping_t *mp_ping;
18615   u8 type = FLOW_CLASSIFY_N_TABLES;
18616   int ret;
18617
18618   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18619     ;
18620   else
18621     {
18622       errmsg ("classify table type must be specified");
18623       return -99;
18624     }
18625
18626   if (!vam->json_output)
18627     {
18628       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18629     }
18630
18631   M (FLOW_CLASSIFY_DUMP, mp);
18632   mp->type = type;
18633   /* send it... */
18634   S (mp);
18635
18636   /* Use a control ping for synchronization */
18637   M (CONTROL_PING, mp_ping);
18638   S (mp_ping);
18639
18640   /* Wait for a reply... */
18641   W (ret);
18642   return ret;
18643 }
18644
18645 static int
18646 api_feature_enable_disable (vat_main_t * vam)
18647 {
18648   unformat_input_t *i = vam->input;
18649   vl_api_feature_enable_disable_t *mp;
18650   u8 *arc_name = 0;
18651   u8 *feature_name = 0;
18652   u32 sw_if_index = ~0;
18653   u8 enable = 1;
18654   int ret;
18655
18656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18657     {
18658       if (unformat (i, "arc_name %s", &arc_name))
18659         ;
18660       else if (unformat (i, "feature_name %s", &feature_name))
18661         ;
18662       else
18663         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18664         ;
18665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18666         ;
18667       else if (unformat (i, "disable"))
18668         enable = 0;
18669       else
18670         break;
18671     }
18672
18673   if (arc_name == 0)
18674     {
18675       errmsg ("missing arc name");
18676       return -99;
18677     }
18678   if (vec_len (arc_name) > 63)
18679     {
18680       errmsg ("arc name too long");
18681     }
18682
18683   if (feature_name == 0)
18684     {
18685       errmsg ("missing feature name");
18686       return -99;
18687     }
18688   if (vec_len (feature_name) > 63)
18689     {
18690       errmsg ("feature name too long");
18691     }
18692
18693   if (sw_if_index == ~0)
18694     {
18695       errmsg ("missing interface name or sw_if_index");
18696       return -99;
18697     }
18698
18699   /* Construct the API message */
18700   M (FEATURE_ENABLE_DISABLE, mp);
18701   mp->sw_if_index = ntohl (sw_if_index);
18702   mp->enable = enable;
18703   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18704   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18705   vec_free (arc_name);
18706   vec_free (feature_name);
18707
18708   S (mp);
18709   W (ret);
18710   return ret;
18711 }
18712
18713 static int
18714 api_sw_interface_tag_add_del (vat_main_t * vam)
18715 {
18716   unformat_input_t *i = vam->input;
18717   vl_api_sw_interface_tag_add_del_t *mp;
18718   u32 sw_if_index = ~0;
18719   u8 *tag = 0;
18720   u8 enable = 1;
18721   int ret;
18722
18723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18724     {
18725       if (unformat (i, "tag %s", &tag))
18726         ;
18727       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18728         ;
18729       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18730         ;
18731       else if (unformat (i, "del"))
18732         enable = 0;
18733       else
18734         break;
18735     }
18736
18737   if (sw_if_index == ~0)
18738     {
18739       errmsg ("missing interface name or sw_if_index");
18740       return -99;
18741     }
18742
18743   if (enable && (tag == 0))
18744     {
18745       errmsg ("no tag specified");
18746       return -99;
18747     }
18748
18749   /* Construct the API message */
18750   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18751   mp->sw_if_index = ntohl (sw_if_index);
18752   mp->is_add = enable;
18753   if (enable)
18754     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18755   vec_free (tag);
18756
18757   S (mp);
18758   W (ret);
18759   return ret;
18760 }
18761
18762 static void vl_api_l2_xconnect_details_t_handler
18763   (vl_api_l2_xconnect_details_t * mp)
18764 {
18765   vat_main_t *vam = &vat_main;
18766
18767   print (vam->ofp, "%15d%15d",
18768          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18769 }
18770
18771 static void vl_api_l2_xconnect_details_t_handler_json
18772   (vl_api_l2_xconnect_details_t * mp)
18773 {
18774   vat_main_t *vam = &vat_main;
18775   vat_json_node_t *node = NULL;
18776
18777   if (VAT_JSON_ARRAY != vam->json_tree.type)
18778     {
18779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18780       vat_json_init_array (&vam->json_tree);
18781     }
18782   node = vat_json_array_add (&vam->json_tree);
18783
18784   vat_json_init_object (node);
18785   vat_json_object_add_uint (node, "rx_sw_if_index",
18786                             ntohl (mp->rx_sw_if_index));
18787   vat_json_object_add_uint (node, "tx_sw_if_index",
18788                             ntohl (mp->tx_sw_if_index));
18789 }
18790
18791 static int
18792 api_l2_xconnect_dump (vat_main_t * vam)
18793 {
18794   vl_api_l2_xconnect_dump_t *mp;
18795   vl_api_control_ping_t *mp_ping;
18796   int ret;
18797
18798   if (!vam->json_output)
18799     {
18800       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18801     }
18802
18803   M (L2_XCONNECT_DUMP, mp);
18804
18805   S (mp);
18806
18807   /* Use a control ping for synchronization */
18808   M (CONTROL_PING, mp_ping);
18809   S (mp_ping);
18810
18811   W (ret);
18812   return ret;
18813 }
18814
18815 static int
18816 api_sw_interface_set_mtu (vat_main_t * vam)
18817 {
18818   unformat_input_t *i = vam->input;
18819   vl_api_sw_interface_set_mtu_t *mp;
18820   u32 sw_if_index = ~0;
18821   u32 mtu = 0;
18822   int ret;
18823
18824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18825     {
18826       if (unformat (i, "mtu %d", &mtu))
18827         ;
18828       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18829         ;
18830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18831         ;
18832       else
18833         break;
18834     }
18835
18836   if (sw_if_index == ~0)
18837     {
18838       errmsg ("missing interface name or sw_if_index");
18839       return -99;
18840     }
18841
18842   if (mtu == 0)
18843     {
18844       errmsg ("no mtu specified");
18845       return -99;
18846     }
18847
18848   /* Construct the API message */
18849   M (SW_INTERFACE_SET_MTU, mp);
18850   mp->sw_if_index = ntohl (sw_if_index);
18851   mp->mtu = ntohs ((u16) mtu);
18852
18853   S (mp);
18854   W (ret);
18855   return ret;
18856 }
18857
18858 static int
18859 api_p2p_ethernet_add (vat_main_t * vam)
18860 {
18861   unformat_input_t *i = vam->input;
18862   vl_api_p2p_ethernet_add_t *mp;
18863   u32 parent_if_index = ~0;
18864   u8 remote_mac[6];
18865   u8 mac_set = 0;
18866   int ret;
18867
18868   memset (remote_mac, 0, sizeof (remote_mac));
18869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18870     {
18871       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
18872         ;
18873       else if (unformat (i, "sw_if_index %d", &parent_if_index))
18874         ;
18875       else
18876         if (unformat
18877             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
18878         mac_set++;
18879       else
18880         {
18881           clib_warning ("parse error '%U'", format_unformat_error, i);
18882           return -99;
18883         }
18884     }
18885
18886   if (parent_if_index == ~0)
18887     {
18888       errmsg ("missing interface name or sw_if_index");
18889       return -99;
18890     }
18891   if (mac_set == 0)
18892     {
18893       errmsg ("missing remote mac address");
18894       return -99;
18895     }
18896
18897   M (P2P_ETHERNET_ADD, mp);
18898   mp->parent_if_index = ntohl (parent_if_index);
18899   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
18900
18901   S (mp);
18902   W (ret);
18903   return ret;
18904 }
18905
18906 static int
18907 api_p2p_ethernet_del (vat_main_t * vam)
18908 {
18909   unformat_input_t *i = vam->input;
18910   vl_api_p2p_ethernet_del_t *mp;
18911   u32 parent_if_index = ~0;
18912   u8 remote_mac[6];
18913   u8 mac_set = 0;
18914   int ret;
18915
18916   memset (remote_mac, 0, sizeof (remote_mac));
18917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18918     {
18919       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
18920         ;
18921       else if (unformat (i, "sw_if_index %d", &parent_if_index))
18922         ;
18923       else
18924         if (unformat
18925             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
18926         mac_set++;
18927       else
18928         {
18929           clib_warning ("parse error '%U'", format_unformat_error, i);
18930           return -99;
18931         }
18932     }
18933
18934   if (parent_if_index == ~0)
18935     {
18936       errmsg ("missing interface name or sw_if_index");
18937       return -99;
18938     }
18939   if (mac_set == 0)
18940     {
18941       errmsg ("missing remote mac address");
18942       return -99;
18943     }
18944
18945   M (P2P_ETHERNET_DEL, mp);
18946   mp->parent_if_index = ntohl (parent_if_index);
18947   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
18948
18949   S (mp);
18950   W (ret);
18951   return ret;
18952 }
18953
18954 static int
18955 q_or_quit (vat_main_t * vam)
18956 {
18957 #if VPP_API_TEST_BUILTIN == 0
18958   longjmp (vam->jump_buf, 1);
18959 #endif
18960   return 0;                     /* not so much */
18961 }
18962
18963 static int
18964 q (vat_main_t * vam)
18965 {
18966   return q_or_quit (vam);
18967 }
18968
18969 static int
18970 quit (vat_main_t * vam)
18971 {
18972   return q_or_quit (vam);
18973 }
18974
18975 static int
18976 comment (vat_main_t * vam)
18977 {
18978   return 0;
18979 }
18980
18981 static int
18982 cmd_cmp (void *a1, void *a2)
18983 {
18984   u8 **c1 = a1;
18985   u8 **c2 = a2;
18986
18987   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18988 }
18989
18990 static int
18991 help (vat_main_t * vam)
18992 {
18993   u8 **cmds = 0;
18994   u8 *name = 0;
18995   hash_pair_t *p;
18996   unformat_input_t *i = vam->input;
18997   int j;
18998
18999   if (unformat (i, "%s", &name))
19000     {
19001       uword *hs;
19002
19003       vec_add1 (name, 0);
19004
19005       hs = hash_get_mem (vam->help_by_name, name);
19006       if (hs)
19007         print (vam->ofp, "usage: %s %s", name, hs[0]);
19008       else
19009         print (vam->ofp, "No such msg / command '%s'", name);
19010       vec_free (name);
19011       return 0;
19012     }
19013
19014   print (vam->ofp, "Help is available for the following:");
19015
19016     /* *INDENT-OFF* */
19017     hash_foreach_pair (p, vam->function_by_name,
19018     ({
19019       vec_add1 (cmds, (u8 *)(p->key));
19020     }));
19021     /* *INDENT-ON* */
19022
19023   vec_sort_with_function (cmds, cmd_cmp);
19024
19025   for (j = 0; j < vec_len (cmds); j++)
19026     print (vam->ofp, "%s", cmds[j]);
19027
19028   vec_free (cmds);
19029   return 0;
19030 }
19031
19032 static int
19033 set (vat_main_t * vam)
19034 {
19035   u8 *name = 0, *value = 0;
19036   unformat_input_t *i = vam->input;
19037
19038   if (unformat (i, "%s", &name))
19039     {
19040       /* The input buffer is a vector, not a string. */
19041       value = vec_dup (i->buffer);
19042       vec_delete (value, i->index, 0);
19043       /* Almost certainly has a trailing newline */
19044       if (value[vec_len (value) - 1] == '\n')
19045         value[vec_len (value) - 1] = 0;
19046       /* Make sure it's a proper string, one way or the other */
19047       vec_add1 (value, 0);
19048       (void) clib_macro_set_value (&vam->macro_main,
19049                                    (char *) name, (char *) value);
19050     }
19051   else
19052     errmsg ("usage: set <name> <value>");
19053
19054   vec_free (name);
19055   vec_free (value);
19056   return 0;
19057 }
19058
19059 static int
19060 unset (vat_main_t * vam)
19061 {
19062   u8 *name = 0;
19063
19064   if (unformat (vam->input, "%s", &name))
19065     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19066       errmsg ("unset: %s wasn't set", name);
19067   vec_free (name);
19068   return 0;
19069 }
19070
19071 typedef struct
19072 {
19073   u8 *name;
19074   u8 *value;
19075 } macro_sort_t;
19076
19077
19078 static int
19079 macro_sort_cmp (void *a1, void *a2)
19080 {
19081   macro_sort_t *s1 = a1;
19082   macro_sort_t *s2 = a2;
19083
19084   return strcmp ((char *) (s1->name), (char *) (s2->name));
19085 }
19086
19087 static int
19088 dump_macro_table (vat_main_t * vam)
19089 {
19090   macro_sort_t *sort_me = 0, *sm;
19091   int i;
19092   hash_pair_t *p;
19093
19094     /* *INDENT-OFF* */
19095     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19096     ({
19097       vec_add2 (sort_me, sm, 1);
19098       sm->name = (u8 *)(p->key);
19099       sm->value = (u8 *) (p->value[0]);
19100     }));
19101     /* *INDENT-ON* */
19102
19103   vec_sort_with_function (sort_me, macro_sort_cmp);
19104
19105   if (vec_len (sort_me))
19106     print (vam->ofp, "%-15s%s", "Name", "Value");
19107   else
19108     print (vam->ofp, "The macro table is empty...");
19109
19110   for (i = 0; i < vec_len (sort_me); i++)
19111     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19112   return 0;
19113 }
19114
19115 static int
19116 dump_node_table (vat_main_t * vam)
19117 {
19118   int i, j;
19119   vlib_node_t *node, *next_node;
19120
19121   if (vec_len (vam->graph_nodes) == 0)
19122     {
19123       print (vam->ofp, "Node table empty, issue get_node_graph...");
19124       return 0;
19125     }
19126
19127   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19128     {
19129       node = vam->graph_nodes[i];
19130       print (vam->ofp, "[%d] %s", i, node->name);
19131       for (j = 0; j < vec_len (node->next_nodes); j++)
19132         {
19133           if (node->next_nodes[j] != ~0)
19134             {
19135               next_node = vam->graph_nodes[node->next_nodes[j]];
19136               print (vam->ofp, "  [%d] %s", j, next_node->name);
19137             }
19138         }
19139     }
19140   return 0;
19141 }
19142
19143 static int
19144 value_sort_cmp (void *a1, void *a2)
19145 {
19146   name_sort_t *n1 = a1;
19147   name_sort_t *n2 = a2;
19148
19149   if (n1->value < n2->value)
19150     return -1;
19151   if (n1->value > n2->value)
19152     return 1;
19153   return 0;
19154 }
19155
19156
19157 static int
19158 dump_msg_api_table (vat_main_t * vam)
19159 {
19160   api_main_t *am = &api_main;
19161   name_sort_t *nses = 0, *ns;
19162   hash_pair_t *hp;
19163   int i;
19164
19165   /* *INDENT-OFF* */
19166   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19167   ({
19168     vec_add2 (nses, ns, 1);
19169     ns->name = (u8 *)(hp->key);
19170     ns->value = (u32) hp->value[0];
19171   }));
19172   /* *INDENT-ON* */
19173
19174   vec_sort_with_function (nses, value_sort_cmp);
19175
19176   for (i = 0; i < vec_len (nses); i++)
19177     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19178   vec_free (nses);
19179   return 0;
19180 }
19181
19182 static int
19183 get_msg_id (vat_main_t * vam)
19184 {
19185   u8 *name_and_crc;
19186   u32 message_index;
19187
19188   if (unformat (vam->input, "%s", &name_and_crc))
19189     {
19190       message_index = vl_api_get_msg_index (name_and_crc);
19191       if (message_index == ~0)
19192         {
19193           print (vam->ofp, " '%s' not found", name_and_crc);
19194           return 0;
19195         }
19196       print (vam->ofp, " '%s' has message index %d",
19197              name_and_crc, message_index);
19198       return 0;
19199     }
19200   errmsg ("name_and_crc required...");
19201   return 0;
19202 }
19203
19204 static int
19205 search_node_table (vat_main_t * vam)
19206 {
19207   unformat_input_t *line_input = vam->input;
19208   u8 *node_to_find;
19209   int j;
19210   vlib_node_t *node, *next_node;
19211   uword *p;
19212
19213   if (vam->graph_node_index_by_name == 0)
19214     {
19215       print (vam->ofp, "Node table empty, issue get_node_graph...");
19216       return 0;
19217     }
19218
19219   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19220     {
19221       if (unformat (line_input, "%s", &node_to_find))
19222         {
19223           vec_add1 (node_to_find, 0);
19224           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19225           if (p == 0)
19226             {
19227               print (vam->ofp, "%s not found...", node_to_find);
19228               goto out;
19229             }
19230           node = vam->graph_nodes[p[0]];
19231           print (vam->ofp, "[%d] %s", p[0], node->name);
19232           for (j = 0; j < vec_len (node->next_nodes); j++)
19233             {
19234               if (node->next_nodes[j] != ~0)
19235                 {
19236                   next_node = vam->graph_nodes[node->next_nodes[j]];
19237                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19238                 }
19239             }
19240         }
19241
19242       else
19243         {
19244           clib_warning ("parse error '%U'", format_unformat_error,
19245                         line_input);
19246           return -99;
19247         }
19248
19249     out:
19250       vec_free (node_to_find);
19251
19252     }
19253
19254   return 0;
19255 }
19256
19257
19258 static int
19259 script (vat_main_t * vam)
19260 {
19261 #if (VPP_API_TEST_BUILTIN==0)
19262   u8 *s = 0;
19263   char *save_current_file;
19264   unformat_input_t save_input;
19265   jmp_buf save_jump_buf;
19266   u32 save_line_number;
19267
19268   FILE *new_fp, *save_ifp;
19269
19270   if (unformat (vam->input, "%s", &s))
19271     {
19272       new_fp = fopen ((char *) s, "r");
19273       if (new_fp == 0)
19274         {
19275           errmsg ("Couldn't open script file %s", s);
19276           vec_free (s);
19277           return -99;
19278         }
19279     }
19280   else
19281     {
19282       errmsg ("Missing script name");
19283       return -99;
19284     }
19285
19286   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19287   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19288   save_ifp = vam->ifp;
19289   save_line_number = vam->input_line_number;
19290   save_current_file = (char *) vam->current_file;
19291
19292   vam->input_line_number = 0;
19293   vam->ifp = new_fp;
19294   vam->current_file = s;
19295   do_one_file (vam);
19296
19297   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19298   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19299   vam->ifp = save_ifp;
19300   vam->input_line_number = save_line_number;
19301   vam->current_file = (u8 *) save_current_file;
19302   vec_free (s);
19303
19304   return 0;
19305 #else
19306   clib_warning ("use the exec command...");
19307   return -99;
19308 #endif
19309 }
19310
19311 static int
19312 echo (vat_main_t * vam)
19313 {
19314   print (vam->ofp, "%v", vam->input->buffer);
19315   return 0;
19316 }
19317
19318 /* List of API message constructors, CLI names map to api_xxx */
19319 #define foreach_vpe_api_msg                                             \
19320 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19321 _(sw_interface_dump,"")                                                 \
19322 _(sw_interface_set_flags,                                               \
19323   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19324 _(sw_interface_add_del_address,                                         \
19325   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19326 _(sw_interface_set_table,                                               \
19327   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19328 _(sw_interface_set_mpls_enable,                                         \
19329   "<intfc> | sw_if_index [disable | dis]")                              \
19330 _(sw_interface_set_vpath,                                               \
19331   "<intfc> | sw_if_index <id> enable | disable")                        \
19332 _(sw_interface_set_vxlan_bypass,                                        \
19333   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19334 _(sw_interface_set_l2_xconnect,                                         \
19335   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19336   "enable | disable")                                                   \
19337 _(sw_interface_set_l2_bridge,                                           \
19338   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19339   "[shg <split-horizon-group>] [bvi]\n"                                 \
19340   "enable | disable")                                                   \
19341 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19342 _(bridge_domain_add_del,                                                \
19343   "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] [del]\n") \
19344 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19345 _(l2fib_add_del,                                                        \
19346   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19347 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19348 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19349 _(l2_flags,                                                             \
19350   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
19351 _(bridge_flags,                                                         \
19352   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19353 _(tap_connect,                                                          \
19354   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19355 _(tap_modify,                                                           \
19356   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19357 _(tap_delete,                                                           \
19358   "<vpp-if-name> | sw_if_index <id>")                                   \
19359 _(sw_interface_tap_dump, "")                                            \
19360 _(ip_add_del_route,                                                     \
19361   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19362   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19363   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19364   "[multipath] [count <n>]")                                            \
19365 _(ip_mroute_add_del,                                                    \
19366   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19367   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19368 _(mpls_route_add_del,                                                   \
19369   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19370   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19371   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19372   "[multipath] [count <n>]")                                            \
19373 _(mpls_ip_bind_unbind,                                                  \
19374   "<label> <addr/len>")                                                 \
19375 _(mpls_tunnel_add_del,                                                  \
19376   " via <addr> [table-id <n>]\n"                                        \
19377   "sw_if_index <id>] [l2]  [del]")                                      \
19378 _(proxy_arp_add_del,                                                    \
19379   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19380 _(proxy_arp_intfc_enable_disable,                                       \
19381   "<intfc> | sw_if_index <id> enable | disable")                        \
19382 _(sw_interface_set_unnumbered,                                          \
19383   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19384 _(ip_neighbor_add_del,                                                  \
19385   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19386   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19387 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19388 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19389 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19390   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19391   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19392   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19393 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19394 _(reset_fib, "vrf <n> [ipv6]")                                          \
19395 _(dhcp_proxy_config,                                                    \
19396   "svr <v46-address> src <v46-address>\n"                               \
19397    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19398 _(dhcp_proxy_set_vss,                                                   \
19399   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19400 _(dhcp_proxy_dump, "ip6")                                               \
19401 _(dhcp_client_config,                                                   \
19402   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19403 _(set_ip_flow_hash,                                                     \
19404   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19405 _(sw_interface_ip6_enable_disable,                                      \
19406   "<intfc> | sw_if_index <id> enable | disable")                        \
19407 _(sw_interface_ip6_set_link_local_address,                              \
19408   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19409 _(ip6nd_proxy_add_del,                                                  \
19410   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19411 _(ip6nd_proxy_dump, "")                                                 \
19412 _(sw_interface_ip6nd_ra_prefix,                                         \
19413   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19414   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19415   "[nolink] [isno]")                                                    \
19416 _(sw_interface_ip6nd_ra_config,                                         \
19417   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19418   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19419   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19420 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19421 _(l2_patch_add_del,                                                     \
19422   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19423   "enable | disable")                                                   \
19424 _(sr_localsid_add_del,                                                  \
19425   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19426   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19427 _(classify_add_del_table,                                               \
19428   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19429   " [del] [del-chain] mask <mask-value>\n"                              \
19430   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19431   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19432 _(classify_add_del_session,                                             \
19433   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19434   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19435   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19436   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19437 _(classify_set_interface_ip_table,                                      \
19438   "<intfc> | sw_if_index <nn> table <nn>")                              \
19439 _(classify_set_interface_l2_tables,                                     \
19440   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19441   "  [other-table <nn>]")                                               \
19442 _(get_node_index, "node <node-name")                                    \
19443 _(add_node_next, "node <node-name> next <next-node-name>")              \
19444 _(l2tpv3_create_tunnel,                                                 \
19445   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
19446   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
19447   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
19448 _(l2tpv3_set_tunnel_cookies,                                            \
19449   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
19450   "[new_remote_cookie <nn>]\n")                                         \
19451 _(l2tpv3_interface_enable_disable,                                      \
19452   "<intfc> | sw_if_index <nn> enable | disable")                        \
19453 _(l2tpv3_set_lookup_key,                                                \
19454   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
19455 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
19456 _(vxlan_add_del_tunnel,                                                 \
19457   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
19458   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19459   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
19460 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
19461 _(gre_add_del_tunnel,                                                   \
19462   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
19463 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
19464 _(l2_fib_clear_table, "")                                               \
19465 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
19466 _(l2_interface_vlan_tag_rewrite,                                        \
19467   "<intfc> | sw_if_index <nn> \n"                                       \
19468   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19469   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19470 _(create_vhost_user_if,                                                 \
19471         "socket <filename> [server] [renumber <dev_instance>] "         \
19472         "[mac <mac_address>]")                                          \
19473 _(modify_vhost_user_if,                                                 \
19474         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19475         "[server] [renumber <dev_instance>]")                           \
19476 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19477 _(sw_interface_vhost_user_dump, "")                                     \
19478 _(show_version, "")                                                     \
19479 _(vxlan_gpe_add_del_tunnel,                                             \
19480   "local <addr> remote <addr> vni <nn>\n"                               \
19481     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
19482   "[next-ethernet] [next-nsh]\n")                                       \
19483 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19484 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19485 _(interface_name_renumber,                                              \
19486   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19487 _(input_acl_set_interface,                                              \
19488   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19489   "  [l2-table <nn>] [del]")                                            \
19490 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19491 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19492 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19493 _(ip_dump, "ipv4 | ipv6")                                               \
19494 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19495 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19496   "  spid_id <n> ")                                                     \
19497 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19498   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19499   "  integ_alg <alg> integ_key <hex>")                                  \
19500 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19501   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19502   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19503   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19504 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19505 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19506   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19507   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19508   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19509 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19510 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19511   "(auth_data 0x<data> | auth_data <data>)")                            \
19512 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19513   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19514 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
19515   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19516   "(local|remote)")                                                     \
19517 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
19518 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19519 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19520 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19521 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19522 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19523 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19524 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19525 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19526 _(delete_loopback,"sw_if_index <nn>")                                   \
19527 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19528 _(map_add_domain,                                                       \
19529   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19530   "ip6-src <ip6addr> "                                                  \
19531   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19532 _(map_del_domain, "index <n>")                                          \
19533 _(map_add_del_rule,                                                     \
19534   "index <n> psid <n> dst <ip6addr> [del]")                             \
19535 _(map_domain_dump, "")                                                  \
19536 _(map_rule_dump, "index <map-domain>")                                  \
19537 _(want_interface_events,  "enable|disable")                             \
19538 _(want_stats,"enable|disable")                                          \
19539 _(get_first_msg_id, "client <name>")                                    \
19540 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19541 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19542   "fib-id <nn> [ip4][ip6][default]")                                    \
19543 _(get_node_graph, " ")                                                  \
19544 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19545 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19546 _(ioam_disable, "")                                                     \
19547 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19548                             " sw_if_index <sw_if_index> p <priority> "  \
19549                             "w <weight>] [del]")                        \
19550 _(one_add_del_locator, "locator-set <locator_name> "                    \
19551                         "iface <intf> | sw_if_index <sw_if_index> "     \
19552                         "p <priority> w <weight> [del]")                \
19553 _(one_add_del_local_eid,"vni <vni> eid "                                \
19554                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19555                          "locator-set <locator_name> [del]"             \
19556                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19557 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19558 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19559 _(one_enable_disable, "enable|disable")                                 \
19560 _(one_map_register_enable_disable, "enable|disable")                    \
19561 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19562 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19563                                "[seid <seid>] "                         \
19564                                "rloc <locator> p <prio> "               \
19565                                "w <weight> [rloc <loc> ... ] "          \
19566                                "action <action> [del-all]")             \
19567 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19568                           "<local-eid>")                                \
19569 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19570 _(one_use_petr, "ip-address> | disable")                                \
19571 _(one_map_request_mode, "src-dst|dst-only")                             \
19572 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19573 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19574 _(one_locator_set_dump, "[local | remote]")                             \
19575 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19576 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19577                        "[local] | [remote]")                            \
19578 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
19579 _(one_l2_arp_bd_get, "")                                                \
19580 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
19581 _(one_stats_enable_disable, "enable|disalbe")                           \
19582 _(show_one_stats_enable_disable, "")                                    \
19583 _(one_eid_table_vni_dump, "")                                           \
19584 _(one_eid_table_map_dump, "l2|l3")                                      \
19585 _(one_map_resolver_dump, "")                                            \
19586 _(one_map_server_dump, "")                                              \
19587 _(one_adjacencies_get, "vni <vni>")                                     \
19588 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
19589 _(show_one_rloc_probe_state, "")                                        \
19590 _(show_one_map_register_state, "")                                      \
19591 _(show_one_status, "")                                                  \
19592 _(one_stats_dump, "")                                                   \
19593 _(one_stats_flush, "")                                                  \
19594 _(one_get_map_request_itr_rlocs, "")                                    \
19595 _(show_one_nsh_mapping, "")                                             \
19596 _(show_one_pitr, "")                                                    \
19597 _(show_one_use_petr, "")                                                \
19598 _(show_one_map_request_mode, "")                                        \
19599 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19600                             " sw_if_index <sw_if_index> p <priority> "  \
19601                             "w <weight>] [del]")                        \
19602 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19603                         "iface <intf> | sw_if_index <sw_if_index> "     \
19604                         "p <priority> w <weight> [del]")                \
19605 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19606                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19607                          "locator-set <locator_name> [del]"             \
19608                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19609 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19610 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19611 _(lisp_enable_disable, "enable|disable")                                \
19612 _(lisp_map_register_enable_disable, "enable|disable")                   \
19613 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19614 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19615                                "[seid <seid>] "                         \
19616                                "rloc <locator> p <prio> "               \
19617                                "w <weight> [rloc <loc> ... ] "          \
19618                                "action <action> [del-all]")             \
19619 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19620                           "<local-eid>")                                \
19621 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19622 _(lisp_use_petr, "<ip-address> | disable")                              \
19623 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19624 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19625 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19626 _(lisp_locator_set_dump, "[local | remote]")                            \
19627 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19628 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19629                        "[local] | [remote]")                            \
19630 _(lisp_eid_table_vni_dump, "")                                          \
19631 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19632 _(lisp_map_resolver_dump, "")                                           \
19633 _(lisp_map_server_dump, "")                                             \
19634 _(lisp_adjacencies_get, "vni <vni>")                                    \
19635 _(gpe_fwd_entry_vnis_get, "")                                           \
19636 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19637 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19638 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19639 _(gpe_get_encap_mode, "")                                               \
19640 _(lisp_gpe_add_del_iface, "up|down")                                    \
19641 _(lisp_gpe_enable_disable, "enable|disable")                            \
19642 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19643   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19644 _(show_lisp_rloc_probe_state, "")                                       \
19645 _(show_lisp_map_register_state, "")                                     \
19646 _(show_lisp_status, "")                                                 \
19647 _(lisp_get_map_request_itr_rlocs, "")                                   \
19648 _(show_lisp_pitr, "")                                                   \
19649 _(show_lisp_use_petr, "")                                               \
19650 _(show_lisp_map_request_mode, "")                                       \
19651 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19652 _(af_packet_delete, "name <host interface name>")                       \
19653 _(policer_add_del, "name <policer name> <params> [del]")                \
19654 _(policer_dump, "[name <policer name>]")                                \
19655 _(policer_classify_set_interface,                                       \
19656   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19657   "  [l2-table <nn>] [del]")                                            \
19658 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19659 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19660     "[master|slave]")                                                   \
19661 _(netmap_delete, "name <interface name>")                               \
19662 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19663 _(mpls_fib_dump, "")                                                    \
19664 _(classify_table_ids, "")                                               \
19665 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19666 _(classify_table_info, "table_id <nn>")                                 \
19667 _(classify_session_dump, "table_id <nn>")                               \
19668 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19669     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19670     "[template_interval <nn>] [udp_checksum]")                          \
19671 _(ipfix_exporter_dump, "")                                              \
19672 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19673 _(ipfix_classify_stream_dump, "")                                       \
19674 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19675 _(ipfix_classify_table_dump, "")                                        \
19676 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19677 _(sw_interface_span_dump, "")                                           \
19678 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19679 _(pg_create_interface, "if_id <nn>")                                    \
19680 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19681 _(pg_enable_disable, "[stream <id>] disable")                           \
19682 _(ip_source_and_port_range_check_add_del,                               \
19683   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19684 _(ip_source_and_port_range_check_interface_add_del,                     \
19685   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19686   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19687 _(ipsec_gre_add_del_tunnel,                                             \
19688   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19689 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19690 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19691 _(l2_interface_pbb_tag_rewrite,                                         \
19692   "<intfc> | sw_if_index <nn> \n"                                       \
19693   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19694   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19695 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19696 _(flow_classify_set_interface,                                          \
19697   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19698 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19699 _(ip_fib_dump, "")                                                      \
19700 _(ip_mfib_dump, "")                                                     \
19701 _(ip6_fib_dump, "")                                                     \
19702 _(ip6_mfib_dump, "")                                                    \
19703 _(feature_enable_disable, "arc_name <arc_name> "                        \
19704   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19705 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19706 "[disable]")                                                            \
19707 _(l2_xconnect_dump, "")                                                 \
19708 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19709 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19710 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
19711 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
19712 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>")
19713
19714 /* List of command functions, CLI names map directly to functions */
19715 #define foreach_cli_function                                    \
19716 _(comment, "usage: comment <ignore-rest-of-line>")              \
19717 _(dump_interface_table, "usage: dump_interface_table")          \
19718 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19719 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19720 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19721 _(dump_stats_table, "usage: dump_stats_table")                  \
19722 _(dump_macro_table, "usage: dump_macro_table ")                 \
19723 _(dump_node_table, "usage: dump_node_table")                    \
19724 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19725 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19726 _(echo, "usage: echo <message>")                                \
19727 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19728 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19729 _(help, "usage: help")                                          \
19730 _(q, "usage: quit")                                             \
19731 _(quit, "usage: quit")                                          \
19732 _(search_node_table, "usage: search_node_table <name>...")      \
19733 _(set, "usage: set <variable-name> <value>")                    \
19734 _(script, "usage: script <file-name>")                          \
19735 _(unset, "usage: unset <variable-name>")
19736
19737 #define _(N,n)                                  \
19738     static void vl_api_##n##_t_handler_uni      \
19739     (vl_api_##n##_t * mp)                       \
19740     {                                           \
19741         vat_main_t * vam = &vat_main;           \
19742         if (vam->json_output) {                 \
19743             vl_api_##n##_t_handler_json(mp);    \
19744         } else {                                \
19745             vl_api_##n##_t_handler(mp);         \
19746         }                                       \
19747     }
19748 foreach_vpe_api_reply_msg;
19749 #if VPP_API_TEST_BUILTIN == 0
19750 foreach_standalone_reply_msg;
19751 #endif
19752 #undef _
19753
19754 void
19755 vat_api_hookup (vat_main_t * vam)
19756 {
19757 #define _(N,n)                                                  \
19758     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19759                            vl_api_##n##_t_handler_uni,          \
19760                            vl_noop_handler,                     \
19761                            vl_api_##n##_t_endian,               \
19762                            vl_api_##n##_t_print,                \
19763                            sizeof(vl_api_##n##_t), 1);
19764   foreach_vpe_api_reply_msg;
19765 #if VPP_API_TEST_BUILTIN == 0
19766   foreach_standalone_reply_msg;
19767 #endif
19768 #undef _
19769
19770 #if (VPP_API_TEST_BUILTIN==0)
19771   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19772
19773   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19774
19775   vam->function_by_name = hash_create_string (0, sizeof (uword));
19776
19777   vam->help_by_name = hash_create_string (0, sizeof (uword));
19778 #endif
19779
19780   /* API messages we can send */
19781 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19782   foreach_vpe_api_msg;
19783 #undef _
19784
19785   /* Help strings */
19786 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19787   foreach_vpe_api_msg;
19788 #undef _
19789
19790   /* CLI functions */
19791 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19792   foreach_cli_function;
19793 #undef _
19794
19795   /* Help strings */
19796 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19797   foreach_cli_function;
19798 #undef _
19799 }
19800
19801 #if VPP_API_TEST_BUILTIN
19802 static clib_error_t *
19803 vat_api_hookup_shim (vlib_main_t * vm)
19804 {
19805   vat_api_hookup (&vat_main);
19806   return 0;
19807 }
19808
19809 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19810 #endif
19811
19812 /*
19813  * fd.io coding-style-patch-verification: ON
19814  *
19815  * Local Variables:
19816  * eval: (c-set-style "gnu")
19817  * End:
19818  */