L2 over MPLS
[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 static void
1287 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1288 {
1289   u32 n_macs = ntohl (mp->n_macs);
1290   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1291           ntohl (mp->pid), mp->client_index, n_macs);
1292   int i;
1293   for (i = 0; i < n_macs; i++)
1294     {
1295       vl_api_mac_entry_t *mac = &mp->mac[i];
1296       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1297               i + 1, ntohl (mac->sw_if_index),
1298               format_ethernet_address, mac->mac_addr, mac->is_del);
1299       if (i == 1000)
1300         break;
1301     }
1302 }
1303
1304 static void
1305 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1311 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1312
1313 /*
1314  * Special-case: build the bridge domain table, maintain
1315  * the next bd id vbl.
1316  */
1317 static void vl_api_bridge_domain_details_t_handler
1318   (vl_api_bridge_domain_details_t * mp)
1319 {
1320   vat_main_t *vam = &vat_main;
1321   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1322   int i;
1323
1324   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1325          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1326
1327   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1328          ntohl (mp->bd_id), mp->learn, mp->forward,
1329          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1330
1331   if (n_sw_ifs)
1332     {
1333       vl_api_bridge_domain_sw_if_t *sw_ifs;
1334       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1335              "Interface Name");
1336
1337       sw_ifs = mp->sw_if_details;
1338       for (i = 0; i < n_sw_ifs; i++)
1339         {
1340           u8 *sw_if_name = 0;
1341           u32 sw_if_index;
1342           hash_pair_t *p;
1343
1344           sw_if_index = ntohl (sw_ifs->sw_if_index);
1345
1346           /* *INDENT-OFF* */
1347           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1348                              ({
1349                                if ((u32) p->value[0] == sw_if_index)
1350                                  {
1351                                    sw_if_name = (u8 *)(p->key);
1352                                    break;
1353                                  }
1354                              }));
1355           /* *INDENT-ON* */
1356           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1357                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1358                  "sw_if_index not found!");
1359
1360           sw_ifs++;
1361         }
1362     }
1363 }
1364
1365 static void vl_api_bridge_domain_details_t_handler_json
1366   (vl_api_bridge_domain_details_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t *node, *array = NULL;
1370   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1371
1372   if (VAT_JSON_ARRAY != vam->json_tree.type)
1373     {
1374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1375       vat_json_init_array (&vam->json_tree);
1376     }
1377   node = vat_json_array_add (&vam->json_tree);
1378
1379   vat_json_init_object (node);
1380   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1381   vat_json_object_add_uint (node, "flood", mp->flood);
1382   vat_json_object_add_uint (node, "forward", mp->forward);
1383   vat_json_object_add_uint (node, "learn", mp->learn);
1384   vat_json_object_add_uint (node, "bvi_sw_if_index",
1385                             ntohl (mp->bvi_sw_if_index));
1386   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1387   array = vat_json_object_add (node, "sw_if");
1388   vat_json_init_array (array);
1389
1390
1391
1392   if (n_sw_ifs)
1393     {
1394       vl_api_bridge_domain_sw_if_t *sw_ifs;
1395       int i;
1396
1397       sw_ifs = mp->sw_if_details;
1398       for (i = 0; i < n_sw_ifs; i++)
1399         {
1400           node = vat_json_array_add (array);
1401           vat_json_init_object (node);
1402           vat_json_object_add_uint (node, "sw_if_index",
1403                                     ntohl (sw_ifs->sw_if_index));
1404           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1405           sw_ifs++;
1406         }
1407     }
1408 }
1409
1410 static void vl_api_control_ping_reply_t_handler
1411   (vl_api_control_ping_reply_t * mp)
1412 {
1413   vat_main_t *vam = &vat_main;
1414   i32 retval = ntohl (mp->retval);
1415   if (vam->async_mode)
1416     {
1417       vam->async_errors += (retval < 0);
1418     }
1419   else
1420     {
1421       vam->retval = retval;
1422       vam->result_ready = 1;
1423     }
1424 }
1425
1426 static void vl_api_control_ping_reply_t_handler_json
1427   (vl_api_control_ping_reply_t * mp)
1428 {
1429   vat_main_t *vam = &vat_main;
1430   i32 retval = ntohl (mp->retval);
1431
1432   if (VAT_JSON_NONE != vam->json_tree.type)
1433     {
1434       vat_json_print (vam->ofp, &vam->json_tree);
1435       vat_json_free (&vam->json_tree);
1436       vam->json_tree.type = VAT_JSON_NONE;
1437     }
1438   else
1439     {
1440       /* just print [] */
1441       vat_json_init_array (&vam->json_tree);
1442       vat_json_print (vam->ofp, &vam->json_tree);
1443       vam->json_tree.type = VAT_JSON_NONE;
1444     }
1445
1446   vam->retval = retval;
1447   vam->result_ready = 1;
1448 }
1449
1450 static void
1451   vl_api_bridge_domain_set_mac_age_reply_t_handler
1452   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   i32 retval = ntohl (mp->retval);
1456   if (vam->async_mode)
1457     {
1458       vam->async_errors += (retval < 0);
1459     }
1460   else
1461     {
1462       vam->retval = retval;
1463       vam->result_ready = 1;
1464     }
1465 }
1466
1467 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1468   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   vat_json_node_t node;
1472
1473   vat_json_init_object (&node);
1474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1475
1476   vat_json_print (vam->ofp, &node);
1477   vat_json_free (&node);
1478
1479   vam->retval = ntohl (mp->retval);
1480   vam->result_ready = 1;
1481 }
1482
1483 static void
1484 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488   if (vam->async_mode)
1489     {
1490       vam->async_errors += (retval < 0);
1491     }
1492   else
1493     {
1494       vam->retval = retval;
1495       vam->result_ready = 1;
1496     }
1497 }
1498
1499 static void vl_api_l2_flags_reply_t_handler_json
1500   (vl_api_l2_flags_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   vat_json_node_t node;
1504
1505   vat_json_init_object (&node);
1506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1507   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1508                             ntohl (mp->resulting_feature_bitmap));
1509
1510   vat_json_print (vam->ofp, &node);
1511   vat_json_free (&node);
1512
1513   vam->retval = ntohl (mp->retval);
1514   vam->result_ready = 1;
1515 }
1516
1517 static void vl_api_bridge_flags_reply_t_handler
1518   (vl_api_bridge_flags_reply_t * mp)
1519 {
1520   vat_main_t *vam = &vat_main;
1521   i32 retval = ntohl (mp->retval);
1522   if (vam->async_mode)
1523     {
1524       vam->async_errors += (retval < 0);
1525     }
1526   else
1527     {
1528       vam->retval = retval;
1529       vam->result_ready = 1;
1530     }
1531 }
1532
1533 static void vl_api_bridge_flags_reply_t_handler_json
1534   (vl_api_bridge_flags_reply_t * mp)
1535 {
1536   vat_main_t *vam = &vat_main;
1537   vat_json_node_t node;
1538
1539   vat_json_init_object (&node);
1540   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1541   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1542                             ntohl (mp->resulting_feature_bitmap));
1543
1544   vat_json_print (vam->ofp, &node);
1545   vat_json_free (&node);
1546
1547   vam->retval = ntohl (mp->retval);
1548   vam->result_ready = 1;
1549 }
1550
1551 static void vl_api_tap_connect_reply_t_handler
1552   (vl_api_tap_connect_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   i32 retval = ntohl (mp->retval);
1556   if (vam->async_mode)
1557     {
1558       vam->async_errors += (retval < 0);
1559     }
1560   else
1561     {
1562       vam->retval = retval;
1563       vam->sw_if_index = ntohl (mp->sw_if_index);
1564       vam->result_ready = 1;
1565     }
1566
1567 }
1568
1569 static void vl_api_tap_connect_reply_t_handler_json
1570   (vl_api_tap_connect_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1578
1579   vat_json_print (vam->ofp, &node);
1580   vat_json_free (&node);
1581
1582   vam->retval = ntohl (mp->retval);
1583   vam->result_ready = 1;
1584
1585 }
1586
1587 static void
1588 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->sw_if_index = ntohl (mp->sw_if_index);
1600       vam->result_ready = 1;
1601     }
1602 }
1603
1604 static void vl_api_tap_modify_reply_t_handler_json
1605   (vl_api_tap_modify_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   vat_json_node_t node;
1609
1610   vat_json_init_object (&node);
1611   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1612   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void
1622 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->result_ready = 1;
1634     }
1635 }
1636
1637 static void vl_api_tap_delete_reply_t_handler_json
1638   (vl_api_tap_delete_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   vat_json_node_t node;
1642
1643   vat_json_init_object (&node);
1644   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1645
1646   vat_json_print (vam->ofp, &node);
1647   vat_json_free (&node);
1648
1649   vam->retval = ntohl (mp->retval);
1650   vam->result_ready = 1;
1651 }
1652
1653 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1654   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   i32 retval = ntohl (mp->retval);
1658   if (vam->async_mode)
1659     {
1660       vam->async_errors += (retval < 0);
1661     }
1662   else
1663     {
1664       vam->retval = retval;
1665       vam->result_ready = 1;
1666     }
1667 }
1668
1669 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1670   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   vat_json_node_t node;
1674
1675   vat_json_init_object (&node);
1676   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1677   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1678                             ntohl (mp->sw_if_index));
1679
1680   vat_json_print (vam->ofp, &node);
1681   vat_json_free (&node);
1682
1683   vam->retval = ntohl (mp->retval);
1684   vam->result_ready = 1;
1685 }
1686
1687 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1688   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   i32 retval = ntohl (mp->retval);
1692   if (vam->async_mode)
1693     {
1694       vam->async_errors += (retval < 0);
1695     }
1696   else
1697     {
1698       vam->retval = retval;
1699       vam->sw_if_index = ntohl (mp->sw_if_index);
1700       vam->result_ready = 1;
1701     }
1702 }
1703
1704 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1705   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   vat_json_node_t node;
1709
1710   vat_json_init_object (&node);
1711   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1712   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1713
1714   vat_json_print (vam->ofp, &node);
1715   vat_json_free (&node);
1716
1717   vam->retval = ntohl (mp->retval);
1718   vam->result_ready = 1;
1719 }
1720
1721 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1722   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1723 {
1724   vat_main_t *vam = &vat_main;
1725   i32 retval = ntohl (mp->retval);
1726   if (vam->async_mode)
1727     {
1728       vam->async_errors += (retval < 0);
1729     }
1730   else
1731     {
1732       vam->retval = retval;
1733       vam->result_ready = 1;
1734     }
1735 }
1736
1737 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1738   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   vat_json_node_t node;
1742
1743   vat_json_init_object (&node);
1744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1745   vat_json_object_add_uint (&node, "fwd_entry_index",
1746                             clib_net_to_host_u32 (mp->fwd_entry_index));
1747
1748   vat_json_print (vam->ofp, &node);
1749   vat_json_free (&node);
1750
1751   vam->retval = ntohl (mp->retval);
1752   vam->result_ready = 1;
1753 }
1754
1755 static void vl_api_one_add_del_locator_set_reply_t_handler
1756   (vl_api_one_add_del_locator_set_reply_t * mp)
1757 {
1758   vat_main_t *vam = &vat_main;
1759   i32 retval = ntohl (mp->retval);
1760   if (vam->async_mode)
1761     {
1762       vam->async_errors += (retval < 0);
1763     }
1764   else
1765     {
1766       vam->retval = retval;
1767       vam->result_ready = 1;
1768     }
1769 }
1770
1771 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1772   (vl_api_one_add_del_locator_set_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   vat_json_node_t node;
1776
1777   vat_json_init_object (&node);
1778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1779   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1780
1781   vat_json_print (vam->ofp, &node);
1782   vat_json_free (&node);
1783
1784   vam->retval = ntohl (mp->retval);
1785   vam->result_ready = 1;
1786 }
1787
1788 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1789   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1790 {
1791   vat_main_t *vam = &vat_main;
1792   i32 retval = ntohl (mp->retval);
1793   if (vam->async_mode)
1794     {
1795       vam->async_errors += (retval < 0);
1796     }
1797   else
1798     {
1799       vam->retval = retval;
1800       vam->sw_if_index = ntohl (mp->sw_if_index);
1801       vam->result_ready = 1;
1802     }
1803 }
1804
1805 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1806   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   vat_json_node_t node;
1810
1811   vat_json_init_object (&node);
1812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1813   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1814
1815   vat_json_print (vam->ofp, &node);
1816   vat_json_free (&node);
1817
1818   vam->retval = ntohl (mp->retval);
1819   vam->result_ready = 1;
1820 }
1821
1822 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1823   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1824 {
1825   vat_main_t *vam = &vat_main;
1826   i32 retval = ntohl (mp->retval);
1827   if (vam->async_mode)
1828     {
1829       vam->async_errors += (retval < 0);
1830     }
1831   else
1832     {
1833       vam->retval = retval;
1834       vam->sw_if_index = ntohl (mp->sw_if_index);
1835       vam->result_ready = 1;
1836     }
1837 }
1838
1839 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1840   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   vat_json_node_t node;
1844
1845   vat_json_init_object (&node);
1846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1848
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_gre_add_del_tunnel_reply_t_handler
1857   (vl_api_gre_add_del_tunnel_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->sw_if_index = ntohl (mp->sw_if_index);
1869       vam->result_ready = 1;
1870     }
1871 }
1872
1873 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1874   (vl_api_gre_add_del_tunnel_reply_t * mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   vat_json_node_t node;
1878
1879   vat_json_init_object (&node);
1880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1881   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1882
1883   vat_json_print (vam->ofp, &node);
1884   vat_json_free (&node);
1885
1886   vam->retval = ntohl (mp->retval);
1887   vam->result_ready = 1;
1888 }
1889
1890 static void vl_api_create_vhost_user_if_reply_t_handler
1891   (vl_api_create_vhost_user_if_reply_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   i32 retval = ntohl (mp->retval);
1895   if (vam->async_mode)
1896     {
1897       vam->async_errors += (retval < 0);
1898     }
1899   else
1900     {
1901       vam->retval = retval;
1902       vam->sw_if_index = ntohl (mp->sw_if_index);
1903       vam->result_ready = 1;
1904     }
1905 }
1906
1907 static void vl_api_create_vhost_user_if_reply_t_handler_json
1908   (vl_api_create_vhost_user_if_reply_t * mp)
1909 {
1910   vat_main_t *vam = &vat_main;
1911   vat_json_node_t node;
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1916
1917   vat_json_print (vam->ofp, &node);
1918   vat_json_free (&node);
1919
1920   vam->retval = ntohl (mp->retval);
1921   vam->result_ready = 1;
1922 }
1923
1924 static void vl_api_ip_address_details_t_handler
1925   (vl_api_ip_address_details_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928   static ip_address_details_t empty_ip_address_details = { {0} };
1929   ip_address_details_t *address = NULL;
1930   ip_details_t *current_ip_details = NULL;
1931   ip_details_t *details = NULL;
1932
1933   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1934
1935   if (!details || vam->current_sw_if_index >= vec_len (details)
1936       || !details[vam->current_sw_if_index].present)
1937     {
1938       errmsg ("ip address details arrived but not stored");
1939       errmsg ("ip_dump should be called first");
1940       return;
1941     }
1942
1943   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1944
1945 #define addresses (current_ip_details->addr)
1946
1947   vec_validate_init_empty (addresses, vec_len (addresses),
1948                            empty_ip_address_details);
1949
1950   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1951
1952   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1953   address->prefix_length = mp->prefix_length;
1954 #undef addresses
1955 }
1956
1957 static void vl_api_ip_address_details_t_handler_json
1958   (vl_api_ip_address_details_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   vat_json_node_t *node = NULL;
1962   struct in6_addr ip6;
1963   struct in_addr ip4;
1964
1965   if (VAT_JSON_ARRAY != vam->json_tree.type)
1966     {
1967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1968       vat_json_init_array (&vam->json_tree);
1969     }
1970   node = vat_json_array_add (&vam->json_tree);
1971
1972   vat_json_init_object (node);
1973   if (vam->is_ipv6)
1974     {
1975       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1976       vat_json_object_add_ip6 (node, "ip", ip6);
1977     }
1978   else
1979     {
1980       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1981       vat_json_object_add_ip4 (node, "ip", ip4);
1982     }
1983   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1984 }
1985
1986 static void
1987 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   static ip_details_t empty_ip_details = { 0 };
1991   ip_details_t *ip = NULL;
1992   u32 sw_if_index = ~0;
1993
1994   sw_if_index = ntohl (mp->sw_if_index);
1995
1996   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1997                            sw_if_index, empty_ip_details);
1998
1999   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2000                          sw_if_index);
2001
2002   ip->present = 1;
2003 }
2004
2005 static void
2006 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2007 {
2008   vat_main_t *vam = &vat_main;
2009
2010   if (VAT_JSON_ARRAY != vam->json_tree.type)
2011     {
2012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2013       vat_json_init_array (&vam->json_tree);
2014     }
2015   vat_json_array_add_uint (&vam->json_tree,
2016                            clib_net_to_host_u32 (mp->sw_if_index));
2017 }
2018
2019 static void vl_api_map_domain_details_t_handler_json
2020   (vl_api_map_domain_details_t * mp)
2021 {
2022   vat_json_node_t *node = NULL;
2023   vat_main_t *vam = &vat_main;
2024   struct in6_addr ip6;
2025   struct in_addr ip4;
2026
2027   if (VAT_JSON_ARRAY != vam->json_tree.type)
2028     {
2029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2030       vat_json_init_array (&vam->json_tree);
2031     }
2032
2033   node = vat_json_array_add (&vam->json_tree);
2034   vat_json_init_object (node);
2035
2036   vat_json_object_add_uint (node, "domain_index",
2037                             clib_net_to_host_u32 (mp->domain_index));
2038   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2039   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2040   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2041   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2042   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2043   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2044   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2045   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2046   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2047   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2048   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2049   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2050   vat_json_object_add_uint (node, "flags", mp->flags);
2051   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2052   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2053 }
2054
2055 static void vl_api_map_domain_details_t_handler
2056   (vl_api_map_domain_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059
2060   if (mp->is_translation)
2061     {
2062       print (vam->ofp,
2063              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2064              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2065              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2066              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2067              clib_net_to_host_u32 (mp->domain_index));
2068     }
2069   else
2070     {
2071       print (vam->ofp,
2072              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2073              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2074              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2075              format_ip6_address, mp->ip6_src,
2076              clib_net_to_host_u32 (mp->domain_index));
2077     }
2078   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2079          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2080          mp->is_translation ? "map-t" : "");
2081 }
2082
2083 static void vl_api_map_rule_details_t_handler_json
2084   (vl_api_map_rule_details_t * mp)
2085 {
2086   struct in6_addr ip6;
2087   vat_json_node_t *node = NULL;
2088   vat_main_t *vam = &vat_main;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095
2096   node = vat_json_array_add (&vam->json_tree);
2097   vat_json_init_object (node);
2098
2099   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2100   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2101   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2102 }
2103
2104 static void
2105 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2109          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2110 }
2111
2112 static void
2113 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2114 {
2115   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2116           "router_addr %U host_mac %U",
2117           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2118           format_ip4_address, &mp->host_address,
2119           format_ip4_address, &mp->router_address,
2120           format_ethernet_address, mp->host_mac);
2121 }
2122
2123 static void vl_api_dhcp_compl_event_t_handler_json
2124   (vl_api_dhcp_compl_event_t * mp)
2125 {
2126   /* JSON output not supported */
2127 }
2128
2129 static void
2130 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2131                               u32 counter)
2132 {
2133   vat_main_t *vam = &vat_main;
2134   static u64 default_counter = 0;
2135
2136   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2137                            NULL);
2138   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2139                            sw_if_index, default_counter);
2140   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2141 }
2142
2143 static void
2144 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2145                                 interface_counter_t counter)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   static interface_counter_t default_counter = { 0, };
2149
2150   vec_validate_init_empty (vam->combined_interface_counters,
2151                            vnet_counter_type, NULL);
2152   vec_validate_init_empty (vam->combined_interface_counters
2153                            [vnet_counter_type], sw_if_index, default_counter);
2154   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2155 }
2156
2157 static void vl_api_vnet_interface_simple_counters_t_handler
2158   (vl_api_vnet_interface_simple_counters_t * mp)
2159 {
2160   /* not supported */
2161 }
2162
2163 static void vl_api_vnet_interface_combined_counters_t_handler
2164   (vl_api_vnet_interface_combined_counters_t * mp)
2165 {
2166   /* not supported */
2167 }
2168
2169 static void vl_api_vnet_interface_simple_counters_t_handler_json
2170   (vl_api_vnet_interface_simple_counters_t * mp)
2171 {
2172   u64 *v_packets;
2173   u64 packets;
2174   u32 count;
2175   u32 first_sw_if_index;
2176   int i;
2177
2178   count = ntohl (mp->count);
2179   first_sw_if_index = ntohl (mp->first_sw_if_index);
2180
2181   v_packets = (u64 *) & mp->data;
2182   for (i = 0; i < count; i++)
2183     {
2184       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2185       set_simple_interface_counter (mp->vnet_counter_type,
2186                                     first_sw_if_index + i, packets);
2187       v_packets++;
2188     }
2189 }
2190
2191 static void vl_api_vnet_interface_combined_counters_t_handler_json
2192   (vl_api_vnet_interface_combined_counters_t * mp)
2193 {
2194   interface_counter_t counter;
2195   vlib_counter_t *v;
2196   u32 first_sw_if_index;
2197   int i;
2198   u32 count;
2199
2200   count = ntohl (mp->count);
2201   first_sw_if_index = ntohl (mp->first_sw_if_index);
2202
2203   v = (vlib_counter_t *) & mp->data;
2204   for (i = 0; i < count; i++)
2205     {
2206       counter.packets =
2207         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2208       counter.bytes =
2209         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2210       set_combined_interface_counter (mp->vnet_counter_type,
2211                                       first_sw_if_index + i, counter);
2212       v++;
2213     }
2214 }
2215
2216 static u32
2217 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   u32 i;
2221
2222   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2223     {
2224       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2225         {
2226           return i;
2227         }
2228     }
2229   return ~0;
2230 }
2231
2232 static u32
2233 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   u32 i;
2237
2238   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2239     {
2240       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2241         {
2242           return i;
2243         }
2244     }
2245   return ~0;
2246 }
2247
2248 static void vl_api_vnet_ip4_fib_counters_t_handler
2249   (vl_api_vnet_ip4_fib_counters_t * mp)
2250 {
2251   /* not supported */
2252 }
2253
2254 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2255   (vl_api_vnet_ip4_fib_counters_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   vl_api_ip4_fib_counter_t *v;
2259   ip4_fib_counter_t *counter;
2260   struct in_addr ip4;
2261   u32 vrf_id;
2262   u32 vrf_index;
2263   u32 count;
2264   int i;
2265
2266   vrf_id = ntohl (mp->vrf_id);
2267   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2268   if (~0 == vrf_index)
2269     {
2270       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2271       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2272       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2273       vec_validate (vam->ip4_fib_counters, vrf_index);
2274       vam->ip4_fib_counters[vrf_index] = NULL;
2275     }
2276
2277   vec_free (vam->ip4_fib_counters[vrf_index]);
2278   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2279   count = ntohl (mp->count);
2280   for (i = 0; i < count; i++)
2281     {
2282       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2283       counter = &vam->ip4_fib_counters[vrf_index][i];
2284       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2285       counter->address = ip4;
2286       counter->address_length = v->address_length;
2287       counter->packets = clib_net_to_host_u64 (v->packets);
2288       counter->bytes = clib_net_to_host_u64 (v->bytes);
2289       v++;
2290     }
2291 }
2292
2293 static void vl_api_vnet_ip4_nbr_counters_t_handler
2294   (vl_api_vnet_ip4_nbr_counters_t * mp)
2295 {
2296   /* not supported */
2297 }
2298
2299 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2300   (vl_api_vnet_ip4_nbr_counters_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   vl_api_ip4_nbr_counter_t *v;
2304   ip4_nbr_counter_t *counter;
2305   u32 sw_if_index;
2306   u32 count;
2307   int i;
2308
2309   sw_if_index = ntohl (mp->sw_if_index);
2310   count = ntohl (mp->count);
2311   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2312
2313   if (mp->begin)
2314     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2315
2316   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2317   for (i = 0; i < count; i++)
2318     {
2319       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2320       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2321       counter->address.s_addr = v->address;
2322       counter->packets = clib_net_to_host_u64 (v->packets);
2323       counter->bytes = clib_net_to_host_u64 (v->bytes);
2324       counter->linkt = v->link_type;
2325       v++;
2326     }
2327 }
2328
2329 static void vl_api_vnet_ip6_fib_counters_t_handler
2330   (vl_api_vnet_ip6_fib_counters_t * mp)
2331 {
2332   /* not supported */
2333 }
2334
2335 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2336   (vl_api_vnet_ip6_fib_counters_t * mp)
2337 {
2338   vat_main_t *vam = &vat_main;
2339   vl_api_ip6_fib_counter_t *v;
2340   ip6_fib_counter_t *counter;
2341   struct in6_addr ip6;
2342   u32 vrf_id;
2343   u32 vrf_index;
2344   u32 count;
2345   int i;
2346
2347   vrf_id = ntohl (mp->vrf_id);
2348   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2349   if (~0 == vrf_index)
2350     {
2351       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2352       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2353       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2354       vec_validate (vam->ip6_fib_counters, vrf_index);
2355       vam->ip6_fib_counters[vrf_index] = NULL;
2356     }
2357
2358   vec_free (vam->ip6_fib_counters[vrf_index]);
2359   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2360   count = ntohl (mp->count);
2361   for (i = 0; i < count; i++)
2362     {
2363       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2364       counter = &vam->ip6_fib_counters[vrf_index][i];
2365       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2366       counter->address = ip6;
2367       counter->address_length = v->address_length;
2368       counter->packets = clib_net_to_host_u64 (v->packets);
2369       counter->bytes = clib_net_to_host_u64 (v->bytes);
2370       v++;
2371     }
2372 }
2373
2374 static void vl_api_vnet_ip6_nbr_counters_t_handler
2375   (vl_api_vnet_ip6_nbr_counters_t * mp)
2376 {
2377   /* not supported */
2378 }
2379
2380 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2381   (vl_api_vnet_ip6_nbr_counters_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vl_api_ip6_nbr_counter_t *v;
2385   ip6_nbr_counter_t *counter;
2386   struct in6_addr ip6;
2387   u32 sw_if_index;
2388   u32 count;
2389   int i;
2390
2391   sw_if_index = ntohl (mp->sw_if_index);
2392   count = ntohl (mp->count);
2393   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2394
2395   if (mp->begin)
2396     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2397
2398   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2399   for (i = 0; i < count; i++)
2400     {
2401       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2402       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2403       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2404       counter->address = ip6;
2405       counter->packets = clib_net_to_host_u64 (v->packets);
2406       counter->bytes = clib_net_to_host_u64 (v->bytes);
2407       v++;
2408     }
2409 }
2410
2411 static void vl_api_get_first_msg_id_reply_t_handler
2412   (vl_api_get_first_msg_id_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416
2417   if (vam->async_mode)
2418     {
2419       vam->async_errors += (retval < 0);
2420     }
2421   else
2422     {
2423       vam->retval = retval;
2424       vam->result_ready = 1;
2425     }
2426   if (retval >= 0)
2427     {
2428       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2429     }
2430 }
2431
2432 static void vl_api_get_first_msg_id_reply_t_handler_json
2433   (vl_api_get_first_msg_id_reply_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436   vat_json_node_t node;
2437
2438   vat_json_init_object (&node);
2439   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2440   vat_json_object_add_uint (&node, "first_msg_id",
2441                             (uint) ntohs (mp->first_msg_id));
2442
2443   vat_json_print (vam->ofp, &node);
2444   vat_json_free (&node);
2445
2446   vam->retval = ntohl (mp->retval);
2447   vam->result_ready = 1;
2448 }
2449
2450 static void vl_api_get_node_graph_reply_t_handler
2451   (vl_api_get_node_graph_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   api_main_t *am = &api_main;
2455   i32 retval = ntohl (mp->retval);
2456   u8 *pvt_copy, *reply;
2457   void *oldheap;
2458   vlib_node_t *node;
2459   int i;
2460
2461   if (vam->async_mode)
2462     {
2463       vam->async_errors += (retval < 0);
2464     }
2465   else
2466     {
2467       vam->retval = retval;
2468       vam->result_ready = 1;
2469     }
2470
2471   /* "Should never happen..." */
2472   if (retval != 0)
2473     return;
2474
2475   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2476   pvt_copy = vec_dup (reply);
2477
2478   /* Toss the shared-memory original... */
2479   pthread_mutex_lock (&am->vlib_rp->mutex);
2480   oldheap = svm_push_data_heap (am->vlib_rp);
2481
2482   vec_free (reply);
2483
2484   svm_pop_heap (oldheap);
2485   pthread_mutex_unlock (&am->vlib_rp->mutex);
2486
2487   if (vam->graph_nodes)
2488     {
2489       hash_free (vam->graph_node_index_by_name);
2490
2491       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2492         {
2493           node = vam->graph_nodes[i];
2494           vec_free (node->name);
2495           vec_free (node->next_nodes);
2496           vec_free (node);
2497         }
2498       vec_free (vam->graph_nodes);
2499     }
2500
2501   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2502   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2503   vec_free (pvt_copy);
2504
2505   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2506     {
2507       node = vam->graph_nodes[i];
2508       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2509     }
2510 }
2511
2512 static void vl_api_get_node_graph_reply_t_handler_json
2513   (vl_api_get_node_graph_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   api_main_t *am = &api_main;
2517   void *oldheap;
2518   vat_json_node_t node;
2519   u8 *reply;
2520
2521   /* $$$$ make this real? */
2522   vat_json_init_object (&node);
2523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2524   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2525
2526   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2527
2528   /* Toss the shared-memory original... */
2529   pthread_mutex_lock (&am->vlib_rp->mutex);
2530   oldheap = svm_push_data_heap (am->vlib_rp);
2531
2532   vec_free (reply);
2533
2534   svm_pop_heap (oldheap);
2535   pthread_mutex_unlock (&am->vlib_rp->mutex);
2536
2537   vat_json_print (vam->ofp, &node);
2538   vat_json_free (&node);
2539
2540   vam->retval = ntohl (mp->retval);
2541   vam->result_ready = 1;
2542 }
2543
2544 static void
2545 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   u8 *s = 0;
2549
2550   if (mp->local)
2551     {
2552       s = format (s, "%=16d%=16d%=16d",
2553                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2554     }
2555   else
2556     {
2557       s = format (s, "%=16U%=16d%=16d",
2558                   mp->is_ipv6 ? format_ip6_address :
2559                   format_ip4_address,
2560                   mp->ip_address, mp->priority, mp->weight);
2561     }
2562
2563   print (vam->ofp, "%v", s);
2564   vec_free (s);
2565 }
2566
2567 static void
2568 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   vat_json_node_t *node = NULL;
2572   struct in6_addr ip6;
2573   struct in_addr ip4;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581   vat_json_init_object (node);
2582
2583   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2584   vat_json_object_add_uint (node, "priority", mp->priority);
2585   vat_json_object_add_uint (node, "weight", mp->weight);
2586
2587   if (mp->local)
2588     vat_json_object_add_uint (node, "sw_if_index",
2589                               clib_net_to_host_u32 (mp->sw_if_index));
2590   else
2591     {
2592       if (mp->is_ipv6)
2593         {
2594           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2595           vat_json_object_add_ip6 (node, "address", ip6);
2596         }
2597       else
2598         {
2599           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2600           vat_json_object_add_ip4 (node, "address", ip4);
2601         }
2602     }
2603 }
2604
2605 static void
2606 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2607                                           mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u8 *ls_name = 0;
2611
2612   ls_name = format (0, "%s", mp->ls_name);
2613
2614   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2615          ls_name);
2616   vec_free (ls_name);
2617 }
2618
2619 static void
2620   vl_api_one_locator_set_details_t_handler_json
2621   (vl_api_one_locator_set_details_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = 0;
2625   u8 *ls_name = 0;
2626
2627   ls_name = format (0, "%s", mp->ls_name);
2628   vec_add1 (ls_name, 0);
2629
2630   if (VAT_JSON_ARRAY != vam->json_tree.type)
2631     {
2632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2633       vat_json_init_array (&vam->json_tree);
2634     }
2635   node = vat_json_array_add (&vam->json_tree);
2636
2637   vat_json_init_object (node);
2638   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2639   vat_json_object_add_uint (node, "ls_index",
2640                             clib_net_to_host_u32 (mp->ls_index));
2641   vec_free (ls_name);
2642 }
2643
2644 typedef struct
2645 {
2646   u32 spi;
2647   u8 si;
2648 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2649
2650 uword
2651 unformat_nsh_address (unformat_input_t * input, va_list * args)
2652 {
2653   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2654   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2655 }
2656
2657 u8 *
2658 format_nsh_address_vat (u8 * s, va_list * args)
2659 {
2660   nsh_t *a = va_arg (*args, nsh_t *);
2661   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2662 }
2663
2664 static u8 *
2665 format_lisp_flat_eid (u8 * s, va_list * args)
2666 {
2667   u32 type = va_arg (*args, u32);
2668   u8 *eid = va_arg (*args, u8 *);
2669   u32 eid_len = va_arg (*args, u32);
2670
2671   switch (type)
2672     {
2673     case 0:
2674       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2675     case 1:
2676       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2677     case 2:
2678       return format (s, "%U", format_ethernet_address, eid);
2679     case 3:
2680       return format (s, "%U", format_nsh_address_vat, eid);
2681     }
2682   return 0;
2683 }
2684
2685 static u8 *
2686 format_lisp_eid_vat (u8 * s, va_list * args)
2687 {
2688   u32 type = va_arg (*args, u32);
2689   u8 *eid = va_arg (*args, u8 *);
2690   u32 eid_len = va_arg (*args, u32);
2691   u8 *seid = va_arg (*args, u8 *);
2692   u32 seid_len = va_arg (*args, u32);
2693   u32 is_src_dst = va_arg (*args, u32);
2694
2695   if (is_src_dst)
2696     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2697
2698   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2699
2700   return s;
2701 }
2702
2703 static void
2704 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   u8 *s = 0, *eid = 0;
2708
2709   if (~0 == mp->locator_set_index)
2710     s = format (0, "action: %d", mp->action);
2711   else
2712     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2713
2714   eid = format (0, "%U", format_lisp_eid_vat,
2715                 mp->eid_type,
2716                 mp->eid,
2717                 mp->eid_prefix_len,
2718                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2719   vec_add1 (eid, 0);
2720
2721   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2722          clib_net_to_host_u32 (mp->vni),
2723          eid,
2724          mp->is_local ? "local" : "remote",
2725          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2726          clib_net_to_host_u16 (mp->key_id), mp->key);
2727
2728   vec_free (s);
2729   vec_free (eid);
2730 }
2731
2732 static void
2733 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2734                                              * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t *node = 0;
2738   u8 *eid = 0;
2739
2740   if (VAT_JSON_ARRAY != vam->json_tree.type)
2741     {
2742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2743       vat_json_init_array (&vam->json_tree);
2744     }
2745   node = vat_json_array_add (&vam->json_tree);
2746
2747   vat_json_init_object (node);
2748   if (~0 == mp->locator_set_index)
2749     vat_json_object_add_uint (node, "action", mp->action);
2750   else
2751     vat_json_object_add_uint (node, "locator_set_index",
2752                               clib_net_to_host_u32 (mp->locator_set_index));
2753
2754   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2755   if (mp->eid_type == 3)
2756     {
2757       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2758       vat_json_init_object (nsh_json);
2759       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2760       vat_json_object_add_uint (nsh_json, "spi",
2761                                 clib_net_to_host_u32 (nsh->spi));
2762       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2763     }
2764   else
2765     {
2766       eid = format (0, "%U", format_lisp_eid_vat,
2767                     mp->eid_type,
2768                     mp->eid,
2769                     mp->eid_prefix_len,
2770                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2771       vec_add1 (eid, 0);
2772       vat_json_object_add_string_copy (node, "eid", eid);
2773       vec_free (eid);
2774     }
2775   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2776   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2777   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2778
2779   if (mp->key_id)
2780     {
2781       vat_json_object_add_uint (node, "key_id",
2782                                 clib_net_to_host_u16 (mp->key_id));
2783       vat_json_object_add_string_copy (node, "key", mp->key);
2784     }
2785 }
2786
2787 static void
2788 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   u8 *seid = 0, *deid = 0;
2792   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2793
2794   deid = format (0, "%U", format_lisp_eid_vat,
2795                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2796
2797   seid = format (0, "%U", format_lisp_eid_vat,
2798                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2799
2800   vec_add1 (deid, 0);
2801   vec_add1 (seid, 0);
2802
2803   if (mp->is_ip4)
2804     format_ip_address_fcn = format_ip4_address;
2805   else
2806     format_ip_address_fcn = format_ip6_address;
2807
2808
2809   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2810          clib_net_to_host_u32 (mp->vni),
2811          seid, deid,
2812          format_ip_address_fcn, mp->lloc,
2813          format_ip_address_fcn, mp->rloc,
2814          clib_net_to_host_u32 (mp->pkt_count),
2815          clib_net_to_host_u32 (mp->bytes));
2816
2817   vec_free (deid);
2818   vec_free (seid);
2819 }
2820
2821 static void
2822 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2823 {
2824   struct in6_addr ip6;
2825   struct in_addr ip4;
2826   vat_main_t *vam = &vat_main;
2827   vat_json_node_t *node = 0;
2828   u8 *deid = 0, *seid = 0;
2829
2830   if (VAT_JSON_ARRAY != vam->json_tree.type)
2831     {
2832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2833       vat_json_init_array (&vam->json_tree);
2834     }
2835   node = vat_json_array_add (&vam->json_tree);
2836
2837   vat_json_init_object (node);
2838   deid = format (0, "%U", format_lisp_eid_vat,
2839                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2840
2841   seid = format (0, "%U", format_lisp_eid_vat,
2842                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2843
2844   vec_add1 (deid, 0);
2845   vec_add1 (seid, 0);
2846
2847   vat_json_object_add_string_copy (node, "seid", seid);
2848   vat_json_object_add_string_copy (node, "deid", deid);
2849   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2850
2851   if (mp->is_ip4)
2852     {
2853       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2854       vat_json_object_add_ip4 (node, "lloc", ip4);
2855       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2856       vat_json_object_add_ip4 (node, "rloc", ip4);
2857     }
2858   else
2859     {
2860       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2861       vat_json_object_add_ip6 (node, "lloc", ip6);
2862       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2863       vat_json_object_add_ip6 (node, "rloc", ip6);
2864     }
2865   vat_json_object_add_uint (node, "pkt_count",
2866                             clib_net_to_host_u32 (mp->pkt_count));
2867   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2868
2869   vec_free (deid);
2870   vec_free (seid);
2871 }
2872
2873 static void
2874   vl_api_one_eid_table_map_details_t_handler
2875   (vl_api_one_eid_table_map_details_t * mp)
2876 {
2877   vat_main_t *vam = &vat_main;
2878
2879   u8 *line = format (0, "%=10d%=10d",
2880                      clib_net_to_host_u32 (mp->vni),
2881                      clib_net_to_host_u32 (mp->dp_table));
2882   print (vam->ofp, "%v", line);
2883   vec_free (line);
2884 }
2885
2886 static void
2887   vl_api_one_eid_table_map_details_t_handler_json
2888   (vl_api_one_eid_table_map_details_t * mp)
2889 {
2890   vat_main_t *vam = &vat_main;
2891   vat_json_node_t *node = NULL;
2892
2893   if (VAT_JSON_ARRAY != vam->json_tree.type)
2894     {
2895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2896       vat_json_init_array (&vam->json_tree);
2897     }
2898   node = vat_json_array_add (&vam->json_tree);
2899   vat_json_init_object (node);
2900   vat_json_object_add_uint (node, "dp_table",
2901                             clib_net_to_host_u32 (mp->dp_table));
2902   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2903 }
2904
2905 static void
2906   vl_api_one_eid_table_vni_details_t_handler
2907   (vl_api_one_eid_table_vni_details_t * mp)
2908 {
2909   vat_main_t *vam = &vat_main;
2910
2911   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2912   print (vam->ofp, "%v", line);
2913   vec_free (line);
2914 }
2915
2916 static void
2917   vl_api_one_eid_table_vni_details_t_handler_json
2918   (vl_api_one_eid_table_vni_details_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   vat_json_node_t *node = NULL;
2922
2923   if (VAT_JSON_ARRAY != vam->json_tree.type)
2924     {
2925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2926       vat_json_init_array (&vam->json_tree);
2927     }
2928   node = vat_json_array_add (&vam->json_tree);
2929   vat_json_init_object (node);
2930   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2931 }
2932
2933 static void
2934   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
2935   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   int retval = clib_net_to_host_u32 (mp->retval);
2939
2940   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2941   print (vam->ofp, "fallback threshold value: %d", mp->value);
2942
2943   vam->retval = retval;
2944   vam->result_ready = 1;
2945 }
2946
2947 static void
2948   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
2949   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   vat_json_node_t _node, *node = &_node;
2953   int retval = clib_net_to_host_u32 (mp->retval);
2954
2955   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2956   vat_json_init_object (node);
2957   vat_json_object_add_uint (node, "value", mp->value);
2958
2959   vat_json_print (vam->ofp, node);
2960   vat_json_free (node);
2961
2962   vam->retval = retval;
2963   vam->result_ready = 1;
2964 }
2965
2966 static void
2967   vl_api_show_one_map_register_state_reply_t_handler
2968   (vl_api_show_one_map_register_state_reply_t * mp)
2969 {
2970   vat_main_t *vam = &vat_main;
2971   int retval = clib_net_to_host_u32 (mp->retval);
2972
2973   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2974
2975   vam->retval = retval;
2976   vam->result_ready = 1;
2977 }
2978
2979 static void
2980   vl_api_show_one_map_register_state_reply_t_handler_json
2981   (vl_api_show_one_map_register_state_reply_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   vat_json_node_t _node, *node = &_node;
2985   int retval = clib_net_to_host_u32 (mp->retval);
2986
2987   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2988
2989   vat_json_init_object (node);
2990   vat_json_object_add_string_copy (node, "state", s);
2991
2992   vat_json_print (vam->ofp, node);
2993   vat_json_free (node);
2994
2995   vam->retval = retval;
2996   vam->result_ready = 1;
2997   vec_free (s);
2998 }
2999
3000 static void
3001   vl_api_show_one_rloc_probe_state_reply_t_handler
3002   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3003 {
3004   vat_main_t *vam = &vat_main;
3005   int retval = clib_net_to_host_u32 (mp->retval);
3006
3007   if (retval)
3008     goto end;
3009
3010   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3011 end:
3012   vam->retval = retval;
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3018   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   vat_json_node_t _node, *node = &_node;
3022   int retval = clib_net_to_host_u32 (mp->retval);
3023
3024   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3025   vat_json_init_object (node);
3026   vat_json_object_add_string_copy (node, "state", s);
3027
3028   vat_json_print (vam->ofp, node);
3029   vat_json_free (node);
3030
3031   vam->retval = retval;
3032   vam->result_ready = 1;
3033   vec_free (s);
3034 }
3035
3036 static void
3037   vl_api_show_one_stats_enable_disable_reply_t_handler
3038   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3039 {
3040   vat_main_t *vam = &vat_main;
3041   int retval = clib_net_to_host_u32 (mp->retval);
3042
3043   if (retval)
3044     goto end;
3045
3046   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3047 end:
3048   vam->retval = retval;
3049   vam->result_ready = 1;
3050 }
3051
3052 static void
3053   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3054   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3055 {
3056   vat_main_t *vam = &vat_main;
3057   vat_json_node_t _node, *node = &_node;
3058   int retval = clib_net_to_host_u32 (mp->retval);
3059
3060   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3061   vat_json_init_object (node);
3062   vat_json_object_add_string_copy (node, "state", s);
3063
3064   vat_json_print (vam->ofp, node);
3065   vat_json_free (node);
3066
3067   vam->retval = retval;
3068   vam->result_ready = 1;
3069   vec_free (s);
3070 }
3071
3072 static void
3073 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3074 {
3075   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3076   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3077   e->vni = clib_net_to_host_u32 (e->vni);
3078 }
3079
3080 static void
3081   gpe_fwd_entries_get_reply_t_net_to_host
3082   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3083 {
3084   u32 i;
3085
3086   mp->count = clib_net_to_host_u32 (mp->count);
3087   for (i = 0; i < mp->count; i++)
3088     {
3089       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3090     }
3091 }
3092
3093 static u8 *
3094 format_gpe_encap_mode (u8 * s, va_list * args)
3095 {
3096   u32 mode = va_arg (*args, u32);
3097
3098   switch (mode)
3099     {
3100     case 0:
3101       return format (s, "lisp");
3102     case 1:
3103       return format (s, "vxlan");
3104     }
3105   return 0;
3106 }
3107
3108 static void
3109   vl_api_gpe_get_encap_mode_reply_t_handler
3110   (vl_api_gpe_get_encap_mode_reply_t * mp)
3111 {
3112   vat_main_t *vam = &vat_main;
3113
3114   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3115   vam->retval = ntohl (mp->retval);
3116   vam->result_ready = 1;
3117 }
3118
3119 static void
3120   vl_api_gpe_get_encap_mode_reply_t_handler_json
3121   (vl_api_gpe_get_encap_mode_reply_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   vat_json_node_t node;
3125
3126   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3127   vec_add1 (encap_mode, 0);
3128
3129   vat_json_init_object (&node);
3130   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3131
3132   vec_free (encap_mode);
3133   vat_json_print (vam->ofp, &node);
3134   vat_json_free (&node);
3135
3136   vam->retval = ntohl (mp->retval);
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_gpe_fwd_entry_path_details_t_handler
3142   (vl_api_gpe_fwd_entry_path_details_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3146
3147   if (mp->lcl_loc.is_ip4)
3148     format_ip_address_fcn = format_ip4_address;
3149   else
3150     format_ip_address_fcn = format_ip6_address;
3151
3152   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3153          format_ip_address_fcn, &mp->lcl_loc,
3154          format_ip_address_fcn, &mp->rmt_loc);
3155 }
3156
3157 static void
3158 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3159 {
3160   struct in6_addr ip6;
3161   struct in_addr ip4;
3162
3163   if (loc->is_ip4)
3164     {
3165       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3166       vat_json_object_add_ip4 (n, "address", ip4);
3167     }
3168   else
3169     {
3170       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3171       vat_json_object_add_ip6 (n, "address", ip6);
3172     }
3173   vat_json_object_add_uint (n, "weight", loc->weight);
3174 }
3175
3176 static void
3177   vl_api_gpe_fwd_entry_path_details_t_handler_json
3178   (vl_api_gpe_fwd_entry_path_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   vat_json_node_t *node = NULL;
3182   vat_json_node_t *loc_node;
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190   vat_json_init_object (node);
3191
3192   loc_node = vat_json_object_add (node, "local_locator");
3193   vat_json_init_object (loc_node);
3194   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3195
3196   loc_node = vat_json_object_add (node, "remote_locator");
3197   vat_json_init_object (loc_node);
3198   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3199 }
3200
3201 static void
3202   vl_api_gpe_fwd_entries_get_reply_t_handler
3203   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206   u32 i;
3207   int retval = clib_net_to_host_u32 (mp->retval);
3208   vl_api_gpe_fwd_entry_t *e;
3209
3210   if (retval)
3211     goto end;
3212
3213   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3214
3215   for (i = 0; i < mp->count; i++)
3216     {
3217       e = &mp->entries[i];
3218       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3219              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3220              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3221     }
3222
3223 end:
3224   vam->retval = retval;
3225   vam->result_ready = 1;
3226 }
3227
3228 static void
3229   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3230   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3231 {
3232   u8 *s = 0;
3233   vat_main_t *vam = &vat_main;
3234   vat_json_node_t *e = 0, root;
3235   u32 i;
3236   int retval = clib_net_to_host_u32 (mp->retval);
3237   vl_api_gpe_fwd_entry_t *fwd;
3238
3239   if (retval)
3240     goto end;
3241
3242   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3243   vat_json_init_array (&root);
3244
3245   for (i = 0; i < mp->count; i++)
3246     {
3247       e = vat_json_array_add (&root);
3248       fwd = &mp->entries[i];
3249
3250       vat_json_init_object (e);
3251       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3252       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3253       vat_json_object_add_int (e, "vni", fwd->vni);
3254       vat_json_object_add_int (e, "action", fwd->action);
3255
3256       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3257                   fwd->leid_prefix_len);
3258       vec_add1 (s, 0);
3259       vat_json_object_add_string_copy (e, "leid", s);
3260       vec_free (s);
3261
3262       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3263                   fwd->reid_prefix_len);
3264       vec_add1 (s, 0);
3265       vat_json_object_add_string_copy (e, "reid", s);
3266       vec_free (s);
3267     }
3268
3269   vat_json_print (vam->ofp, &root);
3270   vat_json_free (&root);
3271
3272 end:
3273   vam->retval = retval;
3274   vam->result_ready = 1;
3275 }
3276
3277 static void
3278   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3279   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   u32 i, n;
3283   int retval = clib_net_to_host_u32 (mp->retval);
3284   vl_api_gpe_native_fwd_rpath_t *r;
3285
3286   if (retval)
3287     goto end;
3288
3289   n = clib_net_to_host_u32 (mp->count);
3290
3291   for (i = 0; i < n; i++)
3292     {
3293       r = &mp->entries[i];
3294       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3295              clib_net_to_host_u32 (r->fib_index),
3296              clib_net_to_host_u32 (r->nh_sw_if_index),
3297              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3298     }
3299
3300 end:
3301   vam->retval = retval;
3302   vam->result_ready = 1;
3303 }
3304
3305 static void
3306   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3307   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   vat_json_node_t root, *e;
3311   u32 i, n;
3312   int retval = clib_net_to_host_u32 (mp->retval);
3313   vl_api_gpe_native_fwd_rpath_t *r;
3314   u8 *s;
3315
3316   if (retval)
3317     goto end;
3318
3319   n = clib_net_to_host_u32 (mp->count);
3320   vat_json_init_array (&root);
3321
3322   for (i = 0; i < n; i++)
3323     {
3324       e = vat_json_array_add (&root);
3325       vat_json_init_object (e);
3326       r = &mp->entries[i];
3327       s =
3328         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3329                 r->nh_addr);
3330       vec_add1 (s, 0);
3331       vat_json_object_add_string_copy (e, "ip4", s);
3332       vec_free (s);
3333
3334       vat_json_object_add_uint (e, "fib_index",
3335                                 clib_net_to_host_u32 (r->fib_index));
3336       vat_json_object_add_uint (e, "nh_sw_if_index",
3337                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3338     }
3339
3340   vat_json_print (vam->ofp, &root);
3341   vat_json_free (&root);
3342
3343 end:
3344   vam->retval = retval;
3345   vam->result_ready = 1;
3346 }
3347
3348 static void
3349   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3350   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3351 {
3352   vat_main_t *vam = &vat_main;
3353   u32 i, n;
3354   int retval = clib_net_to_host_u32 (mp->retval);
3355
3356   if (retval)
3357     goto end;
3358
3359   n = clib_net_to_host_u32 (mp->count);
3360
3361   for (i = 0; i < n; i++)
3362     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3363
3364 end:
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3371   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t root;
3375   u32 i, n;
3376   int retval = clib_net_to_host_u32 (mp->retval);
3377
3378   if (retval)
3379     goto end;
3380
3381   n = clib_net_to_host_u32 (mp->count);
3382   vat_json_init_array (&root);
3383
3384   for (i = 0; i < n; i++)
3385     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3386
3387   vat_json_print (vam->ofp, &root);
3388   vat_json_free (&root);
3389
3390 end:
3391   vam->retval = retval;
3392   vam->result_ready = 1;
3393 }
3394
3395 static void
3396   vl_api_one_l2_arp_entries_get_reply_t_handler
3397   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   u32 i, n;
3401   int retval = clib_net_to_host_u32 (mp->retval);
3402
3403   if (retval)
3404     goto end;
3405
3406   n = clib_net_to_host_u32 (mp->count);
3407
3408   for (i = 0; i < n; i++)
3409     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3410            format_ethernet_address, mp->entries[i].mac);
3411
3412 end:
3413   vam->retval = retval;
3414   vam->result_ready = 1;
3415 }
3416
3417 static void
3418   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3419   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3420 {
3421   u8 *s = 0;
3422   vat_main_t *vam = &vat_main;
3423   vat_json_node_t *e = 0, root;
3424   u32 i, n;
3425   int retval = clib_net_to_host_u32 (mp->retval);
3426   vl_api_one_l2_arp_entry_t *arp_entry;
3427
3428   if (retval)
3429     goto end;
3430
3431   n = clib_net_to_host_u32 (mp->count);
3432   vat_json_init_array (&root);
3433
3434   for (i = 0; i < n; i++)
3435     {
3436       e = vat_json_array_add (&root);
3437       arp_entry = &mp->entries[i];
3438
3439       vat_json_init_object (e);
3440       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3441       vec_add1 (s, 0);
3442
3443       vat_json_object_add_string_copy (e, "mac", s);
3444       vec_free (s);
3445
3446       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3447       vec_add1 (s, 0);
3448       vat_json_object_add_string_copy (e, "ip4", s);
3449       vec_free (s);
3450     }
3451
3452   vat_json_print (vam->ofp, &root);
3453   vat_json_free (&root);
3454
3455 end:
3456   vam->retval = retval;
3457   vam->result_ready = 1;
3458 }
3459
3460 static void
3461   vl_api_one_l2_arp_bd_get_reply_t_handler
3462   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465   u32 i, n;
3466   int retval = clib_net_to_host_u32 (mp->retval);
3467
3468   if (retval)
3469     goto end;
3470
3471   n = clib_net_to_host_u32 (mp->count);
3472
3473   for (i = 0; i < n; i++)
3474     {
3475       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3476     }
3477
3478 end:
3479   vam->retval = retval;
3480   vam->result_ready = 1;
3481 }
3482
3483 static void
3484   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3485   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3486 {
3487   vat_main_t *vam = &vat_main;
3488   vat_json_node_t root;
3489   u32 i, n;
3490   int retval = clib_net_to_host_u32 (mp->retval);
3491
3492   if (retval)
3493     goto end;
3494
3495   n = clib_net_to_host_u32 (mp->count);
3496   vat_json_init_array (&root);
3497
3498   for (i = 0; i < n; i++)
3499     {
3500       vat_json_array_add_uint (&root,
3501                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3502     }
3503
3504   vat_json_print (vam->ofp, &root);
3505   vat_json_free (&root);
3506
3507 end:
3508   vam->retval = retval;
3509   vam->result_ready = 1;
3510 }
3511
3512 static void
3513   vl_api_one_adjacencies_get_reply_t_handler
3514   (vl_api_one_adjacencies_get_reply_t * mp)
3515 {
3516   vat_main_t *vam = &vat_main;
3517   u32 i, n;
3518   int retval = clib_net_to_host_u32 (mp->retval);
3519   vl_api_one_adjacency_t *a;
3520
3521   if (retval)
3522     goto end;
3523
3524   n = clib_net_to_host_u32 (mp->count);
3525
3526   for (i = 0; i < n; i++)
3527     {
3528       a = &mp->adjacencies[i];
3529       print (vam->ofp, "%U %40U",
3530              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3531              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3532     }
3533
3534 end:
3535   vam->retval = retval;
3536   vam->result_ready = 1;
3537 }
3538
3539 static void
3540   vl_api_one_adjacencies_get_reply_t_handler_json
3541   (vl_api_one_adjacencies_get_reply_t * mp)
3542 {
3543   u8 *s = 0;
3544   vat_main_t *vam = &vat_main;
3545   vat_json_node_t *e = 0, root;
3546   u32 i, n;
3547   int retval = clib_net_to_host_u32 (mp->retval);
3548   vl_api_one_adjacency_t *a;
3549
3550   if (retval)
3551     goto end;
3552
3553   n = clib_net_to_host_u32 (mp->count);
3554   vat_json_init_array (&root);
3555
3556   for (i = 0; i < n; i++)
3557     {
3558       e = vat_json_array_add (&root);
3559       a = &mp->adjacencies[i];
3560
3561       vat_json_init_object (e);
3562       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3563                   a->leid_prefix_len);
3564       vec_add1 (s, 0);
3565       vat_json_object_add_string_copy (e, "leid", s);
3566       vec_free (s);
3567
3568       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3569                   a->reid_prefix_len);
3570       vec_add1 (s, 0);
3571       vat_json_object_add_string_copy (e, "reid", s);
3572       vec_free (s);
3573     }
3574
3575   vat_json_print (vam->ofp, &root);
3576   vat_json_free (&root);
3577
3578 end:
3579   vam->retval = retval;
3580   vam->result_ready = 1;
3581 }
3582
3583 static void
3584 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587
3588   print (vam->ofp, "%=20U",
3589          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3590          mp->ip_address);
3591 }
3592
3593 static void
3594   vl_api_one_map_server_details_t_handler_json
3595   (vl_api_one_map_server_details_t * mp)
3596 {
3597   vat_main_t *vam = &vat_main;
3598   vat_json_node_t *node = NULL;
3599   struct in6_addr ip6;
3600   struct in_addr ip4;
3601
3602   if (VAT_JSON_ARRAY != vam->json_tree.type)
3603     {
3604       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3605       vat_json_init_array (&vam->json_tree);
3606     }
3607   node = vat_json_array_add (&vam->json_tree);
3608
3609   vat_json_init_object (node);
3610   if (mp->is_ipv6)
3611     {
3612       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3613       vat_json_object_add_ip6 (node, "map-server", ip6);
3614     }
3615   else
3616     {
3617       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3618       vat_json_object_add_ip4 (node, "map-server", ip4);
3619     }
3620 }
3621
3622 static void
3623 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3624                                            * mp)
3625 {
3626   vat_main_t *vam = &vat_main;
3627
3628   print (vam->ofp, "%=20U",
3629          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3630          mp->ip_address);
3631 }
3632
3633 static void
3634   vl_api_one_map_resolver_details_t_handler_json
3635   (vl_api_one_map_resolver_details_t * mp)
3636 {
3637   vat_main_t *vam = &vat_main;
3638   vat_json_node_t *node = NULL;
3639   struct in6_addr ip6;
3640   struct in_addr ip4;
3641
3642   if (VAT_JSON_ARRAY != vam->json_tree.type)
3643     {
3644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3645       vat_json_init_array (&vam->json_tree);
3646     }
3647   node = vat_json_array_add (&vam->json_tree);
3648
3649   vat_json_init_object (node);
3650   if (mp->is_ipv6)
3651     {
3652       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3653       vat_json_object_add_ip6 (node, "map resolver", ip6);
3654     }
3655   else
3656     {
3657       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3658       vat_json_object_add_ip4 (node, "map resolver", ip4);
3659     }
3660 }
3661
3662 static void
3663 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3664 {
3665   vat_main_t *vam = &vat_main;
3666   i32 retval = ntohl (mp->retval);
3667
3668   if (0 <= retval)
3669     {
3670       print (vam->ofp, "feature: %s\ngpe: %s",
3671              mp->feature_status ? "enabled" : "disabled",
3672              mp->gpe_status ? "enabled" : "disabled");
3673     }
3674
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_show_one_status_reply_t_handler_json
3681   (vl_api_show_one_status_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   vat_json_node_t node;
3685   u8 *gpe_status = NULL;
3686   u8 *feature_status = NULL;
3687
3688   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3689   feature_status = format (0, "%s",
3690                            mp->feature_status ? "enabled" : "disabled");
3691   vec_add1 (gpe_status, 0);
3692   vec_add1 (feature_status, 0);
3693
3694   vat_json_init_object (&node);
3695   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3696   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3697
3698   vec_free (gpe_status);
3699   vec_free (feature_status);
3700
3701   vat_json_print (vam->ofp, &node);
3702   vat_json_free (&node);
3703
3704   vam->retval = ntohl (mp->retval);
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3710   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   i32 retval = ntohl (mp->retval);
3714
3715   if (retval >= 0)
3716     {
3717       print (vam->ofp, "%=20s", mp->locator_set_name);
3718     }
3719
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3726   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729   vat_json_node_t *node = NULL;
3730
3731   if (VAT_JSON_ARRAY != vam->json_tree.type)
3732     {
3733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3734       vat_json_init_array (&vam->json_tree);
3735     }
3736   node = vat_json_array_add (&vam->json_tree);
3737
3738   vat_json_init_object (node);
3739   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
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 u8 *
3749 format_lisp_map_request_mode (u8 * s, va_list * args)
3750 {
3751   u32 mode = va_arg (*args, u32);
3752
3753   switch (mode)
3754     {
3755     case 0:
3756       return format (0, "dst-only");
3757     case 1:
3758       return format (0, "src-dst");
3759     }
3760   return 0;
3761 }
3762
3763 static void
3764   vl_api_show_one_map_request_mode_reply_t_handler
3765   (vl_api_show_one_map_request_mode_reply_t * mp)
3766 {
3767   vat_main_t *vam = &vat_main;
3768   i32 retval = ntohl (mp->retval);
3769
3770   if (0 <= retval)
3771     {
3772       u32 mode = mp->mode;
3773       print (vam->ofp, "map_request_mode: %U",
3774              format_lisp_map_request_mode, mode);
3775     }
3776
3777   vam->retval = retval;
3778   vam->result_ready = 1;
3779 }
3780
3781 static void
3782   vl_api_show_one_map_request_mode_reply_t_handler_json
3783   (vl_api_show_one_map_request_mode_reply_t * mp)
3784 {
3785   vat_main_t *vam = &vat_main;
3786   vat_json_node_t node;
3787   u8 *s = 0;
3788   u32 mode;
3789
3790   mode = mp->mode;
3791   s = format (0, "%U", format_lisp_map_request_mode, mode);
3792   vec_add1 (s, 0);
3793
3794   vat_json_init_object (&node);
3795   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3796   vat_json_print (vam->ofp, &node);
3797   vat_json_free (&node);
3798
3799   vec_free (s);
3800   vam->retval = ntohl (mp->retval);
3801   vam->result_ready = 1;
3802 }
3803
3804 static void
3805   vl_api_show_one_use_petr_reply_t_handler
3806   (vl_api_show_one_use_petr_reply_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   i32 retval = ntohl (mp->retval);
3810
3811   if (0 <= retval)
3812     {
3813       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3814       if (mp->status)
3815         {
3816           print (vam->ofp, "Proxy-ETR address; %U",
3817                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3818                  mp->address);
3819         }
3820     }
3821
3822   vam->retval = retval;
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_show_one_use_petr_reply_t_handler_json
3828   (vl_api_show_one_use_petr_reply_t * mp)
3829 {
3830   vat_main_t *vam = &vat_main;
3831   vat_json_node_t node;
3832   u8 *status = 0;
3833   struct in_addr ip4;
3834   struct in6_addr ip6;
3835
3836   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3837   vec_add1 (status, 0);
3838
3839   vat_json_init_object (&node);
3840   vat_json_object_add_string_copy (&node, "status", status);
3841   if (mp->status)
3842     {
3843       if (mp->is_ip4)
3844         {
3845           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3846           vat_json_object_add_ip6 (&node, "address", ip6);
3847         }
3848       else
3849         {
3850           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3851           vat_json_object_add_ip4 (&node, "address", ip4);
3852         }
3853     }
3854
3855   vec_free (status);
3856
3857   vat_json_print (vam->ofp, &node);
3858   vat_json_free (&node);
3859
3860   vam->retval = ntohl (mp->retval);
3861   vam->result_ready = 1;
3862 }
3863
3864 static void
3865   vl_api_show_one_nsh_mapping_reply_t_handler
3866   (vl_api_show_one_nsh_mapping_reply_t * mp)
3867 {
3868   vat_main_t *vam = &vat_main;
3869   i32 retval = ntohl (mp->retval);
3870
3871   if (0 <= retval)
3872     {
3873       print (vam->ofp, "%-20s%-16s",
3874              mp->is_set ? "set" : "not-set",
3875              mp->is_set ? (char *) mp->locator_set_name : "");
3876     }
3877
3878   vam->retval = retval;
3879   vam->result_ready = 1;
3880 }
3881
3882 static void
3883   vl_api_show_one_nsh_mapping_reply_t_handler_json
3884   (vl_api_show_one_nsh_mapping_reply_t * mp)
3885 {
3886   vat_main_t *vam = &vat_main;
3887   vat_json_node_t node;
3888   u8 *status = 0;
3889
3890   status = format (0, "%s", mp->is_set ? "yes" : "no");
3891   vec_add1 (status, 0);
3892
3893   vat_json_init_object (&node);
3894   vat_json_object_add_string_copy (&node, "is_set", status);
3895   if (mp->is_set)
3896     {
3897       vat_json_object_add_string_copy (&node, "locator_set",
3898                                        mp->locator_set_name);
3899     }
3900
3901   vec_free (status);
3902
3903   vat_json_print (vam->ofp, &node);
3904   vat_json_free (&node);
3905
3906   vam->retval = ntohl (mp->retval);
3907   vam->result_ready = 1;
3908 }
3909
3910 static void
3911   vl_api_show_one_map_register_ttl_reply_t_handler
3912   (vl_api_show_one_map_register_ttl_reply_t * mp)
3913 {
3914   vat_main_t *vam = &vat_main;
3915   i32 retval = ntohl (mp->retval);
3916
3917   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3918
3919   if (0 <= retval)
3920     {
3921       print (vam->ofp, "ttl: %u", mp->ttl);
3922     }
3923
3924   vam->retval = retval;
3925   vam->result_ready = 1;
3926 }
3927
3928 static void
3929   vl_api_show_one_map_register_ttl_reply_t_handler_json
3930   (vl_api_show_one_map_register_ttl_reply_t * mp)
3931 {
3932   vat_main_t *vam = &vat_main;
3933   vat_json_node_t node;
3934
3935   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3936   vat_json_init_object (&node);
3937   vat_json_object_add_uint (&node, "ttl", mp->ttl);
3938
3939   vat_json_print (vam->ofp, &node);
3940   vat_json_free (&node);
3941
3942   vam->retval = ntohl (mp->retval);
3943   vam->result_ready = 1;
3944 }
3945
3946 static void
3947 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3948 {
3949   vat_main_t *vam = &vat_main;
3950   i32 retval = ntohl (mp->retval);
3951
3952   if (0 <= retval)
3953     {
3954       print (vam->ofp, "%-20s%-16s",
3955              mp->status ? "enabled" : "disabled",
3956              mp->status ? (char *) mp->locator_set_name : "");
3957     }
3958
3959   vam->retval = retval;
3960   vam->result_ready = 1;
3961 }
3962
3963 static void
3964 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3965 {
3966   vat_main_t *vam = &vat_main;
3967   vat_json_node_t node;
3968   u8 *status = 0;
3969
3970   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3971   vec_add1 (status, 0);
3972
3973   vat_json_init_object (&node);
3974   vat_json_object_add_string_copy (&node, "status", status);
3975   if (mp->status)
3976     {
3977       vat_json_object_add_string_copy (&node, "locator_set",
3978                                        mp->locator_set_name);
3979     }
3980
3981   vec_free (status);
3982
3983   vat_json_print (vam->ofp, &node);
3984   vat_json_free (&node);
3985
3986   vam->retval = ntohl (mp->retval);
3987   vam->result_ready = 1;
3988 }
3989
3990 static u8 *
3991 format_policer_type (u8 * s, va_list * va)
3992 {
3993   u32 i = va_arg (*va, u32);
3994
3995   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3996     s = format (s, "1r2c");
3997   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3998     s = format (s, "1r3c");
3999   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4000     s = format (s, "2r3c-2698");
4001   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4002     s = format (s, "2r3c-4115");
4003   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4004     s = format (s, "2r3c-mef5cf1");
4005   else
4006     s = format (s, "ILLEGAL");
4007   return s;
4008 }
4009
4010 static u8 *
4011 format_policer_rate_type (u8 * s, va_list * va)
4012 {
4013   u32 i = va_arg (*va, u32);
4014
4015   if (i == SSE2_QOS_RATE_KBPS)
4016     s = format (s, "kbps");
4017   else if (i == SSE2_QOS_RATE_PPS)
4018     s = format (s, "pps");
4019   else
4020     s = format (s, "ILLEGAL");
4021   return s;
4022 }
4023
4024 static u8 *
4025 format_policer_round_type (u8 * s, va_list * va)
4026 {
4027   u32 i = va_arg (*va, u32);
4028
4029   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4030     s = format (s, "closest");
4031   else if (i == SSE2_QOS_ROUND_TO_UP)
4032     s = format (s, "up");
4033   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4034     s = format (s, "down");
4035   else
4036     s = format (s, "ILLEGAL");
4037   return s;
4038 }
4039
4040 static u8 *
4041 format_policer_action_type (u8 * s, va_list * va)
4042 {
4043   u32 i = va_arg (*va, u32);
4044
4045   if (i == SSE2_QOS_ACTION_DROP)
4046     s = format (s, "drop");
4047   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4048     s = format (s, "transmit");
4049   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4050     s = format (s, "mark-and-transmit");
4051   else
4052     s = format (s, "ILLEGAL");
4053   return s;
4054 }
4055
4056 static u8 *
4057 format_dscp (u8 * s, va_list * va)
4058 {
4059   u32 i = va_arg (*va, u32);
4060   char *t = 0;
4061
4062   switch (i)
4063     {
4064 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4065       foreach_vnet_dscp
4066 #undef _
4067     default:
4068       return format (s, "ILLEGAL");
4069     }
4070   s = format (s, "%s", t);
4071   return s;
4072 }
4073
4074 static void
4075 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4076 {
4077   vat_main_t *vam = &vat_main;
4078   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4079
4080   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4081     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4082   else
4083     conform_dscp_str = format (0, "");
4084
4085   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4086     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4087   else
4088     exceed_dscp_str = format (0, "");
4089
4090   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4091     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4092   else
4093     violate_dscp_str = format (0, "");
4094
4095   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4096          "rate type %U, round type %U, %s rate, %s color-aware, "
4097          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4098          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4099          "conform action %U%s, exceed action %U%s, violate action %U%s",
4100          mp->name,
4101          format_policer_type, mp->type,
4102          ntohl (mp->cir),
4103          ntohl (mp->eir),
4104          clib_net_to_host_u64 (mp->cb),
4105          clib_net_to_host_u64 (mp->eb),
4106          format_policer_rate_type, mp->rate_type,
4107          format_policer_round_type, mp->round_type,
4108          mp->single_rate ? "single" : "dual",
4109          mp->color_aware ? "is" : "not",
4110          ntohl (mp->cir_tokens_per_period),
4111          ntohl (mp->pir_tokens_per_period),
4112          ntohl (mp->scale),
4113          ntohl (mp->current_limit),
4114          ntohl (mp->current_bucket),
4115          ntohl (mp->extended_limit),
4116          ntohl (mp->extended_bucket),
4117          clib_net_to_host_u64 (mp->last_update_time),
4118          format_policer_action_type, mp->conform_action_type,
4119          conform_dscp_str,
4120          format_policer_action_type, mp->exceed_action_type,
4121          exceed_dscp_str,
4122          format_policer_action_type, mp->violate_action_type,
4123          violate_dscp_str);
4124
4125   vec_free (conform_dscp_str);
4126   vec_free (exceed_dscp_str);
4127   vec_free (violate_dscp_str);
4128 }
4129
4130 static void vl_api_policer_details_t_handler_json
4131   (vl_api_policer_details_t * mp)
4132 {
4133   vat_main_t *vam = &vat_main;
4134   vat_json_node_t *node;
4135   u8 *rate_type_str, *round_type_str, *type_str;
4136   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4137
4138   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4139   round_type_str =
4140     format (0, "%U", format_policer_round_type, mp->round_type);
4141   type_str = format (0, "%U", format_policer_type, mp->type);
4142   conform_action_str = format (0, "%U", format_policer_action_type,
4143                                mp->conform_action_type);
4144   exceed_action_str = format (0, "%U", format_policer_action_type,
4145                               mp->exceed_action_type);
4146   violate_action_str = format (0, "%U", format_policer_action_type,
4147                                mp->violate_action_type);
4148
4149   if (VAT_JSON_ARRAY != vam->json_tree.type)
4150     {
4151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4152       vat_json_init_array (&vam->json_tree);
4153     }
4154   node = vat_json_array_add (&vam->json_tree);
4155
4156   vat_json_init_object (node);
4157   vat_json_object_add_string_copy (node, "name", mp->name);
4158   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4159   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4160   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4161   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4162   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4163   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4164   vat_json_object_add_string_copy (node, "type", type_str);
4165   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4166   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4167   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4168   vat_json_object_add_uint (node, "cir_tokens_per_period",
4169                             ntohl (mp->cir_tokens_per_period));
4170   vat_json_object_add_uint (node, "eir_tokens_per_period",
4171                             ntohl (mp->pir_tokens_per_period));
4172   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4173   vat_json_object_add_uint (node, "current_bucket",
4174                             ntohl (mp->current_bucket));
4175   vat_json_object_add_uint (node, "extended_limit",
4176                             ntohl (mp->extended_limit));
4177   vat_json_object_add_uint (node, "extended_bucket",
4178                             ntohl (mp->extended_bucket));
4179   vat_json_object_add_uint (node, "last_update_time",
4180                             ntohl (mp->last_update_time));
4181   vat_json_object_add_string_copy (node, "conform_action",
4182                                    conform_action_str);
4183   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4184     {
4185       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4186       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4187       vec_free (dscp_str);
4188     }
4189   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4190   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4191     {
4192       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4193       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4194       vec_free (dscp_str);
4195     }
4196   vat_json_object_add_string_copy (node, "violate_action",
4197                                    violate_action_str);
4198   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4199     {
4200       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4201       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4202       vec_free (dscp_str);
4203     }
4204
4205   vec_free (rate_type_str);
4206   vec_free (round_type_str);
4207   vec_free (type_str);
4208   vec_free (conform_action_str);
4209   vec_free (exceed_action_str);
4210   vec_free (violate_action_str);
4211 }
4212
4213 static void
4214 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4215                                            mp)
4216 {
4217   vat_main_t *vam = &vat_main;
4218   int i, count = ntohl (mp->count);
4219
4220   if (count > 0)
4221     print (vam->ofp, "classify table ids (%d) : ", count);
4222   for (i = 0; i < count; i++)
4223     {
4224       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4225       print (vam->ofp, (i < count - 1) ? "," : "");
4226     }
4227   vam->retval = ntohl (mp->retval);
4228   vam->result_ready = 1;
4229 }
4230
4231 static void
4232   vl_api_classify_table_ids_reply_t_handler_json
4233   (vl_api_classify_table_ids_reply_t * mp)
4234 {
4235   vat_main_t *vam = &vat_main;
4236   int i, count = ntohl (mp->count);
4237
4238   if (count > 0)
4239     {
4240       vat_json_node_t node;
4241
4242       vat_json_init_object (&node);
4243       for (i = 0; i < count; i++)
4244         {
4245           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4246         }
4247       vat_json_print (vam->ofp, &node);
4248       vat_json_free (&node);
4249     }
4250   vam->retval = ntohl (mp->retval);
4251   vam->result_ready = 1;
4252 }
4253
4254 static void
4255   vl_api_classify_table_by_interface_reply_t_handler
4256   (vl_api_classify_table_by_interface_reply_t * mp)
4257 {
4258   vat_main_t *vam = &vat_main;
4259   u32 table_id;
4260
4261   table_id = ntohl (mp->l2_table_id);
4262   if (table_id != ~0)
4263     print (vam->ofp, "l2 table id : %d", table_id);
4264   else
4265     print (vam->ofp, "l2 table id : No input ACL tables configured");
4266   table_id = ntohl (mp->ip4_table_id);
4267   if (table_id != ~0)
4268     print (vam->ofp, "ip4 table id : %d", table_id);
4269   else
4270     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4271   table_id = ntohl (mp->ip6_table_id);
4272   if (table_id != ~0)
4273     print (vam->ofp, "ip6 table id : %d", table_id);
4274   else
4275     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4276   vam->retval = ntohl (mp->retval);
4277   vam->result_ready = 1;
4278 }
4279
4280 static void
4281   vl_api_classify_table_by_interface_reply_t_handler_json
4282   (vl_api_classify_table_by_interface_reply_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285   vat_json_node_t node;
4286
4287   vat_json_init_object (&node);
4288
4289   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4290   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4291   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4292
4293   vat_json_print (vam->ofp, &node);
4294   vat_json_free (&node);
4295
4296   vam->retval = ntohl (mp->retval);
4297   vam->result_ready = 1;
4298 }
4299
4300 static void vl_api_policer_add_del_reply_t_handler
4301   (vl_api_policer_add_del_reply_t * mp)
4302 {
4303   vat_main_t *vam = &vat_main;
4304   i32 retval = ntohl (mp->retval);
4305   if (vam->async_mode)
4306     {
4307       vam->async_errors += (retval < 0);
4308     }
4309   else
4310     {
4311       vam->retval = retval;
4312       vam->result_ready = 1;
4313       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4314         /*
4315          * Note: this is just barely thread-safe, depends on
4316          * the main thread spinning waiting for an answer...
4317          */
4318         errmsg ("policer index %d", ntohl (mp->policer_index));
4319     }
4320 }
4321
4322 static void vl_api_policer_add_del_reply_t_handler_json
4323   (vl_api_policer_add_del_reply_t * mp)
4324 {
4325   vat_main_t *vam = &vat_main;
4326   vat_json_node_t node;
4327
4328   vat_json_init_object (&node);
4329   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4330   vat_json_object_add_uint (&node, "policer_index",
4331                             ntohl (mp->policer_index));
4332
4333   vat_json_print (vam->ofp, &node);
4334   vat_json_free (&node);
4335
4336   vam->retval = ntohl (mp->retval);
4337   vam->result_ready = 1;
4338 }
4339
4340 /* Format hex dump. */
4341 u8 *
4342 format_hex_bytes (u8 * s, va_list * va)
4343 {
4344   u8 *bytes = va_arg (*va, u8 *);
4345   int n_bytes = va_arg (*va, int);
4346   uword i;
4347
4348   /* Print short or long form depending on byte count. */
4349   uword short_form = n_bytes <= 32;
4350   uword indent = format_get_indent (s);
4351
4352   if (n_bytes == 0)
4353     return s;
4354
4355   for (i = 0; i < n_bytes; i++)
4356     {
4357       if (!short_form && (i % 32) == 0)
4358         s = format (s, "%08x: ", i);
4359       s = format (s, "%02x", bytes[i]);
4360       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4361         s = format (s, "\n%U", format_white_space, indent);
4362     }
4363
4364   return s;
4365 }
4366
4367 static void
4368 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4369                                             * mp)
4370 {
4371   vat_main_t *vam = &vat_main;
4372   i32 retval = ntohl (mp->retval);
4373   if (retval == 0)
4374     {
4375       print (vam->ofp, "classify table info :");
4376       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4377              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4378              ntohl (mp->miss_next_index));
4379       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4380              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4381              ntohl (mp->match_n_vectors));
4382       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4383              ntohl (mp->mask_length));
4384     }
4385   vam->retval = retval;
4386   vam->result_ready = 1;
4387 }
4388
4389 static void
4390   vl_api_classify_table_info_reply_t_handler_json
4391   (vl_api_classify_table_info_reply_t * mp)
4392 {
4393   vat_main_t *vam = &vat_main;
4394   vat_json_node_t node;
4395
4396   i32 retval = ntohl (mp->retval);
4397   if (retval == 0)
4398     {
4399       vat_json_init_object (&node);
4400
4401       vat_json_object_add_int (&node, "sessions",
4402                                ntohl (mp->active_sessions));
4403       vat_json_object_add_int (&node, "nexttbl",
4404                                ntohl (mp->next_table_index));
4405       vat_json_object_add_int (&node, "nextnode",
4406                                ntohl (mp->miss_next_index));
4407       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4408       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4409       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4410       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4411                       ntohl (mp->mask_length), 0);
4412       vat_json_object_add_string_copy (&node, "mask", s);
4413
4414       vat_json_print (vam->ofp, &node);
4415       vat_json_free (&node);
4416     }
4417   vam->retval = ntohl (mp->retval);
4418   vam->result_ready = 1;
4419 }
4420
4421 static void
4422 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4423                                            mp)
4424 {
4425   vat_main_t *vam = &vat_main;
4426
4427   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4428          ntohl (mp->hit_next_index), ntohl (mp->advance),
4429          ntohl (mp->opaque_index));
4430   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4431          ntohl (mp->match_length));
4432 }
4433
4434 static void
4435   vl_api_classify_session_details_t_handler_json
4436   (vl_api_classify_session_details_t * mp)
4437 {
4438   vat_main_t *vam = &vat_main;
4439   vat_json_node_t *node = NULL;
4440
4441   if (VAT_JSON_ARRAY != vam->json_tree.type)
4442     {
4443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4444       vat_json_init_array (&vam->json_tree);
4445     }
4446   node = vat_json_array_add (&vam->json_tree);
4447
4448   vat_json_init_object (node);
4449   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4450   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4451   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4452   u8 *s =
4453     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4454             0);
4455   vat_json_object_add_string_copy (node, "match", s);
4456 }
4457
4458 static void vl_api_pg_create_interface_reply_t_handler
4459   (vl_api_pg_create_interface_reply_t * mp)
4460 {
4461   vat_main_t *vam = &vat_main;
4462
4463   vam->retval = ntohl (mp->retval);
4464   vam->result_ready = 1;
4465 }
4466
4467 static void vl_api_pg_create_interface_reply_t_handler_json
4468   (vl_api_pg_create_interface_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   vat_json_node_t node;
4472
4473   i32 retval = ntohl (mp->retval);
4474   if (retval == 0)
4475     {
4476       vat_json_init_object (&node);
4477
4478       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4479
4480       vat_json_print (vam->ofp, &node);
4481       vat_json_free (&node);
4482     }
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void vl_api_policer_classify_details_t_handler
4488   (vl_api_policer_classify_details_t * mp)
4489 {
4490   vat_main_t *vam = &vat_main;
4491
4492   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4493          ntohl (mp->table_index));
4494 }
4495
4496 static void vl_api_policer_classify_details_t_handler_json
4497   (vl_api_policer_classify_details_t * mp)
4498 {
4499   vat_main_t *vam = &vat_main;
4500   vat_json_node_t *node;
4501
4502   if (VAT_JSON_ARRAY != vam->json_tree.type)
4503     {
4504       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4505       vat_json_init_array (&vam->json_tree);
4506     }
4507   node = vat_json_array_add (&vam->json_tree);
4508
4509   vat_json_init_object (node);
4510   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4511   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4512 }
4513
4514 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4515   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4516 {
4517   vat_main_t *vam = &vat_main;
4518   i32 retval = ntohl (mp->retval);
4519   if (vam->async_mode)
4520     {
4521       vam->async_errors += (retval < 0);
4522     }
4523   else
4524     {
4525       vam->retval = retval;
4526       vam->sw_if_index = ntohl (mp->sw_if_index);
4527       vam->result_ready = 1;
4528     }
4529 }
4530
4531 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4532   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4533 {
4534   vat_main_t *vam = &vat_main;
4535   vat_json_node_t node;
4536
4537   vat_json_init_object (&node);
4538   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4539   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4540
4541   vat_json_print (vam->ofp, &node);
4542   vat_json_free (&node);
4543
4544   vam->retval = ntohl (mp->retval);
4545   vam->result_ready = 1;
4546 }
4547
4548 static void vl_api_flow_classify_details_t_handler
4549   (vl_api_flow_classify_details_t * mp)
4550 {
4551   vat_main_t *vam = &vat_main;
4552
4553   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4554          ntohl (mp->table_index));
4555 }
4556
4557 static void vl_api_flow_classify_details_t_handler_json
4558   (vl_api_flow_classify_details_t * mp)
4559 {
4560   vat_main_t *vam = &vat_main;
4561   vat_json_node_t *node;
4562
4563   if (VAT_JSON_ARRAY != vam->json_tree.type)
4564     {
4565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4566       vat_json_init_array (&vam->json_tree);
4567     }
4568   node = vat_json_array_add (&vam->json_tree);
4569
4570   vat_json_init_object (node);
4571   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4572   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4573 }
4574
4575 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4576 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4577 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4578 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4579 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4580 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4581 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4582 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4583 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4584 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4585 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4586 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4587 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4588 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4589 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4590 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4591 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4592 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4593
4594 /*
4595  * Generate boilerplate reply handlers, which
4596  * dig the return value out of the xxx_reply_t API message,
4597  * stick it into vam->retval, and set vam->result_ready
4598  *
4599  * Could also do this by pointing N message decode slots at
4600  * a single function, but that could break in subtle ways.
4601  */
4602
4603 #define foreach_standard_reply_retval_handler           \
4604 _(sw_interface_set_flags_reply)                         \
4605 _(sw_interface_add_del_address_reply)                   \
4606 _(sw_interface_set_table_reply)                         \
4607 _(sw_interface_set_mpls_enable_reply)                   \
4608 _(sw_interface_set_vpath_reply)                         \
4609 _(sw_interface_set_vxlan_bypass_reply)                  \
4610 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4611 _(sw_interface_set_l2_bridge_reply)                     \
4612 _(bridge_domain_add_del_reply)                          \
4613 _(sw_interface_set_l2_xconnect_reply)                   \
4614 _(l2fib_add_del_reply)                                  \
4615 _(l2fib_flush_int_reply)                                \
4616 _(l2fib_flush_bd_reply)                                 \
4617 _(ip_add_del_route_reply)                               \
4618 _(ip_mroute_add_del_reply)                              \
4619 _(mpls_route_add_del_reply)                             \
4620 _(mpls_ip_bind_unbind_reply)                            \
4621 _(proxy_arp_add_del_reply)                              \
4622 _(proxy_arp_intfc_enable_disable_reply)                 \
4623 _(sw_interface_set_unnumbered_reply)                    \
4624 _(ip_neighbor_add_del_reply)                            \
4625 _(reset_vrf_reply)                                      \
4626 _(oam_add_del_reply)                                    \
4627 _(reset_fib_reply)                                      \
4628 _(dhcp_proxy_config_reply)                              \
4629 _(dhcp_proxy_set_vss_reply)                             \
4630 _(dhcp_client_config_reply)                             \
4631 _(set_ip_flow_hash_reply)                               \
4632 _(sw_interface_ip6_enable_disable_reply)                \
4633 _(sw_interface_ip6_set_link_local_address_reply)        \
4634 _(ip6nd_proxy_add_del_reply)                            \
4635 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4636 _(sw_interface_ip6nd_ra_config_reply)                   \
4637 _(set_arp_neighbor_limit_reply)                         \
4638 _(l2_patch_add_del_reply)                               \
4639 _(sr_policy_add_reply)                                  \
4640 _(sr_policy_mod_reply)                                  \
4641 _(sr_policy_del_reply)                                  \
4642 _(sr_localsid_add_del_reply)                            \
4643 _(sr_steering_add_del_reply)                            \
4644 _(classify_add_del_session_reply)                       \
4645 _(classify_set_interface_ip_table_reply)                \
4646 _(classify_set_interface_l2_tables_reply)               \
4647 _(l2tpv3_set_tunnel_cookies_reply)                      \
4648 _(l2tpv3_interface_enable_disable_reply)                \
4649 _(l2tpv3_set_lookup_key_reply)                          \
4650 _(l2_fib_clear_table_reply)                             \
4651 _(l2_interface_efp_filter_reply)                        \
4652 _(l2_interface_vlan_tag_rewrite_reply)                  \
4653 _(modify_vhost_user_if_reply)                           \
4654 _(delete_vhost_user_if_reply)                           \
4655 _(want_ip4_arp_events_reply)                            \
4656 _(want_ip6_nd_events_reply)                             \
4657 _(want_l2_macs_events_reply)                            \
4658 _(input_acl_set_interface_reply)                        \
4659 _(ipsec_spd_add_del_reply)                              \
4660 _(ipsec_interface_add_del_spd_reply)                    \
4661 _(ipsec_spd_add_del_entry_reply)                        \
4662 _(ipsec_sad_add_del_entry_reply)                        \
4663 _(ipsec_sa_set_key_reply)                               \
4664 _(ipsec_tunnel_if_add_del_reply)                        \
4665 _(ikev2_profile_add_del_reply)                          \
4666 _(ikev2_profile_set_auth_reply)                         \
4667 _(ikev2_profile_set_id_reply)                           \
4668 _(ikev2_profile_set_ts_reply)                           \
4669 _(ikev2_set_local_key_reply)                            \
4670 _(ikev2_set_responder_reply)                            \
4671 _(ikev2_set_ike_transforms_reply)                       \
4672 _(ikev2_set_esp_transforms_reply)                       \
4673 _(ikev2_set_sa_lifetime_reply)                          \
4674 _(ikev2_initiate_sa_init_reply)                         \
4675 _(ikev2_initiate_del_ike_sa_reply)                      \
4676 _(ikev2_initiate_del_child_sa_reply)                    \
4677 _(ikev2_initiate_rekey_child_sa_reply)                  \
4678 _(delete_loopback_reply)                                \
4679 _(bd_ip_mac_add_del_reply)                              \
4680 _(map_del_domain_reply)                                 \
4681 _(map_add_del_rule_reply)                               \
4682 _(want_interface_events_reply)                          \
4683 _(want_stats_reply)                                     \
4684 _(cop_interface_enable_disable_reply)                   \
4685 _(cop_whitelist_enable_disable_reply)                   \
4686 _(sw_interface_clear_stats_reply)                       \
4687 _(ioam_enable_reply)                              \
4688 _(ioam_disable_reply)                              \
4689 _(one_add_del_locator_reply)                            \
4690 _(one_add_del_local_eid_reply)                          \
4691 _(one_add_del_remote_mapping_reply)                     \
4692 _(one_add_del_adjacency_reply)                          \
4693 _(one_add_del_map_resolver_reply)                       \
4694 _(one_add_del_map_server_reply)                         \
4695 _(one_enable_disable_reply)                             \
4696 _(one_rloc_probe_enable_disable_reply)                  \
4697 _(one_map_register_enable_disable_reply)                \
4698 _(one_map_register_set_ttl_reply)                       \
4699 _(one_map_register_fallback_threshold_reply)            \
4700 _(one_pitr_set_locator_set_reply)                       \
4701 _(one_map_request_mode_reply)                           \
4702 _(one_add_del_map_request_itr_rlocs_reply)              \
4703 _(one_eid_table_add_del_map_reply)                      \
4704 _(one_use_petr_reply)                                   \
4705 _(one_stats_enable_disable_reply)                       \
4706 _(one_add_del_l2_arp_entry_reply)                       \
4707 _(one_stats_flush_reply)                                \
4708 _(gpe_enable_disable_reply)                             \
4709 _(gpe_set_encap_mode_reply)                             \
4710 _(gpe_add_del_iface_reply)                              \
4711 _(gpe_add_del_native_fwd_rpath_reply)                   \
4712 _(af_packet_delete_reply)                               \
4713 _(policer_classify_set_interface_reply)                 \
4714 _(netmap_create_reply)                                  \
4715 _(netmap_delete_reply)                                  \
4716 _(set_ipfix_exporter_reply)                             \
4717 _(set_ipfix_classify_stream_reply)                      \
4718 _(ipfix_classify_table_add_del_reply)                   \
4719 _(flow_classify_set_interface_reply)                    \
4720 _(sw_interface_span_enable_disable_reply)               \
4721 _(pg_capture_reply)                                     \
4722 _(pg_enable_disable_reply)                              \
4723 _(ip_source_and_port_range_check_add_del_reply)         \
4724 _(ip_source_and_port_range_check_interface_add_del_reply)\
4725 _(delete_subif_reply)                                   \
4726 _(l2_interface_pbb_tag_rewrite_reply)                   \
4727 _(punt_reply)                                           \
4728 _(feature_enable_disable_reply)                         \
4729 _(sw_interface_tag_add_del_reply)                       \
4730 _(sw_interface_set_mtu_reply)                           \
4731 _(p2p_ethernet_add_reply)                               \
4732 _(p2p_ethernet_del_reply)                               \
4733 _(lldp_config_reply)                                    \
4734 _(sw_interface_set_lldp_reply)
4735
4736 #define _(n)                                    \
4737     static void vl_api_##n##_t_handler          \
4738     (vl_api_##n##_t * mp)                       \
4739     {                                           \
4740         vat_main_t * vam = &vat_main;           \
4741         i32 retval = ntohl(mp->retval);         \
4742         if (vam->async_mode) {                  \
4743             vam->async_errors += (retval < 0);  \
4744         } else {                                \
4745             vam->retval = retval;               \
4746             vam->result_ready = 1;              \
4747         }                                       \
4748     }
4749 foreach_standard_reply_retval_handler;
4750 #undef _
4751
4752 #define _(n)                                    \
4753     static void vl_api_##n##_t_handler_json     \
4754     (vl_api_##n##_t * mp)                       \
4755     {                                           \
4756         vat_main_t * vam = &vat_main;           \
4757         vat_json_node_t node;                   \
4758         vat_json_init_object(&node);            \
4759         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4760         vat_json_print(vam->ofp, &node);        \
4761         vam->retval = ntohl(mp->retval);        \
4762         vam->result_ready = 1;                  \
4763     }
4764 foreach_standard_reply_retval_handler;
4765 #undef _
4766
4767 /*
4768  * Table of message reply handlers, must include boilerplate handlers
4769  * we just generated
4770  */
4771
4772 #define foreach_vpe_api_reply_msg                                       \
4773 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4774 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4775 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4776 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4777 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4778 _(CLI_REPLY, cli_reply)                                                 \
4779 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4780 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4781   sw_interface_add_del_address_reply)                                   \
4782 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4783 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4784 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4785 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4786 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4787 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4788   sw_interface_set_l2_xconnect_reply)                                   \
4789 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4790   sw_interface_set_l2_bridge_reply)                                     \
4791 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4792 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4793 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4794 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4795 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4796 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4797 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4798 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4799 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4800 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4801 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4802 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4803 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4804 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4805 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4806 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4807 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4808 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4809   proxy_arp_intfc_enable_disable_reply)                                 \
4810 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4811 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4812   sw_interface_set_unnumbered_reply)                                    \
4813 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4814 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4815 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4816 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4817 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4818 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4819 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4820 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4821 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4822 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4823 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4824 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4825   sw_interface_ip6_enable_disable_reply)                                \
4826 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4827   sw_interface_ip6_set_link_local_address_reply)                        \
4828 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4829 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4830 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4831   sw_interface_ip6nd_ra_prefix_reply)                                   \
4832 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4833   sw_interface_ip6nd_ra_config_reply)                                   \
4834 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4835 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4836 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4837 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4838 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4839 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4840 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4841 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4842 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4843 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4844 classify_set_interface_ip_table_reply)                                  \
4845 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4846   classify_set_interface_l2_tables_reply)                               \
4847 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4848 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4849 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4850 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4851 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4852   l2tpv3_interface_enable_disable_reply)                                \
4853 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4854 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4855 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4856 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4857 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4858 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4859 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4860 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4861 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4862 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4863 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4864 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4865 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4866 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4867 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4868 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4869 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4870 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4871 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4872 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4873 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4874 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4875 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
4876 _(L2_MACS_EVENT, l2_macs_event)                                         \
4877 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4878 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4879 _(IP_DETAILS, ip_details)                                               \
4880 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4881 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4882 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4883 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4884 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4885 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4886 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4887 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4888 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4889 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4890 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4891 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4892 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4893 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4894 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4895 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4896 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4897 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4898 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4899 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4900 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4901 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4902 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4903 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4904 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4905 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4906 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4907 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4908 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4909 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4910 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4911 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4912 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4913 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4914 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4915 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4916 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4917 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4918 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4919 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4920 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4921 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4922 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4923 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4924 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4925   one_map_register_enable_disable_reply)                                \
4926 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
4927 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
4928   one_map_register_fallback_threshold_reply)                            \
4929 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4930   one_rloc_probe_enable_disable_reply)                                  \
4931 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4932 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4933 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4934 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4935 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4936 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4937 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4938 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4939 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4940 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4941 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4942 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4943 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4944 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4945 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4946 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4947   show_one_stats_enable_disable_reply)                                  \
4948 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4949 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4950 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4951 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4952 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4953 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4954 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4955 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4956 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4957 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4958 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4959 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4960   gpe_add_del_native_fwd_rpath_reply)                                   \
4961 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4962   gpe_fwd_entry_path_details)                                           \
4963 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4964 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4965   one_add_del_map_request_itr_rlocs_reply)                              \
4966 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4967   one_get_map_request_itr_rlocs_reply)                                  \
4968 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4969 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4970 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4971 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4972 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4973 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4974   show_one_map_register_state_reply)                                    \
4975 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
4976 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
4977   show_one_map_register_fallback_threshold_reply)                       \
4978 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4979 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4980 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4981 _(POLICER_DETAILS, policer_details)                                     \
4982 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4983 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4984 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4985 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4986 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4987 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4988 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4989 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4990 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4991 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4992 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4993 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4994 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4995 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4996 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4997 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4998 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4999 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5000 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5001 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5002 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5003 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5004 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5005 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5006 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5007  ip_source_and_port_range_check_add_del_reply)                          \
5008 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5009  ip_source_and_port_range_check_interface_add_del_reply)                \
5010 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5011 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5012 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5013 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5014 _(PUNT_REPLY, punt_reply)                                               \
5015 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5016 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5017 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5018 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5019 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5020 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5021 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5022 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5023 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5024 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5025 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5026 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)
5027
5028 #define foreach_standalone_reply_msg                                    \
5029 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
5030 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5031 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5032 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5033 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5034 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5035 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5036
5037 typedef struct
5038 {
5039   u8 *name;
5040   u32 value;
5041 } name_sort_t;
5042
5043
5044 #define STR_VTR_OP_CASE(op)     \
5045     case L2_VTR_ ## op:         \
5046         return "" # op;
5047
5048 static const char *
5049 str_vtr_op (u32 vtr_op)
5050 {
5051   switch (vtr_op)
5052     {
5053       STR_VTR_OP_CASE (DISABLED);
5054       STR_VTR_OP_CASE (PUSH_1);
5055       STR_VTR_OP_CASE (PUSH_2);
5056       STR_VTR_OP_CASE (POP_1);
5057       STR_VTR_OP_CASE (POP_2);
5058       STR_VTR_OP_CASE (TRANSLATE_1_1);
5059       STR_VTR_OP_CASE (TRANSLATE_1_2);
5060       STR_VTR_OP_CASE (TRANSLATE_2_1);
5061       STR_VTR_OP_CASE (TRANSLATE_2_2);
5062     }
5063
5064   return "UNKNOWN";
5065 }
5066
5067 static int
5068 dump_sub_interface_table (vat_main_t * vam)
5069 {
5070   const sw_interface_subif_t *sub = NULL;
5071
5072   if (vam->json_output)
5073     {
5074       clib_warning
5075         ("JSON output supported only for VPE API calls and dump_stats_table");
5076       return -99;
5077     }
5078
5079   print (vam->ofp,
5080          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5081          "Interface", "sw_if_index",
5082          "sub id", "dot1ad", "tags", "outer id",
5083          "inner id", "exact", "default", "outer any", "inner any");
5084
5085   vec_foreach (sub, vam->sw_if_subif_table)
5086   {
5087     print (vam->ofp,
5088            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5089            sub->interface_name,
5090            sub->sw_if_index,
5091            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5092            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5093            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5094            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5095     if (sub->vtr_op != L2_VTR_DISABLED)
5096       {
5097         print (vam->ofp,
5098                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5099                "tag1: %d tag2: %d ]",
5100                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5101                sub->vtr_tag1, sub->vtr_tag2);
5102       }
5103   }
5104
5105   return 0;
5106 }
5107
5108 static int
5109 name_sort_cmp (void *a1, void *a2)
5110 {
5111   name_sort_t *n1 = a1;
5112   name_sort_t *n2 = a2;
5113
5114   return strcmp ((char *) n1->name, (char *) n2->name);
5115 }
5116
5117 static int
5118 dump_interface_table (vat_main_t * vam)
5119 {
5120   hash_pair_t *p;
5121   name_sort_t *nses = 0, *ns;
5122
5123   if (vam->json_output)
5124     {
5125       clib_warning
5126         ("JSON output supported only for VPE API calls and dump_stats_table");
5127       return -99;
5128     }
5129
5130   /* *INDENT-OFF* */
5131   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5132   ({
5133     vec_add2 (nses, ns, 1);
5134     ns->name = (u8 *)(p->key);
5135     ns->value = (u32) p->value[0];
5136   }));
5137   /* *INDENT-ON* */
5138
5139   vec_sort_with_function (nses, name_sort_cmp);
5140
5141   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5142   vec_foreach (ns, nses)
5143   {
5144     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5145   }
5146   vec_free (nses);
5147   return 0;
5148 }
5149
5150 static int
5151 dump_ip_table (vat_main_t * vam, int is_ipv6)
5152 {
5153   const ip_details_t *det = NULL;
5154   const ip_address_details_t *address = NULL;
5155   u32 i = ~0;
5156
5157   print (vam->ofp, "%-12s", "sw_if_index");
5158
5159   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5160   {
5161     i++;
5162     if (!det->present)
5163       {
5164         continue;
5165       }
5166     print (vam->ofp, "%-12d", i);
5167     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5168     if (!det->addr)
5169       {
5170         continue;
5171       }
5172     vec_foreach (address, det->addr)
5173     {
5174       print (vam->ofp,
5175              "            %-30U%-13d",
5176              is_ipv6 ? format_ip6_address : format_ip4_address,
5177              address->ip, address->prefix_length);
5178     }
5179   }
5180
5181   return 0;
5182 }
5183
5184 static int
5185 dump_ipv4_table (vat_main_t * vam)
5186 {
5187   if (vam->json_output)
5188     {
5189       clib_warning
5190         ("JSON output supported only for VPE API calls and dump_stats_table");
5191       return -99;
5192     }
5193
5194   return dump_ip_table (vam, 0);
5195 }
5196
5197 static int
5198 dump_ipv6_table (vat_main_t * vam)
5199 {
5200   if (vam->json_output)
5201     {
5202       clib_warning
5203         ("JSON output supported only for VPE API calls and dump_stats_table");
5204       return -99;
5205     }
5206
5207   return dump_ip_table (vam, 1);
5208 }
5209
5210 static char *
5211 counter_type_to_str (u8 counter_type, u8 is_combined)
5212 {
5213   if (!is_combined)
5214     {
5215       switch (counter_type)
5216         {
5217         case VNET_INTERFACE_COUNTER_DROP:
5218           return "drop";
5219         case VNET_INTERFACE_COUNTER_PUNT:
5220           return "punt";
5221         case VNET_INTERFACE_COUNTER_IP4:
5222           return "ip4";
5223         case VNET_INTERFACE_COUNTER_IP6:
5224           return "ip6";
5225         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5226           return "rx-no-buf";
5227         case VNET_INTERFACE_COUNTER_RX_MISS:
5228           return "rx-miss";
5229         case VNET_INTERFACE_COUNTER_RX_ERROR:
5230           return "rx-error";
5231         case VNET_INTERFACE_COUNTER_TX_ERROR:
5232           return "tx-error";
5233         default:
5234           return "INVALID-COUNTER-TYPE";
5235         }
5236     }
5237   else
5238     {
5239       switch (counter_type)
5240         {
5241         case VNET_INTERFACE_COUNTER_RX:
5242           return "rx";
5243         case VNET_INTERFACE_COUNTER_TX:
5244           return "tx";
5245         default:
5246           return "INVALID-COUNTER-TYPE";
5247         }
5248     }
5249 }
5250
5251 static int
5252 dump_stats_table (vat_main_t * vam)
5253 {
5254   vat_json_node_t node;
5255   vat_json_node_t *msg_array;
5256   vat_json_node_t *msg;
5257   vat_json_node_t *counter_array;
5258   vat_json_node_t *counter;
5259   interface_counter_t c;
5260   u64 packets;
5261   ip4_fib_counter_t *c4;
5262   ip6_fib_counter_t *c6;
5263   ip4_nbr_counter_t *n4;
5264   ip6_nbr_counter_t *n6;
5265   int i, j;
5266
5267   if (!vam->json_output)
5268     {
5269       clib_warning ("dump_stats_table supported only in JSON format");
5270       return -99;
5271     }
5272
5273   vat_json_init_object (&node);
5274
5275   /* interface counters */
5276   msg_array = vat_json_object_add (&node, "interface_counters");
5277   vat_json_init_array (msg_array);
5278   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5279     {
5280       msg = vat_json_array_add (msg_array);
5281       vat_json_init_object (msg);
5282       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5283                                        (u8 *) counter_type_to_str (i, 0));
5284       vat_json_object_add_int (msg, "is_combined", 0);
5285       counter_array = vat_json_object_add (msg, "data");
5286       vat_json_init_array (counter_array);
5287       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5288         {
5289           packets = vam->simple_interface_counters[i][j];
5290           vat_json_array_add_uint (counter_array, packets);
5291         }
5292     }
5293   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5294     {
5295       msg = vat_json_array_add (msg_array);
5296       vat_json_init_object (msg);
5297       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5298                                        (u8 *) counter_type_to_str (i, 1));
5299       vat_json_object_add_int (msg, "is_combined", 1);
5300       counter_array = vat_json_object_add (msg, "data");
5301       vat_json_init_array (counter_array);
5302       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5303         {
5304           c = vam->combined_interface_counters[i][j];
5305           counter = vat_json_array_add (counter_array);
5306           vat_json_init_object (counter);
5307           vat_json_object_add_uint (counter, "packets", c.packets);
5308           vat_json_object_add_uint (counter, "bytes", c.bytes);
5309         }
5310     }
5311
5312   /* ip4 fib counters */
5313   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5314   vat_json_init_array (msg_array);
5315   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5316     {
5317       msg = vat_json_array_add (msg_array);
5318       vat_json_init_object (msg);
5319       vat_json_object_add_uint (msg, "vrf_id",
5320                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5321       counter_array = vat_json_object_add (msg, "c");
5322       vat_json_init_array (counter_array);
5323       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5324         {
5325           counter = vat_json_array_add (counter_array);
5326           vat_json_init_object (counter);
5327           c4 = &vam->ip4_fib_counters[i][j];
5328           vat_json_object_add_ip4 (counter, "address", c4->address);
5329           vat_json_object_add_uint (counter, "address_length",
5330                                     c4->address_length);
5331           vat_json_object_add_uint (counter, "packets", c4->packets);
5332           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5333         }
5334     }
5335
5336   /* ip6 fib counters */
5337   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5338   vat_json_init_array (msg_array);
5339   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5340     {
5341       msg = vat_json_array_add (msg_array);
5342       vat_json_init_object (msg);
5343       vat_json_object_add_uint (msg, "vrf_id",
5344                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5345       counter_array = vat_json_object_add (msg, "c");
5346       vat_json_init_array (counter_array);
5347       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5348         {
5349           counter = vat_json_array_add (counter_array);
5350           vat_json_init_object (counter);
5351           c6 = &vam->ip6_fib_counters[i][j];
5352           vat_json_object_add_ip6 (counter, "address", c6->address);
5353           vat_json_object_add_uint (counter, "address_length",
5354                                     c6->address_length);
5355           vat_json_object_add_uint (counter, "packets", c6->packets);
5356           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5357         }
5358     }
5359
5360   /* ip4 nbr counters */
5361   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5362   vat_json_init_array (msg_array);
5363   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5364     {
5365       msg = vat_json_array_add (msg_array);
5366       vat_json_init_object (msg);
5367       vat_json_object_add_uint (msg, "sw_if_index", i);
5368       counter_array = vat_json_object_add (msg, "c");
5369       vat_json_init_array (counter_array);
5370       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5371         {
5372           counter = vat_json_array_add (counter_array);
5373           vat_json_init_object (counter);
5374           n4 = &vam->ip4_nbr_counters[i][j];
5375           vat_json_object_add_ip4 (counter, "address", n4->address);
5376           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5377           vat_json_object_add_uint (counter, "packets", n4->packets);
5378           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5379         }
5380     }
5381
5382   /* ip6 nbr counters */
5383   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5384   vat_json_init_array (msg_array);
5385   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5386     {
5387       msg = vat_json_array_add (msg_array);
5388       vat_json_init_object (msg);
5389       vat_json_object_add_uint (msg, "sw_if_index", i);
5390       counter_array = vat_json_object_add (msg, "c");
5391       vat_json_init_array (counter_array);
5392       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5393         {
5394           counter = vat_json_array_add (counter_array);
5395           vat_json_init_object (counter);
5396           n6 = &vam->ip6_nbr_counters[i][j];
5397           vat_json_object_add_ip6 (counter, "address", n6->address);
5398           vat_json_object_add_uint (counter, "packets", n6->packets);
5399           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5400         }
5401     }
5402
5403   vat_json_print (vam->ofp, &node);
5404   vat_json_free (&node);
5405
5406   return 0;
5407 }
5408
5409 int
5410 exec (vat_main_t * vam)
5411 {
5412   api_main_t *am = &api_main;
5413   vl_api_cli_t *mp;
5414   f64 timeout;
5415   void *oldheap;
5416   u8 *cmd = 0;
5417   unformat_input_t *i = vam->input;
5418
5419   if (vec_len (i->buffer) == 0)
5420     return -1;
5421
5422   if (vam->exec_mode == 0 && unformat (i, "mode"))
5423     {
5424       vam->exec_mode = 1;
5425       return 0;
5426     }
5427   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5428     {
5429       vam->exec_mode = 0;
5430       return 0;
5431     }
5432
5433
5434   M (CLI, mp);
5435
5436   /*
5437    * Copy cmd into shared memory.
5438    * In order for the CLI command to work, it
5439    * must be a vector ending in \n, not a C-string ending
5440    * in \n\0.
5441    */
5442   pthread_mutex_lock (&am->vlib_rp->mutex);
5443   oldheap = svm_push_data_heap (am->vlib_rp);
5444
5445   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5446   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5447
5448   svm_pop_heap (oldheap);
5449   pthread_mutex_unlock (&am->vlib_rp->mutex);
5450
5451   mp->cmd_in_shmem = pointer_to_uword (cmd);
5452   S (mp);
5453   timeout = vat_time_now (vam) + 10.0;
5454
5455   while (vat_time_now (vam) < timeout)
5456     {
5457       if (vam->result_ready == 1)
5458         {
5459           u8 *free_me;
5460           if (vam->shmem_result != NULL)
5461             print (vam->ofp, "%s", vam->shmem_result);
5462           pthread_mutex_lock (&am->vlib_rp->mutex);
5463           oldheap = svm_push_data_heap (am->vlib_rp);
5464
5465           free_me = (u8 *) vam->shmem_result;
5466           vec_free (free_me);
5467
5468           svm_pop_heap (oldheap);
5469           pthread_mutex_unlock (&am->vlib_rp->mutex);
5470           return 0;
5471         }
5472     }
5473   return -99;
5474 }
5475
5476 /*
5477  * Future replacement of exec() that passes CLI buffers directly in
5478  * the API messages instead of an additional shared memory area.
5479  */
5480 static int
5481 exec_inband (vat_main_t * vam)
5482 {
5483   vl_api_cli_inband_t *mp;
5484   unformat_input_t *i = vam->input;
5485   int ret;
5486
5487   if (vec_len (i->buffer) == 0)
5488     return -1;
5489
5490   if (vam->exec_mode == 0 && unformat (i, "mode"))
5491     {
5492       vam->exec_mode = 1;
5493       return 0;
5494     }
5495   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5496     {
5497       vam->exec_mode = 0;
5498       return 0;
5499     }
5500
5501   /*
5502    * In order for the CLI command to work, it
5503    * must be a vector ending in \n, not a C-string ending
5504    * in \n\0.
5505    */
5506   u32 len = vec_len (vam->input->buffer);
5507   M2 (CLI_INBAND, mp, len);
5508   clib_memcpy (mp->cmd, vam->input->buffer, len);
5509   mp->length = htonl (len);
5510
5511   S (mp);
5512   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5513   return ret;
5514 }
5515
5516 static int
5517 api_create_loopback (vat_main_t * vam)
5518 {
5519   unformat_input_t *i = vam->input;
5520   vl_api_create_loopback_t *mp;
5521   vl_api_create_loopback_instance_t *mp_lbi;
5522   u8 mac_address[6];
5523   u8 mac_set = 0;
5524   u8 is_specified = 0;
5525   u32 user_instance = 0;
5526   int ret;
5527
5528   memset (mac_address, 0, sizeof (mac_address));
5529
5530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5531     {
5532       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5533         mac_set = 1;
5534       if (unformat (i, "instance %d", &user_instance))
5535         is_specified = 1;
5536       else
5537         break;
5538     }
5539
5540   if (is_specified)
5541     {
5542       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5543       mp_lbi->is_specified = is_specified;
5544       if (is_specified)
5545         mp_lbi->user_instance = htonl (user_instance);
5546       if (mac_set)
5547         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5548       S (mp_lbi);
5549     }
5550   else
5551     {
5552       /* Construct the API message */
5553       M (CREATE_LOOPBACK, mp);
5554       if (mac_set)
5555         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5556       S (mp);
5557     }
5558
5559   W (ret);
5560   return ret;
5561 }
5562
5563 static int
5564 api_delete_loopback (vat_main_t * vam)
5565 {
5566   unformat_input_t *i = vam->input;
5567   vl_api_delete_loopback_t *mp;
5568   u32 sw_if_index = ~0;
5569   int ret;
5570
5571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5572     {
5573       if (unformat (i, "sw_if_index %d", &sw_if_index))
5574         ;
5575       else
5576         break;
5577     }
5578
5579   if (sw_if_index == ~0)
5580     {
5581       errmsg ("missing sw_if_index");
5582       return -99;
5583     }
5584
5585   /* Construct the API message */
5586   M (DELETE_LOOPBACK, mp);
5587   mp->sw_if_index = ntohl (sw_if_index);
5588
5589   S (mp);
5590   W (ret);
5591   return ret;
5592 }
5593
5594 static int
5595 api_want_stats (vat_main_t * vam)
5596 {
5597   unformat_input_t *i = vam->input;
5598   vl_api_want_stats_t *mp;
5599   int enable = -1;
5600   int ret;
5601
5602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5603     {
5604       if (unformat (i, "enable"))
5605         enable = 1;
5606       else if (unformat (i, "disable"))
5607         enable = 0;
5608       else
5609         break;
5610     }
5611
5612   if (enable == -1)
5613     {
5614       errmsg ("missing enable|disable");
5615       return -99;
5616     }
5617
5618   M (WANT_STATS, mp);
5619   mp->enable_disable = enable;
5620
5621   S (mp);
5622   W (ret);
5623   return ret;
5624 }
5625
5626 static int
5627 api_want_interface_events (vat_main_t * vam)
5628 {
5629   unformat_input_t *i = vam->input;
5630   vl_api_want_interface_events_t *mp;
5631   int enable = -1;
5632   int ret;
5633
5634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5635     {
5636       if (unformat (i, "enable"))
5637         enable = 1;
5638       else if (unformat (i, "disable"))
5639         enable = 0;
5640       else
5641         break;
5642     }
5643
5644   if (enable == -1)
5645     {
5646       errmsg ("missing enable|disable");
5647       return -99;
5648     }
5649
5650   M (WANT_INTERFACE_EVENTS, mp);
5651   mp->enable_disable = enable;
5652
5653   vam->interface_event_display = enable;
5654
5655   S (mp);
5656   W (ret);
5657   return ret;
5658 }
5659
5660
5661 /* Note: non-static, called once to set up the initial intfc table */
5662 int
5663 api_sw_interface_dump (vat_main_t * vam)
5664 {
5665   vl_api_sw_interface_dump_t *mp;
5666   vl_api_control_ping_t *mp_ping;
5667   hash_pair_t *p;
5668   name_sort_t *nses = 0, *ns;
5669   sw_interface_subif_t *sub = NULL;
5670   int ret;
5671
5672   /* Toss the old name table */
5673   /* *INDENT-OFF* */
5674   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5675   ({
5676     vec_add2 (nses, ns, 1);
5677     ns->name = (u8 *)(p->key);
5678     ns->value = (u32) p->value[0];
5679   }));
5680   /* *INDENT-ON* */
5681
5682   hash_free (vam->sw_if_index_by_interface_name);
5683
5684   vec_foreach (ns, nses) vec_free (ns->name);
5685
5686   vec_free (nses);
5687
5688   vec_foreach (sub, vam->sw_if_subif_table)
5689   {
5690     vec_free (sub->interface_name);
5691   }
5692   vec_free (vam->sw_if_subif_table);
5693
5694   /* recreate the interface name hash table */
5695   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5696
5697   /* Get list of ethernets */
5698   M (SW_INTERFACE_DUMP, mp);
5699   mp->name_filter_valid = 1;
5700   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5701   S (mp);
5702
5703   /* and local / loopback interfaces */
5704   M (SW_INTERFACE_DUMP, mp);
5705   mp->name_filter_valid = 1;
5706   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5707   S (mp);
5708
5709   /* and packet-generator interfaces */
5710   M (SW_INTERFACE_DUMP, mp);
5711   mp->name_filter_valid = 1;
5712   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5713   S (mp);
5714
5715   /* and vxlan-gpe tunnel interfaces */
5716   M (SW_INTERFACE_DUMP, mp);
5717   mp->name_filter_valid = 1;
5718   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5719            sizeof (mp->name_filter) - 1);
5720   S (mp);
5721
5722   /* and vxlan tunnel interfaces */
5723   M (SW_INTERFACE_DUMP, mp);
5724   mp->name_filter_valid = 1;
5725   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5726   S (mp);
5727
5728   /* and host (af_packet) interfaces */
5729   M (SW_INTERFACE_DUMP, mp);
5730   mp->name_filter_valid = 1;
5731   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5732   S (mp);
5733
5734   /* and l2tpv3 tunnel interfaces */
5735   M (SW_INTERFACE_DUMP, mp);
5736   mp->name_filter_valid = 1;
5737   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5738            sizeof (mp->name_filter) - 1);
5739   S (mp);
5740
5741   /* and GRE tunnel interfaces */
5742   M (SW_INTERFACE_DUMP, mp);
5743   mp->name_filter_valid = 1;
5744   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5745   S (mp);
5746
5747   /* and LISP-GPE interfaces */
5748   M (SW_INTERFACE_DUMP, mp);
5749   mp->name_filter_valid = 1;
5750   strncpy ((char *) mp->name_filter, "lisp_gpe",
5751            sizeof (mp->name_filter) - 1);
5752   S (mp);
5753
5754   /* and IPSEC tunnel interfaces */
5755   M (SW_INTERFACE_DUMP, mp);
5756   mp->name_filter_valid = 1;
5757   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5758   S (mp);
5759
5760   /* Use a control ping for synchronization */
5761   M (CONTROL_PING, mp_ping);
5762   S (mp_ping);
5763
5764   W (ret);
5765   return ret;
5766 }
5767
5768 static int
5769 api_sw_interface_set_flags (vat_main_t * vam)
5770 {
5771   unformat_input_t *i = vam->input;
5772   vl_api_sw_interface_set_flags_t *mp;
5773   u32 sw_if_index;
5774   u8 sw_if_index_set = 0;
5775   u8 admin_up = 0, link_up = 0;
5776   int ret;
5777
5778   /* Parse args required to build the message */
5779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780     {
5781       if (unformat (i, "admin-up"))
5782         admin_up = 1;
5783       else if (unformat (i, "admin-down"))
5784         admin_up = 0;
5785       else if (unformat (i, "link-up"))
5786         link_up = 1;
5787       else if (unformat (i, "link-down"))
5788         link_up = 0;
5789       else
5790         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5791         sw_if_index_set = 1;
5792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5793         sw_if_index_set = 1;
5794       else
5795         break;
5796     }
5797
5798   if (sw_if_index_set == 0)
5799     {
5800       errmsg ("missing interface name or sw_if_index");
5801       return -99;
5802     }
5803
5804   /* Construct the API message */
5805   M (SW_INTERFACE_SET_FLAGS, mp);
5806   mp->sw_if_index = ntohl (sw_if_index);
5807   mp->admin_up_down = admin_up;
5808   mp->link_up_down = link_up;
5809
5810   /* send it... */
5811   S (mp);
5812
5813   /* Wait for a reply, return the good/bad news... */
5814   W (ret);
5815   return ret;
5816 }
5817
5818 static int
5819 api_sw_interface_clear_stats (vat_main_t * vam)
5820 {
5821   unformat_input_t *i = vam->input;
5822   vl_api_sw_interface_clear_stats_t *mp;
5823   u32 sw_if_index;
5824   u8 sw_if_index_set = 0;
5825   int ret;
5826
5827   /* Parse args required to build the message */
5828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5829     {
5830       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5831         sw_if_index_set = 1;
5832       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5833         sw_if_index_set = 1;
5834       else
5835         break;
5836     }
5837
5838   /* Construct the API message */
5839   M (SW_INTERFACE_CLEAR_STATS, mp);
5840
5841   if (sw_if_index_set == 1)
5842     mp->sw_if_index = ntohl (sw_if_index);
5843   else
5844     mp->sw_if_index = ~0;
5845
5846   /* send it... */
5847   S (mp);
5848
5849   /* Wait for a reply, return the good/bad news... */
5850   W (ret);
5851   return ret;
5852 }
5853
5854 static int
5855 api_sw_interface_add_del_address (vat_main_t * vam)
5856 {
5857   unformat_input_t *i = vam->input;
5858   vl_api_sw_interface_add_del_address_t *mp;
5859   u32 sw_if_index;
5860   u8 sw_if_index_set = 0;
5861   u8 is_add = 1, del_all = 0;
5862   u32 address_length = 0;
5863   u8 v4_address_set = 0;
5864   u8 v6_address_set = 0;
5865   ip4_address_t v4address;
5866   ip6_address_t v6address;
5867   int ret;
5868
5869   /* Parse args required to build the message */
5870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5871     {
5872       if (unformat (i, "del-all"))
5873         del_all = 1;
5874       else if (unformat (i, "del"))
5875         is_add = 0;
5876       else
5877         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5878         sw_if_index_set = 1;
5879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5880         sw_if_index_set = 1;
5881       else if (unformat (i, "%U/%d",
5882                          unformat_ip4_address, &v4address, &address_length))
5883         v4_address_set = 1;
5884       else if (unformat (i, "%U/%d",
5885                          unformat_ip6_address, &v6address, &address_length))
5886         v6_address_set = 1;
5887       else
5888         break;
5889     }
5890
5891   if (sw_if_index_set == 0)
5892     {
5893       errmsg ("missing interface name or sw_if_index");
5894       return -99;
5895     }
5896   if (v4_address_set && v6_address_set)
5897     {
5898       errmsg ("both v4 and v6 addresses set");
5899       return -99;
5900     }
5901   if (!v4_address_set && !v6_address_set && !del_all)
5902     {
5903       errmsg ("no addresses set");
5904       return -99;
5905     }
5906
5907   /* Construct the API message */
5908   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5909
5910   mp->sw_if_index = ntohl (sw_if_index);
5911   mp->is_add = is_add;
5912   mp->del_all = del_all;
5913   if (v6_address_set)
5914     {
5915       mp->is_ipv6 = 1;
5916       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5917     }
5918   else
5919     {
5920       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5921     }
5922   mp->address_length = address_length;
5923
5924   /* send it... */
5925   S (mp);
5926
5927   /* Wait for a reply, return good/bad news  */
5928   W (ret);
5929   return ret;
5930 }
5931
5932 static int
5933 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5934 {
5935   unformat_input_t *i = vam->input;
5936   vl_api_sw_interface_set_mpls_enable_t *mp;
5937   u32 sw_if_index;
5938   u8 sw_if_index_set = 0;
5939   u8 enable = 1;
5940   int ret;
5941
5942   /* Parse args required to build the message */
5943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5944     {
5945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5946         sw_if_index_set = 1;
5947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5948         sw_if_index_set = 1;
5949       else if (unformat (i, "disable"))
5950         enable = 0;
5951       else if (unformat (i, "dis"))
5952         enable = 0;
5953       else
5954         break;
5955     }
5956
5957   if (sw_if_index_set == 0)
5958     {
5959       errmsg ("missing interface name or sw_if_index");
5960       return -99;
5961     }
5962
5963   /* Construct the API message */
5964   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5965
5966   mp->sw_if_index = ntohl (sw_if_index);
5967   mp->enable = enable;
5968
5969   /* send it... */
5970   S (mp);
5971
5972   /* Wait for a reply... */
5973   W (ret);
5974   return ret;
5975 }
5976
5977 static int
5978 api_sw_interface_set_table (vat_main_t * vam)
5979 {
5980   unformat_input_t *i = vam->input;
5981   vl_api_sw_interface_set_table_t *mp;
5982   u32 sw_if_index, vrf_id = 0;
5983   u8 sw_if_index_set = 0;
5984   u8 is_ipv6 = 0;
5985   int ret;
5986
5987   /* Parse args required to build the message */
5988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5989     {
5990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5991         sw_if_index_set = 1;
5992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5993         sw_if_index_set = 1;
5994       else if (unformat (i, "vrf %d", &vrf_id))
5995         ;
5996       else if (unformat (i, "ipv6"))
5997         is_ipv6 = 1;
5998       else
5999         break;
6000     }
6001
6002   if (sw_if_index_set == 0)
6003     {
6004       errmsg ("missing interface name or sw_if_index");
6005       return -99;
6006     }
6007
6008   /* Construct the API message */
6009   M (SW_INTERFACE_SET_TABLE, mp);
6010
6011   mp->sw_if_index = ntohl (sw_if_index);
6012   mp->is_ipv6 = is_ipv6;
6013   mp->vrf_id = ntohl (vrf_id);
6014
6015   /* send it... */
6016   S (mp);
6017
6018   /* Wait for a reply... */
6019   W (ret);
6020   return ret;
6021 }
6022
6023 static void vl_api_sw_interface_get_table_reply_t_handler
6024   (vl_api_sw_interface_get_table_reply_t * mp)
6025 {
6026   vat_main_t *vam = &vat_main;
6027
6028   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6029
6030   vam->retval = ntohl (mp->retval);
6031   vam->result_ready = 1;
6032
6033 }
6034
6035 static void vl_api_sw_interface_get_table_reply_t_handler_json
6036   (vl_api_sw_interface_get_table_reply_t * mp)
6037 {
6038   vat_main_t *vam = &vat_main;
6039   vat_json_node_t node;
6040
6041   vat_json_init_object (&node);
6042   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6043   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6044
6045   vat_json_print (vam->ofp, &node);
6046   vat_json_free (&node);
6047
6048   vam->retval = ntohl (mp->retval);
6049   vam->result_ready = 1;
6050 }
6051
6052 static int
6053 api_sw_interface_get_table (vat_main_t * vam)
6054 {
6055   unformat_input_t *i = vam->input;
6056   vl_api_sw_interface_get_table_t *mp;
6057   u32 sw_if_index;
6058   u8 sw_if_index_set = 0;
6059   u8 is_ipv6 = 0;
6060   int ret;
6061
6062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6063     {
6064       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6065         sw_if_index_set = 1;
6066       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6067         sw_if_index_set = 1;
6068       else if (unformat (i, "ipv6"))
6069         is_ipv6 = 1;
6070       else
6071         break;
6072     }
6073
6074   if (sw_if_index_set == 0)
6075     {
6076       errmsg ("missing interface name or sw_if_index");
6077       return -99;
6078     }
6079
6080   M (SW_INTERFACE_GET_TABLE, mp);
6081   mp->sw_if_index = htonl (sw_if_index);
6082   mp->is_ipv6 = is_ipv6;
6083
6084   S (mp);
6085   W (ret);
6086   return ret;
6087 }
6088
6089 static int
6090 api_sw_interface_set_vpath (vat_main_t * vam)
6091 {
6092   unformat_input_t *i = vam->input;
6093   vl_api_sw_interface_set_vpath_t *mp;
6094   u32 sw_if_index = 0;
6095   u8 sw_if_index_set = 0;
6096   u8 is_enable = 0;
6097   int ret;
6098
6099   /* Parse args required to build the message */
6100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6101     {
6102       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6103         sw_if_index_set = 1;
6104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6105         sw_if_index_set = 1;
6106       else if (unformat (i, "enable"))
6107         is_enable = 1;
6108       else if (unformat (i, "disable"))
6109         is_enable = 0;
6110       else
6111         break;
6112     }
6113
6114   if (sw_if_index_set == 0)
6115     {
6116       errmsg ("missing interface name or sw_if_index");
6117       return -99;
6118     }
6119
6120   /* Construct the API message */
6121   M (SW_INTERFACE_SET_VPATH, mp);
6122
6123   mp->sw_if_index = ntohl (sw_if_index);
6124   mp->enable = is_enable;
6125
6126   /* send it... */
6127   S (mp);
6128
6129   /* Wait for a reply... */
6130   W (ret);
6131   return ret;
6132 }
6133
6134 static int
6135 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6136 {
6137   unformat_input_t *i = vam->input;
6138   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6139   u32 sw_if_index = 0;
6140   u8 sw_if_index_set = 0;
6141   u8 is_enable = 1;
6142   u8 is_ipv6 = 0;
6143   int ret;
6144
6145   /* Parse args required to build the message */
6146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6147     {
6148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6149         sw_if_index_set = 1;
6150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6151         sw_if_index_set = 1;
6152       else if (unformat (i, "enable"))
6153         is_enable = 1;
6154       else if (unformat (i, "disable"))
6155         is_enable = 0;
6156       else if (unformat (i, "ip4"))
6157         is_ipv6 = 0;
6158       else if (unformat (i, "ip6"))
6159         is_ipv6 = 1;
6160       else
6161         break;
6162     }
6163
6164   if (sw_if_index_set == 0)
6165     {
6166       errmsg ("missing interface name or sw_if_index");
6167       return -99;
6168     }
6169
6170   /* Construct the API message */
6171   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6172
6173   mp->sw_if_index = ntohl (sw_if_index);
6174   mp->enable = is_enable;
6175   mp->is_ipv6 = is_ipv6;
6176
6177   /* send it... */
6178   S (mp);
6179
6180   /* Wait for a reply... */
6181   W (ret);
6182   return ret;
6183 }
6184
6185
6186 static int
6187 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6188 {
6189   unformat_input_t *i = vam->input;
6190   vl_api_sw_interface_set_l2_xconnect_t *mp;
6191   u32 rx_sw_if_index;
6192   u8 rx_sw_if_index_set = 0;
6193   u32 tx_sw_if_index;
6194   u8 tx_sw_if_index_set = 0;
6195   u8 enable = 1;
6196   int ret;
6197
6198   /* Parse args required to build the message */
6199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6200     {
6201       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6202         rx_sw_if_index_set = 1;
6203       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6204         tx_sw_if_index_set = 1;
6205       else if (unformat (i, "rx"))
6206         {
6207           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6208             {
6209               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6210                             &rx_sw_if_index))
6211                 rx_sw_if_index_set = 1;
6212             }
6213           else
6214             break;
6215         }
6216       else if (unformat (i, "tx"))
6217         {
6218           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6219             {
6220               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6221                             &tx_sw_if_index))
6222                 tx_sw_if_index_set = 1;
6223             }
6224           else
6225             break;
6226         }
6227       else if (unformat (i, "enable"))
6228         enable = 1;
6229       else if (unformat (i, "disable"))
6230         enable = 0;
6231       else
6232         break;
6233     }
6234
6235   if (rx_sw_if_index_set == 0)
6236     {
6237       errmsg ("missing rx interface name or rx_sw_if_index");
6238       return -99;
6239     }
6240
6241   if (enable && (tx_sw_if_index_set == 0))
6242     {
6243       errmsg ("missing tx interface name or tx_sw_if_index");
6244       return -99;
6245     }
6246
6247   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6248
6249   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6250   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6251   mp->enable = enable;
6252
6253   S (mp);
6254   W (ret);
6255   return ret;
6256 }
6257
6258 static int
6259 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6260 {
6261   unformat_input_t *i = vam->input;
6262   vl_api_sw_interface_set_l2_bridge_t *mp;
6263   u32 rx_sw_if_index;
6264   u8 rx_sw_if_index_set = 0;
6265   u32 bd_id;
6266   u8 bd_id_set = 0;
6267   u8 bvi = 0;
6268   u32 shg = 0;
6269   u8 enable = 1;
6270   int ret;
6271
6272   /* Parse args required to build the message */
6273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6274     {
6275       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6276         rx_sw_if_index_set = 1;
6277       else if (unformat (i, "bd_id %d", &bd_id))
6278         bd_id_set = 1;
6279       else
6280         if (unformat
6281             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6282         rx_sw_if_index_set = 1;
6283       else if (unformat (i, "shg %d", &shg))
6284         ;
6285       else if (unformat (i, "bvi"))
6286         bvi = 1;
6287       else if (unformat (i, "enable"))
6288         enable = 1;
6289       else if (unformat (i, "disable"))
6290         enable = 0;
6291       else
6292         break;
6293     }
6294
6295   if (rx_sw_if_index_set == 0)
6296     {
6297       errmsg ("missing rx interface name or sw_if_index");
6298       return -99;
6299     }
6300
6301   if (enable && (bd_id_set == 0))
6302     {
6303       errmsg ("missing bridge domain");
6304       return -99;
6305     }
6306
6307   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6308
6309   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6310   mp->bd_id = ntohl (bd_id);
6311   mp->shg = (u8) shg;
6312   mp->bvi = bvi;
6313   mp->enable = enable;
6314
6315   S (mp);
6316   W (ret);
6317   return ret;
6318 }
6319
6320 static int
6321 api_bridge_domain_dump (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_bridge_domain_dump_t *mp;
6325   vl_api_control_ping_t *mp_ping;
6326   u32 bd_id = ~0;
6327   int ret;
6328
6329   /* Parse args required to build the message */
6330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6331     {
6332       if (unformat (i, "bd_id %d", &bd_id))
6333         ;
6334       else
6335         break;
6336     }
6337
6338   M (BRIDGE_DOMAIN_DUMP, mp);
6339   mp->bd_id = ntohl (bd_id);
6340   S (mp);
6341
6342   /* Use a control ping for synchronization */
6343   M (CONTROL_PING, mp_ping);
6344   S (mp_ping);
6345
6346   W (ret);
6347   return ret;
6348 }
6349
6350 static int
6351 api_bridge_domain_add_del (vat_main_t * vam)
6352 {
6353   unformat_input_t *i = vam->input;
6354   vl_api_bridge_domain_add_del_t *mp;
6355   u32 bd_id = ~0;
6356   u8 is_add = 1;
6357   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6358   u32 mac_age = 0;
6359   int ret;
6360
6361   /* Parse args required to build the message */
6362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6363     {
6364       if (unformat (i, "bd_id %d", &bd_id))
6365         ;
6366       else if (unformat (i, "flood %d", &flood))
6367         ;
6368       else if (unformat (i, "uu-flood %d", &uu_flood))
6369         ;
6370       else if (unformat (i, "forward %d", &forward))
6371         ;
6372       else if (unformat (i, "learn %d", &learn))
6373         ;
6374       else if (unformat (i, "arp-term %d", &arp_term))
6375         ;
6376       else if (unformat (i, "mac-age %d", &mac_age))
6377         ;
6378       else if (unformat (i, "del"))
6379         {
6380           is_add = 0;
6381           flood = uu_flood = forward = learn = 0;
6382         }
6383       else
6384         break;
6385     }
6386
6387   if (bd_id == ~0)
6388     {
6389       errmsg ("missing bridge domain");
6390       return -99;
6391     }
6392
6393   if (mac_age > 255)
6394     {
6395       errmsg ("mac age must be less than 256 ");
6396       return -99;
6397     }
6398
6399   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6400
6401   mp->bd_id = ntohl (bd_id);
6402   mp->flood = flood;
6403   mp->uu_flood = uu_flood;
6404   mp->forward = forward;
6405   mp->learn = learn;
6406   mp->arp_term = arp_term;
6407   mp->is_add = is_add;
6408   mp->mac_age = (u8) mac_age;
6409
6410   S (mp);
6411   W (ret);
6412   return ret;
6413 }
6414
6415 static int
6416 api_l2fib_flush_bd (vat_main_t * vam)
6417 {
6418   unformat_input_t *i = vam->input;
6419   vl_api_l2fib_flush_bd_t *mp;
6420   u32 bd_id = ~0;
6421   int ret;
6422
6423   /* Parse args required to build the message */
6424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6425     {
6426       if (unformat (i, "bd_id %d", &bd_id));
6427       else
6428         break;
6429     }
6430
6431   if (bd_id == ~0)
6432     {
6433       errmsg ("missing bridge domain");
6434       return -99;
6435     }
6436
6437   M (L2FIB_FLUSH_BD, mp);
6438
6439   mp->bd_id = htonl (bd_id);
6440
6441   S (mp);
6442   W (ret);
6443   return ret;
6444 }
6445
6446 static int
6447 api_l2fib_flush_int (vat_main_t * vam)
6448 {
6449   unformat_input_t *i = vam->input;
6450   vl_api_l2fib_flush_int_t *mp;
6451   u32 sw_if_index = ~0;
6452   int ret;
6453
6454   /* Parse args required to build the message */
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "sw_if_index %d", &sw_if_index));
6458       else
6459         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6460       else
6461         break;
6462     }
6463
6464   if (sw_if_index == ~0)
6465     {
6466       errmsg ("missing interface name or sw_if_index");
6467       return -99;
6468     }
6469
6470   M (L2FIB_FLUSH_INT, mp);
6471
6472   mp->sw_if_index = ntohl (sw_if_index);
6473
6474   S (mp);
6475   W (ret);
6476   return ret;
6477 }
6478
6479 static int
6480 api_l2fib_add_del (vat_main_t * vam)
6481 {
6482   unformat_input_t *i = vam->input;
6483   vl_api_l2fib_add_del_t *mp;
6484   f64 timeout;
6485   u64 mac = 0;
6486   u8 mac_set = 0;
6487   u32 bd_id;
6488   u8 bd_id_set = 0;
6489   u32 sw_if_index = ~0;
6490   u8 sw_if_index_set = 0;
6491   u8 is_add = 1;
6492   u8 static_mac = 0;
6493   u8 filter_mac = 0;
6494   u8 bvi_mac = 0;
6495   int count = 1;
6496   f64 before = 0;
6497   int j;
6498
6499   /* Parse args required to build the message */
6500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6501     {
6502       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6503         mac_set = 1;
6504       else if (unformat (i, "bd_id %d", &bd_id))
6505         bd_id_set = 1;
6506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6507         sw_if_index_set = 1;
6508       else if (unformat (i, "sw_if"))
6509         {
6510           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6511             {
6512               if (unformat
6513                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6514                 sw_if_index_set = 1;
6515             }
6516           else
6517             break;
6518         }
6519       else if (unformat (i, "static"))
6520         static_mac = 1;
6521       else if (unformat (i, "filter"))
6522         {
6523           filter_mac = 1;
6524           static_mac = 1;
6525         }
6526       else if (unformat (i, "bvi"))
6527         {
6528           bvi_mac = 1;
6529           static_mac = 1;
6530         }
6531       else if (unformat (i, "del"))
6532         is_add = 0;
6533       else if (unformat (i, "count %d", &count))
6534         ;
6535       else
6536         break;
6537     }
6538
6539   if (mac_set == 0)
6540     {
6541       errmsg ("missing mac address");
6542       return -99;
6543     }
6544
6545   if (bd_id_set == 0)
6546     {
6547       errmsg ("missing bridge domain");
6548       return -99;
6549     }
6550
6551   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6552     {
6553       errmsg ("missing interface name or sw_if_index");
6554       return -99;
6555     }
6556
6557   if (count > 1)
6558     {
6559       /* Turn on async mode */
6560       vam->async_mode = 1;
6561       vam->async_errors = 0;
6562       before = vat_time_now (vam);
6563     }
6564
6565   for (j = 0; j < count; j++)
6566     {
6567       M (L2FIB_ADD_DEL, mp);
6568
6569       mp->mac = mac;
6570       mp->bd_id = ntohl (bd_id);
6571       mp->is_add = is_add;
6572
6573       if (is_add)
6574         {
6575           mp->sw_if_index = ntohl (sw_if_index);
6576           mp->static_mac = static_mac;
6577           mp->filter_mac = filter_mac;
6578           mp->bvi_mac = bvi_mac;
6579         }
6580       increment_mac_address (&mac);
6581       /* send it... */
6582       S (mp);
6583     }
6584
6585   if (count > 1)
6586     {
6587       vl_api_control_ping_t *mp_ping;
6588       f64 after;
6589
6590       /* Shut off async mode */
6591       vam->async_mode = 0;
6592
6593       M (CONTROL_PING, mp_ping);
6594       S (mp_ping);
6595
6596       timeout = vat_time_now (vam) + 1.0;
6597       while (vat_time_now (vam) < timeout)
6598         if (vam->result_ready == 1)
6599           goto out;
6600       vam->retval = -99;
6601
6602     out:
6603       if (vam->retval == -99)
6604         errmsg ("timeout");
6605
6606       if (vam->async_errors > 0)
6607         {
6608           errmsg ("%d asynchronous errors", vam->async_errors);
6609           vam->retval = -98;
6610         }
6611       vam->async_errors = 0;
6612       after = vat_time_now (vam);
6613
6614       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6615              count, after - before, count / (after - before));
6616     }
6617   else
6618     {
6619       int ret;
6620
6621       /* Wait for a reply... */
6622       W (ret);
6623       return ret;
6624     }
6625   /* Return the good/bad news */
6626   return (vam->retval);
6627 }
6628
6629 static int
6630 api_bridge_domain_set_mac_age (vat_main_t * vam)
6631 {
6632   unformat_input_t *i = vam->input;
6633   vl_api_bridge_domain_set_mac_age_t *mp;
6634   u32 bd_id = ~0;
6635   u32 mac_age = 0;
6636   int ret;
6637
6638   /* Parse args required to build the message */
6639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6640     {
6641       if (unformat (i, "bd_id %d", &bd_id));
6642       else if (unformat (i, "mac-age %d", &mac_age));
6643       else
6644         break;
6645     }
6646
6647   if (bd_id == ~0)
6648     {
6649       errmsg ("missing bridge domain");
6650       return -99;
6651     }
6652
6653   if (mac_age > 255)
6654     {
6655       errmsg ("mac age must be less than 256 ");
6656       return -99;
6657     }
6658
6659   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6660
6661   mp->bd_id = htonl (bd_id);
6662   mp->mac_age = (u8) mac_age;
6663
6664   S (mp);
6665   W (ret);
6666   return ret;
6667 }
6668
6669 static int
6670 api_l2_flags (vat_main_t * vam)
6671 {
6672   unformat_input_t *i = vam->input;
6673   vl_api_l2_flags_t *mp;
6674   u32 sw_if_index;
6675   u32 flags = 0;
6676   u8 sw_if_index_set = 0;
6677   u8 is_set = 0;
6678   int ret;
6679
6680   /* Parse args required to build the message */
6681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6682     {
6683       if (unformat (i, "sw_if_index %d", &sw_if_index))
6684         sw_if_index_set = 1;
6685       else if (unformat (i, "sw_if"))
6686         {
6687           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6688             {
6689               if (unformat
6690                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6691                 sw_if_index_set = 1;
6692             }
6693           else
6694             break;
6695         }
6696       else if (unformat (i, "learn"))
6697         flags |= L2_LEARN;
6698       else if (unformat (i, "forward"))
6699         flags |= L2_FWD;
6700       else if (unformat (i, "flood"))
6701         flags |= L2_FLOOD;
6702       else if (unformat (i, "uu-flood"))
6703         flags |= L2_UU_FLOOD;
6704       else if (unformat (i, "arp-term"))
6705         flags |= L2_ARP_TERM;
6706       else if (unformat (i, "off"))
6707         is_set = 0;
6708       else if (unformat (i, "disable"))
6709         is_set = 0;
6710       else
6711         break;
6712     }
6713
6714   if (sw_if_index_set == 0)
6715     {
6716       errmsg ("missing interface name or sw_if_index");
6717       return -99;
6718     }
6719
6720   M (L2_FLAGS, mp);
6721
6722   mp->sw_if_index = ntohl (sw_if_index);
6723   mp->feature_bitmap = ntohl (flags);
6724   mp->is_set = is_set;
6725
6726   S (mp);
6727   W (ret);
6728   return ret;
6729 }
6730
6731 static int
6732 api_bridge_flags (vat_main_t * vam)
6733 {
6734   unformat_input_t *i = vam->input;
6735   vl_api_bridge_flags_t *mp;
6736   u32 bd_id;
6737   u8 bd_id_set = 0;
6738   u8 is_set = 1;
6739   u32 flags = 0;
6740   int ret;
6741
6742   /* Parse args required to build the message */
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "bd_id %d", &bd_id))
6746         bd_id_set = 1;
6747       else if (unformat (i, "learn"))
6748         flags |= L2_LEARN;
6749       else if (unformat (i, "forward"))
6750         flags |= L2_FWD;
6751       else if (unformat (i, "flood"))
6752         flags |= L2_FLOOD;
6753       else if (unformat (i, "uu-flood"))
6754         flags |= L2_UU_FLOOD;
6755       else if (unformat (i, "arp-term"))
6756         flags |= L2_ARP_TERM;
6757       else if (unformat (i, "off"))
6758         is_set = 0;
6759       else if (unformat (i, "disable"))
6760         is_set = 0;
6761       else
6762         break;
6763     }
6764
6765   if (bd_id_set == 0)
6766     {
6767       errmsg ("missing bridge domain");
6768       return -99;
6769     }
6770
6771   M (BRIDGE_FLAGS, mp);
6772
6773   mp->bd_id = ntohl (bd_id);
6774   mp->feature_bitmap = ntohl (flags);
6775   mp->is_set = is_set;
6776
6777   S (mp);
6778   W (ret);
6779   return ret;
6780 }
6781
6782 static int
6783 api_bd_ip_mac_add_del (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_bd_ip_mac_add_del_t *mp;
6787   u32 bd_id;
6788   u8 is_ipv6 = 0;
6789   u8 is_add = 1;
6790   u8 bd_id_set = 0;
6791   u8 ip_set = 0;
6792   u8 mac_set = 0;
6793   ip4_address_t v4addr;
6794   ip6_address_t v6addr;
6795   u8 macaddr[6];
6796   int ret;
6797
6798
6799   /* Parse args required to build the message */
6800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6801     {
6802       if (unformat (i, "bd_id %d", &bd_id))
6803         {
6804           bd_id_set++;
6805         }
6806       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6807         {
6808           ip_set++;
6809         }
6810       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6811         {
6812           ip_set++;
6813           is_ipv6++;
6814         }
6815       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6816         {
6817           mac_set++;
6818         }
6819       else if (unformat (i, "del"))
6820         is_add = 0;
6821       else
6822         break;
6823     }
6824
6825   if (bd_id_set == 0)
6826     {
6827       errmsg ("missing bridge domain");
6828       return -99;
6829     }
6830   else if (ip_set == 0)
6831     {
6832       errmsg ("missing IP address");
6833       return -99;
6834     }
6835   else if (mac_set == 0)
6836     {
6837       errmsg ("missing MAC address");
6838       return -99;
6839     }
6840
6841   M (BD_IP_MAC_ADD_DEL, mp);
6842
6843   mp->bd_id = ntohl (bd_id);
6844   mp->is_ipv6 = is_ipv6;
6845   mp->is_add = is_add;
6846   if (is_ipv6)
6847     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6848   else
6849     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6850   clib_memcpy (mp->mac_address, macaddr, 6);
6851   S (mp);
6852   W (ret);
6853   return ret;
6854 }
6855
6856 static int
6857 api_tap_connect (vat_main_t * vam)
6858 {
6859   unformat_input_t *i = vam->input;
6860   vl_api_tap_connect_t *mp;
6861   u8 mac_address[6];
6862   u8 random_mac = 1;
6863   u8 name_set = 0;
6864   u8 *tap_name;
6865   u8 *tag = 0;
6866   ip4_address_t ip4_address;
6867   u32 ip4_mask_width;
6868   int ip4_address_set = 0;
6869   ip6_address_t ip6_address;
6870   u32 ip6_mask_width;
6871   int ip6_address_set = 0;
6872   int ret;
6873
6874   memset (mac_address, 0, sizeof (mac_address));
6875
6876   /* Parse args required to build the message */
6877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6878     {
6879       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6880         {
6881           random_mac = 0;
6882         }
6883       else if (unformat (i, "random-mac"))
6884         random_mac = 1;
6885       else if (unformat (i, "tapname %s", &tap_name))
6886         name_set = 1;
6887       else if (unformat (i, "tag %s", &tag))
6888         ;
6889       else if (unformat (i, "address %U/%d",
6890                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6891         ip4_address_set = 1;
6892       else if (unformat (i, "address %U/%d",
6893                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6894         ip6_address_set = 1;
6895       else
6896         break;
6897     }
6898
6899   if (name_set == 0)
6900     {
6901       errmsg ("missing tap name");
6902       return -99;
6903     }
6904   if (vec_len (tap_name) > 63)
6905     {
6906       errmsg ("tap name too long");
6907       return -99;
6908     }
6909   vec_add1 (tap_name, 0);
6910
6911   if (vec_len (tag) > 63)
6912     {
6913       errmsg ("tag too long");
6914       return -99;
6915     }
6916
6917   /* Construct the API message */
6918   M (TAP_CONNECT, mp);
6919
6920   mp->use_random_mac = random_mac;
6921   clib_memcpy (mp->mac_address, mac_address, 6);
6922   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6923   if (tag)
6924     clib_memcpy (mp->tag, tag, vec_len (tag));
6925
6926   if (ip4_address_set)
6927     {
6928       mp->ip4_address_set = 1;
6929       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6930       mp->ip4_mask_width = ip4_mask_width;
6931     }
6932   if (ip6_address_set)
6933     {
6934       mp->ip6_address_set = 1;
6935       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6936       mp->ip6_mask_width = ip6_mask_width;
6937     }
6938
6939   vec_free (tap_name);
6940   vec_free (tag);
6941
6942   /* send it... */
6943   S (mp);
6944
6945   /* Wait for a reply... */
6946   W (ret);
6947   return ret;
6948 }
6949
6950 static int
6951 api_tap_modify (vat_main_t * vam)
6952 {
6953   unformat_input_t *i = vam->input;
6954   vl_api_tap_modify_t *mp;
6955   u8 mac_address[6];
6956   u8 random_mac = 1;
6957   u8 name_set = 0;
6958   u8 *tap_name;
6959   u32 sw_if_index = ~0;
6960   u8 sw_if_index_set = 0;
6961   int ret;
6962
6963   memset (mac_address, 0, sizeof (mac_address));
6964
6965   /* Parse args required to build the message */
6966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6967     {
6968       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6969         sw_if_index_set = 1;
6970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6971         sw_if_index_set = 1;
6972       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6973         {
6974           random_mac = 0;
6975         }
6976       else if (unformat (i, "random-mac"))
6977         random_mac = 1;
6978       else if (unformat (i, "tapname %s", &tap_name))
6979         name_set = 1;
6980       else
6981         break;
6982     }
6983
6984   if (sw_if_index_set == 0)
6985     {
6986       errmsg ("missing vpp interface name");
6987       return -99;
6988     }
6989   if (name_set == 0)
6990     {
6991       errmsg ("missing tap name");
6992       return -99;
6993     }
6994   if (vec_len (tap_name) > 63)
6995     {
6996       errmsg ("tap name too long");
6997     }
6998   vec_add1 (tap_name, 0);
6999
7000   /* Construct the API message */
7001   M (TAP_MODIFY, mp);
7002
7003   mp->use_random_mac = random_mac;
7004   mp->sw_if_index = ntohl (sw_if_index);
7005   clib_memcpy (mp->mac_address, mac_address, 6);
7006   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7007   vec_free (tap_name);
7008
7009   /* send it... */
7010   S (mp);
7011
7012   /* Wait for a reply... */
7013   W (ret);
7014   return ret;
7015 }
7016
7017 static int
7018 api_tap_delete (vat_main_t * vam)
7019 {
7020   unformat_input_t *i = vam->input;
7021   vl_api_tap_delete_t *mp;
7022   u32 sw_if_index = ~0;
7023   u8 sw_if_index_set = 0;
7024   int ret;
7025
7026   /* Parse args required to build the message */
7027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7028     {
7029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7030         sw_if_index_set = 1;
7031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7032         sw_if_index_set = 1;
7033       else
7034         break;
7035     }
7036
7037   if (sw_if_index_set == 0)
7038     {
7039       errmsg ("missing vpp interface name");
7040       return -99;
7041     }
7042
7043   /* Construct the API message */
7044   M (TAP_DELETE, mp);
7045
7046   mp->sw_if_index = ntohl (sw_if_index);
7047
7048   /* send it... */
7049   S (mp);
7050
7051   /* Wait for a reply... */
7052   W (ret);
7053   return ret;
7054 }
7055
7056 static int
7057 api_ip_add_del_route (vat_main_t * vam)
7058 {
7059   unformat_input_t *i = vam->input;
7060   vl_api_ip_add_del_route_t *mp;
7061   u32 sw_if_index = ~0, vrf_id = 0;
7062   u8 is_ipv6 = 0;
7063   u8 is_local = 0, is_drop = 0;
7064   u8 is_unreach = 0, is_prohibit = 0;
7065   u8 create_vrf_if_needed = 0;
7066   u8 is_add = 1;
7067   u32 next_hop_weight = 1;
7068   u8 not_last = 0;
7069   u8 is_multipath = 0;
7070   u8 address_set = 0;
7071   u8 address_length_set = 0;
7072   u32 next_hop_table_id = 0;
7073   u32 resolve_attempts = 0;
7074   u32 dst_address_length = 0;
7075   u8 next_hop_set = 0;
7076   ip4_address_t v4_dst_address, v4_next_hop_address;
7077   ip6_address_t v6_dst_address, v6_next_hop_address;
7078   int count = 1;
7079   int j;
7080   f64 before = 0;
7081   u32 random_add_del = 0;
7082   u32 *random_vector = 0;
7083   uword *random_hash;
7084   u32 random_seed = 0xdeaddabe;
7085   u32 classify_table_index = ~0;
7086   u8 is_classify = 0;
7087   u8 resolve_host = 0, resolve_attached = 0;
7088   mpls_label_t *next_hop_out_label_stack = NULL;
7089   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7090   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7091
7092   /* Parse args required to build the message */
7093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7094     {
7095       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7096         ;
7097       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7098         ;
7099       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7100         {
7101           address_set = 1;
7102           is_ipv6 = 0;
7103         }
7104       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7105         {
7106           address_set = 1;
7107           is_ipv6 = 1;
7108         }
7109       else if (unformat (i, "/%d", &dst_address_length))
7110         {
7111           address_length_set = 1;
7112         }
7113
7114       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7115                                          &v4_next_hop_address))
7116         {
7117           next_hop_set = 1;
7118         }
7119       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7120                                          &v6_next_hop_address))
7121         {
7122           next_hop_set = 1;
7123         }
7124       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7125         ;
7126       else if (unformat (i, "weight %d", &next_hop_weight))
7127         ;
7128       else if (unformat (i, "drop"))
7129         {
7130           is_drop = 1;
7131         }
7132       else if (unformat (i, "null-send-unreach"))
7133         {
7134           is_unreach = 1;
7135         }
7136       else if (unformat (i, "null-send-prohibit"))
7137         {
7138           is_prohibit = 1;
7139         }
7140       else if (unformat (i, "local"))
7141         {
7142           is_local = 1;
7143         }
7144       else if (unformat (i, "classify %d", &classify_table_index))
7145         {
7146           is_classify = 1;
7147         }
7148       else if (unformat (i, "del"))
7149         is_add = 0;
7150       else if (unformat (i, "add"))
7151         is_add = 1;
7152       else if (unformat (i, "not-last"))
7153         not_last = 1;
7154       else if (unformat (i, "resolve-via-host"))
7155         resolve_host = 1;
7156       else if (unformat (i, "resolve-via-attached"))
7157         resolve_attached = 1;
7158       else if (unformat (i, "multipath"))
7159         is_multipath = 1;
7160       else if (unformat (i, "vrf %d", &vrf_id))
7161         ;
7162       else if (unformat (i, "create-vrf"))
7163         create_vrf_if_needed = 1;
7164       else if (unformat (i, "count %d", &count))
7165         ;
7166       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7167         ;
7168       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7169         ;
7170       else if (unformat (i, "out-label %d", &next_hop_out_label))
7171         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7172       else if (unformat (i, "via-label %d", &next_hop_via_label))
7173         ;
7174       else if (unformat (i, "random"))
7175         random_add_del = 1;
7176       else if (unformat (i, "seed %d", &random_seed))
7177         ;
7178       else
7179         {
7180           clib_warning ("parse error '%U'", format_unformat_error, i);
7181           return -99;
7182         }
7183     }
7184
7185   if (!next_hop_set && !is_drop && !is_local &&
7186       !is_classify && !is_unreach && !is_prohibit &&
7187       MPLS_LABEL_INVALID == next_hop_via_label)
7188     {
7189       errmsg
7190         ("next hop / local / drop / unreach / prohibit / classify not set");
7191       return -99;
7192     }
7193
7194   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7195     {
7196       errmsg ("next hop and next-hop via label set");
7197       return -99;
7198     }
7199   if (address_set == 0)
7200     {
7201       errmsg ("missing addresses");
7202       return -99;
7203     }
7204
7205   if (address_length_set == 0)
7206     {
7207       errmsg ("missing address length");
7208       return -99;
7209     }
7210
7211   /* Generate a pile of unique, random routes */
7212   if (random_add_del)
7213     {
7214       u32 this_random_address;
7215       random_hash = hash_create (count, sizeof (uword));
7216
7217       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7218       for (j = 0; j <= count; j++)
7219         {
7220           do
7221             {
7222               this_random_address = random_u32 (&random_seed);
7223               this_random_address =
7224                 clib_host_to_net_u32 (this_random_address);
7225             }
7226           while (hash_get (random_hash, this_random_address));
7227           vec_add1 (random_vector, this_random_address);
7228           hash_set (random_hash, this_random_address, 1);
7229         }
7230       hash_free (random_hash);
7231       v4_dst_address.as_u32 = random_vector[0];
7232     }
7233
7234   if (count > 1)
7235     {
7236       /* Turn on async mode */
7237       vam->async_mode = 1;
7238       vam->async_errors = 0;
7239       before = vat_time_now (vam);
7240     }
7241
7242   for (j = 0; j < count; j++)
7243     {
7244       /* Construct the API message */
7245       M2 (IP_ADD_DEL_ROUTE, mp,
7246           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7247
7248       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7249       mp->table_id = ntohl (vrf_id);
7250       mp->create_vrf_if_needed = create_vrf_if_needed;
7251
7252       mp->is_add = is_add;
7253       mp->is_drop = is_drop;
7254       mp->is_unreach = is_unreach;
7255       mp->is_prohibit = is_prohibit;
7256       mp->is_ipv6 = is_ipv6;
7257       mp->is_local = is_local;
7258       mp->is_classify = is_classify;
7259       mp->is_multipath = is_multipath;
7260       mp->is_resolve_host = resolve_host;
7261       mp->is_resolve_attached = resolve_attached;
7262       mp->not_last = not_last;
7263       mp->next_hop_weight = next_hop_weight;
7264       mp->dst_address_length = dst_address_length;
7265       mp->next_hop_table_id = ntohl (next_hop_table_id);
7266       mp->classify_table_index = ntohl (classify_table_index);
7267       mp->next_hop_via_label = ntohl (next_hop_via_label);
7268       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7269       if (0 != mp->next_hop_n_out_labels)
7270         {
7271           memcpy (mp->next_hop_out_label_stack,
7272                   next_hop_out_label_stack,
7273                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7274           vec_free (next_hop_out_label_stack);
7275         }
7276
7277       if (is_ipv6)
7278         {
7279           clib_memcpy (mp->dst_address, &v6_dst_address,
7280                        sizeof (v6_dst_address));
7281           if (next_hop_set)
7282             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7283                          sizeof (v6_next_hop_address));
7284           increment_v6_address (&v6_dst_address);
7285         }
7286       else
7287         {
7288           clib_memcpy (mp->dst_address, &v4_dst_address,
7289                        sizeof (v4_dst_address));
7290           if (next_hop_set)
7291             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7292                          sizeof (v4_next_hop_address));
7293           if (random_add_del)
7294             v4_dst_address.as_u32 = random_vector[j + 1];
7295           else
7296             increment_v4_address (&v4_dst_address);
7297         }
7298       /* send it... */
7299       S (mp);
7300       /* If we receive SIGTERM, stop now... */
7301       if (vam->do_exit)
7302         break;
7303     }
7304
7305   /* When testing multiple add/del ops, use a control-ping to sync */
7306   if (count > 1)
7307     {
7308       vl_api_control_ping_t *mp_ping;
7309       f64 after;
7310       f64 timeout;
7311
7312       /* Shut off async mode */
7313       vam->async_mode = 0;
7314
7315       M (CONTROL_PING, mp_ping);
7316       S (mp_ping);
7317
7318       timeout = vat_time_now (vam) + 1.0;
7319       while (vat_time_now (vam) < timeout)
7320         if (vam->result_ready == 1)
7321           goto out;
7322       vam->retval = -99;
7323
7324     out:
7325       if (vam->retval == -99)
7326         errmsg ("timeout");
7327
7328       if (vam->async_errors > 0)
7329         {
7330           errmsg ("%d asynchronous errors", vam->async_errors);
7331           vam->retval = -98;
7332         }
7333       vam->async_errors = 0;
7334       after = vat_time_now (vam);
7335
7336       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7337       if (j > 0)
7338         count = j;
7339
7340       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7341              count, after - before, count / (after - before));
7342     }
7343   else
7344     {
7345       int ret;
7346
7347       /* Wait for a reply... */
7348       W (ret);
7349       return ret;
7350     }
7351
7352   /* Return the good/bad news */
7353   return (vam->retval);
7354 }
7355
7356 static int
7357 api_ip_mroute_add_del (vat_main_t * vam)
7358 {
7359   unformat_input_t *i = vam->input;
7360   vl_api_ip_mroute_add_del_t *mp;
7361   u32 sw_if_index = ~0, vrf_id = 0;
7362   u8 is_ipv6 = 0;
7363   u8 is_local = 0;
7364   u8 create_vrf_if_needed = 0;
7365   u8 is_add = 1;
7366   u8 address_set = 0;
7367   u32 grp_address_length = 0;
7368   ip4_address_t v4_grp_address, v4_src_address;
7369   ip6_address_t v6_grp_address, v6_src_address;
7370   mfib_itf_flags_t iflags = 0;
7371   mfib_entry_flags_t eflags = 0;
7372   int ret;
7373
7374   /* Parse args required to build the message */
7375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7376     {
7377       if (unformat (i, "sw_if_index %d", &sw_if_index))
7378         ;
7379       else if (unformat (i, "%U %U",
7380                          unformat_ip4_address, &v4_src_address,
7381                          unformat_ip4_address, &v4_grp_address))
7382         {
7383           grp_address_length = 64;
7384           address_set = 1;
7385           is_ipv6 = 0;
7386         }
7387       else if (unformat (i, "%U %U",
7388                          unformat_ip6_address, &v6_src_address,
7389                          unformat_ip6_address, &v6_grp_address))
7390         {
7391           grp_address_length = 256;
7392           address_set = 1;
7393           is_ipv6 = 1;
7394         }
7395       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7396         {
7397           memset (&v4_src_address, 0, sizeof (v4_src_address));
7398           grp_address_length = 32;
7399           address_set = 1;
7400           is_ipv6 = 0;
7401         }
7402       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7403         {
7404           memset (&v6_src_address, 0, sizeof (v6_src_address));
7405           grp_address_length = 128;
7406           address_set = 1;
7407           is_ipv6 = 1;
7408         }
7409       else if (unformat (i, "/%d", &grp_address_length))
7410         ;
7411       else if (unformat (i, "local"))
7412         {
7413           is_local = 1;
7414         }
7415       else if (unformat (i, "del"))
7416         is_add = 0;
7417       else if (unformat (i, "add"))
7418         is_add = 1;
7419       else if (unformat (i, "vrf %d", &vrf_id))
7420         ;
7421       else if (unformat (i, "create-vrf"))
7422         create_vrf_if_needed = 1;
7423       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7424         ;
7425       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7426         ;
7427       else
7428         {
7429           clib_warning ("parse error '%U'", format_unformat_error, i);
7430           return -99;
7431         }
7432     }
7433
7434   if (address_set == 0)
7435     {
7436       errmsg ("missing addresses\n");
7437       return -99;
7438     }
7439
7440   /* Construct the API message */
7441   M (IP_MROUTE_ADD_DEL, mp);
7442
7443   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7444   mp->table_id = ntohl (vrf_id);
7445   mp->create_vrf_if_needed = create_vrf_if_needed;
7446
7447   mp->is_add = is_add;
7448   mp->is_ipv6 = is_ipv6;
7449   mp->is_local = is_local;
7450   mp->itf_flags = ntohl (iflags);
7451   mp->entry_flags = ntohl (eflags);
7452   mp->grp_address_length = grp_address_length;
7453   mp->grp_address_length = ntohs (mp->grp_address_length);
7454
7455   if (is_ipv6)
7456     {
7457       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7458       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7459     }
7460   else
7461     {
7462       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7463       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7464
7465     }
7466
7467   /* send it... */
7468   S (mp);
7469   /* Wait for a reply... */
7470   W (ret);
7471   return ret;
7472 }
7473
7474 static int
7475 api_mpls_route_add_del (vat_main_t * vam)
7476 {
7477   unformat_input_t *i = vam->input;
7478   vl_api_mpls_route_add_del_t *mp;
7479   u32 sw_if_index = ~0, table_id = 0;
7480   u8 create_table_if_needed = 0;
7481   u8 is_add = 1;
7482   u32 next_hop_weight = 1;
7483   u8 is_multipath = 0;
7484   u32 next_hop_table_id = 0;
7485   u8 next_hop_set = 0;
7486   ip4_address_t v4_next_hop_address = {
7487     .as_u32 = 0,
7488   };
7489   ip6_address_t v6_next_hop_address = { {0} };
7490   int count = 1;
7491   int j;
7492   f64 before = 0;
7493   u32 classify_table_index = ~0;
7494   u8 is_classify = 0;
7495   u8 resolve_host = 0, resolve_attached = 0;
7496   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7497   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7498   mpls_label_t *next_hop_out_label_stack = NULL;
7499   mpls_label_t local_label = MPLS_LABEL_INVALID;
7500   u8 is_eos = 0;
7501   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
7502
7503   /* Parse args required to build the message */
7504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7505     {
7506       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7507         ;
7508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7509         ;
7510       else if (unformat (i, "%d", &local_label))
7511         ;
7512       else if (unformat (i, "eos"))
7513         is_eos = 1;
7514       else if (unformat (i, "non-eos"))
7515         is_eos = 0;
7516       else if (unformat (i, "via %U", unformat_ip4_address,
7517                          &v4_next_hop_address))
7518         {
7519           next_hop_set = 1;
7520           next_hop_proto = DPO_PROTO_IP4;
7521         }
7522       else if (unformat (i, "via %U", unformat_ip6_address,
7523                          &v6_next_hop_address))
7524         {
7525           next_hop_set = 1;
7526           next_hop_proto = DPO_PROTO_IP6;
7527         }
7528       else if (unformat (i, "weight %d", &next_hop_weight))
7529         ;
7530       else if (unformat (i, "create-table"))
7531         create_table_if_needed = 1;
7532       else if (unformat (i, "classify %d", &classify_table_index))
7533         {
7534           is_classify = 1;
7535         }
7536       else if (unformat (i, "del"))
7537         is_add = 0;
7538       else if (unformat (i, "add"))
7539         is_add = 1;
7540       else if (unformat (i, "resolve-via-host"))
7541         resolve_host = 1;
7542       else if (unformat (i, "resolve-via-attached"))
7543         resolve_attached = 1;
7544       else if (unformat (i, "multipath"))
7545         is_multipath = 1;
7546       else if (unformat (i, "count %d", &count))
7547         ;
7548       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7549         {
7550           next_hop_set = 1;
7551           next_hop_proto = DPO_PROTO_IP4;
7552         }
7553       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7554         {
7555           next_hop_set = 1;
7556           next_hop_proto = DPO_PROTO_IP6;
7557         }
7558       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7559         ;
7560       else if (unformat (i, "via-label %d", &next_hop_via_label))
7561         ;
7562       else if (unformat (i, "out-label %d", &next_hop_out_label))
7563         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7564       else
7565         {
7566           clib_warning ("parse error '%U'", format_unformat_error, i);
7567           return -99;
7568         }
7569     }
7570
7571   if (!next_hop_set && !is_classify)
7572     {
7573       errmsg ("next hop / classify not set");
7574       return -99;
7575     }
7576
7577   if (MPLS_LABEL_INVALID == local_label)
7578     {
7579       errmsg ("missing label");
7580       return -99;
7581     }
7582
7583   if (count > 1)
7584     {
7585       /* Turn on async mode */
7586       vam->async_mode = 1;
7587       vam->async_errors = 0;
7588       before = vat_time_now (vam);
7589     }
7590
7591   for (j = 0; j < count; j++)
7592     {
7593       /* Construct the API message */
7594       M2 (MPLS_ROUTE_ADD_DEL, mp,
7595           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7596
7597       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7598       mp->mr_table_id = ntohl (table_id);
7599       mp->mr_create_table_if_needed = create_table_if_needed;
7600
7601       mp->mr_is_add = is_add;
7602       mp->mr_next_hop_proto = next_hop_proto;
7603       mp->mr_is_classify = is_classify;
7604       mp->mr_is_multipath = is_multipath;
7605       mp->mr_is_resolve_host = resolve_host;
7606       mp->mr_is_resolve_attached = resolve_attached;
7607       mp->mr_next_hop_weight = next_hop_weight;
7608       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7609       mp->mr_classify_table_index = ntohl (classify_table_index);
7610       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7611       mp->mr_label = ntohl (local_label);
7612       mp->mr_eos = is_eos;
7613
7614       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7615       if (0 != mp->mr_next_hop_n_out_labels)
7616         {
7617           memcpy (mp->mr_next_hop_out_label_stack,
7618                   next_hop_out_label_stack,
7619                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7620           vec_free (next_hop_out_label_stack);
7621         }
7622
7623       if (next_hop_set)
7624         {
7625           if (DPO_PROTO_IP4 == next_hop_proto)
7626             {
7627               clib_memcpy (mp->mr_next_hop,
7628                            &v4_next_hop_address,
7629                            sizeof (v4_next_hop_address));
7630             }
7631           else if (DPO_PROTO_IP6 == next_hop_proto)
7632
7633             {
7634               clib_memcpy (mp->mr_next_hop,
7635                            &v6_next_hop_address,
7636                            sizeof (v6_next_hop_address));
7637             }
7638         }
7639       local_label++;
7640
7641       /* send it... */
7642       S (mp);
7643       /* If we receive SIGTERM, stop now... */
7644       if (vam->do_exit)
7645         break;
7646     }
7647
7648   /* When testing multiple add/del ops, use a control-ping to sync */
7649   if (count > 1)
7650     {
7651       vl_api_control_ping_t *mp_ping;
7652       f64 after;
7653       f64 timeout;
7654
7655       /* Shut off async mode */
7656       vam->async_mode = 0;
7657
7658       M (CONTROL_PING, mp_ping);
7659       S (mp_ping);
7660
7661       timeout = vat_time_now (vam) + 1.0;
7662       while (vat_time_now (vam) < timeout)
7663         if (vam->result_ready == 1)
7664           goto out;
7665       vam->retval = -99;
7666
7667     out:
7668       if (vam->retval == -99)
7669         errmsg ("timeout");
7670
7671       if (vam->async_errors > 0)
7672         {
7673           errmsg ("%d asynchronous errors", vam->async_errors);
7674           vam->retval = -98;
7675         }
7676       vam->async_errors = 0;
7677       after = vat_time_now (vam);
7678
7679       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7680       if (j > 0)
7681         count = j;
7682
7683       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7684              count, after - before, count / (after - before));
7685     }
7686   else
7687     {
7688       int ret;
7689
7690       /* Wait for a reply... */
7691       W (ret);
7692       return ret;
7693     }
7694
7695   /* Return the good/bad news */
7696   return (vam->retval);
7697 }
7698
7699 static int
7700 api_mpls_ip_bind_unbind (vat_main_t * vam)
7701 {
7702   unformat_input_t *i = vam->input;
7703   vl_api_mpls_ip_bind_unbind_t *mp;
7704   u32 ip_table_id = 0;
7705   u8 create_table_if_needed = 0;
7706   u8 is_bind = 1;
7707   u8 is_ip4 = 1;
7708   ip4_address_t v4_address;
7709   ip6_address_t v6_address;
7710   u32 address_length;
7711   u8 address_set = 0;
7712   mpls_label_t local_label = MPLS_LABEL_INVALID;
7713   int ret;
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "%U/%d", unformat_ip4_address,
7719                     &v4_address, &address_length))
7720         {
7721           is_ip4 = 1;
7722           address_set = 1;
7723         }
7724       else if (unformat (i, "%U/%d", unformat_ip6_address,
7725                          &v6_address, &address_length))
7726         {
7727           is_ip4 = 0;
7728           address_set = 1;
7729         }
7730       else if (unformat (i, "%d", &local_label))
7731         ;
7732       else if (unformat (i, "create-table"))
7733         create_table_if_needed = 1;
7734       else if (unformat (i, "table-id %d", &ip_table_id))
7735         ;
7736       else if (unformat (i, "unbind"))
7737         is_bind = 0;
7738       else if (unformat (i, "bind"))
7739         is_bind = 1;
7740       else
7741         {
7742           clib_warning ("parse error '%U'", format_unformat_error, i);
7743           return -99;
7744         }
7745     }
7746
7747   if (!address_set)
7748     {
7749       errmsg ("IP addres not set");
7750       return -99;
7751     }
7752
7753   if (MPLS_LABEL_INVALID == local_label)
7754     {
7755       errmsg ("missing label");
7756       return -99;
7757     }
7758
7759   /* Construct the API message */
7760   M (MPLS_IP_BIND_UNBIND, mp);
7761
7762   mp->mb_create_table_if_needed = create_table_if_needed;
7763   mp->mb_is_bind = is_bind;
7764   mp->mb_is_ip4 = is_ip4;
7765   mp->mb_ip_table_id = ntohl (ip_table_id);
7766   mp->mb_mpls_table_id = 0;
7767   mp->mb_label = ntohl (local_label);
7768   mp->mb_address_length = address_length;
7769
7770   if (is_ip4)
7771     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7772   else
7773     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7774
7775   /* send it... */
7776   S (mp);
7777
7778   /* Wait for a reply... */
7779   W (ret);
7780   return ret;
7781 }
7782
7783 static int
7784 api_proxy_arp_add_del (vat_main_t * vam)
7785 {
7786   unformat_input_t *i = vam->input;
7787   vl_api_proxy_arp_add_del_t *mp;
7788   u32 vrf_id = 0;
7789   u8 is_add = 1;
7790   ip4_address_t lo, hi;
7791   u8 range_set = 0;
7792   int ret;
7793
7794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7795     {
7796       if (unformat (i, "vrf %d", &vrf_id))
7797         ;
7798       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7799                          unformat_ip4_address, &hi))
7800         range_set = 1;
7801       else if (unformat (i, "del"))
7802         is_add = 0;
7803       else
7804         {
7805           clib_warning ("parse error '%U'", format_unformat_error, i);
7806           return -99;
7807         }
7808     }
7809
7810   if (range_set == 0)
7811     {
7812       errmsg ("address range not set");
7813       return -99;
7814     }
7815
7816   M (PROXY_ARP_ADD_DEL, mp);
7817
7818   mp->vrf_id = ntohl (vrf_id);
7819   mp->is_add = is_add;
7820   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7821   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7822
7823   S (mp);
7824   W (ret);
7825   return ret;
7826 }
7827
7828 static int
7829 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7830 {
7831   unformat_input_t *i = vam->input;
7832   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7833   u32 sw_if_index;
7834   u8 enable = 1;
7835   u8 sw_if_index_set = 0;
7836   int ret;
7837
7838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7839     {
7840       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7841         sw_if_index_set = 1;
7842       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7843         sw_if_index_set = 1;
7844       else if (unformat (i, "enable"))
7845         enable = 1;
7846       else if (unformat (i, "disable"))
7847         enable = 0;
7848       else
7849         {
7850           clib_warning ("parse error '%U'", format_unformat_error, i);
7851           return -99;
7852         }
7853     }
7854
7855   if (sw_if_index_set == 0)
7856     {
7857       errmsg ("missing interface name or sw_if_index");
7858       return -99;
7859     }
7860
7861   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7862
7863   mp->sw_if_index = ntohl (sw_if_index);
7864   mp->enable_disable = enable;
7865
7866   S (mp);
7867   W (ret);
7868   return ret;
7869 }
7870
7871 static int
7872 api_mpls_tunnel_add_del (vat_main_t * vam)
7873 {
7874   unformat_input_t *i = vam->input;
7875   vl_api_mpls_tunnel_add_del_t *mp;
7876
7877   u8 is_add = 1;
7878   u8 l2_only = 0;
7879   u32 sw_if_index = ~0;
7880   u32 next_hop_sw_if_index = ~0;
7881   u32 next_hop_proto_is_ip4 = 1;
7882
7883   u32 next_hop_table_id = 0;
7884   ip4_address_t v4_next_hop_address = {
7885     .as_u32 = 0,
7886   };
7887   ip6_address_t v6_next_hop_address = { {0} };
7888   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7889   int ret;
7890
7891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7892     {
7893       if (unformat (i, "add"))
7894         is_add = 1;
7895       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7896         is_add = 0;
7897       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7898         ;
7899       else if (unformat (i, "via %U",
7900                          unformat_ip4_address, &v4_next_hop_address))
7901         {
7902           next_hop_proto_is_ip4 = 1;
7903         }
7904       else if (unformat (i, "via %U",
7905                          unformat_ip6_address, &v6_next_hop_address))
7906         {
7907           next_hop_proto_is_ip4 = 0;
7908         }
7909       else if (unformat (i, "l2-only"))
7910         l2_only = 1;
7911       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7912         ;
7913       else if (unformat (i, "out-label %d", &next_hop_out_label))
7914         vec_add1 (labels, ntohl (next_hop_out_label));
7915       else
7916         {
7917           clib_warning ("parse error '%U'", format_unformat_error, i);
7918           return -99;
7919         }
7920     }
7921
7922   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7923
7924   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7925   mp->mt_sw_if_index = ntohl (sw_if_index);
7926   mp->mt_is_add = is_add;
7927   mp->mt_l2_only = l2_only;
7928   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7929   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7930
7931   mp->mt_next_hop_n_out_labels = vec_len (labels);
7932
7933   if (0 != mp->mt_next_hop_n_out_labels)
7934     {
7935       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7936                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7937       vec_free (labels);
7938     }
7939
7940   if (next_hop_proto_is_ip4)
7941     {
7942       clib_memcpy (mp->mt_next_hop,
7943                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7944     }
7945   else
7946     {
7947       clib_memcpy (mp->mt_next_hop,
7948                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7949     }
7950
7951   S (mp);
7952   W (ret);
7953   return ret;
7954 }
7955
7956 static int
7957 api_sw_interface_set_unnumbered (vat_main_t * vam)
7958 {
7959   unformat_input_t *i = vam->input;
7960   vl_api_sw_interface_set_unnumbered_t *mp;
7961   u32 sw_if_index;
7962   u32 unnum_sw_index = ~0;
7963   u8 is_add = 1;
7964   u8 sw_if_index_set = 0;
7965   int ret;
7966
7967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7968     {
7969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7970         sw_if_index_set = 1;
7971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7972         sw_if_index_set = 1;
7973       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7974         ;
7975       else if (unformat (i, "del"))
7976         is_add = 0;
7977       else
7978         {
7979           clib_warning ("parse error '%U'", format_unformat_error, i);
7980           return -99;
7981         }
7982     }
7983
7984   if (sw_if_index_set == 0)
7985     {
7986       errmsg ("missing interface name or sw_if_index");
7987       return -99;
7988     }
7989
7990   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7991
7992   mp->sw_if_index = ntohl (sw_if_index);
7993   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7994   mp->is_add = is_add;
7995
7996   S (mp);
7997   W (ret);
7998   return ret;
7999 }
8000
8001 static int
8002 api_ip_neighbor_add_del (vat_main_t * vam)
8003 {
8004   unformat_input_t *i = vam->input;
8005   vl_api_ip_neighbor_add_del_t *mp;
8006   u32 sw_if_index;
8007   u8 sw_if_index_set = 0;
8008   u8 is_add = 1;
8009   u8 is_static = 0;
8010   u8 is_no_fib_entry = 0;
8011   u8 mac_address[6];
8012   u8 mac_set = 0;
8013   u8 v4_address_set = 0;
8014   u8 v6_address_set = 0;
8015   ip4_address_t v4address;
8016   ip6_address_t v6address;
8017   int ret;
8018
8019   memset (mac_address, 0, sizeof (mac_address));
8020
8021   /* Parse args required to build the message */
8022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8023     {
8024       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8025         {
8026           mac_set = 1;
8027         }
8028       else if (unformat (i, "del"))
8029         is_add = 0;
8030       else
8031         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8032         sw_if_index_set = 1;
8033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8034         sw_if_index_set = 1;
8035       else if (unformat (i, "is_static"))
8036         is_static = 1;
8037       else if (unformat (i, "no-fib-entry"))
8038         is_no_fib_entry = 1;
8039       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8040         v4_address_set = 1;
8041       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8042         v6_address_set = 1;
8043       else
8044         {
8045           clib_warning ("parse error '%U'", format_unformat_error, i);
8046           return -99;
8047         }
8048     }
8049
8050   if (sw_if_index_set == 0)
8051     {
8052       errmsg ("missing interface name or sw_if_index");
8053       return -99;
8054     }
8055   if (v4_address_set && v6_address_set)
8056     {
8057       errmsg ("both v4 and v6 addresses set");
8058       return -99;
8059     }
8060   if (!v4_address_set && !v6_address_set)
8061     {
8062       errmsg ("no address set");
8063       return -99;
8064     }
8065
8066   /* Construct the API message */
8067   M (IP_NEIGHBOR_ADD_DEL, mp);
8068
8069   mp->sw_if_index = ntohl (sw_if_index);
8070   mp->is_add = is_add;
8071   mp->is_static = is_static;
8072   mp->is_no_adj_fib = is_no_fib_entry;
8073   if (mac_set)
8074     clib_memcpy (mp->mac_address, mac_address, 6);
8075   if (v6_address_set)
8076     {
8077       mp->is_ipv6 = 1;
8078       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8079     }
8080   else
8081     {
8082       /* mp->is_ipv6 = 0; via memset in M macro above */
8083       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8084     }
8085
8086   /* send it... */
8087   S (mp);
8088
8089   /* Wait for a reply, return good/bad news  */
8090   W (ret);
8091   return ret;
8092 }
8093
8094 static int
8095 api_reset_vrf (vat_main_t * vam)
8096 {
8097   unformat_input_t *i = vam->input;
8098   vl_api_reset_vrf_t *mp;
8099   u32 vrf_id = 0;
8100   u8 is_ipv6 = 0;
8101   u8 vrf_id_set = 0;
8102   int ret;
8103
8104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8105     {
8106       if (unformat (i, "vrf %d", &vrf_id))
8107         vrf_id_set = 1;
8108       else if (unformat (i, "ipv6"))
8109         is_ipv6 = 1;
8110       else
8111         {
8112           clib_warning ("parse error '%U'", format_unformat_error, i);
8113           return -99;
8114         }
8115     }
8116
8117   if (vrf_id_set == 0)
8118     {
8119       errmsg ("missing vrf id");
8120       return -99;
8121     }
8122
8123   M (RESET_VRF, mp);
8124
8125   mp->vrf_id = ntohl (vrf_id);
8126   mp->is_ipv6 = is_ipv6;
8127
8128   S (mp);
8129   W (ret);
8130   return ret;
8131 }
8132
8133 static int
8134 api_create_vlan_subif (vat_main_t * vam)
8135 {
8136   unformat_input_t *i = vam->input;
8137   vl_api_create_vlan_subif_t *mp;
8138   u32 sw_if_index;
8139   u8 sw_if_index_set = 0;
8140   u32 vlan_id;
8141   u8 vlan_id_set = 0;
8142   int ret;
8143
8144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8145     {
8146       if (unformat (i, "sw_if_index %d", &sw_if_index))
8147         sw_if_index_set = 1;
8148       else
8149         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8150         sw_if_index_set = 1;
8151       else if (unformat (i, "vlan %d", &vlan_id))
8152         vlan_id_set = 1;
8153       else
8154         {
8155           clib_warning ("parse error '%U'", format_unformat_error, i);
8156           return -99;
8157         }
8158     }
8159
8160   if (sw_if_index_set == 0)
8161     {
8162       errmsg ("missing interface name or sw_if_index");
8163       return -99;
8164     }
8165
8166   if (vlan_id_set == 0)
8167     {
8168       errmsg ("missing vlan_id");
8169       return -99;
8170     }
8171   M (CREATE_VLAN_SUBIF, mp);
8172
8173   mp->sw_if_index = ntohl (sw_if_index);
8174   mp->vlan_id = ntohl (vlan_id);
8175
8176   S (mp);
8177   W (ret);
8178   return ret;
8179 }
8180
8181 #define foreach_create_subif_bit                \
8182 _(no_tags)                                      \
8183 _(one_tag)                                      \
8184 _(two_tags)                                     \
8185 _(dot1ad)                                       \
8186 _(exact_match)                                  \
8187 _(default_sub)                                  \
8188 _(outer_vlan_id_any)                            \
8189 _(inner_vlan_id_any)
8190
8191 static int
8192 api_create_subif (vat_main_t * vam)
8193 {
8194   unformat_input_t *i = vam->input;
8195   vl_api_create_subif_t *mp;
8196   u32 sw_if_index;
8197   u8 sw_if_index_set = 0;
8198   u32 sub_id;
8199   u8 sub_id_set = 0;
8200   u32 no_tags = 0;
8201   u32 one_tag = 0;
8202   u32 two_tags = 0;
8203   u32 dot1ad = 0;
8204   u32 exact_match = 0;
8205   u32 default_sub = 0;
8206   u32 outer_vlan_id_any = 0;
8207   u32 inner_vlan_id_any = 0;
8208   u32 tmp;
8209   u16 outer_vlan_id = 0;
8210   u16 inner_vlan_id = 0;
8211   int ret;
8212
8213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8214     {
8215       if (unformat (i, "sw_if_index %d", &sw_if_index))
8216         sw_if_index_set = 1;
8217       else
8218         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8219         sw_if_index_set = 1;
8220       else if (unformat (i, "sub_id %d", &sub_id))
8221         sub_id_set = 1;
8222       else if (unformat (i, "outer_vlan_id %d", &tmp))
8223         outer_vlan_id = tmp;
8224       else if (unformat (i, "inner_vlan_id %d", &tmp))
8225         inner_vlan_id = tmp;
8226
8227 #define _(a) else if (unformat (i, #a)) a = 1 ;
8228       foreach_create_subif_bit
8229 #undef _
8230         else
8231         {
8232           clib_warning ("parse error '%U'", format_unformat_error, i);
8233           return -99;
8234         }
8235     }
8236
8237   if (sw_if_index_set == 0)
8238     {
8239       errmsg ("missing interface name or sw_if_index");
8240       return -99;
8241     }
8242
8243   if (sub_id_set == 0)
8244     {
8245       errmsg ("missing sub_id");
8246       return -99;
8247     }
8248   M (CREATE_SUBIF, mp);
8249
8250   mp->sw_if_index = ntohl (sw_if_index);
8251   mp->sub_id = ntohl (sub_id);
8252
8253 #define _(a) mp->a = a;
8254   foreach_create_subif_bit;
8255 #undef _
8256
8257   mp->outer_vlan_id = ntohs (outer_vlan_id);
8258   mp->inner_vlan_id = ntohs (inner_vlan_id);
8259
8260   S (mp);
8261   W (ret);
8262   return ret;
8263 }
8264
8265 static int
8266 api_oam_add_del (vat_main_t * vam)
8267 {
8268   unformat_input_t *i = vam->input;
8269   vl_api_oam_add_del_t *mp;
8270   u32 vrf_id = 0;
8271   u8 is_add = 1;
8272   ip4_address_t src, dst;
8273   u8 src_set = 0;
8274   u8 dst_set = 0;
8275   int ret;
8276
8277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8278     {
8279       if (unformat (i, "vrf %d", &vrf_id))
8280         ;
8281       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8282         src_set = 1;
8283       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8284         dst_set = 1;
8285       else if (unformat (i, "del"))
8286         is_add = 0;
8287       else
8288         {
8289           clib_warning ("parse error '%U'", format_unformat_error, i);
8290           return -99;
8291         }
8292     }
8293
8294   if (src_set == 0)
8295     {
8296       errmsg ("missing src addr");
8297       return -99;
8298     }
8299
8300   if (dst_set == 0)
8301     {
8302       errmsg ("missing dst addr");
8303       return -99;
8304     }
8305
8306   M (OAM_ADD_DEL, mp);
8307
8308   mp->vrf_id = ntohl (vrf_id);
8309   mp->is_add = is_add;
8310   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8311   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8312
8313   S (mp);
8314   W (ret);
8315   return ret;
8316 }
8317
8318 static int
8319 api_reset_fib (vat_main_t * vam)
8320 {
8321   unformat_input_t *i = vam->input;
8322   vl_api_reset_fib_t *mp;
8323   u32 vrf_id = 0;
8324   u8 is_ipv6 = 0;
8325   u8 vrf_id_set = 0;
8326
8327   int ret;
8328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8329     {
8330       if (unformat (i, "vrf %d", &vrf_id))
8331         vrf_id_set = 1;
8332       else if (unformat (i, "ipv6"))
8333         is_ipv6 = 1;
8334       else
8335         {
8336           clib_warning ("parse error '%U'", format_unformat_error, i);
8337           return -99;
8338         }
8339     }
8340
8341   if (vrf_id_set == 0)
8342     {
8343       errmsg ("missing vrf id");
8344       return -99;
8345     }
8346
8347   M (RESET_FIB, mp);
8348
8349   mp->vrf_id = ntohl (vrf_id);
8350   mp->is_ipv6 = is_ipv6;
8351
8352   S (mp);
8353   W (ret);
8354   return ret;
8355 }
8356
8357 static int
8358 api_dhcp_proxy_config (vat_main_t * vam)
8359 {
8360   unformat_input_t *i = vam->input;
8361   vl_api_dhcp_proxy_config_t *mp;
8362   u32 rx_vrf_id = 0;
8363   u32 server_vrf_id = 0;
8364   u8 is_add = 1;
8365   u8 v4_address_set = 0;
8366   u8 v6_address_set = 0;
8367   ip4_address_t v4address;
8368   ip6_address_t v6address;
8369   u8 v4_src_address_set = 0;
8370   u8 v6_src_address_set = 0;
8371   ip4_address_t v4srcaddress;
8372   ip6_address_t v6srcaddress;
8373   int ret;
8374
8375   /* Parse args required to build the message */
8376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8377     {
8378       if (unformat (i, "del"))
8379         is_add = 0;
8380       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8381         ;
8382       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8383         ;
8384       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8385         v4_address_set = 1;
8386       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8387         v6_address_set = 1;
8388       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8389         v4_src_address_set = 1;
8390       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8391         v6_src_address_set = 1;
8392       else
8393         break;
8394     }
8395
8396   if (v4_address_set && v6_address_set)
8397     {
8398       errmsg ("both v4 and v6 server addresses set");
8399       return -99;
8400     }
8401   if (!v4_address_set && !v6_address_set)
8402     {
8403       errmsg ("no server addresses set");
8404       return -99;
8405     }
8406
8407   if (v4_src_address_set && v6_src_address_set)
8408     {
8409       errmsg ("both v4 and v6  src addresses set");
8410       return -99;
8411     }
8412   if (!v4_src_address_set && !v6_src_address_set)
8413     {
8414       errmsg ("no src addresses set");
8415       return -99;
8416     }
8417
8418   if (!(v4_src_address_set && v4_address_set) &&
8419       !(v6_src_address_set && v6_address_set))
8420     {
8421       errmsg ("no matching server and src addresses set");
8422       return -99;
8423     }
8424
8425   /* Construct the API message */
8426   M (DHCP_PROXY_CONFIG, mp);
8427
8428   mp->is_add = is_add;
8429   mp->rx_vrf_id = ntohl (rx_vrf_id);
8430   mp->server_vrf_id = ntohl (server_vrf_id);
8431   if (v6_address_set)
8432     {
8433       mp->is_ipv6 = 1;
8434       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8435       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8436     }
8437   else
8438     {
8439       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8440       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8441     }
8442
8443   /* send it... */
8444   S (mp);
8445
8446   /* Wait for a reply, return good/bad news  */
8447   W (ret);
8448   return ret;
8449 }
8450
8451 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8452 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8453
8454 static void
8455 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8456 {
8457   vat_main_t *vam = &vat_main;
8458   u32 i, count = mp->count;
8459   vl_api_dhcp_server_t *s;
8460
8461   if (mp->is_ipv6)
8462     print (vam->ofp,
8463            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8464            ntohl (mp->rx_vrf_id),
8465            format_ip6_address, mp->dhcp_src_address,
8466            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8467   else
8468     print (vam->ofp,
8469            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8470            ntohl (mp->rx_vrf_id),
8471            format_ip4_address, mp->dhcp_src_address,
8472            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8473
8474   for (i = 0; i < count; i++)
8475     {
8476       s = &mp->servers[i];
8477
8478       if (mp->is_ipv6)
8479         print (vam->ofp,
8480                " Server Table-ID %d, Server Address %U",
8481                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8482       else
8483         print (vam->ofp,
8484                " Server Table-ID %d, Server Address %U",
8485                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8486     }
8487 }
8488
8489 static void vl_api_dhcp_proxy_details_t_handler_json
8490   (vl_api_dhcp_proxy_details_t * mp)
8491 {
8492   vat_main_t *vam = &vat_main;
8493   vat_json_node_t *node = NULL;
8494   u32 i, count = mp->count;
8495   struct in_addr ip4;
8496   struct in6_addr ip6;
8497   vl_api_dhcp_server_t *s;
8498
8499   if (VAT_JSON_ARRAY != vam->json_tree.type)
8500     {
8501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8502       vat_json_init_array (&vam->json_tree);
8503     }
8504   node = vat_json_array_add (&vam->json_tree);
8505
8506   vat_json_init_object (node);
8507   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8508   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8509   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8510
8511   if (mp->is_ipv6)
8512     {
8513       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8514       vat_json_object_add_ip6 (node, "src_address", ip6);
8515     }
8516   else
8517     {
8518       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8519       vat_json_object_add_ip4 (node, "src_address", ip4);
8520     }
8521
8522   for (i = 0; i < count; i++)
8523     {
8524       s = &mp->servers[i];
8525
8526       vat_json_object_add_uint (node, "server-table-id",
8527                                 ntohl (s->server_vrf_id));
8528
8529       if (mp->is_ipv6)
8530         {
8531           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8532           vat_json_object_add_ip4 (node, "src_address", ip4);
8533         }
8534       else
8535         {
8536           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8537           vat_json_object_add_ip6 (node, "server_address", ip6);
8538         }
8539     }
8540 }
8541
8542 static int
8543 api_dhcp_proxy_dump (vat_main_t * vam)
8544 {
8545   unformat_input_t *i = vam->input;
8546   vl_api_control_ping_t *mp_ping;
8547   vl_api_dhcp_proxy_dump_t *mp;
8548   u8 is_ipv6 = 0;
8549   int ret;
8550
8551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8552     {
8553       if (unformat (i, "ipv6"))
8554         is_ipv6 = 1;
8555       else
8556         {
8557           clib_warning ("parse error '%U'", format_unformat_error, i);
8558           return -99;
8559         }
8560     }
8561
8562   M (DHCP_PROXY_DUMP, mp);
8563
8564   mp->is_ip6 = is_ipv6;
8565   S (mp);
8566
8567   /* Use a control ping for synchronization */
8568   M (CONTROL_PING, mp_ping);
8569   S (mp_ping);
8570
8571   W (ret);
8572   return ret;
8573 }
8574
8575 static int
8576 api_dhcp_proxy_set_vss (vat_main_t * vam)
8577 {
8578   unformat_input_t *i = vam->input;
8579   vl_api_dhcp_proxy_set_vss_t *mp;
8580   u8 is_ipv6 = 0;
8581   u8 is_add = 1;
8582   u32 tbl_id;
8583   u8 tbl_id_set = 0;
8584   u32 oui;
8585   u8 oui_set = 0;
8586   u32 fib_id;
8587   u8 fib_id_set = 0;
8588   int ret;
8589
8590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8591     {
8592       if (unformat (i, "tbl_id %d", &tbl_id))
8593         tbl_id_set = 1;
8594       if (unformat (i, "fib_id %d", &fib_id))
8595         fib_id_set = 1;
8596       if (unformat (i, "oui %d", &oui))
8597         oui_set = 1;
8598       else if (unformat (i, "ipv6"))
8599         is_ipv6 = 1;
8600       else if (unformat (i, "del"))
8601         is_add = 0;
8602       else
8603         {
8604           clib_warning ("parse error '%U'", format_unformat_error, i);
8605           return -99;
8606         }
8607     }
8608
8609   if (tbl_id_set == 0)
8610     {
8611       errmsg ("missing tbl id");
8612       return -99;
8613     }
8614
8615   if (fib_id_set == 0)
8616     {
8617       errmsg ("missing fib id");
8618       return -99;
8619     }
8620   if (oui_set == 0)
8621     {
8622       errmsg ("missing oui");
8623       return -99;
8624     }
8625
8626   M (DHCP_PROXY_SET_VSS, mp);
8627   mp->tbl_id = ntohl (tbl_id);
8628   mp->fib_id = ntohl (fib_id);
8629   mp->oui = ntohl (oui);
8630   mp->is_ipv6 = is_ipv6;
8631   mp->is_add = is_add;
8632
8633   S (mp);
8634   W (ret);
8635   return ret;
8636 }
8637
8638 static int
8639 api_dhcp_client_config (vat_main_t * vam)
8640 {
8641   unformat_input_t *i = vam->input;
8642   vl_api_dhcp_client_config_t *mp;
8643   u32 sw_if_index;
8644   u8 sw_if_index_set = 0;
8645   u8 is_add = 1;
8646   u8 *hostname = 0;
8647   u8 disable_event = 0;
8648   int ret;
8649
8650   /* Parse args required to build the message */
8651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8652     {
8653       if (unformat (i, "del"))
8654         is_add = 0;
8655       else
8656         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8657         sw_if_index_set = 1;
8658       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8659         sw_if_index_set = 1;
8660       else if (unformat (i, "hostname %s", &hostname))
8661         ;
8662       else if (unformat (i, "disable_event"))
8663         disable_event = 1;
8664       else
8665         break;
8666     }
8667
8668   if (sw_if_index_set == 0)
8669     {
8670       errmsg ("missing interface name or sw_if_index");
8671       return -99;
8672     }
8673
8674   if (vec_len (hostname) > 63)
8675     {
8676       errmsg ("hostname too long");
8677     }
8678   vec_add1 (hostname, 0);
8679
8680   /* Construct the API message */
8681   M (DHCP_CLIENT_CONFIG, mp);
8682
8683   mp->sw_if_index = htonl (sw_if_index);
8684   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8685   vec_free (hostname);
8686   mp->is_add = is_add;
8687   mp->want_dhcp_event = disable_event ? 0 : 1;
8688   mp->pid = htonl (getpid ());
8689
8690   /* send it... */
8691   S (mp);
8692
8693   /* Wait for a reply, return good/bad news  */
8694   W (ret);
8695   return ret;
8696 }
8697
8698 static int
8699 api_set_ip_flow_hash (vat_main_t * vam)
8700 {
8701   unformat_input_t *i = vam->input;
8702   vl_api_set_ip_flow_hash_t *mp;
8703   u32 vrf_id = 0;
8704   u8 is_ipv6 = 0;
8705   u8 vrf_id_set = 0;
8706   u8 src = 0;
8707   u8 dst = 0;
8708   u8 sport = 0;
8709   u8 dport = 0;
8710   u8 proto = 0;
8711   u8 reverse = 0;
8712   int ret;
8713
8714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8715     {
8716       if (unformat (i, "vrf %d", &vrf_id))
8717         vrf_id_set = 1;
8718       else if (unformat (i, "ipv6"))
8719         is_ipv6 = 1;
8720       else if (unformat (i, "src"))
8721         src = 1;
8722       else if (unformat (i, "dst"))
8723         dst = 1;
8724       else if (unformat (i, "sport"))
8725         sport = 1;
8726       else if (unformat (i, "dport"))
8727         dport = 1;
8728       else if (unformat (i, "proto"))
8729         proto = 1;
8730       else if (unformat (i, "reverse"))
8731         reverse = 1;
8732
8733       else
8734         {
8735           clib_warning ("parse error '%U'", format_unformat_error, i);
8736           return -99;
8737         }
8738     }
8739
8740   if (vrf_id_set == 0)
8741     {
8742       errmsg ("missing vrf id");
8743       return -99;
8744     }
8745
8746   M (SET_IP_FLOW_HASH, mp);
8747   mp->src = src;
8748   mp->dst = dst;
8749   mp->sport = sport;
8750   mp->dport = dport;
8751   mp->proto = proto;
8752   mp->reverse = reverse;
8753   mp->vrf_id = ntohl (vrf_id);
8754   mp->is_ipv6 = is_ipv6;
8755
8756   S (mp);
8757   W (ret);
8758   return ret;
8759 }
8760
8761 static int
8762 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8763 {
8764   unformat_input_t *i = vam->input;
8765   vl_api_sw_interface_ip6_enable_disable_t *mp;
8766   u32 sw_if_index;
8767   u8 sw_if_index_set = 0;
8768   u8 enable = 0;
8769   int ret;
8770
8771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8772     {
8773       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8774         sw_if_index_set = 1;
8775       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8776         sw_if_index_set = 1;
8777       else if (unformat (i, "enable"))
8778         enable = 1;
8779       else if (unformat (i, "disable"))
8780         enable = 0;
8781       else
8782         {
8783           clib_warning ("parse error '%U'", format_unformat_error, i);
8784           return -99;
8785         }
8786     }
8787
8788   if (sw_if_index_set == 0)
8789     {
8790       errmsg ("missing interface name or sw_if_index");
8791       return -99;
8792     }
8793
8794   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8795
8796   mp->sw_if_index = ntohl (sw_if_index);
8797   mp->enable = enable;
8798
8799   S (mp);
8800   W (ret);
8801   return ret;
8802 }
8803
8804 static int
8805 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8806 {
8807   unformat_input_t *i = vam->input;
8808   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8809   u32 sw_if_index;
8810   u8 sw_if_index_set = 0;
8811   u8 v6_address_set = 0;
8812   ip6_address_t v6address;
8813   int ret;
8814
8815   /* Parse args required to build the message */
8816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8817     {
8818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8819         sw_if_index_set = 1;
8820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8821         sw_if_index_set = 1;
8822       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8823         v6_address_set = 1;
8824       else
8825         break;
8826     }
8827
8828   if (sw_if_index_set == 0)
8829     {
8830       errmsg ("missing interface name or sw_if_index");
8831       return -99;
8832     }
8833   if (!v6_address_set)
8834     {
8835       errmsg ("no address set");
8836       return -99;
8837     }
8838
8839   /* Construct the API message */
8840   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8841
8842   mp->sw_if_index = ntohl (sw_if_index);
8843   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8844
8845   /* send it... */
8846   S (mp);
8847
8848   /* Wait for a reply, return good/bad news  */
8849   W (ret);
8850   return ret;
8851 }
8852
8853 static int
8854 api_ip6nd_proxy_add_del (vat_main_t * vam)
8855 {
8856   unformat_input_t *i = vam->input;
8857   vl_api_ip6nd_proxy_add_del_t *mp;
8858   u32 sw_if_index = ~0;
8859   u8 v6_address_set = 0;
8860   ip6_address_t v6address;
8861   u8 is_del = 0;
8862   int ret;
8863
8864   /* Parse args required to build the message */
8865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8866     {
8867       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8868         ;
8869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8870         ;
8871       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8872         v6_address_set = 1;
8873       if (unformat (i, "del"))
8874         is_del = 1;
8875       else
8876         {
8877           clib_warning ("parse error '%U'", format_unformat_error, i);
8878           return -99;
8879         }
8880     }
8881
8882   if (sw_if_index == ~0)
8883     {
8884       errmsg ("missing interface name or sw_if_index");
8885       return -99;
8886     }
8887   if (!v6_address_set)
8888     {
8889       errmsg ("no address set");
8890       return -99;
8891     }
8892
8893   /* Construct the API message */
8894   M (IP6ND_PROXY_ADD_DEL, mp);
8895
8896   mp->is_del = is_del;
8897   mp->sw_if_index = ntohl (sw_if_index);
8898   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8899
8900   /* send it... */
8901   S (mp);
8902
8903   /* Wait for a reply, return good/bad news  */
8904   W (ret);
8905   return ret;
8906 }
8907
8908 static int
8909 api_ip6nd_proxy_dump (vat_main_t * vam)
8910 {
8911   vl_api_ip6nd_proxy_dump_t *mp;
8912   vl_api_control_ping_t *mp_ping;
8913   int ret;
8914
8915   M (IP6ND_PROXY_DUMP, mp);
8916
8917   S (mp);
8918
8919   /* Use a control ping for synchronization */
8920   M (CONTROL_PING, mp_ping);
8921   S (mp_ping);
8922
8923   W (ret);
8924   return ret;
8925 }
8926
8927 static void vl_api_ip6nd_proxy_details_t_handler
8928   (vl_api_ip6nd_proxy_details_t * mp)
8929 {
8930   vat_main_t *vam = &vat_main;
8931
8932   print (vam->ofp, "host %U sw_if_index %d",
8933          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8934 }
8935
8936 static void vl_api_ip6nd_proxy_details_t_handler_json
8937   (vl_api_ip6nd_proxy_details_t * mp)
8938 {
8939   vat_main_t *vam = &vat_main;
8940   struct in6_addr ip6;
8941   vat_json_node_t *node = NULL;
8942
8943   if (VAT_JSON_ARRAY != vam->json_tree.type)
8944     {
8945       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8946       vat_json_init_array (&vam->json_tree);
8947     }
8948   node = vat_json_array_add (&vam->json_tree);
8949
8950   vat_json_init_object (node);
8951   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8952
8953   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8954   vat_json_object_add_ip6 (node, "host", ip6);
8955 }
8956
8957 static int
8958 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8959 {
8960   unformat_input_t *i = vam->input;
8961   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8962   u32 sw_if_index;
8963   u8 sw_if_index_set = 0;
8964   u32 address_length = 0;
8965   u8 v6_address_set = 0;
8966   ip6_address_t v6address;
8967   u8 use_default = 0;
8968   u8 no_advertise = 0;
8969   u8 off_link = 0;
8970   u8 no_autoconfig = 0;
8971   u8 no_onlink = 0;
8972   u8 is_no = 0;
8973   u32 val_lifetime = 0;
8974   u32 pref_lifetime = 0;
8975   int ret;
8976
8977   /* Parse args required to build the message */
8978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8979     {
8980       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8981         sw_if_index_set = 1;
8982       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8983         sw_if_index_set = 1;
8984       else if (unformat (i, "%U/%d",
8985                          unformat_ip6_address, &v6address, &address_length))
8986         v6_address_set = 1;
8987       else if (unformat (i, "val_life %d", &val_lifetime))
8988         ;
8989       else if (unformat (i, "pref_life %d", &pref_lifetime))
8990         ;
8991       else if (unformat (i, "def"))
8992         use_default = 1;
8993       else if (unformat (i, "noadv"))
8994         no_advertise = 1;
8995       else if (unformat (i, "offl"))
8996         off_link = 1;
8997       else if (unformat (i, "noauto"))
8998         no_autoconfig = 1;
8999       else if (unformat (i, "nolink"))
9000         no_onlink = 1;
9001       else if (unformat (i, "isno"))
9002         is_no = 1;
9003       else
9004         {
9005           clib_warning ("parse error '%U'", format_unformat_error, i);
9006           return -99;
9007         }
9008     }
9009
9010   if (sw_if_index_set == 0)
9011     {
9012       errmsg ("missing interface name or sw_if_index");
9013       return -99;
9014     }
9015   if (!v6_address_set)
9016     {
9017       errmsg ("no address set");
9018       return -99;
9019     }
9020
9021   /* Construct the API message */
9022   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9023
9024   mp->sw_if_index = ntohl (sw_if_index);
9025   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9026   mp->address_length = address_length;
9027   mp->use_default = use_default;
9028   mp->no_advertise = no_advertise;
9029   mp->off_link = off_link;
9030   mp->no_autoconfig = no_autoconfig;
9031   mp->no_onlink = no_onlink;
9032   mp->is_no = is_no;
9033   mp->val_lifetime = ntohl (val_lifetime);
9034   mp->pref_lifetime = ntohl (pref_lifetime);
9035
9036   /* send it... */
9037   S (mp);
9038
9039   /* Wait for a reply, return good/bad news  */
9040   W (ret);
9041   return ret;
9042 }
9043
9044 static int
9045 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9046 {
9047   unformat_input_t *i = vam->input;
9048   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9049   u32 sw_if_index;
9050   u8 sw_if_index_set = 0;
9051   u8 suppress = 0;
9052   u8 managed = 0;
9053   u8 other = 0;
9054   u8 ll_option = 0;
9055   u8 send_unicast = 0;
9056   u8 cease = 0;
9057   u8 is_no = 0;
9058   u8 default_router = 0;
9059   u32 max_interval = 0;
9060   u32 min_interval = 0;
9061   u32 lifetime = 0;
9062   u32 initial_count = 0;
9063   u32 initial_interval = 0;
9064   int ret;
9065
9066
9067   /* Parse args required to build the message */
9068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9069     {
9070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9071         sw_if_index_set = 1;
9072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9073         sw_if_index_set = 1;
9074       else if (unformat (i, "maxint %d", &max_interval))
9075         ;
9076       else if (unformat (i, "minint %d", &min_interval))
9077         ;
9078       else if (unformat (i, "life %d", &lifetime))
9079         ;
9080       else if (unformat (i, "count %d", &initial_count))
9081         ;
9082       else if (unformat (i, "interval %d", &initial_interval))
9083         ;
9084       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9085         suppress = 1;
9086       else if (unformat (i, "managed"))
9087         managed = 1;
9088       else if (unformat (i, "other"))
9089         other = 1;
9090       else if (unformat (i, "ll"))
9091         ll_option = 1;
9092       else if (unformat (i, "send"))
9093         send_unicast = 1;
9094       else if (unformat (i, "cease"))
9095         cease = 1;
9096       else if (unformat (i, "isno"))
9097         is_no = 1;
9098       else if (unformat (i, "def"))
9099         default_router = 1;
9100       else
9101         {
9102           clib_warning ("parse error '%U'", format_unformat_error, i);
9103           return -99;
9104         }
9105     }
9106
9107   if (sw_if_index_set == 0)
9108     {
9109       errmsg ("missing interface name or sw_if_index");
9110       return -99;
9111     }
9112
9113   /* Construct the API message */
9114   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9115
9116   mp->sw_if_index = ntohl (sw_if_index);
9117   mp->max_interval = ntohl (max_interval);
9118   mp->min_interval = ntohl (min_interval);
9119   mp->lifetime = ntohl (lifetime);
9120   mp->initial_count = ntohl (initial_count);
9121   mp->initial_interval = ntohl (initial_interval);
9122   mp->suppress = suppress;
9123   mp->managed = managed;
9124   mp->other = other;
9125   mp->ll_option = ll_option;
9126   mp->send_unicast = send_unicast;
9127   mp->cease = cease;
9128   mp->is_no = is_no;
9129   mp->default_router = default_router;
9130
9131   /* send it... */
9132   S (mp);
9133
9134   /* Wait for a reply, return good/bad news  */
9135   W (ret);
9136   return ret;
9137 }
9138
9139 static int
9140 api_set_arp_neighbor_limit (vat_main_t * vam)
9141 {
9142   unformat_input_t *i = vam->input;
9143   vl_api_set_arp_neighbor_limit_t *mp;
9144   u32 arp_nbr_limit;
9145   u8 limit_set = 0;
9146   u8 is_ipv6 = 0;
9147   int ret;
9148
9149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9150     {
9151       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9152         limit_set = 1;
9153       else if (unformat (i, "ipv6"))
9154         is_ipv6 = 1;
9155       else
9156         {
9157           clib_warning ("parse error '%U'", format_unformat_error, i);
9158           return -99;
9159         }
9160     }
9161
9162   if (limit_set == 0)
9163     {
9164       errmsg ("missing limit value");
9165       return -99;
9166     }
9167
9168   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9169
9170   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9171   mp->is_ipv6 = is_ipv6;
9172
9173   S (mp);
9174   W (ret);
9175   return ret;
9176 }
9177
9178 static int
9179 api_l2_patch_add_del (vat_main_t * vam)
9180 {
9181   unformat_input_t *i = vam->input;
9182   vl_api_l2_patch_add_del_t *mp;
9183   u32 rx_sw_if_index;
9184   u8 rx_sw_if_index_set = 0;
9185   u32 tx_sw_if_index;
9186   u8 tx_sw_if_index_set = 0;
9187   u8 is_add = 1;
9188   int ret;
9189
9190   /* Parse args required to build the message */
9191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9192     {
9193       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9194         rx_sw_if_index_set = 1;
9195       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9196         tx_sw_if_index_set = 1;
9197       else if (unformat (i, "rx"))
9198         {
9199           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9200             {
9201               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9202                             &rx_sw_if_index))
9203                 rx_sw_if_index_set = 1;
9204             }
9205           else
9206             break;
9207         }
9208       else if (unformat (i, "tx"))
9209         {
9210           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9211             {
9212               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9213                             &tx_sw_if_index))
9214                 tx_sw_if_index_set = 1;
9215             }
9216           else
9217             break;
9218         }
9219       else if (unformat (i, "del"))
9220         is_add = 0;
9221       else
9222         break;
9223     }
9224
9225   if (rx_sw_if_index_set == 0)
9226     {
9227       errmsg ("missing rx interface name or rx_sw_if_index");
9228       return -99;
9229     }
9230
9231   if (tx_sw_if_index_set == 0)
9232     {
9233       errmsg ("missing tx interface name or tx_sw_if_index");
9234       return -99;
9235     }
9236
9237   M (L2_PATCH_ADD_DEL, mp);
9238
9239   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9240   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9241   mp->is_add = is_add;
9242
9243   S (mp);
9244   W (ret);
9245   return ret;
9246 }
9247
9248 u8 is_del;
9249 u8 localsid_addr[16];
9250 u8 end_psp;
9251 u8 behavior;
9252 u32 sw_if_index;
9253 u32 vlan_index;
9254 u32 fib_table;
9255 u8 nh_addr[16];
9256
9257 static int
9258 api_sr_localsid_add_del (vat_main_t * vam)
9259 {
9260   unformat_input_t *i = vam->input;
9261   vl_api_sr_localsid_add_del_t *mp;
9262
9263   u8 is_del;
9264   ip6_address_t localsid;
9265   u8 end_psp = 0;
9266   u8 behavior = ~0;
9267   u32 sw_if_index;
9268   u32 fib_table = ~(u32) 0;
9269   ip6_address_t next_hop;
9270
9271   bool nexthop_set = 0;
9272
9273   int ret;
9274
9275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (unformat (i, "del"))
9278         is_del = 1;
9279       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9280       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9281         nexthop_set = 1;
9282       else if (unformat (i, "behavior %u", &behavior));
9283       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9284       else if (unformat (i, "fib-table %u", &fib_table));
9285       else if (unformat (i, "end.psp %u", &behavior));
9286       else
9287         break;
9288     }
9289
9290   M (SR_LOCALSID_ADD_DEL, mp);
9291
9292   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9293   if (nexthop_set)
9294     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9295   mp->behavior = behavior;
9296   mp->sw_if_index = ntohl (sw_if_index);
9297   mp->fib_table = ntohl (fib_table);
9298   mp->end_psp = end_psp;
9299   mp->is_del = is_del;
9300
9301   S (mp);
9302   W (ret);
9303   return ret;
9304 }
9305
9306 static int
9307 api_ioam_enable (vat_main_t * vam)
9308 {
9309   unformat_input_t *input = vam->input;
9310   vl_api_ioam_enable_t *mp;
9311   u32 id = 0;
9312   int has_trace_option = 0;
9313   int has_pot_option = 0;
9314   int has_seqno_option = 0;
9315   int has_analyse_option = 0;
9316   int ret;
9317
9318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9319     {
9320       if (unformat (input, "trace"))
9321         has_trace_option = 1;
9322       else if (unformat (input, "pot"))
9323         has_pot_option = 1;
9324       else if (unformat (input, "seqno"))
9325         has_seqno_option = 1;
9326       else if (unformat (input, "analyse"))
9327         has_analyse_option = 1;
9328       else
9329         break;
9330     }
9331   M (IOAM_ENABLE, mp);
9332   mp->id = htons (id);
9333   mp->seqno = has_seqno_option;
9334   mp->analyse = has_analyse_option;
9335   mp->pot_enable = has_pot_option;
9336   mp->trace_enable = has_trace_option;
9337
9338   S (mp);
9339   W (ret);
9340   return ret;
9341 }
9342
9343
9344 static int
9345 api_ioam_disable (vat_main_t * vam)
9346 {
9347   vl_api_ioam_disable_t *mp;
9348   int ret;
9349
9350   M (IOAM_DISABLE, mp);
9351   S (mp);
9352   W (ret);
9353   return ret;
9354 }
9355
9356 #define foreach_tcp_proto_field                 \
9357 _(src_port)                                     \
9358 _(dst_port)
9359
9360 #define foreach_udp_proto_field                 \
9361 _(src_port)                                     \
9362 _(dst_port)
9363
9364 #define foreach_ip4_proto_field                 \
9365 _(src_address)                                  \
9366 _(dst_address)                                  \
9367 _(tos)                                          \
9368 _(length)                                       \
9369 _(fragment_id)                                  \
9370 _(ttl)                                          \
9371 _(protocol)                                     \
9372 _(checksum)
9373
9374 typedef struct
9375 {
9376   u16 src_port, dst_port;
9377 } tcpudp_header_t;
9378
9379 #if VPP_API_TEST_BUILTIN == 0
9380 uword
9381 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9382 {
9383   u8 **maskp = va_arg (*args, u8 **);
9384   u8 *mask = 0;
9385   u8 found_something = 0;
9386   tcp_header_t *tcp;
9387
9388 #define _(a) u8 a=0;
9389   foreach_tcp_proto_field;
9390 #undef _
9391
9392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9393     {
9394       if (0);
9395 #define _(a) else if (unformat (input, #a)) a=1;
9396       foreach_tcp_proto_field
9397 #undef _
9398         else
9399         break;
9400     }
9401
9402 #define _(a) found_something += a;
9403   foreach_tcp_proto_field;
9404 #undef _
9405
9406   if (found_something == 0)
9407     return 0;
9408
9409   vec_validate (mask, sizeof (*tcp) - 1);
9410
9411   tcp = (tcp_header_t *) mask;
9412
9413 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9414   foreach_tcp_proto_field;
9415 #undef _
9416
9417   *maskp = mask;
9418   return 1;
9419 }
9420
9421 uword
9422 unformat_udp_mask (unformat_input_t * input, va_list * args)
9423 {
9424   u8 **maskp = va_arg (*args, u8 **);
9425   u8 *mask = 0;
9426   u8 found_something = 0;
9427   udp_header_t *udp;
9428
9429 #define _(a) u8 a=0;
9430   foreach_udp_proto_field;
9431 #undef _
9432
9433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9434     {
9435       if (0);
9436 #define _(a) else if (unformat (input, #a)) a=1;
9437       foreach_udp_proto_field
9438 #undef _
9439         else
9440         break;
9441     }
9442
9443 #define _(a) found_something += a;
9444   foreach_udp_proto_field;
9445 #undef _
9446
9447   if (found_something == 0)
9448     return 0;
9449
9450   vec_validate (mask, sizeof (*udp) - 1);
9451
9452   udp = (udp_header_t *) mask;
9453
9454 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9455   foreach_udp_proto_field;
9456 #undef _
9457
9458   *maskp = mask;
9459   return 1;
9460 }
9461
9462 uword
9463 unformat_l4_mask (unformat_input_t * input, va_list * args)
9464 {
9465   u8 **maskp = va_arg (*args, u8 **);
9466   u16 src_port = 0, dst_port = 0;
9467   tcpudp_header_t *tcpudp;
9468
9469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9470     {
9471       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9472         return 1;
9473       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9474         return 1;
9475       else if (unformat (input, "src_port"))
9476         src_port = 0xFFFF;
9477       else if (unformat (input, "dst_port"))
9478         dst_port = 0xFFFF;
9479       else
9480         return 0;
9481     }
9482
9483   if (!src_port && !dst_port)
9484     return 0;
9485
9486   u8 *mask = 0;
9487   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9488
9489   tcpudp = (tcpudp_header_t *) mask;
9490   tcpudp->src_port = src_port;
9491   tcpudp->dst_port = dst_port;
9492
9493   *maskp = mask;
9494
9495   return 1;
9496 }
9497
9498 uword
9499 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9500 {
9501   u8 **maskp = va_arg (*args, u8 **);
9502   u8 *mask = 0;
9503   u8 found_something = 0;
9504   ip4_header_t *ip;
9505
9506 #define _(a) u8 a=0;
9507   foreach_ip4_proto_field;
9508 #undef _
9509   u8 version = 0;
9510   u8 hdr_length = 0;
9511
9512
9513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9514     {
9515       if (unformat (input, "version"))
9516         version = 1;
9517       else if (unformat (input, "hdr_length"))
9518         hdr_length = 1;
9519       else if (unformat (input, "src"))
9520         src_address = 1;
9521       else if (unformat (input, "dst"))
9522         dst_address = 1;
9523       else if (unformat (input, "proto"))
9524         protocol = 1;
9525
9526 #define _(a) else if (unformat (input, #a)) a=1;
9527       foreach_ip4_proto_field
9528 #undef _
9529         else
9530         break;
9531     }
9532
9533 #define _(a) found_something += a;
9534   foreach_ip4_proto_field;
9535 #undef _
9536
9537   if (found_something == 0)
9538     return 0;
9539
9540   vec_validate (mask, sizeof (*ip) - 1);
9541
9542   ip = (ip4_header_t *) mask;
9543
9544 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9545   foreach_ip4_proto_field;
9546 #undef _
9547
9548   ip->ip_version_and_header_length = 0;
9549
9550   if (version)
9551     ip->ip_version_and_header_length |= 0xF0;
9552
9553   if (hdr_length)
9554     ip->ip_version_and_header_length |= 0x0F;
9555
9556   *maskp = mask;
9557   return 1;
9558 }
9559
9560 #define foreach_ip6_proto_field                 \
9561 _(src_address)                                  \
9562 _(dst_address)                                  \
9563 _(payload_length)                               \
9564 _(hop_limit)                                    \
9565 _(protocol)
9566
9567 uword
9568 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9569 {
9570   u8 **maskp = va_arg (*args, u8 **);
9571   u8 *mask = 0;
9572   u8 found_something = 0;
9573   ip6_header_t *ip;
9574   u32 ip_version_traffic_class_and_flow_label;
9575
9576 #define _(a) u8 a=0;
9577   foreach_ip6_proto_field;
9578 #undef _
9579   u8 version = 0;
9580   u8 traffic_class = 0;
9581   u8 flow_label = 0;
9582
9583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9584     {
9585       if (unformat (input, "version"))
9586         version = 1;
9587       else if (unformat (input, "traffic-class"))
9588         traffic_class = 1;
9589       else if (unformat (input, "flow-label"))
9590         flow_label = 1;
9591       else if (unformat (input, "src"))
9592         src_address = 1;
9593       else if (unformat (input, "dst"))
9594         dst_address = 1;
9595       else if (unformat (input, "proto"))
9596         protocol = 1;
9597
9598 #define _(a) else if (unformat (input, #a)) a=1;
9599       foreach_ip6_proto_field
9600 #undef _
9601         else
9602         break;
9603     }
9604
9605 #define _(a) found_something += a;
9606   foreach_ip6_proto_field;
9607 #undef _
9608
9609   if (found_something == 0)
9610     return 0;
9611
9612   vec_validate (mask, sizeof (*ip) - 1);
9613
9614   ip = (ip6_header_t *) mask;
9615
9616 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9617   foreach_ip6_proto_field;
9618 #undef _
9619
9620   ip_version_traffic_class_and_flow_label = 0;
9621
9622   if (version)
9623     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9624
9625   if (traffic_class)
9626     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9627
9628   if (flow_label)
9629     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9630
9631   ip->ip_version_traffic_class_and_flow_label =
9632     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9633
9634   *maskp = mask;
9635   return 1;
9636 }
9637
9638 uword
9639 unformat_l3_mask (unformat_input_t * input, va_list * args)
9640 {
9641   u8 **maskp = va_arg (*args, u8 **);
9642
9643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9644     {
9645       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9646         return 1;
9647       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9648         return 1;
9649       else
9650         break;
9651     }
9652   return 0;
9653 }
9654
9655 uword
9656 unformat_l2_mask (unformat_input_t * input, va_list * args)
9657 {
9658   u8 **maskp = va_arg (*args, u8 **);
9659   u8 *mask = 0;
9660   u8 src = 0;
9661   u8 dst = 0;
9662   u8 proto = 0;
9663   u8 tag1 = 0;
9664   u8 tag2 = 0;
9665   u8 ignore_tag1 = 0;
9666   u8 ignore_tag2 = 0;
9667   u8 cos1 = 0;
9668   u8 cos2 = 0;
9669   u8 dot1q = 0;
9670   u8 dot1ad = 0;
9671   int len = 14;
9672
9673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9674     {
9675       if (unformat (input, "src"))
9676         src = 1;
9677       else if (unformat (input, "dst"))
9678         dst = 1;
9679       else if (unformat (input, "proto"))
9680         proto = 1;
9681       else if (unformat (input, "tag1"))
9682         tag1 = 1;
9683       else if (unformat (input, "tag2"))
9684         tag2 = 1;
9685       else if (unformat (input, "ignore-tag1"))
9686         ignore_tag1 = 1;
9687       else if (unformat (input, "ignore-tag2"))
9688         ignore_tag2 = 1;
9689       else if (unformat (input, "cos1"))
9690         cos1 = 1;
9691       else if (unformat (input, "cos2"))
9692         cos2 = 1;
9693       else if (unformat (input, "dot1q"))
9694         dot1q = 1;
9695       else if (unformat (input, "dot1ad"))
9696         dot1ad = 1;
9697       else
9698         break;
9699     }
9700   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9701        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9702     return 0;
9703
9704   if (tag1 || ignore_tag1 || cos1 || dot1q)
9705     len = 18;
9706   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9707     len = 22;
9708
9709   vec_validate (mask, len - 1);
9710
9711   if (dst)
9712     memset (mask, 0xff, 6);
9713
9714   if (src)
9715     memset (mask + 6, 0xff, 6);
9716
9717   if (tag2 || dot1ad)
9718     {
9719       /* inner vlan tag */
9720       if (tag2)
9721         {
9722           mask[19] = 0xff;
9723           mask[18] = 0x0f;
9724         }
9725       if (cos2)
9726         mask[18] |= 0xe0;
9727       if (proto)
9728         mask[21] = mask[20] = 0xff;
9729       if (tag1)
9730         {
9731           mask[15] = 0xff;
9732           mask[14] = 0x0f;
9733         }
9734       if (cos1)
9735         mask[14] |= 0xe0;
9736       *maskp = mask;
9737       return 1;
9738     }
9739   if (tag1 | dot1q)
9740     {
9741       if (tag1)
9742         {
9743           mask[15] = 0xff;
9744           mask[14] = 0x0f;
9745         }
9746       if (cos1)
9747         mask[14] |= 0xe0;
9748       if (proto)
9749         mask[16] = mask[17] = 0xff;
9750
9751       *maskp = mask;
9752       return 1;
9753     }
9754   if (cos2)
9755     mask[18] |= 0xe0;
9756   if (cos1)
9757     mask[14] |= 0xe0;
9758   if (proto)
9759     mask[12] = mask[13] = 0xff;
9760
9761   *maskp = mask;
9762   return 1;
9763 }
9764
9765 uword
9766 unformat_classify_mask (unformat_input_t * input, va_list * args)
9767 {
9768   u8 **maskp = va_arg (*args, u8 **);
9769   u32 *skipp = va_arg (*args, u32 *);
9770   u32 *matchp = va_arg (*args, u32 *);
9771   u32 match;
9772   u8 *mask = 0;
9773   u8 *l2 = 0;
9774   u8 *l3 = 0;
9775   u8 *l4 = 0;
9776   int i;
9777
9778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9779     {
9780       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9781         ;
9782       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9783         ;
9784       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9785         ;
9786       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9787         ;
9788       else
9789         break;
9790     }
9791
9792   if (l4 && !l3)
9793     {
9794       vec_free (mask);
9795       vec_free (l2);
9796       vec_free (l4);
9797       return 0;
9798     }
9799
9800   if (mask || l2 || l3 || l4)
9801     {
9802       if (l2 || l3 || l4)
9803         {
9804           /* "With a free Ethernet header in every package" */
9805           if (l2 == 0)
9806             vec_validate (l2, 13);
9807           mask = l2;
9808           if (vec_len (l3))
9809             {
9810               vec_append (mask, l3);
9811               vec_free (l3);
9812             }
9813           if (vec_len (l4))
9814             {
9815               vec_append (mask, l4);
9816               vec_free (l4);
9817             }
9818         }
9819
9820       /* Scan forward looking for the first significant mask octet */
9821       for (i = 0; i < vec_len (mask); i++)
9822         if (mask[i])
9823           break;
9824
9825       /* compute (skip, match) params */
9826       *skipp = i / sizeof (u32x4);
9827       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9828
9829       /* Pad mask to an even multiple of the vector size */
9830       while (vec_len (mask) % sizeof (u32x4))
9831         vec_add1 (mask, 0);
9832
9833       match = vec_len (mask) / sizeof (u32x4);
9834
9835       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9836         {
9837           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9838           if (*tmp || *(tmp + 1))
9839             break;
9840           match--;
9841         }
9842       if (match == 0)
9843         clib_warning ("BUG: match 0");
9844
9845       _vec_len (mask) = match * sizeof (u32x4);
9846
9847       *matchp = match;
9848       *maskp = mask;
9849
9850       return 1;
9851     }
9852
9853   return 0;
9854 }
9855 #endif /* VPP_API_TEST_BUILTIN */
9856
9857 #define foreach_l2_next                         \
9858 _(drop, DROP)                                   \
9859 _(ethernet, ETHERNET_INPUT)                     \
9860 _(ip4, IP4_INPUT)                               \
9861 _(ip6, IP6_INPUT)
9862
9863 uword
9864 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9865 {
9866   u32 *miss_next_indexp = va_arg (*args, u32 *);
9867   u32 next_index = 0;
9868   u32 tmp;
9869
9870 #define _(n,N) \
9871   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9872   foreach_l2_next;
9873 #undef _
9874
9875   if (unformat (input, "%d", &tmp))
9876     {
9877       next_index = tmp;
9878       goto out;
9879     }
9880
9881   return 0;
9882
9883 out:
9884   *miss_next_indexp = next_index;
9885   return 1;
9886 }
9887
9888 #define foreach_ip_next                         \
9889 _(drop, DROP)                                   \
9890 _(local, LOCAL)                                 \
9891 _(rewrite, REWRITE)
9892
9893 uword
9894 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9895 {
9896   u32 *miss_next_indexp = va_arg (*args, u32 *);
9897   u32 next_index = 0;
9898   u32 tmp;
9899
9900 #define _(n,N) \
9901   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9902   foreach_ip_next;
9903 #undef _
9904
9905   if (unformat (input, "%d", &tmp))
9906     {
9907       next_index = tmp;
9908       goto out;
9909     }
9910
9911   return 0;
9912
9913 out:
9914   *miss_next_indexp = next_index;
9915   return 1;
9916 }
9917
9918 #define foreach_acl_next                        \
9919 _(deny, DENY)
9920
9921 uword
9922 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9923 {
9924   u32 *miss_next_indexp = va_arg (*args, u32 *);
9925   u32 next_index = 0;
9926   u32 tmp;
9927
9928 #define _(n,N) \
9929   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9930   foreach_acl_next;
9931 #undef _
9932
9933   if (unformat (input, "permit"))
9934     {
9935       next_index = ~0;
9936       goto out;
9937     }
9938   else if (unformat (input, "%d", &tmp))
9939     {
9940       next_index = tmp;
9941       goto out;
9942     }
9943
9944   return 0;
9945
9946 out:
9947   *miss_next_indexp = next_index;
9948   return 1;
9949 }
9950
9951 uword
9952 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9953 {
9954   u32 *r = va_arg (*args, u32 *);
9955
9956   if (unformat (input, "conform-color"))
9957     *r = POLICE_CONFORM;
9958   else if (unformat (input, "exceed-color"))
9959     *r = POLICE_EXCEED;
9960   else
9961     return 0;
9962
9963   return 1;
9964 }
9965
9966 static int
9967 api_classify_add_del_table (vat_main_t * vam)
9968 {
9969   unformat_input_t *i = vam->input;
9970   vl_api_classify_add_del_table_t *mp;
9971
9972   u32 nbuckets = 2;
9973   u32 skip = ~0;
9974   u32 match = ~0;
9975   int is_add = 1;
9976   int del_chain = 0;
9977   u32 table_index = ~0;
9978   u32 next_table_index = ~0;
9979   u32 miss_next_index = ~0;
9980   u32 memory_size = 32 << 20;
9981   u8 *mask = 0;
9982   u32 current_data_flag = 0;
9983   int current_data_offset = 0;
9984   int ret;
9985
9986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9987     {
9988       if (unformat (i, "del"))
9989         is_add = 0;
9990       else if (unformat (i, "del-chain"))
9991         {
9992           is_add = 0;
9993           del_chain = 1;
9994         }
9995       else if (unformat (i, "buckets %d", &nbuckets))
9996         ;
9997       else if (unformat (i, "memory_size %d", &memory_size))
9998         ;
9999       else if (unformat (i, "skip %d", &skip))
10000         ;
10001       else if (unformat (i, "match %d", &match))
10002         ;
10003       else if (unformat (i, "table %d", &table_index))
10004         ;
10005       else if (unformat (i, "mask %U", unformat_classify_mask,
10006                          &mask, &skip, &match))
10007         ;
10008       else if (unformat (i, "next-table %d", &next_table_index))
10009         ;
10010       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10011                          &miss_next_index))
10012         ;
10013       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10014                          &miss_next_index))
10015         ;
10016       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10017                          &miss_next_index))
10018         ;
10019       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10020         ;
10021       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10022         ;
10023       else
10024         break;
10025     }
10026
10027   if (is_add && mask == 0)
10028     {
10029       errmsg ("Mask required");
10030       return -99;
10031     }
10032
10033   if (is_add && skip == ~0)
10034     {
10035       errmsg ("skip count required");
10036       return -99;
10037     }
10038
10039   if (is_add && match == ~0)
10040     {
10041       errmsg ("match count required");
10042       return -99;
10043     }
10044
10045   if (!is_add && table_index == ~0)
10046     {
10047       errmsg ("table index required for delete");
10048       return -99;
10049     }
10050
10051   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10052
10053   mp->is_add = is_add;
10054   mp->del_chain = del_chain;
10055   mp->table_index = ntohl (table_index);
10056   mp->nbuckets = ntohl (nbuckets);
10057   mp->memory_size = ntohl (memory_size);
10058   mp->skip_n_vectors = ntohl (skip);
10059   mp->match_n_vectors = ntohl (match);
10060   mp->next_table_index = ntohl (next_table_index);
10061   mp->miss_next_index = ntohl (miss_next_index);
10062   mp->current_data_flag = ntohl (current_data_flag);
10063   mp->current_data_offset = ntohl (current_data_offset);
10064   clib_memcpy (mp->mask, mask, vec_len (mask));
10065
10066   vec_free (mask);
10067
10068   S (mp);
10069   W (ret);
10070   return ret;
10071 }
10072
10073 #if VPP_API_TEST_BUILTIN == 0
10074 uword
10075 unformat_l4_match (unformat_input_t * input, va_list * args)
10076 {
10077   u8 **matchp = va_arg (*args, u8 **);
10078
10079   u8 *proto_header = 0;
10080   int src_port = 0;
10081   int dst_port = 0;
10082
10083   tcpudp_header_t h;
10084
10085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10086     {
10087       if (unformat (input, "src_port %d", &src_port))
10088         ;
10089       else if (unformat (input, "dst_port %d", &dst_port))
10090         ;
10091       else
10092         return 0;
10093     }
10094
10095   h.src_port = clib_host_to_net_u16 (src_port);
10096   h.dst_port = clib_host_to_net_u16 (dst_port);
10097   vec_validate (proto_header, sizeof (h) - 1);
10098   memcpy (proto_header, &h, sizeof (h));
10099
10100   *matchp = proto_header;
10101
10102   return 1;
10103 }
10104
10105 uword
10106 unformat_ip4_match (unformat_input_t * input, va_list * args)
10107 {
10108   u8 **matchp = va_arg (*args, u8 **);
10109   u8 *match = 0;
10110   ip4_header_t *ip;
10111   int version = 0;
10112   u32 version_val;
10113   int hdr_length = 0;
10114   u32 hdr_length_val;
10115   int src = 0, dst = 0;
10116   ip4_address_t src_val, dst_val;
10117   int proto = 0;
10118   u32 proto_val;
10119   int tos = 0;
10120   u32 tos_val;
10121   int length = 0;
10122   u32 length_val;
10123   int fragment_id = 0;
10124   u32 fragment_id_val;
10125   int ttl = 0;
10126   int ttl_val;
10127   int checksum = 0;
10128   u32 checksum_val;
10129
10130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10131     {
10132       if (unformat (input, "version %d", &version_val))
10133         version = 1;
10134       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10135         hdr_length = 1;
10136       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10137         src = 1;
10138       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10139         dst = 1;
10140       else if (unformat (input, "proto %d", &proto_val))
10141         proto = 1;
10142       else if (unformat (input, "tos %d", &tos_val))
10143         tos = 1;
10144       else if (unformat (input, "length %d", &length_val))
10145         length = 1;
10146       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10147         fragment_id = 1;
10148       else if (unformat (input, "ttl %d", &ttl_val))
10149         ttl = 1;
10150       else if (unformat (input, "checksum %d", &checksum_val))
10151         checksum = 1;
10152       else
10153         break;
10154     }
10155
10156   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10157       + ttl + checksum == 0)
10158     return 0;
10159
10160   /*
10161    * Aligned because we use the real comparison functions
10162    */
10163   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10164
10165   ip = (ip4_header_t *) match;
10166
10167   /* These are realistically matched in practice */
10168   if (src)
10169     ip->src_address.as_u32 = src_val.as_u32;
10170
10171   if (dst)
10172     ip->dst_address.as_u32 = dst_val.as_u32;
10173
10174   if (proto)
10175     ip->protocol = proto_val;
10176
10177
10178   /* These are not, but they're included for completeness */
10179   if (version)
10180     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10181
10182   if (hdr_length)
10183     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10184
10185   if (tos)
10186     ip->tos = tos_val;
10187
10188   if (length)
10189     ip->length = clib_host_to_net_u16 (length_val);
10190
10191   if (ttl)
10192     ip->ttl = ttl_val;
10193
10194   if (checksum)
10195     ip->checksum = clib_host_to_net_u16 (checksum_val);
10196
10197   *matchp = match;
10198   return 1;
10199 }
10200
10201 uword
10202 unformat_ip6_match (unformat_input_t * input, va_list * args)
10203 {
10204   u8 **matchp = va_arg (*args, u8 **);
10205   u8 *match = 0;
10206   ip6_header_t *ip;
10207   int version = 0;
10208   u32 version_val;
10209   u8 traffic_class = 0;
10210   u32 traffic_class_val = 0;
10211   u8 flow_label = 0;
10212   u8 flow_label_val;
10213   int src = 0, dst = 0;
10214   ip6_address_t src_val, dst_val;
10215   int proto = 0;
10216   u32 proto_val;
10217   int payload_length = 0;
10218   u32 payload_length_val;
10219   int hop_limit = 0;
10220   int hop_limit_val;
10221   u32 ip_version_traffic_class_and_flow_label;
10222
10223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10224     {
10225       if (unformat (input, "version %d", &version_val))
10226         version = 1;
10227       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10228         traffic_class = 1;
10229       else if (unformat (input, "flow_label %d", &flow_label_val))
10230         flow_label = 1;
10231       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10232         src = 1;
10233       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10234         dst = 1;
10235       else if (unformat (input, "proto %d", &proto_val))
10236         proto = 1;
10237       else if (unformat (input, "payload_length %d", &payload_length_val))
10238         payload_length = 1;
10239       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10240         hop_limit = 1;
10241       else
10242         break;
10243     }
10244
10245   if (version + traffic_class + flow_label + src + dst + proto +
10246       payload_length + hop_limit == 0)
10247     return 0;
10248
10249   /*
10250    * Aligned because we use the real comparison functions
10251    */
10252   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10253
10254   ip = (ip6_header_t *) match;
10255
10256   if (src)
10257     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10258
10259   if (dst)
10260     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10261
10262   if (proto)
10263     ip->protocol = proto_val;
10264
10265   ip_version_traffic_class_and_flow_label = 0;
10266
10267   if (version)
10268     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10269
10270   if (traffic_class)
10271     ip_version_traffic_class_and_flow_label |=
10272       (traffic_class_val & 0xFF) << 20;
10273
10274   if (flow_label)
10275     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10276
10277   ip->ip_version_traffic_class_and_flow_label =
10278     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10279
10280   if (payload_length)
10281     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10282
10283   if (hop_limit)
10284     ip->hop_limit = hop_limit_val;
10285
10286   *matchp = match;
10287   return 1;
10288 }
10289
10290 uword
10291 unformat_l3_match (unformat_input_t * input, va_list * args)
10292 {
10293   u8 **matchp = va_arg (*args, u8 **);
10294
10295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10296     {
10297       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10298         return 1;
10299       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10300         return 1;
10301       else
10302         break;
10303     }
10304   return 0;
10305 }
10306
10307 uword
10308 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10309 {
10310   u8 *tagp = va_arg (*args, u8 *);
10311   u32 tag;
10312
10313   if (unformat (input, "%d", &tag))
10314     {
10315       tagp[0] = (tag >> 8) & 0x0F;
10316       tagp[1] = tag & 0xFF;
10317       return 1;
10318     }
10319
10320   return 0;
10321 }
10322
10323 uword
10324 unformat_l2_match (unformat_input_t * input, va_list * args)
10325 {
10326   u8 **matchp = va_arg (*args, u8 **);
10327   u8 *match = 0;
10328   u8 src = 0;
10329   u8 src_val[6];
10330   u8 dst = 0;
10331   u8 dst_val[6];
10332   u8 proto = 0;
10333   u16 proto_val;
10334   u8 tag1 = 0;
10335   u8 tag1_val[2];
10336   u8 tag2 = 0;
10337   u8 tag2_val[2];
10338   int len = 14;
10339   u8 ignore_tag1 = 0;
10340   u8 ignore_tag2 = 0;
10341   u8 cos1 = 0;
10342   u8 cos2 = 0;
10343   u32 cos1_val = 0;
10344   u32 cos2_val = 0;
10345
10346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10347     {
10348       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10349         src = 1;
10350       else
10351         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10352         dst = 1;
10353       else if (unformat (input, "proto %U",
10354                          unformat_ethernet_type_host_byte_order, &proto_val))
10355         proto = 1;
10356       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10357         tag1 = 1;
10358       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10359         tag2 = 1;
10360       else if (unformat (input, "ignore-tag1"))
10361         ignore_tag1 = 1;
10362       else if (unformat (input, "ignore-tag2"))
10363         ignore_tag2 = 1;
10364       else if (unformat (input, "cos1 %d", &cos1_val))
10365         cos1 = 1;
10366       else if (unformat (input, "cos2 %d", &cos2_val))
10367         cos2 = 1;
10368       else
10369         break;
10370     }
10371   if ((src + dst + proto + tag1 + tag2 +
10372        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10373     return 0;
10374
10375   if (tag1 || ignore_tag1 || cos1)
10376     len = 18;
10377   if (tag2 || ignore_tag2 || cos2)
10378     len = 22;
10379
10380   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10381
10382   if (dst)
10383     clib_memcpy (match, dst_val, 6);
10384
10385   if (src)
10386     clib_memcpy (match + 6, src_val, 6);
10387
10388   if (tag2)
10389     {
10390       /* inner vlan tag */
10391       match[19] = tag2_val[1];
10392       match[18] = tag2_val[0];
10393       if (cos2)
10394         match[18] |= (cos2_val & 0x7) << 5;
10395       if (proto)
10396         {
10397           match[21] = proto_val & 0xff;
10398           match[20] = proto_val >> 8;
10399         }
10400       if (tag1)
10401         {
10402           match[15] = tag1_val[1];
10403           match[14] = tag1_val[0];
10404         }
10405       if (cos1)
10406         match[14] |= (cos1_val & 0x7) << 5;
10407       *matchp = match;
10408       return 1;
10409     }
10410   if (tag1)
10411     {
10412       match[15] = tag1_val[1];
10413       match[14] = tag1_val[0];
10414       if (proto)
10415         {
10416           match[17] = proto_val & 0xff;
10417           match[16] = proto_val >> 8;
10418         }
10419       if (cos1)
10420         match[14] |= (cos1_val & 0x7) << 5;
10421
10422       *matchp = match;
10423       return 1;
10424     }
10425   if (cos2)
10426     match[18] |= (cos2_val & 0x7) << 5;
10427   if (cos1)
10428     match[14] |= (cos1_val & 0x7) << 5;
10429   if (proto)
10430     {
10431       match[13] = proto_val & 0xff;
10432       match[12] = proto_val >> 8;
10433     }
10434
10435   *matchp = match;
10436   return 1;
10437 }
10438 #endif
10439
10440 uword
10441 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10442 {
10443   u8 **matchp = va_arg (*args, u8 **);
10444   u32 skip_n_vectors = va_arg (*args, u32);
10445   u32 match_n_vectors = va_arg (*args, u32);
10446
10447   u8 *match = 0;
10448   u8 *l2 = 0;
10449   u8 *l3 = 0;
10450   u8 *l4 = 0;
10451
10452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10453     {
10454       if (unformat (input, "hex %U", unformat_hex_string, &match))
10455         ;
10456       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10457         ;
10458       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10459         ;
10460       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10461         ;
10462       else
10463         break;
10464     }
10465
10466   if (l4 && !l3)
10467     {
10468       vec_free (match);
10469       vec_free (l2);
10470       vec_free (l4);
10471       return 0;
10472     }
10473
10474   if (match || l2 || l3 || l4)
10475     {
10476       if (l2 || l3 || l4)
10477         {
10478           /* "Win a free Ethernet header in every packet" */
10479           if (l2 == 0)
10480             vec_validate_aligned (l2, 13, sizeof (u32x4));
10481           match = l2;
10482           if (vec_len (l3))
10483             {
10484               vec_append_aligned (match, l3, sizeof (u32x4));
10485               vec_free (l3);
10486             }
10487           if (vec_len (l4))
10488             {
10489               vec_append_aligned (match, l4, sizeof (u32x4));
10490               vec_free (l4);
10491             }
10492         }
10493
10494       /* Make sure the vector is big enough even if key is all 0's */
10495       vec_validate_aligned
10496         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10497          sizeof (u32x4));
10498
10499       /* Set size, include skipped vectors */
10500       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10501
10502       *matchp = match;
10503
10504       return 1;
10505     }
10506
10507   return 0;
10508 }
10509
10510 static int
10511 api_classify_add_del_session (vat_main_t * vam)
10512 {
10513   unformat_input_t *i = vam->input;
10514   vl_api_classify_add_del_session_t *mp;
10515   int is_add = 1;
10516   u32 table_index = ~0;
10517   u32 hit_next_index = ~0;
10518   u32 opaque_index = ~0;
10519   u8 *match = 0;
10520   i32 advance = 0;
10521   u32 skip_n_vectors = 0;
10522   u32 match_n_vectors = 0;
10523   u32 action = 0;
10524   u32 metadata = 0;
10525   int ret;
10526
10527   /*
10528    * Warning: you have to supply skip_n and match_n
10529    * because the API client cant simply look at the classify
10530    * table object.
10531    */
10532
10533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10534     {
10535       if (unformat (i, "del"))
10536         is_add = 0;
10537       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10538                          &hit_next_index))
10539         ;
10540       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10541                          &hit_next_index))
10542         ;
10543       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10544                          &hit_next_index))
10545         ;
10546       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10547         ;
10548       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10549         ;
10550       else if (unformat (i, "opaque-index %d", &opaque_index))
10551         ;
10552       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10553         ;
10554       else if (unformat (i, "match_n %d", &match_n_vectors))
10555         ;
10556       else if (unformat (i, "match %U", api_unformat_classify_match,
10557                          &match, skip_n_vectors, match_n_vectors))
10558         ;
10559       else if (unformat (i, "advance %d", &advance))
10560         ;
10561       else if (unformat (i, "table-index %d", &table_index))
10562         ;
10563       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10564         action = 1;
10565       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10566         action = 2;
10567       else if (unformat (i, "action %d", &action))
10568         ;
10569       else if (unformat (i, "metadata %d", &metadata))
10570         ;
10571       else
10572         break;
10573     }
10574
10575   if (table_index == ~0)
10576     {
10577       errmsg ("Table index required");
10578       return -99;
10579     }
10580
10581   if (is_add && match == 0)
10582     {
10583       errmsg ("Match value required");
10584       return -99;
10585     }
10586
10587   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10588
10589   mp->is_add = is_add;
10590   mp->table_index = ntohl (table_index);
10591   mp->hit_next_index = ntohl (hit_next_index);
10592   mp->opaque_index = ntohl (opaque_index);
10593   mp->advance = ntohl (advance);
10594   mp->action = action;
10595   mp->metadata = ntohl (metadata);
10596   clib_memcpy (mp->match, match, vec_len (match));
10597   vec_free (match);
10598
10599   S (mp);
10600   W (ret);
10601   return ret;
10602 }
10603
10604 static int
10605 api_classify_set_interface_ip_table (vat_main_t * vam)
10606 {
10607   unformat_input_t *i = vam->input;
10608   vl_api_classify_set_interface_ip_table_t *mp;
10609   u32 sw_if_index;
10610   int sw_if_index_set;
10611   u32 table_index = ~0;
10612   u8 is_ipv6 = 0;
10613   int ret;
10614
10615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10616     {
10617       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10618         sw_if_index_set = 1;
10619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10620         sw_if_index_set = 1;
10621       else if (unformat (i, "table %d", &table_index))
10622         ;
10623       else
10624         {
10625           clib_warning ("parse error '%U'", format_unformat_error, i);
10626           return -99;
10627         }
10628     }
10629
10630   if (sw_if_index_set == 0)
10631     {
10632       errmsg ("missing interface name or sw_if_index");
10633       return -99;
10634     }
10635
10636
10637   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10638
10639   mp->sw_if_index = ntohl (sw_if_index);
10640   mp->table_index = ntohl (table_index);
10641   mp->is_ipv6 = is_ipv6;
10642
10643   S (mp);
10644   W (ret);
10645   return ret;
10646 }
10647
10648 static int
10649 api_classify_set_interface_l2_tables (vat_main_t * vam)
10650 {
10651   unformat_input_t *i = vam->input;
10652   vl_api_classify_set_interface_l2_tables_t *mp;
10653   u32 sw_if_index;
10654   int sw_if_index_set;
10655   u32 ip4_table_index = ~0;
10656   u32 ip6_table_index = ~0;
10657   u32 other_table_index = ~0;
10658   u32 is_input = 1;
10659   int ret;
10660
10661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10662     {
10663       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10664         sw_if_index_set = 1;
10665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10666         sw_if_index_set = 1;
10667       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10668         ;
10669       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10670         ;
10671       else if (unformat (i, "other-table %d", &other_table_index))
10672         ;
10673       else if (unformat (i, "is-input %d", &is_input))
10674         ;
10675       else
10676         {
10677           clib_warning ("parse error '%U'", format_unformat_error, i);
10678           return -99;
10679         }
10680     }
10681
10682   if (sw_if_index_set == 0)
10683     {
10684       errmsg ("missing interface name or sw_if_index");
10685       return -99;
10686     }
10687
10688
10689   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10690
10691   mp->sw_if_index = ntohl (sw_if_index);
10692   mp->ip4_table_index = ntohl (ip4_table_index);
10693   mp->ip6_table_index = ntohl (ip6_table_index);
10694   mp->other_table_index = ntohl (other_table_index);
10695   mp->is_input = (u8) is_input;
10696
10697   S (mp);
10698   W (ret);
10699   return ret;
10700 }
10701
10702 static int
10703 api_set_ipfix_exporter (vat_main_t * vam)
10704 {
10705   unformat_input_t *i = vam->input;
10706   vl_api_set_ipfix_exporter_t *mp;
10707   ip4_address_t collector_address;
10708   u8 collector_address_set = 0;
10709   u32 collector_port = ~0;
10710   ip4_address_t src_address;
10711   u8 src_address_set = 0;
10712   u32 vrf_id = ~0;
10713   u32 path_mtu = ~0;
10714   u32 template_interval = ~0;
10715   u8 udp_checksum = 0;
10716   int ret;
10717
10718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10719     {
10720       if (unformat (i, "collector_address %U", unformat_ip4_address,
10721                     &collector_address))
10722         collector_address_set = 1;
10723       else if (unformat (i, "collector_port %d", &collector_port))
10724         ;
10725       else if (unformat (i, "src_address %U", unformat_ip4_address,
10726                          &src_address))
10727         src_address_set = 1;
10728       else if (unformat (i, "vrf_id %d", &vrf_id))
10729         ;
10730       else if (unformat (i, "path_mtu %d", &path_mtu))
10731         ;
10732       else if (unformat (i, "template_interval %d", &template_interval))
10733         ;
10734       else if (unformat (i, "udp_checksum"))
10735         udp_checksum = 1;
10736       else
10737         break;
10738     }
10739
10740   if (collector_address_set == 0)
10741     {
10742       errmsg ("collector_address required");
10743       return -99;
10744     }
10745
10746   if (src_address_set == 0)
10747     {
10748       errmsg ("src_address required");
10749       return -99;
10750     }
10751
10752   M (SET_IPFIX_EXPORTER, mp);
10753
10754   memcpy (mp->collector_address, collector_address.data,
10755           sizeof (collector_address.data));
10756   mp->collector_port = htons ((u16) collector_port);
10757   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10758   mp->vrf_id = htonl (vrf_id);
10759   mp->path_mtu = htonl (path_mtu);
10760   mp->template_interval = htonl (template_interval);
10761   mp->udp_checksum = udp_checksum;
10762
10763   S (mp);
10764   W (ret);
10765   return ret;
10766 }
10767
10768 static int
10769 api_set_ipfix_classify_stream (vat_main_t * vam)
10770 {
10771   unformat_input_t *i = vam->input;
10772   vl_api_set_ipfix_classify_stream_t *mp;
10773   u32 domain_id = 0;
10774   u32 src_port = UDP_DST_PORT_ipfix;
10775   int ret;
10776
10777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10778     {
10779       if (unformat (i, "domain %d", &domain_id))
10780         ;
10781       else if (unformat (i, "src_port %d", &src_port))
10782         ;
10783       else
10784         {
10785           errmsg ("unknown input `%U'", format_unformat_error, i);
10786           return -99;
10787         }
10788     }
10789
10790   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10791
10792   mp->domain_id = htonl (domain_id);
10793   mp->src_port = htons ((u16) src_port);
10794
10795   S (mp);
10796   W (ret);
10797   return ret;
10798 }
10799
10800 static int
10801 api_ipfix_classify_table_add_del (vat_main_t * vam)
10802 {
10803   unformat_input_t *i = vam->input;
10804   vl_api_ipfix_classify_table_add_del_t *mp;
10805   int is_add = -1;
10806   u32 classify_table_index = ~0;
10807   u8 ip_version = 0;
10808   u8 transport_protocol = 255;
10809   int ret;
10810
10811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10812     {
10813       if (unformat (i, "add"))
10814         is_add = 1;
10815       else if (unformat (i, "del"))
10816         is_add = 0;
10817       else if (unformat (i, "table %d", &classify_table_index))
10818         ;
10819       else if (unformat (i, "ip4"))
10820         ip_version = 4;
10821       else if (unformat (i, "ip6"))
10822         ip_version = 6;
10823       else if (unformat (i, "tcp"))
10824         transport_protocol = 6;
10825       else if (unformat (i, "udp"))
10826         transport_protocol = 17;
10827       else
10828         {
10829           errmsg ("unknown input `%U'", format_unformat_error, i);
10830           return -99;
10831         }
10832     }
10833
10834   if (is_add == -1)
10835     {
10836       errmsg ("expecting: add|del");
10837       return -99;
10838     }
10839   if (classify_table_index == ~0)
10840     {
10841       errmsg ("classifier table not specified");
10842       return -99;
10843     }
10844   if (ip_version == 0)
10845     {
10846       errmsg ("IP version not specified");
10847       return -99;
10848     }
10849
10850   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10851
10852   mp->is_add = is_add;
10853   mp->table_id = htonl (classify_table_index);
10854   mp->ip_version = ip_version;
10855   mp->transport_protocol = transport_protocol;
10856
10857   S (mp);
10858   W (ret);
10859   return ret;
10860 }
10861
10862 static int
10863 api_get_node_index (vat_main_t * vam)
10864 {
10865   unformat_input_t *i = vam->input;
10866   vl_api_get_node_index_t *mp;
10867   u8 *name = 0;
10868   int ret;
10869
10870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10871     {
10872       if (unformat (i, "node %s", &name))
10873         ;
10874       else
10875         break;
10876     }
10877   if (name == 0)
10878     {
10879       errmsg ("node name required");
10880       return -99;
10881     }
10882   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10883     {
10884       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10885       return -99;
10886     }
10887
10888   M (GET_NODE_INDEX, mp);
10889   clib_memcpy (mp->node_name, name, vec_len (name));
10890   vec_free (name);
10891
10892   S (mp);
10893   W (ret);
10894   return ret;
10895 }
10896
10897 static int
10898 api_get_next_index (vat_main_t * vam)
10899 {
10900   unformat_input_t *i = vam->input;
10901   vl_api_get_next_index_t *mp;
10902   u8 *node_name = 0, *next_node_name = 0;
10903   int ret;
10904
10905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10906     {
10907       if (unformat (i, "node-name %s", &node_name))
10908         ;
10909       else if (unformat (i, "next-node-name %s", &next_node_name))
10910         break;
10911     }
10912
10913   if (node_name == 0)
10914     {
10915       errmsg ("node name required");
10916       return -99;
10917     }
10918   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10919     {
10920       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10921       return -99;
10922     }
10923
10924   if (next_node_name == 0)
10925     {
10926       errmsg ("next node name required");
10927       return -99;
10928     }
10929   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10930     {
10931       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10932       return -99;
10933     }
10934
10935   M (GET_NEXT_INDEX, mp);
10936   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10937   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10938   vec_free (node_name);
10939   vec_free (next_node_name);
10940
10941   S (mp);
10942   W (ret);
10943   return ret;
10944 }
10945
10946 static int
10947 api_add_node_next (vat_main_t * vam)
10948 {
10949   unformat_input_t *i = vam->input;
10950   vl_api_add_node_next_t *mp;
10951   u8 *name = 0;
10952   u8 *next = 0;
10953   int ret;
10954
10955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10956     {
10957       if (unformat (i, "node %s", &name))
10958         ;
10959       else if (unformat (i, "next %s", &next))
10960         ;
10961       else
10962         break;
10963     }
10964   if (name == 0)
10965     {
10966       errmsg ("node name required");
10967       return -99;
10968     }
10969   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10970     {
10971       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10972       return -99;
10973     }
10974   if (next == 0)
10975     {
10976       errmsg ("next node required");
10977       return -99;
10978     }
10979   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10980     {
10981       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10982       return -99;
10983     }
10984
10985   M (ADD_NODE_NEXT, mp);
10986   clib_memcpy (mp->node_name, name, vec_len (name));
10987   clib_memcpy (mp->next_name, next, vec_len (next));
10988   vec_free (name);
10989   vec_free (next);
10990
10991   S (mp);
10992   W (ret);
10993   return ret;
10994 }
10995
10996 static int
10997 api_l2tpv3_create_tunnel (vat_main_t * vam)
10998 {
10999   unformat_input_t *i = vam->input;
11000   ip6_address_t client_address, our_address;
11001   int client_address_set = 0;
11002   int our_address_set = 0;
11003   u32 local_session_id = 0;
11004   u32 remote_session_id = 0;
11005   u64 local_cookie = 0;
11006   u64 remote_cookie = 0;
11007   u8 l2_sublayer_present = 0;
11008   vl_api_l2tpv3_create_tunnel_t *mp;
11009   int ret;
11010
11011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11012     {
11013       if (unformat (i, "client_address %U", unformat_ip6_address,
11014                     &client_address))
11015         client_address_set = 1;
11016       else if (unformat (i, "our_address %U", unformat_ip6_address,
11017                          &our_address))
11018         our_address_set = 1;
11019       else if (unformat (i, "local_session_id %d", &local_session_id))
11020         ;
11021       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11022         ;
11023       else if (unformat (i, "local_cookie %lld", &local_cookie))
11024         ;
11025       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11026         ;
11027       else if (unformat (i, "l2-sublayer-present"))
11028         l2_sublayer_present = 1;
11029       else
11030         break;
11031     }
11032
11033   if (client_address_set == 0)
11034     {
11035       errmsg ("client_address required");
11036       return -99;
11037     }
11038
11039   if (our_address_set == 0)
11040     {
11041       errmsg ("our_address required");
11042       return -99;
11043     }
11044
11045   M (L2TPV3_CREATE_TUNNEL, mp);
11046
11047   clib_memcpy (mp->client_address, client_address.as_u8,
11048                sizeof (mp->client_address));
11049
11050   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11051
11052   mp->local_session_id = ntohl (local_session_id);
11053   mp->remote_session_id = ntohl (remote_session_id);
11054   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11055   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11056   mp->l2_sublayer_present = l2_sublayer_present;
11057   mp->is_ipv6 = 1;
11058
11059   S (mp);
11060   W (ret);
11061   return ret;
11062 }
11063
11064 static int
11065 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11066 {
11067   unformat_input_t *i = vam->input;
11068   u32 sw_if_index;
11069   u8 sw_if_index_set = 0;
11070   u64 new_local_cookie = 0;
11071   u64 new_remote_cookie = 0;
11072   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11073   int ret;
11074
11075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11076     {
11077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11078         sw_if_index_set = 1;
11079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11080         sw_if_index_set = 1;
11081       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11082         ;
11083       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11084         ;
11085       else
11086         break;
11087     }
11088
11089   if (sw_if_index_set == 0)
11090     {
11091       errmsg ("missing interface name or sw_if_index");
11092       return -99;
11093     }
11094
11095   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11096
11097   mp->sw_if_index = ntohl (sw_if_index);
11098   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11099   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11100
11101   S (mp);
11102   W (ret);
11103   return ret;
11104 }
11105
11106 static int
11107 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11108 {
11109   unformat_input_t *i = vam->input;
11110   vl_api_l2tpv3_interface_enable_disable_t *mp;
11111   u32 sw_if_index;
11112   u8 sw_if_index_set = 0;
11113   u8 enable_disable = 1;
11114   int ret;
11115
11116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11117     {
11118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11119         sw_if_index_set = 1;
11120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11121         sw_if_index_set = 1;
11122       else if (unformat (i, "enable"))
11123         enable_disable = 1;
11124       else if (unformat (i, "disable"))
11125         enable_disable = 0;
11126       else
11127         break;
11128     }
11129
11130   if (sw_if_index_set == 0)
11131     {
11132       errmsg ("missing interface name or sw_if_index");
11133       return -99;
11134     }
11135
11136   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11137
11138   mp->sw_if_index = ntohl (sw_if_index);
11139   mp->enable_disable = enable_disable;
11140
11141   S (mp);
11142   W (ret);
11143   return ret;
11144 }
11145
11146 static int
11147 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11148 {
11149   unformat_input_t *i = vam->input;
11150   vl_api_l2tpv3_set_lookup_key_t *mp;
11151   u8 key = ~0;
11152   int ret;
11153
11154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11155     {
11156       if (unformat (i, "lookup_v6_src"))
11157         key = L2T_LOOKUP_SRC_ADDRESS;
11158       else if (unformat (i, "lookup_v6_dst"))
11159         key = L2T_LOOKUP_DST_ADDRESS;
11160       else if (unformat (i, "lookup_session_id"))
11161         key = L2T_LOOKUP_SESSION_ID;
11162       else
11163         break;
11164     }
11165
11166   if (key == (u8) ~ 0)
11167     {
11168       errmsg ("l2tp session lookup key unset");
11169       return -99;
11170     }
11171
11172   M (L2TPV3_SET_LOOKUP_KEY, mp);
11173
11174   mp->key = key;
11175
11176   S (mp);
11177   W (ret);
11178   return ret;
11179 }
11180
11181 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11182   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11183 {
11184   vat_main_t *vam = &vat_main;
11185
11186   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11187          format_ip6_address, mp->our_address,
11188          format_ip6_address, mp->client_address,
11189          clib_net_to_host_u32 (mp->sw_if_index));
11190
11191   print (vam->ofp,
11192          "   local cookies %016llx %016llx remote cookie %016llx",
11193          clib_net_to_host_u64 (mp->local_cookie[0]),
11194          clib_net_to_host_u64 (mp->local_cookie[1]),
11195          clib_net_to_host_u64 (mp->remote_cookie));
11196
11197   print (vam->ofp, "   local session-id %d remote session-id %d",
11198          clib_net_to_host_u32 (mp->local_session_id),
11199          clib_net_to_host_u32 (mp->remote_session_id));
11200
11201   print (vam->ofp, "   l2 specific sublayer %s\n",
11202          mp->l2_sublayer_present ? "preset" : "absent");
11203
11204 }
11205
11206 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11207   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11208 {
11209   vat_main_t *vam = &vat_main;
11210   vat_json_node_t *node = NULL;
11211   struct in6_addr addr;
11212
11213   if (VAT_JSON_ARRAY != vam->json_tree.type)
11214     {
11215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11216       vat_json_init_array (&vam->json_tree);
11217     }
11218   node = vat_json_array_add (&vam->json_tree);
11219
11220   vat_json_init_object (node);
11221
11222   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11223   vat_json_object_add_ip6 (node, "our_address", addr);
11224   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11225   vat_json_object_add_ip6 (node, "client_address", addr);
11226
11227   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11228   vat_json_init_array (lc);
11229   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11230   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11231   vat_json_object_add_uint (node, "remote_cookie",
11232                             clib_net_to_host_u64 (mp->remote_cookie));
11233
11234   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11235   vat_json_object_add_uint (node, "local_session_id",
11236                             clib_net_to_host_u32 (mp->local_session_id));
11237   vat_json_object_add_uint (node, "remote_session_id",
11238                             clib_net_to_host_u32 (mp->remote_session_id));
11239   vat_json_object_add_string_copy (node, "l2_sublayer",
11240                                    mp->l2_sublayer_present ? (u8 *) "present"
11241                                    : (u8 *) "absent");
11242 }
11243
11244 static int
11245 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11246 {
11247   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11248   vl_api_control_ping_t *mp_ping;
11249   int ret;
11250
11251   /* Get list of l2tpv3-tunnel interfaces */
11252   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11253   S (mp);
11254
11255   /* Use a control ping for synchronization */
11256   M (CONTROL_PING, mp_ping);
11257   S (mp_ping);
11258
11259   W (ret);
11260   return ret;
11261 }
11262
11263
11264 static void vl_api_sw_interface_tap_details_t_handler
11265   (vl_api_sw_interface_tap_details_t * mp)
11266 {
11267   vat_main_t *vam = &vat_main;
11268
11269   print (vam->ofp, "%-16s %d",
11270          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11271 }
11272
11273 static void vl_api_sw_interface_tap_details_t_handler_json
11274   (vl_api_sw_interface_tap_details_t * mp)
11275 {
11276   vat_main_t *vam = &vat_main;
11277   vat_json_node_t *node = NULL;
11278
11279   if (VAT_JSON_ARRAY != vam->json_tree.type)
11280     {
11281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11282       vat_json_init_array (&vam->json_tree);
11283     }
11284   node = vat_json_array_add (&vam->json_tree);
11285
11286   vat_json_init_object (node);
11287   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11288   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11289 }
11290
11291 static int
11292 api_sw_interface_tap_dump (vat_main_t * vam)
11293 {
11294   vl_api_sw_interface_tap_dump_t *mp;
11295   vl_api_control_ping_t *mp_ping;
11296   int ret;
11297
11298   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11299   /* Get list of tap interfaces */
11300   M (SW_INTERFACE_TAP_DUMP, mp);
11301   S (mp);
11302
11303   /* Use a control ping for synchronization */
11304   M (CONTROL_PING, mp_ping);
11305   S (mp_ping);
11306
11307   W (ret);
11308   return ret;
11309 }
11310
11311 static uword unformat_vxlan_decap_next
11312   (unformat_input_t * input, va_list * args)
11313 {
11314   u32 *result = va_arg (*args, u32 *);
11315   u32 tmp;
11316
11317   if (unformat (input, "l2"))
11318     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11319   else if (unformat (input, "%d", &tmp))
11320     *result = tmp;
11321   else
11322     return 0;
11323   return 1;
11324 }
11325
11326 static int
11327 api_vxlan_add_del_tunnel (vat_main_t * vam)
11328 {
11329   unformat_input_t *line_input = vam->input;
11330   vl_api_vxlan_add_del_tunnel_t *mp;
11331   ip46_address_t src, dst;
11332   u8 is_add = 1;
11333   u8 ipv4_set = 0, ipv6_set = 0;
11334   u8 src_set = 0;
11335   u8 dst_set = 0;
11336   u8 grp_set = 0;
11337   u32 mcast_sw_if_index = ~0;
11338   u32 encap_vrf_id = 0;
11339   u32 decap_next_index = ~0;
11340   u32 vni = 0;
11341   int ret;
11342
11343   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11344   memset (&src, 0, sizeof src);
11345   memset (&dst, 0, sizeof dst);
11346
11347   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11348     {
11349       if (unformat (line_input, "del"))
11350         is_add = 0;
11351       else
11352         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11353         {
11354           ipv4_set = 1;
11355           src_set = 1;
11356         }
11357       else
11358         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11359         {
11360           ipv4_set = 1;
11361           dst_set = 1;
11362         }
11363       else
11364         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11365         {
11366           ipv6_set = 1;
11367           src_set = 1;
11368         }
11369       else
11370         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11371         {
11372           ipv6_set = 1;
11373           dst_set = 1;
11374         }
11375       else if (unformat (line_input, "group %U %U",
11376                          unformat_ip4_address, &dst.ip4,
11377                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11378         {
11379           grp_set = dst_set = 1;
11380           ipv4_set = 1;
11381         }
11382       else if (unformat (line_input, "group %U",
11383                          unformat_ip4_address, &dst.ip4))
11384         {
11385           grp_set = dst_set = 1;
11386           ipv4_set = 1;
11387         }
11388       else if (unformat (line_input, "group %U %U",
11389                          unformat_ip6_address, &dst.ip6,
11390                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11391         {
11392           grp_set = dst_set = 1;
11393           ipv6_set = 1;
11394         }
11395       else if (unformat (line_input, "group %U",
11396                          unformat_ip6_address, &dst.ip6))
11397         {
11398           grp_set = dst_set = 1;
11399           ipv6_set = 1;
11400         }
11401       else
11402         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11403         ;
11404       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11405         ;
11406       else if (unformat (line_input, "decap-next %U",
11407                          unformat_vxlan_decap_next, &decap_next_index))
11408         ;
11409       else if (unformat (line_input, "vni %d", &vni))
11410         ;
11411       else
11412         {
11413           errmsg ("parse error '%U'", format_unformat_error, line_input);
11414           return -99;
11415         }
11416     }
11417
11418   if (src_set == 0)
11419     {
11420       errmsg ("tunnel src address not specified");
11421       return -99;
11422     }
11423   if (dst_set == 0)
11424     {
11425       errmsg ("tunnel dst address not specified");
11426       return -99;
11427     }
11428
11429   if (grp_set && !ip46_address_is_multicast (&dst))
11430     {
11431       errmsg ("tunnel group address not multicast");
11432       return -99;
11433     }
11434   if (grp_set && mcast_sw_if_index == ~0)
11435     {
11436       errmsg ("tunnel nonexistent multicast device");
11437       return -99;
11438     }
11439   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11440     {
11441       errmsg ("tunnel dst address must be unicast");
11442       return -99;
11443     }
11444
11445
11446   if (ipv4_set && ipv6_set)
11447     {
11448       errmsg ("both IPv4 and IPv6 addresses specified");
11449       return -99;
11450     }
11451
11452   if ((vni == 0) || (vni >> 24))
11453     {
11454       errmsg ("vni not specified or out of range");
11455       return -99;
11456     }
11457
11458   M (VXLAN_ADD_DEL_TUNNEL, mp);
11459
11460   if (ipv6_set)
11461     {
11462       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11463       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11464     }
11465   else
11466     {
11467       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11468       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11469     }
11470   mp->encap_vrf_id = ntohl (encap_vrf_id);
11471   mp->decap_next_index = ntohl (decap_next_index);
11472   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11473   mp->vni = ntohl (vni);
11474   mp->is_add = is_add;
11475   mp->is_ipv6 = ipv6_set;
11476
11477   S (mp);
11478   W (ret);
11479   return ret;
11480 }
11481
11482 static void vl_api_vxlan_tunnel_details_t_handler
11483   (vl_api_vxlan_tunnel_details_t * mp)
11484 {
11485   vat_main_t *vam = &vat_main;
11486   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11487   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11488
11489   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11490          ntohl (mp->sw_if_index),
11491          format_ip46_address, &src, IP46_TYPE_ANY,
11492          format_ip46_address, &dst, IP46_TYPE_ANY,
11493          ntohl (mp->encap_vrf_id),
11494          ntohl (mp->decap_next_index), ntohl (mp->vni),
11495          ntohl (mp->mcast_sw_if_index));
11496 }
11497
11498 static void vl_api_vxlan_tunnel_details_t_handler_json
11499   (vl_api_vxlan_tunnel_details_t * mp)
11500 {
11501   vat_main_t *vam = &vat_main;
11502   vat_json_node_t *node = NULL;
11503
11504   if (VAT_JSON_ARRAY != vam->json_tree.type)
11505     {
11506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11507       vat_json_init_array (&vam->json_tree);
11508     }
11509   node = vat_json_array_add (&vam->json_tree);
11510
11511   vat_json_init_object (node);
11512   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11513   if (mp->is_ipv6)
11514     {
11515       struct in6_addr ip6;
11516
11517       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11518       vat_json_object_add_ip6 (node, "src_address", ip6);
11519       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11520       vat_json_object_add_ip6 (node, "dst_address", ip6);
11521     }
11522   else
11523     {
11524       struct in_addr ip4;
11525
11526       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11527       vat_json_object_add_ip4 (node, "src_address", ip4);
11528       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11529       vat_json_object_add_ip4 (node, "dst_address", ip4);
11530     }
11531   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11532   vat_json_object_add_uint (node, "decap_next_index",
11533                             ntohl (mp->decap_next_index));
11534   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11535   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11536   vat_json_object_add_uint (node, "mcast_sw_if_index",
11537                             ntohl (mp->mcast_sw_if_index));
11538 }
11539
11540 static int
11541 api_vxlan_tunnel_dump (vat_main_t * vam)
11542 {
11543   unformat_input_t *i = vam->input;
11544   vl_api_vxlan_tunnel_dump_t *mp;
11545   vl_api_control_ping_t *mp_ping;
11546   u32 sw_if_index;
11547   u8 sw_if_index_set = 0;
11548   int ret;
11549
11550   /* Parse args required to build the message */
11551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11552     {
11553       if (unformat (i, "sw_if_index %d", &sw_if_index))
11554         sw_if_index_set = 1;
11555       else
11556         break;
11557     }
11558
11559   if (sw_if_index_set == 0)
11560     {
11561       sw_if_index = ~0;
11562     }
11563
11564   if (!vam->json_output)
11565     {
11566       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11567              "sw_if_index", "src_address", "dst_address",
11568              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11569     }
11570
11571   /* Get list of vxlan-tunnel interfaces */
11572   M (VXLAN_TUNNEL_DUMP, mp);
11573
11574   mp->sw_if_index = htonl (sw_if_index);
11575
11576   S (mp);
11577
11578   /* Use a control ping for synchronization */
11579   M (CONTROL_PING, mp_ping);
11580   S (mp_ping);
11581
11582   W (ret);
11583   return ret;
11584 }
11585
11586 static int
11587 api_gre_add_del_tunnel (vat_main_t * vam)
11588 {
11589   unformat_input_t *line_input = vam->input;
11590   vl_api_gre_add_del_tunnel_t *mp;
11591   ip4_address_t src4, dst4;
11592   ip6_address_t src6, dst6;
11593   u8 is_add = 1;
11594   u8 ipv4_set = 0;
11595   u8 ipv6_set = 0;
11596   u8 teb = 0;
11597   u8 src_set = 0;
11598   u8 dst_set = 0;
11599   u32 outer_fib_id = 0;
11600   int ret;
11601
11602   memset (&src4, 0, sizeof src4);
11603   memset (&dst4, 0, sizeof dst4);
11604   memset (&src6, 0, sizeof src6);
11605   memset (&dst6, 0, sizeof dst6);
11606
11607   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11608     {
11609       if (unformat (line_input, "del"))
11610         is_add = 0;
11611       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11612         {
11613           src_set = 1;
11614           ipv4_set = 1;
11615         }
11616       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11617         {
11618           dst_set = 1;
11619           ipv4_set = 1;
11620         }
11621       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11622         {
11623           src_set = 1;
11624           ipv6_set = 1;
11625         }
11626       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11627         {
11628           dst_set = 1;
11629           ipv6_set = 1;
11630         }
11631       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11632         ;
11633       else if (unformat (line_input, "teb"))
11634         teb = 1;
11635       else
11636         {
11637           errmsg ("parse error '%U'", format_unformat_error, line_input);
11638           return -99;
11639         }
11640     }
11641
11642   if (src_set == 0)
11643     {
11644       errmsg ("tunnel src address not specified");
11645       return -99;
11646     }
11647   if (dst_set == 0)
11648     {
11649       errmsg ("tunnel dst address not specified");
11650       return -99;
11651     }
11652   if (ipv4_set && ipv6_set)
11653     {
11654       errmsg ("both IPv4 and IPv6 addresses specified");
11655       return -99;
11656     }
11657
11658
11659   M (GRE_ADD_DEL_TUNNEL, mp);
11660
11661   if (ipv4_set)
11662     {
11663       clib_memcpy (&mp->src_address, &src4, 4);
11664       clib_memcpy (&mp->dst_address, &dst4, 4);
11665     }
11666   else
11667     {
11668       clib_memcpy (&mp->src_address, &src6, 16);
11669       clib_memcpy (&mp->dst_address, &dst6, 16);
11670     }
11671   mp->outer_fib_id = ntohl (outer_fib_id);
11672   mp->is_add = is_add;
11673   mp->teb = teb;
11674   mp->is_ipv6 = ipv6_set;
11675
11676   S (mp);
11677   W (ret);
11678   return ret;
11679 }
11680
11681 static void vl_api_gre_tunnel_details_t_handler
11682   (vl_api_gre_tunnel_details_t * mp)
11683 {
11684   vat_main_t *vam = &vat_main;
11685   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11686   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11687
11688   print (vam->ofp, "%11d%24U%24U%6d%14d",
11689          ntohl (mp->sw_if_index),
11690          format_ip46_address, &src, IP46_TYPE_ANY,
11691          format_ip46_address, &dst, IP46_TYPE_ANY,
11692          mp->teb, ntohl (mp->outer_fib_id));
11693 }
11694
11695 static void vl_api_gre_tunnel_details_t_handler_json
11696   (vl_api_gre_tunnel_details_t * mp)
11697 {
11698   vat_main_t *vam = &vat_main;
11699   vat_json_node_t *node = NULL;
11700   struct in_addr ip4;
11701   struct in6_addr ip6;
11702
11703   if (VAT_JSON_ARRAY != vam->json_tree.type)
11704     {
11705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11706       vat_json_init_array (&vam->json_tree);
11707     }
11708   node = vat_json_array_add (&vam->json_tree);
11709
11710   vat_json_init_object (node);
11711   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11712   if (!mp->is_ipv6)
11713     {
11714       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11715       vat_json_object_add_ip4 (node, "src_address", ip4);
11716       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11717       vat_json_object_add_ip4 (node, "dst_address", ip4);
11718     }
11719   else
11720     {
11721       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11722       vat_json_object_add_ip6 (node, "src_address", ip6);
11723       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11724       vat_json_object_add_ip6 (node, "dst_address", ip6);
11725     }
11726   vat_json_object_add_uint (node, "teb", mp->teb);
11727   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11728   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11729 }
11730
11731 static int
11732 api_gre_tunnel_dump (vat_main_t * vam)
11733 {
11734   unformat_input_t *i = vam->input;
11735   vl_api_gre_tunnel_dump_t *mp;
11736   vl_api_control_ping_t *mp_ping;
11737   u32 sw_if_index;
11738   u8 sw_if_index_set = 0;
11739   int ret;
11740
11741   /* Parse args required to build the message */
11742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11743     {
11744       if (unformat (i, "sw_if_index %d", &sw_if_index))
11745         sw_if_index_set = 1;
11746       else
11747         break;
11748     }
11749
11750   if (sw_if_index_set == 0)
11751     {
11752       sw_if_index = ~0;
11753     }
11754
11755   if (!vam->json_output)
11756     {
11757       print (vam->ofp, "%11s%24s%24s%6s%14s",
11758              "sw_if_index", "src_address", "dst_address", "teb",
11759              "outer_fib_id");
11760     }
11761
11762   /* Get list of gre-tunnel interfaces */
11763   M (GRE_TUNNEL_DUMP, mp);
11764
11765   mp->sw_if_index = htonl (sw_if_index);
11766
11767   S (mp);
11768
11769   /* Use a control ping for synchronization */
11770   M (CONTROL_PING, mp_ping);
11771   S (mp_ping);
11772
11773   W (ret);
11774   return ret;
11775 }
11776
11777 static int
11778 api_l2_fib_clear_table (vat_main_t * vam)
11779 {
11780 //  unformat_input_t * i = vam->input;
11781   vl_api_l2_fib_clear_table_t *mp;
11782   int ret;
11783
11784   M (L2_FIB_CLEAR_TABLE, mp);
11785
11786   S (mp);
11787   W (ret);
11788   return ret;
11789 }
11790
11791 static int
11792 api_l2_interface_efp_filter (vat_main_t * vam)
11793 {
11794   unformat_input_t *i = vam->input;
11795   vl_api_l2_interface_efp_filter_t *mp;
11796   u32 sw_if_index;
11797   u8 enable = 1;
11798   u8 sw_if_index_set = 0;
11799   int ret;
11800
11801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11802     {
11803       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11804         sw_if_index_set = 1;
11805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11806         sw_if_index_set = 1;
11807       else if (unformat (i, "enable"))
11808         enable = 1;
11809       else if (unformat (i, "disable"))
11810         enable = 0;
11811       else
11812         {
11813           clib_warning ("parse error '%U'", format_unformat_error, i);
11814           return -99;
11815         }
11816     }
11817
11818   if (sw_if_index_set == 0)
11819     {
11820       errmsg ("missing sw_if_index");
11821       return -99;
11822     }
11823
11824   M (L2_INTERFACE_EFP_FILTER, mp);
11825
11826   mp->sw_if_index = ntohl (sw_if_index);
11827   mp->enable_disable = enable;
11828
11829   S (mp);
11830   W (ret);
11831   return ret;
11832 }
11833
11834 #define foreach_vtr_op                          \
11835 _("disable",  L2_VTR_DISABLED)                  \
11836 _("push-1",  L2_VTR_PUSH_1)                     \
11837 _("push-2",  L2_VTR_PUSH_2)                     \
11838 _("pop-1",  L2_VTR_POP_1)                       \
11839 _("pop-2",  L2_VTR_POP_2)                       \
11840 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11841 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11842 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11843 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11844
11845 static int
11846 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11847 {
11848   unformat_input_t *i = vam->input;
11849   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11850   u32 sw_if_index;
11851   u8 sw_if_index_set = 0;
11852   u8 vtr_op_set = 0;
11853   u32 vtr_op = 0;
11854   u32 push_dot1q = 1;
11855   u32 tag1 = ~0;
11856   u32 tag2 = ~0;
11857   int ret;
11858
11859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11860     {
11861       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11862         sw_if_index_set = 1;
11863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11864         sw_if_index_set = 1;
11865       else if (unformat (i, "vtr_op %d", &vtr_op))
11866         vtr_op_set = 1;
11867 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11868       foreach_vtr_op
11869 #undef _
11870         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11871         ;
11872       else if (unformat (i, "tag1 %d", &tag1))
11873         ;
11874       else if (unformat (i, "tag2 %d", &tag2))
11875         ;
11876       else
11877         {
11878           clib_warning ("parse error '%U'", format_unformat_error, i);
11879           return -99;
11880         }
11881     }
11882
11883   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11884     {
11885       errmsg ("missing vtr operation or sw_if_index");
11886       return -99;
11887     }
11888
11889   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11890   mp->sw_if_index = ntohl (sw_if_index);
11891   mp->vtr_op = ntohl (vtr_op);
11892   mp->push_dot1q = ntohl (push_dot1q);
11893   mp->tag1 = ntohl (tag1);
11894   mp->tag2 = ntohl (tag2);
11895
11896   S (mp);
11897   W (ret);
11898   return ret;
11899 }
11900
11901 static int
11902 api_create_vhost_user_if (vat_main_t * vam)
11903 {
11904   unformat_input_t *i = vam->input;
11905   vl_api_create_vhost_user_if_t *mp;
11906   u8 *file_name;
11907   u8 is_server = 0;
11908   u8 file_name_set = 0;
11909   u32 custom_dev_instance = ~0;
11910   u8 hwaddr[6];
11911   u8 use_custom_mac = 0;
11912   u8 *tag = 0;
11913   int ret;
11914
11915   /* Shut up coverity */
11916   memset (hwaddr, 0, sizeof (hwaddr));
11917
11918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11919     {
11920       if (unformat (i, "socket %s", &file_name))
11921         {
11922           file_name_set = 1;
11923         }
11924       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11925         ;
11926       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11927         use_custom_mac = 1;
11928       else if (unformat (i, "server"))
11929         is_server = 1;
11930       else if (unformat (i, "tag %s", &tag))
11931         ;
11932       else
11933         break;
11934     }
11935
11936   if (file_name_set == 0)
11937     {
11938       errmsg ("missing socket file name");
11939       return -99;
11940     }
11941
11942   if (vec_len (file_name) > 255)
11943     {
11944       errmsg ("socket file name too long");
11945       return -99;
11946     }
11947   vec_add1 (file_name, 0);
11948
11949   M (CREATE_VHOST_USER_IF, mp);
11950
11951   mp->is_server = is_server;
11952   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11953   vec_free (file_name);
11954   if (custom_dev_instance != ~0)
11955     {
11956       mp->renumber = 1;
11957       mp->custom_dev_instance = ntohl (custom_dev_instance);
11958     }
11959   mp->use_custom_mac = use_custom_mac;
11960   clib_memcpy (mp->mac_address, hwaddr, 6);
11961   if (tag)
11962     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11963   vec_free (tag);
11964
11965   S (mp);
11966   W (ret);
11967   return ret;
11968 }
11969
11970 static int
11971 api_modify_vhost_user_if (vat_main_t * vam)
11972 {
11973   unformat_input_t *i = vam->input;
11974   vl_api_modify_vhost_user_if_t *mp;
11975   u8 *file_name;
11976   u8 is_server = 0;
11977   u8 file_name_set = 0;
11978   u32 custom_dev_instance = ~0;
11979   u8 sw_if_index_set = 0;
11980   u32 sw_if_index = (u32) ~ 0;
11981   int ret;
11982
11983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11984     {
11985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11986         sw_if_index_set = 1;
11987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11988         sw_if_index_set = 1;
11989       else if (unformat (i, "socket %s", &file_name))
11990         {
11991           file_name_set = 1;
11992         }
11993       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11994         ;
11995       else if (unformat (i, "server"))
11996         is_server = 1;
11997       else
11998         break;
11999     }
12000
12001   if (sw_if_index_set == 0)
12002     {
12003       errmsg ("missing sw_if_index or interface name");
12004       return -99;
12005     }
12006
12007   if (file_name_set == 0)
12008     {
12009       errmsg ("missing socket file name");
12010       return -99;
12011     }
12012
12013   if (vec_len (file_name) > 255)
12014     {
12015       errmsg ("socket file name too long");
12016       return -99;
12017     }
12018   vec_add1 (file_name, 0);
12019
12020   M (MODIFY_VHOST_USER_IF, mp);
12021
12022   mp->sw_if_index = ntohl (sw_if_index);
12023   mp->is_server = is_server;
12024   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12025   vec_free (file_name);
12026   if (custom_dev_instance != ~0)
12027     {
12028       mp->renumber = 1;
12029       mp->custom_dev_instance = ntohl (custom_dev_instance);
12030     }
12031
12032   S (mp);
12033   W (ret);
12034   return ret;
12035 }
12036
12037 static int
12038 api_delete_vhost_user_if (vat_main_t * vam)
12039 {
12040   unformat_input_t *i = vam->input;
12041   vl_api_delete_vhost_user_if_t *mp;
12042   u32 sw_if_index = ~0;
12043   u8 sw_if_index_set = 0;
12044   int ret;
12045
12046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12047     {
12048       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12049         sw_if_index_set = 1;
12050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12051         sw_if_index_set = 1;
12052       else
12053         break;
12054     }
12055
12056   if (sw_if_index_set == 0)
12057     {
12058       errmsg ("missing sw_if_index or interface name");
12059       return -99;
12060     }
12061
12062
12063   M (DELETE_VHOST_USER_IF, mp);
12064
12065   mp->sw_if_index = ntohl (sw_if_index);
12066
12067   S (mp);
12068   W (ret);
12069   return ret;
12070 }
12071
12072 static void vl_api_sw_interface_vhost_user_details_t_handler
12073   (vl_api_sw_interface_vhost_user_details_t * mp)
12074 {
12075   vat_main_t *vam = &vat_main;
12076
12077   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12078          (char *) mp->interface_name,
12079          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12080          clib_net_to_host_u64 (mp->features), mp->is_server,
12081          ntohl (mp->num_regions), (char *) mp->sock_filename);
12082   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12083 }
12084
12085 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12086   (vl_api_sw_interface_vhost_user_details_t * mp)
12087 {
12088   vat_main_t *vam = &vat_main;
12089   vat_json_node_t *node = NULL;
12090
12091   if (VAT_JSON_ARRAY != vam->json_tree.type)
12092     {
12093       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12094       vat_json_init_array (&vam->json_tree);
12095     }
12096   node = vat_json_array_add (&vam->json_tree);
12097
12098   vat_json_init_object (node);
12099   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12100   vat_json_object_add_string_copy (node, "interface_name",
12101                                    mp->interface_name);
12102   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12103                             ntohl (mp->virtio_net_hdr_sz));
12104   vat_json_object_add_uint (node, "features",
12105                             clib_net_to_host_u64 (mp->features));
12106   vat_json_object_add_uint (node, "is_server", mp->is_server);
12107   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12108   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12109   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12110 }
12111
12112 static int
12113 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12114 {
12115   vl_api_sw_interface_vhost_user_dump_t *mp;
12116   vl_api_control_ping_t *mp_ping;
12117   int ret;
12118   print (vam->ofp,
12119          "Interface name            idx hdr_sz features server regions filename");
12120
12121   /* Get list of vhost-user interfaces */
12122   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12123   S (mp);
12124
12125   /* Use a control ping for synchronization */
12126   M (CONTROL_PING, mp_ping);
12127   S (mp_ping);
12128
12129   W (ret);
12130   return ret;
12131 }
12132
12133 static int
12134 api_show_version (vat_main_t * vam)
12135 {
12136   vl_api_show_version_t *mp;
12137   int ret;
12138
12139   M (SHOW_VERSION, mp);
12140
12141   S (mp);
12142   W (ret);
12143   return ret;
12144 }
12145
12146
12147 static int
12148 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12149 {
12150   unformat_input_t *line_input = vam->input;
12151   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12152   ip4_address_t local4, remote4;
12153   ip6_address_t local6, remote6;
12154   u8 is_add = 1;
12155   u8 ipv4_set = 0, ipv6_set = 0;
12156   u8 local_set = 0;
12157   u8 remote_set = 0;
12158   u8 grp_set = 0;
12159   u32 mcast_sw_if_index = ~0;
12160   u32 encap_vrf_id = 0;
12161   u32 decap_vrf_id = 0;
12162   u8 protocol = ~0;
12163   u32 vni;
12164   u8 vni_set = 0;
12165   int ret;
12166
12167   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12168   memset (&local4, 0, sizeof local4);
12169   memset (&remote4, 0, sizeof remote4);
12170   memset (&local6, 0, sizeof local6);
12171   memset (&remote6, 0, sizeof remote6);
12172
12173   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12174     {
12175       if (unformat (line_input, "del"))
12176         is_add = 0;
12177       else if (unformat (line_input, "local %U",
12178                          unformat_ip4_address, &local4))
12179         {
12180           local_set = 1;
12181           ipv4_set = 1;
12182         }
12183       else if (unformat (line_input, "remote %U",
12184                          unformat_ip4_address, &remote4))
12185         {
12186           remote_set = 1;
12187           ipv4_set = 1;
12188         }
12189       else if (unformat (line_input, "local %U",
12190                          unformat_ip6_address, &local6))
12191         {
12192           local_set = 1;
12193           ipv6_set = 1;
12194         }
12195       else if (unformat (line_input, "remote %U",
12196                          unformat_ip6_address, &remote6))
12197         {
12198           remote_set = 1;
12199           ipv6_set = 1;
12200         }
12201       else if (unformat (line_input, "group %U %U",
12202                          unformat_ip4_address, &remote4,
12203                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12204         {
12205           grp_set = remote_set = 1;
12206           ipv4_set = 1;
12207         }
12208       else if (unformat (line_input, "group %U",
12209                          unformat_ip4_address, &remote4))
12210         {
12211           grp_set = remote_set = 1;
12212           ipv4_set = 1;
12213         }
12214       else if (unformat (line_input, "group %U %U",
12215                          unformat_ip6_address, &remote6,
12216                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12217         {
12218           grp_set = remote_set = 1;
12219           ipv6_set = 1;
12220         }
12221       else if (unformat (line_input, "group %U",
12222                          unformat_ip6_address, &remote6))
12223         {
12224           grp_set = remote_set = 1;
12225           ipv6_set = 1;
12226         }
12227       else
12228         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12229         ;
12230       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12231         ;
12232       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12233         ;
12234       else if (unformat (line_input, "vni %d", &vni))
12235         vni_set = 1;
12236       else if (unformat (line_input, "next-ip4"))
12237         protocol = 1;
12238       else if (unformat (line_input, "next-ip6"))
12239         protocol = 2;
12240       else if (unformat (line_input, "next-ethernet"))
12241         protocol = 3;
12242       else if (unformat (line_input, "next-nsh"))
12243         protocol = 4;
12244       else
12245         {
12246           errmsg ("parse error '%U'", format_unformat_error, line_input);
12247           return -99;
12248         }
12249     }
12250
12251   if (local_set == 0)
12252     {
12253       errmsg ("tunnel local address not specified");
12254       return -99;
12255     }
12256   if (remote_set == 0)
12257     {
12258       errmsg ("tunnel remote address not specified");
12259       return -99;
12260     }
12261   if (grp_set && mcast_sw_if_index == ~0)
12262     {
12263       errmsg ("tunnel nonexistent multicast device");
12264       return -99;
12265     }
12266   if (ipv4_set && ipv6_set)
12267     {
12268       errmsg ("both IPv4 and IPv6 addresses specified");
12269       return -99;
12270     }
12271
12272   if (vni_set == 0)
12273     {
12274       errmsg ("vni not specified");
12275       return -99;
12276     }
12277
12278   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12279
12280
12281   if (ipv6_set)
12282     {
12283       clib_memcpy (&mp->local, &local6, sizeof (local6));
12284       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12285     }
12286   else
12287     {
12288       clib_memcpy (&mp->local, &local4, sizeof (local4));
12289       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12290     }
12291
12292   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12293   mp->encap_vrf_id = ntohl (encap_vrf_id);
12294   mp->decap_vrf_id = ntohl (decap_vrf_id);
12295   mp->protocol = protocol;
12296   mp->vni = ntohl (vni);
12297   mp->is_add = is_add;
12298   mp->is_ipv6 = ipv6_set;
12299
12300   S (mp);
12301   W (ret);
12302   return ret;
12303 }
12304
12305 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12306   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12307 {
12308   vat_main_t *vam = &vat_main;
12309   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12310   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12311
12312   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12313          ntohl (mp->sw_if_index),
12314          format_ip46_address, &local, IP46_TYPE_ANY,
12315          format_ip46_address, &remote, IP46_TYPE_ANY,
12316          ntohl (mp->vni), mp->protocol,
12317          ntohl (mp->mcast_sw_if_index),
12318          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12319 }
12320
12321
12322 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12323   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12324 {
12325   vat_main_t *vam = &vat_main;
12326   vat_json_node_t *node = NULL;
12327   struct in_addr ip4;
12328   struct in6_addr ip6;
12329
12330   if (VAT_JSON_ARRAY != vam->json_tree.type)
12331     {
12332       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12333       vat_json_init_array (&vam->json_tree);
12334     }
12335   node = vat_json_array_add (&vam->json_tree);
12336
12337   vat_json_init_object (node);
12338   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12339   if (mp->is_ipv6)
12340     {
12341       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12342       vat_json_object_add_ip6 (node, "local", ip6);
12343       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12344       vat_json_object_add_ip6 (node, "remote", ip6);
12345     }
12346   else
12347     {
12348       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12349       vat_json_object_add_ip4 (node, "local", ip4);
12350       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12351       vat_json_object_add_ip4 (node, "remote", ip4);
12352     }
12353   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12354   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12355   vat_json_object_add_uint (node, "mcast_sw_if_index",
12356                             ntohl (mp->mcast_sw_if_index));
12357   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12358   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12359   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12360 }
12361
12362 static int
12363 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12364 {
12365   unformat_input_t *i = vam->input;
12366   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12367   vl_api_control_ping_t *mp_ping;
12368   u32 sw_if_index;
12369   u8 sw_if_index_set = 0;
12370   int ret;
12371
12372   /* Parse args required to build the message */
12373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12374     {
12375       if (unformat (i, "sw_if_index %d", &sw_if_index))
12376         sw_if_index_set = 1;
12377       else
12378         break;
12379     }
12380
12381   if (sw_if_index_set == 0)
12382     {
12383       sw_if_index = ~0;
12384     }
12385
12386   if (!vam->json_output)
12387     {
12388       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12389              "sw_if_index", "local", "remote", "vni",
12390              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12391     }
12392
12393   /* Get list of vxlan-tunnel interfaces */
12394   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12395
12396   mp->sw_if_index = htonl (sw_if_index);
12397
12398   S (mp);
12399
12400   /* Use a control ping for synchronization */
12401   M (CONTROL_PING, mp_ping);
12402   S (mp_ping);
12403
12404   W (ret);
12405   return ret;
12406 }
12407
12408
12409 u8 *
12410 format_l2_fib_mac_address (u8 * s, va_list * args)
12411 {
12412   u8 *a = va_arg (*args, u8 *);
12413
12414   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12415                  a[2], a[3], a[4], a[5], a[6], a[7]);
12416 }
12417
12418 static void vl_api_l2_fib_table_details_t_handler
12419   (vl_api_l2_fib_table_details_t * mp)
12420 {
12421   vat_main_t *vam = &vat_main;
12422
12423   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12424          "       %d       %d     %d",
12425          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12426          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12427          mp->bvi_mac);
12428 }
12429
12430 static void vl_api_l2_fib_table_details_t_handler_json
12431   (vl_api_l2_fib_table_details_t * mp)
12432 {
12433   vat_main_t *vam = &vat_main;
12434   vat_json_node_t *node = NULL;
12435
12436   if (VAT_JSON_ARRAY != vam->json_tree.type)
12437     {
12438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12439       vat_json_init_array (&vam->json_tree);
12440     }
12441   node = vat_json_array_add (&vam->json_tree);
12442
12443   vat_json_init_object (node);
12444   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12445   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12446   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12447   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12448   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12449   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12450 }
12451
12452 static int
12453 api_l2_fib_table_dump (vat_main_t * vam)
12454 {
12455   unformat_input_t *i = vam->input;
12456   vl_api_l2_fib_table_dump_t *mp;
12457   vl_api_control_ping_t *mp_ping;
12458   u32 bd_id;
12459   u8 bd_id_set = 0;
12460   int ret;
12461
12462   /* Parse args required to build the message */
12463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12464     {
12465       if (unformat (i, "bd_id %d", &bd_id))
12466         bd_id_set = 1;
12467       else
12468         break;
12469     }
12470
12471   if (bd_id_set == 0)
12472     {
12473       errmsg ("missing bridge domain");
12474       return -99;
12475     }
12476
12477   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12478
12479   /* Get list of l2 fib entries */
12480   M (L2_FIB_TABLE_DUMP, mp);
12481
12482   mp->bd_id = ntohl (bd_id);
12483   S (mp);
12484
12485   /* Use a control ping for synchronization */
12486   M (CONTROL_PING, mp_ping);
12487   S (mp_ping);
12488
12489   W (ret);
12490   return ret;
12491 }
12492
12493
12494 static int
12495 api_interface_name_renumber (vat_main_t * vam)
12496 {
12497   unformat_input_t *line_input = vam->input;
12498   vl_api_interface_name_renumber_t *mp;
12499   u32 sw_if_index = ~0;
12500   u32 new_show_dev_instance = ~0;
12501   int ret;
12502
12503   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12504     {
12505       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12506                     &sw_if_index))
12507         ;
12508       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12509         ;
12510       else if (unformat (line_input, "new_show_dev_instance %d",
12511                          &new_show_dev_instance))
12512         ;
12513       else
12514         break;
12515     }
12516
12517   if (sw_if_index == ~0)
12518     {
12519       errmsg ("missing interface name or sw_if_index");
12520       return -99;
12521     }
12522
12523   if (new_show_dev_instance == ~0)
12524     {
12525       errmsg ("missing new_show_dev_instance");
12526       return -99;
12527     }
12528
12529   M (INTERFACE_NAME_RENUMBER, mp);
12530
12531   mp->sw_if_index = ntohl (sw_if_index);
12532   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12533
12534   S (mp);
12535   W (ret);
12536   return ret;
12537 }
12538
12539 static int
12540 api_want_ip4_arp_events (vat_main_t * vam)
12541 {
12542   unformat_input_t *line_input = vam->input;
12543   vl_api_want_ip4_arp_events_t *mp;
12544   ip4_address_t address;
12545   int address_set = 0;
12546   u32 enable_disable = 1;
12547   int ret;
12548
12549   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12550     {
12551       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12552         address_set = 1;
12553       else if (unformat (line_input, "del"))
12554         enable_disable = 0;
12555       else
12556         break;
12557     }
12558
12559   if (address_set == 0)
12560     {
12561       errmsg ("missing addresses");
12562       return -99;
12563     }
12564
12565   M (WANT_IP4_ARP_EVENTS, mp);
12566   mp->enable_disable = enable_disable;
12567   mp->pid = htonl (getpid ());
12568   mp->address = address.as_u32;
12569
12570   S (mp);
12571   W (ret);
12572   return ret;
12573 }
12574
12575 static int
12576 api_want_ip6_nd_events (vat_main_t * vam)
12577 {
12578   unformat_input_t *line_input = vam->input;
12579   vl_api_want_ip6_nd_events_t *mp;
12580   ip6_address_t address;
12581   int address_set = 0;
12582   u32 enable_disable = 1;
12583   int ret;
12584
12585   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12586     {
12587       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12588         address_set = 1;
12589       else if (unformat (line_input, "del"))
12590         enable_disable = 0;
12591       else
12592         break;
12593     }
12594
12595   if (address_set == 0)
12596     {
12597       errmsg ("missing addresses");
12598       return -99;
12599     }
12600
12601   M (WANT_IP6_ND_EVENTS, mp);
12602   mp->enable_disable = enable_disable;
12603   mp->pid = htonl (getpid ());
12604   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12605
12606   S (mp);
12607   W (ret);
12608   return ret;
12609 }
12610
12611 static int
12612 api_want_l2_macs_events (vat_main_t * vam)
12613 {
12614   unformat_input_t *line_input = vam->input;
12615   vl_api_want_l2_macs_events_t *mp;
12616   u8 enable_disable = 1;
12617   u32 scan_delay = 0;
12618   u32 max_macs_in_event = 0;
12619   u32 learn_limit = 0;
12620   int ret;
12621
12622   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12623     {
12624       if (unformat (line_input, "learn-limit %d", &learn_limit))
12625         ;
12626       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12627         ;
12628       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12629         ;
12630       else if (unformat (line_input, "disable"))
12631         enable_disable = 0;
12632       else
12633         break;
12634     }
12635
12636   M (WANT_L2_MACS_EVENTS, mp);
12637   mp->enable_disable = enable_disable;
12638   mp->pid = htonl (getpid ());
12639   mp->learn_limit = htonl (learn_limit);
12640   mp->scan_delay = (u8) scan_delay;
12641   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12642   S (mp);
12643   W (ret);
12644   return ret;
12645 }
12646
12647 static int
12648 api_input_acl_set_interface (vat_main_t * vam)
12649 {
12650   unformat_input_t *i = vam->input;
12651   vl_api_input_acl_set_interface_t *mp;
12652   u32 sw_if_index;
12653   int sw_if_index_set;
12654   u32 ip4_table_index = ~0;
12655   u32 ip6_table_index = ~0;
12656   u32 l2_table_index = ~0;
12657   u8 is_add = 1;
12658   int ret;
12659
12660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12661     {
12662       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12663         sw_if_index_set = 1;
12664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12665         sw_if_index_set = 1;
12666       else if (unformat (i, "del"))
12667         is_add = 0;
12668       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12669         ;
12670       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12671         ;
12672       else if (unformat (i, "l2-table %d", &l2_table_index))
12673         ;
12674       else
12675         {
12676           clib_warning ("parse error '%U'", format_unformat_error, i);
12677           return -99;
12678         }
12679     }
12680
12681   if (sw_if_index_set == 0)
12682     {
12683       errmsg ("missing interface name or sw_if_index");
12684       return -99;
12685     }
12686
12687   M (INPUT_ACL_SET_INTERFACE, mp);
12688
12689   mp->sw_if_index = ntohl (sw_if_index);
12690   mp->ip4_table_index = ntohl (ip4_table_index);
12691   mp->ip6_table_index = ntohl (ip6_table_index);
12692   mp->l2_table_index = ntohl (l2_table_index);
12693   mp->is_add = is_add;
12694
12695   S (mp);
12696   W (ret);
12697   return ret;
12698 }
12699
12700 static int
12701 api_ip_address_dump (vat_main_t * vam)
12702 {
12703   unformat_input_t *i = vam->input;
12704   vl_api_ip_address_dump_t *mp;
12705   vl_api_control_ping_t *mp_ping;
12706   u32 sw_if_index = ~0;
12707   u8 sw_if_index_set = 0;
12708   u8 ipv4_set = 0;
12709   u8 ipv6_set = 0;
12710   int ret;
12711
12712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12713     {
12714       if (unformat (i, "sw_if_index %d", &sw_if_index))
12715         sw_if_index_set = 1;
12716       else
12717         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12718         sw_if_index_set = 1;
12719       else if (unformat (i, "ipv4"))
12720         ipv4_set = 1;
12721       else if (unformat (i, "ipv6"))
12722         ipv6_set = 1;
12723       else
12724         break;
12725     }
12726
12727   if (ipv4_set && ipv6_set)
12728     {
12729       errmsg ("ipv4 and ipv6 flags cannot be both set");
12730       return -99;
12731     }
12732
12733   if ((!ipv4_set) && (!ipv6_set))
12734     {
12735       errmsg ("no ipv4 nor ipv6 flag set");
12736       return -99;
12737     }
12738
12739   if (sw_if_index_set == 0)
12740     {
12741       errmsg ("missing interface name or sw_if_index");
12742       return -99;
12743     }
12744
12745   vam->current_sw_if_index = sw_if_index;
12746   vam->is_ipv6 = ipv6_set;
12747
12748   M (IP_ADDRESS_DUMP, mp);
12749   mp->sw_if_index = ntohl (sw_if_index);
12750   mp->is_ipv6 = ipv6_set;
12751   S (mp);
12752
12753   /* Use a control ping for synchronization */
12754   M (CONTROL_PING, mp_ping);
12755   S (mp_ping);
12756
12757   W (ret);
12758   return ret;
12759 }
12760
12761 static int
12762 api_ip_dump (vat_main_t * vam)
12763 {
12764   vl_api_ip_dump_t *mp;
12765   vl_api_control_ping_t *mp_ping;
12766   unformat_input_t *in = vam->input;
12767   int ipv4_set = 0;
12768   int ipv6_set = 0;
12769   int is_ipv6;
12770   int i;
12771   int ret;
12772
12773   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12774     {
12775       if (unformat (in, "ipv4"))
12776         ipv4_set = 1;
12777       else if (unformat (in, "ipv6"))
12778         ipv6_set = 1;
12779       else
12780         break;
12781     }
12782
12783   if (ipv4_set && ipv6_set)
12784     {
12785       errmsg ("ipv4 and ipv6 flags cannot be both set");
12786       return -99;
12787     }
12788
12789   if ((!ipv4_set) && (!ipv6_set))
12790     {
12791       errmsg ("no ipv4 nor ipv6 flag set");
12792       return -99;
12793     }
12794
12795   is_ipv6 = ipv6_set;
12796   vam->is_ipv6 = is_ipv6;
12797
12798   /* free old data */
12799   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12800     {
12801       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12802     }
12803   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12804
12805   M (IP_DUMP, mp);
12806   mp->is_ipv6 = ipv6_set;
12807   S (mp);
12808
12809   /* Use a control ping for synchronization */
12810   M (CONTROL_PING, mp_ping);
12811   S (mp_ping);
12812
12813   W (ret);
12814   return ret;
12815 }
12816
12817 static int
12818 api_ipsec_spd_add_del (vat_main_t * vam)
12819 {
12820   unformat_input_t *i = vam->input;
12821   vl_api_ipsec_spd_add_del_t *mp;
12822   u32 spd_id = ~0;
12823   u8 is_add = 1;
12824   int ret;
12825
12826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12827     {
12828       if (unformat (i, "spd_id %d", &spd_id))
12829         ;
12830       else if (unformat (i, "del"))
12831         is_add = 0;
12832       else
12833         {
12834           clib_warning ("parse error '%U'", format_unformat_error, i);
12835           return -99;
12836         }
12837     }
12838   if (spd_id == ~0)
12839     {
12840       errmsg ("spd_id must be set");
12841       return -99;
12842     }
12843
12844   M (IPSEC_SPD_ADD_DEL, mp);
12845
12846   mp->spd_id = ntohl (spd_id);
12847   mp->is_add = is_add;
12848
12849   S (mp);
12850   W (ret);
12851   return ret;
12852 }
12853
12854 static int
12855 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12856 {
12857   unformat_input_t *i = vam->input;
12858   vl_api_ipsec_interface_add_del_spd_t *mp;
12859   u32 sw_if_index;
12860   u8 sw_if_index_set = 0;
12861   u32 spd_id = (u32) ~ 0;
12862   u8 is_add = 1;
12863   int ret;
12864
12865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12866     {
12867       if (unformat (i, "del"))
12868         is_add = 0;
12869       else if (unformat (i, "spd_id %d", &spd_id))
12870         ;
12871       else
12872         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12873         sw_if_index_set = 1;
12874       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12875         sw_if_index_set = 1;
12876       else
12877         {
12878           clib_warning ("parse error '%U'", format_unformat_error, i);
12879           return -99;
12880         }
12881
12882     }
12883
12884   if (spd_id == (u32) ~ 0)
12885     {
12886       errmsg ("spd_id must be set");
12887       return -99;
12888     }
12889
12890   if (sw_if_index_set == 0)
12891     {
12892       errmsg ("missing interface name or sw_if_index");
12893       return -99;
12894     }
12895
12896   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12897
12898   mp->spd_id = ntohl (spd_id);
12899   mp->sw_if_index = ntohl (sw_if_index);
12900   mp->is_add = is_add;
12901
12902   S (mp);
12903   W (ret);
12904   return ret;
12905 }
12906
12907 static int
12908 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12909 {
12910   unformat_input_t *i = vam->input;
12911   vl_api_ipsec_spd_add_del_entry_t *mp;
12912   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12913   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12914   i32 priority = 0;
12915   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12916   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12917   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12918   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12919   int ret;
12920
12921   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12922   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12923   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12924   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12925   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12926   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12927
12928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12929     {
12930       if (unformat (i, "del"))
12931         is_add = 0;
12932       if (unformat (i, "outbound"))
12933         is_outbound = 1;
12934       if (unformat (i, "inbound"))
12935         is_outbound = 0;
12936       else if (unformat (i, "spd_id %d", &spd_id))
12937         ;
12938       else if (unformat (i, "sa_id %d", &sa_id))
12939         ;
12940       else if (unformat (i, "priority %d", &priority))
12941         ;
12942       else if (unformat (i, "protocol %d", &protocol))
12943         ;
12944       else if (unformat (i, "lport_start %d", &lport_start))
12945         ;
12946       else if (unformat (i, "lport_stop %d", &lport_stop))
12947         ;
12948       else if (unformat (i, "rport_start %d", &rport_start))
12949         ;
12950       else if (unformat (i, "rport_stop %d", &rport_stop))
12951         ;
12952       else
12953         if (unformat
12954             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12955         {
12956           is_ipv6 = 0;
12957           is_ip_any = 0;
12958         }
12959       else
12960         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12961         {
12962           is_ipv6 = 0;
12963           is_ip_any = 0;
12964         }
12965       else
12966         if (unformat
12967             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12968         {
12969           is_ipv6 = 0;
12970           is_ip_any = 0;
12971         }
12972       else
12973         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12974         {
12975           is_ipv6 = 0;
12976           is_ip_any = 0;
12977         }
12978       else
12979         if (unformat
12980             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12981         {
12982           is_ipv6 = 1;
12983           is_ip_any = 0;
12984         }
12985       else
12986         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12987         {
12988           is_ipv6 = 1;
12989           is_ip_any = 0;
12990         }
12991       else
12992         if (unformat
12993             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12994         {
12995           is_ipv6 = 1;
12996           is_ip_any = 0;
12997         }
12998       else
12999         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13000         {
13001           is_ipv6 = 1;
13002           is_ip_any = 0;
13003         }
13004       else
13005         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13006         {
13007           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13008             {
13009               clib_warning ("unsupported action: 'resolve'");
13010               return -99;
13011             }
13012         }
13013       else
13014         {
13015           clib_warning ("parse error '%U'", format_unformat_error, i);
13016           return -99;
13017         }
13018
13019     }
13020
13021   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13022
13023   mp->spd_id = ntohl (spd_id);
13024   mp->priority = ntohl (priority);
13025   mp->is_outbound = is_outbound;
13026
13027   mp->is_ipv6 = is_ipv6;
13028   if (is_ipv6 || is_ip_any)
13029     {
13030       clib_memcpy (mp->remote_address_start, &raddr6_start,
13031                    sizeof (ip6_address_t));
13032       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13033                    sizeof (ip6_address_t));
13034       clib_memcpy (mp->local_address_start, &laddr6_start,
13035                    sizeof (ip6_address_t));
13036       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13037                    sizeof (ip6_address_t));
13038     }
13039   else
13040     {
13041       clib_memcpy (mp->remote_address_start, &raddr4_start,
13042                    sizeof (ip4_address_t));
13043       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13044                    sizeof (ip4_address_t));
13045       clib_memcpy (mp->local_address_start, &laddr4_start,
13046                    sizeof (ip4_address_t));
13047       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13048                    sizeof (ip4_address_t));
13049     }
13050   mp->protocol = (u8) protocol;
13051   mp->local_port_start = ntohs ((u16) lport_start);
13052   mp->local_port_stop = ntohs ((u16) lport_stop);
13053   mp->remote_port_start = ntohs ((u16) rport_start);
13054   mp->remote_port_stop = ntohs ((u16) rport_stop);
13055   mp->policy = (u8) policy;
13056   mp->sa_id = ntohl (sa_id);
13057   mp->is_add = is_add;
13058   mp->is_ip_any = is_ip_any;
13059   S (mp);
13060   W (ret);
13061   return ret;
13062 }
13063
13064 static int
13065 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13066 {
13067   unformat_input_t *i = vam->input;
13068   vl_api_ipsec_sad_add_del_entry_t *mp;
13069   u32 sad_id = 0, spi = 0;
13070   u8 *ck = 0, *ik = 0;
13071   u8 is_add = 1;
13072
13073   u8 protocol = IPSEC_PROTOCOL_AH;
13074   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13075   u32 crypto_alg = 0, integ_alg = 0;
13076   ip4_address_t tun_src4;
13077   ip4_address_t tun_dst4;
13078   ip6_address_t tun_src6;
13079   ip6_address_t tun_dst6;
13080   int ret;
13081
13082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13083     {
13084       if (unformat (i, "del"))
13085         is_add = 0;
13086       else if (unformat (i, "sad_id %d", &sad_id))
13087         ;
13088       else if (unformat (i, "spi %d", &spi))
13089         ;
13090       else if (unformat (i, "esp"))
13091         protocol = IPSEC_PROTOCOL_ESP;
13092       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13093         {
13094           is_tunnel = 1;
13095           is_tunnel_ipv6 = 0;
13096         }
13097       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13098         {
13099           is_tunnel = 1;
13100           is_tunnel_ipv6 = 0;
13101         }
13102       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13103         {
13104           is_tunnel = 1;
13105           is_tunnel_ipv6 = 1;
13106         }
13107       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13108         {
13109           is_tunnel = 1;
13110           is_tunnel_ipv6 = 1;
13111         }
13112       else
13113         if (unformat
13114             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13115         {
13116           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13117               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13118             {
13119               clib_warning ("unsupported crypto-alg: '%U'",
13120                             format_ipsec_crypto_alg, crypto_alg);
13121               return -99;
13122             }
13123         }
13124       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13125         ;
13126       else
13127         if (unformat
13128             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13129         {
13130           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13131               integ_alg >= IPSEC_INTEG_N_ALG)
13132             {
13133               clib_warning ("unsupported integ-alg: '%U'",
13134                             format_ipsec_integ_alg, integ_alg);
13135               return -99;
13136             }
13137         }
13138       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13139         ;
13140       else
13141         {
13142           clib_warning ("parse error '%U'", format_unformat_error, i);
13143           return -99;
13144         }
13145
13146     }
13147
13148   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13149
13150   mp->sad_id = ntohl (sad_id);
13151   mp->is_add = is_add;
13152   mp->protocol = protocol;
13153   mp->spi = ntohl (spi);
13154   mp->is_tunnel = is_tunnel;
13155   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13156   mp->crypto_algorithm = crypto_alg;
13157   mp->integrity_algorithm = integ_alg;
13158   mp->crypto_key_length = vec_len (ck);
13159   mp->integrity_key_length = vec_len (ik);
13160
13161   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13162     mp->crypto_key_length = sizeof (mp->crypto_key);
13163
13164   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13165     mp->integrity_key_length = sizeof (mp->integrity_key);
13166
13167   if (ck)
13168     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13169   if (ik)
13170     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13171
13172   if (is_tunnel)
13173     {
13174       if (is_tunnel_ipv6)
13175         {
13176           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13177                        sizeof (ip6_address_t));
13178           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13179                        sizeof (ip6_address_t));
13180         }
13181       else
13182         {
13183           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13184                        sizeof (ip4_address_t));
13185           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13186                        sizeof (ip4_address_t));
13187         }
13188     }
13189
13190   S (mp);
13191   W (ret);
13192   return ret;
13193 }
13194
13195 static int
13196 api_ipsec_sa_set_key (vat_main_t * vam)
13197 {
13198   unformat_input_t *i = vam->input;
13199   vl_api_ipsec_sa_set_key_t *mp;
13200   u32 sa_id;
13201   u8 *ck = 0, *ik = 0;
13202   int ret;
13203
13204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13205     {
13206       if (unformat (i, "sa_id %d", &sa_id))
13207         ;
13208       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13209         ;
13210       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13211         ;
13212       else
13213         {
13214           clib_warning ("parse error '%U'", format_unformat_error, i);
13215           return -99;
13216         }
13217     }
13218
13219   M (IPSEC_SA_SET_KEY, mp);
13220
13221   mp->sa_id = ntohl (sa_id);
13222   mp->crypto_key_length = vec_len (ck);
13223   mp->integrity_key_length = vec_len (ik);
13224
13225   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13226     mp->crypto_key_length = sizeof (mp->crypto_key);
13227
13228   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13229     mp->integrity_key_length = sizeof (mp->integrity_key);
13230
13231   if (ck)
13232     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13233   if (ik)
13234     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13235
13236   S (mp);
13237   W (ret);
13238   return ret;
13239 }
13240
13241 static int
13242 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13243 {
13244   unformat_input_t *i = vam->input;
13245   vl_api_ipsec_tunnel_if_add_del_t *mp;
13246   u32 local_spi = 0, remote_spi = 0;
13247   u32 crypto_alg = 0, integ_alg = 0;
13248   u8 *lck = NULL, *rck = NULL;
13249   u8 *lik = NULL, *rik = NULL;
13250   ip4_address_t local_ip = { {0} };
13251   ip4_address_t remote_ip = { {0} };
13252   u8 is_add = 1;
13253   u8 esn = 0;
13254   u8 anti_replay = 0;
13255   int ret;
13256
13257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13258     {
13259       if (unformat (i, "del"))
13260         is_add = 0;
13261       else if (unformat (i, "esn"))
13262         esn = 1;
13263       else if (unformat (i, "anti_replay"))
13264         anti_replay = 1;
13265       else if (unformat (i, "local_spi %d", &local_spi))
13266         ;
13267       else if (unformat (i, "remote_spi %d", &remote_spi))
13268         ;
13269       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13270         ;
13271       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13272         ;
13273       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13274         ;
13275       else
13276         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13277         ;
13278       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13279         ;
13280       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13281         ;
13282       else
13283         if (unformat
13284             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13285         {
13286           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13287               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13288             {
13289               errmsg ("unsupported crypto-alg: '%U'\n",
13290                       format_ipsec_crypto_alg, crypto_alg);
13291               return -99;
13292             }
13293         }
13294       else
13295         if (unformat
13296             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13297         {
13298           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13299               integ_alg >= IPSEC_INTEG_N_ALG)
13300             {
13301               errmsg ("unsupported integ-alg: '%U'\n",
13302                       format_ipsec_integ_alg, integ_alg);
13303               return -99;
13304             }
13305         }
13306       else
13307         {
13308           errmsg ("parse error '%U'\n", format_unformat_error, i);
13309           return -99;
13310         }
13311     }
13312
13313   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13314
13315   mp->is_add = is_add;
13316   mp->esn = esn;
13317   mp->anti_replay = anti_replay;
13318
13319   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13320   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13321
13322   mp->local_spi = htonl (local_spi);
13323   mp->remote_spi = htonl (remote_spi);
13324   mp->crypto_alg = (u8) crypto_alg;
13325
13326   mp->local_crypto_key_len = 0;
13327   if (lck)
13328     {
13329       mp->local_crypto_key_len = vec_len (lck);
13330       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13331         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13332       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13333     }
13334
13335   mp->remote_crypto_key_len = 0;
13336   if (rck)
13337     {
13338       mp->remote_crypto_key_len = vec_len (rck);
13339       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13340         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13341       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13342     }
13343
13344   mp->integ_alg = (u8) integ_alg;
13345
13346   mp->local_integ_key_len = 0;
13347   if (lik)
13348     {
13349       mp->local_integ_key_len = vec_len (lik);
13350       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13351         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13352       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13353     }
13354
13355   mp->remote_integ_key_len = 0;
13356   if (rik)
13357     {
13358       mp->remote_integ_key_len = vec_len (rik);
13359       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13360         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13361       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13362     }
13363
13364   S (mp);
13365   W (ret);
13366   return ret;
13367 }
13368
13369 static int
13370 api_ikev2_profile_add_del (vat_main_t * vam)
13371 {
13372   unformat_input_t *i = vam->input;
13373   vl_api_ikev2_profile_add_del_t *mp;
13374   u8 is_add = 1;
13375   u8 *name = 0;
13376   int ret;
13377
13378   const char *valid_chars = "a-zA-Z0-9_";
13379
13380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13381     {
13382       if (unformat (i, "del"))
13383         is_add = 0;
13384       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13385         vec_add1 (name, 0);
13386       else
13387         {
13388           errmsg ("parse error '%U'", format_unformat_error, i);
13389           return -99;
13390         }
13391     }
13392
13393   if (!vec_len (name))
13394     {
13395       errmsg ("profile name must be specified");
13396       return -99;
13397     }
13398
13399   if (vec_len (name) > 64)
13400     {
13401       errmsg ("profile name too long");
13402       return -99;
13403     }
13404
13405   M (IKEV2_PROFILE_ADD_DEL, mp);
13406
13407   clib_memcpy (mp->name, name, vec_len (name));
13408   mp->is_add = is_add;
13409   vec_free (name);
13410
13411   S (mp);
13412   W (ret);
13413   return ret;
13414 }
13415
13416 static int
13417 api_ikev2_profile_set_auth (vat_main_t * vam)
13418 {
13419   unformat_input_t *i = vam->input;
13420   vl_api_ikev2_profile_set_auth_t *mp;
13421   u8 *name = 0;
13422   u8 *data = 0;
13423   u32 auth_method = 0;
13424   u8 is_hex = 0;
13425   int ret;
13426
13427   const char *valid_chars = "a-zA-Z0-9_";
13428
13429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13430     {
13431       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13432         vec_add1 (name, 0);
13433       else if (unformat (i, "auth_method %U",
13434                          unformat_ikev2_auth_method, &auth_method))
13435         ;
13436       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13437         is_hex = 1;
13438       else if (unformat (i, "auth_data %v", &data))
13439         ;
13440       else
13441         {
13442           errmsg ("parse error '%U'", format_unformat_error, i);
13443           return -99;
13444         }
13445     }
13446
13447   if (!vec_len (name))
13448     {
13449       errmsg ("profile name must be specified");
13450       return -99;
13451     }
13452
13453   if (vec_len (name) > 64)
13454     {
13455       errmsg ("profile name too long");
13456       return -99;
13457     }
13458
13459   if (!vec_len (data))
13460     {
13461       errmsg ("auth_data must be specified");
13462       return -99;
13463     }
13464
13465   if (!auth_method)
13466     {
13467       errmsg ("auth_method must be specified");
13468       return -99;
13469     }
13470
13471   M (IKEV2_PROFILE_SET_AUTH, mp);
13472
13473   mp->is_hex = is_hex;
13474   mp->auth_method = (u8) auth_method;
13475   mp->data_len = vec_len (data);
13476   clib_memcpy (mp->name, name, vec_len (name));
13477   clib_memcpy (mp->data, data, vec_len (data));
13478   vec_free (name);
13479   vec_free (data);
13480
13481   S (mp);
13482   W (ret);
13483   return ret;
13484 }
13485
13486 static int
13487 api_ikev2_profile_set_id (vat_main_t * vam)
13488 {
13489   unformat_input_t *i = vam->input;
13490   vl_api_ikev2_profile_set_id_t *mp;
13491   u8 *name = 0;
13492   u8 *data = 0;
13493   u8 is_local = 0;
13494   u32 id_type = 0;
13495   ip4_address_t ip4;
13496   int ret;
13497
13498   const char *valid_chars = "a-zA-Z0-9_";
13499
13500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13501     {
13502       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13503         vec_add1 (name, 0);
13504       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13505         ;
13506       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13507         {
13508           data = vec_new (u8, 4);
13509           clib_memcpy (data, ip4.as_u8, 4);
13510         }
13511       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13512         ;
13513       else if (unformat (i, "id_data %v", &data))
13514         ;
13515       else if (unformat (i, "local"))
13516         is_local = 1;
13517       else if (unformat (i, "remote"))
13518         is_local = 0;
13519       else
13520         {
13521           errmsg ("parse error '%U'", format_unformat_error, i);
13522           return -99;
13523         }
13524     }
13525
13526   if (!vec_len (name))
13527     {
13528       errmsg ("profile name must be specified");
13529       return -99;
13530     }
13531
13532   if (vec_len (name) > 64)
13533     {
13534       errmsg ("profile name too long");
13535       return -99;
13536     }
13537
13538   if (!vec_len (data))
13539     {
13540       errmsg ("id_data must be specified");
13541       return -99;
13542     }
13543
13544   if (!id_type)
13545     {
13546       errmsg ("id_type must be specified");
13547       return -99;
13548     }
13549
13550   M (IKEV2_PROFILE_SET_ID, mp);
13551
13552   mp->is_local = is_local;
13553   mp->id_type = (u8) id_type;
13554   mp->data_len = vec_len (data);
13555   clib_memcpy (mp->name, name, vec_len (name));
13556   clib_memcpy (mp->data, data, vec_len (data));
13557   vec_free (name);
13558   vec_free (data);
13559
13560   S (mp);
13561   W (ret);
13562   return ret;
13563 }
13564
13565 static int
13566 api_ikev2_profile_set_ts (vat_main_t * vam)
13567 {
13568   unformat_input_t *i = vam->input;
13569   vl_api_ikev2_profile_set_ts_t *mp;
13570   u8 *name = 0;
13571   u8 is_local = 0;
13572   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13573   ip4_address_t start_addr, end_addr;
13574
13575   const char *valid_chars = "a-zA-Z0-9_";
13576   int ret;
13577
13578   start_addr.as_u32 = 0;
13579   end_addr.as_u32 = (u32) ~ 0;
13580
13581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13582     {
13583       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13584         vec_add1 (name, 0);
13585       else if (unformat (i, "protocol %d", &proto))
13586         ;
13587       else if (unformat (i, "start_port %d", &start_port))
13588         ;
13589       else if (unformat (i, "end_port %d", &end_port))
13590         ;
13591       else
13592         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13593         ;
13594       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13595         ;
13596       else if (unformat (i, "local"))
13597         is_local = 1;
13598       else if (unformat (i, "remote"))
13599         is_local = 0;
13600       else
13601         {
13602           errmsg ("parse error '%U'", format_unformat_error, i);
13603           return -99;
13604         }
13605     }
13606
13607   if (!vec_len (name))
13608     {
13609       errmsg ("profile name must be specified");
13610       return -99;
13611     }
13612
13613   if (vec_len (name) > 64)
13614     {
13615       errmsg ("profile name too long");
13616       return -99;
13617     }
13618
13619   M (IKEV2_PROFILE_SET_TS, mp);
13620
13621   mp->is_local = is_local;
13622   mp->proto = (u8) proto;
13623   mp->start_port = (u16) start_port;
13624   mp->end_port = (u16) end_port;
13625   mp->start_addr = start_addr.as_u32;
13626   mp->end_addr = end_addr.as_u32;
13627   clib_memcpy (mp->name, name, vec_len (name));
13628   vec_free (name);
13629
13630   S (mp);
13631   W (ret);
13632   return ret;
13633 }
13634
13635 static int
13636 api_ikev2_set_local_key (vat_main_t * vam)
13637 {
13638   unformat_input_t *i = vam->input;
13639   vl_api_ikev2_set_local_key_t *mp;
13640   u8 *file = 0;
13641   int ret;
13642
13643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13644     {
13645       if (unformat (i, "file %v", &file))
13646         vec_add1 (file, 0);
13647       else
13648         {
13649           errmsg ("parse error '%U'", format_unformat_error, i);
13650           return -99;
13651         }
13652     }
13653
13654   if (!vec_len (file))
13655     {
13656       errmsg ("RSA key file must be specified");
13657       return -99;
13658     }
13659
13660   if (vec_len (file) > 256)
13661     {
13662       errmsg ("file name too long");
13663       return -99;
13664     }
13665
13666   M (IKEV2_SET_LOCAL_KEY, mp);
13667
13668   clib_memcpy (mp->key_file, file, vec_len (file));
13669   vec_free (file);
13670
13671   S (mp);
13672   W (ret);
13673   return ret;
13674 }
13675
13676 static int
13677 api_ikev2_set_responder (vat_main_t * vam)
13678 {
13679   unformat_input_t *i = vam->input;
13680   vl_api_ikev2_set_responder_t *mp;
13681   int ret;
13682   u8 *name = 0;
13683   u32 sw_if_index = ~0;
13684   ip4_address_t address;
13685
13686   const char *valid_chars = "a-zA-Z0-9_";
13687
13688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13689     {
13690       if (unformat
13691           (i, "%U interface %d address %U", unformat_token, valid_chars,
13692            &name, &sw_if_index, unformat_ip4_address, &address))
13693         vec_add1 (name, 0);
13694       else
13695         {
13696           errmsg ("parse error '%U'", format_unformat_error, i);
13697           return -99;
13698         }
13699     }
13700
13701   if (!vec_len (name))
13702     {
13703       errmsg ("profile name must be specified");
13704       return -99;
13705     }
13706
13707   if (vec_len (name) > 64)
13708     {
13709       errmsg ("profile name too long");
13710       return -99;
13711     }
13712
13713   M (IKEV2_SET_RESPONDER, mp);
13714
13715   clib_memcpy (mp->name, name, vec_len (name));
13716   vec_free (name);
13717
13718   mp->sw_if_index = sw_if_index;
13719   clib_memcpy (mp->address, &address, sizeof (address));
13720
13721   S (mp);
13722   W (ret);
13723   return ret;
13724 }
13725
13726 static int
13727 api_ikev2_set_ike_transforms (vat_main_t * vam)
13728 {
13729   unformat_input_t *i = vam->input;
13730   vl_api_ikev2_set_ike_transforms_t *mp;
13731   int ret;
13732   u8 *name = 0;
13733   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13734
13735   const char *valid_chars = "a-zA-Z0-9_";
13736
13737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13738     {
13739       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13740                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13741         vec_add1 (name, 0);
13742       else
13743         {
13744           errmsg ("parse error '%U'", format_unformat_error, i);
13745           return -99;
13746         }
13747     }
13748
13749   if (!vec_len (name))
13750     {
13751       errmsg ("profile name must be specified");
13752       return -99;
13753     }
13754
13755   if (vec_len (name) > 64)
13756     {
13757       errmsg ("profile name too long");
13758       return -99;
13759     }
13760
13761   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13762
13763   clib_memcpy (mp->name, name, vec_len (name));
13764   vec_free (name);
13765   mp->crypto_alg = crypto_alg;
13766   mp->crypto_key_size = crypto_key_size;
13767   mp->integ_alg = integ_alg;
13768   mp->dh_group = dh_group;
13769
13770   S (mp);
13771   W (ret);
13772   return ret;
13773 }
13774
13775
13776 static int
13777 api_ikev2_set_esp_transforms (vat_main_t * vam)
13778 {
13779   unformat_input_t *i = vam->input;
13780   vl_api_ikev2_set_esp_transforms_t *mp;
13781   int ret;
13782   u8 *name = 0;
13783   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13784
13785   const char *valid_chars = "a-zA-Z0-9_";
13786
13787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13788     {
13789       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13790                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13791         vec_add1 (name, 0);
13792       else
13793         {
13794           errmsg ("parse error '%U'", format_unformat_error, i);
13795           return -99;
13796         }
13797     }
13798
13799   if (!vec_len (name))
13800     {
13801       errmsg ("profile name must be specified");
13802       return -99;
13803     }
13804
13805   if (vec_len (name) > 64)
13806     {
13807       errmsg ("profile name too long");
13808       return -99;
13809     }
13810
13811   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13812
13813   clib_memcpy (mp->name, name, vec_len (name));
13814   vec_free (name);
13815   mp->crypto_alg = crypto_alg;
13816   mp->crypto_key_size = crypto_key_size;
13817   mp->integ_alg = integ_alg;
13818   mp->dh_group = dh_group;
13819
13820   S (mp);
13821   W (ret);
13822   return ret;
13823 }
13824
13825 static int
13826 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13827 {
13828   unformat_input_t *i = vam->input;
13829   vl_api_ikev2_set_sa_lifetime_t *mp;
13830   int ret;
13831   u8 *name = 0;
13832   u64 lifetime, lifetime_maxdata;
13833   u32 lifetime_jitter, handover;
13834
13835   const char *valid_chars = "a-zA-Z0-9_";
13836
13837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13838     {
13839       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13840                     &lifetime, &lifetime_jitter, &handover,
13841                     &lifetime_maxdata))
13842         vec_add1 (name, 0);
13843       else
13844         {
13845           errmsg ("parse error '%U'", format_unformat_error, i);
13846           return -99;
13847         }
13848     }
13849
13850   if (!vec_len (name))
13851     {
13852       errmsg ("profile name must be specified");
13853       return -99;
13854     }
13855
13856   if (vec_len (name) > 64)
13857     {
13858       errmsg ("profile name too long");
13859       return -99;
13860     }
13861
13862   M (IKEV2_SET_SA_LIFETIME, mp);
13863
13864   clib_memcpy (mp->name, name, vec_len (name));
13865   vec_free (name);
13866   mp->lifetime = lifetime;
13867   mp->lifetime_jitter = lifetime_jitter;
13868   mp->handover = handover;
13869   mp->lifetime_maxdata = lifetime_maxdata;
13870
13871   S (mp);
13872   W (ret);
13873   return ret;
13874 }
13875
13876 static int
13877 api_ikev2_initiate_sa_init (vat_main_t * vam)
13878 {
13879   unformat_input_t *i = vam->input;
13880   vl_api_ikev2_initiate_sa_init_t *mp;
13881   int ret;
13882   u8 *name = 0;
13883
13884   const char *valid_chars = "a-zA-Z0-9_";
13885
13886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13887     {
13888       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13889         vec_add1 (name, 0);
13890       else
13891         {
13892           errmsg ("parse error '%U'", format_unformat_error, i);
13893           return -99;
13894         }
13895     }
13896
13897   if (!vec_len (name))
13898     {
13899       errmsg ("profile name must be specified");
13900       return -99;
13901     }
13902
13903   if (vec_len (name) > 64)
13904     {
13905       errmsg ("profile name too long");
13906       return -99;
13907     }
13908
13909   M (IKEV2_INITIATE_SA_INIT, mp);
13910
13911   clib_memcpy (mp->name, name, vec_len (name));
13912   vec_free (name);
13913
13914   S (mp);
13915   W (ret);
13916   return ret;
13917 }
13918
13919 static int
13920 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13921 {
13922   unformat_input_t *i = vam->input;
13923   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13924   int ret;
13925   u64 ispi;
13926
13927
13928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13929     {
13930       if (unformat (i, "%lx", &ispi))
13931         ;
13932       else
13933         {
13934           errmsg ("parse error '%U'", format_unformat_error, i);
13935           return -99;
13936         }
13937     }
13938
13939   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13940
13941   mp->ispi = ispi;
13942
13943   S (mp);
13944   W (ret);
13945   return ret;
13946 }
13947
13948 static int
13949 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13950 {
13951   unformat_input_t *i = vam->input;
13952   vl_api_ikev2_initiate_del_child_sa_t *mp;
13953   int ret;
13954   u32 ispi;
13955
13956
13957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13958     {
13959       if (unformat (i, "%x", &ispi))
13960         ;
13961       else
13962         {
13963           errmsg ("parse error '%U'", format_unformat_error, i);
13964           return -99;
13965         }
13966     }
13967
13968   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13969
13970   mp->ispi = ispi;
13971
13972   S (mp);
13973   W (ret);
13974   return ret;
13975 }
13976
13977 static int
13978 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13979 {
13980   unformat_input_t *i = vam->input;
13981   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13982   int ret;
13983   u32 ispi;
13984
13985
13986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13987     {
13988       if (unformat (i, "%x", &ispi))
13989         ;
13990       else
13991         {
13992           errmsg ("parse error '%U'", format_unformat_error, i);
13993           return -99;
13994         }
13995     }
13996
13997   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13998
13999   mp->ispi = ispi;
14000
14001   S (mp);
14002   W (ret);
14003   return ret;
14004 }
14005
14006 /*
14007  * MAP
14008  */
14009 static int
14010 api_map_add_domain (vat_main_t * vam)
14011 {
14012   unformat_input_t *i = vam->input;
14013   vl_api_map_add_domain_t *mp;
14014
14015   ip4_address_t ip4_prefix;
14016   ip6_address_t ip6_prefix;
14017   ip6_address_t ip6_src;
14018   u32 num_m_args = 0;
14019   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14020     0, psid_length = 0;
14021   u8 is_translation = 0;
14022   u32 mtu = 0;
14023   u32 ip6_src_len = 128;
14024   int ret;
14025
14026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14027     {
14028       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14029                     &ip4_prefix, &ip4_prefix_len))
14030         num_m_args++;
14031       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14032                          &ip6_prefix, &ip6_prefix_len))
14033         num_m_args++;
14034       else
14035         if (unformat
14036             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14037              &ip6_src_len))
14038         num_m_args++;
14039       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14040         num_m_args++;
14041       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14042         num_m_args++;
14043       else if (unformat (i, "psid-offset %d", &psid_offset))
14044         num_m_args++;
14045       else if (unformat (i, "psid-len %d", &psid_length))
14046         num_m_args++;
14047       else if (unformat (i, "mtu %d", &mtu))
14048         num_m_args++;
14049       else if (unformat (i, "map-t"))
14050         is_translation = 1;
14051       else
14052         {
14053           clib_warning ("parse error '%U'", format_unformat_error, i);
14054           return -99;
14055         }
14056     }
14057
14058   if (num_m_args < 3)
14059     {
14060       errmsg ("mandatory argument(s) missing");
14061       return -99;
14062     }
14063
14064   /* Construct the API message */
14065   M (MAP_ADD_DOMAIN, mp);
14066
14067   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14068   mp->ip4_prefix_len = ip4_prefix_len;
14069
14070   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14071   mp->ip6_prefix_len = ip6_prefix_len;
14072
14073   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14074   mp->ip6_src_prefix_len = ip6_src_len;
14075
14076   mp->ea_bits_len = ea_bits_len;
14077   mp->psid_offset = psid_offset;
14078   mp->psid_length = psid_length;
14079   mp->is_translation = is_translation;
14080   mp->mtu = htons (mtu);
14081
14082   /* send it... */
14083   S (mp);
14084
14085   /* Wait for a reply, return good/bad news  */
14086   W (ret);
14087   return ret;
14088 }
14089
14090 static int
14091 api_map_del_domain (vat_main_t * vam)
14092 {
14093   unformat_input_t *i = vam->input;
14094   vl_api_map_del_domain_t *mp;
14095
14096   u32 num_m_args = 0;
14097   u32 index;
14098   int ret;
14099
14100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14101     {
14102       if (unformat (i, "index %d", &index))
14103         num_m_args++;
14104       else
14105         {
14106           clib_warning ("parse error '%U'", format_unformat_error, i);
14107           return -99;
14108         }
14109     }
14110
14111   if (num_m_args != 1)
14112     {
14113       errmsg ("mandatory argument(s) missing");
14114       return -99;
14115     }
14116
14117   /* Construct the API message */
14118   M (MAP_DEL_DOMAIN, mp);
14119
14120   mp->index = ntohl (index);
14121
14122   /* send it... */
14123   S (mp);
14124
14125   /* Wait for a reply, return good/bad news  */
14126   W (ret);
14127   return ret;
14128 }
14129
14130 static int
14131 api_map_add_del_rule (vat_main_t * vam)
14132 {
14133   unformat_input_t *i = vam->input;
14134   vl_api_map_add_del_rule_t *mp;
14135   u8 is_add = 1;
14136   ip6_address_t ip6_dst;
14137   u32 num_m_args = 0, index, psid = 0;
14138   int ret;
14139
14140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14141     {
14142       if (unformat (i, "index %d", &index))
14143         num_m_args++;
14144       else if (unformat (i, "psid %d", &psid))
14145         num_m_args++;
14146       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14147         num_m_args++;
14148       else if (unformat (i, "del"))
14149         {
14150           is_add = 0;
14151         }
14152       else
14153         {
14154           clib_warning ("parse error '%U'", format_unformat_error, i);
14155           return -99;
14156         }
14157     }
14158
14159   /* Construct the API message */
14160   M (MAP_ADD_DEL_RULE, mp);
14161
14162   mp->index = ntohl (index);
14163   mp->is_add = is_add;
14164   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14165   mp->psid = ntohs (psid);
14166
14167   /* send it... */
14168   S (mp);
14169
14170   /* Wait for a reply, return good/bad news  */
14171   W (ret);
14172   return ret;
14173 }
14174
14175 static int
14176 api_map_domain_dump (vat_main_t * vam)
14177 {
14178   vl_api_map_domain_dump_t *mp;
14179   vl_api_control_ping_t *mp_ping;
14180   int ret;
14181
14182   /* Construct the API message */
14183   M (MAP_DOMAIN_DUMP, mp);
14184
14185   /* send it... */
14186   S (mp);
14187
14188   /* Use a control ping for synchronization */
14189   M (CONTROL_PING, mp_ping);
14190   S (mp_ping);
14191
14192   W (ret);
14193   return ret;
14194 }
14195
14196 static int
14197 api_map_rule_dump (vat_main_t * vam)
14198 {
14199   unformat_input_t *i = vam->input;
14200   vl_api_map_rule_dump_t *mp;
14201   vl_api_control_ping_t *mp_ping;
14202   u32 domain_index = ~0;
14203   int ret;
14204
14205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14206     {
14207       if (unformat (i, "index %u", &domain_index))
14208         ;
14209       else
14210         break;
14211     }
14212
14213   if (domain_index == ~0)
14214     {
14215       clib_warning ("parse error: domain index expected");
14216       return -99;
14217     }
14218
14219   /* Construct the API message */
14220   M (MAP_RULE_DUMP, mp);
14221
14222   mp->domain_index = htonl (domain_index);
14223
14224   /* send it... */
14225   S (mp);
14226
14227   /* Use a control ping for synchronization */
14228   M (CONTROL_PING, mp_ping);
14229   S (mp_ping);
14230
14231   W (ret);
14232   return ret;
14233 }
14234
14235 static void vl_api_map_add_domain_reply_t_handler
14236   (vl_api_map_add_domain_reply_t * mp)
14237 {
14238   vat_main_t *vam = &vat_main;
14239   i32 retval = ntohl (mp->retval);
14240
14241   if (vam->async_mode)
14242     {
14243       vam->async_errors += (retval < 0);
14244     }
14245   else
14246     {
14247       vam->retval = retval;
14248       vam->result_ready = 1;
14249     }
14250 }
14251
14252 static void vl_api_map_add_domain_reply_t_handler_json
14253   (vl_api_map_add_domain_reply_t * mp)
14254 {
14255   vat_main_t *vam = &vat_main;
14256   vat_json_node_t node;
14257
14258   vat_json_init_object (&node);
14259   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14260   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14261
14262   vat_json_print (vam->ofp, &node);
14263   vat_json_free (&node);
14264
14265   vam->retval = ntohl (mp->retval);
14266   vam->result_ready = 1;
14267 }
14268
14269 static int
14270 api_get_first_msg_id (vat_main_t * vam)
14271 {
14272   vl_api_get_first_msg_id_t *mp;
14273   unformat_input_t *i = vam->input;
14274   u8 *name;
14275   u8 name_set = 0;
14276   int ret;
14277
14278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14279     {
14280       if (unformat (i, "client %s", &name))
14281         name_set = 1;
14282       else
14283         break;
14284     }
14285
14286   if (name_set == 0)
14287     {
14288       errmsg ("missing client name");
14289       return -99;
14290     }
14291   vec_add1 (name, 0);
14292
14293   if (vec_len (name) > 63)
14294     {
14295       errmsg ("client name too long");
14296       return -99;
14297     }
14298
14299   M (GET_FIRST_MSG_ID, mp);
14300   clib_memcpy (mp->name, name, vec_len (name));
14301   S (mp);
14302   W (ret);
14303   return ret;
14304 }
14305
14306 static int
14307 api_cop_interface_enable_disable (vat_main_t * vam)
14308 {
14309   unformat_input_t *line_input = vam->input;
14310   vl_api_cop_interface_enable_disable_t *mp;
14311   u32 sw_if_index = ~0;
14312   u8 enable_disable = 1;
14313   int ret;
14314
14315   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14316     {
14317       if (unformat (line_input, "disable"))
14318         enable_disable = 0;
14319       if (unformat (line_input, "enable"))
14320         enable_disable = 1;
14321       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14322                          vam, &sw_if_index))
14323         ;
14324       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14325         ;
14326       else
14327         break;
14328     }
14329
14330   if (sw_if_index == ~0)
14331     {
14332       errmsg ("missing interface name or sw_if_index");
14333       return -99;
14334     }
14335
14336   /* Construct the API message */
14337   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14338   mp->sw_if_index = ntohl (sw_if_index);
14339   mp->enable_disable = enable_disable;
14340
14341   /* send it... */
14342   S (mp);
14343   /* Wait for the reply */
14344   W (ret);
14345   return ret;
14346 }
14347
14348 static int
14349 api_cop_whitelist_enable_disable (vat_main_t * vam)
14350 {
14351   unformat_input_t *line_input = vam->input;
14352   vl_api_cop_whitelist_enable_disable_t *mp;
14353   u32 sw_if_index = ~0;
14354   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14355   u32 fib_id = 0;
14356   int ret;
14357
14358   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14359     {
14360       if (unformat (line_input, "ip4"))
14361         ip4 = 1;
14362       else if (unformat (line_input, "ip6"))
14363         ip6 = 1;
14364       else if (unformat (line_input, "default"))
14365         default_cop = 1;
14366       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14367                          vam, &sw_if_index))
14368         ;
14369       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14370         ;
14371       else if (unformat (line_input, "fib-id %d", &fib_id))
14372         ;
14373       else
14374         break;
14375     }
14376
14377   if (sw_if_index == ~0)
14378     {
14379       errmsg ("missing interface name or sw_if_index");
14380       return -99;
14381     }
14382
14383   /* Construct the API message */
14384   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14385   mp->sw_if_index = ntohl (sw_if_index);
14386   mp->fib_id = ntohl (fib_id);
14387   mp->ip4 = ip4;
14388   mp->ip6 = ip6;
14389   mp->default_cop = default_cop;
14390
14391   /* send it... */
14392   S (mp);
14393   /* Wait for the reply */
14394   W (ret);
14395   return ret;
14396 }
14397
14398 static int
14399 api_get_node_graph (vat_main_t * vam)
14400 {
14401   vl_api_get_node_graph_t *mp;
14402   int ret;
14403
14404   M (GET_NODE_GRAPH, mp);
14405
14406   /* send it... */
14407   S (mp);
14408   /* Wait for the reply */
14409   W (ret);
14410   return ret;
14411 }
14412
14413 /* *INDENT-OFF* */
14414 /** Used for parsing LISP eids */
14415 typedef CLIB_PACKED(struct{
14416   u8 addr[16];   /**< eid address */
14417   u32 len;       /**< prefix length if IP */
14418   u8 type;      /**< type of eid */
14419 }) lisp_eid_vat_t;
14420 /* *INDENT-ON* */
14421
14422 static uword
14423 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14424 {
14425   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14426
14427   memset (a, 0, sizeof (a[0]));
14428
14429   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14430     {
14431       a->type = 0;              /* ipv4 type */
14432     }
14433   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14434     {
14435       a->type = 1;              /* ipv6 type */
14436     }
14437   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14438     {
14439       a->type = 2;              /* mac type */
14440     }
14441   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14442     {
14443       a->type = 3;              /* NSH type */
14444       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14445       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14446     }
14447   else
14448     {
14449       return 0;
14450     }
14451
14452   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14453     {
14454       return 0;
14455     }
14456
14457   return 1;
14458 }
14459
14460 static int
14461 lisp_eid_size_vat (u8 type)
14462 {
14463   switch (type)
14464     {
14465     case 0:
14466       return 4;
14467     case 1:
14468       return 16;
14469     case 2:
14470       return 6;
14471     case 3:
14472       return 5;
14473     }
14474   return 0;
14475 }
14476
14477 static void
14478 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14479 {
14480   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14481 }
14482
14483 static int
14484 api_one_add_del_locator_set (vat_main_t * vam)
14485 {
14486   unformat_input_t *input = vam->input;
14487   vl_api_one_add_del_locator_set_t *mp;
14488   u8 is_add = 1;
14489   u8 *locator_set_name = NULL;
14490   u8 locator_set_name_set = 0;
14491   vl_api_local_locator_t locator, *locators = 0;
14492   u32 sw_if_index, priority, weight;
14493   u32 data_len = 0;
14494
14495   int ret;
14496   /* Parse args required to build the message */
14497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14498     {
14499       if (unformat (input, "del"))
14500         {
14501           is_add = 0;
14502         }
14503       else if (unformat (input, "locator-set %s", &locator_set_name))
14504         {
14505           locator_set_name_set = 1;
14506         }
14507       else if (unformat (input, "sw_if_index %u p %u w %u",
14508                          &sw_if_index, &priority, &weight))
14509         {
14510           locator.sw_if_index = htonl (sw_if_index);
14511           locator.priority = priority;
14512           locator.weight = weight;
14513           vec_add1 (locators, locator);
14514         }
14515       else
14516         if (unformat
14517             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14518              &sw_if_index, &priority, &weight))
14519         {
14520           locator.sw_if_index = htonl (sw_if_index);
14521           locator.priority = priority;
14522           locator.weight = weight;
14523           vec_add1 (locators, locator);
14524         }
14525       else
14526         break;
14527     }
14528
14529   if (locator_set_name_set == 0)
14530     {
14531       errmsg ("missing locator-set name");
14532       vec_free (locators);
14533       return -99;
14534     }
14535
14536   if (vec_len (locator_set_name) > 64)
14537     {
14538       errmsg ("locator-set name too long");
14539       vec_free (locator_set_name);
14540       vec_free (locators);
14541       return -99;
14542     }
14543   vec_add1 (locator_set_name, 0);
14544
14545   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14546
14547   /* Construct the API message */
14548   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14549
14550   mp->is_add = is_add;
14551   clib_memcpy (mp->locator_set_name, locator_set_name,
14552                vec_len (locator_set_name));
14553   vec_free (locator_set_name);
14554
14555   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14556   if (locators)
14557     clib_memcpy (mp->locators, locators, data_len);
14558   vec_free (locators);
14559
14560   /* send it... */
14561   S (mp);
14562
14563   /* Wait for a reply... */
14564   W (ret);
14565   return ret;
14566 }
14567
14568 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14569
14570 static int
14571 api_one_add_del_locator (vat_main_t * vam)
14572 {
14573   unformat_input_t *input = vam->input;
14574   vl_api_one_add_del_locator_t *mp;
14575   u32 tmp_if_index = ~0;
14576   u32 sw_if_index = ~0;
14577   u8 sw_if_index_set = 0;
14578   u8 sw_if_index_if_name_set = 0;
14579   u32 priority = ~0;
14580   u8 priority_set = 0;
14581   u32 weight = ~0;
14582   u8 weight_set = 0;
14583   u8 is_add = 1;
14584   u8 *locator_set_name = NULL;
14585   u8 locator_set_name_set = 0;
14586   int ret;
14587
14588   /* Parse args required to build the message */
14589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14590     {
14591       if (unformat (input, "del"))
14592         {
14593           is_add = 0;
14594         }
14595       else if (unformat (input, "locator-set %s", &locator_set_name))
14596         {
14597           locator_set_name_set = 1;
14598         }
14599       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14600                          &tmp_if_index))
14601         {
14602           sw_if_index_if_name_set = 1;
14603           sw_if_index = tmp_if_index;
14604         }
14605       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14606         {
14607           sw_if_index_set = 1;
14608           sw_if_index = tmp_if_index;
14609         }
14610       else if (unformat (input, "p %d", &priority))
14611         {
14612           priority_set = 1;
14613         }
14614       else if (unformat (input, "w %d", &weight))
14615         {
14616           weight_set = 1;
14617         }
14618       else
14619         break;
14620     }
14621
14622   if (locator_set_name_set == 0)
14623     {
14624       errmsg ("missing locator-set name");
14625       return -99;
14626     }
14627
14628   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14629     {
14630       errmsg ("missing sw_if_index");
14631       vec_free (locator_set_name);
14632       return -99;
14633     }
14634
14635   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14636     {
14637       errmsg ("cannot use both params interface name and sw_if_index");
14638       vec_free (locator_set_name);
14639       return -99;
14640     }
14641
14642   if (priority_set == 0)
14643     {
14644       errmsg ("missing locator-set priority");
14645       vec_free (locator_set_name);
14646       return -99;
14647     }
14648
14649   if (weight_set == 0)
14650     {
14651       errmsg ("missing locator-set weight");
14652       vec_free (locator_set_name);
14653       return -99;
14654     }
14655
14656   if (vec_len (locator_set_name) > 64)
14657     {
14658       errmsg ("locator-set name too long");
14659       vec_free (locator_set_name);
14660       return -99;
14661     }
14662   vec_add1 (locator_set_name, 0);
14663
14664   /* Construct the API message */
14665   M (ONE_ADD_DEL_LOCATOR, mp);
14666
14667   mp->is_add = is_add;
14668   mp->sw_if_index = ntohl (sw_if_index);
14669   mp->priority = priority;
14670   mp->weight = weight;
14671   clib_memcpy (mp->locator_set_name, locator_set_name,
14672                vec_len (locator_set_name));
14673   vec_free (locator_set_name);
14674
14675   /* send it... */
14676   S (mp);
14677
14678   /* Wait for a reply... */
14679   W (ret);
14680   return ret;
14681 }
14682
14683 #define api_lisp_add_del_locator api_one_add_del_locator
14684
14685 uword
14686 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14687 {
14688   u32 *key_id = va_arg (*args, u32 *);
14689   u8 *s = 0;
14690
14691   if (unformat (input, "%s", &s))
14692     {
14693       if (!strcmp ((char *) s, "sha1"))
14694         key_id[0] = HMAC_SHA_1_96;
14695       else if (!strcmp ((char *) s, "sha256"))
14696         key_id[0] = HMAC_SHA_256_128;
14697       else
14698         {
14699           clib_warning ("invalid key_id: '%s'", s);
14700           key_id[0] = HMAC_NO_KEY;
14701         }
14702     }
14703   else
14704     return 0;
14705
14706   vec_free (s);
14707   return 1;
14708 }
14709
14710 static int
14711 api_one_add_del_local_eid (vat_main_t * vam)
14712 {
14713   unformat_input_t *input = vam->input;
14714   vl_api_one_add_del_local_eid_t *mp;
14715   u8 is_add = 1;
14716   u8 eid_set = 0;
14717   lisp_eid_vat_t _eid, *eid = &_eid;
14718   u8 *locator_set_name = 0;
14719   u8 locator_set_name_set = 0;
14720   u32 vni = 0;
14721   u16 key_id = 0;
14722   u8 *key = 0;
14723   int ret;
14724
14725   /* Parse args required to build the message */
14726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14727     {
14728       if (unformat (input, "del"))
14729         {
14730           is_add = 0;
14731         }
14732       else if (unformat (input, "vni %d", &vni))
14733         {
14734           ;
14735         }
14736       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14737         {
14738           eid_set = 1;
14739         }
14740       else if (unformat (input, "locator-set %s", &locator_set_name))
14741         {
14742           locator_set_name_set = 1;
14743         }
14744       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14745         ;
14746       else if (unformat (input, "secret-key %_%v%_", &key))
14747         ;
14748       else
14749         break;
14750     }
14751
14752   if (locator_set_name_set == 0)
14753     {
14754       errmsg ("missing locator-set name");
14755       return -99;
14756     }
14757
14758   if (0 == eid_set)
14759     {
14760       errmsg ("EID address not set!");
14761       vec_free (locator_set_name);
14762       return -99;
14763     }
14764
14765   if (key && (0 == key_id))
14766     {
14767       errmsg ("invalid key_id!");
14768       return -99;
14769     }
14770
14771   if (vec_len (key) > 64)
14772     {
14773       errmsg ("key too long");
14774       vec_free (key);
14775       return -99;
14776     }
14777
14778   if (vec_len (locator_set_name) > 64)
14779     {
14780       errmsg ("locator-set name too long");
14781       vec_free (locator_set_name);
14782       return -99;
14783     }
14784   vec_add1 (locator_set_name, 0);
14785
14786   /* Construct the API message */
14787   M (ONE_ADD_DEL_LOCAL_EID, mp);
14788
14789   mp->is_add = is_add;
14790   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14791   mp->eid_type = eid->type;
14792   mp->prefix_len = eid->len;
14793   mp->vni = clib_host_to_net_u32 (vni);
14794   mp->key_id = clib_host_to_net_u16 (key_id);
14795   clib_memcpy (mp->locator_set_name, locator_set_name,
14796                vec_len (locator_set_name));
14797   clib_memcpy (mp->key, key, vec_len (key));
14798
14799   vec_free (locator_set_name);
14800   vec_free (key);
14801
14802   /* send it... */
14803   S (mp);
14804
14805   /* Wait for a reply... */
14806   W (ret);
14807   return ret;
14808 }
14809
14810 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14811
14812 static int
14813 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14814 {
14815   u32 dp_table = 0, vni = 0;;
14816   unformat_input_t *input = vam->input;
14817   vl_api_gpe_add_del_fwd_entry_t *mp;
14818   u8 is_add = 1;
14819   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14820   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14821   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14822   u32 action = ~0, w;
14823   ip4_address_t rmt_rloc4, lcl_rloc4;
14824   ip6_address_t rmt_rloc6, lcl_rloc6;
14825   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14826   int ret;
14827
14828   memset (&rloc, 0, sizeof (rloc));
14829
14830   /* Parse args required to build the message */
14831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14832     {
14833       if (unformat (input, "del"))
14834         is_add = 0;
14835       else if (unformat (input, "add"))
14836         is_add = 1;
14837       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14838         {
14839           rmt_eid_set = 1;
14840         }
14841       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14842         {
14843           lcl_eid_set = 1;
14844         }
14845       else if (unformat (input, "vrf %d", &dp_table))
14846         ;
14847       else if (unformat (input, "bd %d", &dp_table))
14848         ;
14849       else if (unformat (input, "vni %d", &vni))
14850         ;
14851       else if (unformat (input, "w %d", &w))
14852         {
14853           if (!curr_rloc)
14854             {
14855               errmsg ("No RLOC configured for setting priority/weight!");
14856               return -99;
14857             }
14858           curr_rloc->weight = w;
14859         }
14860       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14861                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14862         {
14863           rloc.is_ip4 = 1;
14864
14865           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14866           rloc.weight = 0;
14867           vec_add1 (lcl_locs, rloc);
14868
14869           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14870           vec_add1 (rmt_locs, rloc);
14871           /* weight saved in rmt loc */
14872           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14873         }
14874       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14875                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14876         {
14877           rloc.is_ip4 = 0;
14878           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14879           rloc.weight = 0;
14880           vec_add1 (lcl_locs, rloc);
14881
14882           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14883           vec_add1 (rmt_locs, rloc);
14884           /* weight saved in rmt loc */
14885           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14886         }
14887       else if (unformat (input, "action %d", &action))
14888         {
14889           ;
14890         }
14891       else
14892         {
14893           clib_warning ("parse error '%U'", format_unformat_error, input);
14894           return -99;
14895         }
14896     }
14897
14898   if (!rmt_eid_set)
14899     {
14900       errmsg ("remote eid addresses not set");
14901       return -99;
14902     }
14903
14904   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14905     {
14906       errmsg ("eid types don't match");
14907       return -99;
14908     }
14909
14910   if (0 == rmt_locs && (u32) ~ 0 == action)
14911     {
14912       errmsg ("action not set for negative mapping");
14913       return -99;
14914     }
14915
14916   /* Construct the API message */
14917   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14918       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14919
14920   mp->is_add = is_add;
14921   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14922   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14923   mp->eid_type = rmt_eid->type;
14924   mp->dp_table = clib_host_to_net_u32 (dp_table);
14925   mp->vni = clib_host_to_net_u32 (vni);
14926   mp->rmt_len = rmt_eid->len;
14927   mp->lcl_len = lcl_eid->len;
14928   mp->action = action;
14929
14930   if (0 != rmt_locs && 0 != lcl_locs)
14931     {
14932       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14933       clib_memcpy (mp->locs, lcl_locs,
14934                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14935
14936       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14937       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14938                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14939     }
14940   vec_free (lcl_locs);
14941   vec_free (rmt_locs);
14942
14943   /* send it... */
14944   S (mp);
14945
14946   /* Wait for a reply... */
14947   W (ret);
14948   return ret;
14949 }
14950
14951 static int
14952 api_one_add_del_map_server (vat_main_t * vam)
14953 {
14954   unformat_input_t *input = vam->input;
14955   vl_api_one_add_del_map_server_t *mp;
14956   u8 is_add = 1;
14957   u8 ipv4_set = 0;
14958   u8 ipv6_set = 0;
14959   ip4_address_t ipv4;
14960   ip6_address_t ipv6;
14961   int ret;
14962
14963   /* Parse args required to build the message */
14964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14965     {
14966       if (unformat (input, "del"))
14967         {
14968           is_add = 0;
14969         }
14970       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14971         {
14972           ipv4_set = 1;
14973         }
14974       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14975         {
14976           ipv6_set = 1;
14977         }
14978       else
14979         break;
14980     }
14981
14982   if (ipv4_set && ipv6_set)
14983     {
14984       errmsg ("both eid v4 and v6 addresses set");
14985       return -99;
14986     }
14987
14988   if (!ipv4_set && !ipv6_set)
14989     {
14990       errmsg ("eid addresses not set");
14991       return -99;
14992     }
14993
14994   /* Construct the API message */
14995   M (ONE_ADD_DEL_MAP_SERVER, mp);
14996
14997   mp->is_add = is_add;
14998   if (ipv6_set)
14999     {
15000       mp->is_ipv6 = 1;
15001       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15002     }
15003   else
15004     {
15005       mp->is_ipv6 = 0;
15006       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15007     }
15008
15009   /* send it... */
15010   S (mp);
15011
15012   /* Wait for a reply... */
15013   W (ret);
15014   return ret;
15015 }
15016
15017 #define api_lisp_add_del_map_server api_one_add_del_map_server
15018
15019 static int
15020 api_one_add_del_map_resolver (vat_main_t * vam)
15021 {
15022   unformat_input_t *input = vam->input;
15023   vl_api_one_add_del_map_resolver_t *mp;
15024   u8 is_add = 1;
15025   u8 ipv4_set = 0;
15026   u8 ipv6_set = 0;
15027   ip4_address_t ipv4;
15028   ip6_address_t ipv6;
15029   int ret;
15030
15031   /* Parse args required to build the message */
15032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15033     {
15034       if (unformat (input, "del"))
15035         {
15036           is_add = 0;
15037         }
15038       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15039         {
15040           ipv4_set = 1;
15041         }
15042       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15043         {
15044           ipv6_set = 1;
15045         }
15046       else
15047         break;
15048     }
15049
15050   if (ipv4_set && ipv6_set)
15051     {
15052       errmsg ("both eid v4 and v6 addresses set");
15053       return -99;
15054     }
15055
15056   if (!ipv4_set && !ipv6_set)
15057     {
15058       errmsg ("eid addresses not set");
15059       return -99;
15060     }
15061
15062   /* Construct the API message */
15063   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15064
15065   mp->is_add = is_add;
15066   if (ipv6_set)
15067     {
15068       mp->is_ipv6 = 1;
15069       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15070     }
15071   else
15072     {
15073       mp->is_ipv6 = 0;
15074       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15075     }
15076
15077   /* send it... */
15078   S (mp);
15079
15080   /* Wait for a reply... */
15081   W (ret);
15082   return ret;
15083 }
15084
15085 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15086
15087 static int
15088 api_lisp_gpe_enable_disable (vat_main_t * vam)
15089 {
15090   unformat_input_t *input = vam->input;
15091   vl_api_gpe_enable_disable_t *mp;
15092   u8 is_set = 0;
15093   u8 is_en = 1;
15094   int ret;
15095
15096   /* Parse args required to build the message */
15097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15098     {
15099       if (unformat (input, "enable"))
15100         {
15101           is_set = 1;
15102           is_en = 1;
15103         }
15104       else if (unformat (input, "disable"))
15105         {
15106           is_set = 1;
15107           is_en = 0;
15108         }
15109       else
15110         break;
15111     }
15112
15113   if (is_set == 0)
15114     {
15115       errmsg ("Value not set");
15116       return -99;
15117     }
15118
15119   /* Construct the API message */
15120   M (GPE_ENABLE_DISABLE, mp);
15121
15122   mp->is_en = is_en;
15123
15124   /* send it... */
15125   S (mp);
15126
15127   /* Wait for a reply... */
15128   W (ret);
15129   return ret;
15130 }
15131
15132 static int
15133 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15134 {
15135   unformat_input_t *input = vam->input;
15136   vl_api_one_rloc_probe_enable_disable_t *mp;
15137   u8 is_set = 0;
15138   u8 is_en = 0;
15139   int ret;
15140
15141   /* Parse args required to build the message */
15142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15143     {
15144       if (unformat (input, "enable"))
15145         {
15146           is_set = 1;
15147           is_en = 1;
15148         }
15149       else if (unformat (input, "disable"))
15150         is_set = 1;
15151       else
15152         break;
15153     }
15154
15155   if (!is_set)
15156     {
15157       errmsg ("Value not set");
15158       return -99;
15159     }
15160
15161   /* Construct the API message */
15162   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15163
15164   mp->is_enabled = is_en;
15165
15166   /* send it... */
15167   S (mp);
15168
15169   /* Wait for a reply... */
15170   W (ret);
15171   return ret;
15172 }
15173
15174 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15175
15176 static int
15177 api_one_map_register_enable_disable (vat_main_t * vam)
15178 {
15179   unformat_input_t *input = vam->input;
15180   vl_api_one_map_register_enable_disable_t *mp;
15181   u8 is_set = 0;
15182   u8 is_en = 0;
15183   int ret;
15184
15185   /* Parse args required to build the message */
15186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15187     {
15188       if (unformat (input, "enable"))
15189         {
15190           is_set = 1;
15191           is_en = 1;
15192         }
15193       else if (unformat (input, "disable"))
15194         is_set = 1;
15195       else
15196         break;
15197     }
15198
15199   if (!is_set)
15200     {
15201       errmsg ("Value not set");
15202       return -99;
15203     }
15204
15205   /* Construct the API message */
15206   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15207
15208   mp->is_enabled = is_en;
15209
15210   /* send it... */
15211   S (mp);
15212
15213   /* Wait for a reply... */
15214   W (ret);
15215   return ret;
15216 }
15217
15218 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15219
15220 static int
15221 api_one_enable_disable (vat_main_t * vam)
15222 {
15223   unformat_input_t *input = vam->input;
15224   vl_api_one_enable_disable_t *mp;
15225   u8 is_set = 0;
15226   u8 is_en = 0;
15227   int ret;
15228
15229   /* Parse args required to build the message */
15230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15231     {
15232       if (unformat (input, "enable"))
15233         {
15234           is_set = 1;
15235           is_en = 1;
15236         }
15237       else if (unformat (input, "disable"))
15238         {
15239           is_set = 1;
15240         }
15241       else
15242         break;
15243     }
15244
15245   if (!is_set)
15246     {
15247       errmsg ("Value not set");
15248       return -99;
15249     }
15250
15251   /* Construct the API message */
15252   M (ONE_ENABLE_DISABLE, mp);
15253
15254   mp->is_en = is_en;
15255
15256   /* send it... */
15257   S (mp);
15258
15259   /* Wait for a reply... */
15260   W (ret);
15261   return ret;
15262 }
15263
15264 #define api_lisp_enable_disable api_one_enable_disable
15265
15266 static int
15267 api_show_one_map_register_state (vat_main_t * vam)
15268 {
15269   vl_api_show_one_map_register_state_t *mp;
15270   int ret;
15271
15272   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15273
15274   /* send */
15275   S (mp);
15276
15277   /* wait for reply */
15278   W (ret);
15279   return ret;
15280 }
15281
15282 #define api_show_lisp_map_register_state api_show_one_map_register_state
15283
15284 static int
15285 api_show_one_rloc_probe_state (vat_main_t * vam)
15286 {
15287   vl_api_show_one_rloc_probe_state_t *mp;
15288   int ret;
15289
15290   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15291
15292   /* send */
15293   S (mp);
15294
15295   /* wait for reply */
15296   W (ret);
15297   return ret;
15298 }
15299
15300 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15301
15302 static int
15303 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15304 {
15305   vl_api_one_add_del_l2_arp_entry_t *mp;
15306   unformat_input_t *input = vam->input;
15307   u8 is_add = 1;
15308   u8 mac_set = 0;
15309   u8 bd_set = 0;
15310   u8 ip_set = 0;
15311   u8 mac[6] = { 0, };
15312   u32 ip4 = 0, bd = ~0;
15313   int ret;
15314
15315   /* Parse args required to build the message */
15316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15317     {
15318       if (unformat (input, "del"))
15319         is_add = 0;
15320       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15321         mac_set = 1;
15322       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15323         ip_set = 1;
15324       else if (unformat (input, "bd %d", &bd))
15325         bd_set = 1;
15326       else
15327         {
15328           errmsg ("parse error '%U'", format_unformat_error, input);
15329           return -99;
15330         }
15331     }
15332
15333   if (!bd_set || !ip_set || (!mac_set && is_add))
15334     {
15335       errmsg ("Missing BD, IP or MAC!");
15336       return -99;
15337     }
15338
15339   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15340   mp->is_add = is_add;
15341   clib_memcpy (mp->mac, mac, 6);
15342   mp->bd = clib_host_to_net_u32 (bd);
15343   mp->ip4 = ip4;
15344
15345   /* send */
15346   S (mp);
15347
15348   /* wait for reply */
15349   W (ret);
15350   return ret;
15351 }
15352
15353 static int
15354 api_one_l2_arp_bd_get (vat_main_t * vam)
15355 {
15356   vl_api_one_l2_arp_bd_get_t *mp;
15357   int ret;
15358
15359   M (ONE_L2_ARP_BD_GET, mp);
15360
15361   /* send */
15362   S (mp);
15363
15364   /* wait for reply */
15365   W (ret);
15366   return ret;
15367 }
15368
15369 static int
15370 api_one_l2_arp_entries_get (vat_main_t * vam)
15371 {
15372   vl_api_one_l2_arp_entries_get_t *mp;
15373   unformat_input_t *input = vam->input;
15374   u8 bd_set = 0;
15375   u32 bd = ~0;
15376   int ret;
15377
15378   /* Parse args required to build the message */
15379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15380     {
15381       if (unformat (input, "bd %d", &bd))
15382         bd_set = 1;
15383       else
15384         {
15385           errmsg ("parse error '%U'", format_unformat_error, input);
15386           return -99;
15387         }
15388     }
15389
15390   if (!bd_set)
15391     {
15392       errmsg ("Expected bridge domain!");
15393       return -99;
15394     }
15395
15396   M (ONE_L2_ARP_ENTRIES_GET, mp);
15397   mp->bd = clib_host_to_net_u32 (bd);
15398
15399   /* send */
15400   S (mp);
15401
15402   /* wait for reply */
15403   W (ret);
15404   return ret;
15405 }
15406
15407 static int
15408 api_one_stats_enable_disable (vat_main_t * vam)
15409 {
15410   vl_api_one_stats_enable_disable_t *mp;
15411   unformat_input_t *input = vam->input;
15412   u8 is_set = 0;
15413   u8 is_en = 0;
15414   int ret;
15415
15416   /* Parse args required to build the message */
15417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15418     {
15419       if (unformat (input, "enable"))
15420         {
15421           is_set = 1;
15422           is_en = 1;
15423         }
15424       else if (unformat (input, "disable"))
15425         {
15426           is_set = 1;
15427         }
15428       else
15429         break;
15430     }
15431
15432   if (!is_set)
15433     {
15434       errmsg ("Value not set");
15435       return -99;
15436     }
15437
15438   M (ONE_STATS_ENABLE_DISABLE, mp);
15439   mp->is_en = is_en;
15440
15441   /* send */
15442   S (mp);
15443
15444   /* wait for reply */
15445   W (ret);
15446   return ret;
15447 }
15448
15449 static int
15450 api_show_one_stats_enable_disable (vat_main_t * vam)
15451 {
15452   vl_api_show_one_stats_enable_disable_t *mp;
15453   int ret;
15454
15455   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15456
15457   /* send */
15458   S (mp);
15459
15460   /* wait for reply */
15461   W (ret);
15462   return ret;
15463 }
15464
15465 static int
15466 api_show_one_map_request_mode (vat_main_t * vam)
15467 {
15468   vl_api_show_one_map_request_mode_t *mp;
15469   int ret;
15470
15471   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15472
15473   /* send */
15474   S (mp);
15475
15476   /* wait for reply */
15477   W (ret);
15478   return ret;
15479 }
15480
15481 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15482
15483 static int
15484 api_one_map_request_mode (vat_main_t * vam)
15485 {
15486   unformat_input_t *input = vam->input;
15487   vl_api_one_map_request_mode_t *mp;
15488   u8 mode = 0;
15489   int ret;
15490
15491   /* Parse args required to build the message */
15492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15493     {
15494       if (unformat (input, "dst-only"))
15495         mode = 0;
15496       else if (unformat (input, "src-dst"))
15497         mode = 1;
15498       else
15499         {
15500           errmsg ("parse error '%U'", format_unformat_error, input);
15501           return -99;
15502         }
15503     }
15504
15505   M (ONE_MAP_REQUEST_MODE, mp);
15506
15507   mp->mode = mode;
15508
15509   /* send */
15510   S (mp);
15511
15512   /* wait for reply */
15513   W (ret);
15514   return ret;
15515 }
15516
15517 #define api_lisp_map_request_mode api_one_map_request_mode
15518
15519 /**
15520  * Enable/disable ONE proxy ITR.
15521  *
15522  * @param vam vpp API test context
15523  * @return return code
15524  */
15525 static int
15526 api_one_pitr_set_locator_set (vat_main_t * vam)
15527 {
15528   u8 ls_name_set = 0;
15529   unformat_input_t *input = vam->input;
15530   vl_api_one_pitr_set_locator_set_t *mp;
15531   u8 is_add = 1;
15532   u8 *ls_name = 0;
15533   int ret;
15534
15535   /* Parse args required to build the message */
15536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15537     {
15538       if (unformat (input, "del"))
15539         is_add = 0;
15540       else if (unformat (input, "locator-set %s", &ls_name))
15541         ls_name_set = 1;
15542       else
15543         {
15544           errmsg ("parse error '%U'", format_unformat_error, input);
15545           return -99;
15546         }
15547     }
15548
15549   if (!ls_name_set)
15550     {
15551       errmsg ("locator-set name not set!");
15552       return -99;
15553     }
15554
15555   M (ONE_PITR_SET_LOCATOR_SET, mp);
15556
15557   mp->is_add = is_add;
15558   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15559   vec_free (ls_name);
15560
15561   /* send */
15562   S (mp);
15563
15564   /* wait for reply */
15565   W (ret);
15566   return ret;
15567 }
15568
15569 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15570
15571 static int
15572 api_one_nsh_set_locator_set (vat_main_t * vam)
15573 {
15574   u8 ls_name_set = 0;
15575   unformat_input_t *input = vam->input;
15576   vl_api_one_nsh_set_locator_set_t *mp;
15577   u8 is_add = 1;
15578   u8 *ls_name = 0;
15579   int ret;
15580
15581   /* Parse args required to build the message */
15582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15583     {
15584       if (unformat (input, "del"))
15585         is_add = 0;
15586       else if (unformat (input, "ls %s", &ls_name))
15587         ls_name_set = 1;
15588       else
15589         {
15590           errmsg ("parse error '%U'", format_unformat_error, input);
15591           return -99;
15592         }
15593     }
15594
15595   if (!ls_name_set && is_add)
15596     {
15597       errmsg ("locator-set name not set!");
15598       return -99;
15599     }
15600
15601   M (ONE_NSH_SET_LOCATOR_SET, mp);
15602
15603   mp->is_add = is_add;
15604   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15605   vec_free (ls_name);
15606
15607   /* send */
15608   S (mp);
15609
15610   /* wait for reply */
15611   W (ret);
15612   return ret;
15613 }
15614
15615 static int
15616 api_show_one_pitr (vat_main_t * vam)
15617 {
15618   vl_api_show_one_pitr_t *mp;
15619   int ret;
15620
15621   if (!vam->json_output)
15622     {
15623       print (vam->ofp, "%=20s", "lisp status:");
15624     }
15625
15626   M (SHOW_ONE_PITR, mp);
15627   /* send it... */
15628   S (mp);
15629
15630   /* Wait for a reply... */
15631   W (ret);
15632   return ret;
15633 }
15634
15635 #define api_show_lisp_pitr api_show_one_pitr
15636
15637 static int
15638 api_one_use_petr (vat_main_t * vam)
15639 {
15640   unformat_input_t *input = vam->input;
15641   vl_api_one_use_petr_t *mp;
15642   u8 is_add = 0;
15643   ip_address_t ip;
15644   int ret;
15645
15646   memset (&ip, 0, sizeof (ip));
15647
15648   /* Parse args required to build the message */
15649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15650     {
15651       if (unformat (input, "disable"))
15652         is_add = 0;
15653       else
15654         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15655         {
15656           is_add = 1;
15657           ip_addr_version (&ip) = IP4;
15658         }
15659       else
15660         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15661         {
15662           is_add = 1;
15663           ip_addr_version (&ip) = IP6;
15664         }
15665       else
15666         {
15667           errmsg ("parse error '%U'", format_unformat_error, input);
15668           return -99;
15669         }
15670     }
15671
15672   M (ONE_USE_PETR, mp);
15673
15674   mp->is_add = is_add;
15675   if (is_add)
15676     {
15677       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15678       if (mp->is_ip4)
15679         clib_memcpy (mp->address, &ip, 4);
15680       else
15681         clib_memcpy (mp->address, &ip, 16);
15682     }
15683
15684   /* send */
15685   S (mp);
15686
15687   /* wait for reply */
15688   W (ret);
15689   return ret;
15690 }
15691
15692 #define api_lisp_use_petr api_one_use_petr
15693
15694 static int
15695 api_show_one_nsh_mapping (vat_main_t * vam)
15696 {
15697   vl_api_show_one_use_petr_t *mp;
15698   int ret;
15699
15700   if (!vam->json_output)
15701     {
15702       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15703     }
15704
15705   M (SHOW_ONE_NSH_MAPPING, mp);
15706   /* send it... */
15707   S (mp);
15708
15709   /* Wait for a reply... */
15710   W (ret);
15711   return ret;
15712 }
15713
15714 static int
15715 api_show_one_use_petr (vat_main_t * vam)
15716 {
15717   vl_api_show_one_use_petr_t *mp;
15718   int ret;
15719
15720   if (!vam->json_output)
15721     {
15722       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15723     }
15724
15725   M (SHOW_ONE_USE_PETR, mp);
15726   /* send it... */
15727   S (mp);
15728
15729   /* Wait for a reply... */
15730   W (ret);
15731   return ret;
15732 }
15733
15734 #define api_show_lisp_use_petr api_show_one_use_petr
15735
15736 /**
15737  * Add/delete mapping between vni and vrf
15738  */
15739 static int
15740 api_one_eid_table_add_del_map (vat_main_t * vam)
15741 {
15742   unformat_input_t *input = vam->input;
15743   vl_api_one_eid_table_add_del_map_t *mp;
15744   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15745   u32 vni, vrf, bd_index;
15746   int ret;
15747
15748   /* Parse args required to build the message */
15749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15750     {
15751       if (unformat (input, "del"))
15752         is_add = 0;
15753       else if (unformat (input, "vrf %d", &vrf))
15754         vrf_set = 1;
15755       else if (unformat (input, "bd_index %d", &bd_index))
15756         bd_index_set = 1;
15757       else if (unformat (input, "vni %d", &vni))
15758         vni_set = 1;
15759       else
15760         break;
15761     }
15762
15763   if (!vni_set || (!vrf_set && !bd_index_set))
15764     {
15765       errmsg ("missing arguments!");
15766       return -99;
15767     }
15768
15769   if (vrf_set && bd_index_set)
15770     {
15771       errmsg ("error: both vrf and bd entered!");
15772       return -99;
15773     }
15774
15775   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15776
15777   mp->is_add = is_add;
15778   mp->vni = htonl (vni);
15779   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15780   mp->is_l2 = bd_index_set;
15781
15782   /* send */
15783   S (mp);
15784
15785   /* wait for reply */
15786   W (ret);
15787   return ret;
15788 }
15789
15790 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15791
15792 uword
15793 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15794 {
15795   u32 *action = va_arg (*args, u32 *);
15796   u8 *s = 0;
15797
15798   if (unformat (input, "%s", &s))
15799     {
15800       if (!strcmp ((char *) s, "no-action"))
15801         action[0] = 0;
15802       else if (!strcmp ((char *) s, "natively-forward"))
15803         action[0] = 1;
15804       else if (!strcmp ((char *) s, "send-map-request"))
15805         action[0] = 2;
15806       else if (!strcmp ((char *) s, "drop"))
15807         action[0] = 3;
15808       else
15809         {
15810           clib_warning ("invalid action: '%s'", s);
15811           action[0] = 3;
15812         }
15813     }
15814   else
15815     return 0;
15816
15817   vec_free (s);
15818   return 1;
15819 }
15820
15821 /**
15822  * Add/del remote mapping to/from ONE control plane
15823  *
15824  * @param vam vpp API test context
15825  * @return return code
15826  */
15827 static int
15828 api_one_add_del_remote_mapping (vat_main_t * vam)
15829 {
15830   unformat_input_t *input = vam->input;
15831   vl_api_one_add_del_remote_mapping_t *mp;
15832   u32 vni = 0;
15833   lisp_eid_vat_t _eid, *eid = &_eid;
15834   lisp_eid_vat_t _seid, *seid = &_seid;
15835   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15836   u32 action = ~0, p, w, data_len;
15837   ip4_address_t rloc4;
15838   ip6_address_t rloc6;
15839   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15840   int ret;
15841
15842   memset (&rloc, 0, sizeof (rloc));
15843
15844   /* Parse args required to build the message */
15845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15846     {
15847       if (unformat (input, "del-all"))
15848         {
15849           del_all = 1;
15850         }
15851       else if (unformat (input, "del"))
15852         {
15853           is_add = 0;
15854         }
15855       else if (unformat (input, "add"))
15856         {
15857           is_add = 1;
15858         }
15859       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15860         {
15861           eid_set = 1;
15862         }
15863       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15864         {
15865           seid_set = 1;
15866         }
15867       else if (unformat (input, "vni %d", &vni))
15868         {
15869           ;
15870         }
15871       else if (unformat (input, "p %d w %d", &p, &w))
15872         {
15873           if (!curr_rloc)
15874             {
15875               errmsg ("No RLOC configured for setting priority/weight!");
15876               return -99;
15877             }
15878           curr_rloc->priority = p;
15879           curr_rloc->weight = w;
15880         }
15881       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15882         {
15883           rloc.is_ip4 = 1;
15884           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15885           vec_add1 (rlocs, rloc);
15886           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15887         }
15888       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15889         {
15890           rloc.is_ip4 = 0;
15891           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15892           vec_add1 (rlocs, rloc);
15893           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15894         }
15895       else if (unformat (input, "action %U",
15896                          unformat_negative_mapping_action, &action))
15897         {
15898           ;
15899         }
15900       else
15901         {
15902           clib_warning ("parse error '%U'", format_unformat_error, input);
15903           return -99;
15904         }
15905     }
15906
15907   if (0 == eid_set)
15908     {
15909       errmsg ("missing params!");
15910       return -99;
15911     }
15912
15913   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15914     {
15915       errmsg ("no action set for negative map-reply!");
15916       return -99;
15917     }
15918
15919   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15920
15921   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15922   mp->is_add = is_add;
15923   mp->vni = htonl (vni);
15924   mp->action = (u8) action;
15925   mp->is_src_dst = seid_set;
15926   mp->eid_len = eid->len;
15927   mp->seid_len = seid->len;
15928   mp->del_all = del_all;
15929   mp->eid_type = eid->type;
15930   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15931   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15932
15933   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15934   clib_memcpy (mp->rlocs, rlocs, data_len);
15935   vec_free (rlocs);
15936
15937   /* send it... */
15938   S (mp);
15939
15940   /* Wait for a reply... */
15941   W (ret);
15942   return ret;
15943 }
15944
15945 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15946
15947 /**
15948  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15949  * forwarding entries in data-plane accordingly.
15950  *
15951  * @param vam vpp API test context
15952  * @return return code
15953  */
15954 static int
15955 api_one_add_del_adjacency (vat_main_t * vam)
15956 {
15957   unformat_input_t *input = vam->input;
15958   vl_api_one_add_del_adjacency_t *mp;
15959   u32 vni = 0;
15960   ip4_address_t leid4, reid4;
15961   ip6_address_t leid6, reid6;
15962   u8 reid_mac[6] = { 0 };
15963   u8 leid_mac[6] = { 0 };
15964   u8 reid_type, leid_type;
15965   u32 leid_len = 0, reid_len = 0, len;
15966   u8 is_add = 1;
15967   int ret;
15968
15969   leid_type = reid_type = (u8) ~ 0;
15970
15971   /* Parse args required to build the message */
15972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15973     {
15974       if (unformat (input, "del"))
15975         {
15976           is_add = 0;
15977         }
15978       else if (unformat (input, "add"))
15979         {
15980           is_add = 1;
15981         }
15982       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15983                          &reid4, &len))
15984         {
15985           reid_type = 0;        /* ipv4 */
15986           reid_len = len;
15987         }
15988       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15989                          &reid6, &len))
15990         {
15991           reid_type = 1;        /* ipv6 */
15992           reid_len = len;
15993         }
15994       else if (unformat (input, "reid %U", unformat_ethernet_address,
15995                          reid_mac))
15996         {
15997           reid_type = 2;        /* mac */
15998         }
15999       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16000                          &leid4, &len))
16001         {
16002           leid_type = 0;        /* ipv4 */
16003           leid_len = len;
16004         }
16005       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16006                          &leid6, &len))
16007         {
16008           leid_type = 1;        /* ipv6 */
16009           leid_len = len;
16010         }
16011       else if (unformat (input, "leid %U", unformat_ethernet_address,
16012                          leid_mac))
16013         {
16014           leid_type = 2;        /* mac */
16015         }
16016       else if (unformat (input, "vni %d", &vni))
16017         {
16018           ;
16019         }
16020       else
16021         {
16022           errmsg ("parse error '%U'", format_unformat_error, input);
16023           return -99;
16024         }
16025     }
16026
16027   if ((u8) ~ 0 == reid_type)
16028     {
16029       errmsg ("missing params!");
16030       return -99;
16031     }
16032
16033   if (leid_type != reid_type)
16034     {
16035       errmsg ("remote and local EIDs are of different types!");
16036       return -99;
16037     }
16038
16039   M (ONE_ADD_DEL_ADJACENCY, mp);
16040   mp->is_add = is_add;
16041   mp->vni = htonl (vni);
16042   mp->leid_len = leid_len;
16043   mp->reid_len = reid_len;
16044   mp->eid_type = reid_type;
16045
16046   switch (mp->eid_type)
16047     {
16048     case 0:
16049       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16050       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16051       break;
16052     case 1:
16053       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16054       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16055       break;
16056     case 2:
16057       clib_memcpy (mp->leid, leid_mac, 6);
16058       clib_memcpy (mp->reid, reid_mac, 6);
16059       break;
16060     default:
16061       errmsg ("unknown EID type %d!", mp->eid_type);
16062       return 0;
16063     }
16064
16065   /* send it... */
16066   S (mp);
16067
16068   /* Wait for a reply... */
16069   W (ret);
16070   return ret;
16071 }
16072
16073 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16074
16075 uword
16076 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16077 {
16078   u32 *mode = va_arg (*args, u32 *);
16079
16080   if (unformat (input, "lisp"))
16081     *mode = 0;
16082   else if (unformat (input, "vxlan"))
16083     *mode = 1;
16084   else
16085     return 0;
16086
16087   return 1;
16088 }
16089
16090 static int
16091 api_gpe_get_encap_mode (vat_main_t * vam)
16092 {
16093   vl_api_gpe_get_encap_mode_t *mp;
16094   int ret;
16095
16096   /* Construct the API message */
16097   M (GPE_GET_ENCAP_MODE, mp);
16098
16099   /* send it... */
16100   S (mp);
16101
16102   /* Wait for a reply... */
16103   W (ret);
16104   return ret;
16105 }
16106
16107 static int
16108 api_gpe_set_encap_mode (vat_main_t * vam)
16109 {
16110   unformat_input_t *input = vam->input;
16111   vl_api_gpe_set_encap_mode_t *mp;
16112   int ret;
16113   u32 mode = 0;
16114
16115   /* Parse args required to build the message */
16116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16117     {
16118       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16119         ;
16120       else
16121         break;
16122     }
16123
16124   /* Construct the API message */
16125   M (GPE_SET_ENCAP_MODE, mp);
16126
16127   mp->mode = mode;
16128
16129   /* send it... */
16130   S (mp);
16131
16132   /* Wait for a reply... */
16133   W (ret);
16134   return ret;
16135 }
16136
16137 static int
16138 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16139 {
16140   unformat_input_t *input = vam->input;
16141   vl_api_gpe_add_del_iface_t *mp;
16142   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16143   u32 dp_table = 0, vni = 0;
16144   int ret;
16145
16146   /* Parse args required to build the message */
16147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16148     {
16149       if (unformat (input, "up"))
16150         {
16151           action_set = 1;
16152           is_add = 1;
16153         }
16154       else if (unformat (input, "down"))
16155         {
16156           action_set = 1;
16157           is_add = 0;
16158         }
16159       else if (unformat (input, "table_id %d", &dp_table))
16160         {
16161           dp_table_set = 1;
16162         }
16163       else if (unformat (input, "bd_id %d", &dp_table))
16164         {
16165           dp_table_set = 1;
16166           is_l2 = 1;
16167         }
16168       else if (unformat (input, "vni %d", &vni))
16169         {
16170           vni_set = 1;
16171         }
16172       else
16173         break;
16174     }
16175
16176   if (action_set == 0)
16177     {
16178       errmsg ("Action not set");
16179       return -99;
16180     }
16181   if (dp_table_set == 0 || vni_set == 0)
16182     {
16183       errmsg ("vni and dp_table must be set");
16184       return -99;
16185     }
16186
16187   /* Construct the API message */
16188   M (GPE_ADD_DEL_IFACE, mp);
16189
16190   mp->is_add = is_add;
16191   mp->dp_table = clib_host_to_net_u32 (dp_table);
16192   mp->is_l2 = is_l2;
16193   mp->vni = clib_host_to_net_u32 (vni);
16194
16195   /* send it... */
16196   S (mp);
16197
16198   /* Wait for a reply... */
16199   W (ret);
16200   return ret;
16201 }
16202
16203 static int
16204 api_one_map_register_fallback_threshold (vat_main_t * vam)
16205 {
16206   unformat_input_t *input = vam->input;
16207   vl_api_one_map_register_fallback_threshold_t *mp;
16208   u32 value = 0;
16209   u8 is_set = 0;
16210   int ret;
16211
16212   /* Parse args required to build the message */
16213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16214     {
16215       if (unformat (input, "%u", &value))
16216         is_set = 1;
16217       else
16218         {
16219           clib_warning ("parse error '%U'", format_unformat_error, input);
16220           return -99;
16221         }
16222     }
16223
16224   if (!is_set)
16225     {
16226       errmsg ("fallback threshold value is missing!");
16227       return -99;
16228     }
16229
16230   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16231   mp->value = clib_host_to_net_u32 (value);
16232
16233   /* send it... */
16234   S (mp);
16235
16236   /* Wait for a reply... */
16237   W (ret);
16238   return ret;
16239 }
16240
16241 static int
16242 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16243 {
16244   vl_api_show_one_map_register_fallback_threshold_t *mp;
16245   int ret;
16246
16247   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16248
16249   /* send it... */
16250   S (mp);
16251
16252   /* Wait for a reply... */
16253   W (ret);
16254   return ret;
16255 }
16256
16257 static int
16258 api_one_map_register_set_ttl (vat_main_t * vam)
16259 {
16260   unformat_input_t *input = vam->input;
16261   vl_api_one_map_register_set_ttl_t *mp;
16262   u32 ttl = 0;
16263   u8 is_set = 0;
16264   int ret;
16265
16266   /* Parse args required to build the message */
16267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16268     {
16269       if (unformat (input, "%u", &ttl))
16270         is_set = 1;
16271       else
16272         {
16273           clib_warning ("parse error '%U'", format_unformat_error, input);
16274           return -99;
16275         }
16276     }
16277
16278   if (!is_set)
16279     {
16280       errmsg ("TTL value missing!");
16281       return -99;
16282     }
16283
16284   M (ONE_MAP_REGISTER_SET_TTL, mp);
16285   mp->ttl = clib_host_to_net_u32 (ttl);
16286
16287   /* send it... */
16288   S (mp);
16289
16290   /* Wait for a reply... */
16291   W (ret);
16292   return ret;
16293 }
16294
16295 static int
16296 api_show_one_map_register_ttl (vat_main_t * vam)
16297 {
16298   vl_api_show_one_map_register_ttl_t *mp;
16299   int ret;
16300
16301   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16302
16303   /* send it... */
16304   S (mp);
16305
16306   /* Wait for a reply... */
16307   W (ret);
16308   return ret;
16309 }
16310
16311 /**
16312  * Add/del map request itr rlocs from ONE control plane and updates
16313  *
16314  * @param vam vpp API test context
16315  * @return return code
16316  */
16317 static int
16318 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16319 {
16320   unformat_input_t *input = vam->input;
16321   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16322   u8 *locator_set_name = 0;
16323   u8 locator_set_name_set = 0;
16324   u8 is_add = 1;
16325   int ret;
16326
16327   /* Parse args required to build the message */
16328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16329     {
16330       if (unformat (input, "del"))
16331         {
16332           is_add = 0;
16333         }
16334       else if (unformat (input, "%_%v%_", &locator_set_name))
16335         {
16336           locator_set_name_set = 1;
16337         }
16338       else
16339         {
16340           clib_warning ("parse error '%U'", format_unformat_error, input);
16341           return -99;
16342         }
16343     }
16344
16345   if (is_add && !locator_set_name_set)
16346     {
16347       errmsg ("itr-rloc is not set!");
16348       return -99;
16349     }
16350
16351   if (is_add && vec_len (locator_set_name) > 64)
16352     {
16353       errmsg ("itr-rloc locator-set name too long");
16354       vec_free (locator_set_name);
16355       return -99;
16356     }
16357
16358   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16359   mp->is_add = is_add;
16360   if (is_add)
16361     {
16362       clib_memcpy (mp->locator_set_name, locator_set_name,
16363                    vec_len (locator_set_name));
16364     }
16365   else
16366     {
16367       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16368     }
16369   vec_free (locator_set_name);
16370
16371   /* send it... */
16372   S (mp);
16373
16374   /* Wait for a reply... */
16375   W (ret);
16376   return ret;
16377 }
16378
16379 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16380
16381 static int
16382 api_one_locator_dump (vat_main_t * vam)
16383 {
16384   unformat_input_t *input = vam->input;
16385   vl_api_one_locator_dump_t *mp;
16386   vl_api_control_ping_t *mp_ping;
16387   u8 is_index_set = 0, is_name_set = 0;
16388   u8 *ls_name = 0;
16389   u32 ls_index = ~0;
16390   int ret;
16391
16392   /* Parse args required to build the message */
16393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16394     {
16395       if (unformat (input, "ls_name %_%v%_", &ls_name))
16396         {
16397           is_name_set = 1;
16398         }
16399       else if (unformat (input, "ls_index %d", &ls_index))
16400         {
16401           is_index_set = 1;
16402         }
16403       else
16404         {
16405           errmsg ("parse error '%U'", format_unformat_error, input);
16406           return -99;
16407         }
16408     }
16409
16410   if (!is_index_set && !is_name_set)
16411     {
16412       errmsg ("error: expected one of index or name!");
16413       return -99;
16414     }
16415
16416   if (is_index_set && is_name_set)
16417     {
16418       errmsg ("error: only one param expected!");
16419       return -99;
16420     }
16421
16422   if (vec_len (ls_name) > 62)
16423     {
16424       errmsg ("error: locator set name too long!");
16425       return -99;
16426     }
16427
16428   if (!vam->json_output)
16429     {
16430       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16431     }
16432
16433   M (ONE_LOCATOR_DUMP, mp);
16434   mp->is_index_set = is_index_set;
16435
16436   if (is_index_set)
16437     mp->ls_index = clib_host_to_net_u32 (ls_index);
16438   else
16439     {
16440       vec_add1 (ls_name, 0);
16441       strncpy ((char *) mp->ls_name, (char *) ls_name,
16442                sizeof (mp->ls_name) - 1);
16443     }
16444
16445   /* send it... */
16446   S (mp);
16447
16448   /* Use a control ping for synchronization */
16449   M (CONTROL_PING, mp_ping);
16450   S (mp_ping);
16451
16452   /* Wait for a reply... */
16453   W (ret);
16454   return ret;
16455 }
16456
16457 #define api_lisp_locator_dump api_one_locator_dump
16458
16459 static int
16460 api_one_locator_set_dump (vat_main_t * vam)
16461 {
16462   vl_api_one_locator_set_dump_t *mp;
16463   vl_api_control_ping_t *mp_ping;
16464   unformat_input_t *input = vam->input;
16465   u8 filter = 0;
16466   int ret;
16467
16468   /* Parse args required to build the message */
16469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16470     {
16471       if (unformat (input, "local"))
16472         {
16473           filter = 1;
16474         }
16475       else if (unformat (input, "remote"))
16476         {
16477           filter = 2;
16478         }
16479       else
16480         {
16481           errmsg ("parse error '%U'", format_unformat_error, input);
16482           return -99;
16483         }
16484     }
16485
16486   if (!vam->json_output)
16487     {
16488       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16489     }
16490
16491   M (ONE_LOCATOR_SET_DUMP, mp);
16492
16493   mp->filter = filter;
16494
16495   /* send it... */
16496   S (mp);
16497
16498   /* Use a control ping for synchronization */
16499   M (CONTROL_PING, mp_ping);
16500   S (mp_ping);
16501
16502   /* Wait for a reply... */
16503   W (ret);
16504   return ret;
16505 }
16506
16507 #define api_lisp_locator_set_dump api_one_locator_set_dump
16508
16509 static int
16510 api_one_eid_table_map_dump (vat_main_t * vam)
16511 {
16512   u8 is_l2 = 0;
16513   u8 mode_set = 0;
16514   unformat_input_t *input = vam->input;
16515   vl_api_one_eid_table_map_dump_t *mp;
16516   vl_api_control_ping_t *mp_ping;
16517   int ret;
16518
16519   /* Parse args required to build the message */
16520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16521     {
16522       if (unformat (input, "l2"))
16523         {
16524           is_l2 = 1;
16525           mode_set = 1;
16526         }
16527       else if (unformat (input, "l3"))
16528         {
16529           is_l2 = 0;
16530           mode_set = 1;
16531         }
16532       else
16533         {
16534           errmsg ("parse error '%U'", format_unformat_error, input);
16535           return -99;
16536         }
16537     }
16538
16539   if (!mode_set)
16540     {
16541       errmsg ("expected one of 'l2' or 'l3' parameter!");
16542       return -99;
16543     }
16544
16545   if (!vam->json_output)
16546     {
16547       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16548     }
16549
16550   M (ONE_EID_TABLE_MAP_DUMP, mp);
16551   mp->is_l2 = is_l2;
16552
16553   /* send it... */
16554   S (mp);
16555
16556   /* Use a control ping for synchronization */
16557   M (CONTROL_PING, mp_ping);
16558   S (mp_ping);
16559
16560   /* Wait for a reply... */
16561   W (ret);
16562   return ret;
16563 }
16564
16565 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16566
16567 static int
16568 api_one_eid_table_vni_dump (vat_main_t * vam)
16569 {
16570   vl_api_one_eid_table_vni_dump_t *mp;
16571   vl_api_control_ping_t *mp_ping;
16572   int ret;
16573
16574   if (!vam->json_output)
16575     {
16576       print (vam->ofp, "VNI");
16577     }
16578
16579   M (ONE_EID_TABLE_VNI_DUMP, mp);
16580
16581   /* send it... */
16582   S (mp);
16583
16584   /* Use a control ping for synchronization */
16585   M (CONTROL_PING, mp_ping);
16586   S (mp_ping);
16587
16588   /* Wait for a reply... */
16589   W (ret);
16590   return ret;
16591 }
16592
16593 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16594
16595 static int
16596 api_one_eid_table_dump (vat_main_t * vam)
16597 {
16598   unformat_input_t *i = vam->input;
16599   vl_api_one_eid_table_dump_t *mp;
16600   vl_api_control_ping_t *mp_ping;
16601   struct in_addr ip4;
16602   struct in6_addr ip6;
16603   u8 mac[6];
16604   u8 eid_type = ~0, eid_set = 0;
16605   u32 prefix_length = ~0, t, vni = 0;
16606   u8 filter = 0;
16607   int ret;
16608   lisp_nsh_api_t nsh;
16609
16610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16611     {
16612       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16613         {
16614           eid_set = 1;
16615           eid_type = 0;
16616           prefix_length = t;
16617         }
16618       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16619         {
16620           eid_set = 1;
16621           eid_type = 1;
16622           prefix_length = t;
16623         }
16624       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16625         {
16626           eid_set = 1;
16627           eid_type = 2;
16628         }
16629       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16630         {
16631           eid_set = 1;
16632           eid_type = 3;
16633         }
16634       else if (unformat (i, "vni %d", &t))
16635         {
16636           vni = t;
16637         }
16638       else if (unformat (i, "local"))
16639         {
16640           filter = 1;
16641         }
16642       else if (unformat (i, "remote"))
16643         {
16644           filter = 2;
16645         }
16646       else
16647         {
16648           errmsg ("parse error '%U'", format_unformat_error, i);
16649           return -99;
16650         }
16651     }
16652
16653   if (!vam->json_output)
16654     {
16655       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16656              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16657     }
16658
16659   M (ONE_EID_TABLE_DUMP, mp);
16660
16661   mp->filter = filter;
16662   if (eid_set)
16663     {
16664       mp->eid_set = 1;
16665       mp->vni = htonl (vni);
16666       mp->eid_type = eid_type;
16667       switch (eid_type)
16668         {
16669         case 0:
16670           mp->prefix_length = prefix_length;
16671           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16672           break;
16673         case 1:
16674           mp->prefix_length = prefix_length;
16675           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16676           break;
16677         case 2:
16678           clib_memcpy (mp->eid, mac, sizeof (mac));
16679           break;
16680         case 3:
16681           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16682           break;
16683         default:
16684           errmsg ("unknown EID type %d!", eid_type);
16685           return -99;
16686         }
16687     }
16688
16689   /* send it... */
16690   S (mp);
16691
16692   /* Use a control ping for synchronization */
16693   M (CONTROL_PING, mp_ping);
16694   S (mp_ping);
16695
16696   /* Wait for a reply... */
16697   W (ret);
16698   return ret;
16699 }
16700
16701 #define api_lisp_eid_table_dump api_one_eid_table_dump
16702
16703 static int
16704 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16705 {
16706   unformat_input_t *i = vam->input;
16707   vl_api_gpe_fwd_entries_get_t *mp;
16708   u8 vni_set = 0;
16709   u32 vni = ~0;
16710   int ret;
16711
16712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16713     {
16714       if (unformat (i, "vni %d", &vni))
16715         {
16716           vni_set = 1;
16717         }
16718       else
16719         {
16720           errmsg ("parse error '%U'", format_unformat_error, i);
16721           return -99;
16722         }
16723     }
16724
16725   if (!vni_set)
16726     {
16727       errmsg ("vni not set!");
16728       return -99;
16729     }
16730
16731   if (!vam->json_output)
16732     {
16733       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16734              "leid", "reid");
16735     }
16736
16737   M (GPE_FWD_ENTRIES_GET, mp);
16738   mp->vni = clib_host_to_net_u32 (vni);
16739
16740   /* send it... */
16741   S (mp);
16742
16743   /* Wait for a reply... */
16744   W (ret);
16745   return ret;
16746 }
16747
16748 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16749 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16750 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16751 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16752 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16753 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16754 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16755 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16756
16757 static int
16758 api_one_adjacencies_get (vat_main_t * vam)
16759 {
16760   unformat_input_t *i = vam->input;
16761   vl_api_one_adjacencies_get_t *mp;
16762   u8 vni_set = 0;
16763   u32 vni = ~0;
16764   int ret;
16765
16766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16767     {
16768       if (unformat (i, "vni %d", &vni))
16769         {
16770           vni_set = 1;
16771         }
16772       else
16773         {
16774           errmsg ("parse error '%U'", format_unformat_error, i);
16775           return -99;
16776         }
16777     }
16778
16779   if (!vni_set)
16780     {
16781       errmsg ("vni not set!");
16782       return -99;
16783     }
16784
16785   if (!vam->json_output)
16786     {
16787       print (vam->ofp, "%s %40s", "leid", "reid");
16788     }
16789
16790   M (ONE_ADJACENCIES_GET, mp);
16791   mp->vni = clib_host_to_net_u32 (vni);
16792
16793   /* send it... */
16794   S (mp);
16795
16796   /* Wait for a reply... */
16797   W (ret);
16798   return ret;
16799 }
16800
16801 #define api_lisp_adjacencies_get api_one_adjacencies_get
16802
16803 static int
16804 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16805 {
16806   unformat_input_t *i = vam->input;
16807   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16808   int ret;
16809   u8 ip_family_set = 0, is_ip4 = 1;
16810
16811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16812     {
16813       if (unformat (i, "ip4"))
16814         {
16815           ip_family_set = 1;
16816           is_ip4 = 1;
16817         }
16818       else if (unformat (i, "ip6"))
16819         {
16820           ip_family_set = 1;
16821           is_ip4 = 0;
16822         }
16823       else
16824         {
16825           errmsg ("parse error '%U'", format_unformat_error, i);
16826           return -99;
16827         }
16828     }
16829
16830   if (!ip_family_set)
16831     {
16832       errmsg ("ip family not set!");
16833       return -99;
16834     }
16835
16836   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16837   mp->is_ip4 = is_ip4;
16838
16839   /* send it... */
16840   S (mp);
16841
16842   /* Wait for a reply... */
16843   W (ret);
16844   return ret;
16845 }
16846
16847 static int
16848 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16849 {
16850   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16851   int ret;
16852
16853   if (!vam->json_output)
16854     {
16855       print (vam->ofp, "VNIs");
16856     }
16857
16858   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16859
16860   /* send it... */
16861   S (mp);
16862
16863   /* Wait for a reply... */
16864   W (ret);
16865   return ret;
16866 }
16867
16868 static int
16869 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16870 {
16871   unformat_input_t *i = vam->input;
16872   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16873   int ret = 0;
16874   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16875   struct in_addr ip4;
16876   struct in6_addr ip6;
16877   u32 table_id = 0, nh_sw_if_index = ~0;
16878
16879   memset (&ip4, 0, sizeof (ip4));
16880   memset (&ip6, 0, sizeof (ip6));
16881
16882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16883     {
16884       if (unformat (i, "del"))
16885         is_add = 0;
16886       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16887                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16888         {
16889           ip_set = 1;
16890           is_ip4 = 1;
16891         }
16892       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16893                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16894         {
16895           ip_set = 1;
16896           is_ip4 = 0;
16897         }
16898       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16899         {
16900           ip_set = 1;
16901           is_ip4 = 1;
16902           nh_sw_if_index = ~0;
16903         }
16904       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16905         {
16906           ip_set = 1;
16907           is_ip4 = 0;
16908           nh_sw_if_index = ~0;
16909         }
16910       else if (unformat (i, "table %d", &table_id))
16911         ;
16912       else
16913         {
16914           errmsg ("parse error '%U'", format_unformat_error, i);
16915           return -99;
16916         }
16917     }
16918
16919   if (!ip_set)
16920     {
16921       errmsg ("nh addr not set!");
16922       return -99;
16923     }
16924
16925   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16926   mp->is_add = is_add;
16927   mp->table_id = clib_host_to_net_u32 (table_id);
16928   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16929   mp->is_ip4 = is_ip4;
16930   if (is_ip4)
16931     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16932   else
16933     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16934
16935   /* send it... */
16936   S (mp);
16937
16938   /* Wait for a reply... */
16939   W (ret);
16940   return ret;
16941 }
16942
16943 static int
16944 api_one_map_server_dump (vat_main_t * vam)
16945 {
16946   vl_api_one_map_server_dump_t *mp;
16947   vl_api_control_ping_t *mp_ping;
16948   int ret;
16949
16950   if (!vam->json_output)
16951     {
16952       print (vam->ofp, "%=20s", "Map server");
16953     }
16954
16955   M (ONE_MAP_SERVER_DUMP, mp);
16956   /* send it... */
16957   S (mp);
16958
16959   /* Use a control ping for synchronization */
16960   M (CONTROL_PING, mp_ping);
16961   S (mp_ping);
16962
16963   /* Wait for a reply... */
16964   W (ret);
16965   return ret;
16966 }
16967
16968 #define api_lisp_map_server_dump api_one_map_server_dump
16969
16970 static int
16971 api_one_map_resolver_dump (vat_main_t * vam)
16972 {
16973   vl_api_one_map_resolver_dump_t *mp;
16974   vl_api_control_ping_t *mp_ping;
16975   int ret;
16976
16977   if (!vam->json_output)
16978     {
16979       print (vam->ofp, "%=20s", "Map resolver");
16980     }
16981
16982   M (ONE_MAP_RESOLVER_DUMP, mp);
16983   /* send it... */
16984   S (mp);
16985
16986   /* Use a control ping for synchronization */
16987   M (CONTROL_PING, mp_ping);
16988   S (mp_ping);
16989
16990   /* Wait for a reply... */
16991   W (ret);
16992   return ret;
16993 }
16994
16995 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16996
16997 static int
16998 api_one_stats_flush (vat_main_t * vam)
16999 {
17000   vl_api_one_stats_flush_t *mp;
17001   int ret = 0;
17002
17003   M (ONE_STATS_FLUSH, mp);
17004   S (mp);
17005   W (ret);
17006   return ret;
17007 }
17008
17009 static int
17010 api_one_stats_dump (vat_main_t * vam)
17011 {
17012   vl_api_one_stats_dump_t *mp;
17013   vl_api_control_ping_t *mp_ping;
17014   int ret;
17015
17016   M (ONE_STATS_DUMP, mp);
17017   /* send it... */
17018   S (mp);
17019
17020   /* Use a control ping for synchronization */
17021   M (CONTROL_PING, mp_ping);
17022   S (mp_ping);
17023
17024   /* Wait for a reply... */
17025   W (ret);
17026   return ret;
17027 }
17028
17029 static int
17030 api_show_one_status (vat_main_t * vam)
17031 {
17032   vl_api_show_one_status_t *mp;
17033   int ret;
17034
17035   if (!vam->json_output)
17036     {
17037       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17038     }
17039
17040   M (SHOW_ONE_STATUS, mp);
17041   /* send it... */
17042   S (mp);
17043   /* Wait for a reply... */
17044   W (ret);
17045   return ret;
17046 }
17047
17048 #define api_show_lisp_status api_show_one_status
17049
17050 static int
17051 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17052 {
17053   vl_api_gpe_fwd_entry_path_dump_t *mp;
17054   vl_api_control_ping_t *mp_ping;
17055   unformat_input_t *i = vam->input;
17056   u32 fwd_entry_index = ~0;
17057   int ret;
17058
17059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17060     {
17061       if (unformat (i, "index %d", &fwd_entry_index))
17062         ;
17063       else
17064         break;
17065     }
17066
17067   if (~0 == fwd_entry_index)
17068     {
17069       errmsg ("no index specified!");
17070       return -99;
17071     }
17072
17073   if (!vam->json_output)
17074     {
17075       print (vam->ofp, "first line");
17076     }
17077
17078   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17079
17080   /* send it... */
17081   S (mp);
17082   /* Use a control ping for synchronization */
17083   M (CONTROL_PING, mp_ping);
17084   S (mp_ping);
17085
17086   /* Wait for a reply... */
17087   W (ret);
17088   return ret;
17089 }
17090
17091 static int
17092 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17093 {
17094   vl_api_one_get_map_request_itr_rlocs_t *mp;
17095   int ret;
17096
17097   if (!vam->json_output)
17098     {
17099       print (vam->ofp, "%=20s", "itr-rlocs:");
17100     }
17101
17102   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17103   /* send it... */
17104   S (mp);
17105   /* Wait for a reply... */
17106   W (ret);
17107   return ret;
17108 }
17109
17110 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17111
17112 static int
17113 api_af_packet_create (vat_main_t * vam)
17114 {
17115   unformat_input_t *i = vam->input;
17116   vl_api_af_packet_create_t *mp;
17117   u8 *host_if_name = 0;
17118   u8 hw_addr[6];
17119   u8 random_hw_addr = 1;
17120   int ret;
17121
17122   memset (hw_addr, 0, sizeof (hw_addr));
17123
17124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17125     {
17126       if (unformat (i, "name %s", &host_if_name))
17127         vec_add1 (host_if_name, 0);
17128       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17129         random_hw_addr = 0;
17130       else
17131         break;
17132     }
17133
17134   if (!vec_len (host_if_name))
17135     {
17136       errmsg ("host-interface name must be specified");
17137       return -99;
17138     }
17139
17140   if (vec_len (host_if_name) > 64)
17141     {
17142       errmsg ("host-interface name too long");
17143       return -99;
17144     }
17145
17146   M (AF_PACKET_CREATE, mp);
17147
17148   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17149   clib_memcpy (mp->hw_addr, hw_addr, 6);
17150   mp->use_random_hw_addr = random_hw_addr;
17151   vec_free (host_if_name);
17152
17153   S (mp);
17154
17155   /* *INDENT-OFF* */
17156   W2 (ret,
17157       ({
17158         if (ret == 0)
17159           fprintf (vam->ofp ? vam->ofp : stderr,
17160                    " new sw_if_index = %d\n", vam->sw_if_index);
17161       }));
17162   /* *INDENT-ON* */
17163   return ret;
17164 }
17165
17166 static int
17167 api_af_packet_delete (vat_main_t * vam)
17168 {
17169   unformat_input_t *i = vam->input;
17170   vl_api_af_packet_delete_t *mp;
17171   u8 *host_if_name = 0;
17172   int ret;
17173
17174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17175     {
17176       if (unformat (i, "name %s", &host_if_name))
17177         vec_add1 (host_if_name, 0);
17178       else
17179         break;
17180     }
17181
17182   if (!vec_len (host_if_name))
17183     {
17184       errmsg ("host-interface name must be specified");
17185       return -99;
17186     }
17187
17188   if (vec_len (host_if_name) > 64)
17189     {
17190       errmsg ("host-interface name too long");
17191       return -99;
17192     }
17193
17194   M (AF_PACKET_DELETE, mp);
17195
17196   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17197   vec_free (host_if_name);
17198
17199   S (mp);
17200   W (ret);
17201   return ret;
17202 }
17203
17204 static int
17205 api_policer_add_del (vat_main_t * vam)
17206 {
17207   unformat_input_t *i = vam->input;
17208   vl_api_policer_add_del_t *mp;
17209   u8 is_add = 1;
17210   u8 *name = 0;
17211   u32 cir = 0;
17212   u32 eir = 0;
17213   u64 cb = 0;
17214   u64 eb = 0;
17215   u8 rate_type = 0;
17216   u8 round_type = 0;
17217   u8 type = 0;
17218   u8 color_aware = 0;
17219   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17220   int ret;
17221
17222   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17223   conform_action.dscp = 0;
17224   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17225   exceed_action.dscp = 0;
17226   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17227   violate_action.dscp = 0;
17228
17229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17230     {
17231       if (unformat (i, "del"))
17232         is_add = 0;
17233       else if (unformat (i, "name %s", &name))
17234         vec_add1 (name, 0);
17235       else if (unformat (i, "cir %u", &cir))
17236         ;
17237       else if (unformat (i, "eir %u", &eir))
17238         ;
17239       else if (unformat (i, "cb %u", &cb))
17240         ;
17241       else if (unformat (i, "eb %u", &eb))
17242         ;
17243       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17244                          &rate_type))
17245         ;
17246       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17247                          &round_type))
17248         ;
17249       else if (unformat (i, "type %U", unformat_policer_type, &type))
17250         ;
17251       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17252                          &conform_action))
17253         ;
17254       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17255                          &exceed_action))
17256         ;
17257       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17258                          &violate_action))
17259         ;
17260       else if (unformat (i, "color-aware"))
17261         color_aware = 1;
17262       else
17263         break;
17264     }
17265
17266   if (!vec_len (name))
17267     {
17268       errmsg ("policer name must be specified");
17269       return -99;
17270     }
17271
17272   if (vec_len (name) > 64)
17273     {
17274       errmsg ("policer name too long");
17275       return -99;
17276     }
17277
17278   M (POLICER_ADD_DEL, mp);
17279
17280   clib_memcpy (mp->name, name, vec_len (name));
17281   vec_free (name);
17282   mp->is_add = is_add;
17283   mp->cir = cir;
17284   mp->eir = eir;
17285   mp->cb = cb;
17286   mp->eb = eb;
17287   mp->rate_type = rate_type;
17288   mp->round_type = round_type;
17289   mp->type = type;
17290   mp->conform_action_type = conform_action.action_type;
17291   mp->conform_dscp = conform_action.dscp;
17292   mp->exceed_action_type = exceed_action.action_type;
17293   mp->exceed_dscp = exceed_action.dscp;
17294   mp->violate_action_type = violate_action.action_type;
17295   mp->violate_dscp = violate_action.dscp;
17296   mp->color_aware = color_aware;
17297
17298   S (mp);
17299   W (ret);
17300   return ret;
17301 }
17302
17303 static int
17304 api_policer_dump (vat_main_t * vam)
17305 {
17306   unformat_input_t *i = vam->input;
17307   vl_api_policer_dump_t *mp;
17308   vl_api_control_ping_t *mp_ping;
17309   u8 *match_name = 0;
17310   u8 match_name_valid = 0;
17311   int ret;
17312
17313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17314     {
17315       if (unformat (i, "name %s", &match_name))
17316         {
17317           vec_add1 (match_name, 0);
17318           match_name_valid = 1;
17319         }
17320       else
17321         break;
17322     }
17323
17324   M (POLICER_DUMP, mp);
17325   mp->match_name_valid = match_name_valid;
17326   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17327   vec_free (match_name);
17328   /* send it... */
17329   S (mp);
17330
17331   /* Use a control ping for synchronization */
17332   M (CONTROL_PING, mp_ping);
17333   S (mp_ping);
17334
17335   /* Wait for a reply... */
17336   W (ret);
17337   return ret;
17338 }
17339
17340 static int
17341 api_policer_classify_set_interface (vat_main_t * vam)
17342 {
17343   unformat_input_t *i = vam->input;
17344   vl_api_policer_classify_set_interface_t *mp;
17345   u32 sw_if_index;
17346   int sw_if_index_set;
17347   u32 ip4_table_index = ~0;
17348   u32 ip6_table_index = ~0;
17349   u32 l2_table_index = ~0;
17350   u8 is_add = 1;
17351   int ret;
17352
17353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17354     {
17355       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17356         sw_if_index_set = 1;
17357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17358         sw_if_index_set = 1;
17359       else if (unformat (i, "del"))
17360         is_add = 0;
17361       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17362         ;
17363       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17364         ;
17365       else if (unformat (i, "l2-table %d", &l2_table_index))
17366         ;
17367       else
17368         {
17369           clib_warning ("parse error '%U'", format_unformat_error, i);
17370           return -99;
17371         }
17372     }
17373
17374   if (sw_if_index_set == 0)
17375     {
17376       errmsg ("missing interface name or sw_if_index");
17377       return -99;
17378     }
17379
17380   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17381
17382   mp->sw_if_index = ntohl (sw_if_index);
17383   mp->ip4_table_index = ntohl (ip4_table_index);
17384   mp->ip6_table_index = ntohl (ip6_table_index);
17385   mp->l2_table_index = ntohl (l2_table_index);
17386   mp->is_add = is_add;
17387
17388   S (mp);
17389   W (ret);
17390   return ret;
17391 }
17392
17393 static int
17394 api_policer_classify_dump (vat_main_t * vam)
17395 {
17396   unformat_input_t *i = vam->input;
17397   vl_api_policer_classify_dump_t *mp;
17398   vl_api_control_ping_t *mp_ping;
17399   u8 type = POLICER_CLASSIFY_N_TABLES;
17400   int ret;
17401
17402   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17403     ;
17404   else
17405     {
17406       errmsg ("classify table type must be specified");
17407       return -99;
17408     }
17409
17410   if (!vam->json_output)
17411     {
17412       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17413     }
17414
17415   M (POLICER_CLASSIFY_DUMP, mp);
17416   mp->type = type;
17417   /* send it... */
17418   S (mp);
17419
17420   /* Use a control ping for synchronization */
17421   M (CONTROL_PING, mp_ping);
17422   S (mp_ping);
17423
17424   /* Wait for a reply... */
17425   W (ret);
17426   return ret;
17427 }
17428
17429 static int
17430 api_netmap_create (vat_main_t * vam)
17431 {
17432   unformat_input_t *i = vam->input;
17433   vl_api_netmap_create_t *mp;
17434   u8 *if_name = 0;
17435   u8 hw_addr[6];
17436   u8 random_hw_addr = 1;
17437   u8 is_pipe = 0;
17438   u8 is_master = 0;
17439   int ret;
17440
17441   memset (hw_addr, 0, sizeof (hw_addr));
17442
17443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17444     {
17445       if (unformat (i, "name %s", &if_name))
17446         vec_add1 (if_name, 0);
17447       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17448         random_hw_addr = 0;
17449       else if (unformat (i, "pipe"))
17450         is_pipe = 1;
17451       else if (unformat (i, "master"))
17452         is_master = 1;
17453       else if (unformat (i, "slave"))
17454         is_master = 0;
17455       else
17456         break;
17457     }
17458
17459   if (!vec_len (if_name))
17460     {
17461       errmsg ("interface name must be specified");
17462       return -99;
17463     }
17464
17465   if (vec_len (if_name) > 64)
17466     {
17467       errmsg ("interface name too long");
17468       return -99;
17469     }
17470
17471   M (NETMAP_CREATE, mp);
17472
17473   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17474   clib_memcpy (mp->hw_addr, hw_addr, 6);
17475   mp->use_random_hw_addr = random_hw_addr;
17476   mp->is_pipe = is_pipe;
17477   mp->is_master = is_master;
17478   vec_free (if_name);
17479
17480   S (mp);
17481   W (ret);
17482   return ret;
17483 }
17484
17485 static int
17486 api_netmap_delete (vat_main_t * vam)
17487 {
17488   unformat_input_t *i = vam->input;
17489   vl_api_netmap_delete_t *mp;
17490   u8 *if_name = 0;
17491   int ret;
17492
17493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17494     {
17495       if (unformat (i, "name %s", &if_name))
17496         vec_add1 (if_name, 0);
17497       else
17498         break;
17499     }
17500
17501   if (!vec_len (if_name))
17502     {
17503       errmsg ("interface name must be specified");
17504       return -99;
17505     }
17506
17507   if (vec_len (if_name) > 64)
17508     {
17509       errmsg ("interface name too long");
17510       return -99;
17511     }
17512
17513   M (NETMAP_DELETE, mp);
17514
17515   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17516   vec_free (if_name);
17517
17518   S (mp);
17519   W (ret);
17520   return ret;
17521 }
17522
17523 static void
17524 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17525 {
17526   if (fp->afi == IP46_TYPE_IP6)
17527     print (vam->ofp,
17528            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17529            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17530            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17531            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17532            format_ip6_address, fp->next_hop);
17533   else if (fp->afi == IP46_TYPE_IP4)
17534     print (vam->ofp,
17535            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17536            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17537            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17538            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17539            format_ip4_address, fp->next_hop);
17540 }
17541
17542 static void
17543 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17544                                  vl_api_fib_path2_t * fp)
17545 {
17546   struct in_addr ip4;
17547   struct in6_addr ip6;
17548
17549   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17550   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17551   vat_json_object_add_uint (node, "is_local", fp->is_local);
17552   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17553   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17554   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17555   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17556   if (fp->afi == IP46_TYPE_IP4)
17557     {
17558       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17559       vat_json_object_add_ip4 (node, "next_hop", ip4);
17560     }
17561   else if (fp->afi == IP46_TYPE_IP6)
17562     {
17563       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17564       vat_json_object_add_ip6 (node, "next_hop", ip6);
17565     }
17566 }
17567
17568 static void
17569 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17570 {
17571   vat_main_t *vam = &vat_main;
17572   int count = ntohl (mp->mt_count);
17573   vl_api_fib_path2_t *fp;
17574   i32 i;
17575
17576   print (vam->ofp, "[%d]: sw_if_index %d via:",
17577          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17578   fp = mp->mt_paths;
17579   for (i = 0; i < count; i++)
17580     {
17581       vl_api_mpls_fib_path_print (vam, fp);
17582       fp++;
17583     }
17584
17585   print (vam->ofp, "");
17586 }
17587
17588 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17589 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17590
17591 static void
17592 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17593 {
17594   vat_main_t *vam = &vat_main;
17595   vat_json_node_t *node = NULL;
17596   int count = ntohl (mp->mt_count);
17597   vl_api_fib_path2_t *fp;
17598   i32 i;
17599
17600   if (VAT_JSON_ARRAY != vam->json_tree.type)
17601     {
17602       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17603       vat_json_init_array (&vam->json_tree);
17604     }
17605   node = vat_json_array_add (&vam->json_tree);
17606
17607   vat_json_init_object (node);
17608   vat_json_object_add_uint (node, "tunnel_index",
17609                             ntohl (mp->mt_tunnel_index));
17610   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17611
17612   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17613
17614   fp = mp->mt_paths;
17615   for (i = 0; i < count; i++)
17616     {
17617       vl_api_mpls_fib_path_json_print (node, fp);
17618       fp++;
17619     }
17620 }
17621
17622 static int
17623 api_mpls_tunnel_dump (vat_main_t * vam)
17624 {
17625   vl_api_mpls_tunnel_dump_t *mp;
17626   vl_api_control_ping_t *mp_ping;
17627   i32 index = -1;
17628   int ret;
17629
17630   /* Parse args required to build the message */
17631   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17632     {
17633       if (!unformat (vam->input, "tunnel_index %d", &index))
17634         {
17635           index = -1;
17636           break;
17637         }
17638     }
17639
17640   print (vam->ofp, "  tunnel_index %d", index);
17641
17642   M (MPLS_TUNNEL_DUMP, mp);
17643   mp->tunnel_index = htonl (index);
17644   S (mp);
17645
17646   /* Use a control ping for synchronization */
17647   M (CONTROL_PING, mp_ping);
17648   S (mp_ping);
17649
17650   W (ret);
17651   return ret;
17652 }
17653
17654 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17655 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17656
17657
17658 static void
17659 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17660 {
17661   vat_main_t *vam = &vat_main;
17662   int count = ntohl (mp->count);
17663   vl_api_fib_path2_t *fp;
17664   int i;
17665
17666   print (vam->ofp,
17667          "table-id %d, label %u, ess_bit %u",
17668          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17669   fp = mp->path;
17670   for (i = 0; i < count; i++)
17671     {
17672       vl_api_mpls_fib_path_print (vam, fp);
17673       fp++;
17674     }
17675 }
17676
17677 static void vl_api_mpls_fib_details_t_handler_json
17678   (vl_api_mpls_fib_details_t * mp)
17679 {
17680   vat_main_t *vam = &vat_main;
17681   int count = ntohl (mp->count);
17682   vat_json_node_t *node = NULL;
17683   vl_api_fib_path2_t *fp;
17684   int i;
17685
17686   if (VAT_JSON_ARRAY != vam->json_tree.type)
17687     {
17688       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17689       vat_json_init_array (&vam->json_tree);
17690     }
17691   node = vat_json_array_add (&vam->json_tree);
17692
17693   vat_json_init_object (node);
17694   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17695   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17696   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17697   vat_json_object_add_uint (node, "path_count", count);
17698   fp = mp->path;
17699   for (i = 0; i < count; i++)
17700     {
17701       vl_api_mpls_fib_path_json_print (node, fp);
17702       fp++;
17703     }
17704 }
17705
17706 static int
17707 api_mpls_fib_dump (vat_main_t * vam)
17708 {
17709   vl_api_mpls_fib_dump_t *mp;
17710   vl_api_control_ping_t *mp_ping;
17711   int ret;
17712
17713   M (MPLS_FIB_DUMP, mp);
17714   S (mp);
17715
17716   /* Use a control ping for synchronization */
17717   M (CONTROL_PING, mp_ping);
17718   S (mp_ping);
17719
17720   W (ret);
17721   return ret;
17722 }
17723
17724 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17725 #define vl_api_ip_fib_details_t_print vl_noop_handler
17726
17727 static void
17728 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17729 {
17730   vat_main_t *vam = &vat_main;
17731   int count = ntohl (mp->count);
17732   vl_api_fib_path_t *fp;
17733   int i;
17734
17735   print (vam->ofp,
17736          "table-id %d, prefix %U/%d",
17737          ntohl (mp->table_id), format_ip4_address, mp->address,
17738          mp->address_length);
17739   fp = mp->path;
17740   for (i = 0; i < count; i++)
17741     {
17742       if (fp->afi == IP46_TYPE_IP6)
17743         print (vam->ofp,
17744                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17745                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17746                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17747                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17748                format_ip6_address, fp->next_hop);
17749       else if (fp->afi == IP46_TYPE_IP4)
17750         print (vam->ofp,
17751                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17752                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17753                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17754                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17755                format_ip4_address, fp->next_hop);
17756       fp++;
17757     }
17758 }
17759
17760 static void vl_api_ip_fib_details_t_handler_json
17761   (vl_api_ip_fib_details_t * mp)
17762 {
17763   vat_main_t *vam = &vat_main;
17764   int count = ntohl (mp->count);
17765   vat_json_node_t *node = NULL;
17766   struct in_addr ip4;
17767   struct in6_addr ip6;
17768   vl_api_fib_path_t *fp;
17769   int i;
17770
17771   if (VAT_JSON_ARRAY != vam->json_tree.type)
17772     {
17773       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17774       vat_json_init_array (&vam->json_tree);
17775     }
17776   node = vat_json_array_add (&vam->json_tree);
17777
17778   vat_json_init_object (node);
17779   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17780   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17781   vat_json_object_add_ip4 (node, "prefix", ip4);
17782   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17783   vat_json_object_add_uint (node, "path_count", count);
17784   fp = mp->path;
17785   for (i = 0; i < count; i++)
17786     {
17787       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17788       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17789       vat_json_object_add_uint (node, "is_local", fp->is_local);
17790       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17791       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17792       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17793       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17794       if (fp->afi == IP46_TYPE_IP4)
17795         {
17796           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17797           vat_json_object_add_ip4 (node, "next_hop", ip4);
17798         }
17799       else if (fp->afi == IP46_TYPE_IP6)
17800         {
17801           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17802           vat_json_object_add_ip6 (node, "next_hop", ip6);
17803         }
17804     }
17805 }
17806
17807 static int
17808 api_ip_fib_dump (vat_main_t * vam)
17809 {
17810   vl_api_ip_fib_dump_t *mp;
17811   vl_api_control_ping_t *mp_ping;
17812   int ret;
17813
17814   M (IP_FIB_DUMP, mp);
17815   S (mp);
17816
17817   /* Use a control ping for synchronization */
17818   M (CONTROL_PING, mp_ping);
17819   S (mp_ping);
17820
17821   W (ret);
17822   return ret;
17823 }
17824
17825 static int
17826 api_ip_mfib_dump (vat_main_t * vam)
17827 {
17828   vl_api_ip_mfib_dump_t *mp;
17829   vl_api_control_ping_t *mp_ping;
17830   int ret;
17831
17832   M (IP_MFIB_DUMP, mp);
17833   S (mp);
17834
17835   /* Use a control ping for synchronization */
17836   M (CONTROL_PING, mp_ping);
17837   S (mp_ping);
17838
17839   W (ret);
17840   return ret;
17841 }
17842
17843 static void vl_api_ip_neighbor_details_t_handler
17844   (vl_api_ip_neighbor_details_t * mp)
17845 {
17846   vat_main_t *vam = &vat_main;
17847
17848   print (vam->ofp, "%c %U %U",
17849          (mp->is_static) ? 'S' : 'D',
17850          format_ethernet_address, &mp->mac_address,
17851          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17852          &mp->ip_address);
17853 }
17854
17855 static void vl_api_ip_neighbor_details_t_handler_json
17856   (vl_api_ip_neighbor_details_t * mp)
17857 {
17858
17859   vat_main_t *vam = &vat_main;
17860   vat_json_node_t *node;
17861   struct in_addr ip4;
17862   struct in6_addr ip6;
17863
17864   if (VAT_JSON_ARRAY != vam->json_tree.type)
17865     {
17866       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17867       vat_json_init_array (&vam->json_tree);
17868     }
17869   node = vat_json_array_add (&vam->json_tree);
17870
17871   vat_json_init_object (node);
17872   vat_json_object_add_string_copy (node, "flag",
17873                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17874                                    "dynamic");
17875
17876   vat_json_object_add_string_copy (node, "link_layer",
17877                                    format (0, "%U", format_ethernet_address,
17878                                            &mp->mac_address));
17879
17880   if (mp->is_ipv6)
17881     {
17882       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17883       vat_json_object_add_ip6 (node, "ip_address", ip6);
17884     }
17885   else
17886     {
17887       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17888       vat_json_object_add_ip4 (node, "ip_address", ip4);
17889     }
17890 }
17891
17892 static int
17893 api_ip_neighbor_dump (vat_main_t * vam)
17894 {
17895   unformat_input_t *i = vam->input;
17896   vl_api_ip_neighbor_dump_t *mp;
17897   vl_api_control_ping_t *mp_ping;
17898   u8 is_ipv6 = 0;
17899   u32 sw_if_index = ~0;
17900   int ret;
17901
17902   /* Parse args required to build the message */
17903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17904     {
17905       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17906         ;
17907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17908         ;
17909       else if (unformat (i, "ip6"))
17910         is_ipv6 = 1;
17911       else
17912         break;
17913     }
17914
17915   if (sw_if_index == ~0)
17916     {
17917       errmsg ("missing interface name or sw_if_index");
17918       return -99;
17919     }
17920
17921   M (IP_NEIGHBOR_DUMP, mp);
17922   mp->is_ipv6 = (u8) is_ipv6;
17923   mp->sw_if_index = ntohl (sw_if_index);
17924   S (mp);
17925
17926   /* Use a control ping for synchronization */
17927   M (CONTROL_PING, mp_ping);
17928   S (mp_ping);
17929
17930   W (ret);
17931   return ret;
17932 }
17933
17934 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17935 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17936
17937 static void
17938 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17939 {
17940   vat_main_t *vam = &vat_main;
17941   int count = ntohl (mp->count);
17942   vl_api_fib_path_t *fp;
17943   int i;
17944
17945   print (vam->ofp,
17946          "table-id %d, prefix %U/%d",
17947          ntohl (mp->table_id), format_ip6_address, mp->address,
17948          mp->address_length);
17949   fp = mp->path;
17950   for (i = 0; i < count; i++)
17951     {
17952       if (fp->afi == IP46_TYPE_IP6)
17953         print (vam->ofp,
17954                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17955                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17956                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17957                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17958                format_ip6_address, fp->next_hop);
17959       else if (fp->afi == IP46_TYPE_IP4)
17960         print (vam->ofp,
17961                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17962                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17963                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17964                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17965                format_ip4_address, fp->next_hop);
17966       fp++;
17967     }
17968 }
17969
17970 static void vl_api_ip6_fib_details_t_handler_json
17971   (vl_api_ip6_fib_details_t * mp)
17972 {
17973   vat_main_t *vam = &vat_main;
17974   int count = ntohl (mp->count);
17975   vat_json_node_t *node = NULL;
17976   struct in_addr ip4;
17977   struct in6_addr ip6;
17978   vl_api_fib_path_t *fp;
17979   int i;
17980
17981   if (VAT_JSON_ARRAY != vam->json_tree.type)
17982     {
17983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17984       vat_json_init_array (&vam->json_tree);
17985     }
17986   node = vat_json_array_add (&vam->json_tree);
17987
17988   vat_json_init_object (node);
17989   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17990   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17991   vat_json_object_add_ip6 (node, "prefix", ip6);
17992   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17993   vat_json_object_add_uint (node, "path_count", count);
17994   fp = mp->path;
17995   for (i = 0; i < count; i++)
17996     {
17997       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17998       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17999       vat_json_object_add_uint (node, "is_local", fp->is_local);
18000       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18001       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18002       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18003       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18004       if (fp->afi == IP46_TYPE_IP4)
18005         {
18006           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18007           vat_json_object_add_ip4 (node, "next_hop", ip4);
18008         }
18009       else if (fp->afi == IP46_TYPE_IP6)
18010         {
18011           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18012           vat_json_object_add_ip6 (node, "next_hop", ip6);
18013         }
18014     }
18015 }
18016
18017 static int
18018 api_ip6_fib_dump (vat_main_t * vam)
18019 {
18020   vl_api_ip6_fib_dump_t *mp;
18021   vl_api_control_ping_t *mp_ping;
18022   int ret;
18023
18024   M (IP6_FIB_DUMP, mp);
18025   S (mp);
18026
18027   /* Use a control ping for synchronization */
18028   M (CONTROL_PING, mp_ping);
18029   S (mp_ping);
18030
18031   W (ret);
18032   return ret;
18033 }
18034
18035 static int
18036 api_ip6_mfib_dump (vat_main_t * vam)
18037 {
18038   vl_api_ip6_mfib_dump_t *mp;
18039   vl_api_control_ping_t *mp_ping;
18040   int ret;
18041
18042   M (IP6_MFIB_DUMP, mp);
18043   S (mp);
18044
18045   /* Use a control ping for synchronization */
18046   M (CONTROL_PING, mp_ping);
18047   S (mp_ping);
18048
18049   W (ret);
18050   return ret;
18051 }
18052
18053 int
18054 api_classify_table_ids (vat_main_t * vam)
18055 {
18056   vl_api_classify_table_ids_t *mp;
18057   int ret;
18058
18059   /* Construct the API message */
18060   M (CLASSIFY_TABLE_IDS, mp);
18061   mp->context = 0;
18062
18063   S (mp);
18064   W (ret);
18065   return ret;
18066 }
18067
18068 int
18069 api_classify_table_by_interface (vat_main_t * vam)
18070 {
18071   unformat_input_t *input = vam->input;
18072   vl_api_classify_table_by_interface_t *mp;
18073
18074   u32 sw_if_index = ~0;
18075   int ret;
18076   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18077     {
18078       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18079         ;
18080       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18081         ;
18082       else
18083         break;
18084     }
18085   if (sw_if_index == ~0)
18086     {
18087       errmsg ("missing interface name or sw_if_index");
18088       return -99;
18089     }
18090
18091   /* Construct the API message */
18092   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18093   mp->context = 0;
18094   mp->sw_if_index = ntohl (sw_if_index);
18095
18096   S (mp);
18097   W (ret);
18098   return ret;
18099 }
18100
18101 int
18102 api_classify_table_info (vat_main_t * vam)
18103 {
18104   unformat_input_t *input = vam->input;
18105   vl_api_classify_table_info_t *mp;
18106
18107   u32 table_id = ~0;
18108   int ret;
18109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18110     {
18111       if (unformat (input, "table_id %d", &table_id))
18112         ;
18113       else
18114         break;
18115     }
18116   if (table_id == ~0)
18117     {
18118       errmsg ("missing table id");
18119       return -99;
18120     }
18121
18122   /* Construct the API message */
18123   M (CLASSIFY_TABLE_INFO, mp);
18124   mp->context = 0;
18125   mp->table_id = ntohl (table_id);
18126
18127   S (mp);
18128   W (ret);
18129   return ret;
18130 }
18131
18132 int
18133 api_classify_session_dump (vat_main_t * vam)
18134 {
18135   unformat_input_t *input = vam->input;
18136   vl_api_classify_session_dump_t *mp;
18137   vl_api_control_ping_t *mp_ping;
18138
18139   u32 table_id = ~0;
18140   int ret;
18141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18142     {
18143       if (unformat (input, "table_id %d", &table_id))
18144         ;
18145       else
18146         break;
18147     }
18148   if (table_id == ~0)
18149     {
18150       errmsg ("missing table id");
18151       return -99;
18152     }
18153
18154   /* Construct the API message */
18155   M (CLASSIFY_SESSION_DUMP, mp);
18156   mp->context = 0;
18157   mp->table_id = ntohl (table_id);
18158   S (mp);
18159
18160   /* Use a control ping for synchronization */
18161   M (CONTROL_PING, mp_ping);
18162   S (mp_ping);
18163
18164   W (ret);
18165   return ret;
18166 }
18167
18168 static void
18169 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18170 {
18171   vat_main_t *vam = &vat_main;
18172
18173   print (vam->ofp, "collector_address %U, collector_port %d, "
18174          "src_address %U, vrf_id %d, path_mtu %u, "
18175          "template_interval %u, udp_checksum %d",
18176          format_ip4_address, mp->collector_address,
18177          ntohs (mp->collector_port),
18178          format_ip4_address, mp->src_address,
18179          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18180          ntohl (mp->template_interval), mp->udp_checksum);
18181
18182   vam->retval = 0;
18183   vam->result_ready = 1;
18184 }
18185
18186 static void
18187   vl_api_ipfix_exporter_details_t_handler_json
18188   (vl_api_ipfix_exporter_details_t * mp)
18189 {
18190   vat_main_t *vam = &vat_main;
18191   vat_json_node_t node;
18192   struct in_addr collector_address;
18193   struct in_addr src_address;
18194
18195   vat_json_init_object (&node);
18196   clib_memcpy (&collector_address, &mp->collector_address,
18197                sizeof (collector_address));
18198   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18199   vat_json_object_add_uint (&node, "collector_port",
18200                             ntohs (mp->collector_port));
18201   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18202   vat_json_object_add_ip4 (&node, "src_address", src_address);
18203   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18204   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18205   vat_json_object_add_uint (&node, "template_interval",
18206                             ntohl (mp->template_interval));
18207   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18208
18209   vat_json_print (vam->ofp, &node);
18210   vat_json_free (&node);
18211   vam->retval = 0;
18212   vam->result_ready = 1;
18213 }
18214
18215 int
18216 api_ipfix_exporter_dump (vat_main_t * vam)
18217 {
18218   vl_api_ipfix_exporter_dump_t *mp;
18219   int ret;
18220
18221   /* Construct the API message */
18222   M (IPFIX_EXPORTER_DUMP, mp);
18223   mp->context = 0;
18224
18225   S (mp);
18226   W (ret);
18227   return ret;
18228 }
18229
18230 static int
18231 api_ipfix_classify_stream_dump (vat_main_t * vam)
18232 {
18233   vl_api_ipfix_classify_stream_dump_t *mp;
18234   int ret;
18235
18236   /* Construct the API message */
18237   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18238   mp->context = 0;
18239
18240   S (mp);
18241   W (ret);
18242   return ret;
18243   /* NOTREACHED */
18244   return 0;
18245 }
18246
18247 static void
18248   vl_api_ipfix_classify_stream_details_t_handler
18249   (vl_api_ipfix_classify_stream_details_t * mp)
18250 {
18251   vat_main_t *vam = &vat_main;
18252   print (vam->ofp, "domain_id %d, src_port %d",
18253          ntohl (mp->domain_id), ntohs (mp->src_port));
18254   vam->retval = 0;
18255   vam->result_ready = 1;
18256 }
18257
18258 static void
18259   vl_api_ipfix_classify_stream_details_t_handler_json
18260   (vl_api_ipfix_classify_stream_details_t * mp)
18261 {
18262   vat_main_t *vam = &vat_main;
18263   vat_json_node_t node;
18264
18265   vat_json_init_object (&node);
18266   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18267   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18268
18269   vat_json_print (vam->ofp, &node);
18270   vat_json_free (&node);
18271   vam->retval = 0;
18272   vam->result_ready = 1;
18273 }
18274
18275 static int
18276 api_ipfix_classify_table_dump (vat_main_t * vam)
18277 {
18278   vl_api_ipfix_classify_table_dump_t *mp;
18279   vl_api_control_ping_t *mp_ping;
18280   int ret;
18281
18282   if (!vam->json_output)
18283     {
18284       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18285              "transport_protocol");
18286     }
18287
18288   /* Construct the API message */
18289   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18290
18291   /* send it... */
18292   S (mp);
18293
18294   /* Use a control ping for synchronization */
18295   M (CONTROL_PING, mp_ping);
18296   S (mp_ping);
18297
18298   W (ret);
18299   return ret;
18300 }
18301
18302 static void
18303   vl_api_ipfix_classify_table_details_t_handler
18304   (vl_api_ipfix_classify_table_details_t * mp)
18305 {
18306   vat_main_t *vam = &vat_main;
18307   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18308          mp->transport_protocol);
18309 }
18310
18311 static void
18312   vl_api_ipfix_classify_table_details_t_handler_json
18313   (vl_api_ipfix_classify_table_details_t * mp)
18314 {
18315   vat_json_node_t *node = NULL;
18316   vat_main_t *vam = &vat_main;
18317
18318   if (VAT_JSON_ARRAY != vam->json_tree.type)
18319     {
18320       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18321       vat_json_init_array (&vam->json_tree);
18322     }
18323
18324   node = vat_json_array_add (&vam->json_tree);
18325   vat_json_init_object (node);
18326
18327   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18328   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18329   vat_json_object_add_uint (node, "transport_protocol",
18330                             mp->transport_protocol);
18331 }
18332
18333 static int
18334 api_sw_interface_span_enable_disable (vat_main_t * vam)
18335 {
18336   unformat_input_t *i = vam->input;
18337   vl_api_sw_interface_span_enable_disable_t *mp;
18338   u32 src_sw_if_index = ~0;
18339   u32 dst_sw_if_index = ~0;
18340   u8 state = 3;
18341   int ret;
18342   u8 is_l2 = 0;
18343
18344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18345     {
18346       if (unformat
18347           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18348         ;
18349       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18350         ;
18351       else
18352         if (unformat
18353             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18354         ;
18355       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18356         ;
18357       else if (unformat (i, "disable"))
18358         state = 0;
18359       else if (unformat (i, "rx"))
18360         state = 1;
18361       else if (unformat (i, "tx"))
18362         state = 2;
18363       else if (unformat (i, "both"))
18364         state = 3;
18365       else if (unformat (i, "l2"))
18366         is_l2 = 1;
18367       else
18368         break;
18369     }
18370
18371   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18372
18373   mp->sw_if_index_from = htonl (src_sw_if_index);
18374   mp->sw_if_index_to = htonl (dst_sw_if_index);
18375   mp->state = state;
18376   mp->is_l2 = is_l2;
18377
18378   S (mp);
18379   W (ret);
18380   return ret;
18381 }
18382
18383 static void
18384 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18385                                             * mp)
18386 {
18387   vat_main_t *vam = &vat_main;
18388   u8 *sw_if_from_name = 0;
18389   u8 *sw_if_to_name = 0;
18390   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18391   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18392   char *states[] = { "none", "rx", "tx", "both" };
18393   hash_pair_t *p;
18394
18395   /* *INDENT-OFF* */
18396   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18397   ({
18398     if ((u32) p->value[0] == sw_if_index_from)
18399       {
18400         sw_if_from_name = (u8 *)(p->key);
18401         if (sw_if_to_name)
18402           break;
18403       }
18404     if ((u32) p->value[0] == sw_if_index_to)
18405       {
18406         sw_if_to_name = (u8 *)(p->key);
18407         if (sw_if_from_name)
18408           break;
18409       }
18410   }));
18411   /* *INDENT-ON* */
18412   print (vam->ofp, "%20s => %20s (%s)",
18413          sw_if_from_name, sw_if_to_name, states[mp->state]);
18414 }
18415
18416 static void
18417   vl_api_sw_interface_span_details_t_handler_json
18418   (vl_api_sw_interface_span_details_t * mp)
18419 {
18420   vat_main_t *vam = &vat_main;
18421   vat_json_node_t *node = NULL;
18422   u8 *sw_if_from_name = 0;
18423   u8 *sw_if_to_name = 0;
18424   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18425   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18426   hash_pair_t *p;
18427
18428   /* *INDENT-OFF* */
18429   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18430   ({
18431     if ((u32) p->value[0] == sw_if_index_from)
18432       {
18433         sw_if_from_name = (u8 *)(p->key);
18434         if (sw_if_to_name)
18435           break;
18436       }
18437     if ((u32) p->value[0] == sw_if_index_to)
18438       {
18439         sw_if_to_name = (u8 *)(p->key);
18440         if (sw_if_from_name)
18441           break;
18442       }
18443   }));
18444   /* *INDENT-ON* */
18445
18446   if (VAT_JSON_ARRAY != vam->json_tree.type)
18447     {
18448       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18449       vat_json_init_array (&vam->json_tree);
18450     }
18451   node = vat_json_array_add (&vam->json_tree);
18452
18453   vat_json_init_object (node);
18454   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18455   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18456   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18457   if (0 != sw_if_to_name)
18458     {
18459       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18460     }
18461   vat_json_object_add_uint (node, "state", mp->state);
18462 }
18463
18464 static int
18465 api_sw_interface_span_dump (vat_main_t * vam)
18466 {
18467   unformat_input_t *input = vam->input;
18468   vl_api_sw_interface_span_dump_t *mp;
18469   vl_api_control_ping_t *mp_ping;
18470   u8 is_l2 = 0;
18471   int ret;
18472
18473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18474     {
18475       if (unformat (input, "l2"))
18476         is_l2 = 1;
18477       else
18478         break;
18479     }
18480
18481   M (SW_INTERFACE_SPAN_DUMP, mp);
18482   mp->is_l2 = is_l2;
18483   S (mp);
18484
18485   /* Use a control ping for synchronization */
18486   M (CONTROL_PING, mp_ping);
18487   S (mp_ping);
18488
18489   W (ret);
18490   return ret;
18491 }
18492
18493 int
18494 api_pg_create_interface (vat_main_t * vam)
18495 {
18496   unformat_input_t *input = vam->input;
18497   vl_api_pg_create_interface_t *mp;
18498
18499   u32 if_id = ~0;
18500   int ret;
18501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18502     {
18503       if (unformat (input, "if_id %d", &if_id))
18504         ;
18505       else
18506         break;
18507     }
18508   if (if_id == ~0)
18509     {
18510       errmsg ("missing pg interface index");
18511       return -99;
18512     }
18513
18514   /* Construct the API message */
18515   M (PG_CREATE_INTERFACE, mp);
18516   mp->context = 0;
18517   mp->interface_id = ntohl (if_id);
18518
18519   S (mp);
18520   W (ret);
18521   return ret;
18522 }
18523
18524 int
18525 api_pg_capture (vat_main_t * vam)
18526 {
18527   unformat_input_t *input = vam->input;
18528   vl_api_pg_capture_t *mp;
18529
18530   u32 if_id = ~0;
18531   u8 enable = 1;
18532   u32 count = 1;
18533   u8 pcap_file_set = 0;
18534   u8 *pcap_file = 0;
18535   int ret;
18536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18537     {
18538       if (unformat (input, "if_id %d", &if_id))
18539         ;
18540       else if (unformat (input, "pcap %s", &pcap_file))
18541         pcap_file_set = 1;
18542       else if (unformat (input, "count %d", &count))
18543         ;
18544       else if (unformat (input, "disable"))
18545         enable = 0;
18546       else
18547         break;
18548     }
18549   if (if_id == ~0)
18550     {
18551       errmsg ("missing pg interface index");
18552       return -99;
18553     }
18554   if (pcap_file_set > 0)
18555     {
18556       if (vec_len (pcap_file) > 255)
18557         {
18558           errmsg ("pcap file name is too long");
18559           return -99;
18560         }
18561     }
18562
18563   u32 name_len = vec_len (pcap_file);
18564   /* Construct the API message */
18565   M (PG_CAPTURE, mp);
18566   mp->context = 0;
18567   mp->interface_id = ntohl (if_id);
18568   mp->is_enabled = enable;
18569   mp->count = ntohl (count);
18570   mp->pcap_name_length = ntohl (name_len);
18571   if (pcap_file_set != 0)
18572     {
18573       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18574     }
18575   vec_free (pcap_file);
18576
18577   S (mp);
18578   W (ret);
18579   return ret;
18580 }
18581
18582 int
18583 api_pg_enable_disable (vat_main_t * vam)
18584 {
18585   unformat_input_t *input = vam->input;
18586   vl_api_pg_enable_disable_t *mp;
18587
18588   u8 enable = 1;
18589   u8 stream_name_set = 0;
18590   u8 *stream_name = 0;
18591   int ret;
18592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18593     {
18594       if (unformat (input, "stream %s", &stream_name))
18595         stream_name_set = 1;
18596       else if (unformat (input, "disable"))
18597         enable = 0;
18598       else
18599         break;
18600     }
18601
18602   if (stream_name_set > 0)
18603     {
18604       if (vec_len (stream_name) > 255)
18605         {
18606           errmsg ("stream name too long");
18607           return -99;
18608         }
18609     }
18610
18611   u32 name_len = vec_len (stream_name);
18612   /* Construct the API message */
18613   M (PG_ENABLE_DISABLE, mp);
18614   mp->context = 0;
18615   mp->is_enabled = enable;
18616   if (stream_name_set != 0)
18617     {
18618       mp->stream_name_length = ntohl (name_len);
18619       clib_memcpy (mp->stream_name, stream_name, name_len);
18620     }
18621   vec_free (stream_name);
18622
18623   S (mp);
18624   W (ret);
18625   return ret;
18626 }
18627
18628 int
18629 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18630 {
18631   unformat_input_t *input = vam->input;
18632   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18633
18634   u16 *low_ports = 0;
18635   u16 *high_ports = 0;
18636   u16 this_low;
18637   u16 this_hi;
18638   ip4_address_t ip4_addr;
18639   ip6_address_t ip6_addr;
18640   u32 length;
18641   u32 tmp, tmp2;
18642   u8 prefix_set = 0;
18643   u32 vrf_id = ~0;
18644   u8 is_add = 1;
18645   u8 is_ipv6 = 0;
18646   int ret;
18647
18648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18649     {
18650       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18651         {
18652           prefix_set = 1;
18653         }
18654       else
18655         if (unformat
18656             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18657         {
18658           prefix_set = 1;
18659           is_ipv6 = 1;
18660         }
18661       else if (unformat (input, "vrf %d", &vrf_id))
18662         ;
18663       else if (unformat (input, "del"))
18664         is_add = 0;
18665       else if (unformat (input, "port %d", &tmp))
18666         {
18667           if (tmp == 0 || tmp > 65535)
18668             {
18669               errmsg ("port %d out of range", tmp);
18670               return -99;
18671             }
18672           this_low = tmp;
18673           this_hi = this_low + 1;
18674           vec_add1 (low_ports, this_low);
18675           vec_add1 (high_ports, this_hi);
18676         }
18677       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18678         {
18679           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18680             {
18681               errmsg ("incorrect range parameters");
18682               return -99;
18683             }
18684           this_low = tmp;
18685           /* Note: in debug CLI +1 is added to high before
18686              passing to real fn that does "the work"
18687              (ip_source_and_port_range_check_add_del).
18688              This fn is a wrapper around the binary API fn a
18689              control plane will call, which expects this increment
18690              to have occurred. Hence letting the binary API control
18691              plane fn do the increment for consistency between VAT
18692              and other control planes.
18693            */
18694           this_hi = tmp2;
18695           vec_add1 (low_ports, this_low);
18696           vec_add1 (high_ports, this_hi);
18697         }
18698       else
18699         break;
18700     }
18701
18702   if (prefix_set == 0)
18703     {
18704       errmsg ("<address>/<mask> not specified");
18705       return -99;
18706     }
18707
18708   if (vrf_id == ~0)
18709     {
18710       errmsg ("VRF ID required, not specified");
18711       return -99;
18712     }
18713
18714   if (vrf_id == 0)
18715     {
18716       errmsg
18717         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18718       return -99;
18719     }
18720
18721   if (vec_len (low_ports) == 0)
18722     {
18723       errmsg ("At least one port or port range required");
18724       return -99;
18725     }
18726
18727   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18728
18729   mp->is_add = is_add;
18730
18731   if (is_ipv6)
18732     {
18733       mp->is_ipv6 = 1;
18734       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18735     }
18736   else
18737     {
18738       mp->is_ipv6 = 0;
18739       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18740     }
18741
18742   mp->mask_length = length;
18743   mp->number_of_ranges = vec_len (low_ports);
18744
18745   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18746   vec_free (low_ports);
18747
18748   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18749   vec_free (high_ports);
18750
18751   mp->vrf_id = ntohl (vrf_id);
18752
18753   S (mp);
18754   W (ret);
18755   return ret;
18756 }
18757
18758 int
18759 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18760 {
18761   unformat_input_t *input = vam->input;
18762   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18763   u32 sw_if_index = ~0;
18764   int vrf_set = 0;
18765   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18766   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18767   u8 is_add = 1;
18768   int ret;
18769
18770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18771     {
18772       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18773         ;
18774       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18775         ;
18776       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18777         vrf_set = 1;
18778       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18779         vrf_set = 1;
18780       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18781         vrf_set = 1;
18782       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18783         vrf_set = 1;
18784       else if (unformat (input, "del"))
18785         is_add = 0;
18786       else
18787         break;
18788     }
18789
18790   if (sw_if_index == ~0)
18791     {
18792       errmsg ("Interface required but not specified");
18793       return -99;
18794     }
18795
18796   if (vrf_set == 0)
18797     {
18798       errmsg ("VRF ID required but not specified");
18799       return -99;
18800     }
18801
18802   if (tcp_out_vrf_id == 0
18803       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18804     {
18805       errmsg
18806         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18807       return -99;
18808     }
18809
18810   /* Construct the API message */
18811   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18812
18813   mp->sw_if_index = ntohl (sw_if_index);
18814   mp->is_add = is_add;
18815   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18816   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18817   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18818   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18819
18820   /* send it... */
18821   S (mp);
18822
18823   /* Wait for a reply... */
18824   W (ret);
18825   return ret;
18826 }
18827
18828 static int
18829 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18830 {
18831   unformat_input_t *i = vam->input;
18832   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18833   u32 local_sa_id = 0;
18834   u32 remote_sa_id = 0;
18835   ip4_address_t src_address;
18836   ip4_address_t dst_address;
18837   u8 is_add = 1;
18838   int ret;
18839
18840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18841     {
18842       if (unformat (i, "local_sa %d", &local_sa_id))
18843         ;
18844       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18845         ;
18846       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18847         ;
18848       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18849         ;
18850       else if (unformat (i, "del"))
18851         is_add = 0;
18852       else
18853         {
18854           clib_warning ("parse error '%U'", format_unformat_error, i);
18855           return -99;
18856         }
18857     }
18858
18859   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18860
18861   mp->local_sa_id = ntohl (local_sa_id);
18862   mp->remote_sa_id = ntohl (remote_sa_id);
18863   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18864   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18865   mp->is_add = is_add;
18866
18867   S (mp);
18868   W (ret);
18869   return ret;
18870 }
18871
18872 static int
18873 api_punt (vat_main_t * vam)
18874 {
18875   unformat_input_t *i = vam->input;
18876   vl_api_punt_t *mp;
18877   u32 ipv = ~0;
18878   u32 protocol = ~0;
18879   u32 port = ~0;
18880   int is_add = 1;
18881   int ret;
18882
18883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18884     {
18885       if (unformat (i, "ip %d", &ipv))
18886         ;
18887       else if (unformat (i, "protocol %d", &protocol))
18888         ;
18889       else if (unformat (i, "port %d", &port))
18890         ;
18891       else if (unformat (i, "del"))
18892         is_add = 0;
18893       else
18894         {
18895           clib_warning ("parse error '%U'", format_unformat_error, i);
18896           return -99;
18897         }
18898     }
18899
18900   M (PUNT, mp);
18901
18902   mp->is_add = (u8) is_add;
18903   mp->ipv = (u8) ipv;
18904   mp->l4_protocol = (u8) protocol;
18905   mp->l4_port = htons ((u16) port);
18906
18907   S (mp);
18908   W (ret);
18909   return ret;
18910 }
18911
18912 static void vl_api_ipsec_gre_tunnel_details_t_handler
18913   (vl_api_ipsec_gre_tunnel_details_t * mp)
18914 {
18915   vat_main_t *vam = &vat_main;
18916
18917   print (vam->ofp, "%11d%15U%15U%14d%14d",
18918          ntohl (mp->sw_if_index),
18919          format_ip4_address, &mp->src_address,
18920          format_ip4_address, &mp->dst_address,
18921          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18922 }
18923
18924 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18925   (vl_api_ipsec_gre_tunnel_details_t * mp)
18926 {
18927   vat_main_t *vam = &vat_main;
18928   vat_json_node_t *node = NULL;
18929   struct in_addr ip4;
18930
18931   if (VAT_JSON_ARRAY != vam->json_tree.type)
18932     {
18933       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18934       vat_json_init_array (&vam->json_tree);
18935     }
18936   node = vat_json_array_add (&vam->json_tree);
18937
18938   vat_json_init_object (node);
18939   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18940   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18941   vat_json_object_add_ip4 (node, "src_address", ip4);
18942   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18943   vat_json_object_add_ip4 (node, "dst_address", ip4);
18944   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18945   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18946 }
18947
18948 static int
18949 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18950 {
18951   unformat_input_t *i = vam->input;
18952   vl_api_ipsec_gre_tunnel_dump_t *mp;
18953   vl_api_control_ping_t *mp_ping;
18954   u32 sw_if_index;
18955   u8 sw_if_index_set = 0;
18956   int ret;
18957
18958   /* Parse args required to build the message */
18959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18960     {
18961       if (unformat (i, "sw_if_index %d", &sw_if_index))
18962         sw_if_index_set = 1;
18963       else
18964         break;
18965     }
18966
18967   if (sw_if_index_set == 0)
18968     {
18969       sw_if_index = ~0;
18970     }
18971
18972   if (!vam->json_output)
18973     {
18974       print (vam->ofp, "%11s%15s%15s%14s%14s",
18975              "sw_if_index", "src_address", "dst_address",
18976              "local_sa_id", "remote_sa_id");
18977     }
18978
18979   /* Get list of gre-tunnel interfaces */
18980   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18981
18982   mp->sw_if_index = htonl (sw_if_index);
18983
18984   S (mp);
18985
18986   /* Use a control ping for synchronization */
18987   M (CONTROL_PING, mp_ping);
18988   S (mp_ping);
18989
18990   W (ret);
18991   return ret;
18992 }
18993
18994 static int
18995 api_delete_subif (vat_main_t * vam)
18996 {
18997   unformat_input_t *i = vam->input;
18998   vl_api_delete_subif_t *mp;
18999   u32 sw_if_index = ~0;
19000   int ret;
19001
19002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19003     {
19004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19005         ;
19006       if (unformat (i, "sw_if_index %d", &sw_if_index))
19007         ;
19008       else
19009         break;
19010     }
19011
19012   if (sw_if_index == ~0)
19013     {
19014       errmsg ("missing sw_if_index");
19015       return -99;
19016     }
19017
19018   /* Construct the API message */
19019   M (DELETE_SUBIF, mp);
19020   mp->sw_if_index = ntohl (sw_if_index);
19021
19022   S (mp);
19023   W (ret);
19024   return ret;
19025 }
19026
19027 #define foreach_pbb_vtr_op      \
19028 _("disable",  L2_VTR_DISABLED)  \
19029 _("pop",  L2_VTR_POP_2)         \
19030 _("push",  L2_VTR_PUSH_2)
19031
19032 static int
19033 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19034 {
19035   unformat_input_t *i = vam->input;
19036   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19037   u32 sw_if_index = ~0, vtr_op = ~0;
19038   u16 outer_tag = ~0;
19039   u8 dmac[6], smac[6];
19040   u8 dmac_set = 0, smac_set = 0;
19041   u16 vlanid = 0;
19042   u32 sid = ~0;
19043   u32 tmp;
19044   int ret;
19045
19046   /* Shut up coverity */
19047   memset (dmac, 0, sizeof (dmac));
19048   memset (smac, 0, sizeof (smac));
19049
19050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19051     {
19052       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19053         ;
19054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19055         ;
19056       else if (unformat (i, "vtr_op %d", &vtr_op))
19057         ;
19058 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19059       foreach_pbb_vtr_op
19060 #undef _
19061         else if (unformat (i, "translate_pbb_stag"))
19062         {
19063           if (unformat (i, "%d", &tmp))
19064             {
19065               vtr_op = L2_VTR_TRANSLATE_2_1;
19066               outer_tag = tmp;
19067             }
19068           else
19069             {
19070               errmsg
19071                 ("translate_pbb_stag operation requires outer tag definition");
19072               return -99;
19073             }
19074         }
19075       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19076         dmac_set++;
19077       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19078         smac_set++;
19079       else if (unformat (i, "sid %d", &sid))
19080         ;
19081       else if (unformat (i, "vlanid %d", &tmp))
19082         vlanid = tmp;
19083       else
19084         {
19085           clib_warning ("parse error '%U'", format_unformat_error, i);
19086           return -99;
19087         }
19088     }
19089
19090   if ((sw_if_index == ~0) || (vtr_op == ~0))
19091     {
19092       errmsg ("missing sw_if_index or vtr operation");
19093       return -99;
19094     }
19095   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19096       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19097     {
19098       errmsg
19099         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19100       return -99;
19101     }
19102
19103   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19104   mp->sw_if_index = ntohl (sw_if_index);
19105   mp->vtr_op = ntohl (vtr_op);
19106   mp->outer_tag = ntohs (outer_tag);
19107   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19108   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19109   mp->b_vlanid = ntohs (vlanid);
19110   mp->i_sid = ntohl (sid);
19111
19112   S (mp);
19113   W (ret);
19114   return ret;
19115 }
19116
19117 static int
19118 api_flow_classify_set_interface (vat_main_t * vam)
19119 {
19120   unformat_input_t *i = vam->input;
19121   vl_api_flow_classify_set_interface_t *mp;
19122   u32 sw_if_index;
19123   int sw_if_index_set;
19124   u32 ip4_table_index = ~0;
19125   u32 ip6_table_index = ~0;
19126   u8 is_add = 1;
19127   int ret;
19128
19129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19130     {
19131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19132         sw_if_index_set = 1;
19133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19134         sw_if_index_set = 1;
19135       else if (unformat (i, "del"))
19136         is_add = 0;
19137       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19138         ;
19139       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19140         ;
19141       else
19142         {
19143           clib_warning ("parse error '%U'", format_unformat_error, i);
19144           return -99;
19145         }
19146     }
19147
19148   if (sw_if_index_set == 0)
19149     {
19150       errmsg ("missing interface name or sw_if_index");
19151       return -99;
19152     }
19153
19154   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19155
19156   mp->sw_if_index = ntohl (sw_if_index);
19157   mp->ip4_table_index = ntohl (ip4_table_index);
19158   mp->ip6_table_index = ntohl (ip6_table_index);
19159   mp->is_add = is_add;
19160
19161   S (mp);
19162   W (ret);
19163   return ret;
19164 }
19165
19166 static int
19167 api_flow_classify_dump (vat_main_t * vam)
19168 {
19169   unformat_input_t *i = vam->input;
19170   vl_api_flow_classify_dump_t *mp;
19171   vl_api_control_ping_t *mp_ping;
19172   u8 type = FLOW_CLASSIFY_N_TABLES;
19173   int ret;
19174
19175   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19176     ;
19177   else
19178     {
19179       errmsg ("classify table type must be specified");
19180       return -99;
19181     }
19182
19183   if (!vam->json_output)
19184     {
19185       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19186     }
19187
19188   M (FLOW_CLASSIFY_DUMP, mp);
19189   mp->type = type;
19190   /* send it... */
19191   S (mp);
19192
19193   /* Use a control ping for synchronization */
19194   M (CONTROL_PING, mp_ping);
19195   S (mp_ping);
19196
19197   /* Wait for a reply... */
19198   W (ret);
19199   return ret;
19200 }
19201
19202 static int
19203 api_feature_enable_disable (vat_main_t * vam)
19204 {
19205   unformat_input_t *i = vam->input;
19206   vl_api_feature_enable_disable_t *mp;
19207   u8 *arc_name = 0;
19208   u8 *feature_name = 0;
19209   u32 sw_if_index = ~0;
19210   u8 enable = 1;
19211   int ret;
19212
19213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19214     {
19215       if (unformat (i, "arc_name %s", &arc_name))
19216         ;
19217       else if (unformat (i, "feature_name %s", &feature_name))
19218         ;
19219       else
19220         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19221         ;
19222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19223         ;
19224       else if (unformat (i, "disable"))
19225         enable = 0;
19226       else
19227         break;
19228     }
19229
19230   if (arc_name == 0)
19231     {
19232       errmsg ("missing arc name");
19233       return -99;
19234     }
19235   if (vec_len (arc_name) > 63)
19236     {
19237       errmsg ("arc name too long");
19238     }
19239
19240   if (feature_name == 0)
19241     {
19242       errmsg ("missing feature name");
19243       return -99;
19244     }
19245   if (vec_len (feature_name) > 63)
19246     {
19247       errmsg ("feature name too long");
19248     }
19249
19250   if (sw_if_index == ~0)
19251     {
19252       errmsg ("missing interface name or sw_if_index");
19253       return -99;
19254     }
19255
19256   /* Construct the API message */
19257   M (FEATURE_ENABLE_DISABLE, mp);
19258   mp->sw_if_index = ntohl (sw_if_index);
19259   mp->enable = enable;
19260   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19261   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19262   vec_free (arc_name);
19263   vec_free (feature_name);
19264
19265   S (mp);
19266   W (ret);
19267   return ret;
19268 }
19269
19270 static int
19271 api_sw_interface_tag_add_del (vat_main_t * vam)
19272 {
19273   unformat_input_t *i = vam->input;
19274   vl_api_sw_interface_tag_add_del_t *mp;
19275   u32 sw_if_index = ~0;
19276   u8 *tag = 0;
19277   u8 enable = 1;
19278   int ret;
19279
19280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19281     {
19282       if (unformat (i, "tag %s", &tag))
19283         ;
19284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19285         ;
19286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19287         ;
19288       else if (unformat (i, "del"))
19289         enable = 0;
19290       else
19291         break;
19292     }
19293
19294   if (sw_if_index == ~0)
19295     {
19296       errmsg ("missing interface name or sw_if_index");
19297       return -99;
19298     }
19299
19300   if (enable && (tag == 0))
19301     {
19302       errmsg ("no tag specified");
19303       return -99;
19304     }
19305
19306   /* Construct the API message */
19307   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19308   mp->sw_if_index = ntohl (sw_if_index);
19309   mp->is_add = enable;
19310   if (enable)
19311     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19312   vec_free (tag);
19313
19314   S (mp);
19315   W (ret);
19316   return ret;
19317 }
19318
19319 static void vl_api_l2_xconnect_details_t_handler
19320   (vl_api_l2_xconnect_details_t * mp)
19321 {
19322   vat_main_t *vam = &vat_main;
19323
19324   print (vam->ofp, "%15d%15d",
19325          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19326 }
19327
19328 static void vl_api_l2_xconnect_details_t_handler_json
19329   (vl_api_l2_xconnect_details_t * mp)
19330 {
19331   vat_main_t *vam = &vat_main;
19332   vat_json_node_t *node = NULL;
19333
19334   if (VAT_JSON_ARRAY != vam->json_tree.type)
19335     {
19336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19337       vat_json_init_array (&vam->json_tree);
19338     }
19339   node = vat_json_array_add (&vam->json_tree);
19340
19341   vat_json_init_object (node);
19342   vat_json_object_add_uint (node, "rx_sw_if_index",
19343                             ntohl (mp->rx_sw_if_index));
19344   vat_json_object_add_uint (node, "tx_sw_if_index",
19345                             ntohl (mp->tx_sw_if_index));
19346 }
19347
19348 static int
19349 api_l2_xconnect_dump (vat_main_t * vam)
19350 {
19351   vl_api_l2_xconnect_dump_t *mp;
19352   vl_api_control_ping_t *mp_ping;
19353   int ret;
19354
19355   if (!vam->json_output)
19356     {
19357       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19358     }
19359
19360   M (L2_XCONNECT_DUMP, mp);
19361
19362   S (mp);
19363
19364   /* Use a control ping for synchronization */
19365   M (CONTROL_PING, mp_ping);
19366   S (mp_ping);
19367
19368   W (ret);
19369   return ret;
19370 }
19371
19372 static int
19373 api_sw_interface_set_mtu (vat_main_t * vam)
19374 {
19375   unformat_input_t *i = vam->input;
19376   vl_api_sw_interface_set_mtu_t *mp;
19377   u32 sw_if_index = ~0;
19378   u32 mtu = 0;
19379   int ret;
19380
19381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19382     {
19383       if (unformat (i, "mtu %d", &mtu))
19384         ;
19385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19386         ;
19387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19388         ;
19389       else
19390         break;
19391     }
19392
19393   if (sw_if_index == ~0)
19394     {
19395       errmsg ("missing interface name or sw_if_index");
19396       return -99;
19397     }
19398
19399   if (mtu == 0)
19400     {
19401       errmsg ("no mtu specified");
19402       return -99;
19403     }
19404
19405   /* Construct the API message */
19406   M (SW_INTERFACE_SET_MTU, mp);
19407   mp->sw_if_index = ntohl (sw_if_index);
19408   mp->mtu = ntohs ((u16) mtu);
19409
19410   S (mp);
19411   W (ret);
19412   return ret;
19413 }
19414
19415 static int
19416 api_p2p_ethernet_add (vat_main_t * vam)
19417 {
19418   unformat_input_t *i = vam->input;
19419   vl_api_p2p_ethernet_add_t *mp;
19420   u32 parent_if_index = ~0;
19421   u32 sub_id = ~0;
19422   u8 remote_mac[6];
19423   u8 mac_set = 0;
19424   int ret;
19425
19426   memset (remote_mac, 0, sizeof (remote_mac));
19427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19428     {
19429       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19430         ;
19431       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19432         ;
19433       else
19434         if (unformat
19435             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19436         mac_set++;
19437       else if (unformat (i, "sub_id %d", &sub_id))
19438         ;
19439       else
19440         {
19441           clib_warning ("parse error '%U'", format_unformat_error, i);
19442           return -99;
19443         }
19444     }
19445
19446   if (parent_if_index == ~0)
19447     {
19448       errmsg ("missing interface name or sw_if_index");
19449       return -99;
19450     }
19451   if (mac_set == 0)
19452     {
19453       errmsg ("missing remote mac address");
19454       return -99;
19455     }
19456   if (sub_id == ~0)
19457     {
19458       errmsg ("missing sub-interface id");
19459       return -99;
19460     }
19461
19462   M (P2P_ETHERNET_ADD, mp);
19463   mp->parent_if_index = ntohl (parent_if_index);
19464   mp->subif_id = ntohl (sub_id);
19465   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19466
19467   S (mp);
19468   W (ret);
19469   return ret;
19470 }
19471
19472 static int
19473 api_p2p_ethernet_del (vat_main_t * vam)
19474 {
19475   unformat_input_t *i = vam->input;
19476   vl_api_p2p_ethernet_del_t *mp;
19477   u32 parent_if_index = ~0;
19478   u8 remote_mac[6];
19479   u8 mac_set = 0;
19480   int ret;
19481
19482   memset (remote_mac, 0, sizeof (remote_mac));
19483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19484     {
19485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19486         ;
19487       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19488         ;
19489       else
19490         if (unformat
19491             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19492         mac_set++;
19493       else
19494         {
19495           clib_warning ("parse error '%U'", format_unformat_error, i);
19496           return -99;
19497         }
19498     }
19499
19500   if (parent_if_index == ~0)
19501     {
19502       errmsg ("missing interface name or sw_if_index");
19503       return -99;
19504     }
19505   if (mac_set == 0)
19506     {
19507       errmsg ("missing remote mac address");
19508       return -99;
19509     }
19510
19511   M (P2P_ETHERNET_DEL, mp);
19512   mp->parent_if_index = ntohl (parent_if_index);
19513   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19514
19515   S (mp);
19516   W (ret);
19517   return ret;
19518 }
19519
19520 static int
19521 api_lldp_config (vat_main_t * vam)
19522 {
19523   unformat_input_t *i = vam->input;
19524   vl_api_lldp_config_t *mp;
19525   int tx_hold = 0;
19526   int tx_interval = 0;
19527   u8 *sys_name = NULL;
19528   int ret;
19529
19530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19531     {
19532       if (unformat (i, "system-name %s", &sys_name))
19533         ;
19534       else if (unformat (i, "tx-hold %d", &tx_hold))
19535         ;
19536       else if (unformat (i, "tx-interval %d", &tx_interval))
19537         ;
19538       else
19539         {
19540           clib_warning ("parse error '%U'", format_unformat_error, i);
19541           return -99;
19542         }
19543     }
19544
19545   vec_add1 (sys_name, 0);
19546
19547   M (LLDP_CONFIG, mp);
19548   mp->tx_hold = htonl (tx_hold);
19549   mp->tx_interval = htonl (tx_interval);
19550   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19551   vec_free (sys_name);
19552
19553   S (mp);
19554   W (ret);
19555   return ret;
19556 }
19557
19558 static int
19559 api_sw_interface_set_lldp (vat_main_t * vam)
19560 {
19561   unformat_input_t *i = vam->input;
19562   vl_api_sw_interface_set_lldp_t *mp;
19563   u32 sw_if_index = ~0;
19564   u32 enable = 1;
19565   u8 *port_desc = NULL;
19566   int ret;
19567
19568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19569     {
19570       if (unformat (i, "disable"))
19571         enable = 0;
19572       else
19573         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19574         ;
19575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19576         ;
19577       else if (unformat (i, "port-desc %s", &port_desc))
19578         ;
19579       else
19580         break;
19581     }
19582
19583   if (sw_if_index == ~0)
19584     {
19585       errmsg ("missing interface name or sw_if_index");
19586       return -99;
19587     }
19588
19589   /* Construct the API message */
19590   vec_add1 (port_desc, 0);
19591   M (SW_INTERFACE_SET_LLDP, mp);
19592   mp->sw_if_index = ntohl (sw_if_index);
19593   mp->enable = enable;
19594   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19595   vec_free (port_desc);
19596
19597   S (mp);
19598   W (ret);
19599   return ret;
19600 }
19601
19602 static int
19603 q_or_quit (vat_main_t * vam)
19604 {
19605 #if VPP_API_TEST_BUILTIN == 0
19606   longjmp (vam->jump_buf, 1);
19607 #endif
19608   return 0;                     /* not so much */
19609 }
19610
19611 static int
19612 q (vat_main_t * vam)
19613 {
19614   return q_or_quit (vam);
19615 }
19616
19617 static int
19618 quit (vat_main_t * vam)
19619 {
19620   return q_or_quit (vam);
19621 }
19622
19623 static int
19624 comment (vat_main_t * vam)
19625 {
19626   return 0;
19627 }
19628
19629 static int
19630 cmd_cmp (void *a1, void *a2)
19631 {
19632   u8 **c1 = a1;
19633   u8 **c2 = a2;
19634
19635   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19636 }
19637
19638 static int
19639 help (vat_main_t * vam)
19640 {
19641   u8 **cmds = 0;
19642   u8 *name = 0;
19643   hash_pair_t *p;
19644   unformat_input_t *i = vam->input;
19645   int j;
19646
19647   if (unformat (i, "%s", &name))
19648     {
19649       uword *hs;
19650
19651       vec_add1 (name, 0);
19652
19653       hs = hash_get_mem (vam->help_by_name, name);
19654       if (hs)
19655         print (vam->ofp, "usage: %s %s", name, hs[0]);
19656       else
19657         print (vam->ofp, "No such msg / command '%s'", name);
19658       vec_free (name);
19659       return 0;
19660     }
19661
19662   print (vam->ofp, "Help is available for the following:");
19663
19664     /* *INDENT-OFF* */
19665     hash_foreach_pair (p, vam->function_by_name,
19666     ({
19667       vec_add1 (cmds, (u8 *)(p->key));
19668     }));
19669     /* *INDENT-ON* */
19670
19671   vec_sort_with_function (cmds, cmd_cmp);
19672
19673   for (j = 0; j < vec_len (cmds); j++)
19674     print (vam->ofp, "%s", cmds[j]);
19675
19676   vec_free (cmds);
19677   return 0;
19678 }
19679
19680 static int
19681 set (vat_main_t * vam)
19682 {
19683   u8 *name = 0, *value = 0;
19684   unformat_input_t *i = vam->input;
19685
19686   if (unformat (i, "%s", &name))
19687     {
19688       /* The input buffer is a vector, not a string. */
19689       value = vec_dup (i->buffer);
19690       vec_delete (value, i->index, 0);
19691       /* Almost certainly has a trailing newline */
19692       if (value[vec_len (value) - 1] == '\n')
19693         value[vec_len (value) - 1] = 0;
19694       /* Make sure it's a proper string, one way or the other */
19695       vec_add1 (value, 0);
19696       (void) clib_macro_set_value (&vam->macro_main,
19697                                    (char *) name, (char *) value);
19698     }
19699   else
19700     errmsg ("usage: set <name> <value>");
19701
19702   vec_free (name);
19703   vec_free (value);
19704   return 0;
19705 }
19706
19707 static int
19708 unset (vat_main_t * vam)
19709 {
19710   u8 *name = 0;
19711
19712   if (unformat (vam->input, "%s", &name))
19713     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19714       errmsg ("unset: %s wasn't set", name);
19715   vec_free (name);
19716   return 0;
19717 }
19718
19719 typedef struct
19720 {
19721   u8 *name;
19722   u8 *value;
19723 } macro_sort_t;
19724
19725
19726 static int
19727 macro_sort_cmp (void *a1, void *a2)
19728 {
19729   macro_sort_t *s1 = a1;
19730   macro_sort_t *s2 = a2;
19731
19732   return strcmp ((char *) (s1->name), (char *) (s2->name));
19733 }
19734
19735 static int
19736 dump_macro_table (vat_main_t * vam)
19737 {
19738   macro_sort_t *sort_me = 0, *sm;
19739   int i;
19740   hash_pair_t *p;
19741
19742     /* *INDENT-OFF* */
19743     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19744     ({
19745       vec_add2 (sort_me, sm, 1);
19746       sm->name = (u8 *)(p->key);
19747       sm->value = (u8 *) (p->value[0]);
19748     }));
19749     /* *INDENT-ON* */
19750
19751   vec_sort_with_function (sort_me, macro_sort_cmp);
19752
19753   if (vec_len (sort_me))
19754     print (vam->ofp, "%-15s%s", "Name", "Value");
19755   else
19756     print (vam->ofp, "The macro table is empty...");
19757
19758   for (i = 0; i < vec_len (sort_me); i++)
19759     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19760   return 0;
19761 }
19762
19763 static int
19764 dump_node_table (vat_main_t * vam)
19765 {
19766   int i, j;
19767   vlib_node_t *node, *next_node;
19768
19769   if (vec_len (vam->graph_nodes) == 0)
19770     {
19771       print (vam->ofp, "Node table empty, issue get_node_graph...");
19772       return 0;
19773     }
19774
19775   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19776     {
19777       node = vam->graph_nodes[i];
19778       print (vam->ofp, "[%d] %s", i, node->name);
19779       for (j = 0; j < vec_len (node->next_nodes); j++)
19780         {
19781           if (node->next_nodes[j] != ~0)
19782             {
19783               next_node = vam->graph_nodes[node->next_nodes[j]];
19784               print (vam->ofp, "  [%d] %s", j, next_node->name);
19785             }
19786         }
19787     }
19788   return 0;
19789 }
19790
19791 static int
19792 value_sort_cmp (void *a1, void *a2)
19793 {
19794   name_sort_t *n1 = a1;
19795   name_sort_t *n2 = a2;
19796
19797   if (n1->value < n2->value)
19798     return -1;
19799   if (n1->value > n2->value)
19800     return 1;
19801   return 0;
19802 }
19803
19804
19805 static int
19806 dump_msg_api_table (vat_main_t * vam)
19807 {
19808   api_main_t *am = &api_main;
19809   name_sort_t *nses = 0, *ns;
19810   hash_pair_t *hp;
19811   int i;
19812
19813   /* *INDENT-OFF* */
19814   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19815   ({
19816     vec_add2 (nses, ns, 1);
19817     ns->name = (u8 *)(hp->key);
19818     ns->value = (u32) hp->value[0];
19819   }));
19820   /* *INDENT-ON* */
19821
19822   vec_sort_with_function (nses, value_sort_cmp);
19823
19824   for (i = 0; i < vec_len (nses); i++)
19825     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19826   vec_free (nses);
19827   return 0;
19828 }
19829
19830 static int
19831 get_msg_id (vat_main_t * vam)
19832 {
19833   u8 *name_and_crc;
19834   u32 message_index;
19835
19836   if (unformat (vam->input, "%s", &name_and_crc))
19837     {
19838       message_index = vl_api_get_msg_index (name_and_crc);
19839       if (message_index == ~0)
19840         {
19841           print (vam->ofp, " '%s' not found", name_and_crc);
19842           return 0;
19843         }
19844       print (vam->ofp, " '%s' has message index %d",
19845              name_and_crc, message_index);
19846       return 0;
19847     }
19848   errmsg ("name_and_crc required...");
19849   return 0;
19850 }
19851
19852 static int
19853 search_node_table (vat_main_t * vam)
19854 {
19855   unformat_input_t *line_input = vam->input;
19856   u8 *node_to_find;
19857   int j;
19858   vlib_node_t *node, *next_node;
19859   uword *p;
19860
19861   if (vam->graph_node_index_by_name == 0)
19862     {
19863       print (vam->ofp, "Node table empty, issue get_node_graph...");
19864       return 0;
19865     }
19866
19867   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19868     {
19869       if (unformat (line_input, "%s", &node_to_find))
19870         {
19871           vec_add1 (node_to_find, 0);
19872           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19873           if (p == 0)
19874             {
19875               print (vam->ofp, "%s not found...", node_to_find);
19876               goto out;
19877             }
19878           node = vam->graph_nodes[p[0]];
19879           print (vam->ofp, "[%d] %s", p[0], node->name);
19880           for (j = 0; j < vec_len (node->next_nodes); j++)
19881             {
19882               if (node->next_nodes[j] != ~0)
19883                 {
19884                   next_node = vam->graph_nodes[node->next_nodes[j]];
19885                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19886                 }
19887             }
19888         }
19889
19890       else
19891         {
19892           clib_warning ("parse error '%U'", format_unformat_error,
19893                         line_input);
19894           return -99;
19895         }
19896
19897     out:
19898       vec_free (node_to_find);
19899
19900     }
19901
19902   return 0;
19903 }
19904
19905
19906 static int
19907 script (vat_main_t * vam)
19908 {
19909 #if (VPP_API_TEST_BUILTIN==0)
19910   u8 *s = 0;
19911   char *save_current_file;
19912   unformat_input_t save_input;
19913   jmp_buf save_jump_buf;
19914   u32 save_line_number;
19915
19916   FILE *new_fp, *save_ifp;
19917
19918   if (unformat (vam->input, "%s", &s))
19919     {
19920       new_fp = fopen ((char *) s, "r");
19921       if (new_fp == 0)
19922         {
19923           errmsg ("Couldn't open script file %s", s);
19924           vec_free (s);
19925           return -99;
19926         }
19927     }
19928   else
19929     {
19930       errmsg ("Missing script name");
19931       return -99;
19932     }
19933
19934   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19935   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19936   save_ifp = vam->ifp;
19937   save_line_number = vam->input_line_number;
19938   save_current_file = (char *) vam->current_file;
19939
19940   vam->input_line_number = 0;
19941   vam->ifp = new_fp;
19942   vam->current_file = s;
19943   do_one_file (vam);
19944
19945   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19946   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19947   vam->ifp = save_ifp;
19948   vam->input_line_number = save_line_number;
19949   vam->current_file = (u8 *) save_current_file;
19950   vec_free (s);
19951
19952   return 0;
19953 #else
19954   clib_warning ("use the exec command...");
19955   return -99;
19956 #endif
19957 }
19958
19959 static int
19960 echo (vat_main_t * vam)
19961 {
19962   print (vam->ofp, "%v", vam->input->buffer);
19963   return 0;
19964 }
19965
19966 /* List of API message constructors, CLI names map to api_xxx */
19967 #define foreach_vpe_api_msg                                             \
19968 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19969 _(sw_interface_dump,"")                                                 \
19970 _(sw_interface_set_flags,                                               \
19971   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19972 _(sw_interface_add_del_address,                                         \
19973   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19974 _(sw_interface_set_table,                                               \
19975   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19976 _(sw_interface_set_mpls_enable,                                         \
19977   "<intfc> | sw_if_index [disable | dis]")                              \
19978 _(sw_interface_set_vpath,                                               \
19979   "<intfc> | sw_if_index <id> enable | disable")                        \
19980 _(sw_interface_set_vxlan_bypass,                                        \
19981   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19982 _(sw_interface_set_l2_xconnect,                                         \
19983   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19984   "enable | disable")                                                   \
19985 _(sw_interface_set_l2_bridge,                                           \
19986   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19987   "[shg <split-horizon-group>] [bvi]\n"                                 \
19988   "enable | disable")                                                   \
19989 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19990 _(bridge_domain_add_del,                                                \
19991   "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") \
19992 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19993 _(l2fib_add_del,                                                        \
19994   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19995 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19996 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19997 _(l2_flags,                                                             \
19998   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19999 _(bridge_flags,                                                         \
20000   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20001 _(tap_connect,                                                          \
20002   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
20003 _(tap_modify,                                                           \
20004   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20005 _(tap_delete,                                                           \
20006   "<vpp-if-name> | sw_if_index <id>")                                   \
20007 _(sw_interface_tap_dump, "")                                            \
20008 _(ip_add_del_route,                                                     \
20009   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20010   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20011   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20012   "[multipath] [count <n>]")                                            \
20013 _(ip_mroute_add_del,                                                    \
20014   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20015   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20016 _(mpls_route_add_del,                                                   \
20017   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20018   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20019   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20020   "[multipath] [count <n>]")                                            \
20021 _(mpls_ip_bind_unbind,                                                  \
20022   "<label> <addr/len>")                                                 \
20023 _(mpls_tunnel_add_del,                                                  \
20024   " via <addr> [table-id <n>]\n"                                        \
20025   "sw_if_index <id>] [l2]  [del]")                                      \
20026 _(proxy_arp_add_del,                                                    \
20027   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20028 _(proxy_arp_intfc_enable_disable,                                       \
20029   "<intfc> | sw_if_index <id> enable | disable")                        \
20030 _(sw_interface_set_unnumbered,                                          \
20031   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20032 _(ip_neighbor_add_del,                                                  \
20033   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20034   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20035 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20036 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20037 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20038   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20039   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20040   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20041 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20042 _(reset_fib, "vrf <n> [ipv6]")                                          \
20043 _(dhcp_proxy_config,                                                    \
20044   "svr <v46-address> src <v46-address>\n"                               \
20045    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20046 _(dhcp_proxy_set_vss,                                                   \
20047   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20048 _(dhcp_proxy_dump, "ip6")                                               \
20049 _(dhcp_client_config,                                                   \
20050   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20051 _(set_ip_flow_hash,                                                     \
20052   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20053 _(sw_interface_ip6_enable_disable,                                      \
20054   "<intfc> | sw_if_index <id> enable | disable")                        \
20055 _(sw_interface_ip6_set_link_local_address,                              \
20056   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20057 _(ip6nd_proxy_add_del,                                                  \
20058   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20059 _(ip6nd_proxy_dump, "")                                                 \
20060 _(sw_interface_ip6nd_ra_prefix,                                         \
20061   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20062   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20063   "[nolink] [isno]")                                                    \
20064 _(sw_interface_ip6nd_ra_config,                                         \
20065   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20066   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20067   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20068 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20069 _(l2_patch_add_del,                                                     \
20070   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20071   "enable | disable")                                                   \
20072 _(sr_localsid_add_del,                                                  \
20073   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20074   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20075 _(classify_add_del_table,                                               \
20076   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20077   " [del] [del-chain] mask <mask-value>\n"                              \
20078   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20079   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20080 _(classify_add_del_session,                                             \
20081   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20082   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20083   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20084   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20085 _(classify_set_interface_ip_table,                                      \
20086   "<intfc> | sw_if_index <nn> table <nn>")                              \
20087 _(classify_set_interface_l2_tables,                                     \
20088   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20089   "  [other-table <nn>]")                                               \
20090 _(get_node_index, "node <node-name")                                    \
20091 _(add_node_next, "node <node-name> next <next-node-name>")              \
20092 _(l2tpv3_create_tunnel,                                                 \
20093   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20094   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20095   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20096 _(l2tpv3_set_tunnel_cookies,                                            \
20097   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20098   "[new_remote_cookie <nn>]\n")                                         \
20099 _(l2tpv3_interface_enable_disable,                                      \
20100   "<intfc> | sw_if_index <nn> enable | disable")                        \
20101 _(l2tpv3_set_lookup_key,                                                \
20102   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20103 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20104 _(vxlan_add_del_tunnel,                                                 \
20105   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20106   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20107   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20108 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20109 _(gre_add_del_tunnel,                                                   \
20110   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20111 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20112 _(l2_fib_clear_table, "")                                               \
20113 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20114 _(l2_interface_vlan_tag_rewrite,                                        \
20115   "<intfc> | sw_if_index <nn> \n"                                       \
20116   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20117   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20118 _(create_vhost_user_if,                                                 \
20119         "socket <filename> [server] [renumber <dev_instance>] "         \
20120         "[mac <mac_address>]")                                          \
20121 _(modify_vhost_user_if,                                                 \
20122         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20123         "[server] [renumber <dev_instance>]")                           \
20124 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20125 _(sw_interface_vhost_user_dump, "")                                     \
20126 _(show_version, "")                                                     \
20127 _(vxlan_gpe_add_del_tunnel,                                             \
20128   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20129   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20130   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20131   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20132 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20133 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20134 _(interface_name_renumber,                                              \
20135   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20136 _(input_acl_set_interface,                                              \
20137   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20138   "  [l2-table <nn>] [del]")                                            \
20139 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20140 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20141 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20142 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20143 _(ip_dump, "ipv4 | ipv6")                                               \
20144 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20145 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20146   "  spid_id <n> ")                                                     \
20147 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20148   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20149   "  integ_alg <alg> integ_key <hex>")                                  \
20150 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20151   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20152   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20153   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20154 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20155 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20156   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20157   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20158   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20159 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20160 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20161   "(auth_data 0x<data> | auth_data <data>)")                            \
20162 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20163   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20164 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20165   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20166   "(local|remote)")                                                     \
20167 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20168 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20169 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20170 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20171 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20172 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20173 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20174 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20175 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20176 _(delete_loopback,"sw_if_index <nn>")                                   \
20177 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20178 _(map_add_domain,                                                       \
20179   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20180   "ip6-src <ip6addr> "                                                  \
20181   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20182 _(map_del_domain, "index <n>")                                          \
20183 _(map_add_del_rule,                                                     \
20184   "index <n> psid <n> dst <ip6addr> [del]")                             \
20185 _(map_domain_dump, "")                                                  \
20186 _(map_rule_dump, "index <map-domain>")                                  \
20187 _(want_interface_events,  "enable|disable")                             \
20188 _(want_stats,"enable|disable")                                          \
20189 _(get_first_msg_id, "client <name>")                                    \
20190 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20191 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20192   "fib-id <nn> [ip4][ip6][default]")                                    \
20193 _(get_node_graph, " ")                                                  \
20194 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20195 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20196 _(ioam_disable, "")                                                     \
20197 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20198                             " sw_if_index <sw_if_index> p <priority> "  \
20199                             "w <weight>] [del]")                        \
20200 _(one_add_del_locator, "locator-set <locator_name> "                    \
20201                         "iface <intf> | sw_if_index <sw_if_index> "     \
20202                         "p <priority> w <weight> [del]")                \
20203 _(one_add_del_local_eid,"vni <vni> eid "                                \
20204                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20205                          "locator-set <locator_name> [del]"             \
20206                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20207 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20208 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20209 _(one_enable_disable, "enable|disable")                                 \
20210 _(one_map_register_enable_disable, "enable|disable")                    \
20211 _(one_map_register_fallback_threshold, "<value>")                       \
20212 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20213 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20214                                "[seid <seid>] "                         \
20215                                "rloc <locator> p <prio> "               \
20216                                "w <weight> [rloc <loc> ... ] "          \
20217                                "action <action> [del-all]")             \
20218 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20219                           "<local-eid>")                                \
20220 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20221 _(one_use_petr, "ip-address> | disable")                                \
20222 _(one_map_request_mode, "src-dst|dst-only")                             \
20223 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20224 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20225 _(one_locator_set_dump, "[local | remote]")                             \
20226 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20227 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20228                        "[local] | [remote]")                            \
20229 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20230 _(one_l2_arp_bd_get, "")                                                \
20231 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20232 _(one_stats_enable_disable, "enable|disalbe")                           \
20233 _(show_one_stats_enable_disable, "")                                    \
20234 _(one_eid_table_vni_dump, "")                                           \
20235 _(one_eid_table_map_dump, "l2|l3")                                      \
20236 _(one_map_resolver_dump, "")                                            \
20237 _(one_map_server_dump, "")                                              \
20238 _(one_adjacencies_get, "vni <vni>")                                     \
20239 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20240 _(show_one_rloc_probe_state, "")                                        \
20241 _(show_one_map_register_state, "")                                      \
20242 _(show_one_status, "")                                                  \
20243 _(one_stats_dump, "")                                                   \
20244 _(one_stats_flush, "")                                                  \
20245 _(one_get_map_request_itr_rlocs, "")                                    \
20246 _(one_map_register_set_ttl, "<ttl>")                                    \
20247 _(show_one_nsh_mapping, "")                                             \
20248 _(show_one_pitr, "")                                                    \
20249 _(show_one_use_petr, "")                                                \
20250 _(show_one_map_request_mode, "")                                        \
20251 _(show_one_map_register_ttl, "")                                        \
20252 _(show_one_map_register_fallback_threshold, "")                         \
20253 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20254                             " sw_if_index <sw_if_index> p <priority> "  \
20255                             "w <weight>] [del]")                        \
20256 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20257                         "iface <intf> | sw_if_index <sw_if_index> "     \
20258                         "p <priority> w <weight> [del]")                \
20259 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20260                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20261                          "locator-set <locator_name> [del]"             \
20262                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20263 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20264 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20265 _(lisp_enable_disable, "enable|disable")                                \
20266 _(lisp_map_register_enable_disable, "enable|disable")                   \
20267 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20268 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20269                                "[seid <seid>] "                         \
20270                                "rloc <locator> p <prio> "               \
20271                                "w <weight> [rloc <loc> ... ] "          \
20272                                "action <action> [del-all]")             \
20273 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20274                           "<local-eid>")                                \
20275 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20276 _(lisp_use_petr, "<ip-address> | disable")                              \
20277 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20278 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20279 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20280 _(lisp_locator_set_dump, "[local | remote]")                            \
20281 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20282 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20283                        "[local] | [remote]")                            \
20284 _(lisp_eid_table_vni_dump, "")                                          \
20285 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20286 _(lisp_map_resolver_dump, "")                                           \
20287 _(lisp_map_server_dump, "")                                             \
20288 _(lisp_adjacencies_get, "vni <vni>")                                    \
20289 _(gpe_fwd_entry_vnis_get, "")                                           \
20290 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20291 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20292                                 "[table <table-id>]")                   \
20293 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20294 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20295 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20296 _(gpe_get_encap_mode, "")                                               \
20297 _(lisp_gpe_add_del_iface, "up|down")                                    \
20298 _(lisp_gpe_enable_disable, "enable|disable")                            \
20299 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20300   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20301 _(show_lisp_rloc_probe_state, "")                                       \
20302 _(show_lisp_map_register_state, "")                                     \
20303 _(show_lisp_status, "")                                                 \
20304 _(lisp_get_map_request_itr_rlocs, "")                                   \
20305 _(show_lisp_pitr, "")                                                   \
20306 _(show_lisp_use_petr, "")                                               \
20307 _(show_lisp_map_request_mode, "")                                       \
20308 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20309 _(af_packet_delete, "name <host interface name>")                       \
20310 _(policer_add_del, "name <policer name> <params> [del]")                \
20311 _(policer_dump, "[name <policer name>]")                                \
20312 _(policer_classify_set_interface,                                       \
20313   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20314   "  [l2-table <nn>] [del]")                                            \
20315 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20316 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20317     "[master|slave]")                                                   \
20318 _(netmap_delete, "name <interface name>")                               \
20319 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20320 _(mpls_fib_dump, "")                                                    \
20321 _(classify_table_ids, "")                                               \
20322 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20323 _(classify_table_info, "table_id <nn>")                                 \
20324 _(classify_session_dump, "table_id <nn>")                               \
20325 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20326     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20327     "[template_interval <nn>] [udp_checksum]")                          \
20328 _(ipfix_exporter_dump, "")                                              \
20329 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20330 _(ipfix_classify_stream_dump, "")                                       \
20331 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20332 _(ipfix_classify_table_dump, "")                                        \
20333 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20334 _(sw_interface_span_dump, "[l2]")                                           \
20335 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20336 _(pg_create_interface, "if_id <nn>")                                    \
20337 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20338 _(pg_enable_disable, "[stream <id>] disable")                           \
20339 _(ip_source_and_port_range_check_add_del,                               \
20340   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20341 _(ip_source_and_port_range_check_interface_add_del,                     \
20342   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20343   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20344 _(ipsec_gre_add_del_tunnel,                                             \
20345   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20346 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20347 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20348 _(l2_interface_pbb_tag_rewrite,                                         \
20349   "<intfc> | sw_if_index <nn> \n"                                       \
20350   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20351   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20352 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20353 _(flow_classify_set_interface,                                          \
20354   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20355 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20356 _(ip_fib_dump, "")                                                      \
20357 _(ip_mfib_dump, "")                                                     \
20358 _(ip6_fib_dump, "")                                                     \
20359 _(ip6_mfib_dump, "")                                                    \
20360 _(feature_enable_disable, "arc_name <arc_name> "                        \
20361   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20362 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20363 "[disable]")                                                            \
20364 _(l2_xconnect_dump, "")                                                 \
20365 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20366 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20367 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20368 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20369 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20370 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20371 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]")
20372
20373 /* List of command functions, CLI names map directly to functions */
20374 #define foreach_cli_function                                    \
20375 _(comment, "usage: comment <ignore-rest-of-line>")              \
20376 _(dump_interface_table, "usage: dump_interface_table")          \
20377 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20378 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20379 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20380 _(dump_stats_table, "usage: dump_stats_table")                  \
20381 _(dump_macro_table, "usage: dump_macro_table ")                 \
20382 _(dump_node_table, "usage: dump_node_table")                    \
20383 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20384 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20385 _(echo, "usage: echo <message>")                                \
20386 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20387 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20388 _(help, "usage: help")                                          \
20389 _(q, "usage: quit")                                             \
20390 _(quit, "usage: quit")                                          \
20391 _(search_node_table, "usage: search_node_table <name>...")      \
20392 _(set, "usage: set <variable-name> <value>")                    \
20393 _(script, "usage: script <file-name>")                          \
20394 _(unset, "usage: unset <variable-name>")
20395 #define _(N,n)                                  \
20396     static void vl_api_##n##_t_handler_uni      \
20397     (vl_api_##n##_t * mp)                       \
20398     {                                           \
20399         vat_main_t * vam = &vat_main;           \
20400         if (vam->json_output) {                 \
20401             vl_api_##n##_t_handler_json(mp);    \
20402         } else {                                \
20403             vl_api_##n##_t_handler(mp);         \
20404         }                                       \
20405     }
20406 foreach_vpe_api_reply_msg;
20407 #if VPP_API_TEST_BUILTIN == 0
20408 foreach_standalone_reply_msg;
20409 #endif
20410 #undef _
20411
20412 void
20413 vat_api_hookup (vat_main_t * vam)
20414 {
20415 #define _(N,n)                                                  \
20416     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20417                            vl_api_##n##_t_handler_uni,          \
20418                            vl_noop_handler,                     \
20419                            vl_api_##n##_t_endian,               \
20420                            vl_api_##n##_t_print,                \
20421                            sizeof(vl_api_##n##_t), 1);
20422   foreach_vpe_api_reply_msg;
20423 #if VPP_API_TEST_BUILTIN == 0
20424   foreach_standalone_reply_msg;
20425 #endif
20426 #undef _
20427
20428 #if (VPP_API_TEST_BUILTIN==0)
20429   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20430
20431   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20432
20433   vam->function_by_name = hash_create_string (0, sizeof (uword));
20434
20435   vam->help_by_name = hash_create_string (0, sizeof (uword));
20436 #endif
20437
20438   /* API messages we can send */
20439 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20440   foreach_vpe_api_msg;
20441 #undef _
20442
20443   /* Help strings */
20444 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20445   foreach_vpe_api_msg;
20446 #undef _
20447
20448   /* CLI functions */
20449 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20450   foreach_cli_function;
20451 #undef _
20452
20453   /* Help strings */
20454 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20455   foreach_cli_function;
20456 #undef _
20457 }
20458
20459 #if VPP_API_TEST_BUILTIN
20460 static clib_error_t *
20461 vat_api_hookup_shim (vlib_main_t * vm)
20462 {
20463   vat_api_hookup (&vat_main);
20464   return 0;
20465 }
20466
20467 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20468 #endif
20469
20470 /*
20471  * fd.io coding-style-patch-verification: ON
20472  *
20473  * Local Variables:
20474  * eval: (c-set-style "gnu")
20475  * End:
20476  */