LISP: Map-server fallback feature
[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   u8 next_hop_proto_is_ip4 = 1;
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_is_ip4 = 1;
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_is_ip4 = 0;
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_is_ip4 = 1;
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_is_ip4 = 0;
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_is_ip4 = next_hop_proto_is_ip4;
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 (next_hop_proto_is_ip4)
7626             {
7627               clib_memcpy (mp->mr_next_hop,
7628                            &v4_next_hop_address,
7629                            sizeof (v4_next_hop_address));
7630             }
7631           else
7632             {
7633               clib_memcpy (mp->mr_next_hop,
7634                            &v6_next_hop_address,
7635                            sizeof (v6_next_hop_address));
7636             }
7637         }
7638       local_label++;
7639
7640       /* send it... */
7641       S (mp);
7642       /* If we receive SIGTERM, stop now... */
7643       if (vam->do_exit)
7644         break;
7645     }
7646
7647   /* When testing multiple add/del ops, use a control-ping to sync */
7648   if (count > 1)
7649     {
7650       vl_api_control_ping_t *mp_ping;
7651       f64 after;
7652       f64 timeout;
7653
7654       /* Shut off async mode */
7655       vam->async_mode = 0;
7656
7657       M (CONTROL_PING, mp_ping);
7658       S (mp_ping);
7659
7660       timeout = vat_time_now (vam) + 1.0;
7661       while (vat_time_now (vam) < timeout)
7662         if (vam->result_ready == 1)
7663           goto out;
7664       vam->retval = -99;
7665
7666     out:
7667       if (vam->retval == -99)
7668         errmsg ("timeout");
7669
7670       if (vam->async_errors > 0)
7671         {
7672           errmsg ("%d asynchronous errors", vam->async_errors);
7673           vam->retval = -98;
7674         }
7675       vam->async_errors = 0;
7676       after = vat_time_now (vam);
7677
7678       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7679       if (j > 0)
7680         count = j;
7681
7682       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7683              count, after - before, count / (after - before));
7684     }
7685   else
7686     {
7687       int ret;
7688
7689       /* Wait for a reply... */
7690       W (ret);
7691       return ret;
7692     }
7693
7694   /* Return the good/bad news */
7695   return (vam->retval);
7696 }
7697
7698 static int
7699 api_mpls_ip_bind_unbind (vat_main_t * vam)
7700 {
7701   unformat_input_t *i = vam->input;
7702   vl_api_mpls_ip_bind_unbind_t *mp;
7703   u32 ip_table_id = 0;
7704   u8 create_table_if_needed = 0;
7705   u8 is_bind = 1;
7706   u8 is_ip4 = 1;
7707   ip4_address_t v4_address;
7708   ip6_address_t v6_address;
7709   u32 address_length;
7710   u8 address_set = 0;
7711   mpls_label_t local_label = MPLS_LABEL_INVALID;
7712   int ret;
7713
7714   /* Parse args required to build the message */
7715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7716     {
7717       if (unformat (i, "%U/%d", unformat_ip4_address,
7718                     &v4_address, &address_length))
7719         {
7720           is_ip4 = 1;
7721           address_set = 1;
7722         }
7723       else if (unformat (i, "%U/%d", unformat_ip6_address,
7724                          &v6_address, &address_length))
7725         {
7726           is_ip4 = 0;
7727           address_set = 1;
7728         }
7729       else if (unformat (i, "%d", &local_label))
7730         ;
7731       else if (unformat (i, "create-table"))
7732         create_table_if_needed = 1;
7733       else if (unformat (i, "table-id %d", &ip_table_id))
7734         ;
7735       else if (unformat (i, "unbind"))
7736         is_bind = 0;
7737       else if (unformat (i, "bind"))
7738         is_bind = 1;
7739       else
7740         {
7741           clib_warning ("parse error '%U'", format_unformat_error, i);
7742           return -99;
7743         }
7744     }
7745
7746   if (!address_set)
7747     {
7748       errmsg ("IP addres not set");
7749       return -99;
7750     }
7751
7752   if (MPLS_LABEL_INVALID == local_label)
7753     {
7754       errmsg ("missing label");
7755       return -99;
7756     }
7757
7758   /* Construct the API message */
7759   M (MPLS_IP_BIND_UNBIND, mp);
7760
7761   mp->mb_create_table_if_needed = create_table_if_needed;
7762   mp->mb_is_bind = is_bind;
7763   mp->mb_is_ip4 = is_ip4;
7764   mp->mb_ip_table_id = ntohl (ip_table_id);
7765   mp->mb_mpls_table_id = 0;
7766   mp->mb_label = ntohl (local_label);
7767   mp->mb_address_length = address_length;
7768
7769   if (is_ip4)
7770     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7771   else
7772     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7773
7774   /* send it... */
7775   S (mp);
7776
7777   /* Wait for a reply... */
7778   W (ret);
7779   return ret;
7780 }
7781
7782 static int
7783 api_proxy_arp_add_del (vat_main_t * vam)
7784 {
7785   unformat_input_t *i = vam->input;
7786   vl_api_proxy_arp_add_del_t *mp;
7787   u32 vrf_id = 0;
7788   u8 is_add = 1;
7789   ip4_address_t lo, hi;
7790   u8 range_set = 0;
7791   int ret;
7792
7793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7794     {
7795       if (unformat (i, "vrf %d", &vrf_id))
7796         ;
7797       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7798                          unformat_ip4_address, &hi))
7799         range_set = 1;
7800       else if (unformat (i, "del"))
7801         is_add = 0;
7802       else
7803         {
7804           clib_warning ("parse error '%U'", format_unformat_error, i);
7805           return -99;
7806         }
7807     }
7808
7809   if (range_set == 0)
7810     {
7811       errmsg ("address range not set");
7812       return -99;
7813     }
7814
7815   M (PROXY_ARP_ADD_DEL, mp);
7816
7817   mp->vrf_id = ntohl (vrf_id);
7818   mp->is_add = is_add;
7819   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7820   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7821
7822   S (mp);
7823   W (ret);
7824   return ret;
7825 }
7826
7827 static int
7828 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7829 {
7830   unformat_input_t *i = vam->input;
7831   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7832   u32 sw_if_index;
7833   u8 enable = 1;
7834   u8 sw_if_index_set = 0;
7835   int ret;
7836
7837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7838     {
7839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7840         sw_if_index_set = 1;
7841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7842         sw_if_index_set = 1;
7843       else if (unformat (i, "enable"))
7844         enable = 1;
7845       else if (unformat (i, "disable"))
7846         enable = 0;
7847       else
7848         {
7849           clib_warning ("parse error '%U'", format_unformat_error, i);
7850           return -99;
7851         }
7852     }
7853
7854   if (sw_if_index_set == 0)
7855     {
7856       errmsg ("missing interface name or sw_if_index");
7857       return -99;
7858     }
7859
7860   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7861
7862   mp->sw_if_index = ntohl (sw_if_index);
7863   mp->enable_disable = enable;
7864
7865   S (mp);
7866   W (ret);
7867   return ret;
7868 }
7869
7870 static int
7871 api_mpls_tunnel_add_del (vat_main_t * vam)
7872 {
7873   unformat_input_t *i = vam->input;
7874   vl_api_mpls_tunnel_add_del_t *mp;
7875
7876   u8 is_add = 1;
7877   u8 l2_only = 0;
7878   u32 sw_if_index = ~0;
7879   u32 next_hop_sw_if_index = ~0;
7880   u32 next_hop_proto_is_ip4 = 1;
7881
7882   u32 next_hop_table_id = 0;
7883   ip4_address_t v4_next_hop_address = {
7884     .as_u32 = 0,
7885   };
7886   ip6_address_t v6_next_hop_address = { {0} };
7887   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7888   int ret;
7889
7890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7891     {
7892       if (unformat (i, "add"))
7893         is_add = 1;
7894       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7895         is_add = 0;
7896       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7897         ;
7898       else if (unformat (i, "via %U",
7899                          unformat_ip4_address, &v4_next_hop_address))
7900         {
7901           next_hop_proto_is_ip4 = 1;
7902         }
7903       else if (unformat (i, "via %U",
7904                          unformat_ip6_address, &v6_next_hop_address))
7905         {
7906           next_hop_proto_is_ip4 = 0;
7907         }
7908       else if (unformat (i, "l2-only"))
7909         l2_only = 1;
7910       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7911         ;
7912       else if (unformat (i, "out-label %d", &next_hop_out_label))
7913         vec_add1 (labels, ntohl (next_hop_out_label));
7914       else
7915         {
7916           clib_warning ("parse error '%U'", format_unformat_error, i);
7917           return -99;
7918         }
7919     }
7920
7921   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7922
7923   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7924   mp->mt_sw_if_index = ntohl (sw_if_index);
7925   mp->mt_is_add = is_add;
7926   mp->mt_l2_only = l2_only;
7927   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7928   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7929
7930   mp->mt_next_hop_n_out_labels = vec_len (labels);
7931
7932   if (0 != mp->mt_next_hop_n_out_labels)
7933     {
7934       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7935                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7936       vec_free (labels);
7937     }
7938
7939   if (next_hop_proto_is_ip4)
7940     {
7941       clib_memcpy (mp->mt_next_hop,
7942                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7943     }
7944   else
7945     {
7946       clib_memcpy (mp->mt_next_hop,
7947                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7948     }
7949
7950   S (mp);
7951   W (ret);
7952   return ret;
7953 }
7954
7955 static int
7956 api_sw_interface_set_unnumbered (vat_main_t * vam)
7957 {
7958   unformat_input_t *i = vam->input;
7959   vl_api_sw_interface_set_unnumbered_t *mp;
7960   u32 sw_if_index;
7961   u32 unnum_sw_index = ~0;
7962   u8 is_add = 1;
7963   u8 sw_if_index_set = 0;
7964   int ret;
7965
7966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7967     {
7968       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7969         sw_if_index_set = 1;
7970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7971         sw_if_index_set = 1;
7972       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7973         ;
7974       else if (unformat (i, "del"))
7975         is_add = 0;
7976       else
7977         {
7978           clib_warning ("parse error '%U'", format_unformat_error, i);
7979           return -99;
7980         }
7981     }
7982
7983   if (sw_if_index_set == 0)
7984     {
7985       errmsg ("missing interface name or sw_if_index");
7986       return -99;
7987     }
7988
7989   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7990
7991   mp->sw_if_index = ntohl (sw_if_index);
7992   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7993   mp->is_add = is_add;
7994
7995   S (mp);
7996   W (ret);
7997   return ret;
7998 }
7999
8000 static int
8001 api_ip_neighbor_add_del (vat_main_t * vam)
8002 {
8003   unformat_input_t *i = vam->input;
8004   vl_api_ip_neighbor_add_del_t *mp;
8005   u32 sw_if_index;
8006   u8 sw_if_index_set = 0;
8007   u8 is_add = 1;
8008   u8 is_static = 0;
8009   u8 is_no_fib_entry = 0;
8010   u8 mac_address[6];
8011   u8 mac_set = 0;
8012   u8 v4_address_set = 0;
8013   u8 v6_address_set = 0;
8014   ip4_address_t v4address;
8015   ip6_address_t v6address;
8016   int ret;
8017
8018   memset (mac_address, 0, sizeof (mac_address));
8019
8020   /* Parse args required to build the message */
8021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8022     {
8023       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8024         {
8025           mac_set = 1;
8026         }
8027       else if (unformat (i, "del"))
8028         is_add = 0;
8029       else
8030         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8031         sw_if_index_set = 1;
8032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8033         sw_if_index_set = 1;
8034       else if (unformat (i, "is_static"))
8035         is_static = 1;
8036       else if (unformat (i, "no-fib-entry"))
8037         is_no_fib_entry = 1;
8038       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8039         v4_address_set = 1;
8040       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8041         v6_address_set = 1;
8042       else
8043         {
8044           clib_warning ("parse error '%U'", format_unformat_error, i);
8045           return -99;
8046         }
8047     }
8048
8049   if (sw_if_index_set == 0)
8050     {
8051       errmsg ("missing interface name or sw_if_index");
8052       return -99;
8053     }
8054   if (v4_address_set && v6_address_set)
8055     {
8056       errmsg ("both v4 and v6 addresses set");
8057       return -99;
8058     }
8059   if (!v4_address_set && !v6_address_set)
8060     {
8061       errmsg ("no address set");
8062       return -99;
8063     }
8064
8065   /* Construct the API message */
8066   M (IP_NEIGHBOR_ADD_DEL, mp);
8067
8068   mp->sw_if_index = ntohl (sw_if_index);
8069   mp->is_add = is_add;
8070   mp->is_static = is_static;
8071   mp->is_no_adj_fib = is_no_fib_entry;
8072   if (mac_set)
8073     clib_memcpy (mp->mac_address, mac_address, 6);
8074   if (v6_address_set)
8075     {
8076       mp->is_ipv6 = 1;
8077       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8078     }
8079   else
8080     {
8081       /* mp->is_ipv6 = 0; via memset in M macro above */
8082       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8083     }
8084
8085   /* send it... */
8086   S (mp);
8087
8088   /* Wait for a reply, return good/bad news  */
8089   W (ret);
8090   return ret;
8091 }
8092
8093 static int
8094 api_reset_vrf (vat_main_t * vam)
8095 {
8096   unformat_input_t *i = vam->input;
8097   vl_api_reset_vrf_t *mp;
8098   u32 vrf_id = 0;
8099   u8 is_ipv6 = 0;
8100   u8 vrf_id_set = 0;
8101   int ret;
8102
8103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8104     {
8105       if (unformat (i, "vrf %d", &vrf_id))
8106         vrf_id_set = 1;
8107       else if (unformat (i, "ipv6"))
8108         is_ipv6 = 1;
8109       else
8110         {
8111           clib_warning ("parse error '%U'", format_unformat_error, i);
8112           return -99;
8113         }
8114     }
8115
8116   if (vrf_id_set == 0)
8117     {
8118       errmsg ("missing vrf id");
8119       return -99;
8120     }
8121
8122   M (RESET_VRF, mp);
8123
8124   mp->vrf_id = ntohl (vrf_id);
8125   mp->is_ipv6 = is_ipv6;
8126
8127   S (mp);
8128   W (ret);
8129   return ret;
8130 }
8131
8132 static int
8133 api_create_vlan_subif (vat_main_t * vam)
8134 {
8135   unformat_input_t *i = vam->input;
8136   vl_api_create_vlan_subif_t *mp;
8137   u32 sw_if_index;
8138   u8 sw_if_index_set = 0;
8139   u32 vlan_id;
8140   u8 vlan_id_set = 0;
8141   int ret;
8142
8143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8144     {
8145       if (unformat (i, "sw_if_index %d", &sw_if_index))
8146         sw_if_index_set = 1;
8147       else
8148         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8149         sw_if_index_set = 1;
8150       else if (unformat (i, "vlan %d", &vlan_id))
8151         vlan_id_set = 1;
8152       else
8153         {
8154           clib_warning ("parse error '%U'", format_unformat_error, i);
8155           return -99;
8156         }
8157     }
8158
8159   if (sw_if_index_set == 0)
8160     {
8161       errmsg ("missing interface name or sw_if_index");
8162       return -99;
8163     }
8164
8165   if (vlan_id_set == 0)
8166     {
8167       errmsg ("missing vlan_id");
8168       return -99;
8169     }
8170   M (CREATE_VLAN_SUBIF, mp);
8171
8172   mp->sw_if_index = ntohl (sw_if_index);
8173   mp->vlan_id = ntohl (vlan_id);
8174
8175   S (mp);
8176   W (ret);
8177   return ret;
8178 }
8179
8180 #define foreach_create_subif_bit                \
8181 _(no_tags)                                      \
8182 _(one_tag)                                      \
8183 _(two_tags)                                     \
8184 _(dot1ad)                                       \
8185 _(exact_match)                                  \
8186 _(default_sub)                                  \
8187 _(outer_vlan_id_any)                            \
8188 _(inner_vlan_id_any)
8189
8190 static int
8191 api_create_subif (vat_main_t * vam)
8192 {
8193   unformat_input_t *i = vam->input;
8194   vl_api_create_subif_t *mp;
8195   u32 sw_if_index;
8196   u8 sw_if_index_set = 0;
8197   u32 sub_id;
8198   u8 sub_id_set = 0;
8199   u32 no_tags = 0;
8200   u32 one_tag = 0;
8201   u32 two_tags = 0;
8202   u32 dot1ad = 0;
8203   u32 exact_match = 0;
8204   u32 default_sub = 0;
8205   u32 outer_vlan_id_any = 0;
8206   u32 inner_vlan_id_any = 0;
8207   u32 tmp;
8208   u16 outer_vlan_id = 0;
8209   u16 inner_vlan_id = 0;
8210   int ret;
8211
8212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8213     {
8214       if (unformat (i, "sw_if_index %d", &sw_if_index))
8215         sw_if_index_set = 1;
8216       else
8217         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8218         sw_if_index_set = 1;
8219       else if (unformat (i, "sub_id %d", &sub_id))
8220         sub_id_set = 1;
8221       else if (unformat (i, "outer_vlan_id %d", &tmp))
8222         outer_vlan_id = tmp;
8223       else if (unformat (i, "inner_vlan_id %d", &tmp))
8224         inner_vlan_id = tmp;
8225
8226 #define _(a) else if (unformat (i, #a)) a = 1 ;
8227       foreach_create_subif_bit
8228 #undef _
8229         else
8230         {
8231           clib_warning ("parse error '%U'", format_unformat_error, i);
8232           return -99;
8233         }
8234     }
8235
8236   if (sw_if_index_set == 0)
8237     {
8238       errmsg ("missing interface name or sw_if_index");
8239       return -99;
8240     }
8241
8242   if (sub_id_set == 0)
8243     {
8244       errmsg ("missing sub_id");
8245       return -99;
8246     }
8247   M (CREATE_SUBIF, mp);
8248
8249   mp->sw_if_index = ntohl (sw_if_index);
8250   mp->sub_id = ntohl (sub_id);
8251
8252 #define _(a) mp->a = a;
8253   foreach_create_subif_bit;
8254 #undef _
8255
8256   mp->outer_vlan_id = ntohs (outer_vlan_id);
8257   mp->inner_vlan_id = ntohs (inner_vlan_id);
8258
8259   S (mp);
8260   W (ret);
8261   return ret;
8262 }
8263
8264 static int
8265 api_oam_add_del (vat_main_t * vam)
8266 {
8267   unformat_input_t *i = vam->input;
8268   vl_api_oam_add_del_t *mp;
8269   u32 vrf_id = 0;
8270   u8 is_add = 1;
8271   ip4_address_t src, dst;
8272   u8 src_set = 0;
8273   u8 dst_set = 0;
8274   int ret;
8275
8276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8277     {
8278       if (unformat (i, "vrf %d", &vrf_id))
8279         ;
8280       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8281         src_set = 1;
8282       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8283         dst_set = 1;
8284       else if (unformat (i, "del"))
8285         is_add = 0;
8286       else
8287         {
8288           clib_warning ("parse error '%U'", format_unformat_error, i);
8289           return -99;
8290         }
8291     }
8292
8293   if (src_set == 0)
8294     {
8295       errmsg ("missing src addr");
8296       return -99;
8297     }
8298
8299   if (dst_set == 0)
8300     {
8301       errmsg ("missing dst addr");
8302       return -99;
8303     }
8304
8305   M (OAM_ADD_DEL, mp);
8306
8307   mp->vrf_id = ntohl (vrf_id);
8308   mp->is_add = is_add;
8309   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8310   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8311
8312   S (mp);
8313   W (ret);
8314   return ret;
8315 }
8316
8317 static int
8318 api_reset_fib (vat_main_t * vam)
8319 {
8320   unformat_input_t *i = vam->input;
8321   vl_api_reset_fib_t *mp;
8322   u32 vrf_id = 0;
8323   u8 is_ipv6 = 0;
8324   u8 vrf_id_set = 0;
8325
8326   int ret;
8327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8328     {
8329       if (unformat (i, "vrf %d", &vrf_id))
8330         vrf_id_set = 1;
8331       else if (unformat (i, "ipv6"))
8332         is_ipv6 = 1;
8333       else
8334         {
8335           clib_warning ("parse error '%U'", format_unformat_error, i);
8336           return -99;
8337         }
8338     }
8339
8340   if (vrf_id_set == 0)
8341     {
8342       errmsg ("missing vrf id");
8343       return -99;
8344     }
8345
8346   M (RESET_FIB, mp);
8347
8348   mp->vrf_id = ntohl (vrf_id);
8349   mp->is_ipv6 = is_ipv6;
8350
8351   S (mp);
8352   W (ret);
8353   return ret;
8354 }
8355
8356 static int
8357 api_dhcp_proxy_config (vat_main_t * vam)
8358 {
8359   unformat_input_t *i = vam->input;
8360   vl_api_dhcp_proxy_config_t *mp;
8361   u32 rx_vrf_id = 0;
8362   u32 server_vrf_id = 0;
8363   u8 is_add = 1;
8364   u8 v4_address_set = 0;
8365   u8 v6_address_set = 0;
8366   ip4_address_t v4address;
8367   ip6_address_t v6address;
8368   u8 v4_src_address_set = 0;
8369   u8 v6_src_address_set = 0;
8370   ip4_address_t v4srcaddress;
8371   ip6_address_t v6srcaddress;
8372   int ret;
8373
8374   /* Parse args required to build the message */
8375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8376     {
8377       if (unformat (i, "del"))
8378         is_add = 0;
8379       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8380         ;
8381       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8382         ;
8383       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8384         v4_address_set = 1;
8385       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8386         v6_address_set = 1;
8387       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8388         v4_src_address_set = 1;
8389       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8390         v6_src_address_set = 1;
8391       else
8392         break;
8393     }
8394
8395   if (v4_address_set && v6_address_set)
8396     {
8397       errmsg ("both v4 and v6 server addresses set");
8398       return -99;
8399     }
8400   if (!v4_address_set && !v6_address_set)
8401     {
8402       errmsg ("no server addresses set");
8403       return -99;
8404     }
8405
8406   if (v4_src_address_set && v6_src_address_set)
8407     {
8408       errmsg ("both v4 and v6  src addresses set");
8409       return -99;
8410     }
8411   if (!v4_src_address_set && !v6_src_address_set)
8412     {
8413       errmsg ("no src addresses set");
8414       return -99;
8415     }
8416
8417   if (!(v4_src_address_set && v4_address_set) &&
8418       !(v6_src_address_set && v6_address_set))
8419     {
8420       errmsg ("no matching server and src addresses set");
8421       return -99;
8422     }
8423
8424   /* Construct the API message */
8425   M (DHCP_PROXY_CONFIG, mp);
8426
8427   mp->is_add = is_add;
8428   mp->rx_vrf_id = ntohl (rx_vrf_id);
8429   mp->server_vrf_id = ntohl (server_vrf_id);
8430   if (v6_address_set)
8431     {
8432       mp->is_ipv6 = 1;
8433       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8434       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8435     }
8436   else
8437     {
8438       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8439       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8440     }
8441
8442   /* send it... */
8443   S (mp);
8444
8445   /* Wait for a reply, return good/bad news  */
8446   W (ret);
8447   return ret;
8448 }
8449
8450 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8451 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8452
8453 static void
8454 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8455 {
8456   vat_main_t *vam = &vat_main;
8457   u32 i, count = mp->count;
8458   vl_api_dhcp_server_t *s;
8459
8460   if (mp->is_ipv6)
8461     print (vam->ofp,
8462            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8463            ntohl (mp->rx_vrf_id),
8464            format_ip6_address, mp->dhcp_src_address,
8465            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8466   else
8467     print (vam->ofp,
8468            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8469            ntohl (mp->rx_vrf_id),
8470            format_ip4_address, mp->dhcp_src_address,
8471            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8472
8473   for (i = 0; i < count; i++)
8474     {
8475       s = &mp->servers[i];
8476
8477       if (mp->is_ipv6)
8478         print (vam->ofp,
8479                " Server Table-ID %d, Server Address %U",
8480                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8481       else
8482         print (vam->ofp,
8483                " Server Table-ID %d, Server Address %U",
8484                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8485     }
8486 }
8487
8488 static void vl_api_dhcp_proxy_details_t_handler_json
8489   (vl_api_dhcp_proxy_details_t * mp)
8490 {
8491   vat_main_t *vam = &vat_main;
8492   vat_json_node_t *node = NULL;
8493   u32 i, count = mp->count;
8494   struct in_addr ip4;
8495   struct in6_addr ip6;
8496   vl_api_dhcp_server_t *s;
8497
8498   if (VAT_JSON_ARRAY != vam->json_tree.type)
8499     {
8500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8501       vat_json_init_array (&vam->json_tree);
8502     }
8503   node = vat_json_array_add (&vam->json_tree);
8504
8505   vat_json_init_object (node);
8506   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8507   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8508   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8509
8510   if (mp->is_ipv6)
8511     {
8512       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8513       vat_json_object_add_ip6 (node, "src_address", ip6);
8514     }
8515   else
8516     {
8517       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8518       vat_json_object_add_ip4 (node, "src_address", ip4);
8519     }
8520
8521   for (i = 0; i < count; i++)
8522     {
8523       s = &mp->servers[i];
8524
8525       vat_json_object_add_uint (node, "server-table-id",
8526                                 ntohl (s->server_vrf_id));
8527
8528       if (mp->is_ipv6)
8529         {
8530           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8531           vat_json_object_add_ip4 (node, "src_address", ip4);
8532         }
8533       else
8534         {
8535           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8536           vat_json_object_add_ip6 (node, "server_address", ip6);
8537         }
8538     }
8539 }
8540
8541 static int
8542 api_dhcp_proxy_dump (vat_main_t * vam)
8543 {
8544   unformat_input_t *i = vam->input;
8545   vl_api_control_ping_t *mp_ping;
8546   vl_api_dhcp_proxy_dump_t *mp;
8547   u8 is_ipv6 = 0;
8548   int ret;
8549
8550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8551     {
8552       if (unformat (i, "ipv6"))
8553         is_ipv6 = 1;
8554       else
8555         {
8556           clib_warning ("parse error '%U'", format_unformat_error, i);
8557           return -99;
8558         }
8559     }
8560
8561   M (DHCP_PROXY_DUMP, mp);
8562
8563   mp->is_ip6 = is_ipv6;
8564   S (mp);
8565
8566   /* Use a control ping for synchronization */
8567   M (CONTROL_PING, mp_ping);
8568   S (mp_ping);
8569
8570   W (ret);
8571   return ret;
8572 }
8573
8574 static int
8575 api_dhcp_proxy_set_vss (vat_main_t * vam)
8576 {
8577   unformat_input_t *i = vam->input;
8578   vl_api_dhcp_proxy_set_vss_t *mp;
8579   u8 is_ipv6 = 0;
8580   u8 is_add = 1;
8581   u32 tbl_id;
8582   u8 tbl_id_set = 0;
8583   u32 oui;
8584   u8 oui_set = 0;
8585   u32 fib_id;
8586   u8 fib_id_set = 0;
8587   int ret;
8588
8589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8590     {
8591       if (unformat (i, "tbl_id %d", &tbl_id))
8592         tbl_id_set = 1;
8593       if (unformat (i, "fib_id %d", &fib_id))
8594         fib_id_set = 1;
8595       if (unformat (i, "oui %d", &oui))
8596         oui_set = 1;
8597       else if (unformat (i, "ipv6"))
8598         is_ipv6 = 1;
8599       else if (unformat (i, "del"))
8600         is_add = 0;
8601       else
8602         {
8603           clib_warning ("parse error '%U'", format_unformat_error, i);
8604           return -99;
8605         }
8606     }
8607
8608   if (tbl_id_set == 0)
8609     {
8610       errmsg ("missing tbl id");
8611       return -99;
8612     }
8613
8614   if (fib_id_set == 0)
8615     {
8616       errmsg ("missing fib id");
8617       return -99;
8618     }
8619   if (oui_set == 0)
8620     {
8621       errmsg ("missing oui");
8622       return -99;
8623     }
8624
8625   M (DHCP_PROXY_SET_VSS, mp);
8626   mp->tbl_id = ntohl (tbl_id);
8627   mp->fib_id = ntohl (fib_id);
8628   mp->oui = ntohl (oui);
8629   mp->is_ipv6 = is_ipv6;
8630   mp->is_add = is_add;
8631
8632   S (mp);
8633   W (ret);
8634   return ret;
8635 }
8636
8637 static int
8638 api_dhcp_client_config (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_dhcp_client_config_t *mp;
8642   u32 sw_if_index;
8643   u8 sw_if_index_set = 0;
8644   u8 is_add = 1;
8645   u8 *hostname = 0;
8646   u8 disable_event = 0;
8647   int ret;
8648
8649   /* Parse args required to build the message */
8650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8651     {
8652       if (unformat (i, "del"))
8653         is_add = 0;
8654       else
8655         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8656         sw_if_index_set = 1;
8657       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8658         sw_if_index_set = 1;
8659       else if (unformat (i, "hostname %s", &hostname))
8660         ;
8661       else if (unformat (i, "disable_event"))
8662         disable_event = 1;
8663       else
8664         break;
8665     }
8666
8667   if (sw_if_index_set == 0)
8668     {
8669       errmsg ("missing interface name or sw_if_index");
8670       return -99;
8671     }
8672
8673   if (vec_len (hostname) > 63)
8674     {
8675       errmsg ("hostname too long");
8676     }
8677   vec_add1 (hostname, 0);
8678
8679   /* Construct the API message */
8680   M (DHCP_CLIENT_CONFIG, mp);
8681
8682   mp->sw_if_index = htonl (sw_if_index);
8683   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8684   vec_free (hostname);
8685   mp->is_add = is_add;
8686   mp->want_dhcp_event = disable_event ? 0 : 1;
8687   mp->pid = htonl (getpid ());
8688
8689   /* send it... */
8690   S (mp);
8691
8692   /* Wait for a reply, return good/bad news  */
8693   W (ret);
8694   return ret;
8695 }
8696
8697 static int
8698 api_set_ip_flow_hash (vat_main_t * vam)
8699 {
8700   unformat_input_t *i = vam->input;
8701   vl_api_set_ip_flow_hash_t *mp;
8702   u32 vrf_id = 0;
8703   u8 is_ipv6 = 0;
8704   u8 vrf_id_set = 0;
8705   u8 src = 0;
8706   u8 dst = 0;
8707   u8 sport = 0;
8708   u8 dport = 0;
8709   u8 proto = 0;
8710   u8 reverse = 0;
8711   int ret;
8712
8713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8714     {
8715       if (unformat (i, "vrf %d", &vrf_id))
8716         vrf_id_set = 1;
8717       else if (unformat (i, "ipv6"))
8718         is_ipv6 = 1;
8719       else if (unformat (i, "src"))
8720         src = 1;
8721       else if (unformat (i, "dst"))
8722         dst = 1;
8723       else if (unformat (i, "sport"))
8724         sport = 1;
8725       else if (unformat (i, "dport"))
8726         dport = 1;
8727       else if (unformat (i, "proto"))
8728         proto = 1;
8729       else if (unformat (i, "reverse"))
8730         reverse = 1;
8731
8732       else
8733         {
8734           clib_warning ("parse error '%U'", format_unformat_error, i);
8735           return -99;
8736         }
8737     }
8738
8739   if (vrf_id_set == 0)
8740     {
8741       errmsg ("missing vrf id");
8742       return -99;
8743     }
8744
8745   M (SET_IP_FLOW_HASH, mp);
8746   mp->src = src;
8747   mp->dst = dst;
8748   mp->sport = sport;
8749   mp->dport = dport;
8750   mp->proto = proto;
8751   mp->reverse = reverse;
8752   mp->vrf_id = ntohl (vrf_id);
8753   mp->is_ipv6 = is_ipv6;
8754
8755   S (mp);
8756   W (ret);
8757   return ret;
8758 }
8759
8760 static int
8761 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8762 {
8763   unformat_input_t *i = vam->input;
8764   vl_api_sw_interface_ip6_enable_disable_t *mp;
8765   u32 sw_if_index;
8766   u8 sw_if_index_set = 0;
8767   u8 enable = 0;
8768   int ret;
8769
8770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8771     {
8772       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8773         sw_if_index_set = 1;
8774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8775         sw_if_index_set = 1;
8776       else if (unformat (i, "enable"))
8777         enable = 1;
8778       else if (unformat (i, "disable"))
8779         enable = 0;
8780       else
8781         {
8782           clib_warning ("parse error '%U'", format_unformat_error, i);
8783           return -99;
8784         }
8785     }
8786
8787   if (sw_if_index_set == 0)
8788     {
8789       errmsg ("missing interface name or sw_if_index");
8790       return -99;
8791     }
8792
8793   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8794
8795   mp->sw_if_index = ntohl (sw_if_index);
8796   mp->enable = enable;
8797
8798   S (mp);
8799   W (ret);
8800   return ret;
8801 }
8802
8803 static int
8804 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8805 {
8806   unformat_input_t *i = vam->input;
8807   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8808   u32 sw_if_index;
8809   u8 sw_if_index_set = 0;
8810   u8 v6_address_set = 0;
8811   ip6_address_t v6address;
8812   int ret;
8813
8814   /* Parse args required to build the message */
8815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8816     {
8817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8818         sw_if_index_set = 1;
8819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8820         sw_if_index_set = 1;
8821       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8822         v6_address_set = 1;
8823       else
8824         break;
8825     }
8826
8827   if (sw_if_index_set == 0)
8828     {
8829       errmsg ("missing interface name or sw_if_index");
8830       return -99;
8831     }
8832   if (!v6_address_set)
8833     {
8834       errmsg ("no address set");
8835       return -99;
8836     }
8837
8838   /* Construct the API message */
8839   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8840
8841   mp->sw_if_index = ntohl (sw_if_index);
8842   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8843
8844   /* send it... */
8845   S (mp);
8846
8847   /* Wait for a reply, return good/bad news  */
8848   W (ret);
8849   return ret;
8850 }
8851
8852 static int
8853 api_ip6nd_proxy_add_del (vat_main_t * vam)
8854 {
8855   unformat_input_t *i = vam->input;
8856   vl_api_ip6nd_proxy_add_del_t *mp;
8857   u32 sw_if_index = ~0;
8858   u8 v6_address_set = 0;
8859   ip6_address_t v6address;
8860   u8 is_del = 0;
8861   int ret;
8862
8863   /* Parse args required to build the message */
8864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8865     {
8866       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8867         ;
8868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8869         ;
8870       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8871         v6_address_set = 1;
8872       if (unformat (i, "del"))
8873         is_del = 1;
8874       else
8875         {
8876           clib_warning ("parse error '%U'", format_unformat_error, i);
8877           return -99;
8878         }
8879     }
8880
8881   if (sw_if_index == ~0)
8882     {
8883       errmsg ("missing interface name or sw_if_index");
8884       return -99;
8885     }
8886   if (!v6_address_set)
8887     {
8888       errmsg ("no address set");
8889       return -99;
8890     }
8891
8892   /* Construct the API message */
8893   M (IP6ND_PROXY_ADD_DEL, mp);
8894
8895   mp->is_del = is_del;
8896   mp->sw_if_index = ntohl (sw_if_index);
8897   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8898
8899   /* send it... */
8900   S (mp);
8901
8902   /* Wait for a reply, return good/bad news  */
8903   W (ret);
8904   return ret;
8905 }
8906
8907 static int
8908 api_ip6nd_proxy_dump (vat_main_t * vam)
8909 {
8910   vl_api_ip6nd_proxy_dump_t *mp;
8911   vl_api_control_ping_t *mp_ping;
8912   int ret;
8913
8914   M (IP6ND_PROXY_DUMP, mp);
8915
8916   S (mp);
8917
8918   /* Use a control ping for synchronization */
8919   M (CONTROL_PING, mp_ping);
8920   S (mp_ping);
8921
8922   W (ret);
8923   return ret;
8924 }
8925
8926 static void vl_api_ip6nd_proxy_details_t_handler
8927   (vl_api_ip6nd_proxy_details_t * mp)
8928 {
8929   vat_main_t *vam = &vat_main;
8930
8931   print (vam->ofp, "host %U sw_if_index %d",
8932          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8933 }
8934
8935 static void vl_api_ip6nd_proxy_details_t_handler_json
8936   (vl_api_ip6nd_proxy_details_t * mp)
8937 {
8938   vat_main_t *vam = &vat_main;
8939   struct in6_addr ip6;
8940   vat_json_node_t *node = NULL;
8941
8942   if (VAT_JSON_ARRAY != vam->json_tree.type)
8943     {
8944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8945       vat_json_init_array (&vam->json_tree);
8946     }
8947   node = vat_json_array_add (&vam->json_tree);
8948
8949   vat_json_init_object (node);
8950   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8951
8952   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8953   vat_json_object_add_ip6 (node, "host", ip6);
8954 }
8955
8956 static int
8957 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8958 {
8959   unformat_input_t *i = vam->input;
8960   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8961   u32 sw_if_index;
8962   u8 sw_if_index_set = 0;
8963   u32 address_length = 0;
8964   u8 v6_address_set = 0;
8965   ip6_address_t v6address;
8966   u8 use_default = 0;
8967   u8 no_advertise = 0;
8968   u8 off_link = 0;
8969   u8 no_autoconfig = 0;
8970   u8 no_onlink = 0;
8971   u8 is_no = 0;
8972   u32 val_lifetime = 0;
8973   u32 pref_lifetime = 0;
8974   int ret;
8975
8976   /* Parse args required to build the message */
8977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8978     {
8979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8980         sw_if_index_set = 1;
8981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8982         sw_if_index_set = 1;
8983       else if (unformat (i, "%U/%d",
8984                          unformat_ip6_address, &v6address, &address_length))
8985         v6_address_set = 1;
8986       else if (unformat (i, "val_life %d", &val_lifetime))
8987         ;
8988       else if (unformat (i, "pref_life %d", &pref_lifetime))
8989         ;
8990       else if (unformat (i, "def"))
8991         use_default = 1;
8992       else if (unformat (i, "noadv"))
8993         no_advertise = 1;
8994       else if (unformat (i, "offl"))
8995         off_link = 1;
8996       else if (unformat (i, "noauto"))
8997         no_autoconfig = 1;
8998       else if (unformat (i, "nolink"))
8999         no_onlink = 1;
9000       else if (unformat (i, "isno"))
9001         is_no = 1;
9002       else
9003         {
9004           clib_warning ("parse error '%U'", format_unformat_error, i);
9005           return -99;
9006         }
9007     }
9008
9009   if (sw_if_index_set == 0)
9010     {
9011       errmsg ("missing interface name or sw_if_index");
9012       return -99;
9013     }
9014   if (!v6_address_set)
9015     {
9016       errmsg ("no address set");
9017       return -99;
9018     }
9019
9020   /* Construct the API message */
9021   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9022
9023   mp->sw_if_index = ntohl (sw_if_index);
9024   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9025   mp->address_length = address_length;
9026   mp->use_default = use_default;
9027   mp->no_advertise = no_advertise;
9028   mp->off_link = off_link;
9029   mp->no_autoconfig = no_autoconfig;
9030   mp->no_onlink = no_onlink;
9031   mp->is_no = is_no;
9032   mp->val_lifetime = ntohl (val_lifetime);
9033   mp->pref_lifetime = ntohl (pref_lifetime);
9034
9035   /* send it... */
9036   S (mp);
9037
9038   /* Wait for a reply, return good/bad news  */
9039   W (ret);
9040   return ret;
9041 }
9042
9043 static int
9044 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9045 {
9046   unformat_input_t *i = vam->input;
9047   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9048   u32 sw_if_index;
9049   u8 sw_if_index_set = 0;
9050   u8 suppress = 0;
9051   u8 managed = 0;
9052   u8 other = 0;
9053   u8 ll_option = 0;
9054   u8 send_unicast = 0;
9055   u8 cease = 0;
9056   u8 is_no = 0;
9057   u8 default_router = 0;
9058   u32 max_interval = 0;
9059   u32 min_interval = 0;
9060   u32 lifetime = 0;
9061   u32 initial_count = 0;
9062   u32 initial_interval = 0;
9063   int ret;
9064
9065
9066   /* Parse args required to build the message */
9067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9068     {
9069       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9070         sw_if_index_set = 1;
9071       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9072         sw_if_index_set = 1;
9073       else if (unformat (i, "maxint %d", &max_interval))
9074         ;
9075       else if (unformat (i, "minint %d", &min_interval))
9076         ;
9077       else if (unformat (i, "life %d", &lifetime))
9078         ;
9079       else if (unformat (i, "count %d", &initial_count))
9080         ;
9081       else if (unformat (i, "interval %d", &initial_interval))
9082         ;
9083       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9084         suppress = 1;
9085       else if (unformat (i, "managed"))
9086         managed = 1;
9087       else if (unformat (i, "other"))
9088         other = 1;
9089       else if (unformat (i, "ll"))
9090         ll_option = 1;
9091       else if (unformat (i, "send"))
9092         send_unicast = 1;
9093       else if (unformat (i, "cease"))
9094         cease = 1;
9095       else if (unformat (i, "isno"))
9096         is_no = 1;
9097       else if (unformat (i, "def"))
9098         default_router = 1;
9099       else
9100         {
9101           clib_warning ("parse error '%U'", format_unformat_error, i);
9102           return -99;
9103         }
9104     }
9105
9106   if (sw_if_index_set == 0)
9107     {
9108       errmsg ("missing interface name or sw_if_index");
9109       return -99;
9110     }
9111
9112   /* Construct the API message */
9113   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9114
9115   mp->sw_if_index = ntohl (sw_if_index);
9116   mp->max_interval = ntohl (max_interval);
9117   mp->min_interval = ntohl (min_interval);
9118   mp->lifetime = ntohl (lifetime);
9119   mp->initial_count = ntohl (initial_count);
9120   mp->initial_interval = ntohl (initial_interval);
9121   mp->suppress = suppress;
9122   mp->managed = managed;
9123   mp->other = other;
9124   mp->ll_option = ll_option;
9125   mp->send_unicast = send_unicast;
9126   mp->cease = cease;
9127   mp->is_no = is_no;
9128   mp->default_router = default_router;
9129
9130   /* send it... */
9131   S (mp);
9132
9133   /* Wait for a reply, return good/bad news  */
9134   W (ret);
9135   return ret;
9136 }
9137
9138 static int
9139 api_set_arp_neighbor_limit (vat_main_t * vam)
9140 {
9141   unformat_input_t *i = vam->input;
9142   vl_api_set_arp_neighbor_limit_t *mp;
9143   u32 arp_nbr_limit;
9144   u8 limit_set = 0;
9145   u8 is_ipv6 = 0;
9146   int ret;
9147
9148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9149     {
9150       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9151         limit_set = 1;
9152       else if (unformat (i, "ipv6"))
9153         is_ipv6 = 1;
9154       else
9155         {
9156           clib_warning ("parse error '%U'", format_unformat_error, i);
9157           return -99;
9158         }
9159     }
9160
9161   if (limit_set == 0)
9162     {
9163       errmsg ("missing limit value");
9164       return -99;
9165     }
9166
9167   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9168
9169   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9170   mp->is_ipv6 = is_ipv6;
9171
9172   S (mp);
9173   W (ret);
9174   return ret;
9175 }
9176
9177 static int
9178 api_l2_patch_add_del (vat_main_t * vam)
9179 {
9180   unformat_input_t *i = vam->input;
9181   vl_api_l2_patch_add_del_t *mp;
9182   u32 rx_sw_if_index;
9183   u8 rx_sw_if_index_set = 0;
9184   u32 tx_sw_if_index;
9185   u8 tx_sw_if_index_set = 0;
9186   u8 is_add = 1;
9187   int ret;
9188
9189   /* Parse args required to build the message */
9190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9191     {
9192       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9193         rx_sw_if_index_set = 1;
9194       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9195         tx_sw_if_index_set = 1;
9196       else if (unformat (i, "rx"))
9197         {
9198           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9199             {
9200               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9201                             &rx_sw_if_index))
9202                 rx_sw_if_index_set = 1;
9203             }
9204           else
9205             break;
9206         }
9207       else if (unformat (i, "tx"))
9208         {
9209           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9210             {
9211               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9212                             &tx_sw_if_index))
9213                 tx_sw_if_index_set = 1;
9214             }
9215           else
9216             break;
9217         }
9218       else if (unformat (i, "del"))
9219         is_add = 0;
9220       else
9221         break;
9222     }
9223
9224   if (rx_sw_if_index_set == 0)
9225     {
9226       errmsg ("missing rx interface name or rx_sw_if_index");
9227       return -99;
9228     }
9229
9230   if (tx_sw_if_index_set == 0)
9231     {
9232       errmsg ("missing tx interface name or tx_sw_if_index");
9233       return -99;
9234     }
9235
9236   M (L2_PATCH_ADD_DEL, mp);
9237
9238   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9239   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9240   mp->is_add = is_add;
9241
9242   S (mp);
9243   W (ret);
9244   return ret;
9245 }
9246
9247 u8 is_del;
9248 u8 localsid_addr[16];
9249 u8 end_psp;
9250 u8 behavior;
9251 u32 sw_if_index;
9252 u32 vlan_index;
9253 u32 fib_table;
9254 u8 nh_addr[16];
9255
9256 static int
9257 api_sr_localsid_add_del (vat_main_t * vam)
9258 {
9259   unformat_input_t *i = vam->input;
9260   vl_api_sr_localsid_add_del_t *mp;
9261
9262   u8 is_del;
9263   ip6_address_t localsid;
9264   u8 end_psp = 0;
9265   u8 behavior = ~0;
9266   u32 sw_if_index;
9267   u32 fib_table = ~(u32) 0;
9268   ip6_address_t next_hop;
9269
9270   bool nexthop_set = 0;
9271
9272   int ret;
9273
9274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (i, "del"))
9277         is_del = 1;
9278       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9279       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9280         nexthop_set = 1;
9281       else if (unformat (i, "behavior %u", &behavior));
9282       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9283       else if (unformat (i, "fib-table %u", &fib_table));
9284       else if (unformat (i, "end.psp %u", &behavior));
9285       else
9286         break;
9287     }
9288
9289   M (SR_LOCALSID_ADD_DEL, mp);
9290
9291   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9292   if (nexthop_set)
9293     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9294   mp->behavior = behavior;
9295   mp->sw_if_index = ntohl (sw_if_index);
9296   mp->fib_table = ntohl (fib_table);
9297   mp->end_psp = end_psp;
9298   mp->is_del = is_del;
9299
9300   S (mp);
9301   W (ret);
9302   return ret;
9303 }
9304
9305 static int
9306 api_ioam_enable (vat_main_t * vam)
9307 {
9308   unformat_input_t *input = vam->input;
9309   vl_api_ioam_enable_t *mp;
9310   u32 id = 0;
9311   int has_trace_option = 0;
9312   int has_pot_option = 0;
9313   int has_seqno_option = 0;
9314   int has_analyse_option = 0;
9315   int ret;
9316
9317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9318     {
9319       if (unformat (input, "trace"))
9320         has_trace_option = 1;
9321       else if (unformat (input, "pot"))
9322         has_pot_option = 1;
9323       else if (unformat (input, "seqno"))
9324         has_seqno_option = 1;
9325       else if (unformat (input, "analyse"))
9326         has_analyse_option = 1;
9327       else
9328         break;
9329     }
9330   M (IOAM_ENABLE, mp);
9331   mp->id = htons (id);
9332   mp->seqno = has_seqno_option;
9333   mp->analyse = has_analyse_option;
9334   mp->pot_enable = has_pot_option;
9335   mp->trace_enable = has_trace_option;
9336
9337   S (mp);
9338   W (ret);
9339   return ret;
9340 }
9341
9342
9343 static int
9344 api_ioam_disable (vat_main_t * vam)
9345 {
9346   vl_api_ioam_disable_t *mp;
9347   int ret;
9348
9349   M (IOAM_DISABLE, mp);
9350   S (mp);
9351   W (ret);
9352   return ret;
9353 }
9354
9355 #define foreach_tcp_proto_field                 \
9356 _(src_port)                                     \
9357 _(dst_port)
9358
9359 #define foreach_udp_proto_field                 \
9360 _(src_port)                                     \
9361 _(dst_port)
9362
9363 #define foreach_ip4_proto_field                 \
9364 _(src_address)                                  \
9365 _(dst_address)                                  \
9366 _(tos)                                          \
9367 _(length)                                       \
9368 _(fragment_id)                                  \
9369 _(ttl)                                          \
9370 _(protocol)                                     \
9371 _(checksum)
9372
9373 typedef struct
9374 {
9375   u16 src_port, dst_port;
9376 } tcpudp_header_t;
9377
9378 #if VPP_API_TEST_BUILTIN == 0
9379 uword
9380 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9381 {
9382   u8 **maskp = va_arg (*args, u8 **);
9383   u8 *mask = 0;
9384   u8 found_something = 0;
9385   tcp_header_t *tcp;
9386
9387 #define _(a) u8 a=0;
9388   foreach_tcp_proto_field;
9389 #undef _
9390
9391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9392     {
9393       if (0);
9394 #define _(a) else if (unformat (input, #a)) a=1;
9395       foreach_tcp_proto_field
9396 #undef _
9397         else
9398         break;
9399     }
9400
9401 #define _(a) found_something += a;
9402   foreach_tcp_proto_field;
9403 #undef _
9404
9405   if (found_something == 0)
9406     return 0;
9407
9408   vec_validate (mask, sizeof (*tcp) - 1);
9409
9410   tcp = (tcp_header_t *) mask;
9411
9412 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9413   foreach_tcp_proto_field;
9414 #undef _
9415
9416   *maskp = mask;
9417   return 1;
9418 }
9419
9420 uword
9421 unformat_udp_mask (unformat_input_t * input, va_list * args)
9422 {
9423   u8 **maskp = va_arg (*args, u8 **);
9424   u8 *mask = 0;
9425   u8 found_something = 0;
9426   udp_header_t *udp;
9427
9428 #define _(a) u8 a=0;
9429   foreach_udp_proto_field;
9430 #undef _
9431
9432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9433     {
9434       if (0);
9435 #define _(a) else if (unformat (input, #a)) a=1;
9436       foreach_udp_proto_field
9437 #undef _
9438         else
9439         break;
9440     }
9441
9442 #define _(a) found_something += a;
9443   foreach_udp_proto_field;
9444 #undef _
9445
9446   if (found_something == 0)
9447     return 0;
9448
9449   vec_validate (mask, sizeof (*udp) - 1);
9450
9451   udp = (udp_header_t *) mask;
9452
9453 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9454   foreach_udp_proto_field;
9455 #undef _
9456
9457   *maskp = mask;
9458   return 1;
9459 }
9460
9461 uword
9462 unformat_l4_mask (unformat_input_t * input, va_list * args)
9463 {
9464   u8 **maskp = va_arg (*args, u8 **);
9465   u16 src_port = 0, dst_port = 0;
9466   tcpudp_header_t *tcpudp;
9467
9468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9469     {
9470       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9471         return 1;
9472       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9473         return 1;
9474       else if (unformat (input, "src_port"))
9475         src_port = 0xFFFF;
9476       else if (unformat (input, "dst_port"))
9477         dst_port = 0xFFFF;
9478       else
9479         return 0;
9480     }
9481
9482   if (!src_port && !dst_port)
9483     return 0;
9484
9485   u8 *mask = 0;
9486   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9487
9488   tcpudp = (tcpudp_header_t *) mask;
9489   tcpudp->src_port = src_port;
9490   tcpudp->dst_port = dst_port;
9491
9492   *maskp = mask;
9493
9494   return 1;
9495 }
9496
9497 uword
9498 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9499 {
9500   u8 **maskp = va_arg (*args, u8 **);
9501   u8 *mask = 0;
9502   u8 found_something = 0;
9503   ip4_header_t *ip;
9504
9505 #define _(a) u8 a=0;
9506   foreach_ip4_proto_field;
9507 #undef _
9508   u8 version = 0;
9509   u8 hdr_length = 0;
9510
9511
9512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9513     {
9514       if (unformat (input, "version"))
9515         version = 1;
9516       else if (unformat (input, "hdr_length"))
9517         hdr_length = 1;
9518       else if (unformat (input, "src"))
9519         src_address = 1;
9520       else if (unformat (input, "dst"))
9521         dst_address = 1;
9522       else if (unformat (input, "proto"))
9523         protocol = 1;
9524
9525 #define _(a) else if (unformat (input, #a)) a=1;
9526       foreach_ip4_proto_field
9527 #undef _
9528         else
9529         break;
9530     }
9531
9532 #define _(a) found_something += a;
9533   foreach_ip4_proto_field;
9534 #undef _
9535
9536   if (found_something == 0)
9537     return 0;
9538
9539   vec_validate (mask, sizeof (*ip) - 1);
9540
9541   ip = (ip4_header_t *) mask;
9542
9543 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9544   foreach_ip4_proto_field;
9545 #undef _
9546
9547   ip->ip_version_and_header_length = 0;
9548
9549   if (version)
9550     ip->ip_version_and_header_length |= 0xF0;
9551
9552   if (hdr_length)
9553     ip->ip_version_and_header_length |= 0x0F;
9554
9555   *maskp = mask;
9556   return 1;
9557 }
9558
9559 #define foreach_ip6_proto_field                 \
9560 _(src_address)                                  \
9561 _(dst_address)                                  \
9562 _(payload_length)                               \
9563 _(hop_limit)                                    \
9564 _(protocol)
9565
9566 uword
9567 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9568 {
9569   u8 **maskp = va_arg (*args, u8 **);
9570   u8 *mask = 0;
9571   u8 found_something = 0;
9572   ip6_header_t *ip;
9573   u32 ip_version_traffic_class_and_flow_label;
9574
9575 #define _(a) u8 a=0;
9576   foreach_ip6_proto_field;
9577 #undef _
9578   u8 version = 0;
9579   u8 traffic_class = 0;
9580   u8 flow_label = 0;
9581
9582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9583     {
9584       if (unformat (input, "version"))
9585         version = 1;
9586       else if (unformat (input, "traffic-class"))
9587         traffic_class = 1;
9588       else if (unformat (input, "flow-label"))
9589         flow_label = 1;
9590       else if (unformat (input, "src"))
9591         src_address = 1;
9592       else if (unformat (input, "dst"))
9593         dst_address = 1;
9594       else if (unformat (input, "proto"))
9595         protocol = 1;
9596
9597 #define _(a) else if (unformat (input, #a)) a=1;
9598       foreach_ip6_proto_field
9599 #undef _
9600         else
9601         break;
9602     }
9603
9604 #define _(a) found_something += a;
9605   foreach_ip6_proto_field;
9606 #undef _
9607
9608   if (found_something == 0)
9609     return 0;
9610
9611   vec_validate (mask, sizeof (*ip) - 1);
9612
9613   ip = (ip6_header_t *) mask;
9614
9615 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9616   foreach_ip6_proto_field;
9617 #undef _
9618
9619   ip_version_traffic_class_and_flow_label = 0;
9620
9621   if (version)
9622     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9623
9624   if (traffic_class)
9625     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9626
9627   if (flow_label)
9628     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9629
9630   ip->ip_version_traffic_class_and_flow_label =
9631     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9632
9633   *maskp = mask;
9634   return 1;
9635 }
9636
9637 uword
9638 unformat_l3_mask (unformat_input_t * input, va_list * args)
9639 {
9640   u8 **maskp = va_arg (*args, u8 **);
9641
9642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9643     {
9644       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9645         return 1;
9646       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9647         return 1;
9648       else
9649         break;
9650     }
9651   return 0;
9652 }
9653
9654 uword
9655 unformat_l2_mask (unformat_input_t * input, va_list * args)
9656 {
9657   u8 **maskp = va_arg (*args, u8 **);
9658   u8 *mask = 0;
9659   u8 src = 0;
9660   u8 dst = 0;
9661   u8 proto = 0;
9662   u8 tag1 = 0;
9663   u8 tag2 = 0;
9664   u8 ignore_tag1 = 0;
9665   u8 ignore_tag2 = 0;
9666   u8 cos1 = 0;
9667   u8 cos2 = 0;
9668   u8 dot1q = 0;
9669   u8 dot1ad = 0;
9670   int len = 14;
9671
9672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9673     {
9674       if (unformat (input, "src"))
9675         src = 1;
9676       else if (unformat (input, "dst"))
9677         dst = 1;
9678       else if (unformat (input, "proto"))
9679         proto = 1;
9680       else if (unformat (input, "tag1"))
9681         tag1 = 1;
9682       else if (unformat (input, "tag2"))
9683         tag2 = 1;
9684       else if (unformat (input, "ignore-tag1"))
9685         ignore_tag1 = 1;
9686       else if (unformat (input, "ignore-tag2"))
9687         ignore_tag2 = 1;
9688       else if (unformat (input, "cos1"))
9689         cos1 = 1;
9690       else if (unformat (input, "cos2"))
9691         cos2 = 1;
9692       else if (unformat (input, "dot1q"))
9693         dot1q = 1;
9694       else if (unformat (input, "dot1ad"))
9695         dot1ad = 1;
9696       else
9697         break;
9698     }
9699   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9700        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9701     return 0;
9702
9703   if (tag1 || ignore_tag1 || cos1 || dot1q)
9704     len = 18;
9705   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9706     len = 22;
9707
9708   vec_validate (mask, len - 1);
9709
9710   if (dst)
9711     memset (mask, 0xff, 6);
9712
9713   if (src)
9714     memset (mask + 6, 0xff, 6);
9715
9716   if (tag2 || dot1ad)
9717     {
9718       /* inner vlan tag */
9719       if (tag2)
9720         {
9721           mask[19] = 0xff;
9722           mask[18] = 0x0f;
9723         }
9724       if (cos2)
9725         mask[18] |= 0xe0;
9726       if (proto)
9727         mask[21] = mask[20] = 0xff;
9728       if (tag1)
9729         {
9730           mask[15] = 0xff;
9731           mask[14] = 0x0f;
9732         }
9733       if (cos1)
9734         mask[14] |= 0xe0;
9735       *maskp = mask;
9736       return 1;
9737     }
9738   if (tag1 | dot1q)
9739     {
9740       if (tag1)
9741         {
9742           mask[15] = 0xff;
9743           mask[14] = 0x0f;
9744         }
9745       if (cos1)
9746         mask[14] |= 0xe0;
9747       if (proto)
9748         mask[16] = mask[17] = 0xff;
9749
9750       *maskp = mask;
9751       return 1;
9752     }
9753   if (cos2)
9754     mask[18] |= 0xe0;
9755   if (cos1)
9756     mask[14] |= 0xe0;
9757   if (proto)
9758     mask[12] = mask[13] = 0xff;
9759
9760   *maskp = mask;
9761   return 1;
9762 }
9763
9764 uword
9765 unformat_classify_mask (unformat_input_t * input, va_list * args)
9766 {
9767   u8 **maskp = va_arg (*args, u8 **);
9768   u32 *skipp = va_arg (*args, u32 *);
9769   u32 *matchp = va_arg (*args, u32 *);
9770   u32 match;
9771   u8 *mask = 0;
9772   u8 *l2 = 0;
9773   u8 *l3 = 0;
9774   u8 *l4 = 0;
9775   int i;
9776
9777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9778     {
9779       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9780         ;
9781       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9782         ;
9783       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9784         ;
9785       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9786         ;
9787       else
9788         break;
9789     }
9790
9791   if (l4 && !l3)
9792     {
9793       vec_free (mask);
9794       vec_free (l2);
9795       vec_free (l4);
9796       return 0;
9797     }
9798
9799   if (mask || l2 || l3 || l4)
9800     {
9801       if (l2 || l3 || l4)
9802         {
9803           /* "With a free Ethernet header in every package" */
9804           if (l2 == 0)
9805             vec_validate (l2, 13);
9806           mask = l2;
9807           if (vec_len (l3))
9808             {
9809               vec_append (mask, l3);
9810               vec_free (l3);
9811             }
9812           if (vec_len (l4))
9813             {
9814               vec_append (mask, l4);
9815               vec_free (l4);
9816             }
9817         }
9818
9819       /* Scan forward looking for the first significant mask octet */
9820       for (i = 0; i < vec_len (mask); i++)
9821         if (mask[i])
9822           break;
9823
9824       /* compute (skip, match) params */
9825       *skipp = i / sizeof (u32x4);
9826       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9827
9828       /* Pad mask to an even multiple of the vector size */
9829       while (vec_len (mask) % sizeof (u32x4))
9830         vec_add1 (mask, 0);
9831
9832       match = vec_len (mask) / sizeof (u32x4);
9833
9834       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9835         {
9836           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9837           if (*tmp || *(tmp + 1))
9838             break;
9839           match--;
9840         }
9841       if (match == 0)
9842         clib_warning ("BUG: match 0");
9843
9844       _vec_len (mask) = match * sizeof (u32x4);
9845
9846       *matchp = match;
9847       *maskp = mask;
9848
9849       return 1;
9850     }
9851
9852   return 0;
9853 }
9854 #endif /* VPP_API_TEST_BUILTIN */
9855
9856 #define foreach_l2_next                         \
9857 _(drop, DROP)                                   \
9858 _(ethernet, ETHERNET_INPUT)                     \
9859 _(ip4, IP4_INPUT)                               \
9860 _(ip6, IP6_INPUT)
9861
9862 uword
9863 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9864 {
9865   u32 *miss_next_indexp = va_arg (*args, u32 *);
9866   u32 next_index = 0;
9867   u32 tmp;
9868
9869 #define _(n,N) \
9870   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9871   foreach_l2_next;
9872 #undef _
9873
9874   if (unformat (input, "%d", &tmp))
9875     {
9876       next_index = tmp;
9877       goto out;
9878     }
9879
9880   return 0;
9881
9882 out:
9883   *miss_next_indexp = next_index;
9884   return 1;
9885 }
9886
9887 #define foreach_ip_next                         \
9888 _(drop, DROP)                                   \
9889 _(local, LOCAL)                                 \
9890 _(rewrite, REWRITE)
9891
9892 uword
9893 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9894 {
9895   u32 *miss_next_indexp = va_arg (*args, u32 *);
9896   u32 next_index = 0;
9897   u32 tmp;
9898
9899 #define _(n,N) \
9900   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9901   foreach_ip_next;
9902 #undef _
9903
9904   if (unformat (input, "%d", &tmp))
9905     {
9906       next_index = tmp;
9907       goto out;
9908     }
9909
9910   return 0;
9911
9912 out:
9913   *miss_next_indexp = next_index;
9914   return 1;
9915 }
9916
9917 #define foreach_acl_next                        \
9918 _(deny, DENY)
9919
9920 uword
9921 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9922 {
9923   u32 *miss_next_indexp = va_arg (*args, u32 *);
9924   u32 next_index = 0;
9925   u32 tmp;
9926
9927 #define _(n,N) \
9928   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9929   foreach_acl_next;
9930 #undef _
9931
9932   if (unformat (input, "permit"))
9933     {
9934       next_index = ~0;
9935       goto out;
9936     }
9937   else if (unformat (input, "%d", &tmp))
9938     {
9939       next_index = tmp;
9940       goto out;
9941     }
9942
9943   return 0;
9944
9945 out:
9946   *miss_next_indexp = next_index;
9947   return 1;
9948 }
9949
9950 uword
9951 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9952 {
9953   u32 *r = va_arg (*args, u32 *);
9954
9955   if (unformat (input, "conform-color"))
9956     *r = POLICE_CONFORM;
9957   else if (unformat (input, "exceed-color"))
9958     *r = POLICE_EXCEED;
9959   else
9960     return 0;
9961
9962   return 1;
9963 }
9964
9965 static int
9966 api_classify_add_del_table (vat_main_t * vam)
9967 {
9968   unformat_input_t *i = vam->input;
9969   vl_api_classify_add_del_table_t *mp;
9970
9971   u32 nbuckets = 2;
9972   u32 skip = ~0;
9973   u32 match = ~0;
9974   int is_add = 1;
9975   int del_chain = 0;
9976   u32 table_index = ~0;
9977   u32 next_table_index = ~0;
9978   u32 miss_next_index = ~0;
9979   u32 memory_size = 32 << 20;
9980   u8 *mask = 0;
9981   u32 current_data_flag = 0;
9982   int current_data_offset = 0;
9983   int ret;
9984
9985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9986     {
9987       if (unformat (i, "del"))
9988         is_add = 0;
9989       else if (unformat (i, "del-chain"))
9990         {
9991           is_add = 0;
9992           del_chain = 1;
9993         }
9994       else if (unformat (i, "buckets %d", &nbuckets))
9995         ;
9996       else if (unformat (i, "memory_size %d", &memory_size))
9997         ;
9998       else if (unformat (i, "skip %d", &skip))
9999         ;
10000       else if (unformat (i, "match %d", &match))
10001         ;
10002       else if (unformat (i, "table %d", &table_index))
10003         ;
10004       else if (unformat (i, "mask %U", unformat_classify_mask,
10005                          &mask, &skip, &match))
10006         ;
10007       else if (unformat (i, "next-table %d", &next_table_index))
10008         ;
10009       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10010                          &miss_next_index))
10011         ;
10012       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10013                          &miss_next_index))
10014         ;
10015       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10016                          &miss_next_index))
10017         ;
10018       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10019         ;
10020       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10021         ;
10022       else
10023         break;
10024     }
10025
10026   if (is_add && mask == 0)
10027     {
10028       errmsg ("Mask required");
10029       return -99;
10030     }
10031
10032   if (is_add && skip == ~0)
10033     {
10034       errmsg ("skip count required");
10035       return -99;
10036     }
10037
10038   if (is_add && match == ~0)
10039     {
10040       errmsg ("match count required");
10041       return -99;
10042     }
10043
10044   if (!is_add && table_index == ~0)
10045     {
10046       errmsg ("table index required for delete");
10047       return -99;
10048     }
10049
10050   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10051
10052   mp->is_add = is_add;
10053   mp->del_chain = del_chain;
10054   mp->table_index = ntohl (table_index);
10055   mp->nbuckets = ntohl (nbuckets);
10056   mp->memory_size = ntohl (memory_size);
10057   mp->skip_n_vectors = ntohl (skip);
10058   mp->match_n_vectors = ntohl (match);
10059   mp->next_table_index = ntohl (next_table_index);
10060   mp->miss_next_index = ntohl (miss_next_index);
10061   mp->current_data_flag = ntohl (current_data_flag);
10062   mp->current_data_offset = ntohl (current_data_offset);
10063   clib_memcpy (mp->mask, mask, vec_len (mask));
10064
10065   vec_free (mask);
10066
10067   S (mp);
10068   W (ret);
10069   return ret;
10070 }
10071
10072 #if VPP_API_TEST_BUILTIN == 0
10073 uword
10074 unformat_l4_match (unformat_input_t * input, va_list * args)
10075 {
10076   u8 **matchp = va_arg (*args, u8 **);
10077
10078   u8 *proto_header = 0;
10079   int src_port = 0;
10080   int dst_port = 0;
10081
10082   tcpudp_header_t h;
10083
10084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10085     {
10086       if (unformat (input, "src_port %d", &src_port))
10087         ;
10088       else if (unformat (input, "dst_port %d", &dst_port))
10089         ;
10090       else
10091         return 0;
10092     }
10093
10094   h.src_port = clib_host_to_net_u16 (src_port);
10095   h.dst_port = clib_host_to_net_u16 (dst_port);
10096   vec_validate (proto_header, sizeof (h) - 1);
10097   memcpy (proto_header, &h, sizeof (h));
10098
10099   *matchp = proto_header;
10100
10101   return 1;
10102 }
10103
10104 uword
10105 unformat_ip4_match (unformat_input_t * input, va_list * args)
10106 {
10107   u8 **matchp = va_arg (*args, u8 **);
10108   u8 *match = 0;
10109   ip4_header_t *ip;
10110   int version = 0;
10111   u32 version_val;
10112   int hdr_length = 0;
10113   u32 hdr_length_val;
10114   int src = 0, dst = 0;
10115   ip4_address_t src_val, dst_val;
10116   int proto = 0;
10117   u32 proto_val;
10118   int tos = 0;
10119   u32 tos_val;
10120   int length = 0;
10121   u32 length_val;
10122   int fragment_id = 0;
10123   u32 fragment_id_val;
10124   int ttl = 0;
10125   int ttl_val;
10126   int checksum = 0;
10127   u32 checksum_val;
10128
10129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10130     {
10131       if (unformat (input, "version %d", &version_val))
10132         version = 1;
10133       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10134         hdr_length = 1;
10135       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10136         src = 1;
10137       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10138         dst = 1;
10139       else if (unformat (input, "proto %d", &proto_val))
10140         proto = 1;
10141       else if (unformat (input, "tos %d", &tos_val))
10142         tos = 1;
10143       else if (unformat (input, "length %d", &length_val))
10144         length = 1;
10145       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10146         fragment_id = 1;
10147       else if (unformat (input, "ttl %d", &ttl_val))
10148         ttl = 1;
10149       else if (unformat (input, "checksum %d", &checksum_val))
10150         checksum = 1;
10151       else
10152         break;
10153     }
10154
10155   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10156       + ttl + checksum == 0)
10157     return 0;
10158
10159   /*
10160    * Aligned because we use the real comparison functions
10161    */
10162   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10163
10164   ip = (ip4_header_t *) match;
10165
10166   /* These are realistically matched in practice */
10167   if (src)
10168     ip->src_address.as_u32 = src_val.as_u32;
10169
10170   if (dst)
10171     ip->dst_address.as_u32 = dst_val.as_u32;
10172
10173   if (proto)
10174     ip->protocol = proto_val;
10175
10176
10177   /* These are not, but they're included for completeness */
10178   if (version)
10179     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10180
10181   if (hdr_length)
10182     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10183
10184   if (tos)
10185     ip->tos = tos_val;
10186
10187   if (length)
10188     ip->length = clib_host_to_net_u16 (length_val);
10189
10190   if (ttl)
10191     ip->ttl = ttl_val;
10192
10193   if (checksum)
10194     ip->checksum = clib_host_to_net_u16 (checksum_val);
10195
10196   *matchp = match;
10197   return 1;
10198 }
10199
10200 uword
10201 unformat_ip6_match (unformat_input_t * input, va_list * args)
10202 {
10203   u8 **matchp = va_arg (*args, u8 **);
10204   u8 *match = 0;
10205   ip6_header_t *ip;
10206   int version = 0;
10207   u32 version_val;
10208   u8 traffic_class = 0;
10209   u32 traffic_class_val = 0;
10210   u8 flow_label = 0;
10211   u8 flow_label_val;
10212   int src = 0, dst = 0;
10213   ip6_address_t src_val, dst_val;
10214   int proto = 0;
10215   u32 proto_val;
10216   int payload_length = 0;
10217   u32 payload_length_val;
10218   int hop_limit = 0;
10219   int hop_limit_val;
10220   u32 ip_version_traffic_class_and_flow_label;
10221
10222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10223     {
10224       if (unformat (input, "version %d", &version_val))
10225         version = 1;
10226       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10227         traffic_class = 1;
10228       else if (unformat (input, "flow_label %d", &flow_label_val))
10229         flow_label = 1;
10230       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10231         src = 1;
10232       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10233         dst = 1;
10234       else if (unformat (input, "proto %d", &proto_val))
10235         proto = 1;
10236       else if (unformat (input, "payload_length %d", &payload_length_val))
10237         payload_length = 1;
10238       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10239         hop_limit = 1;
10240       else
10241         break;
10242     }
10243
10244   if (version + traffic_class + flow_label + src + dst + proto +
10245       payload_length + hop_limit == 0)
10246     return 0;
10247
10248   /*
10249    * Aligned because we use the real comparison functions
10250    */
10251   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10252
10253   ip = (ip6_header_t *) match;
10254
10255   if (src)
10256     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10257
10258   if (dst)
10259     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10260
10261   if (proto)
10262     ip->protocol = proto_val;
10263
10264   ip_version_traffic_class_and_flow_label = 0;
10265
10266   if (version)
10267     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10268
10269   if (traffic_class)
10270     ip_version_traffic_class_and_flow_label |=
10271       (traffic_class_val & 0xFF) << 20;
10272
10273   if (flow_label)
10274     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10275
10276   ip->ip_version_traffic_class_and_flow_label =
10277     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10278
10279   if (payload_length)
10280     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10281
10282   if (hop_limit)
10283     ip->hop_limit = hop_limit_val;
10284
10285   *matchp = match;
10286   return 1;
10287 }
10288
10289 uword
10290 unformat_l3_match (unformat_input_t * input, va_list * args)
10291 {
10292   u8 **matchp = va_arg (*args, u8 **);
10293
10294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10295     {
10296       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10297         return 1;
10298       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10299         return 1;
10300       else
10301         break;
10302     }
10303   return 0;
10304 }
10305
10306 uword
10307 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10308 {
10309   u8 *tagp = va_arg (*args, u8 *);
10310   u32 tag;
10311
10312   if (unformat (input, "%d", &tag))
10313     {
10314       tagp[0] = (tag >> 8) & 0x0F;
10315       tagp[1] = tag & 0xFF;
10316       return 1;
10317     }
10318
10319   return 0;
10320 }
10321
10322 uword
10323 unformat_l2_match (unformat_input_t * input, va_list * args)
10324 {
10325   u8 **matchp = va_arg (*args, u8 **);
10326   u8 *match = 0;
10327   u8 src = 0;
10328   u8 src_val[6];
10329   u8 dst = 0;
10330   u8 dst_val[6];
10331   u8 proto = 0;
10332   u16 proto_val;
10333   u8 tag1 = 0;
10334   u8 tag1_val[2];
10335   u8 tag2 = 0;
10336   u8 tag2_val[2];
10337   int len = 14;
10338   u8 ignore_tag1 = 0;
10339   u8 ignore_tag2 = 0;
10340   u8 cos1 = 0;
10341   u8 cos2 = 0;
10342   u32 cos1_val = 0;
10343   u32 cos2_val = 0;
10344
10345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10346     {
10347       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10348         src = 1;
10349       else
10350         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10351         dst = 1;
10352       else if (unformat (input, "proto %U",
10353                          unformat_ethernet_type_host_byte_order, &proto_val))
10354         proto = 1;
10355       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10356         tag1 = 1;
10357       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10358         tag2 = 1;
10359       else if (unformat (input, "ignore-tag1"))
10360         ignore_tag1 = 1;
10361       else if (unformat (input, "ignore-tag2"))
10362         ignore_tag2 = 1;
10363       else if (unformat (input, "cos1 %d", &cos1_val))
10364         cos1 = 1;
10365       else if (unformat (input, "cos2 %d", &cos2_val))
10366         cos2 = 1;
10367       else
10368         break;
10369     }
10370   if ((src + dst + proto + tag1 + tag2 +
10371        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10372     return 0;
10373
10374   if (tag1 || ignore_tag1 || cos1)
10375     len = 18;
10376   if (tag2 || ignore_tag2 || cos2)
10377     len = 22;
10378
10379   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10380
10381   if (dst)
10382     clib_memcpy (match, dst_val, 6);
10383
10384   if (src)
10385     clib_memcpy (match + 6, src_val, 6);
10386
10387   if (tag2)
10388     {
10389       /* inner vlan tag */
10390       match[19] = tag2_val[1];
10391       match[18] = tag2_val[0];
10392       if (cos2)
10393         match[18] |= (cos2_val & 0x7) << 5;
10394       if (proto)
10395         {
10396           match[21] = proto_val & 0xff;
10397           match[20] = proto_val >> 8;
10398         }
10399       if (tag1)
10400         {
10401           match[15] = tag1_val[1];
10402           match[14] = tag1_val[0];
10403         }
10404       if (cos1)
10405         match[14] |= (cos1_val & 0x7) << 5;
10406       *matchp = match;
10407       return 1;
10408     }
10409   if (tag1)
10410     {
10411       match[15] = tag1_val[1];
10412       match[14] = tag1_val[0];
10413       if (proto)
10414         {
10415           match[17] = proto_val & 0xff;
10416           match[16] = proto_val >> 8;
10417         }
10418       if (cos1)
10419         match[14] |= (cos1_val & 0x7) << 5;
10420
10421       *matchp = match;
10422       return 1;
10423     }
10424   if (cos2)
10425     match[18] |= (cos2_val & 0x7) << 5;
10426   if (cos1)
10427     match[14] |= (cos1_val & 0x7) << 5;
10428   if (proto)
10429     {
10430       match[13] = proto_val & 0xff;
10431       match[12] = proto_val >> 8;
10432     }
10433
10434   *matchp = match;
10435   return 1;
10436 }
10437 #endif
10438
10439 uword
10440 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10441 {
10442   u8 **matchp = va_arg (*args, u8 **);
10443   u32 skip_n_vectors = va_arg (*args, u32);
10444   u32 match_n_vectors = va_arg (*args, u32);
10445
10446   u8 *match = 0;
10447   u8 *l2 = 0;
10448   u8 *l3 = 0;
10449   u8 *l4 = 0;
10450
10451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10452     {
10453       if (unformat (input, "hex %U", unformat_hex_string, &match))
10454         ;
10455       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10456         ;
10457       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10458         ;
10459       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10460         ;
10461       else
10462         break;
10463     }
10464
10465   if (l4 && !l3)
10466     {
10467       vec_free (match);
10468       vec_free (l2);
10469       vec_free (l4);
10470       return 0;
10471     }
10472
10473   if (match || l2 || l3 || l4)
10474     {
10475       if (l2 || l3 || l4)
10476         {
10477           /* "Win a free Ethernet header in every packet" */
10478           if (l2 == 0)
10479             vec_validate_aligned (l2, 13, sizeof (u32x4));
10480           match = l2;
10481           if (vec_len (l3))
10482             {
10483               vec_append_aligned (match, l3, sizeof (u32x4));
10484               vec_free (l3);
10485             }
10486           if (vec_len (l4))
10487             {
10488               vec_append_aligned (match, l4, sizeof (u32x4));
10489               vec_free (l4);
10490             }
10491         }
10492
10493       /* Make sure the vector is big enough even if key is all 0's */
10494       vec_validate_aligned
10495         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10496          sizeof (u32x4));
10497
10498       /* Set size, include skipped vectors */
10499       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10500
10501       *matchp = match;
10502
10503       return 1;
10504     }
10505
10506   return 0;
10507 }
10508
10509 static int
10510 api_classify_add_del_session (vat_main_t * vam)
10511 {
10512   unformat_input_t *i = vam->input;
10513   vl_api_classify_add_del_session_t *mp;
10514   int is_add = 1;
10515   u32 table_index = ~0;
10516   u32 hit_next_index = ~0;
10517   u32 opaque_index = ~0;
10518   u8 *match = 0;
10519   i32 advance = 0;
10520   u32 skip_n_vectors = 0;
10521   u32 match_n_vectors = 0;
10522   u32 action = 0;
10523   u32 metadata = 0;
10524   int ret;
10525
10526   /*
10527    * Warning: you have to supply skip_n and match_n
10528    * because the API client cant simply look at the classify
10529    * table object.
10530    */
10531
10532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10533     {
10534       if (unformat (i, "del"))
10535         is_add = 0;
10536       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10537                          &hit_next_index))
10538         ;
10539       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10540                          &hit_next_index))
10541         ;
10542       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10543                          &hit_next_index))
10544         ;
10545       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10546         ;
10547       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10548         ;
10549       else if (unformat (i, "opaque-index %d", &opaque_index))
10550         ;
10551       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10552         ;
10553       else if (unformat (i, "match_n %d", &match_n_vectors))
10554         ;
10555       else if (unformat (i, "match %U", api_unformat_classify_match,
10556                          &match, skip_n_vectors, match_n_vectors))
10557         ;
10558       else if (unformat (i, "advance %d", &advance))
10559         ;
10560       else if (unformat (i, "table-index %d", &table_index))
10561         ;
10562       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10563         action = 1;
10564       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10565         action = 2;
10566       else if (unformat (i, "action %d", &action))
10567         ;
10568       else if (unformat (i, "metadata %d", &metadata))
10569         ;
10570       else
10571         break;
10572     }
10573
10574   if (table_index == ~0)
10575     {
10576       errmsg ("Table index required");
10577       return -99;
10578     }
10579
10580   if (is_add && match == 0)
10581     {
10582       errmsg ("Match value required");
10583       return -99;
10584     }
10585
10586   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10587
10588   mp->is_add = is_add;
10589   mp->table_index = ntohl (table_index);
10590   mp->hit_next_index = ntohl (hit_next_index);
10591   mp->opaque_index = ntohl (opaque_index);
10592   mp->advance = ntohl (advance);
10593   mp->action = action;
10594   mp->metadata = ntohl (metadata);
10595   clib_memcpy (mp->match, match, vec_len (match));
10596   vec_free (match);
10597
10598   S (mp);
10599   W (ret);
10600   return ret;
10601 }
10602
10603 static int
10604 api_classify_set_interface_ip_table (vat_main_t * vam)
10605 {
10606   unformat_input_t *i = vam->input;
10607   vl_api_classify_set_interface_ip_table_t *mp;
10608   u32 sw_if_index;
10609   int sw_if_index_set;
10610   u32 table_index = ~0;
10611   u8 is_ipv6 = 0;
10612   int ret;
10613
10614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10615     {
10616       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10617         sw_if_index_set = 1;
10618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10619         sw_if_index_set = 1;
10620       else if (unformat (i, "table %d", &table_index))
10621         ;
10622       else
10623         {
10624           clib_warning ("parse error '%U'", format_unformat_error, i);
10625           return -99;
10626         }
10627     }
10628
10629   if (sw_if_index_set == 0)
10630     {
10631       errmsg ("missing interface name or sw_if_index");
10632       return -99;
10633     }
10634
10635
10636   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10637
10638   mp->sw_if_index = ntohl (sw_if_index);
10639   mp->table_index = ntohl (table_index);
10640   mp->is_ipv6 = is_ipv6;
10641
10642   S (mp);
10643   W (ret);
10644   return ret;
10645 }
10646
10647 static int
10648 api_classify_set_interface_l2_tables (vat_main_t * vam)
10649 {
10650   unformat_input_t *i = vam->input;
10651   vl_api_classify_set_interface_l2_tables_t *mp;
10652   u32 sw_if_index;
10653   int sw_if_index_set;
10654   u32 ip4_table_index = ~0;
10655   u32 ip6_table_index = ~0;
10656   u32 other_table_index = ~0;
10657   u32 is_input = 1;
10658   int ret;
10659
10660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10661     {
10662       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10663         sw_if_index_set = 1;
10664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10665         sw_if_index_set = 1;
10666       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10667         ;
10668       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10669         ;
10670       else if (unformat (i, "other-table %d", &other_table_index))
10671         ;
10672       else if (unformat (i, "is-input %d", &is_input))
10673         ;
10674       else
10675         {
10676           clib_warning ("parse error '%U'", format_unformat_error, i);
10677           return -99;
10678         }
10679     }
10680
10681   if (sw_if_index_set == 0)
10682     {
10683       errmsg ("missing interface name or sw_if_index");
10684       return -99;
10685     }
10686
10687
10688   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10689
10690   mp->sw_if_index = ntohl (sw_if_index);
10691   mp->ip4_table_index = ntohl (ip4_table_index);
10692   mp->ip6_table_index = ntohl (ip6_table_index);
10693   mp->other_table_index = ntohl (other_table_index);
10694   mp->is_input = (u8) is_input;
10695
10696   S (mp);
10697   W (ret);
10698   return ret;
10699 }
10700
10701 static int
10702 api_set_ipfix_exporter (vat_main_t * vam)
10703 {
10704   unformat_input_t *i = vam->input;
10705   vl_api_set_ipfix_exporter_t *mp;
10706   ip4_address_t collector_address;
10707   u8 collector_address_set = 0;
10708   u32 collector_port = ~0;
10709   ip4_address_t src_address;
10710   u8 src_address_set = 0;
10711   u32 vrf_id = ~0;
10712   u32 path_mtu = ~0;
10713   u32 template_interval = ~0;
10714   u8 udp_checksum = 0;
10715   int ret;
10716
10717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10718     {
10719       if (unformat (i, "collector_address %U", unformat_ip4_address,
10720                     &collector_address))
10721         collector_address_set = 1;
10722       else if (unformat (i, "collector_port %d", &collector_port))
10723         ;
10724       else if (unformat (i, "src_address %U", unformat_ip4_address,
10725                          &src_address))
10726         src_address_set = 1;
10727       else if (unformat (i, "vrf_id %d", &vrf_id))
10728         ;
10729       else if (unformat (i, "path_mtu %d", &path_mtu))
10730         ;
10731       else if (unformat (i, "template_interval %d", &template_interval))
10732         ;
10733       else if (unformat (i, "udp_checksum"))
10734         udp_checksum = 1;
10735       else
10736         break;
10737     }
10738
10739   if (collector_address_set == 0)
10740     {
10741       errmsg ("collector_address required");
10742       return -99;
10743     }
10744
10745   if (src_address_set == 0)
10746     {
10747       errmsg ("src_address required");
10748       return -99;
10749     }
10750
10751   M (SET_IPFIX_EXPORTER, mp);
10752
10753   memcpy (mp->collector_address, collector_address.data,
10754           sizeof (collector_address.data));
10755   mp->collector_port = htons ((u16) collector_port);
10756   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10757   mp->vrf_id = htonl (vrf_id);
10758   mp->path_mtu = htonl (path_mtu);
10759   mp->template_interval = htonl (template_interval);
10760   mp->udp_checksum = udp_checksum;
10761
10762   S (mp);
10763   W (ret);
10764   return ret;
10765 }
10766
10767 static int
10768 api_set_ipfix_classify_stream (vat_main_t * vam)
10769 {
10770   unformat_input_t *i = vam->input;
10771   vl_api_set_ipfix_classify_stream_t *mp;
10772   u32 domain_id = 0;
10773   u32 src_port = UDP_DST_PORT_ipfix;
10774   int ret;
10775
10776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10777     {
10778       if (unformat (i, "domain %d", &domain_id))
10779         ;
10780       else if (unformat (i, "src_port %d", &src_port))
10781         ;
10782       else
10783         {
10784           errmsg ("unknown input `%U'", format_unformat_error, i);
10785           return -99;
10786         }
10787     }
10788
10789   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10790
10791   mp->domain_id = htonl (domain_id);
10792   mp->src_port = htons ((u16) src_port);
10793
10794   S (mp);
10795   W (ret);
10796   return ret;
10797 }
10798
10799 static int
10800 api_ipfix_classify_table_add_del (vat_main_t * vam)
10801 {
10802   unformat_input_t *i = vam->input;
10803   vl_api_ipfix_classify_table_add_del_t *mp;
10804   int is_add = -1;
10805   u32 classify_table_index = ~0;
10806   u8 ip_version = 0;
10807   u8 transport_protocol = 255;
10808   int ret;
10809
10810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10811     {
10812       if (unformat (i, "add"))
10813         is_add = 1;
10814       else if (unformat (i, "del"))
10815         is_add = 0;
10816       else if (unformat (i, "table %d", &classify_table_index))
10817         ;
10818       else if (unformat (i, "ip4"))
10819         ip_version = 4;
10820       else if (unformat (i, "ip6"))
10821         ip_version = 6;
10822       else if (unformat (i, "tcp"))
10823         transport_protocol = 6;
10824       else if (unformat (i, "udp"))
10825         transport_protocol = 17;
10826       else
10827         {
10828           errmsg ("unknown input `%U'", format_unformat_error, i);
10829           return -99;
10830         }
10831     }
10832
10833   if (is_add == -1)
10834     {
10835       errmsg ("expecting: add|del");
10836       return -99;
10837     }
10838   if (classify_table_index == ~0)
10839     {
10840       errmsg ("classifier table not specified");
10841       return -99;
10842     }
10843   if (ip_version == 0)
10844     {
10845       errmsg ("IP version not specified");
10846       return -99;
10847     }
10848
10849   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10850
10851   mp->is_add = is_add;
10852   mp->table_id = htonl (classify_table_index);
10853   mp->ip_version = ip_version;
10854   mp->transport_protocol = transport_protocol;
10855
10856   S (mp);
10857   W (ret);
10858   return ret;
10859 }
10860
10861 static int
10862 api_get_node_index (vat_main_t * vam)
10863 {
10864   unformat_input_t *i = vam->input;
10865   vl_api_get_node_index_t *mp;
10866   u8 *name = 0;
10867   int ret;
10868
10869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10870     {
10871       if (unformat (i, "node %s", &name))
10872         ;
10873       else
10874         break;
10875     }
10876   if (name == 0)
10877     {
10878       errmsg ("node name required");
10879       return -99;
10880     }
10881   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10882     {
10883       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10884       return -99;
10885     }
10886
10887   M (GET_NODE_INDEX, mp);
10888   clib_memcpy (mp->node_name, name, vec_len (name));
10889   vec_free (name);
10890
10891   S (mp);
10892   W (ret);
10893   return ret;
10894 }
10895
10896 static int
10897 api_get_next_index (vat_main_t * vam)
10898 {
10899   unformat_input_t *i = vam->input;
10900   vl_api_get_next_index_t *mp;
10901   u8 *node_name = 0, *next_node_name = 0;
10902   int ret;
10903
10904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10905     {
10906       if (unformat (i, "node-name %s", &node_name))
10907         ;
10908       else if (unformat (i, "next-node-name %s", &next_node_name))
10909         break;
10910     }
10911
10912   if (node_name == 0)
10913     {
10914       errmsg ("node name required");
10915       return -99;
10916     }
10917   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10918     {
10919       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10920       return -99;
10921     }
10922
10923   if (next_node_name == 0)
10924     {
10925       errmsg ("next node name required");
10926       return -99;
10927     }
10928   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10929     {
10930       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10931       return -99;
10932     }
10933
10934   M (GET_NEXT_INDEX, mp);
10935   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10936   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10937   vec_free (node_name);
10938   vec_free (next_node_name);
10939
10940   S (mp);
10941   W (ret);
10942   return ret;
10943 }
10944
10945 static int
10946 api_add_node_next (vat_main_t * vam)
10947 {
10948   unformat_input_t *i = vam->input;
10949   vl_api_add_node_next_t *mp;
10950   u8 *name = 0;
10951   u8 *next = 0;
10952   int ret;
10953
10954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10955     {
10956       if (unformat (i, "node %s", &name))
10957         ;
10958       else if (unformat (i, "next %s", &next))
10959         ;
10960       else
10961         break;
10962     }
10963   if (name == 0)
10964     {
10965       errmsg ("node name required");
10966       return -99;
10967     }
10968   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10969     {
10970       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10971       return -99;
10972     }
10973   if (next == 0)
10974     {
10975       errmsg ("next node required");
10976       return -99;
10977     }
10978   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10979     {
10980       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10981       return -99;
10982     }
10983
10984   M (ADD_NODE_NEXT, mp);
10985   clib_memcpy (mp->node_name, name, vec_len (name));
10986   clib_memcpy (mp->next_name, next, vec_len (next));
10987   vec_free (name);
10988   vec_free (next);
10989
10990   S (mp);
10991   W (ret);
10992   return ret;
10993 }
10994
10995 static int
10996 api_l2tpv3_create_tunnel (vat_main_t * vam)
10997 {
10998   unformat_input_t *i = vam->input;
10999   ip6_address_t client_address, our_address;
11000   int client_address_set = 0;
11001   int our_address_set = 0;
11002   u32 local_session_id = 0;
11003   u32 remote_session_id = 0;
11004   u64 local_cookie = 0;
11005   u64 remote_cookie = 0;
11006   u8 l2_sublayer_present = 0;
11007   vl_api_l2tpv3_create_tunnel_t *mp;
11008   int ret;
11009
11010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11011     {
11012       if (unformat (i, "client_address %U", unformat_ip6_address,
11013                     &client_address))
11014         client_address_set = 1;
11015       else if (unformat (i, "our_address %U", unformat_ip6_address,
11016                          &our_address))
11017         our_address_set = 1;
11018       else if (unformat (i, "local_session_id %d", &local_session_id))
11019         ;
11020       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11021         ;
11022       else if (unformat (i, "local_cookie %lld", &local_cookie))
11023         ;
11024       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11025         ;
11026       else if (unformat (i, "l2-sublayer-present"))
11027         l2_sublayer_present = 1;
11028       else
11029         break;
11030     }
11031
11032   if (client_address_set == 0)
11033     {
11034       errmsg ("client_address required");
11035       return -99;
11036     }
11037
11038   if (our_address_set == 0)
11039     {
11040       errmsg ("our_address required");
11041       return -99;
11042     }
11043
11044   M (L2TPV3_CREATE_TUNNEL, mp);
11045
11046   clib_memcpy (mp->client_address, client_address.as_u8,
11047                sizeof (mp->client_address));
11048
11049   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11050
11051   mp->local_session_id = ntohl (local_session_id);
11052   mp->remote_session_id = ntohl (remote_session_id);
11053   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11054   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11055   mp->l2_sublayer_present = l2_sublayer_present;
11056   mp->is_ipv6 = 1;
11057
11058   S (mp);
11059   W (ret);
11060   return ret;
11061 }
11062
11063 static int
11064 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11065 {
11066   unformat_input_t *i = vam->input;
11067   u32 sw_if_index;
11068   u8 sw_if_index_set = 0;
11069   u64 new_local_cookie = 0;
11070   u64 new_remote_cookie = 0;
11071   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11072   int ret;
11073
11074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11075     {
11076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11077         sw_if_index_set = 1;
11078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11079         sw_if_index_set = 1;
11080       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11081         ;
11082       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11083         ;
11084       else
11085         break;
11086     }
11087
11088   if (sw_if_index_set == 0)
11089     {
11090       errmsg ("missing interface name or sw_if_index");
11091       return -99;
11092     }
11093
11094   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11095
11096   mp->sw_if_index = ntohl (sw_if_index);
11097   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11098   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11099
11100   S (mp);
11101   W (ret);
11102   return ret;
11103 }
11104
11105 static int
11106 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11107 {
11108   unformat_input_t *i = vam->input;
11109   vl_api_l2tpv3_interface_enable_disable_t *mp;
11110   u32 sw_if_index;
11111   u8 sw_if_index_set = 0;
11112   u8 enable_disable = 1;
11113   int ret;
11114
11115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11116     {
11117       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11118         sw_if_index_set = 1;
11119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11120         sw_if_index_set = 1;
11121       else if (unformat (i, "enable"))
11122         enable_disable = 1;
11123       else if (unformat (i, "disable"))
11124         enable_disable = 0;
11125       else
11126         break;
11127     }
11128
11129   if (sw_if_index_set == 0)
11130     {
11131       errmsg ("missing interface name or sw_if_index");
11132       return -99;
11133     }
11134
11135   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11136
11137   mp->sw_if_index = ntohl (sw_if_index);
11138   mp->enable_disable = enable_disable;
11139
11140   S (mp);
11141   W (ret);
11142   return ret;
11143 }
11144
11145 static int
11146 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11147 {
11148   unformat_input_t *i = vam->input;
11149   vl_api_l2tpv3_set_lookup_key_t *mp;
11150   u8 key = ~0;
11151   int ret;
11152
11153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11154     {
11155       if (unformat (i, "lookup_v6_src"))
11156         key = L2T_LOOKUP_SRC_ADDRESS;
11157       else if (unformat (i, "lookup_v6_dst"))
11158         key = L2T_LOOKUP_DST_ADDRESS;
11159       else if (unformat (i, "lookup_session_id"))
11160         key = L2T_LOOKUP_SESSION_ID;
11161       else
11162         break;
11163     }
11164
11165   if (key == (u8) ~ 0)
11166     {
11167       errmsg ("l2tp session lookup key unset");
11168       return -99;
11169     }
11170
11171   M (L2TPV3_SET_LOOKUP_KEY, mp);
11172
11173   mp->key = key;
11174
11175   S (mp);
11176   W (ret);
11177   return ret;
11178 }
11179
11180 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11181   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11182 {
11183   vat_main_t *vam = &vat_main;
11184
11185   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11186          format_ip6_address, mp->our_address,
11187          format_ip6_address, mp->client_address,
11188          clib_net_to_host_u32 (mp->sw_if_index));
11189
11190   print (vam->ofp,
11191          "   local cookies %016llx %016llx remote cookie %016llx",
11192          clib_net_to_host_u64 (mp->local_cookie[0]),
11193          clib_net_to_host_u64 (mp->local_cookie[1]),
11194          clib_net_to_host_u64 (mp->remote_cookie));
11195
11196   print (vam->ofp, "   local session-id %d remote session-id %d",
11197          clib_net_to_host_u32 (mp->local_session_id),
11198          clib_net_to_host_u32 (mp->remote_session_id));
11199
11200   print (vam->ofp, "   l2 specific sublayer %s\n",
11201          mp->l2_sublayer_present ? "preset" : "absent");
11202
11203 }
11204
11205 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11206   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11207 {
11208   vat_main_t *vam = &vat_main;
11209   vat_json_node_t *node = NULL;
11210   struct in6_addr addr;
11211
11212   if (VAT_JSON_ARRAY != vam->json_tree.type)
11213     {
11214       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11215       vat_json_init_array (&vam->json_tree);
11216     }
11217   node = vat_json_array_add (&vam->json_tree);
11218
11219   vat_json_init_object (node);
11220
11221   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11222   vat_json_object_add_ip6 (node, "our_address", addr);
11223   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11224   vat_json_object_add_ip6 (node, "client_address", addr);
11225
11226   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11227   vat_json_init_array (lc);
11228   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11229   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11230   vat_json_object_add_uint (node, "remote_cookie",
11231                             clib_net_to_host_u64 (mp->remote_cookie));
11232
11233   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11234   vat_json_object_add_uint (node, "local_session_id",
11235                             clib_net_to_host_u32 (mp->local_session_id));
11236   vat_json_object_add_uint (node, "remote_session_id",
11237                             clib_net_to_host_u32 (mp->remote_session_id));
11238   vat_json_object_add_string_copy (node, "l2_sublayer",
11239                                    mp->l2_sublayer_present ? (u8 *) "present"
11240                                    : (u8 *) "absent");
11241 }
11242
11243 static int
11244 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11245 {
11246   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11247   vl_api_control_ping_t *mp_ping;
11248   int ret;
11249
11250   /* Get list of l2tpv3-tunnel interfaces */
11251   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11252   S (mp);
11253
11254   /* Use a control ping for synchronization */
11255   M (CONTROL_PING, mp_ping);
11256   S (mp_ping);
11257
11258   W (ret);
11259   return ret;
11260 }
11261
11262
11263 static void vl_api_sw_interface_tap_details_t_handler
11264   (vl_api_sw_interface_tap_details_t * mp)
11265 {
11266   vat_main_t *vam = &vat_main;
11267
11268   print (vam->ofp, "%-16s %d",
11269          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11270 }
11271
11272 static void vl_api_sw_interface_tap_details_t_handler_json
11273   (vl_api_sw_interface_tap_details_t * mp)
11274 {
11275   vat_main_t *vam = &vat_main;
11276   vat_json_node_t *node = NULL;
11277
11278   if (VAT_JSON_ARRAY != vam->json_tree.type)
11279     {
11280       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11281       vat_json_init_array (&vam->json_tree);
11282     }
11283   node = vat_json_array_add (&vam->json_tree);
11284
11285   vat_json_init_object (node);
11286   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11287   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11288 }
11289
11290 static int
11291 api_sw_interface_tap_dump (vat_main_t * vam)
11292 {
11293   vl_api_sw_interface_tap_dump_t *mp;
11294   vl_api_control_ping_t *mp_ping;
11295   int ret;
11296
11297   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11298   /* Get list of tap interfaces */
11299   M (SW_INTERFACE_TAP_DUMP, mp);
11300   S (mp);
11301
11302   /* Use a control ping for synchronization */
11303   M (CONTROL_PING, mp_ping);
11304   S (mp_ping);
11305
11306   W (ret);
11307   return ret;
11308 }
11309
11310 static uword unformat_vxlan_decap_next
11311   (unformat_input_t * input, va_list * args)
11312 {
11313   u32 *result = va_arg (*args, u32 *);
11314   u32 tmp;
11315
11316   if (unformat (input, "l2"))
11317     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11318   else if (unformat (input, "%d", &tmp))
11319     *result = tmp;
11320   else
11321     return 0;
11322   return 1;
11323 }
11324
11325 static int
11326 api_vxlan_add_del_tunnel (vat_main_t * vam)
11327 {
11328   unformat_input_t *line_input = vam->input;
11329   vl_api_vxlan_add_del_tunnel_t *mp;
11330   ip46_address_t src, dst;
11331   u8 is_add = 1;
11332   u8 ipv4_set = 0, ipv6_set = 0;
11333   u8 src_set = 0;
11334   u8 dst_set = 0;
11335   u8 grp_set = 0;
11336   u32 mcast_sw_if_index = ~0;
11337   u32 encap_vrf_id = 0;
11338   u32 decap_next_index = ~0;
11339   u32 vni = 0;
11340   int ret;
11341
11342   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11343   memset (&src, 0, sizeof src);
11344   memset (&dst, 0, sizeof dst);
11345
11346   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11347     {
11348       if (unformat (line_input, "del"))
11349         is_add = 0;
11350       else
11351         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11352         {
11353           ipv4_set = 1;
11354           src_set = 1;
11355         }
11356       else
11357         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11358         {
11359           ipv4_set = 1;
11360           dst_set = 1;
11361         }
11362       else
11363         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11364         {
11365           ipv6_set = 1;
11366           src_set = 1;
11367         }
11368       else
11369         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11370         {
11371           ipv6_set = 1;
11372           dst_set = 1;
11373         }
11374       else if (unformat (line_input, "group %U %U",
11375                          unformat_ip4_address, &dst.ip4,
11376                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11377         {
11378           grp_set = dst_set = 1;
11379           ipv4_set = 1;
11380         }
11381       else if (unformat (line_input, "group %U",
11382                          unformat_ip4_address, &dst.ip4))
11383         {
11384           grp_set = dst_set = 1;
11385           ipv4_set = 1;
11386         }
11387       else if (unformat (line_input, "group %U %U",
11388                          unformat_ip6_address, &dst.ip6,
11389                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11390         {
11391           grp_set = dst_set = 1;
11392           ipv6_set = 1;
11393         }
11394       else if (unformat (line_input, "group %U",
11395                          unformat_ip6_address, &dst.ip6))
11396         {
11397           grp_set = dst_set = 1;
11398           ipv6_set = 1;
11399         }
11400       else
11401         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11402         ;
11403       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11404         ;
11405       else if (unformat (line_input, "decap-next %U",
11406                          unformat_vxlan_decap_next, &decap_next_index))
11407         ;
11408       else if (unformat (line_input, "vni %d", &vni))
11409         ;
11410       else
11411         {
11412           errmsg ("parse error '%U'", format_unformat_error, line_input);
11413           return -99;
11414         }
11415     }
11416
11417   if (src_set == 0)
11418     {
11419       errmsg ("tunnel src address not specified");
11420       return -99;
11421     }
11422   if (dst_set == 0)
11423     {
11424       errmsg ("tunnel dst address not specified");
11425       return -99;
11426     }
11427
11428   if (grp_set && !ip46_address_is_multicast (&dst))
11429     {
11430       errmsg ("tunnel group address not multicast");
11431       return -99;
11432     }
11433   if (grp_set && mcast_sw_if_index == ~0)
11434     {
11435       errmsg ("tunnel nonexistent multicast device");
11436       return -99;
11437     }
11438   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11439     {
11440       errmsg ("tunnel dst address must be unicast");
11441       return -99;
11442     }
11443
11444
11445   if (ipv4_set && ipv6_set)
11446     {
11447       errmsg ("both IPv4 and IPv6 addresses specified");
11448       return -99;
11449     }
11450
11451   if ((vni == 0) || (vni >> 24))
11452     {
11453       errmsg ("vni not specified or out of range");
11454       return -99;
11455     }
11456
11457   M (VXLAN_ADD_DEL_TUNNEL, mp);
11458
11459   if (ipv6_set)
11460     {
11461       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11462       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11463     }
11464   else
11465     {
11466       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11467       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11468     }
11469   mp->encap_vrf_id = ntohl (encap_vrf_id);
11470   mp->decap_next_index = ntohl (decap_next_index);
11471   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11472   mp->vni = ntohl (vni);
11473   mp->is_add = is_add;
11474   mp->is_ipv6 = ipv6_set;
11475
11476   S (mp);
11477   W (ret);
11478   return ret;
11479 }
11480
11481 static void vl_api_vxlan_tunnel_details_t_handler
11482   (vl_api_vxlan_tunnel_details_t * mp)
11483 {
11484   vat_main_t *vam = &vat_main;
11485   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11486   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11487
11488   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11489          ntohl (mp->sw_if_index),
11490          format_ip46_address, &src, IP46_TYPE_ANY,
11491          format_ip46_address, &dst, IP46_TYPE_ANY,
11492          ntohl (mp->encap_vrf_id),
11493          ntohl (mp->decap_next_index), ntohl (mp->vni),
11494          ntohl (mp->mcast_sw_if_index));
11495 }
11496
11497 static void vl_api_vxlan_tunnel_details_t_handler_json
11498   (vl_api_vxlan_tunnel_details_t * mp)
11499 {
11500   vat_main_t *vam = &vat_main;
11501   vat_json_node_t *node = NULL;
11502
11503   if (VAT_JSON_ARRAY != vam->json_tree.type)
11504     {
11505       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11506       vat_json_init_array (&vam->json_tree);
11507     }
11508   node = vat_json_array_add (&vam->json_tree);
11509
11510   vat_json_init_object (node);
11511   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11512   if (mp->is_ipv6)
11513     {
11514       struct in6_addr ip6;
11515
11516       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11517       vat_json_object_add_ip6 (node, "src_address", ip6);
11518       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11519       vat_json_object_add_ip6 (node, "dst_address", ip6);
11520     }
11521   else
11522     {
11523       struct in_addr ip4;
11524
11525       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11526       vat_json_object_add_ip4 (node, "src_address", ip4);
11527       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11528       vat_json_object_add_ip4 (node, "dst_address", ip4);
11529     }
11530   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11531   vat_json_object_add_uint (node, "decap_next_index",
11532                             ntohl (mp->decap_next_index));
11533   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11534   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11535   vat_json_object_add_uint (node, "mcast_sw_if_index",
11536                             ntohl (mp->mcast_sw_if_index));
11537 }
11538
11539 static int
11540 api_vxlan_tunnel_dump (vat_main_t * vam)
11541 {
11542   unformat_input_t *i = vam->input;
11543   vl_api_vxlan_tunnel_dump_t *mp;
11544   vl_api_control_ping_t *mp_ping;
11545   u32 sw_if_index;
11546   u8 sw_if_index_set = 0;
11547   int ret;
11548
11549   /* Parse args required to build the message */
11550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11551     {
11552       if (unformat (i, "sw_if_index %d", &sw_if_index))
11553         sw_if_index_set = 1;
11554       else
11555         break;
11556     }
11557
11558   if (sw_if_index_set == 0)
11559     {
11560       sw_if_index = ~0;
11561     }
11562
11563   if (!vam->json_output)
11564     {
11565       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11566              "sw_if_index", "src_address", "dst_address",
11567              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11568     }
11569
11570   /* Get list of vxlan-tunnel interfaces */
11571   M (VXLAN_TUNNEL_DUMP, mp);
11572
11573   mp->sw_if_index = htonl (sw_if_index);
11574
11575   S (mp);
11576
11577   /* Use a control ping for synchronization */
11578   M (CONTROL_PING, mp_ping);
11579   S (mp_ping);
11580
11581   W (ret);
11582   return ret;
11583 }
11584
11585 static int
11586 api_gre_add_del_tunnel (vat_main_t * vam)
11587 {
11588   unformat_input_t *line_input = vam->input;
11589   vl_api_gre_add_del_tunnel_t *mp;
11590   ip4_address_t src4, dst4;
11591   ip6_address_t src6, dst6;
11592   u8 is_add = 1;
11593   u8 ipv4_set = 0;
11594   u8 ipv6_set = 0;
11595   u8 teb = 0;
11596   u8 src_set = 0;
11597   u8 dst_set = 0;
11598   u32 outer_fib_id = 0;
11599   int ret;
11600
11601   memset (&src4, 0, sizeof src4);
11602   memset (&dst4, 0, sizeof dst4);
11603   memset (&src6, 0, sizeof src6);
11604   memset (&dst6, 0, sizeof dst6);
11605
11606   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11607     {
11608       if (unformat (line_input, "del"))
11609         is_add = 0;
11610       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11611         {
11612           src_set = 1;
11613           ipv4_set = 1;
11614         }
11615       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11616         {
11617           dst_set = 1;
11618           ipv4_set = 1;
11619         }
11620       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11621         {
11622           src_set = 1;
11623           ipv6_set = 1;
11624         }
11625       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11626         {
11627           dst_set = 1;
11628           ipv6_set = 1;
11629         }
11630       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11631         ;
11632       else if (unformat (line_input, "teb"))
11633         teb = 1;
11634       else
11635         {
11636           errmsg ("parse error '%U'", format_unformat_error, line_input);
11637           return -99;
11638         }
11639     }
11640
11641   if (src_set == 0)
11642     {
11643       errmsg ("tunnel src address not specified");
11644       return -99;
11645     }
11646   if (dst_set == 0)
11647     {
11648       errmsg ("tunnel dst address not specified");
11649       return -99;
11650     }
11651   if (ipv4_set && ipv6_set)
11652     {
11653       errmsg ("both IPv4 and IPv6 addresses specified");
11654       return -99;
11655     }
11656
11657
11658   M (GRE_ADD_DEL_TUNNEL, mp);
11659
11660   if (ipv4_set)
11661     {
11662       clib_memcpy (&mp->src_address, &src4, 4);
11663       clib_memcpy (&mp->dst_address, &dst4, 4);
11664     }
11665   else
11666     {
11667       clib_memcpy (&mp->src_address, &src6, 16);
11668       clib_memcpy (&mp->dst_address, &dst6, 16);
11669     }
11670   mp->outer_fib_id = ntohl (outer_fib_id);
11671   mp->is_add = is_add;
11672   mp->teb = teb;
11673   mp->is_ipv6 = ipv6_set;
11674
11675   S (mp);
11676   W (ret);
11677   return ret;
11678 }
11679
11680 static void vl_api_gre_tunnel_details_t_handler
11681   (vl_api_gre_tunnel_details_t * mp)
11682 {
11683   vat_main_t *vam = &vat_main;
11684   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11685   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11686
11687   print (vam->ofp, "%11d%24U%24U%6d%14d",
11688          ntohl (mp->sw_if_index),
11689          format_ip46_address, &src, IP46_TYPE_ANY,
11690          format_ip46_address, &dst, IP46_TYPE_ANY,
11691          mp->teb, ntohl (mp->outer_fib_id));
11692 }
11693
11694 static void vl_api_gre_tunnel_details_t_handler_json
11695   (vl_api_gre_tunnel_details_t * mp)
11696 {
11697   vat_main_t *vam = &vat_main;
11698   vat_json_node_t *node = NULL;
11699   struct in_addr ip4;
11700   struct in6_addr ip6;
11701
11702   if (VAT_JSON_ARRAY != vam->json_tree.type)
11703     {
11704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11705       vat_json_init_array (&vam->json_tree);
11706     }
11707   node = vat_json_array_add (&vam->json_tree);
11708
11709   vat_json_init_object (node);
11710   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11711   if (!mp->is_ipv6)
11712     {
11713       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11714       vat_json_object_add_ip4 (node, "src_address", ip4);
11715       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11716       vat_json_object_add_ip4 (node, "dst_address", ip4);
11717     }
11718   else
11719     {
11720       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11721       vat_json_object_add_ip6 (node, "src_address", ip6);
11722       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11723       vat_json_object_add_ip6 (node, "dst_address", ip6);
11724     }
11725   vat_json_object_add_uint (node, "teb", mp->teb);
11726   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11727   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11728 }
11729
11730 static int
11731 api_gre_tunnel_dump (vat_main_t * vam)
11732 {
11733   unformat_input_t *i = vam->input;
11734   vl_api_gre_tunnel_dump_t *mp;
11735   vl_api_control_ping_t *mp_ping;
11736   u32 sw_if_index;
11737   u8 sw_if_index_set = 0;
11738   int ret;
11739
11740   /* Parse args required to build the message */
11741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11742     {
11743       if (unformat (i, "sw_if_index %d", &sw_if_index))
11744         sw_if_index_set = 1;
11745       else
11746         break;
11747     }
11748
11749   if (sw_if_index_set == 0)
11750     {
11751       sw_if_index = ~0;
11752     }
11753
11754   if (!vam->json_output)
11755     {
11756       print (vam->ofp, "%11s%24s%24s%6s%14s",
11757              "sw_if_index", "src_address", "dst_address", "teb",
11758              "outer_fib_id");
11759     }
11760
11761   /* Get list of gre-tunnel interfaces */
11762   M (GRE_TUNNEL_DUMP, mp);
11763
11764   mp->sw_if_index = htonl (sw_if_index);
11765
11766   S (mp);
11767
11768   /* Use a control ping for synchronization */
11769   M (CONTROL_PING, mp_ping);
11770   S (mp_ping);
11771
11772   W (ret);
11773   return ret;
11774 }
11775
11776 static int
11777 api_l2_fib_clear_table (vat_main_t * vam)
11778 {
11779 //  unformat_input_t * i = vam->input;
11780   vl_api_l2_fib_clear_table_t *mp;
11781   int ret;
11782
11783   M (L2_FIB_CLEAR_TABLE, mp);
11784
11785   S (mp);
11786   W (ret);
11787   return ret;
11788 }
11789
11790 static int
11791 api_l2_interface_efp_filter (vat_main_t * vam)
11792 {
11793   unformat_input_t *i = vam->input;
11794   vl_api_l2_interface_efp_filter_t *mp;
11795   u32 sw_if_index;
11796   u8 enable = 1;
11797   u8 sw_if_index_set = 0;
11798   int ret;
11799
11800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11801     {
11802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11803         sw_if_index_set = 1;
11804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11805         sw_if_index_set = 1;
11806       else if (unformat (i, "enable"))
11807         enable = 1;
11808       else if (unformat (i, "disable"))
11809         enable = 0;
11810       else
11811         {
11812           clib_warning ("parse error '%U'", format_unformat_error, i);
11813           return -99;
11814         }
11815     }
11816
11817   if (sw_if_index_set == 0)
11818     {
11819       errmsg ("missing sw_if_index");
11820       return -99;
11821     }
11822
11823   M (L2_INTERFACE_EFP_FILTER, mp);
11824
11825   mp->sw_if_index = ntohl (sw_if_index);
11826   mp->enable_disable = enable;
11827
11828   S (mp);
11829   W (ret);
11830   return ret;
11831 }
11832
11833 #define foreach_vtr_op                          \
11834 _("disable",  L2_VTR_DISABLED)                  \
11835 _("push-1",  L2_VTR_PUSH_1)                     \
11836 _("push-2",  L2_VTR_PUSH_2)                     \
11837 _("pop-1",  L2_VTR_POP_1)                       \
11838 _("pop-2",  L2_VTR_POP_2)                       \
11839 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11840 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11841 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11842 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11843
11844 static int
11845 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11846 {
11847   unformat_input_t *i = vam->input;
11848   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11849   u32 sw_if_index;
11850   u8 sw_if_index_set = 0;
11851   u8 vtr_op_set = 0;
11852   u32 vtr_op = 0;
11853   u32 push_dot1q = 1;
11854   u32 tag1 = ~0;
11855   u32 tag2 = ~0;
11856   int ret;
11857
11858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11859     {
11860       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11861         sw_if_index_set = 1;
11862       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11863         sw_if_index_set = 1;
11864       else if (unformat (i, "vtr_op %d", &vtr_op))
11865         vtr_op_set = 1;
11866 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11867       foreach_vtr_op
11868 #undef _
11869         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11870         ;
11871       else if (unformat (i, "tag1 %d", &tag1))
11872         ;
11873       else if (unformat (i, "tag2 %d", &tag2))
11874         ;
11875       else
11876         {
11877           clib_warning ("parse error '%U'", format_unformat_error, i);
11878           return -99;
11879         }
11880     }
11881
11882   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11883     {
11884       errmsg ("missing vtr operation or sw_if_index");
11885       return -99;
11886     }
11887
11888   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11889   mp->sw_if_index = ntohl (sw_if_index);
11890   mp->vtr_op = ntohl (vtr_op);
11891   mp->push_dot1q = ntohl (push_dot1q);
11892   mp->tag1 = ntohl (tag1);
11893   mp->tag2 = ntohl (tag2);
11894
11895   S (mp);
11896   W (ret);
11897   return ret;
11898 }
11899
11900 static int
11901 api_create_vhost_user_if (vat_main_t * vam)
11902 {
11903   unformat_input_t *i = vam->input;
11904   vl_api_create_vhost_user_if_t *mp;
11905   u8 *file_name;
11906   u8 is_server = 0;
11907   u8 file_name_set = 0;
11908   u32 custom_dev_instance = ~0;
11909   u8 hwaddr[6];
11910   u8 use_custom_mac = 0;
11911   u8 *tag = 0;
11912   int ret;
11913
11914   /* Shut up coverity */
11915   memset (hwaddr, 0, sizeof (hwaddr));
11916
11917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (i, "socket %s", &file_name))
11920         {
11921           file_name_set = 1;
11922         }
11923       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11924         ;
11925       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11926         use_custom_mac = 1;
11927       else if (unformat (i, "server"))
11928         is_server = 1;
11929       else if (unformat (i, "tag %s", &tag))
11930         ;
11931       else
11932         break;
11933     }
11934
11935   if (file_name_set == 0)
11936     {
11937       errmsg ("missing socket file name");
11938       return -99;
11939     }
11940
11941   if (vec_len (file_name) > 255)
11942     {
11943       errmsg ("socket file name too long");
11944       return -99;
11945     }
11946   vec_add1 (file_name, 0);
11947
11948   M (CREATE_VHOST_USER_IF, mp);
11949
11950   mp->is_server = is_server;
11951   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11952   vec_free (file_name);
11953   if (custom_dev_instance != ~0)
11954     {
11955       mp->renumber = 1;
11956       mp->custom_dev_instance = ntohl (custom_dev_instance);
11957     }
11958   mp->use_custom_mac = use_custom_mac;
11959   clib_memcpy (mp->mac_address, hwaddr, 6);
11960   if (tag)
11961     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11962   vec_free (tag);
11963
11964   S (mp);
11965   W (ret);
11966   return ret;
11967 }
11968
11969 static int
11970 api_modify_vhost_user_if (vat_main_t * vam)
11971 {
11972   unformat_input_t *i = vam->input;
11973   vl_api_modify_vhost_user_if_t *mp;
11974   u8 *file_name;
11975   u8 is_server = 0;
11976   u8 file_name_set = 0;
11977   u32 custom_dev_instance = ~0;
11978   u8 sw_if_index_set = 0;
11979   u32 sw_if_index = (u32) ~ 0;
11980   int ret;
11981
11982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11983     {
11984       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11985         sw_if_index_set = 1;
11986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11987         sw_if_index_set = 1;
11988       else if (unformat (i, "socket %s", &file_name))
11989         {
11990           file_name_set = 1;
11991         }
11992       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11993         ;
11994       else if (unformat (i, "server"))
11995         is_server = 1;
11996       else
11997         break;
11998     }
11999
12000   if (sw_if_index_set == 0)
12001     {
12002       errmsg ("missing sw_if_index or interface name");
12003       return -99;
12004     }
12005
12006   if (file_name_set == 0)
12007     {
12008       errmsg ("missing socket file name");
12009       return -99;
12010     }
12011
12012   if (vec_len (file_name) > 255)
12013     {
12014       errmsg ("socket file name too long");
12015       return -99;
12016     }
12017   vec_add1 (file_name, 0);
12018
12019   M (MODIFY_VHOST_USER_IF, mp);
12020
12021   mp->sw_if_index = ntohl (sw_if_index);
12022   mp->is_server = is_server;
12023   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12024   vec_free (file_name);
12025   if (custom_dev_instance != ~0)
12026     {
12027       mp->renumber = 1;
12028       mp->custom_dev_instance = ntohl (custom_dev_instance);
12029     }
12030
12031   S (mp);
12032   W (ret);
12033   return ret;
12034 }
12035
12036 static int
12037 api_delete_vhost_user_if (vat_main_t * vam)
12038 {
12039   unformat_input_t *i = vam->input;
12040   vl_api_delete_vhost_user_if_t *mp;
12041   u32 sw_if_index = ~0;
12042   u8 sw_if_index_set = 0;
12043   int ret;
12044
12045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12046     {
12047       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12048         sw_if_index_set = 1;
12049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12050         sw_if_index_set = 1;
12051       else
12052         break;
12053     }
12054
12055   if (sw_if_index_set == 0)
12056     {
12057       errmsg ("missing sw_if_index or interface name");
12058       return -99;
12059     }
12060
12061
12062   M (DELETE_VHOST_USER_IF, mp);
12063
12064   mp->sw_if_index = ntohl (sw_if_index);
12065
12066   S (mp);
12067   W (ret);
12068   return ret;
12069 }
12070
12071 static void vl_api_sw_interface_vhost_user_details_t_handler
12072   (vl_api_sw_interface_vhost_user_details_t * mp)
12073 {
12074   vat_main_t *vam = &vat_main;
12075
12076   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12077          (char *) mp->interface_name,
12078          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12079          clib_net_to_host_u64 (mp->features), mp->is_server,
12080          ntohl (mp->num_regions), (char *) mp->sock_filename);
12081   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12082 }
12083
12084 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12085   (vl_api_sw_interface_vhost_user_details_t * mp)
12086 {
12087   vat_main_t *vam = &vat_main;
12088   vat_json_node_t *node = NULL;
12089
12090   if (VAT_JSON_ARRAY != vam->json_tree.type)
12091     {
12092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12093       vat_json_init_array (&vam->json_tree);
12094     }
12095   node = vat_json_array_add (&vam->json_tree);
12096
12097   vat_json_init_object (node);
12098   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12099   vat_json_object_add_string_copy (node, "interface_name",
12100                                    mp->interface_name);
12101   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12102                             ntohl (mp->virtio_net_hdr_sz));
12103   vat_json_object_add_uint (node, "features",
12104                             clib_net_to_host_u64 (mp->features));
12105   vat_json_object_add_uint (node, "is_server", mp->is_server);
12106   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12107   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12108   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12109 }
12110
12111 static int
12112 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12113 {
12114   vl_api_sw_interface_vhost_user_dump_t *mp;
12115   vl_api_control_ping_t *mp_ping;
12116   int ret;
12117   print (vam->ofp,
12118          "Interface name            idx hdr_sz features server regions filename");
12119
12120   /* Get list of vhost-user interfaces */
12121   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12122   S (mp);
12123
12124   /* Use a control ping for synchronization */
12125   M (CONTROL_PING, mp_ping);
12126   S (mp_ping);
12127
12128   W (ret);
12129   return ret;
12130 }
12131
12132 static int
12133 api_show_version (vat_main_t * vam)
12134 {
12135   vl_api_show_version_t *mp;
12136   int ret;
12137
12138   M (SHOW_VERSION, mp);
12139
12140   S (mp);
12141   W (ret);
12142   return ret;
12143 }
12144
12145
12146 static int
12147 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12148 {
12149   unformat_input_t *line_input = vam->input;
12150   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12151   ip4_address_t local4, remote4;
12152   ip6_address_t local6, remote6;
12153   u8 is_add = 1;
12154   u8 ipv4_set = 0, ipv6_set = 0;
12155   u8 local_set = 0;
12156   u8 remote_set = 0;
12157   u8 grp_set = 0;
12158   u32 mcast_sw_if_index = ~0;
12159   u32 encap_vrf_id = 0;
12160   u32 decap_vrf_id = 0;
12161   u8 protocol = ~0;
12162   u32 vni;
12163   u8 vni_set = 0;
12164   int ret;
12165
12166   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12167   memset (&local4, 0, sizeof local4);
12168   memset (&remote4, 0, sizeof remote4);
12169   memset (&local6, 0, sizeof local6);
12170   memset (&remote6, 0, sizeof remote6);
12171
12172   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12173     {
12174       if (unformat (line_input, "del"))
12175         is_add = 0;
12176       else if (unformat (line_input, "local %U",
12177                          unformat_ip4_address, &local4))
12178         {
12179           local_set = 1;
12180           ipv4_set = 1;
12181         }
12182       else if (unformat (line_input, "remote %U",
12183                          unformat_ip4_address, &remote4))
12184         {
12185           remote_set = 1;
12186           ipv4_set = 1;
12187         }
12188       else if (unformat (line_input, "local %U",
12189                          unformat_ip6_address, &local6))
12190         {
12191           local_set = 1;
12192           ipv6_set = 1;
12193         }
12194       else if (unformat (line_input, "remote %U",
12195                          unformat_ip6_address, &remote6))
12196         {
12197           remote_set = 1;
12198           ipv6_set = 1;
12199         }
12200       else if (unformat (line_input, "group %U %U",
12201                          unformat_ip4_address, &remote4,
12202                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12203         {
12204           grp_set = remote_set = 1;
12205           ipv4_set = 1;
12206         }
12207       else if (unformat (line_input, "group %U",
12208                          unformat_ip4_address, &remote4))
12209         {
12210           grp_set = remote_set = 1;
12211           ipv4_set = 1;
12212         }
12213       else if (unformat (line_input, "group %U %U",
12214                          unformat_ip6_address, &remote6,
12215                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12216         {
12217           grp_set = remote_set = 1;
12218           ipv6_set = 1;
12219         }
12220       else if (unformat (line_input, "group %U",
12221                          unformat_ip6_address, &remote6))
12222         {
12223           grp_set = remote_set = 1;
12224           ipv6_set = 1;
12225         }
12226       else
12227         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12228         ;
12229       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12230         ;
12231       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12232         ;
12233       else if (unformat (line_input, "vni %d", &vni))
12234         vni_set = 1;
12235       else if (unformat (line_input, "next-ip4"))
12236         protocol = 1;
12237       else if (unformat (line_input, "next-ip6"))
12238         protocol = 2;
12239       else if (unformat (line_input, "next-ethernet"))
12240         protocol = 3;
12241       else if (unformat (line_input, "next-nsh"))
12242         protocol = 4;
12243       else
12244         {
12245           errmsg ("parse error '%U'", format_unformat_error, line_input);
12246           return -99;
12247         }
12248     }
12249
12250   if (local_set == 0)
12251     {
12252       errmsg ("tunnel local address not specified");
12253       return -99;
12254     }
12255   if (remote_set == 0)
12256     {
12257       errmsg ("tunnel remote address not specified");
12258       return -99;
12259     }
12260   if (grp_set && mcast_sw_if_index == ~0)
12261     {
12262       errmsg ("tunnel nonexistent multicast device");
12263       return -99;
12264     }
12265   if (ipv4_set && ipv6_set)
12266     {
12267       errmsg ("both IPv4 and IPv6 addresses specified");
12268       return -99;
12269     }
12270
12271   if (vni_set == 0)
12272     {
12273       errmsg ("vni not specified");
12274       return -99;
12275     }
12276
12277   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12278
12279
12280   if (ipv6_set)
12281     {
12282       clib_memcpy (&mp->local, &local6, sizeof (local6));
12283       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12284     }
12285   else
12286     {
12287       clib_memcpy (&mp->local, &local4, sizeof (local4));
12288       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12289     }
12290
12291   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12292   mp->encap_vrf_id = ntohl (encap_vrf_id);
12293   mp->decap_vrf_id = ntohl (decap_vrf_id);
12294   mp->protocol = protocol;
12295   mp->vni = ntohl (vni);
12296   mp->is_add = is_add;
12297   mp->is_ipv6 = ipv6_set;
12298
12299   S (mp);
12300   W (ret);
12301   return ret;
12302 }
12303
12304 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12305   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12306 {
12307   vat_main_t *vam = &vat_main;
12308   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12309   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12310
12311   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12312          ntohl (mp->sw_if_index),
12313          format_ip46_address, &local, IP46_TYPE_ANY,
12314          format_ip46_address, &remote, IP46_TYPE_ANY,
12315          ntohl (mp->vni), mp->protocol,
12316          ntohl (mp->mcast_sw_if_index),
12317          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12318 }
12319
12320
12321 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12322   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12323 {
12324   vat_main_t *vam = &vat_main;
12325   vat_json_node_t *node = NULL;
12326   struct in_addr ip4;
12327   struct in6_addr ip6;
12328
12329   if (VAT_JSON_ARRAY != vam->json_tree.type)
12330     {
12331       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12332       vat_json_init_array (&vam->json_tree);
12333     }
12334   node = vat_json_array_add (&vam->json_tree);
12335
12336   vat_json_init_object (node);
12337   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12338   if (mp->is_ipv6)
12339     {
12340       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12341       vat_json_object_add_ip6 (node, "local", ip6);
12342       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12343       vat_json_object_add_ip6 (node, "remote", ip6);
12344     }
12345   else
12346     {
12347       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12348       vat_json_object_add_ip4 (node, "local", ip4);
12349       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12350       vat_json_object_add_ip4 (node, "remote", ip4);
12351     }
12352   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12353   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12354   vat_json_object_add_uint (node, "mcast_sw_if_index",
12355                             ntohl (mp->mcast_sw_if_index));
12356   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12357   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12358   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12359 }
12360
12361 static int
12362 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12363 {
12364   unformat_input_t *i = vam->input;
12365   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12366   vl_api_control_ping_t *mp_ping;
12367   u32 sw_if_index;
12368   u8 sw_if_index_set = 0;
12369   int ret;
12370
12371   /* Parse args required to build the message */
12372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12373     {
12374       if (unformat (i, "sw_if_index %d", &sw_if_index))
12375         sw_if_index_set = 1;
12376       else
12377         break;
12378     }
12379
12380   if (sw_if_index_set == 0)
12381     {
12382       sw_if_index = ~0;
12383     }
12384
12385   if (!vam->json_output)
12386     {
12387       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12388              "sw_if_index", "local", "remote", "vni",
12389              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12390     }
12391
12392   /* Get list of vxlan-tunnel interfaces */
12393   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12394
12395   mp->sw_if_index = htonl (sw_if_index);
12396
12397   S (mp);
12398
12399   /* Use a control ping for synchronization */
12400   M (CONTROL_PING, mp_ping);
12401   S (mp_ping);
12402
12403   W (ret);
12404   return ret;
12405 }
12406
12407
12408 u8 *
12409 format_l2_fib_mac_address (u8 * s, va_list * args)
12410 {
12411   u8 *a = va_arg (*args, u8 *);
12412
12413   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12414                  a[2], a[3], a[4], a[5], a[6], a[7]);
12415 }
12416
12417 static void vl_api_l2_fib_table_details_t_handler
12418   (vl_api_l2_fib_table_details_t * mp)
12419 {
12420   vat_main_t *vam = &vat_main;
12421
12422   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12423          "       %d       %d     %d",
12424          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12425          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12426          mp->bvi_mac);
12427 }
12428
12429 static void vl_api_l2_fib_table_details_t_handler_json
12430   (vl_api_l2_fib_table_details_t * mp)
12431 {
12432   vat_main_t *vam = &vat_main;
12433   vat_json_node_t *node = NULL;
12434
12435   if (VAT_JSON_ARRAY != vam->json_tree.type)
12436     {
12437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12438       vat_json_init_array (&vam->json_tree);
12439     }
12440   node = vat_json_array_add (&vam->json_tree);
12441
12442   vat_json_init_object (node);
12443   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12444   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12445   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12446   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12447   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12448   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12449 }
12450
12451 static int
12452 api_l2_fib_table_dump (vat_main_t * vam)
12453 {
12454   unformat_input_t *i = vam->input;
12455   vl_api_l2_fib_table_dump_t *mp;
12456   vl_api_control_ping_t *mp_ping;
12457   u32 bd_id;
12458   u8 bd_id_set = 0;
12459   int ret;
12460
12461   /* Parse args required to build the message */
12462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12463     {
12464       if (unformat (i, "bd_id %d", &bd_id))
12465         bd_id_set = 1;
12466       else
12467         break;
12468     }
12469
12470   if (bd_id_set == 0)
12471     {
12472       errmsg ("missing bridge domain");
12473       return -99;
12474     }
12475
12476   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12477
12478   /* Get list of l2 fib entries */
12479   M (L2_FIB_TABLE_DUMP, mp);
12480
12481   mp->bd_id = ntohl (bd_id);
12482   S (mp);
12483
12484   /* Use a control ping for synchronization */
12485   M (CONTROL_PING, mp_ping);
12486   S (mp_ping);
12487
12488   W (ret);
12489   return ret;
12490 }
12491
12492
12493 static int
12494 api_interface_name_renumber (vat_main_t * vam)
12495 {
12496   unformat_input_t *line_input = vam->input;
12497   vl_api_interface_name_renumber_t *mp;
12498   u32 sw_if_index = ~0;
12499   u32 new_show_dev_instance = ~0;
12500   int ret;
12501
12502   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12503     {
12504       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12505                     &sw_if_index))
12506         ;
12507       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12508         ;
12509       else if (unformat (line_input, "new_show_dev_instance %d",
12510                          &new_show_dev_instance))
12511         ;
12512       else
12513         break;
12514     }
12515
12516   if (sw_if_index == ~0)
12517     {
12518       errmsg ("missing interface name or sw_if_index");
12519       return -99;
12520     }
12521
12522   if (new_show_dev_instance == ~0)
12523     {
12524       errmsg ("missing new_show_dev_instance");
12525       return -99;
12526     }
12527
12528   M (INTERFACE_NAME_RENUMBER, mp);
12529
12530   mp->sw_if_index = ntohl (sw_if_index);
12531   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12532
12533   S (mp);
12534   W (ret);
12535   return ret;
12536 }
12537
12538 static int
12539 api_want_ip4_arp_events (vat_main_t * vam)
12540 {
12541   unformat_input_t *line_input = vam->input;
12542   vl_api_want_ip4_arp_events_t *mp;
12543   ip4_address_t address;
12544   int address_set = 0;
12545   u32 enable_disable = 1;
12546   int ret;
12547
12548   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12549     {
12550       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12551         address_set = 1;
12552       else if (unformat (line_input, "del"))
12553         enable_disable = 0;
12554       else
12555         break;
12556     }
12557
12558   if (address_set == 0)
12559     {
12560       errmsg ("missing addresses");
12561       return -99;
12562     }
12563
12564   M (WANT_IP4_ARP_EVENTS, mp);
12565   mp->enable_disable = enable_disable;
12566   mp->pid = htonl (getpid ());
12567   mp->address = address.as_u32;
12568
12569   S (mp);
12570   W (ret);
12571   return ret;
12572 }
12573
12574 static int
12575 api_want_ip6_nd_events (vat_main_t * vam)
12576 {
12577   unformat_input_t *line_input = vam->input;
12578   vl_api_want_ip6_nd_events_t *mp;
12579   ip6_address_t address;
12580   int address_set = 0;
12581   u32 enable_disable = 1;
12582   int ret;
12583
12584   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12585     {
12586       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12587         address_set = 1;
12588       else if (unformat (line_input, "del"))
12589         enable_disable = 0;
12590       else
12591         break;
12592     }
12593
12594   if (address_set == 0)
12595     {
12596       errmsg ("missing addresses");
12597       return -99;
12598     }
12599
12600   M (WANT_IP6_ND_EVENTS, mp);
12601   mp->enable_disable = enable_disable;
12602   mp->pid = htonl (getpid ());
12603   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12604
12605   S (mp);
12606   W (ret);
12607   return ret;
12608 }
12609
12610 static int
12611 api_want_l2_macs_events (vat_main_t * vam)
12612 {
12613   unformat_input_t *line_input = vam->input;
12614   vl_api_want_l2_macs_events_t *mp;
12615   u8 enable_disable = 1;
12616   u32 scan_delay = 0;
12617   u32 max_macs_in_event = 0;
12618   u32 learn_limit = 0;
12619   int ret;
12620
12621   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12622     {
12623       if (unformat (line_input, "learn-limit %d", &learn_limit))
12624         ;
12625       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12626         ;
12627       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12628         ;
12629       else if (unformat (line_input, "disable"))
12630         enable_disable = 0;
12631       else
12632         break;
12633     }
12634
12635   M (WANT_L2_MACS_EVENTS, mp);
12636   mp->enable_disable = enable_disable;
12637   mp->pid = htonl (getpid ());
12638   mp->learn_limit = htonl (learn_limit);
12639   mp->scan_delay = (u8) scan_delay;
12640   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12641   S (mp);
12642   W (ret);
12643   return ret;
12644 }
12645
12646 static int
12647 api_input_acl_set_interface (vat_main_t * vam)
12648 {
12649   unformat_input_t *i = vam->input;
12650   vl_api_input_acl_set_interface_t *mp;
12651   u32 sw_if_index;
12652   int sw_if_index_set;
12653   u32 ip4_table_index = ~0;
12654   u32 ip6_table_index = ~0;
12655   u32 l2_table_index = ~0;
12656   u8 is_add = 1;
12657   int ret;
12658
12659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12660     {
12661       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12662         sw_if_index_set = 1;
12663       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12664         sw_if_index_set = 1;
12665       else if (unformat (i, "del"))
12666         is_add = 0;
12667       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12668         ;
12669       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12670         ;
12671       else if (unformat (i, "l2-table %d", &l2_table_index))
12672         ;
12673       else
12674         {
12675           clib_warning ("parse error '%U'", format_unformat_error, i);
12676           return -99;
12677         }
12678     }
12679
12680   if (sw_if_index_set == 0)
12681     {
12682       errmsg ("missing interface name or sw_if_index");
12683       return -99;
12684     }
12685
12686   M (INPUT_ACL_SET_INTERFACE, mp);
12687
12688   mp->sw_if_index = ntohl (sw_if_index);
12689   mp->ip4_table_index = ntohl (ip4_table_index);
12690   mp->ip6_table_index = ntohl (ip6_table_index);
12691   mp->l2_table_index = ntohl (l2_table_index);
12692   mp->is_add = is_add;
12693
12694   S (mp);
12695   W (ret);
12696   return ret;
12697 }
12698
12699 static int
12700 api_ip_address_dump (vat_main_t * vam)
12701 {
12702   unformat_input_t *i = vam->input;
12703   vl_api_ip_address_dump_t *mp;
12704   vl_api_control_ping_t *mp_ping;
12705   u32 sw_if_index = ~0;
12706   u8 sw_if_index_set = 0;
12707   u8 ipv4_set = 0;
12708   u8 ipv6_set = 0;
12709   int ret;
12710
12711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12712     {
12713       if (unformat (i, "sw_if_index %d", &sw_if_index))
12714         sw_if_index_set = 1;
12715       else
12716         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12717         sw_if_index_set = 1;
12718       else if (unformat (i, "ipv4"))
12719         ipv4_set = 1;
12720       else if (unformat (i, "ipv6"))
12721         ipv6_set = 1;
12722       else
12723         break;
12724     }
12725
12726   if (ipv4_set && ipv6_set)
12727     {
12728       errmsg ("ipv4 and ipv6 flags cannot be both set");
12729       return -99;
12730     }
12731
12732   if ((!ipv4_set) && (!ipv6_set))
12733     {
12734       errmsg ("no ipv4 nor ipv6 flag set");
12735       return -99;
12736     }
12737
12738   if (sw_if_index_set == 0)
12739     {
12740       errmsg ("missing interface name or sw_if_index");
12741       return -99;
12742     }
12743
12744   vam->current_sw_if_index = sw_if_index;
12745   vam->is_ipv6 = ipv6_set;
12746
12747   M (IP_ADDRESS_DUMP, mp);
12748   mp->sw_if_index = ntohl (sw_if_index);
12749   mp->is_ipv6 = ipv6_set;
12750   S (mp);
12751
12752   /* Use a control ping for synchronization */
12753   M (CONTROL_PING, mp_ping);
12754   S (mp_ping);
12755
12756   W (ret);
12757   return ret;
12758 }
12759
12760 static int
12761 api_ip_dump (vat_main_t * vam)
12762 {
12763   vl_api_ip_dump_t *mp;
12764   vl_api_control_ping_t *mp_ping;
12765   unformat_input_t *in = vam->input;
12766   int ipv4_set = 0;
12767   int ipv6_set = 0;
12768   int is_ipv6;
12769   int i;
12770   int ret;
12771
12772   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12773     {
12774       if (unformat (in, "ipv4"))
12775         ipv4_set = 1;
12776       else if (unformat (in, "ipv6"))
12777         ipv6_set = 1;
12778       else
12779         break;
12780     }
12781
12782   if (ipv4_set && ipv6_set)
12783     {
12784       errmsg ("ipv4 and ipv6 flags cannot be both set");
12785       return -99;
12786     }
12787
12788   if ((!ipv4_set) && (!ipv6_set))
12789     {
12790       errmsg ("no ipv4 nor ipv6 flag set");
12791       return -99;
12792     }
12793
12794   is_ipv6 = ipv6_set;
12795   vam->is_ipv6 = is_ipv6;
12796
12797   /* free old data */
12798   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12799     {
12800       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12801     }
12802   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12803
12804   M (IP_DUMP, mp);
12805   mp->is_ipv6 = ipv6_set;
12806   S (mp);
12807
12808   /* Use a control ping for synchronization */
12809   M (CONTROL_PING, mp_ping);
12810   S (mp_ping);
12811
12812   W (ret);
12813   return ret;
12814 }
12815
12816 static int
12817 api_ipsec_spd_add_del (vat_main_t * vam)
12818 {
12819   unformat_input_t *i = vam->input;
12820   vl_api_ipsec_spd_add_del_t *mp;
12821   u32 spd_id = ~0;
12822   u8 is_add = 1;
12823   int ret;
12824
12825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12826     {
12827       if (unformat (i, "spd_id %d", &spd_id))
12828         ;
12829       else if (unformat (i, "del"))
12830         is_add = 0;
12831       else
12832         {
12833           clib_warning ("parse error '%U'", format_unformat_error, i);
12834           return -99;
12835         }
12836     }
12837   if (spd_id == ~0)
12838     {
12839       errmsg ("spd_id must be set");
12840       return -99;
12841     }
12842
12843   M (IPSEC_SPD_ADD_DEL, mp);
12844
12845   mp->spd_id = ntohl (spd_id);
12846   mp->is_add = is_add;
12847
12848   S (mp);
12849   W (ret);
12850   return ret;
12851 }
12852
12853 static int
12854 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12855 {
12856   unformat_input_t *i = vam->input;
12857   vl_api_ipsec_interface_add_del_spd_t *mp;
12858   u32 sw_if_index;
12859   u8 sw_if_index_set = 0;
12860   u32 spd_id = (u32) ~ 0;
12861   u8 is_add = 1;
12862   int ret;
12863
12864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12865     {
12866       if (unformat (i, "del"))
12867         is_add = 0;
12868       else if (unformat (i, "spd_id %d", &spd_id))
12869         ;
12870       else
12871         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12872         sw_if_index_set = 1;
12873       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12874         sw_if_index_set = 1;
12875       else
12876         {
12877           clib_warning ("parse error '%U'", format_unformat_error, i);
12878           return -99;
12879         }
12880
12881     }
12882
12883   if (spd_id == (u32) ~ 0)
12884     {
12885       errmsg ("spd_id must be set");
12886       return -99;
12887     }
12888
12889   if (sw_if_index_set == 0)
12890     {
12891       errmsg ("missing interface name or sw_if_index");
12892       return -99;
12893     }
12894
12895   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12896
12897   mp->spd_id = ntohl (spd_id);
12898   mp->sw_if_index = ntohl (sw_if_index);
12899   mp->is_add = is_add;
12900
12901   S (mp);
12902   W (ret);
12903   return ret;
12904 }
12905
12906 static int
12907 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12908 {
12909   unformat_input_t *i = vam->input;
12910   vl_api_ipsec_spd_add_del_entry_t *mp;
12911   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12912   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12913   i32 priority = 0;
12914   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12915   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12916   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12917   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12918   int ret;
12919
12920   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12921   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12922   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12923   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12924   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12925   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12926
12927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12928     {
12929       if (unformat (i, "del"))
12930         is_add = 0;
12931       if (unformat (i, "outbound"))
12932         is_outbound = 1;
12933       if (unformat (i, "inbound"))
12934         is_outbound = 0;
12935       else if (unformat (i, "spd_id %d", &spd_id))
12936         ;
12937       else if (unformat (i, "sa_id %d", &sa_id))
12938         ;
12939       else if (unformat (i, "priority %d", &priority))
12940         ;
12941       else if (unformat (i, "protocol %d", &protocol))
12942         ;
12943       else if (unformat (i, "lport_start %d", &lport_start))
12944         ;
12945       else if (unformat (i, "lport_stop %d", &lport_stop))
12946         ;
12947       else if (unformat (i, "rport_start %d", &rport_start))
12948         ;
12949       else if (unformat (i, "rport_stop %d", &rport_stop))
12950         ;
12951       else
12952         if (unformat
12953             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12954         {
12955           is_ipv6 = 0;
12956           is_ip_any = 0;
12957         }
12958       else
12959         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12960         {
12961           is_ipv6 = 0;
12962           is_ip_any = 0;
12963         }
12964       else
12965         if (unformat
12966             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12967         {
12968           is_ipv6 = 0;
12969           is_ip_any = 0;
12970         }
12971       else
12972         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12973         {
12974           is_ipv6 = 0;
12975           is_ip_any = 0;
12976         }
12977       else
12978         if (unformat
12979             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12980         {
12981           is_ipv6 = 1;
12982           is_ip_any = 0;
12983         }
12984       else
12985         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12986         {
12987           is_ipv6 = 1;
12988           is_ip_any = 0;
12989         }
12990       else
12991         if (unformat
12992             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12993         {
12994           is_ipv6 = 1;
12995           is_ip_any = 0;
12996         }
12997       else
12998         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12999         {
13000           is_ipv6 = 1;
13001           is_ip_any = 0;
13002         }
13003       else
13004         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13005         {
13006           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13007             {
13008               clib_warning ("unsupported action: 'resolve'");
13009               return -99;
13010             }
13011         }
13012       else
13013         {
13014           clib_warning ("parse error '%U'", format_unformat_error, i);
13015           return -99;
13016         }
13017
13018     }
13019
13020   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13021
13022   mp->spd_id = ntohl (spd_id);
13023   mp->priority = ntohl (priority);
13024   mp->is_outbound = is_outbound;
13025
13026   mp->is_ipv6 = is_ipv6;
13027   if (is_ipv6 || is_ip_any)
13028     {
13029       clib_memcpy (mp->remote_address_start, &raddr6_start,
13030                    sizeof (ip6_address_t));
13031       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13032                    sizeof (ip6_address_t));
13033       clib_memcpy (mp->local_address_start, &laddr6_start,
13034                    sizeof (ip6_address_t));
13035       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13036                    sizeof (ip6_address_t));
13037     }
13038   else
13039     {
13040       clib_memcpy (mp->remote_address_start, &raddr4_start,
13041                    sizeof (ip4_address_t));
13042       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13043                    sizeof (ip4_address_t));
13044       clib_memcpy (mp->local_address_start, &laddr4_start,
13045                    sizeof (ip4_address_t));
13046       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13047                    sizeof (ip4_address_t));
13048     }
13049   mp->protocol = (u8) protocol;
13050   mp->local_port_start = ntohs ((u16) lport_start);
13051   mp->local_port_stop = ntohs ((u16) lport_stop);
13052   mp->remote_port_start = ntohs ((u16) rport_start);
13053   mp->remote_port_stop = ntohs ((u16) rport_stop);
13054   mp->policy = (u8) policy;
13055   mp->sa_id = ntohl (sa_id);
13056   mp->is_add = is_add;
13057   mp->is_ip_any = is_ip_any;
13058   S (mp);
13059   W (ret);
13060   return ret;
13061 }
13062
13063 static int
13064 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13065 {
13066   unformat_input_t *i = vam->input;
13067   vl_api_ipsec_sad_add_del_entry_t *mp;
13068   u32 sad_id = 0, spi = 0;
13069   u8 *ck = 0, *ik = 0;
13070   u8 is_add = 1;
13071
13072   u8 protocol = IPSEC_PROTOCOL_AH;
13073   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13074   u32 crypto_alg = 0, integ_alg = 0;
13075   ip4_address_t tun_src4;
13076   ip4_address_t tun_dst4;
13077   ip6_address_t tun_src6;
13078   ip6_address_t tun_dst6;
13079   int ret;
13080
13081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13082     {
13083       if (unformat (i, "del"))
13084         is_add = 0;
13085       else if (unformat (i, "sad_id %d", &sad_id))
13086         ;
13087       else if (unformat (i, "spi %d", &spi))
13088         ;
13089       else if (unformat (i, "esp"))
13090         protocol = IPSEC_PROTOCOL_ESP;
13091       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13092         {
13093           is_tunnel = 1;
13094           is_tunnel_ipv6 = 0;
13095         }
13096       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13097         {
13098           is_tunnel = 1;
13099           is_tunnel_ipv6 = 0;
13100         }
13101       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13102         {
13103           is_tunnel = 1;
13104           is_tunnel_ipv6 = 1;
13105         }
13106       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13107         {
13108           is_tunnel = 1;
13109           is_tunnel_ipv6 = 1;
13110         }
13111       else
13112         if (unformat
13113             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13114         {
13115           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13116               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13117             {
13118               clib_warning ("unsupported crypto-alg: '%U'",
13119                             format_ipsec_crypto_alg, crypto_alg);
13120               return -99;
13121             }
13122         }
13123       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13124         ;
13125       else
13126         if (unformat
13127             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13128         {
13129           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13130               integ_alg >= IPSEC_INTEG_N_ALG)
13131             {
13132               clib_warning ("unsupported integ-alg: '%U'",
13133                             format_ipsec_integ_alg, integ_alg);
13134               return -99;
13135             }
13136         }
13137       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13138         ;
13139       else
13140         {
13141           clib_warning ("parse error '%U'", format_unformat_error, i);
13142           return -99;
13143         }
13144
13145     }
13146
13147   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13148
13149   mp->sad_id = ntohl (sad_id);
13150   mp->is_add = is_add;
13151   mp->protocol = protocol;
13152   mp->spi = ntohl (spi);
13153   mp->is_tunnel = is_tunnel;
13154   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13155   mp->crypto_algorithm = crypto_alg;
13156   mp->integrity_algorithm = integ_alg;
13157   mp->crypto_key_length = vec_len (ck);
13158   mp->integrity_key_length = vec_len (ik);
13159
13160   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13161     mp->crypto_key_length = sizeof (mp->crypto_key);
13162
13163   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13164     mp->integrity_key_length = sizeof (mp->integrity_key);
13165
13166   if (ck)
13167     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13168   if (ik)
13169     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13170
13171   if (is_tunnel)
13172     {
13173       if (is_tunnel_ipv6)
13174         {
13175           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13176                        sizeof (ip6_address_t));
13177           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13178                        sizeof (ip6_address_t));
13179         }
13180       else
13181         {
13182           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13183                        sizeof (ip4_address_t));
13184           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13185                        sizeof (ip4_address_t));
13186         }
13187     }
13188
13189   S (mp);
13190   W (ret);
13191   return ret;
13192 }
13193
13194 static int
13195 api_ipsec_sa_set_key (vat_main_t * vam)
13196 {
13197   unformat_input_t *i = vam->input;
13198   vl_api_ipsec_sa_set_key_t *mp;
13199   u32 sa_id;
13200   u8 *ck = 0, *ik = 0;
13201   int ret;
13202
13203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13204     {
13205       if (unformat (i, "sa_id %d", &sa_id))
13206         ;
13207       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13208         ;
13209       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13210         ;
13211       else
13212         {
13213           clib_warning ("parse error '%U'", format_unformat_error, i);
13214           return -99;
13215         }
13216     }
13217
13218   M (IPSEC_SA_SET_KEY, mp);
13219
13220   mp->sa_id = ntohl (sa_id);
13221   mp->crypto_key_length = vec_len (ck);
13222   mp->integrity_key_length = vec_len (ik);
13223
13224   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13225     mp->crypto_key_length = sizeof (mp->crypto_key);
13226
13227   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13228     mp->integrity_key_length = sizeof (mp->integrity_key);
13229
13230   if (ck)
13231     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13232   if (ik)
13233     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13234
13235   S (mp);
13236   W (ret);
13237   return ret;
13238 }
13239
13240 static int
13241 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13242 {
13243   unformat_input_t *i = vam->input;
13244   vl_api_ipsec_tunnel_if_add_del_t *mp;
13245   u32 local_spi = 0, remote_spi = 0;
13246   u32 crypto_alg = 0, integ_alg = 0;
13247   u8 *lck = NULL, *rck = NULL;
13248   u8 *lik = NULL, *rik = NULL;
13249   ip4_address_t local_ip = { {0} };
13250   ip4_address_t remote_ip = { {0} };
13251   u8 is_add = 1;
13252   u8 esn = 0;
13253   u8 anti_replay = 0;
13254   int ret;
13255
13256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13257     {
13258       if (unformat (i, "del"))
13259         is_add = 0;
13260       else if (unformat (i, "esn"))
13261         esn = 1;
13262       else if (unformat (i, "anti_replay"))
13263         anti_replay = 1;
13264       else if (unformat (i, "local_spi %d", &local_spi))
13265         ;
13266       else if (unformat (i, "remote_spi %d", &remote_spi))
13267         ;
13268       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13269         ;
13270       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13271         ;
13272       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13273         ;
13274       else
13275         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13276         ;
13277       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13278         ;
13279       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13280         ;
13281       else
13282         if (unformat
13283             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13284         {
13285           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13286               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13287             {
13288               errmsg ("unsupported crypto-alg: '%U'\n",
13289                       format_ipsec_crypto_alg, crypto_alg);
13290               return -99;
13291             }
13292         }
13293       else
13294         if (unformat
13295             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13296         {
13297           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13298               integ_alg >= IPSEC_INTEG_N_ALG)
13299             {
13300               errmsg ("unsupported integ-alg: '%U'\n",
13301                       format_ipsec_integ_alg, integ_alg);
13302               return -99;
13303             }
13304         }
13305       else
13306         {
13307           errmsg ("parse error '%U'\n", format_unformat_error, i);
13308           return -99;
13309         }
13310     }
13311
13312   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13313
13314   mp->is_add = is_add;
13315   mp->esn = esn;
13316   mp->anti_replay = anti_replay;
13317
13318   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13319   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13320
13321   mp->local_spi = htonl (local_spi);
13322   mp->remote_spi = htonl (remote_spi);
13323   mp->crypto_alg = (u8) crypto_alg;
13324
13325   mp->local_crypto_key_len = 0;
13326   if (lck)
13327     {
13328       mp->local_crypto_key_len = vec_len (lck);
13329       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13330         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13331       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13332     }
13333
13334   mp->remote_crypto_key_len = 0;
13335   if (rck)
13336     {
13337       mp->remote_crypto_key_len = vec_len (rck);
13338       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13339         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13340       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13341     }
13342
13343   mp->integ_alg = (u8) integ_alg;
13344
13345   mp->local_integ_key_len = 0;
13346   if (lik)
13347     {
13348       mp->local_integ_key_len = vec_len (lik);
13349       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13350         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13351       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13352     }
13353
13354   mp->remote_integ_key_len = 0;
13355   if (rik)
13356     {
13357       mp->remote_integ_key_len = vec_len (rik);
13358       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13359         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13360       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13361     }
13362
13363   S (mp);
13364   W (ret);
13365   return ret;
13366 }
13367
13368 static int
13369 api_ikev2_profile_add_del (vat_main_t * vam)
13370 {
13371   unformat_input_t *i = vam->input;
13372   vl_api_ikev2_profile_add_del_t *mp;
13373   u8 is_add = 1;
13374   u8 *name = 0;
13375   int ret;
13376
13377   const char *valid_chars = "a-zA-Z0-9_";
13378
13379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13380     {
13381       if (unformat (i, "del"))
13382         is_add = 0;
13383       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13384         vec_add1 (name, 0);
13385       else
13386         {
13387           errmsg ("parse error '%U'", format_unformat_error, i);
13388           return -99;
13389         }
13390     }
13391
13392   if (!vec_len (name))
13393     {
13394       errmsg ("profile name must be specified");
13395       return -99;
13396     }
13397
13398   if (vec_len (name) > 64)
13399     {
13400       errmsg ("profile name too long");
13401       return -99;
13402     }
13403
13404   M (IKEV2_PROFILE_ADD_DEL, mp);
13405
13406   clib_memcpy (mp->name, name, vec_len (name));
13407   mp->is_add = is_add;
13408   vec_free (name);
13409
13410   S (mp);
13411   W (ret);
13412   return ret;
13413 }
13414
13415 static int
13416 api_ikev2_profile_set_auth (vat_main_t * vam)
13417 {
13418   unformat_input_t *i = vam->input;
13419   vl_api_ikev2_profile_set_auth_t *mp;
13420   u8 *name = 0;
13421   u8 *data = 0;
13422   u32 auth_method = 0;
13423   u8 is_hex = 0;
13424   int ret;
13425
13426   const char *valid_chars = "a-zA-Z0-9_";
13427
13428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13429     {
13430       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13431         vec_add1 (name, 0);
13432       else if (unformat (i, "auth_method %U",
13433                          unformat_ikev2_auth_method, &auth_method))
13434         ;
13435       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13436         is_hex = 1;
13437       else if (unformat (i, "auth_data %v", &data))
13438         ;
13439       else
13440         {
13441           errmsg ("parse error '%U'", format_unformat_error, i);
13442           return -99;
13443         }
13444     }
13445
13446   if (!vec_len (name))
13447     {
13448       errmsg ("profile name must be specified");
13449       return -99;
13450     }
13451
13452   if (vec_len (name) > 64)
13453     {
13454       errmsg ("profile name too long");
13455       return -99;
13456     }
13457
13458   if (!vec_len (data))
13459     {
13460       errmsg ("auth_data must be specified");
13461       return -99;
13462     }
13463
13464   if (!auth_method)
13465     {
13466       errmsg ("auth_method must be specified");
13467       return -99;
13468     }
13469
13470   M (IKEV2_PROFILE_SET_AUTH, mp);
13471
13472   mp->is_hex = is_hex;
13473   mp->auth_method = (u8) auth_method;
13474   mp->data_len = vec_len (data);
13475   clib_memcpy (mp->name, name, vec_len (name));
13476   clib_memcpy (mp->data, data, vec_len (data));
13477   vec_free (name);
13478   vec_free (data);
13479
13480   S (mp);
13481   W (ret);
13482   return ret;
13483 }
13484
13485 static int
13486 api_ikev2_profile_set_id (vat_main_t * vam)
13487 {
13488   unformat_input_t *i = vam->input;
13489   vl_api_ikev2_profile_set_id_t *mp;
13490   u8 *name = 0;
13491   u8 *data = 0;
13492   u8 is_local = 0;
13493   u32 id_type = 0;
13494   ip4_address_t ip4;
13495   int ret;
13496
13497   const char *valid_chars = "a-zA-Z0-9_";
13498
13499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13500     {
13501       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13502         vec_add1 (name, 0);
13503       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13504         ;
13505       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13506         {
13507           data = vec_new (u8, 4);
13508           clib_memcpy (data, ip4.as_u8, 4);
13509         }
13510       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13511         ;
13512       else if (unformat (i, "id_data %v", &data))
13513         ;
13514       else if (unformat (i, "local"))
13515         is_local = 1;
13516       else if (unformat (i, "remote"))
13517         is_local = 0;
13518       else
13519         {
13520           errmsg ("parse error '%U'", format_unformat_error, i);
13521           return -99;
13522         }
13523     }
13524
13525   if (!vec_len (name))
13526     {
13527       errmsg ("profile name must be specified");
13528       return -99;
13529     }
13530
13531   if (vec_len (name) > 64)
13532     {
13533       errmsg ("profile name too long");
13534       return -99;
13535     }
13536
13537   if (!vec_len (data))
13538     {
13539       errmsg ("id_data must be specified");
13540       return -99;
13541     }
13542
13543   if (!id_type)
13544     {
13545       errmsg ("id_type must be specified");
13546       return -99;
13547     }
13548
13549   M (IKEV2_PROFILE_SET_ID, mp);
13550
13551   mp->is_local = is_local;
13552   mp->id_type = (u8) id_type;
13553   mp->data_len = vec_len (data);
13554   clib_memcpy (mp->name, name, vec_len (name));
13555   clib_memcpy (mp->data, data, vec_len (data));
13556   vec_free (name);
13557   vec_free (data);
13558
13559   S (mp);
13560   W (ret);
13561   return ret;
13562 }
13563
13564 static int
13565 api_ikev2_profile_set_ts (vat_main_t * vam)
13566 {
13567   unformat_input_t *i = vam->input;
13568   vl_api_ikev2_profile_set_ts_t *mp;
13569   u8 *name = 0;
13570   u8 is_local = 0;
13571   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13572   ip4_address_t start_addr, end_addr;
13573
13574   const char *valid_chars = "a-zA-Z0-9_";
13575   int ret;
13576
13577   start_addr.as_u32 = 0;
13578   end_addr.as_u32 = (u32) ~ 0;
13579
13580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13581     {
13582       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13583         vec_add1 (name, 0);
13584       else if (unformat (i, "protocol %d", &proto))
13585         ;
13586       else if (unformat (i, "start_port %d", &start_port))
13587         ;
13588       else if (unformat (i, "end_port %d", &end_port))
13589         ;
13590       else
13591         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13592         ;
13593       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13594         ;
13595       else if (unformat (i, "local"))
13596         is_local = 1;
13597       else if (unformat (i, "remote"))
13598         is_local = 0;
13599       else
13600         {
13601           errmsg ("parse error '%U'", format_unformat_error, i);
13602           return -99;
13603         }
13604     }
13605
13606   if (!vec_len (name))
13607     {
13608       errmsg ("profile name must be specified");
13609       return -99;
13610     }
13611
13612   if (vec_len (name) > 64)
13613     {
13614       errmsg ("profile name too long");
13615       return -99;
13616     }
13617
13618   M (IKEV2_PROFILE_SET_TS, mp);
13619
13620   mp->is_local = is_local;
13621   mp->proto = (u8) proto;
13622   mp->start_port = (u16) start_port;
13623   mp->end_port = (u16) end_port;
13624   mp->start_addr = start_addr.as_u32;
13625   mp->end_addr = end_addr.as_u32;
13626   clib_memcpy (mp->name, name, vec_len (name));
13627   vec_free (name);
13628
13629   S (mp);
13630   W (ret);
13631   return ret;
13632 }
13633
13634 static int
13635 api_ikev2_set_local_key (vat_main_t * vam)
13636 {
13637   unformat_input_t *i = vam->input;
13638   vl_api_ikev2_set_local_key_t *mp;
13639   u8 *file = 0;
13640   int ret;
13641
13642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13643     {
13644       if (unformat (i, "file %v", &file))
13645         vec_add1 (file, 0);
13646       else
13647         {
13648           errmsg ("parse error '%U'", format_unformat_error, i);
13649           return -99;
13650         }
13651     }
13652
13653   if (!vec_len (file))
13654     {
13655       errmsg ("RSA key file must be specified");
13656       return -99;
13657     }
13658
13659   if (vec_len (file) > 256)
13660     {
13661       errmsg ("file name too long");
13662       return -99;
13663     }
13664
13665   M (IKEV2_SET_LOCAL_KEY, mp);
13666
13667   clib_memcpy (mp->key_file, file, vec_len (file));
13668   vec_free (file);
13669
13670   S (mp);
13671   W (ret);
13672   return ret;
13673 }
13674
13675 static int
13676 api_ikev2_set_responder (vat_main_t * vam)
13677 {
13678   unformat_input_t *i = vam->input;
13679   vl_api_ikev2_set_responder_t *mp;
13680   int ret;
13681   u8 *name = 0;
13682   u32 sw_if_index = ~0;
13683   ip4_address_t address;
13684
13685   const char *valid_chars = "a-zA-Z0-9_";
13686
13687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13688     {
13689       if (unformat
13690           (i, "%U interface %d address %U", unformat_token, valid_chars,
13691            &name, &sw_if_index, unformat_ip4_address, &address))
13692         vec_add1 (name, 0);
13693       else
13694         {
13695           errmsg ("parse error '%U'", format_unformat_error, i);
13696           return -99;
13697         }
13698     }
13699
13700   if (!vec_len (name))
13701     {
13702       errmsg ("profile name must be specified");
13703       return -99;
13704     }
13705
13706   if (vec_len (name) > 64)
13707     {
13708       errmsg ("profile name too long");
13709       return -99;
13710     }
13711
13712   M (IKEV2_SET_RESPONDER, mp);
13713
13714   clib_memcpy (mp->name, name, vec_len (name));
13715   vec_free (name);
13716
13717   mp->sw_if_index = sw_if_index;
13718   clib_memcpy (mp->address, &address, sizeof (address));
13719
13720   S (mp);
13721   W (ret);
13722   return ret;
13723 }
13724
13725 static int
13726 api_ikev2_set_ike_transforms (vat_main_t * vam)
13727 {
13728   unformat_input_t *i = vam->input;
13729   vl_api_ikev2_set_ike_transforms_t *mp;
13730   int ret;
13731   u8 *name = 0;
13732   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13733
13734   const char *valid_chars = "a-zA-Z0-9_";
13735
13736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13737     {
13738       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13739                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13740         vec_add1 (name, 0);
13741       else
13742         {
13743           errmsg ("parse error '%U'", format_unformat_error, i);
13744           return -99;
13745         }
13746     }
13747
13748   if (!vec_len (name))
13749     {
13750       errmsg ("profile name must be specified");
13751       return -99;
13752     }
13753
13754   if (vec_len (name) > 64)
13755     {
13756       errmsg ("profile name too long");
13757       return -99;
13758     }
13759
13760   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13761
13762   clib_memcpy (mp->name, name, vec_len (name));
13763   vec_free (name);
13764   mp->crypto_alg = crypto_alg;
13765   mp->crypto_key_size = crypto_key_size;
13766   mp->integ_alg = integ_alg;
13767   mp->dh_group = dh_group;
13768
13769   S (mp);
13770   W (ret);
13771   return ret;
13772 }
13773
13774
13775 static int
13776 api_ikev2_set_esp_transforms (vat_main_t * vam)
13777 {
13778   unformat_input_t *i = vam->input;
13779   vl_api_ikev2_set_esp_transforms_t *mp;
13780   int ret;
13781   u8 *name = 0;
13782   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13783
13784   const char *valid_chars = "a-zA-Z0-9_";
13785
13786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13787     {
13788       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13789                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13790         vec_add1 (name, 0);
13791       else
13792         {
13793           errmsg ("parse error '%U'", format_unformat_error, i);
13794           return -99;
13795         }
13796     }
13797
13798   if (!vec_len (name))
13799     {
13800       errmsg ("profile name must be specified");
13801       return -99;
13802     }
13803
13804   if (vec_len (name) > 64)
13805     {
13806       errmsg ("profile name too long");
13807       return -99;
13808     }
13809
13810   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13811
13812   clib_memcpy (mp->name, name, vec_len (name));
13813   vec_free (name);
13814   mp->crypto_alg = crypto_alg;
13815   mp->crypto_key_size = crypto_key_size;
13816   mp->integ_alg = integ_alg;
13817   mp->dh_group = dh_group;
13818
13819   S (mp);
13820   W (ret);
13821   return ret;
13822 }
13823
13824 static int
13825 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13826 {
13827   unformat_input_t *i = vam->input;
13828   vl_api_ikev2_set_sa_lifetime_t *mp;
13829   int ret;
13830   u8 *name = 0;
13831   u64 lifetime, lifetime_maxdata;
13832   u32 lifetime_jitter, handover;
13833
13834   const char *valid_chars = "a-zA-Z0-9_";
13835
13836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13837     {
13838       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13839                     &lifetime, &lifetime_jitter, &handover,
13840                     &lifetime_maxdata))
13841         vec_add1 (name, 0);
13842       else
13843         {
13844           errmsg ("parse error '%U'", format_unformat_error, i);
13845           return -99;
13846         }
13847     }
13848
13849   if (!vec_len (name))
13850     {
13851       errmsg ("profile name must be specified");
13852       return -99;
13853     }
13854
13855   if (vec_len (name) > 64)
13856     {
13857       errmsg ("profile name too long");
13858       return -99;
13859     }
13860
13861   M (IKEV2_SET_SA_LIFETIME, mp);
13862
13863   clib_memcpy (mp->name, name, vec_len (name));
13864   vec_free (name);
13865   mp->lifetime = lifetime;
13866   mp->lifetime_jitter = lifetime_jitter;
13867   mp->handover = handover;
13868   mp->lifetime_maxdata = lifetime_maxdata;
13869
13870   S (mp);
13871   W (ret);
13872   return ret;
13873 }
13874
13875 static int
13876 api_ikev2_initiate_sa_init (vat_main_t * vam)
13877 {
13878   unformat_input_t *i = vam->input;
13879   vl_api_ikev2_initiate_sa_init_t *mp;
13880   int ret;
13881   u8 *name = 0;
13882
13883   const char *valid_chars = "a-zA-Z0-9_";
13884
13885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13886     {
13887       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13888         vec_add1 (name, 0);
13889       else
13890         {
13891           errmsg ("parse error '%U'", format_unformat_error, i);
13892           return -99;
13893         }
13894     }
13895
13896   if (!vec_len (name))
13897     {
13898       errmsg ("profile name must be specified");
13899       return -99;
13900     }
13901
13902   if (vec_len (name) > 64)
13903     {
13904       errmsg ("profile name too long");
13905       return -99;
13906     }
13907
13908   M (IKEV2_INITIATE_SA_INIT, mp);
13909
13910   clib_memcpy (mp->name, name, vec_len (name));
13911   vec_free (name);
13912
13913   S (mp);
13914   W (ret);
13915   return ret;
13916 }
13917
13918 static int
13919 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13920 {
13921   unformat_input_t *i = vam->input;
13922   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13923   int ret;
13924   u64 ispi;
13925
13926
13927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13928     {
13929       if (unformat (i, "%lx", &ispi))
13930         ;
13931       else
13932         {
13933           errmsg ("parse error '%U'", format_unformat_error, i);
13934           return -99;
13935         }
13936     }
13937
13938   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13939
13940   mp->ispi = ispi;
13941
13942   S (mp);
13943   W (ret);
13944   return ret;
13945 }
13946
13947 static int
13948 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13949 {
13950   unformat_input_t *i = vam->input;
13951   vl_api_ikev2_initiate_del_child_sa_t *mp;
13952   int ret;
13953   u32 ispi;
13954
13955
13956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13957     {
13958       if (unformat (i, "%x", &ispi))
13959         ;
13960       else
13961         {
13962           errmsg ("parse error '%U'", format_unformat_error, i);
13963           return -99;
13964         }
13965     }
13966
13967   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13968
13969   mp->ispi = ispi;
13970
13971   S (mp);
13972   W (ret);
13973   return ret;
13974 }
13975
13976 static int
13977 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13978 {
13979   unformat_input_t *i = vam->input;
13980   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13981   int ret;
13982   u32 ispi;
13983
13984
13985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13986     {
13987       if (unformat (i, "%x", &ispi))
13988         ;
13989       else
13990         {
13991           errmsg ("parse error '%U'", format_unformat_error, i);
13992           return -99;
13993         }
13994     }
13995
13996   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13997
13998   mp->ispi = ispi;
13999
14000   S (mp);
14001   W (ret);
14002   return ret;
14003 }
14004
14005 /*
14006  * MAP
14007  */
14008 static int
14009 api_map_add_domain (vat_main_t * vam)
14010 {
14011   unformat_input_t *i = vam->input;
14012   vl_api_map_add_domain_t *mp;
14013
14014   ip4_address_t ip4_prefix;
14015   ip6_address_t ip6_prefix;
14016   ip6_address_t ip6_src;
14017   u32 num_m_args = 0;
14018   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14019     0, psid_length = 0;
14020   u8 is_translation = 0;
14021   u32 mtu = 0;
14022   u32 ip6_src_len = 128;
14023   int ret;
14024
14025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14026     {
14027       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14028                     &ip4_prefix, &ip4_prefix_len))
14029         num_m_args++;
14030       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14031                          &ip6_prefix, &ip6_prefix_len))
14032         num_m_args++;
14033       else
14034         if (unformat
14035             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14036              &ip6_src_len))
14037         num_m_args++;
14038       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14039         num_m_args++;
14040       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14041         num_m_args++;
14042       else if (unformat (i, "psid-offset %d", &psid_offset))
14043         num_m_args++;
14044       else if (unformat (i, "psid-len %d", &psid_length))
14045         num_m_args++;
14046       else if (unformat (i, "mtu %d", &mtu))
14047         num_m_args++;
14048       else if (unformat (i, "map-t"))
14049         is_translation = 1;
14050       else
14051         {
14052           clib_warning ("parse error '%U'", format_unformat_error, i);
14053           return -99;
14054         }
14055     }
14056
14057   if (num_m_args < 3)
14058     {
14059       errmsg ("mandatory argument(s) missing");
14060       return -99;
14061     }
14062
14063   /* Construct the API message */
14064   M (MAP_ADD_DOMAIN, mp);
14065
14066   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14067   mp->ip4_prefix_len = ip4_prefix_len;
14068
14069   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14070   mp->ip6_prefix_len = ip6_prefix_len;
14071
14072   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14073   mp->ip6_src_prefix_len = ip6_src_len;
14074
14075   mp->ea_bits_len = ea_bits_len;
14076   mp->psid_offset = psid_offset;
14077   mp->psid_length = psid_length;
14078   mp->is_translation = is_translation;
14079   mp->mtu = htons (mtu);
14080
14081   /* send it... */
14082   S (mp);
14083
14084   /* Wait for a reply, return good/bad news  */
14085   W (ret);
14086   return ret;
14087 }
14088
14089 static int
14090 api_map_del_domain (vat_main_t * vam)
14091 {
14092   unformat_input_t *i = vam->input;
14093   vl_api_map_del_domain_t *mp;
14094
14095   u32 num_m_args = 0;
14096   u32 index;
14097   int ret;
14098
14099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14100     {
14101       if (unformat (i, "index %d", &index))
14102         num_m_args++;
14103       else
14104         {
14105           clib_warning ("parse error '%U'", format_unformat_error, i);
14106           return -99;
14107         }
14108     }
14109
14110   if (num_m_args != 1)
14111     {
14112       errmsg ("mandatory argument(s) missing");
14113       return -99;
14114     }
14115
14116   /* Construct the API message */
14117   M (MAP_DEL_DOMAIN, mp);
14118
14119   mp->index = ntohl (index);
14120
14121   /* send it... */
14122   S (mp);
14123
14124   /* Wait for a reply, return good/bad news  */
14125   W (ret);
14126   return ret;
14127 }
14128
14129 static int
14130 api_map_add_del_rule (vat_main_t * vam)
14131 {
14132   unformat_input_t *i = vam->input;
14133   vl_api_map_add_del_rule_t *mp;
14134   u8 is_add = 1;
14135   ip6_address_t ip6_dst;
14136   u32 num_m_args = 0, index, psid = 0;
14137   int ret;
14138
14139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14140     {
14141       if (unformat (i, "index %d", &index))
14142         num_m_args++;
14143       else if (unformat (i, "psid %d", &psid))
14144         num_m_args++;
14145       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14146         num_m_args++;
14147       else if (unformat (i, "del"))
14148         {
14149           is_add = 0;
14150         }
14151       else
14152         {
14153           clib_warning ("parse error '%U'", format_unformat_error, i);
14154           return -99;
14155         }
14156     }
14157
14158   /* Construct the API message */
14159   M (MAP_ADD_DEL_RULE, mp);
14160
14161   mp->index = ntohl (index);
14162   mp->is_add = is_add;
14163   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14164   mp->psid = ntohs (psid);
14165
14166   /* send it... */
14167   S (mp);
14168
14169   /* Wait for a reply, return good/bad news  */
14170   W (ret);
14171   return ret;
14172 }
14173
14174 static int
14175 api_map_domain_dump (vat_main_t * vam)
14176 {
14177   vl_api_map_domain_dump_t *mp;
14178   vl_api_control_ping_t *mp_ping;
14179   int ret;
14180
14181   /* Construct the API message */
14182   M (MAP_DOMAIN_DUMP, mp);
14183
14184   /* send it... */
14185   S (mp);
14186
14187   /* Use a control ping for synchronization */
14188   M (CONTROL_PING, mp_ping);
14189   S (mp_ping);
14190
14191   W (ret);
14192   return ret;
14193 }
14194
14195 static int
14196 api_map_rule_dump (vat_main_t * vam)
14197 {
14198   unformat_input_t *i = vam->input;
14199   vl_api_map_rule_dump_t *mp;
14200   vl_api_control_ping_t *mp_ping;
14201   u32 domain_index = ~0;
14202   int ret;
14203
14204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14205     {
14206       if (unformat (i, "index %u", &domain_index))
14207         ;
14208       else
14209         break;
14210     }
14211
14212   if (domain_index == ~0)
14213     {
14214       clib_warning ("parse error: domain index expected");
14215       return -99;
14216     }
14217
14218   /* Construct the API message */
14219   M (MAP_RULE_DUMP, mp);
14220
14221   mp->domain_index = htonl (domain_index);
14222
14223   /* send it... */
14224   S (mp);
14225
14226   /* Use a control ping for synchronization */
14227   M (CONTROL_PING, mp_ping);
14228   S (mp_ping);
14229
14230   W (ret);
14231   return ret;
14232 }
14233
14234 static void vl_api_map_add_domain_reply_t_handler
14235   (vl_api_map_add_domain_reply_t * mp)
14236 {
14237   vat_main_t *vam = &vat_main;
14238   i32 retval = ntohl (mp->retval);
14239
14240   if (vam->async_mode)
14241     {
14242       vam->async_errors += (retval < 0);
14243     }
14244   else
14245     {
14246       vam->retval = retval;
14247       vam->result_ready = 1;
14248     }
14249 }
14250
14251 static void vl_api_map_add_domain_reply_t_handler_json
14252   (vl_api_map_add_domain_reply_t * mp)
14253 {
14254   vat_main_t *vam = &vat_main;
14255   vat_json_node_t node;
14256
14257   vat_json_init_object (&node);
14258   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14259   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14260
14261   vat_json_print (vam->ofp, &node);
14262   vat_json_free (&node);
14263
14264   vam->retval = ntohl (mp->retval);
14265   vam->result_ready = 1;
14266 }
14267
14268 static int
14269 api_get_first_msg_id (vat_main_t * vam)
14270 {
14271   vl_api_get_first_msg_id_t *mp;
14272   unformat_input_t *i = vam->input;
14273   u8 *name;
14274   u8 name_set = 0;
14275   int ret;
14276
14277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14278     {
14279       if (unformat (i, "client %s", &name))
14280         name_set = 1;
14281       else
14282         break;
14283     }
14284
14285   if (name_set == 0)
14286     {
14287       errmsg ("missing client name");
14288       return -99;
14289     }
14290   vec_add1 (name, 0);
14291
14292   if (vec_len (name) > 63)
14293     {
14294       errmsg ("client name too long");
14295       return -99;
14296     }
14297
14298   M (GET_FIRST_MSG_ID, mp);
14299   clib_memcpy (mp->name, name, vec_len (name));
14300   S (mp);
14301   W (ret);
14302   return ret;
14303 }
14304
14305 static int
14306 api_cop_interface_enable_disable (vat_main_t * vam)
14307 {
14308   unformat_input_t *line_input = vam->input;
14309   vl_api_cop_interface_enable_disable_t *mp;
14310   u32 sw_if_index = ~0;
14311   u8 enable_disable = 1;
14312   int ret;
14313
14314   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14315     {
14316       if (unformat (line_input, "disable"))
14317         enable_disable = 0;
14318       if (unformat (line_input, "enable"))
14319         enable_disable = 1;
14320       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14321                          vam, &sw_if_index))
14322         ;
14323       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14324         ;
14325       else
14326         break;
14327     }
14328
14329   if (sw_if_index == ~0)
14330     {
14331       errmsg ("missing interface name or sw_if_index");
14332       return -99;
14333     }
14334
14335   /* Construct the API message */
14336   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14337   mp->sw_if_index = ntohl (sw_if_index);
14338   mp->enable_disable = enable_disable;
14339
14340   /* send it... */
14341   S (mp);
14342   /* Wait for the reply */
14343   W (ret);
14344   return ret;
14345 }
14346
14347 static int
14348 api_cop_whitelist_enable_disable (vat_main_t * vam)
14349 {
14350   unformat_input_t *line_input = vam->input;
14351   vl_api_cop_whitelist_enable_disable_t *mp;
14352   u32 sw_if_index = ~0;
14353   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14354   u32 fib_id = 0;
14355   int ret;
14356
14357   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14358     {
14359       if (unformat (line_input, "ip4"))
14360         ip4 = 1;
14361       else if (unformat (line_input, "ip6"))
14362         ip6 = 1;
14363       else if (unformat (line_input, "default"))
14364         default_cop = 1;
14365       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14366                          vam, &sw_if_index))
14367         ;
14368       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14369         ;
14370       else if (unformat (line_input, "fib-id %d", &fib_id))
14371         ;
14372       else
14373         break;
14374     }
14375
14376   if (sw_if_index == ~0)
14377     {
14378       errmsg ("missing interface name or sw_if_index");
14379       return -99;
14380     }
14381
14382   /* Construct the API message */
14383   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14384   mp->sw_if_index = ntohl (sw_if_index);
14385   mp->fib_id = ntohl (fib_id);
14386   mp->ip4 = ip4;
14387   mp->ip6 = ip6;
14388   mp->default_cop = default_cop;
14389
14390   /* send it... */
14391   S (mp);
14392   /* Wait for the reply */
14393   W (ret);
14394   return ret;
14395 }
14396
14397 static int
14398 api_get_node_graph (vat_main_t * vam)
14399 {
14400   vl_api_get_node_graph_t *mp;
14401   int ret;
14402
14403   M (GET_NODE_GRAPH, mp);
14404
14405   /* send it... */
14406   S (mp);
14407   /* Wait for the reply */
14408   W (ret);
14409   return ret;
14410 }
14411
14412 /* *INDENT-OFF* */
14413 /** Used for parsing LISP eids */
14414 typedef CLIB_PACKED(struct{
14415   u8 addr[16];   /**< eid address */
14416   u32 len;       /**< prefix length if IP */
14417   u8 type;      /**< type of eid */
14418 }) lisp_eid_vat_t;
14419 /* *INDENT-ON* */
14420
14421 static uword
14422 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14423 {
14424   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14425
14426   memset (a, 0, sizeof (a[0]));
14427
14428   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14429     {
14430       a->type = 0;              /* ipv4 type */
14431     }
14432   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14433     {
14434       a->type = 1;              /* ipv6 type */
14435     }
14436   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14437     {
14438       a->type = 2;              /* mac type */
14439     }
14440   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14441     {
14442       a->type = 3;              /* NSH type */
14443       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14444       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14445     }
14446   else
14447     {
14448       return 0;
14449     }
14450
14451   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14452     {
14453       return 0;
14454     }
14455
14456   return 1;
14457 }
14458
14459 static int
14460 lisp_eid_size_vat (u8 type)
14461 {
14462   switch (type)
14463     {
14464     case 0:
14465       return 4;
14466     case 1:
14467       return 16;
14468     case 2:
14469       return 6;
14470     case 3:
14471       return 5;
14472     }
14473   return 0;
14474 }
14475
14476 static void
14477 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14478 {
14479   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14480 }
14481
14482 static int
14483 api_one_add_del_locator_set (vat_main_t * vam)
14484 {
14485   unformat_input_t *input = vam->input;
14486   vl_api_one_add_del_locator_set_t *mp;
14487   u8 is_add = 1;
14488   u8 *locator_set_name = NULL;
14489   u8 locator_set_name_set = 0;
14490   vl_api_local_locator_t locator, *locators = 0;
14491   u32 sw_if_index, priority, weight;
14492   u32 data_len = 0;
14493
14494   int ret;
14495   /* Parse args required to build the message */
14496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14497     {
14498       if (unformat (input, "del"))
14499         {
14500           is_add = 0;
14501         }
14502       else if (unformat (input, "locator-set %s", &locator_set_name))
14503         {
14504           locator_set_name_set = 1;
14505         }
14506       else if (unformat (input, "sw_if_index %u p %u w %u",
14507                          &sw_if_index, &priority, &weight))
14508         {
14509           locator.sw_if_index = htonl (sw_if_index);
14510           locator.priority = priority;
14511           locator.weight = weight;
14512           vec_add1 (locators, locator);
14513         }
14514       else
14515         if (unformat
14516             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14517              &sw_if_index, &priority, &weight))
14518         {
14519           locator.sw_if_index = htonl (sw_if_index);
14520           locator.priority = priority;
14521           locator.weight = weight;
14522           vec_add1 (locators, locator);
14523         }
14524       else
14525         break;
14526     }
14527
14528   if (locator_set_name_set == 0)
14529     {
14530       errmsg ("missing locator-set name");
14531       vec_free (locators);
14532       return -99;
14533     }
14534
14535   if (vec_len (locator_set_name) > 64)
14536     {
14537       errmsg ("locator-set name too long");
14538       vec_free (locator_set_name);
14539       vec_free (locators);
14540       return -99;
14541     }
14542   vec_add1 (locator_set_name, 0);
14543
14544   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14545
14546   /* Construct the API message */
14547   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14548
14549   mp->is_add = is_add;
14550   clib_memcpy (mp->locator_set_name, locator_set_name,
14551                vec_len (locator_set_name));
14552   vec_free (locator_set_name);
14553
14554   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14555   if (locators)
14556     clib_memcpy (mp->locators, locators, data_len);
14557   vec_free (locators);
14558
14559   /* send it... */
14560   S (mp);
14561
14562   /* Wait for a reply... */
14563   W (ret);
14564   return ret;
14565 }
14566
14567 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14568
14569 static int
14570 api_one_add_del_locator (vat_main_t * vam)
14571 {
14572   unformat_input_t *input = vam->input;
14573   vl_api_one_add_del_locator_t *mp;
14574   u32 tmp_if_index = ~0;
14575   u32 sw_if_index = ~0;
14576   u8 sw_if_index_set = 0;
14577   u8 sw_if_index_if_name_set = 0;
14578   u32 priority = ~0;
14579   u8 priority_set = 0;
14580   u32 weight = ~0;
14581   u8 weight_set = 0;
14582   u8 is_add = 1;
14583   u8 *locator_set_name = NULL;
14584   u8 locator_set_name_set = 0;
14585   int ret;
14586
14587   /* Parse args required to build the message */
14588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14589     {
14590       if (unformat (input, "del"))
14591         {
14592           is_add = 0;
14593         }
14594       else if (unformat (input, "locator-set %s", &locator_set_name))
14595         {
14596           locator_set_name_set = 1;
14597         }
14598       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14599                          &tmp_if_index))
14600         {
14601           sw_if_index_if_name_set = 1;
14602           sw_if_index = tmp_if_index;
14603         }
14604       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14605         {
14606           sw_if_index_set = 1;
14607           sw_if_index = tmp_if_index;
14608         }
14609       else if (unformat (input, "p %d", &priority))
14610         {
14611           priority_set = 1;
14612         }
14613       else if (unformat (input, "w %d", &weight))
14614         {
14615           weight_set = 1;
14616         }
14617       else
14618         break;
14619     }
14620
14621   if (locator_set_name_set == 0)
14622     {
14623       errmsg ("missing locator-set name");
14624       return -99;
14625     }
14626
14627   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14628     {
14629       errmsg ("missing sw_if_index");
14630       vec_free (locator_set_name);
14631       return -99;
14632     }
14633
14634   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14635     {
14636       errmsg ("cannot use both params interface name and sw_if_index");
14637       vec_free (locator_set_name);
14638       return -99;
14639     }
14640
14641   if (priority_set == 0)
14642     {
14643       errmsg ("missing locator-set priority");
14644       vec_free (locator_set_name);
14645       return -99;
14646     }
14647
14648   if (weight_set == 0)
14649     {
14650       errmsg ("missing locator-set weight");
14651       vec_free (locator_set_name);
14652       return -99;
14653     }
14654
14655   if (vec_len (locator_set_name) > 64)
14656     {
14657       errmsg ("locator-set name too long");
14658       vec_free (locator_set_name);
14659       return -99;
14660     }
14661   vec_add1 (locator_set_name, 0);
14662
14663   /* Construct the API message */
14664   M (ONE_ADD_DEL_LOCATOR, mp);
14665
14666   mp->is_add = is_add;
14667   mp->sw_if_index = ntohl (sw_if_index);
14668   mp->priority = priority;
14669   mp->weight = weight;
14670   clib_memcpy (mp->locator_set_name, locator_set_name,
14671                vec_len (locator_set_name));
14672   vec_free (locator_set_name);
14673
14674   /* send it... */
14675   S (mp);
14676
14677   /* Wait for a reply... */
14678   W (ret);
14679   return ret;
14680 }
14681
14682 #define api_lisp_add_del_locator api_one_add_del_locator
14683
14684 uword
14685 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14686 {
14687   u32 *key_id = va_arg (*args, u32 *);
14688   u8 *s = 0;
14689
14690   if (unformat (input, "%s", &s))
14691     {
14692       if (!strcmp ((char *) s, "sha1"))
14693         key_id[0] = HMAC_SHA_1_96;
14694       else if (!strcmp ((char *) s, "sha256"))
14695         key_id[0] = HMAC_SHA_256_128;
14696       else
14697         {
14698           clib_warning ("invalid key_id: '%s'", s);
14699           key_id[0] = HMAC_NO_KEY;
14700         }
14701     }
14702   else
14703     return 0;
14704
14705   vec_free (s);
14706   return 1;
14707 }
14708
14709 static int
14710 api_one_add_del_local_eid (vat_main_t * vam)
14711 {
14712   unformat_input_t *input = vam->input;
14713   vl_api_one_add_del_local_eid_t *mp;
14714   u8 is_add = 1;
14715   u8 eid_set = 0;
14716   lisp_eid_vat_t _eid, *eid = &_eid;
14717   u8 *locator_set_name = 0;
14718   u8 locator_set_name_set = 0;
14719   u32 vni = 0;
14720   u16 key_id = 0;
14721   u8 *key = 0;
14722   int ret;
14723
14724   /* Parse args required to build the message */
14725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14726     {
14727       if (unformat (input, "del"))
14728         {
14729           is_add = 0;
14730         }
14731       else if (unformat (input, "vni %d", &vni))
14732         {
14733           ;
14734         }
14735       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14736         {
14737           eid_set = 1;
14738         }
14739       else if (unformat (input, "locator-set %s", &locator_set_name))
14740         {
14741           locator_set_name_set = 1;
14742         }
14743       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14744         ;
14745       else if (unformat (input, "secret-key %_%v%_", &key))
14746         ;
14747       else
14748         break;
14749     }
14750
14751   if (locator_set_name_set == 0)
14752     {
14753       errmsg ("missing locator-set name");
14754       return -99;
14755     }
14756
14757   if (0 == eid_set)
14758     {
14759       errmsg ("EID address not set!");
14760       vec_free (locator_set_name);
14761       return -99;
14762     }
14763
14764   if (key && (0 == key_id))
14765     {
14766       errmsg ("invalid key_id!");
14767       return -99;
14768     }
14769
14770   if (vec_len (key) > 64)
14771     {
14772       errmsg ("key too long");
14773       vec_free (key);
14774       return -99;
14775     }
14776
14777   if (vec_len (locator_set_name) > 64)
14778     {
14779       errmsg ("locator-set name too long");
14780       vec_free (locator_set_name);
14781       return -99;
14782     }
14783   vec_add1 (locator_set_name, 0);
14784
14785   /* Construct the API message */
14786   M (ONE_ADD_DEL_LOCAL_EID, mp);
14787
14788   mp->is_add = is_add;
14789   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14790   mp->eid_type = eid->type;
14791   mp->prefix_len = eid->len;
14792   mp->vni = clib_host_to_net_u32 (vni);
14793   mp->key_id = clib_host_to_net_u16 (key_id);
14794   clib_memcpy (mp->locator_set_name, locator_set_name,
14795                vec_len (locator_set_name));
14796   clib_memcpy (mp->key, key, vec_len (key));
14797
14798   vec_free (locator_set_name);
14799   vec_free (key);
14800
14801   /* send it... */
14802   S (mp);
14803
14804   /* Wait for a reply... */
14805   W (ret);
14806   return ret;
14807 }
14808
14809 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14810
14811 static int
14812 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14813 {
14814   u32 dp_table = 0, vni = 0;;
14815   unformat_input_t *input = vam->input;
14816   vl_api_gpe_add_del_fwd_entry_t *mp;
14817   u8 is_add = 1;
14818   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14819   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14820   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14821   u32 action = ~0, w;
14822   ip4_address_t rmt_rloc4, lcl_rloc4;
14823   ip6_address_t rmt_rloc6, lcl_rloc6;
14824   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14825   int ret;
14826
14827   memset (&rloc, 0, sizeof (rloc));
14828
14829   /* Parse args required to build the message */
14830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14831     {
14832       if (unformat (input, "del"))
14833         is_add = 0;
14834       else if (unformat (input, "add"))
14835         is_add = 1;
14836       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14837         {
14838           rmt_eid_set = 1;
14839         }
14840       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14841         {
14842           lcl_eid_set = 1;
14843         }
14844       else if (unformat (input, "vrf %d", &dp_table))
14845         ;
14846       else if (unformat (input, "bd %d", &dp_table))
14847         ;
14848       else if (unformat (input, "vni %d", &vni))
14849         ;
14850       else if (unformat (input, "w %d", &w))
14851         {
14852           if (!curr_rloc)
14853             {
14854               errmsg ("No RLOC configured for setting priority/weight!");
14855               return -99;
14856             }
14857           curr_rloc->weight = w;
14858         }
14859       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14860                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14861         {
14862           rloc.is_ip4 = 1;
14863
14864           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14865           rloc.weight = 0;
14866           vec_add1 (lcl_locs, rloc);
14867
14868           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14869           vec_add1 (rmt_locs, rloc);
14870           /* weight saved in rmt loc */
14871           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14872         }
14873       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14874                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14875         {
14876           rloc.is_ip4 = 0;
14877           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14878           rloc.weight = 0;
14879           vec_add1 (lcl_locs, rloc);
14880
14881           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14882           vec_add1 (rmt_locs, rloc);
14883           /* weight saved in rmt loc */
14884           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14885         }
14886       else if (unformat (input, "action %d", &action))
14887         {
14888           ;
14889         }
14890       else
14891         {
14892           clib_warning ("parse error '%U'", format_unformat_error, input);
14893           return -99;
14894         }
14895     }
14896
14897   if (!rmt_eid_set)
14898     {
14899       errmsg ("remote eid addresses not set");
14900       return -99;
14901     }
14902
14903   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14904     {
14905       errmsg ("eid types don't match");
14906       return -99;
14907     }
14908
14909   if (0 == rmt_locs && (u32) ~ 0 == action)
14910     {
14911       errmsg ("action not set for negative mapping");
14912       return -99;
14913     }
14914
14915   /* Construct the API message */
14916   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14917       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14918
14919   mp->is_add = is_add;
14920   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14921   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14922   mp->eid_type = rmt_eid->type;
14923   mp->dp_table = clib_host_to_net_u32 (dp_table);
14924   mp->vni = clib_host_to_net_u32 (vni);
14925   mp->rmt_len = rmt_eid->len;
14926   mp->lcl_len = lcl_eid->len;
14927   mp->action = action;
14928
14929   if (0 != rmt_locs && 0 != lcl_locs)
14930     {
14931       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14932       clib_memcpy (mp->locs, lcl_locs,
14933                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14934
14935       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14936       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14937                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14938     }
14939   vec_free (lcl_locs);
14940   vec_free (rmt_locs);
14941
14942   /* send it... */
14943   S (mp);
14944
14945   /* Wait for a reply... */
14946   W (ret);
14947   return ret;
14948 }
14949
14950 static int
14951 api_one_add_del_map_server (vat_main_t * vam)
14952 {
14953   unformat_input_t *input = vam->input;
14954   vl_api_one_add_del_map_server_t *mp;
14955   u8 is_add = 1;
14956   u8 ipv4_set = 0;
14957   u8 ipv6_set = 0;
14958   ip4_address_t ipv4;
14959   ip6_address_t ipv6;
14960   int ret;
14961
14962   /* Parse args required to build the message */
14963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14964     {
14965       if (unformat (input, "del"))
14966         {
14967           is_add = 0;
14968         }
14969       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14970         {
14971           ipv4_set = 1;
14972         }
14973       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14974         {
14975           ipv6_set = 1;
14976         }
14977       else
14978         break;
14979     }
14980
14981   if (ipv4_set && ipv6_set)
14982     {
14983       errmsg ("both eid v4 and v6 addresses set");
14984       return -99;
14985     }
14986
14987   if (!ipv4_set && !ipv6_set)
14988     {
14989       errmsg ("eid addresses not set");
14990       return -99;
14991     }
14992
14993   /* Construct the API message */
14994   M (ONE_ADD_DEL_MAP_SERVER, mp);
14995
14996   mp->is_add = is_add;
14997   if (ipv6_set)
14998     {
14999       mp->is_ipv6 = 1;
15000       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15001     }
15002   else
15003     {
15004       mp->is_ipv6 = 0;
15005       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15006     }
15007
15008   /* send it... */
15009   S (mp);
15010
15011   /* Wait for a reply... */
15012   W (ret);
15013   return ret;
15014 }
15015
15016 #define api_lisp_add_del_map_server api_one_add_del_map_server
15017
15018 static int
15019 api_one_add_del_map_resolver (vat_main_t * vam)
15020 {
15021   unformat_input_t *input = vam->input;
15022   vl_api_one_add_del_map_resolver_t *mp;
15023   u8 is_add = 1;
15024   u8 ipv4_set = 0;
15025   u8 ipv6_set = 0;
15026   ip4_address_t ipv4;
15027   ip6_address_t ipv6;
15028   int ret;
15029
15030   /* Parse args required to build the message */
15031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15032     {
15033       if (unformat (input, "del"))
15034         {
15035           is_add = 0;
15036         }
15037       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15038         {
15039           ipv4_set = 1;
15040         }
15041       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15042         {
15043           ipv6_set = 1;
15044         }
15045       else
15046         break;
15047     }
15048
15049   if (ipv4_set && ipv6_set)
15050     {
15051       errmsg ("both eid v4 and v6 addresses set");
15052       return -99;
15053     }
15054
15055   if (!ipv4_set && !ipv6_set)
15056     {
15057       errmsg ("eid addresses not set");
15058       return -99;
15059     }
15060
15061   /* Construct the API message */
15062   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15063
15064   mp->is_add = is_add;
15065   if (ipv6_set)
15066     {
15067       mp->is_ipv6 = 1;
15068       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15069     }
15070   else
15071     {
15072       mp->is_ipv6 = 0;
15073       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15074     }
15075
15076   /* send it... */
15077   S (mp);
15078
15079   /* Wait for a reply... */
15080   W (ret);
15081   return ret;
15082 }
15083
15084 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15085
15086 static int
15087 api_lisp_gpe_enable_disable (vat_main_t * vam)
15088 {
15089   unformat_input_t *input = vam->input;
15090   vl_api_gpe_enable_disable_t *mp;
15091   u8 is_set = 0;
15092   u8 is_en = 1;
15093   int ret;
15094
15095   /* Parse args required to build the message */
15096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15097     {
15098       if (unformat (input, "enable"))
15099         {
15100           is_set = 1;
15101           is_en = 1;
15102         }
15103       else if (unformat (input, "disable"))
15104         {
15105           is_set = 1;
15106           is_en = 0;
15107         }
15108       else
15109         break;
15110     }
15111
15112   if (is_set == 0)
15113     {
15114       errmsg ("Value not set");
15115       return -99;
15116     }
15117
15118   /* Construct the API message */
15119   M (GPE_ENABLE_DISABLE, mp);
15120
15121   mp->is_en = is_en;
15122
15123   /* send it... */
15124   S (mp);
15125
15126   /* Wait for a reply... */
15127   W (ret);
15128   return ret;
15129 }
15130
15131 static int
15132 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15133 {
15134   unformat_input_t *input = vam->input;
15135   vl_api_one_rloc_probe_enable_disable_t *mp;
15136   u8 is_set = 0;
15137   u8 is_en = 0;
15138   int ret;
15139
15140   /* Parse args required to build the message */
15141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15142     {
15143       if (unformat (input, "enable"))
15144         {
15145           is_set = 1;
15146           is_en = 1;
15147         }
15148       else if (unformat (input, "disable"))
15149         is_set = 1;
15150       else
15151         break;
15152     }
15153
15154   if (!is_set)
15155     {
15156       errmsg ("Value not set");
15157       return -99;
15158     }
15159
15160   /* Construct the API message */
15161   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15162
15163   mp->is_enabled = is_en;
15164
15165   /* send it... */
15166   S (mp);
15167
15168   /* Wait for a reply... */
15169   W (ret);
15170   return ret;
15171 }
15172
15173 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15174
15175 static int
15176 api_one_map_register_enable_disable (vat_main_t * vam)
15177 {
15178   unformat_input_t *input = vam->input;
15179   vl_api_one_map_register_enable_disable_t *mp;
15180   u8 is_set = 0;
15181   u8 is_en = 0;
15182   int ret;
15183
15184   /* Parse args required to build the message */
15185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15186     {
15187       if (unformat (input, "enable"))
15188         {
15189           is_set = 1;
15190           is_en = 1;
15191         }
15192       else if (unformat (input, "disable"))
15193         is_set = 1;
15194       else
15195         break;
15196     }
15197
15198   if (!is_set)
15199     {
15200       errmsg ("Value not set");
15201       return -99;
15202     }
15203
15204   /* Construct the API message */
15205   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15206
15207   mp->is_enabled = is_en;
15208
15209   /* send it... */
15210   S (mp);
15211
15212   /* Wait for a reply... */
15213   W (ret);
15214   return ret;
15215 }
15216
15217 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15218
15219 static int
15220 api_one_enable_disable (vat_main_t * vam)
15221 {
15222   unformat_input_t *input = vam->input;
15223   vl_api_one_enable_disable_t *mp;
15224   u8 is_set = 0;
15225   u8 is_en = 0;
15226   int ret;
15227
15228   /* Parse args required to build the message */
15229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15230     {
15231       if (unformat (input, "enable"))
15232         {
15233           is_set = 1;
15234           is_en = 1;
15235         }
15236       else if (unformat (input, "disable"))
15237         {
15238           is_set = 1;
15239         }
15240       else
15241         break;
15242     }
15243
15244   if (!is_set)
15245     {
15246       errmsg ("Value not set");
15247       return -99;
15248     }
15249
15250   /* Construct the API message */
15251   M (ONE_ENABLE_DISABLE, mp);
15252
15253   mp->is_en = is_en;
15254
15255   /* send it... */
15256   S (mp);
15257
15258   /* Wait for a reply... */
15259   W (ret);
15260   return ret;
15261 }
15262
15263 #define api_lisp_enable_disable api_one_enable_disable
15264
15265 static int
15266 api_show_one_map_register_state (vat_main_t * vam)
15267 {
15268   vl_api_show_one_map_register_state_t *mp;
15269   int ret;
15270
15271   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15272
15273   /* send */
15274   S (mp);
15275
15276   /* wait for reply */
15277   W (ret);
15278   return ret;
15279 }
15280
15281 #define api_show_lisp_map_register_state api_show_one_map_register_state
15282
15283 static int
15284 api_show_one_rloc_probe_state (vat_main_t * vam)
15285 {
15286   vl_api_show_one_rloc_probe_state_t *mp;
15287   int ret;
15288
15289   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15290
15291   /* send */
15292   S (mp);
15293
15294   /* wait for reply */
15295   W (ret);
15296   return ret;
15297 }
15298
15299 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15300
15301 static int
15302 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15303 {
15304   vl_api_one_add_del_l2_arp_entry_t *mp;
15305   unformat_input_t *input = vam->input;
15306   u8 is_add = 1;
15307   u8 mac_set = 0;
15308   u8 bd_set = 0;
15309   u8 ip_set = 0;
15310   u8 mac[6] = { 0, };
15311   u32 ip4 = 0, bd = ~0;
15312   int ret;
15313
15314   /* Parse args required to build the message */
15315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15316     {
15317       if (unformat (input, "del"))
15318         is_add = 0;
15319       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15320         mac_set = 1;
15321       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15322         ip_set = 1;
15323       else if (unformat (input, "bd %d", &bd))
15324         bd_set = 1;
15325       else
15326         {
15327           errmsg ("parse error '%U'", format_unformat_error, input);
15328           return -99;
15329         }
15330     }
15331
15332   if (!bd_set || !ip_set || (!mac_set && is_add))
15333     {
15334       errmsg ("Missing BD, IP or MAC!");
15335       return -99;
15336     }
15337
15338   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15339   mp->is_add = is_add;
15340   clib_memcpy (mp->mac, mac, 6);
15341   mp->bd = clib_host_to_net_u32 (bd);
15342   mp->ip4 = ip4;
15343
15344   /* send */
15345   S (mp);
15346
15347   /* wait for reply */
15348   W (ret);
15349   return ret;
15350 }
15351
15352 static int
15353 api_one_l2_arp_bd_get (vat_main_t * vam)
15354 {
15355   vl_api_one_l2_arp_bd_get_t *mp;
15356   int ret;
15357
15358   M (ONE_L2_ARP_BD_GET, mp);
15359
15360   /* send */
15361   S (mp);
15362
15363   /* wait for reply */
15364   W (ret);
15365   return ret;
15366 }
15367
15368 static int
15369 api_one_l2_arp_entries_get (vat_main_t * vam)
15370 {
15371   vl_api_one_l2_arp_entries_get_t *mp;
15372   unformat_input_t *input = vam->input;
15373   u8 bd_set = 0;
15374   u32 bd = ~0;
15375   int ret;
15376
15377   /* Parse args required to build the message */
15378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15379     {
15380       if (unformat (input, "bd %d", &bd))
15381         bd_set = 1;
15382       else
15383         {
15384           errmsg ("parse error '%U'", format_unformat_error, input);
15385           return -99;
15386         }
15387     }
15388
15389   if (!bd_set)
15390     {
15391       errmsg ("Expected bridge domain!");
15392       return -99;
15393     }
15394
15395   M (ONE_L2_ARP_ENTRIES_GET, mp);
15396   mp->bd = clib_host_to_net_u32 (bd);
15397
15398   /* send */
15399   S (mp);
15400
15401   /* wait for reply */
15402   W (ret);
15403   return ret;
15404 }
15405
15406 static int
15407 api_one_stats_enable_disable (vat_main_t * vam)
15408 {
15409   vl_api_one_stats_enable_disable_t *mp;
15410   unformat_input_t *input = vam->input;
15411   u8 is_set = 0;
15412   u8 is_en = 0;
15413   int ret;
15414
15415   /* Parse args required to build the message */
15416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15417     {
15418       if (unformat (input, "enable"))
15419         {
15420           is_set = 1;
15421           is_en = 1;
15422         }
15423       else if (unformat (input, "disable"))
15424         {
15425           is_set = 1;
15426         }
15427       else
15428         break;
15429     }
15430
15431   if (!is_set)
15432     {
15433       errmsg ("Value not set");
15434       return -99;
15435     }
15436
15437   M (ONE_STATS_ENABLE_DISABLE, mp);
15438   mp->is_en = is_en;
15439
15440   /* send */
15441   S (mp);
15442
15443   /* wait for reply */
15444   W (ret);
15445   return ret;
15446 }
15447
15448 static int
15449 api_show_one_stats_enable_disable (vat_main_t * vam)
15450 {
15451   vl_api_show_one_stats_enable_disable_t *mp;
15452   int ret;
15453
15454   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15455
15456   /* send */
15457   S (mp);
15458
15459   /* wait for reply */
15460   W (ret);
15461   return ret;
15462 }
15463
15464 static int
15465 api_show_one_map_request_mode (vat_main_t * vam)
15466 {
15467   vl_api_show_one_map_request_mode_t *mp;
15468   int ret;
15469
15470   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15471
15472   /* send */
15473   S (mp);
15474
15475   /* wait for reply */
15476   W (ret);
15477   return ret;
15478 }
15479
15480 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15481
15482 static int
15483 api_one_map_request_mode (vat_main_t * vam)
15484 {
15485   unformat_input_t *input = vam->input;
15486   vl_api_one_map_request_mode_t *mp;
15487   u8 mode = 0;
15488   int ret;
15489
15490   /* Parse args required to build the message */
15491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15492     {
15493       if (unformat (input, "dst-only"))
15494         mode = 0;
15495       else if (unformat (input, "src-dst"))
15496         mode = 1;
15497       else
15498         {
15499           errmsg ("parse error '%U'", format_unformat_error, input);
15500           return -99;
15501         }
15502     }
15503
15504   M (ONE_MAP_REQUEST_MODE, mp);
15505
15506   mp->mode = mode;
15507
15508   /* send */
15509   S (mp);
15510
15511   /* wait for reply */
15512   W (ret);
15513   return ret;
15514 }
15515
15516 #define api_lisp_map_request_mode api_one_map_request_mode
15517
15518 /**
15519  * Enable/disable ONE proxy ITR.
15520  *
15521  * @param vam vpp API test context
15522  * @return return code
15523  */
15524 static int
15525 api_one_pitr_set_locator_set (vat_main_t * vam)
15526 {
15527   u8 ls_name_set = 0;
15528   unformat_input_t *input = vam->input;
15529   vl_api_one_pitr_set_locator_set_t *mp;
15530   u8 is_add = 1;
15531   u8 *ls_name = 0;
15532   int ret;
15533
15534   /* Parse args required to build the message */
15535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15536     {
15537       if (unformat (input, "del"))
15538         is_add = 0;
15539       else if (unformat (input, "locator-set %s", &ls_name))
15540         ls_name_set = 1;
15541       else
15542         {
15543           errmsg ("parse error '%U'", format_unformat_error, input);
15544           return -99;
15545         }
15546     }
15547
15548   if (!ls_name_set)
15549     {
15550       errmsg ("locator-set name not set!");
15551       return -99;
15552     }
15553
15554   M (ONE_PITR_SET_LOCATOR_SET, mp);
15555
15556   mp->is_add = is_add;
15557   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15558   vec_free (ls_name);
15559
15560   /* send */
15561   S (mp);
15562
15563   /* wait for reply */
15564   W (ret);
15565   return ret;
15566 }
15567
15568 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15569
15570 static int
15571 api_one_nsh_set_locator_set (vat_main_t * vam)
15572 {
15573   u8 ls_name_set = 0;
15574   unformat_input_t *input = vam->input;
15575   vl_api_one_nsh_set_locator_set_t *mp;
15576   u8 is_add = 1;
15577   u8 *ls_name = 0;
15578   int ret;
15579
15580   /* Parse args required to build the message */
15581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15582     {
15583       if (unformat (input, "del"))
15584         is_add = 0;
15585       else if (unformat (input, "ls %s", &ls_name))
15586         ls_name_set = 1;
15587       else
15588         {
15589           errmsg ("parse error '%U'", format_unformat_error, input);
15590           return -99;
15591         }
15592     }
15593
15594   if (!ls_name_set && is_add)
15595     {
15596       errmsg ("locator-set name not set!");
15597       return -99;
15598     }
15599
15600   M (ONE_NSH_SET_LOCATOR_SET, mp);
15601
15602   mp->is_add = is_add;
15603   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15604   vec_free (ls_name);
15605
15606   /* send */
15607   S (mp);
15608
15609   /* wait for reply */
15610   W (ret);
15611   return ret;
15612 }
15613
15614 static int
15615 api_show_one_pitr (vat_main_t * vam)
15616 {
15617   vl_api_show_one_pitr_t *mp;
15618   int ret;
15619
15620   if (!vam->json_output)
15621     {
15622       print (vam->ofp, "%=20s", "lisp status:");
15623     }
15624
15625   M (SHOW_ONE_PITR, mp);
15626   /* send it... */
15627   S (mp);
15628
15629   /* Wait for a reply... */
15630   W (ret);
15631   return ret;
15632 }
15633
15634 #define api_show_lisp_pitr api_show_one_pitr
15635
15636 static int
15637 api_one_use_petr (vat_main_t * vam)
15638 {
15639   unformat_input_t *input = vam->input;
15640   vl_api_one_use_petr_t *mp;
15641   u8 is_add = 0;
15642   ip_address_t ip;
15643   int ret;
15644
15645   memset (&ip, 0, sizeof (ip));
15646
15647   /* Parse args required to build the message */
15648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15649     {
15650       if (unformat (input, "disable"))
15651         is_add = 0;
15652       else
15653         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15654         {
15655           is_add = 1;
15656           ip_addr_version (&ip) = IP4;
15657         }
15658       else
15659         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15660         {
15661           is_add = 1;
15662           ip_addr_version (&ip) = IP6;
15663         }
15664       else
15665         {
15666           errmsg ("parse error '%U'", format_unformat_error, input);
15667           return -99;
15668         }
15669     }
15670
15671   M (ONE_USE_PETR, mp);
15672
15673   mp->is_add = is_add;
15674   if (is_add)
15675     {
15676       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15677       if (mp->is_ip4)
15678         clib_memcpy (mp->address, &ip, 4);
15679       else
15680         clib_memcpy (mp->address, &ip, 16);
15681     }
15682
15683   /* send */
15684   S (mp);
15685
15686   /* wait for reply */
15687   W (ret);
15688   return ret;
15689 }
15690
15691 #define api_lisp_use_petr api_one_use_petr
15692
15693 static int
15694 api_show_one_nsh_mapping (vat_main_t * vam)
15695 {
15696   vl_api_show_one_use_petr_t *mp;
15697   int ret;
15698
15699   if (!vam->json_output)
15700     {
15701       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15702     }
15703
15704   M (SHOW_ONE_NSH_MAPPING, mp);
15705   /* send it... */
15706   S (mp);
15707
15708   /* Wait for a reply... */
15709   W (ret);
15710   return ret;
15711 }
15712
15713 static int
15714 api_show_one_use_petr (vat_main_t * vam)
15715 {
15716   vl_api_show_one_use_petr_t *mp;
15717   int ret;
15718
15719   if (!vam->json_output)
15720     {
15721       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15722     }
15723
15724   M (SHOW_ONE_USE_PETR, mp);
15725   /* send it... */
15726   S (mp);
15727
15728   /* Wait for a reply... */
15729   W (ret);
15730   return ret;
15731 }
15732
15733 #define api_show_lisp_use_petr api_show_one_use_petr
15734
15735 /**
15736  * Add/delete mapping between vni and vrf
15737  */
15738 static int
15739 api_one_eid_table_add_del_map (vat_main_t * vam)
15740 {
15741   unformat_input_t *input = vam->input;
15742   vl_api_one_eid_table_add_del_map_t *mp;
15743   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15744   u32 vni, vrf, bd_index;
15745   int ret;
15746
15747   /* Parse args required to build the message */
15748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15749     {
15750       if (unformat (input, "del"))
15751         is_add = 0;
15752       else if (unformat (input, "vrf %d", &vrf))
15753         vrf_set = 1;
15754       else if (unformat (input, "bd_index %d", &bd_index))
15755         bd_index_set = 1;
15756       else if (unformat (input, "vni %d", &vni))
15757         vni_set = 1;
15758       else
15759         break;
15760     }
15761
15762   if (!vni_set || (!vrf_set && !bd_index_set))
15763     {
15764       errmsg ("missing arguments!");
15765       return -99;
15766     }
15767
15768   if (vrf_set && bd_index_set)
15769     {
15770       errmsg ("error: both vrf and bd entered!");
15771       return -99;
15772     }
15773
15774   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15775
15776   mp->is_add = is_add;
15777   mp->vni = htonl (vni);
15778   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15779   mp->is_l2 = bd_index_set;
15780
15781   /* send */
15782   S (mp);
15783
15784   /* wait for reply */
15785   W (ret);
15786   return ret;
15787 }
15788
15789 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15790
15791 uword
15792 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15793 {
15794   u32 *action = va_arg (*args, u32 *);
15795   u8 *s = 0;
15796
15797   if (unformat (input, "%s", &s))
15798     {
15799       if (!strcmp ((char *) s, "no-action"))
15800         action[0] = 0;
15801       else if (!strcmp ((char *) s, "natively-forward"))
15802         action[0] = 1;
15803       else if (!strcmp ((char *) s, "send-map-request"))
15804         action[0] = 2;
15805       else if (!strcmp ((char *) s, "drop"))
15806         action[0] = 3;
15807       else
15808         {
15809           clib_warning ("invalid action: '%s'", s);
15810           action[0] = 3;
15811         }
15812     }
15813   else
15814     return 0;
15815
15816   vec_free (s);
15817   return 1;
15818 }
15819
15820 /**
15821  * Add/del remote mapping to/from ONE control plane
15822  *
15823  * @param vam vpp API test context
15824  * @return return code
15825  */
15826 static int
15827 api_one_add_del_remote_mapping (vat_main_t * vam)
15828 {
15829   unformat_input_t *input = vam->input;
15830   vl_api_one_add_del_remote_mapping_t *mp;
15831   u32 vni = 0;
15832   lisp_eid_vat_t _eid, *eid = &_eid;
15833   lisp_eid_vat_t _seid, *seid = &_seid;
15834   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15835   u32 action = ~0, p, w, data_len;
15836   ip4_address_t rloc4;
15837   ip6_address_t rloc6;
15838   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15839   int ret;
15840
15841   memset (&rloc, 0, sizeof (rloc));
15842
15843   /* Parse args required to build the message */
15844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15845     {
15846       if (unformat (input, "del-all"))
15847         {
15848           del_all = 1;
15849         }
15850       else if (unformat (input, "del"))
15851         {
15852           is_add = 0;
15853         }
15854       else if (unformat (input, "add"))
15855         {
15856           is_add = 1;
15857         }
15858       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15859         {
15860           eid_set = 1;
15861         }
15862       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15863         {
15864           seid_set = 1;
15865         }
15866       else if (unformat (input, "vni %d", &vni))
15867         {
15868           ;
15869         }
15870       else if (unformat (input, "p %d w %d", &p, &w))
15871         {
15872           if (!curr_rloc)
15873             {
15874               errmsg ("No RLOC configured for setting priority/weight!");
15875               return -99;
15876             }
15877           curr_rloc->priority = p;
15878           curr_rloc->weight = w;
15879         }
15880       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15881         {
15882           rloc.is_ip4 = 1;
15883           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15884           vec_add1 (rlocs, rloc);
15885           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15886         }
15887       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15888         {
15889           rloc.is_ip4 = 0;
15890           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15891           vec_add1 (rlocs, rloc);
15892           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15893         }
15894       else if (unformat (input, "action %U",
15895                          unformat_negative_mapping_action, &action))
15896         {
15897           ;
15898         }
15899       else
15900         {
15901           clib_warning ("parse error '%U'", format_unformat_error, input);
15902           return -99;
15903         }
15904     }
15905
15906   if (0 == eid_set)
15907     {
15908       errmsg ("missing params!");
15909       return -99;
15910     }
15911
15912   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15913     {
15914       errmsg ("no action set for negative map-reply!");
15915       return -99;
15916     }
15917
15918   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15919
15920   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15921   mp->is_add = is_add;
15922   mp->vni = htonl (vni);
15923   mp->action = (u8) action;
15924   mp->is_src_dst = seid_set;
15925   mp->eid_len = eid->len;
15926   mp->seid_len = seid->len;
15927   mp->del_all = del_all;
15928   mp->eid_type = eid->type;
15929   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15930   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15931
15932   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15933   clib_memcpy (mp->rlocs, rlocs, data_len);
15934   vec_free (rlocs);
15935
15936   /* send it... */
15937   S (mp);
15938
15939   /* Wait for a reply... */
15940   W (ret);
15941   return ret;
15942 }
15943
15944 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15945
15946 /**
15947  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15948  * forwarding entries in data-plane accordingly.
15949  *
15950  * @param vam vpp API test context
15951  * @return return code
15952  */
15953 static int
15954 api_one_add_del_adjacency (vat_main_t * vam)
15955 {
15956   unformat_input_t *input = vam->input;
15957   vl_api_one_add_del_adjacency_t *mp;
15958   u32 vni = 0;
15959   ip4_address_t leid4, reid4;
15960   ip6_address_t leid6, reid6;
15961   u8 reid_mac[6] = { 0 };
15962   u8 leid_mac[6] = { 0 };
15963   u8 reid_type, leid_type;
15964   u32 leid_len = 0, reid_len = 0, len;
15965   u8 is_add = 1;
15966   int ret;
15967
15968   leid_type = reid_type = (u8) ~ 0;
15969
15970   /* Parse args required to build the message */
15971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15972     {
15973       if (unformat (input, "del"))
15974         {
15975           is_add = 0;
15976         }
15977       else if (unformat (input, "add"))
15978         {
15979           is_add = 1;
15980         }
15981       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15982                          &reid4, &len))
15983         {
15984           reid_type = 0;        /* ipv4 */
15985           reid_len = len;
15986         }
15987       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15988                          &reid6, &len))
15989         {
15990           reid_type = 1;        /* ipv6 */
15991           reid_len = len;
15992         }
15993       else if (unformat (input, "reid %U", unformat_ethernet_address,
15994                          reid_mac))
15995         {
15996           reid_type = 2;        /* mac */
15997         }
15998       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15999                          &leid4, &len))
16000         {
16001           leid_type = 0;        /* ipv4 */
16002           leid_len = len;
16003         }
16004       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16005                          &leid6, &len))
16006         {
16007           leid_type = 1;        /* ipv6 */
16008           leid_len = len;
16009         }
16010       else if (unformat (input, "leid %U", unformat_ethernet_address,
16011                          leid_mac))
16012         {
16013           leid_type = 2;        /* mac */
16014         }
16015       else if (unformat (input, "vni %d", &vni))
16016         {
16017           ;
16018         }
16019       else
16020         {
16021           errmsg ("parse error '%U'", format_unformat_error, input);
16022           return -99;
16023         }
16024     }
16025
16026   if ((u8) ~ 0 == reid_type)
16027     {
16028       errmsg ("missing params!");
16029       return -99;
16030     }
16031
16032   if (leid_type != reid_type)
16033     {
16034       errmsg ("remote and local EIDs are of different types!");
16035       return -99;
16036     }
16037
16038   M (ONE_ADD_DEL_ADJACENCY, mp);
16039   mp->is_add = is_add;
16040   mp->vni = htonl (vni);
16041   mp->leid_len = leid_len;
16042   mp->reid_len = reid_len;
16043   mp->eid_type = reid_type;
16044
16045   switch (mp->eid_type)
16046     {
16047     case 0:
16048       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16049       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16050       break;
16051     case 1:
16052       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16053       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16054       break;
16055     case 2:
16056       clib_memcpy (mp->leid, leid_mac, 6);
16057       clib_memcpy (mp->reid, reid_mac, 6);
16058       break;
16059     default:
16060       errmsg ("unknown EID type %d!", mp->eid_type);
16061       return 0;
16062     }
16063
16064   /* send it... */
16065   S (mp);
16066
16067   /* Wait for a reply... */
16068   W (ret);
16069   return ret;
16070 }
16071
16072 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16073
16074 uword
16075 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16076 {
16077   u32 *mode = va_arg (*args, u32 *);
16078
16079   if (unformat (input, "lisp"))
16080     *mode = 0;
16081   else if (unformat (input, "vxlan"))
16082     *mode = 1;
16083   else
16084     return 0;
16085
16086   return 1;
16087 }
16088
16089 static int
16090 api_gpe_get_encap_mode (vat_main_t * vam)
16091 {
16092   vl_api_gpe_get_encap_mode_t *mp;
16093   int ret;
16094
16095   /* Construct the API message */
16096   M (GPE_GET_ENCAP_MODE, mp);
16097
16098   /* send it... */
16099   S (mp);
16100
16101   /* Wait for a reply... */
16102   W (ret);
16103   return ret;
16104 }
16105
16106 static int
16107 api_gpe_set_encap_mode (vat_main_t * vam)
16108 {
16109   unformat_input_t *input = vam->input;
16110   vl_api_gpe_set_encap_mode_t *mp;
16111   int ret;
16112   u32 mode = 0;
16113
16114   /* Parse args required to build the message */
16115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16116     {
16117       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16118         ;
16119       else
16120         break;
16121     }
16122
16123   /* Construct the API message */
16124   M (GPE_SET_ENCAP_MODE, mp);
16125
16126   mp->mode = mode;
16127
16128   /* send it... */
16129   S (mp);
16130
16131   /* Wait for a reply... */
16132   W (ret);
16133   return ret;
16134 }
16135
16136 static int
16137 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16138 {
16139   unformat_input_t *input = vam->input;
16140   vl_api_gpe_add_del_iface_t *mp;
16141   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16142   u32 dp_table = 0, vni = 0;
16143   int ret;
16144
16145   /* Parse args required to build the message */
16146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16147     {
16148       if (unformat (input, "up"))
16149         {
16150           action_set = 1;
16151           is_add = 1;
16152         }
16153       else if (unformat (input, "down"))
16154         {
16155           action_set = 1;
16156           is_add = 0;
16157         }
16158       else if (unformat (input, "table_id %d", &dp_table))
16159         {
16160           dp_table_set = 1;
16161         }
16162       else if (unformat (input, "bd_id %d", &dp_table))
16163         {
16164           dp_table_set = 1;
16165           is_l2 = 1;
16166         }
16167       else if (unformat (input, "vni %d", &vni))
16168         {
16169           vni_set = 1;
16170         }
16171       else
16172         break;
16173     }
16174
16175   if (action_set == 0)
16176     {
16177       errmsg ("Action not set");
16178       return -99;
16179     }
16180   if (dp_table_set == 0 || vni_set == 0)
16181     {
16182       errmsg ("vni and dp_table must be set");
16183       return -99;
16184     }
16185
16186   /* Construct the API message */
16187   M (GPE_ADD_DEL_IFACE, mp);
16188
16189   mp->is_add = is_add;
16190   mp->dp_table = clib_host_to_net_u32 (dp_table);
16191   mp->is_l2 = is_l2;
16192   mp->vni = clib_host_to_net_u32 (vni);
16193
16194   /* send it... */
16195   S (mp);
16196
16197   /* Wait for a reply... */
16198   W (ret);
16199   return ret;
16200 }
16201
16202 static int
16203 api_one_map_register_fallback_threshold (vat_main_t * vam)
16204 {
16205   unformat_input_t *input = vam->input;
16206   vl_api_one_map_register_fallback_threshold_t *mp;
16207   u32 value = 0;
16208   u8 is_set = 0;
16209   int ret;
16210
16211   /* Parse args required to build the message */
16212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16213     {
16214       if (unformat (input, "%u", &value))
16215         is_set = 1;
16216       else
16217         {
16218           clib_warning ("parse error '%U'", format_unformat_error, input);
16219           return -99;
16220         }
16221     }
16222
16223   if (!is_set)
16224     {
16225       errmsg ("fallback threshold value is missing!");
16226       return -99;
16227     }
16228
16229   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16230   mp->value = clib_host_to_net_u32 (value);
16231
16232   /* send it... */
16233   S (mp);
16234
16235   /* Wait for a reply... */
16236   W (ret);
16237   return ret;
16238 }
16239
16240 static int
16241 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16242 {
16243   vl_api_show_one_map_register_fallback_threshold_t *mp;
16244   int ret;
16245
16246   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16247
16248   /* send it... */
16249   S (mp);
16250
16251   /* Wait for a reply... */
16252   W (ret);
16253   return ret;
16254 }
16255
16256 static int
16257 api_one_map_register_set_ttl (vat_main_t * vam)
16258 {
16259   unformat_input_t *input = vam->input;
16260   vl_api_one_map_register_set_ttl_t *mp;
16261   u32 ttl = 0;
16262   u8 is_set = 0;
16263   int ret;
16264
16265   /* Parse args required to build the message */
16266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16267     {
16268       if (unformat (input, "%u", &ttl))
16269         is_set = 1;
16270       else
16271         {
16272           clib_warning ("parse error '%U'", format_unformat_error, input);
16273           return -99;
16274         }
16275     }
16276
16277   if (!is_set)
16278     {
16279       errmsg ("TTL value missing!");
16280       return -99;
16281     }
16282
16283   M (ONE_MAP_REGISTER_SET_TTL, mp);
16284   mp->ttl = clib_host_to_net_u32 (ttl);
16285
16286   /* send it... */
16287   S (mp);
16288
16289   /* Wait for a reply... */
16290   W (ret);
16291   return ret;
16292 }
16293
16294 static int
16295 api_show_one_map_register_ttl (vat_main_t * vam)
16296 {
16297   vl_api_show_one_map_register_ttl_t *mp;
16298   int ret;
16299
16300   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16301
16302   /* send it... */
16303   S (mp);
16304
16305   /* Wait for a reply... */
16306   W (ret);
16307   return ret;
16308 }
16309
16310 /**
16311  * Add/del map request itr rlocs from ONE control plane and updates
16312  *
16313  * @param vam vpp API test context
16314  * @return return code
16315  */
16316 static int
16317 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16318 {
16319   unformat_input_t *input = vam->input;
16320   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16321   u8 *locator_set_name = 0;
16322   u8 locator_set_name_set = 0;
16323   u8 is_add = 1;
16324   int ret;
16325
16326   /* Parse args required to build the message */
16327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16328     {
16329       if (unformat (input, "del"))
16330         {
16331           is_add = 0;
16332         }
16333       else if (unformat (input, "%_%v%_", &locator_set_name))
16334         {
16335           locator_set_name_set = 1;
16336         }
16337       else
16338         {
16339           clib_warning ("parse error '%U'", format_unformat_error, input);
16340           return -99;
16341         }
16342     }
16343
16344   if (is_add && !locator_set_name_set)
16345     {
16346       errmsg ("itr-rloc is not set!");
16347       return -99;
16348     }
16349
16350   if (is_add && vec_len (locator_set_name) > 64)
16351     {
16352       errmsg ("itr-rloc locator-set name too long");
16353       vec_free (locator_set_name);
16354       return -99;
16355     }
16356
16357   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16358   mp->is_add = is_add;
16359   if (is_add)
16360     {
16361       clib_memcpy (mp->locator_set_name, locator_set_name,
16362                    vec_len (locator_set_name));
16363     }
16364   else
16365     {
16366       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16367     }
16368   vec_free (locator_set_name);
16369
16370   /* send it... */
16371   S (mp);
16372
16373   /* Wait for a reply... */
16374   W (ret);
16375   return ret;
16376 }
16377
16378 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16379
16380 static int
16381 api_one_locator_dump (vat_main_t * vam)
16382 {
16383   unformat_input_t *input = vam->input;
16384   vl_api_one_locator_dump_t *mp;
16385   vl_api_control_ping_t *mp_ping;
16386   u8 is_index_set = 0, is_name_set = 0;
16387   u8 *ls_name = 0;
16388   u32 ls_index = ~0;
16389   int ret;
16390
16391   /* Parse args required to build the message */
16392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16393     {
16394       if (unformat (input, "ls_name %_%v%_", &ls_name))
16395         {
16396           is_name_set = 1;
16397         }
16398       else if (unformat (input, "ls_index %d", &ls_index))
16399         {
16400           is_index_set = 1;
16401         }
16402       else
16403         {
16404           errmsg ("parse error '%U'", format_unformat_error, input);
16405           return -99;
16406         }
16407     }
16408
16409   if (!is_index_set && !is_name_set)
16410     {
16411       errmsg ("error: expected one of index or name!");
16412       return -99;
16413     }
16414
16415   if (is_index_set && is_name_set)
16416     {
16417       errmsg ("error: only one param expected!");
16418       return -99;
16419     }
16420
16421   if (vec_len (ls_name) > 62)
16422     {
16423       errmsg ("error: locator set name too long!");
16424       return -99;
16425     }
16426
16427   if (!vam->json_output)
16428     {
16429       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16430     }
16431
16432   M (ONE_LOCATOR_DUMP, mp);
16433   mp->is_index_set = is_index_set;
16434
16435   if (is_index_set)
16436     mp->ls_index = clib_host_to_net_u32 (ls_index);
16437   else
16438     {
16439       vec_add1 (ls_name, 0);
16440       strncpy ((char *) mp->ls_name, (char *) ls_name,
16441                sizeof (mp->ls_name) - 1);
16442     }
16443
16444   /* send it... */
16445   S (mp);
16446
16447   /* Use a control ping for synchronization */
16448   M (CONTROL_PING, mp_ping);
16449   S (mp_ping);
16450
16451   /* Wait for a reply... */
16452   W (ret);
16453   return ret;
16454 }
16455
16456 #define api_lisp_locator_dump api_one_locator_dump
16457
16458 static int
16459 api_one_locator_set_dump (vat_main_t * vam)
16460 {
16461   vl_api_one_locator_set_dump_t *mp;
16462   vl_api_control_ping_t *mp_ping;
16463   unformat_input_t *input = vam->input;
16464   u8 filter = 0;
16465   int ret;
16466
16467   /* Parse args required to build the message */
16468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16469     {
16470       if (unformat (input, "local"))
16471         {
16472           filter = 1;
16473         }
16474       else if (unformat (input, "remote"))
16475         {
16476           filter = 2;
16477         }
16478       else
16479         {
16480           errmsg ("parse error '%U'", format_unformat_error, input);
16481           return -99;
16482         }
16483     }
16484
16485   if (!vam->json_output)
16486     {
16487       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16488     }
16489
16490   M (ONE_LOCATOR_SET_DUMP, mp);
16491
16492   mp->filter = filter;
16493
16494   /* send it... */
16495   S (mp);
16496
16497   /* Use a control ping for synchronization */
16498   M (CONTROL_PING, mp_ping);
16499   S (mp_ping);
16500
16501   /* Wait for a reply... */
16502   W (ret);
16503   return ret;
16504 }
16505
16506 #define api_lisp_locator_set_dump api_one_locator_set_dump
16507
16508 static int
16509 api_one_eid_table_map_dump (vat_main_t * vam)
16510 {
16511   u8 is_l2 = 0;
16512   u8 mode_set = 0;
16513   unformat_input_t *input = vam->input;
16514   vl_api_one_eid_table_map_dump_t *mp;
16515   vl_api_control_ping_t *mp_ping;
16516   int ret;
16517
16518   /* Parse args required to build the message */
16519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16520     {
16521       if (unformat (input, "l2"))
16522         {
16523           is_l2 = 1;
16524           mode_set = 1;
16525         }
16526       else if (unformat (input, "l3"))
16527         {
16528           is_l2 = 0;
16529           mode_set = 1;
16530         }
16531       else
16532         {
16533           errmsg ("parse error '%U'", format_unformat_error, input);
16534           return -99;
16535         }
16536     }
16537
16538   if (!mode_set)
16539     {
16540       errmsg ("expected one of 'l2' or 'l3' parameter!");
16541       return -99;
16542     }
16543
16544   if (!vam->json_output)
16545     {
16546       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16547     }
16548
16549   M (ONE_EID_TABLE_MAP_DUMP, mp);
16550   mp->is_l2 = is_l2;
16551
16552   /* send it... */
16553   S (mp);
16554
16555   /* Use a control ping for synchronization */
16556   M (CONTROL_PING, mp_ping);
16557   S (mp_ping);
16558
16559   /* Wait for a reply... */
16560   W (ret);
16561   return ret;
16562 }
16563
16564 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16565
16566 static int
16567 api_one_eid_table_vni_dump (vat_main_t * vam)
16568 {
16569   vl_api_one_eid_table_vni_dump_t *mp;
16570   vl_api_control_ping_t *mp_ping;
16571   int ret;
16572
16573   if (!vam->json_output)
16574     {
16575       print (vam->ofp, "VNI");
16576     }
16577
16578   M (ONE_EID_TABLE_VNI_DUMP, mp);
16579
16580   /* send it... */
16581   S (mp);
16582
16583   /* Use a control ping for synchronization */
16584   M (CONTROL_PING, mp_ping);
16585   S (mp_ping);
16586
16587   /* Wait for a reply... */
16588   W (ret);
16589   return ret;
16590 }
16591
16592 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16593
16594 static int
16595 api_one_eid_table_dump (vat_main_t * vam)
16596 {
16597   unformat_input_t *i = vam->input;
16598   vl_api_one_eid_table_dump_t *mp;
16599   vl_api_control_ping_t *mp_ping;
16600   struct in_addr ip4;
16601   struct in6_addr ip6;
16602   u8 mac[6];
16603   u8 eid_type = ~0, eid_set = 0;
16604   u32 prefix_length = ~0, t, vni = 0;
16605   u8 filter = 0;
16606   int ret;
16607   lisp_nsh_api_t nsh;
16608
16609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16610     {
16611       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16612         {
16613           eid_set = 1;
16614           eid_type = 0;
16615           prefix_length = t;
16616         }
16617       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16618         {
16619           eid_set = 1;
16620           eid_type = 1;
16621           prefix_length = t;
16622         }
16623       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16624         {
16625           eid_set = 1;
16626           eid_type = 2;
16627         }
16628       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16629         {
16630           eid_set = 1;
16631           eid_type = 3;
16632         }
16633       else if (unformat (i, "vni %d", &t))
16634         {
16635           vni = t;
16636         }
16637       else if (unformat (i, "local"))
16638         {
16639           filter = 1;
16640         }
16641       else if (unformat (i, "remote"))
16642         {
16643           filter = 2;
16644         }
16645       else
16646         {
16647           errmsg ("parse error '%U'", format_unformat_error, i);
16648           return -99;
16649         }
16650     }
16651
16652   if (!vam->json_output)
16653     {
16654       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16655              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16656     }
16657
16658   M (ONE_EID_TABLE_DUMP, mp);
16659
16660   mp->filter = filter;
16661   if (eid_set)
16662     {
16663       mp->eid_set = 1;
16664       mp->vni = htonl (vni);
16665       mp->eid_type = eid_type;
16666       switch (eid_type)
16667         {
16668         case 0:
16669           mp->prefix_length = prefix_length;
16670           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16671           break;
16672         case 1:
16673           mp->prefix_length = prefix_length;
16674           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16675           break;
16676         case 2:
16677           clib_memcpy (mp->eid, mac, sizeof (mac));
16678           break;
16679         case 3:
16680           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16681           break;
16682         default:
16683           errmsg ("unknown EID type %d!", eid_type);
16684           return -99;
16685         }
16686     }
16687
16688   /* send it... */
16689   S (mp);
16690
16691   /* Use a control ping for synchronization */
16692   M (CONTROL_PING, mp_ping);
16693   S (mp_ping);
16694
16695   /* Wait for a reply... */
16696   W (ret);
16697   return ret;
16698 }
16699
16700 #define api_lisp_eid_table_dump api_one_eid_table_dump
16701
16702 static int
16703 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16704 {
16705   unformat_input_t *i = vam->input;
16706   vl_api_gpe_fwd_entries_get_t *mp;
16707   u8 vni_set = 0;
16708   u32 vni = ~0;
16709   int ret;
16710
16711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16712     {
16713       if (unformat (i, "vni %d", &vni))
16714         {
16715           vni_set = 1;
16716         }
16717       else
16718         {
16719           errmsg ("parse error '%U'", format_unformat_error, i);
16720           return -99;
16721         }
16722     }
16723
16724   if (!vni_set)
16725     {
16726       errmsg ("vni not set!");
16727       return -99;
16728     }
16729
16730   if (!vam->json_output)
16731     {
16732       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16733              "leid", "reid");
16734     }
16735
16736   M (GPE_FWD_ENTRIES_GET, mp);
16737   mp->vni = clib_host_to_net_u32 (vni);
16738
16739   /* send it... */
16740   S (mp);
16741
16742   /* Wait for a reply... */
16743   W (ret);
16744   return ret;
16745 }
16746
16747 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16748 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16749 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16750 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16751 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16752 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16753 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16754 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16755
16756 static int
16757 api_one_adjacencies_get (vat_main_t * vam)
16758 {
16759   unformat_input_t *i = vam->input;
16760   vl_api_one_adjacencies_get_t *mp;
16761   u8 vni_set = 0;
16762   u32 vni = ~0;
16763   int ret;
16764
16765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16766     {
16767       if (unformat (i, "vni %d", &vni))
16768         {
16769           vni_set = 1;
16770         }
16771       else
16772         {
16773           errmsg ("parse error '%U'", format_unformat_error, i);
16774           return -99;
16775         }
16776     }
16777
16778   if (!vni_set)
16779     {
16780       errmsg ("vni not set!");
16781       return -99;
16782     }
16783
16784   if (!vam->json_output)
16785     {
16786       print (vam->ofp, "%s %40s", "leid", "reid");
16787     }
16788
16789   M (ONE_ADJACENCIES_GET, mp);
16790   mp->vni = clib_host_to_net_u32 (vni);
16791
16792   /* send it... */
16793   S (mp);
16794
16795   /* Wait for a reply... */
16796   W (ret);
16797   return ret;
16798 }
16799
16800 #define api_lisp_adjacencies_get api_one_adjacencies_get
16801
16802 static int
16803 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16804 {
16805   unformat_input_t *i = vam->input;
16806   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16807   int ret;
16808   u8 ip_family_set = 0, is_ip4 = 1;
16809
16810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16811     {
16812       if (unformat (i, "ip4"))
16813         {
16814           ip_family_set = 1;
16815           is_ip4 = 1;
16816         }
16817       else if (unformat (i, "ip6"))
16818         {
16819           ip_family_set = 1;
16820           is_ip4 = 0;
16821         }
16822       else
16823         {
16824           errmsg ("parse error '%U'", format_unformat_error, i);
16825           return -99;
16826         }
16827     }
16828
16829   if (!ip_family_set)
16830     {
16831       errmsg ("ip family not set!");
16832       return -99;
16833     }
16834
16835   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16836   mp->is_ip4 = is_ip4;
16837
16838   /* send it... */
16839   S (mp);
16840
16841   /* Wait for a reply... */
16842   W (ret);
16843   return ret;
16844 }
16845
16846 static int
16847 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16848 {
16849   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16850   int ret;
16851
16852   if (!vam->json_output)
16853     {
16854       print (vam->ofp, "VNIs");
16855     }
16856
16857   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16858
16859   /* send it... */
16860   S (mp);
16861
16862   /* Wait for a reply... */
16863   W (ret);
16864   return ret;
16865 }
16866
16867 static int
16868 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16869 {
16870   unformat_input_t *i = vam->input;
16871   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16872   int ret = 0;
16873   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16874   struct in_addr ip4;
16875   struct in6_addr ip6;
16876   u32 table_id = 0, nh_sw_if_index = ~0;
16877
16878   memset (&ip4, 0, sizeof (ip4));
16879   memset (&ip6, 0, sizeof (ip6));
16880
16881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16882     {
16883       if (unformat (i, "del"))
16884         is_add = 0;
16885       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16886                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16887         {
16888           ip_set = 1;
16889           is_ip4 = 1;
16890         }
16891       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16892                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16893         {
16894           ip_set = 1;
16895           is_ip4 = 0;
16896         }
16897       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16898         {
16899           ip_set = 1;
16900           is_ip4 = 1;
16901           nh_sw_if_index = ~0;
16902         }
16903       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16904         {
16905           ip_set = 1;
16906           is_ip4 = 0;
16907           nh_sw_if_index = ~0;
16908         }
16909       else if (unformat (i, "table %d", &table_id))
16910         ;
16911       else
16912         {
16913           errmsg ("parse error '%U'", format_unformat_error, i);
16914           return -99;
16915         }
16916     }
16917
16918   if (!ip_set)
16919     {
16920       errmsg ("nh addr not set!");
16921       return -99;
16922     }
16923
16924   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16925   mp->is_add = is_add;
16926   mp->table_id = clib_host_to_net_u32 (table_id);
16927   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16928   mp->is_ip4 = is_ip4;
16929   if (is_ip4)
16930     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16931   else
16932     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16933
16934   /* send it... */
16935   S (mp);
16936
16937   /* Wait for a reply... */
16938   W (ret);
16939   return ret;
16940 }
16941
16942 static int
16943 api_one_map_server_dump (vat_main_t * vam)
16944 {
16945   vl_api_one_map_server_dump_t *mp;
16946   vl_api_control_ping_t *mp_ping;
16947   int ret;
16948
16949   if (!vam->json_output)
16950     {
16951       print (vam->ofp, "%=20s", "Map server");
16952     }
16953
16954   M (ONE_MAP_SERVER_DUMP, mp);
16955   /* send it... */
16956   S (mp);
16957
16958   /* Use a control ping for synchronization */
16959   M (CONTROL_PING, mp_ping);
16960   S (mp_ping);
16961
16962   /* Wait for a reply... */
16963   W (ret);
16964   return ret;
16965 }
16966
16967 #define api_lisp_map_server_dump api_one_map_server_dump
16968
16969 static int
16970 api_one_map_resolver_dump (vat_main_t * vam)
16971 {
16972   vl_api_one_map_resolver_dump_t *mp;
16973   vl_api_control_ping_t *mp_ping;
16974   int ret;
16975
16976   if (!vam->json_output)
16977     {
16978       print (vam->ofp, "%=20s", "Map resolver");
16979     }
16980
16981   M (ONE_MAP_RESOLVER_DUMP, mp);
16982   /* send it... */
16983   S (mp);
16984
16985   /* Use a control ping for synchronization */
16986   M (CONTROL_PING, mp_ping);
16987   S (mp_ping);
16988
16989   /* Wait for a reply... */
16990   W (ret);
16991   return ret;
16992 }
16993
16994 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16995
16996 static int
16997 api_one_stats_flush (vat_main_t * vam)
16998 {
16999   vl_api_one_stats_flush_t *mp;
17000   int ret = 0;
17001
17002   M (ONE_STATS_FLUSH, mp);
17003   S (mp);
17004   W (ret);
17005   return ret;
17006 }
17007
17008 static int
17009 api_one_stats_dump (vat_main_t * vam)
17010 {
17011   vl_api_one_stats_dump_t *mp;
17012   vl_api_control_ping_t *mp_ping;
17013   int ret;
17014
17015   M (ONE_STATS_DUMP, mp);
17016   /* send it... */
17017   S (mp);
17018
17019   /* Use a control ping for synchronization */
17020   M (CONTROL_PING, mp_ping);
17021   S (mp_ping);
17022
17023   /* Wait for a reply... */
17024   W (ret);
17025   return ret;
17026 }
17027
17028 static int
17029 api_show_one_status (vat_main_t * vam)
17030 {
17031   vl_api_show_one_status_t *mp;
17032   int ret;
17033
17034   if (!vam->json_output)
17035     {
17036       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17037     }
17038
17039   M (SHOW_ONE_STATUS, mp);
17040   /* send it... */
17041   S (mp);
17042   /* Wait for a reply... */
17043   W (ret);
17044   return ret;
17045 }
17046
17047 #define api_show_lisp_status api_show_one_status
17048
17049 static int
17050 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17051 {
17052   vl_api_gpe_fwd_entry_path_dump_t *mp;
17053   vl_api_control_ping_t *mp_ping;
17054   unformat_input_t *i = vam->input;
17055   u32 fwd_entry_index = ~0;
17056   int ret;
17057
17058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17059     {
17060       if (unformat (i, "index %d", &fwd_entry_index))
17061         ;
17062       else
17063         break;
17064     }
17065
17066   if (~0 == fwd_entry_index)
17067     {
17068       errmsg ("no index specified!");
17069       return -99;
17070     }
17071
17072   if (!vam->json_output)
17073     {
17074       print (vam->ofp, "first line");
17075     }
17076
17077   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17078
17079   /* send it... */
17080   S (mp);
17081   /* Use a control ping for synchronization */
17082   M (CONTROL_PING, mp_ping);
17083   S (mp_ping);
17084
17085   /* Wait for a reply... */
17086   W (ret);
17087   return ret;
17088 }
17089
17090 static int
17091 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17092 {
17093   vl_api_one_get_map_request_itr_rlocs_t *mp;
17094   int ret;
17095
17096   if (!vam->json_output)
17097     {
17098       print (vam->ofp, "%=20s", "itr-rlocs:");
17099     }
17100
17101   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17102   /* send it... */
17103   S (mp);
17104   /* Wait for a reply... */
17105   W (ret);
17106   return ret;
17107 }
17108
17109 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17110
17111 static int
17112 api_af_packet_create (vat_main_t * vam)
17113 {
17114   unformat_input_t *i = vam->input;
17115   vl_api_af_packet_create_t *mp;
17116   u8 *host_if_name = 0;
17117   u8 hw_addr[6];
17118   u8 random_hw_addr = 1;
17119   int ret;
17120
17121   memset (hw_addr, 0, sizeof (hw_addr));
17122
17123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17124     {
17125       if (unformat (i, "name %s", &host_if_name))
17126         vec_add1 (host_if_name, 0);
17127       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17128         random_hw_addr = 0;
17129       else
17130         break;
17131     }
17132
17133   if (!vec_len (host_if_name))
17134     {
17135       errmsg ("host-interface name must be specified");
17136       return -99;
17137     }
17138
17139   if (vec_len (host_if_name) > 64)
17140     {
17141       errmsg ("host-interface name too long");
17142       return -99;
17143     }
17144
17145   M (AF_PACKET_CREATE, mp);
17146
17147   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17148   clib_memcpy (mp->hw_addr, hw_addr, 6);
17149   mp->use_random_hw_addr = random_hw_addr;
17150   vec_free (host_if_name);
17151
17152   S (mp);
17153
17154   /* *INDENT-OFF* */
17155   W2 (ret,
17156       ({
17157         if (ret == 0)
17158           fprintf (vam->ofp ? vam->ofp : stderr,
17159                    " new sw_if_index = %d\n", vam->sw_if_index);
17160       }));
17161   /* *INDENT-ON* */
17162   return ret;
17163 }
17164
17165 static int
17166 api_af_packet_delete (vat_main_t * vam)
17167 {
17168   unformat_input_t *i = vam->input;
17169   vl_api_af_packet_delete_t *mp;
17170   u8 *host_if_name = 0;
17171   int ret;
17172
17173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17174     {
17175       if (unformat (i, "name %s", &host_if_name))
17176         vec_add1 (host_if_name, 0);
17177       else
17178         break;
17179     }
17180
17181   if (!vec_len (host_if_name))
17182     {
17183       errmsg ("host-interface name must be specified");
17184       return -99;
17185     }
17186
17187   if (vec_len (host_if_name) > 64)
17188     {
17189       errmsg ("host-interface name too long");
17190       return -99;
17191     }
17192
17193   M (AF_PACKET_DELETE, mp);
17194
17195   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17196   vec_free (host_if_name);
17197
17198   S (mp);
17199   W (ret);
17200   return ret;
17201 }
17202
17203 static int
17204 api_policer_add_del (vat_main_t * vam)
17205 {
17206   unformat_input_t *i = vam->input;
17207   vl_api_policer_add_del_t *mp;
17208   u8 is_add = 1;
17209   u8 *name = 0;
17210   u32 cir = 0;
17211   u32 eir = 0;
17212   u64 cb = 0;
17213   u64 eb = 0;
17214   u8 rate_type = 0;
17215   u8 round_type = 0;
17216   u8 type = 0;
17217   u8 color_aware = 0;
17218   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17219   int ret;
17220
17221   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17222   conform_action.dscp = 0;
17223   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17224   exceed_action.dscp = 0;
17225   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17226   violate_action.dscp = 0;
17227
17228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17229     {
17230       if (unformat (i, "del"))
17231         is_add = 0;
17232       else if (unformat (i, "name %s", &name))
17233         vec_add1 (name, 0);
17234       else if (unformat (i, "cir %u", &cir))
17235         ;
17236       else if (unformat (i, "eir %u", &eir))
17237         ;
17238       else if (unformat (i, "cb %u", &cb))
17239         ;
17240       else if (unformat (i, "eb %u", &eb))
17241         ;
17242       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17243                          &rate_type))
17244         ;
17245       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17246                          &round_type))
17247         ;
17248       else if (unformat (i, "type %U", unformat_policer_type, &type))
17249         ;
17250       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17251                          &conform_action))
17252         ;
17253       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17254                          &exceed_action))
17255         ;
17256       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17257                          &violate_action))
17258         ;
17259       else if (unformat (i, "color-aware"))
17260         color_aware = 1;
17261       else
17262         break;
17263     }
17264
17265   if (!vec_len (name))
17266     {
17267       errmsg ("policer name must be specified");
17268       return -99;
17269     }
17270
17271   if (vec_len (name) > 64)
17272     {
17273       errmsg ("policer name too long");
17274       return -99;
17275     }
17276
17277   M (POLICER_ADD_DEL, mp);
17278
17279   clib_memcpy (mp->name, name, vec_len (name));
17280   vec_free (name);
17281   mp->is_add = is_add;
17282   mp->cir = cir;
17283   mp->eir = eir;
17284   mp->cb = cb;
17285   mp->eb = eb;
17286   mp->rate_type = rate_type;
17287   mp->round_type = round_type;
17288   mp->type = type;
17289   mp->conform_action_type = conform_action.action_type;
17290   mp->conform_dscp = conform_action.dscp;
17291   mp->exceed_action_type = exceed_action.action_type;
17292   mp->exceed_dscp = exceed_action.dscp;
17293   mp->violate_action_type = violate_action.action_type;
17294   mp->violate_dscp = violate_action.dscp;
17295   mp->color_aware = color_aware;
17296
17297   S (mp);
17298   W (ret);
17299   return ret;
17300 }
17301
17302 static int
17303 api_policer_dump (vat_main_t * vam)
17304 {
17305   unformat_input_t *i = vam->input;
17306   vl_api_policer_dump_t *mp;
17307   vl_api_control_ping_t *mp_ping;
17308   u8 *match_name = 0;
17309   u8 match_name_valid = 0;
17310   int ret;
17311
17312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17313     {
17314       if (unformat (i, "name %s", &match_name))
17315         {
17316           vec_add1 (match_name, 0);
17317           match_name_valid = 1;
17318         }
17319       else
17320         break;
17321     }
17322
17323   M (POLICER_DUMP, mp);
17324   mp->match_name_valid = match_name_valid;
17325   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17326   vec_free (match_name);
17327   /* send it... */
17328   S (mp);
17329
17330   /* Use a control ping for synchronization */
17331   M (CONTROL_PING, mp_ping);
17332   S (mp_ping);
17333
17334   /* Wait for a reply... */
17335   W (ret);
17336   return ret;
17337 }
17338
17339 static int
17340 api_policer_classify_set_interface (vat_main_t * vam)
17341 {
17342   unformat_input_t *i = vam->input;
17343   vl_api_policer_classify_set_interface_t *mp;
17344   u32 sw_if_index;
17345   int sw_if_index_set;
17346   u32 ip4_table_index = ~0;
17347   u32 ip6_table_index = ~0;
17348   u32 l2_table_index = ~0;
17349   u8 is_add = 1;
17350   int ret;
17351
17352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17353     {
17354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17355         sw_if_index_set = 1;
17356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17357         sw_if_index_set = 1;
17358       else if (unformat (i, "del"))
17359         is_add = 0;
17360       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17361         ;
17362       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17363         ;
17364       else if (unformat (i, "l2-table %d", &l2_table_index))
17365         ;
17366       else
17367         {
17368           clib_warning ("parse error '%U'", format_unformat_error, i);
17369           return -99;
17370         }
17371     }
17372
17373   if (sw_if_index_set == 0)
17374     {
17375       errmsg ("missing interface name or sw_if_index");
17376       return -99;
17377     }
17378
17379   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17380
17381   mp->sw_if_index = ntohl (sw_if_index);
17382   mp->ip4_table_index = ntohl (ip4_table_index);
17383   mp->ip6_table_index = ntohl (ip6_table_index);
17384   mp->l2_table_index = ntohl (l2_table_index);
17385   mp->is_add = is_add;
17386
17387   S (mp);
17388   W (ret);
17389   return ret;
17390 }
17391
17392 static int
17393 api_policer_classify_dump (vat_main_t * vam)
17394 {
17395   unformat_input_t *i = vam->input;
17396   vl_api_policer_classify_dump_t *mp;
17397   vl_api_control_ping_t *mp_ping;
17398   u8 type = POLICER_CLASSIFY_N_TABLES;
17399   int ret;
17400
17401   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17402     ;
17403   else
17404     {
17405       errmsg ("classify table type must be specified");
17406       return -99;
17407     }
17408
17409   if (!vam->json_output)
17410     {
17411       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17412     }
17413
17414   M (POLICER_CLASSIFY_DUMP, mp);
17415   mp->type = type;
17416   /* send it... */
17417   S (mp);
17418
17419   /* Use a control ping for synchronization */
17420   M (CONTROL_PING, mp_ping);
17421   S (mp_ping);
17422
17423   /* Wait for a reply... */
17424   W (ret);
17425   return ret;
17426 }
17427
17428 static int
17429 api_netmap_create (vat_main_t * vam)
17430 {
17431   unformat_input_t *i = vam->input;
17432   vl_api_netmap_create_t *mp;
17433   u8 *if_name = 0;
17434   u8 hw_addr[6];
17435   u8 random_hw_addr = 1;
17436   u8 is_pipe = 0;
17437   u8 is_master = 0;
17438   int ret;
17439
17440   memset (hw_addr, 0, sizeof (hw_addr));
17441
17442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17443     {
17444       if (unformat (i, "name %s", &if_name))
17445         vec_add1 (if_name, 0);
17446       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17447         random_hw_addr = 0;
17448       else if (unformat (i, "pipe"))
17449         is_pipe = 1;
17450       else if (unformat (i, "master"))
17451         is_master = 1;
17452       else if (unformat (i, "slave"))
17453         is_master = 0;
17454       else
17455         break;
17456     }
17457
17458   if (!vec_len (if_name))
17459     {
17460       errmsg ("interface name must be specified");
17461       return -99;
17462     }
17463
17464   if (vec_len (if_name) > 64)
17465     {
17466       errmsg ("interface name too long");
17467       return -99;
17468     }
17469
17470   M (NETMAP_CREATE, mp);
17471
17472   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17473   clib_memcpy (mp->hw_addr, hw_addr, 6);
17474   mp->use_random_hw_addr = random_hw_addr;
17475   mp->is_pipe = is_pipe;
17476   mp->is_master = is_master;
17477   vec_free (if_name);
17478
17479   S (mp);
17480   W (ret);
17481   return ret;
17482 }
17483
17484 static int
17485 api_netmap_delete (vat_main_t * vam)
17486 {
17487   unformat_input_t *i = vam->input;
17488   vl_api_netmap_delete_t *mp;
17489   u8 *if_name = 0;
17490   int ret;
17491
17492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17493     {
17494       if (unformat (i, "name %s", &if_name))
17495         vec_add1 (if_name, 0);
17496       else
17497         break;
17498     }
17499
17500   if (!vec_len (if_name))
17501     {
17502       errmsg ("interface name must be specified");
17503       return -99;
17504     }
17505
17506   if (vec_len (if_name) > 64)
17507     {
17508       errmsg ("interface name too long");
17509       return -99;
17510     }
17511
17512   M (NETMAP_DELETE, mp);
17513
17514   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17515   vec_free (if_name);
17516
17517   S (mp);
17518   W (ret);
17519   return ret;
17520 }
17521
17522 static void
17523 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17524 {
17525   if (fp->afi == IP46_TYPE_IP6)
17526     print (vam->ofp,
17527            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17528            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17529            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17530            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17531            format_ip6_address, fp->next_hop);
17532   else if (fp->afi == IP46_TYPE_IP4)
17533     print (vam->ofp,
17534            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17535            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17536            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17537            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17538            format_ip4_address, fp->next_hop);
17539 }
17540
17541 static void
17542 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17543                                  vl_api_fib_path2_t * fp)
17544 {
17545   struct in_addr ip4;
17546   struct in6_addr ip6;
17547
17548   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17549   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17550   vat_json_object_add_uint (node, "is_local", fp->is_local);
17551   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17552   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17553   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17554   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17555   if (fp->afi == IP46_TYPE_IP4)
17556     {
17557       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17558       vat_json_object_add_ip4 (node, "next_hop", ip4);
17559     }
17560   else if (fp->afi == IP46_TYPE_IP6)
17561     {
17562       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17563       vat_json_object_add_ip6 (node, "next_hop", ip6);
17564     }
17565 }
17566
17567 static void
17568 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17569 {
17570   vat_main_t *vam = &vat_main;
17571   int count = ntohl (mp->mt_count);
17572   vl_api_fib_path2_t *fp;
17573   i32 i;
17574
17575   print (vam->ofp, "[%d]: sw_if_index %d via:",
17576          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17577   fp = mp->mt_paths;
17578   for (i = 0; i < count; i++)
17579     {
17580       vl_api_mpls_fib_path_print (vam, fp);
17581       fp++;
17582     }
17583
17584   print (vam->ofp, "");
17585 }
17586
17587 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17588 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17589
17590 static void
17591 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17592 {
17593   vat_main_t *vam = &vat_main;
17594   vat_json_node_t *node = NULL;
17595   int count = ntohl (mp->mt_count);
17596   vl_api_fib_path2_t *fp;
17597   i32 i;
17598
17599   if (VAT_JSON_ARRAY != vam->json_tree.type)
17600     {
17601       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17602       vat_json_init_array (&vam->json_tree);
17603     }
17604   node = vat_json_array_add (&vam->json_tree);
17605
17606   vat_json_init_object (node);
17607   vat_json_object_add_uint (node, "tunnel_index",
17608                             ntohl (mp->mt_tunnel_index));
17609   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17610
17611   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17612
17613   fp = mp->mt_paths;
17614   for (i = 0; i < count; i++)
17615     {
17616       vl_api_mpls_fib_path_json_print (node, fp);
17617       fp++;
17618     }
17619 }
17620
17621 static int
17622 api_mpls_tunnel_dump (vat_main_t * vam)
17623 {
17624   vl_api_mpls_tunnel_dump_t *mp;
17625   vl_api_control_ping_t *mp_ping;
17626   i32 index = -1;
17627   int ret;
17628
17629   /* Parse args required to build the message */
17630   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17631     {
17632       if (!unformat (vam->input, "tunnel_index %d", &index))
17633         {
17634           index = -1;
17635           break;
17636         }
17637     }
17638
17639   print (vam->ofp, "  tunnel_index %d", index);
17640
17641   M (MPLS_TUNNEL_DUMP, mp);
17642   mp->tunnel_index = htonl (index);
17643   S (mp);
17644
17645   /* Use a control ping for synchronization */
17646   M (CONTROL_PING, mp_ping);
17647   S (mp_ping);
17648
17649   W (ret);
17650   return ret;
17651 }
17652
17653 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17654 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17655
17656
17657 static void
17658 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17659 {
17660   vat_main_t *vam = &vat_main;
17661   int count = ntohl (mp->count);
17662   vl_api_fib_path2_t *fp;
17663   int i;
17664
17665   print (vam->ofp,
17666          "table-id %d, label %u, ess_bit %u",
17667          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17668   fp = mp->path;
17669   for (i = 0; i < count; i++)
17670     {
17671       vl_api_mpls_fib_path_print (vam, fp);
17672       fp++;
17673     }
17674 }
17675
17676 static void vl_api_mpls_fib_details_t_handler_json
17677   (vl_api_mpls_fib_details_t * mp)
17678 {
17679   vat_main_t *vam = &vat_main;
17680   int count = ntohl (mp->count);
17681   vat_json_node_t *node = NULL;
17682   vl_api_fib_path2_t *fp;
17683   int i;
17684
17685   if (VAT_JSON_ARRAY != vam->json_tree.type)
17686     {
17687       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17688       vat_json_init_array (&vam->json_tree);
17689     }
17690   node = vat_json_array_add (&vam->json_tree);
17691
17692   vat_json_init_object (node);
17693   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17694   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17695   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17696   vat_json_object_add_uint (node, "path_count", count);
17697   fp = mp->path;
17698   for (i = 0; i < count; i++)
17699     {
17700       vl_api_mpls_fib_path_json_print (node, fp);
17701       fp++;
17702     }
17703 }
17704
17705 static int
17706 api_mpls_fib_dump (vat_main_t * vam)
17707 {
17708   vl_api_mpls_fib_dump_t *mp;
17709   vl_api_control_ping_t *mp_ping;
17710   int ret;
17711
17712   M (MPLS_FIB_DUMP, mp);
17713   S (mp);
17714
17715   /* Use a control ping for synchronization */
17716   M (CONTROL_PING, mp_ping);
17717   S (mp_ping);
17718
17719   W (ret);
17720   return ret;
17721 }
17722
17723 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17724 #define vl_api_ip_fib_details_t_print vl_noop_handler
17725
17726 static void
17727 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17728 {
17729   vat_main_t *vam = &vat_main;
17730   int count = ntohl (mp->count);
17731   vl_api_fib_path_t *fp;
17732   int i;
17733
17734   print (vam->ofp,
17735          "table-id %d, prefix %U/%d",
17736          ntohl (mp->table_id), format_ip4_address, mp->address,
17737          mp->address_length);
17738   fp = mp->path;
17739   for (i = 0; i < count; i++)
17740     {
17741       if (fp->afi == IP46_TYPE_IP6)
17742         print (vam->ofp,
17743                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17744                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17745                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17746                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17747                format_ip6_address, fp->next_hop);
17748       else if (fp->afi == IP46_TYPE_IP4)
17749         print (vam->ofp,
17750                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17751                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17752                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17753                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17754                format_ip4_address, fp->next_hop);
17755       fp++;
17756     }
17757 }
17758
17759 static void vl_api_ip_fib_details_t_handler_json
17760   (vl_api_ip_fib_details_t * mp)
17761 {
17762   vat_main_t *vam = &vat_main;
17763   int count = ntohl (mp->count);
17764   vat_json_node_t *node = NULL;
17765   struct in_addr ip4;
17766   struct in6_addr ip6;
17767   vl_api_fib_path_t *fp;
17768   int i;
17769
17770   if (VAT_JSON_ARRAY != vam->json_tree.type)
17771     {
17772       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17773       vat_json_init_array (&vam->json_tree);
17774     }
17775   node = vat_json_array_add (&vam->json_tree);
17776
17777   vat_json_init_object (node);
17778   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17779   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17780   vat_json_object_add_ip4 (node, "prefix", ip4);
17781   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17782   vat_json_object_add_uint (node, "path_count", count);
17783   fp = mp->path;
17784   for (i = 0; i < count; i++)
17785     {
17786       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17787       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17788       vat_json_object_add_uint (node, "is_local", fp->is_local);
17789       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17790       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17791       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17792       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17793       if (fp->afi == IP46_TYPE_IP4)
17794         {
17795           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17796           vat_json_object_add_ip4 (node, "next_hop", ip4);
17797         }
17798       else if (fp->afi == IP46_TYPE_IP6)
17799         {
17800           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17801           vat_json_object_add_ip6 (node, "next_hop", ip6);
17802         }
17803     }
17804 }
17805
17806 static int
17807 api_ip_fib_dump (vat_main_t * vam)
17808 {
17809   vl_api_ip_fib_dump_t *mp;
17810   vl_api_control_ping_t *mp_ping;
17811   int ret;
17812
17813   M (IP_FIB_DUMP, mp);
17814   S (mp);
17815
17816   /* Use a control ping for synchronization */
17817   M (CONTROL_PING, mp_ping);
17818   S (mp_ping);
17819
17820   W (ret);
17821   return ret;
17822 }
17823
17824 static int
17825 api_ip_mfib_dump (vat_main_t * vam)
17826 {
17827   vl_api_ip_mfib_dump_t *mp;
17828   vl_api_control_ping_t *mp_ping;
17829   int ret;
17830
17831   M (IP_MFIB_DUMP, mp);
17832   S (mp);
17833
17834   /* Use a control ping for synchronization */
17835   M (CONTROL_PING, mp_ping);
17836   S (mp_ping);
17837
17838   W (ret);
17839   return ret;
17840 }
17841
17842 static void vl_api_ip_neighbor_details_t_handler
17843   (vl_api_ip_neighbor_details_t * mp)
17844 {
17845   vat_main_t *vam = &vat_main;
17846
17847   print (vam->ofp, "%c %U %U",
17848          (mp->is_static) ? 'S' : 'D',
17849          format_ethernet_address, &mp->mac_address,
17850          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17851          &mp->ip_address);
17852 }
17853
17854 static void vl_api_ip_neighbor_details_t_handler_json
17855   (vl_api_ip_neighbor_details_t * mp)
17856 {
17857
17858   vat_main_t *vam = &vat_main;
17859   vat_json_node_t *node;
17860   struct in_addr ip4;
17861   struct in6_addr ip6;
17862
17863   if (VAT_JSON_ARRAY != vam->json_tree.type)
17864     {
17865       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17866       vat_json_init_array (&vam->json_tree);
17867     }
17868   node = vat_json_array_add (&vam->json_tree);
17869
17870   vat_json_init_object (node);
17871   vat_json_object_add_string_copy (node, "flag",
17872                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17873                                    "dynamic");
17874
17875   vat_json_object_add_string_copy (node, "link_layer",
17876                                    format (0, "%U", format_ethernet_address,
17877                                            &mp->mac_address));
17878
17879   if (mp->is_ipv6)
17880     {
17881       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17882       vat_json_object_add_ip6 (node, "ip_address", ip6);
17883     }
17884   else
17885     {
17886       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17887       vat_json_object_add_ip4 (node, "ip_address", ip4);
17888     }
17889 }
17890
17891 static int
17892 api_ip_neighbor_dump (vat_main_t * vam)
17893 {
17894   unformat_input_t *i = vam->input;
17895   vl_api_ip_neighbor_dump_t *mp;
17896   vl_api_control_ping_t *mp_ping;
17897   u8 is_ipv6 = 0;
17898   u32 sw_if_index = ~0;
17899   int ret;
17900
17901   /* Parse args required to build the message */
17902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17903     {
17904       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17905         ;
17906       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17907         ;
17908       else if (unformat (i, "ip6"))
17909         is_ipv6 = 1;
17910       else
17911         break;
17912     }
17913
17914   if (sw_if_index == ~0)
17915     {
17916       errmsg ("missing interface name or sw_if_index");
17917       return -99;
17918     }
17919
17920   M (IP_NEIGHBOR_DUMP, mp);
17921   mp->is_ipv6 = (u8) is_ipv6;
17922   mp->sw_if_index = ntohl (sw_if_index);
17923   S (mp);
17924
17925   /* Use a control ping for synchronization */
17926   M (CONTROL_PING, mp_ping);
17927   S (mp_ping);
17928
17929   W (ret);
17930   return ret;
17931 }
17932
17933 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17934 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17935
17936 static void
17937 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17938 {
17939   vat_main_t *vam = &vat_main;
17940   int count = ntohl (mp->count);
17941   vl_api_fib_path_t *fp;
17942   int i;
17943
17944   print (vam->ofp,
17945          "table-id %d, prefix %U/%d",
17946          ntohl (mp->table_id), format_ip6_address, mp->address,
17947          mp->address_length);
17948   fp = mp->path;
17949   for (i = 0; i < count; i++)
17950     {
17951       if (fp->afi == IP46_TYPE_IP6)
17952         print (vam->ofp,
17953                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17954                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17955                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17956                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17957                format_ip6_address, fp->next_hop);
17958       else if (fp->afi == IP46_TYPE_IP4)
17959         print (vam->ofp,
17960                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17961                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17962                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17963                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17964                format_ip4_address, fp->next_hop);
17965       fp++;
17966     }
17967 }
17968
17969 static void vl_api_ip6_fib_details_t_handler_json
17970   (vl_api_ip6_fib_details_t * mp)
17971 {
17972   vat_main_t *vam = &vat_main;
17973   int count = ntohl (mp->count);
17974   vat_json_node_t *node = NULL;
17975   struct in_addr ip4;
17976   struct in6_addr ip6;
17977   vl_api_fib_path_t *fp;
17978   int i;
17979
17980   if (VAT_JSON_ARRAY != vam->json_tree.type)
17981     {
17982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17983       vat_json_init_array (&vam->json_tree);
17984     }
17985   node = vat_json_array_add (&vam->json_tree);
17986
17987   vat_json_init_object (node);
17988   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17989   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17990   vat_json_object_add_ip6 (node, "prefix", ip6);
17991   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17992   vat_json_object_add_uint (node, "path_count", count);
17993   fp = mp->path;
17994   for (i = 0; i < count; i++)
17995     {
17996       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17997       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17998       vat_json_object_add_uint (node, "is_local", fp->is_local);
17999       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18000       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18001       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18002       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18003       if (fp->afi == IP46_TYPE_IP4)
18004         {
18005           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18006           vat_json_object_add_ip4 (node, "next_hop", ip4);
18007         }
18008       else if (fp->afi == IP46_TYPE_IP6)
18009         {
18010           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18011           vat_json_object_add_ip6 (node, "next_hop", ip6);
18012         }
18013     }
18014 }
18015
18016 static int
18017 api_ip6_fib_dump (vat_main_t * vam)
18018 {
18019   vl_api_ip6_fib_dump_t *mp;
18020   vl_api_control_ping_t *mp_ping;
18021   int ret;
18022
18023   M (IP6_FIB_DUMP, mp);
18024   S (mp);
18025
18026   /* Use a control ping for synchronization */
18027   M (CONTROL_PING, mp_ping);
18028   S (mp_ping);
18029
18030   W (ret);
18031   return ret;
18032 }
18033
18034 static int
18035 api_ip6_mfib_dump (vat_main_t * vam)
18036 {
18037   vl_api_ip6_mfib_dump_t *mp;
18038   vl_api_control_ping_t *mp_ping;
18039   int ret;
18040
18041   M (IP6_MFIB_DUMP, mp);
18042   S (mp);
18043
18044   /* Use a control ping for synchronization */
18045   M (CONTROL_PING, mp_ping);
18046   S (mp_ping);
18047
18048   W (ret);
18049   return ret;
18050 }
18051
18052 int
18053 api_classify_table_ids (vat_main_t * vam)
18054 {
18055   vl_api_classify_table_ids_t *mp;
18056   int ret;
18057
18058   /* Construct the API message */
18059   M (CLASSIFY_TABLE_IDS, mp);
18060   mp->context = 0;
18061
18062   S (mp);
18063   W (ret);
18064   return ret;
18065 }
18066
18067 int
18068 api_classify_table_by_interface (vat_main_t * vam)
18069 {
18070   unformat_input_t *input = vam->input;
18071   vl_api_classify_table_by_interface_t *mp;
18072
18073   u32 sw_if_index = ~0;
18074   int ret;
18075   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18076     {
18077       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18078         ;
18079       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18080         ;
18081       else
18082         break;
18083     }
18084   if (sw_if_index == ~0)
18085     {
18086       errmsg ("missing interface name or sw_if_index");
18087       return -99;
18088     }
18089
18090   /* Construct the API message */
18091   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18092   mp->context = 0;
18093   mp->sw_if_index = ntohl (sw_if_index);
18094
18095   S (mp);
18096   W (ret);
18097   return ret;
18098 }
18099
18100 int
18101 api_classify_table_info (vat_main_t * vam)
18102 {
18103   unformat_input_t *input = vam->input;
18104   vl_api_classify_table_info_t *mp;
18105
18106   u32 table_id = ~0;
18107   int ret;
18108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18109     {
18110       if (unformat (input, "table_id %d", &table_id))
18111         ;
18112       else
18113         break;
18114     }
18115   if (table_id == ~0)
18116     {
18117       errmsg ("missing table id");
18118       return -99;
18119     }
18120
18121   /* Construct the API message */
18122   M (CLASSIFY_TABLE_INFO, mp);
18123   mp->context = 0;
18124   mp->table_id = ntohl (table_id);
18125
18126   S (mp);
18127   W (ret);
18128   return ret;
18129 }
18130
18131 int
18132 api_classify_session_dump (vat_main_t * vam)
18133 {
18134   unformat_input_t *input = vam->input;
18135   vl_api_classify_session_dump_t *mp;
18136   vl_api_control_ping_t *mp_ping;
18137
18138   u32 table_id = ~0;
18139   int ret;
18140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18141     {
18142       if (unformat (input, "table_id %d", &table_id))
18143         ;
18144       else
18145         break;
18146     }
18147   if (table_id == ~0)
18148     {
18149       errmsg ("missing table id");
18150       return -99;
18151     }
18152
18153   /* Construct the API message */
18154   M (CLASSIFY_SESSION_DUMP, mp);
18155   mp->context = 0;
18156   mp->table_id = ntohl (table_id);
18157   S (mp);
18158
18159   /* Use a control ping for synchronization */
18160   M (CONTROL_PING, mp_ping);
18161   S (mp_ping);
18162
18163   W (ret);
18164   return ret;
18165 }
18166
18167 static void
18168 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18169 {
18170   vat_main_t *vam = &vat_main;
18171
18172   print (vam->ofp, "collector_address %U, collector_port %d, "
18173          "src_address %U, vrf_id %d, path_mtu %u, "
18174          "template_interval %u, udp_checksum %d",
18175          format_ip4_address, mp->collector_address,
18176          ntohs (mp->collector_port),
18177          format_ip4_address, mp->src_address,
18178          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18179          ntohl (mp->template_interval), mp->udp_checksum);
18180
18181   vam->retval = 0;
18182   vam->result_ready = 1;
18183 }
18184
18185 static void
18186   vl_api_ipfix_exporter_details_t_handler_json
18187   (vl_api_ipfix_exporter_details_t * mp)
18188 {
18189   vat_main_t *vam = &vat_main;
18190   vat_json_node_t node;
18191   struct in_addr collector_address;
18192   struct in_addr src_address;
18193
18194   vat_json_init_object (&node);
18195   clib_memcpy (&collector_address, &mp->collector_address,
18196                sizeof (collector_address));
18197   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18198   vat_json_object_add_uint (&node, "collector_port",
18199                             ntohs (mp->collector_port));
18200   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18201   vat_json_object_add_ip4 (&node, "src_address", src_address);
18202   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18203   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18204   vat_json_object_add_uint (&node, "template_interval",
18205                             ntohl (mp->template_interval));
18206   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18207
18208   vat_json_print (vam->ofp, &node);
18209   vat_json_free (&node);
18210   vam->retval = 0;
18211   vam->result_ready = 1;
18212 }
18213
18214 int
18215 api_ipfix_exporter_dump (vat_main_t * vam)
18216 {
18217   vl_api_ipfix_exporter_dump_t *mp;
18218   int ret;
18219
18220   /* Construct the API message */
18221   M (IPFIX_EXPORTER_DUMP, mp);
18222   mp->context = 0;
18223
18224   S (mp);
18225   W (ret);
18226   return ret;
18227 }
18228
18229 static int
18230 api_ipfix_classify_stream_dump (vat_main_t * vam)
18231 {
18232   vl_api_ipfix_classify_stream_dump_t *mp;
18233   int ret;
18234
18235   /* Construct the API message */
18236   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18237   mp->context = 0;
18238
18239   S (mp);
18240   W (ret);
18241   return ret;
18242   /* NOTREACHED */
18243   return 0;
18244 }
18245
18246 static void
18247   vl_api_ipfix_classify_stream_details_t_handler
18248   (vl_api_ipfix_classify_stream_details_t * mp)
18249 {
18250   vat_main_t *vam = &vat_main;
18251   print (vam->ofp, "domain_id %d, src_port %d",
18252          ntohl (mp->domain_id), ntohs (mp->src_port));
18253   vam->retval = 0;
18254   vam->result_ready = 1;
18255 }
18256
18257 static void
18258   vl_api_ipfix_classify_stream_details_t_handler_json
18259   (vl_api_ipfix_classify_stream_details_t * mp)
18260 {
18261   vat_main_t *vam = &vat_main;
18262   vat_json_node_t node;
18263
18264   vat_json_init_object (&node);
18265   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18266   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18267
18268   vat_json_print (vam->ofp, &node);
18269   vat_json_free (&node);
18270   vam->retval = 0;
18271   vam->result_ready = 1;
18272 }
18273
18274 static int
18275 api_ipfix_classify_table_dump (vat_main_t * vam)
18276 {
18277   vl_api_ipfix_classify_table_dump_t *mp;
18278   vl_api_control_ping_t *mp_ping;
18279   int ret;
18280
18281   if (!vam->json_output)
18282     {
18283       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18284              "transport_protocol");
18285     }
18286
18287   /* Construct the API message */
18288   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18289
18290   /* send it... */
18291   S (mp);
18292
18293   /* Use a control ping for synchronization */
18294   M (CONTROL_PING, mp_ping);
18295   S (mp_ping);
18296
18297   W (ret);
18298   return ret;
18299 }
18300
18301 static void
18302   vl_api_ipfix_classify_table_details_t_handler
18303   (vl_api_ipfix_classify_table_details_t * mp)
18304 {
18305   vat_main_t *vam = &vat_main;
18306   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18307          mp->transport_protocol);
18308 }
18309
18310 static void
18311   vl_api_ipfix_classify_table_details_t_handler_json
18312   (vl_api_ipfix_classify_table_details_t * mp)
18313 {
18314   vat_json_node_t *node = NULL;
18315   vat_main_t *vam = &vat_main;
18316
18317   if (VAT_JSON_ARRAY != vam->json_tree.type)
18318     {
18319       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18320       vat_json_init_array (&vam->json_tree);
18321     }
18322
18323   node = vat_json_array_add (&vam->json_tree);
18324   vat_json_init_object (node);
18325
18326   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18327   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18328   vat_json_object_add_uint (node, "transport_protocol",
18329                             mp->transport_protocol);
18330 }
18331
18332 static int
18333 api_sw_interface_span_enable_disable (vat_main_t * vam)
18334 {
18335   unformat_input_t *i = vam->input;
18336   vl_api_sw_interface_span_enable_disable_t *mp;
18337   u32 src_sw_if_index = ~0;
18338   u32 dst_sw_if_index = ~0;
18339   u8 state = 3;
18340   int ret;
18341   u8 is_l2 = 0;
18342
18343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18344     {
18345       if (unformat
18346           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18347         ;
18348       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18349         ;
18350       else
18351         if (unformat
18352             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18353         ;
18354       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18355         ;
18356       else if (unformat (i, "disable"))
18357         state = 0;
18358       else if (unformat (i, "rx"))
18359         state = 1;
18360       else if (unformat (i, "tx"))
18361         state = 2;
18362       else if (unformat (i, "both"))
18363         state = 3;
18364       else if (unformat (i, "l2"))
18365         is_l2 = 1;
18366       else
18367         break;
18368     }
18369
18370   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18371
18372   mp->sw_if_index_from = htonl (src_sw_if_index);
18373   mp->sw_if_index_to = htonl (dst_sw_if_index);
18374   mp->state = state;
18375   mp->is_l2 = is_l2;
18376
18377   S (mp);
18378   W (ret);
18379   return ret;
18380 }
18381
18382 static void
18383 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18384                                             * mp)
18385 {
18386   vat_main_t *vam = &vat_main;
18387   u8 *sw_if_from_name = 0;
18388   u8 *sw_if_to_name = 0;
18389   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18390   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18391   char *states[] = { "none", "rx", "tx", "both" };
18392   hash_pair_t *p;
18393
18394   /* *INDENT-OFF* */
18395   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18396   ({
18397     if ((u32) p->value[0] == sw_if_index_from)
18398       {
18399         sw_if_from_name = (u8 *)(p->key);
18400         if (sw_if_to_name)
18401           break;
18402       }
18403     if ((u32) p->value[0] == sw_if_index_to)
18404       {
18405         sw_if_to_name = (u8 *)(p->key);
18406         if (sw_if_from_name)
18407           break;
18408       }
18409   }));
18410   /* *INDENT-ON* */
18411   print (vam->ofp, "%20s => %20s (%s)",
18412          sw_if_from_name, sw_if_to_name, states[mp->state]);
18413 }
18414
18415 static void
18416   vl_api_sw_interface_span_details_t_handler_json
18417   (vl_api_sw_interface_span_details_t * mp)
18418 {
18419   vat_main_t *vam = &vat_main;
18420   vat_json_node_t *node = NULL;
18421   u8 *sw_if_from_name = 0;
18422   u8 *sw_if_to_name = 0;
18423   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18424   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18425   hash_pair_t *p;
18426
18427   /* *INDENT-OFF* */
18428   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18429   ({
18430     if ((u32) p->value[0] == sw_if_index_from)
18431       {
18432         sw_if_from_name = (u8 *)(p->key);
18433         if (sw_if_to_name)
18434           break;
18435       }
18436     if ((u32) p->value[0] == sw_if_index_to)
18437       {
18438         sw_if_to_name = (u8 *)(p->key);
18439         if (sw_if_from_name)
18440           break;
18441       }
18442   }));
18443   /* *INDENT-ON* */
18444
18445   if (VAT_JSON_ARRAY != vam->json_tree.type)
18446     {
18447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18448       vat_json_init_array (&vam->json_tree);
18449     }
18450   node = vat_json_array_add (&vam->json_tree);
18451
18452   vat_json_init_object (node);
18453   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18454   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18455   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18456   if (0 != sw_if_to_name)
18457     {
18458       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18459     }
18460   vat_json_object_add_uint (node, "state", mp->state);
18461 }
18462
18463 static int
18464 api_sw_interface_span_dump (vat_main_t * vam)
18465 {
18466   unformat_input_t *input = vam->input;
18467   vl_api_sw_interface_span_dump_t *mp;
18468   vl_api_control_ping_t *mp_ping;
18469   u8 is_l2 = 0;
18470   int ret;
18471
18472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18473     {
18474       if (unformat (input, "l2"))
18475         is_l2 = 1;
18476       else
18477         break;
18478     }
18479
18480   M (SW_INTERFACE_SPAN_DUMP, mp);
18481   mp->is_l2 = is_l2;
18482   S (mp);
18483
18484   /* Use a control ping for synchronization */
18485   M (CONTROL_PING, mp_ping);
18486   S (mp_ping);
18487
18488   W (ret);
18489   return ret;
18490 }
18491
18492 int
18493 api_pg_create_interface (vat_main_t * vam)
18494 {
18495   unformat_input_t *input = vam->input;
18496   vl_api_pg_create_interface_t *mp;
18497
18498   u32 if_id = ~0;
18499   int ret;
18500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18501     {
18502       if (unformat (input, "if_id %d", &if_id))
18503         ;
18504       else
18505         break;
18506     }
18507   if (if_id == ~0)
18508     {
18509       errmsg ("missing pg interface index");
18510       return -99;
18511     }
18512
18513   /* Construct the API message */
18514   M (PG_CREATE_INTERFACE, mp);
18515   mp->context = 0;
18516   mp->interface_id = ntohl (if_id);
18517
18518   S (mp);
18519   W (ret);
18520   return ret;
18521 }
18522
18523 int
18524 api_pg_capture (vat_main_t * vam)
18525 {
18526   unformat_input_t *input = vam->input;
18527   vl_api_pg_capture_t *mp;
18528
18529   u32 if_id = ~0;
18530   u8 enable = 1;
18531   u32 count = 1;
18532   u8 pcap_file_set = 0;
18533   u8 *pcap_file = 0;
18534   int ret;
18535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18536     {
18537       if (unformat (input, "if_id %d", &if_id))
18538         ;
18539       else if (unformat (input, "pcap %s", &pcap_file))
18540         pcap_file_set = 1;
18541       else if (unformat (input, "count %d", &count))
18542         ;
18543       else if (unformat (input, "disable"))
18544         enable = 0;
18545       else
18546         break;
18547     }
18548   if (if_id == ~0)
18549     {
18550       errmsg ("missing pg interface index");
18551       return -99;
18552     }
18553   if (pcap_file_set > 0)
18554     {
18555       if (vec_len (pcap_file) > 255)
18556         {
18557           errmsg ("pcap file name is too long");
18558           return -99;
18559         }
18560     }
18561
18562   u32 name_len = vec_len (pcap_file);
18563   /* Construct the API message */
18564   M (PG_CAPTURE, mp);
18565   mp->context = 0;
18566   mp->interface_id = ntohl (if_id);
18567   mp->is_enabled = enable;
18568   mp->count = ntohl (count);
18569   mp->pcap_name_length = ntohl (name_len);
18570   if (pcap_file_set != 0)
18571     {
18572       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18573     }
18574   vec_free (pcap_file);
18575
18576   S (mp);
18577   W (ret);
18578   return ret;
18579 }
18580
18581 int
18582 api_pg_enable_disable (vat_main_t * vam)
18583 {
18584   unformat_input_t *input = vam->input;
18585   vl_api_pg_enable_disable_t *mp;
18586
18587   u8 enable = 1;
18588   u8 stream_name_set = 0;
18589   u8 *stream_name = 0;
18590   int ret;
18591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18592     {
18593       if (unformat (input, "stream %s", &stream_name))
18594         stream_name_set = 1;
18595       else if (unformat (input, "disable"))
18596         enable = 0;
18597       else
18598         break;
18599     }
18600
18601   if (stream_name_set > 0)
18602     {
18603       if (vec_len (stream_name) > 255)
18604         {
18605           errmsg ("stream name too long");
18606           return -99;
18607         }
18608     }
18609
18610   u32 name_len = vec_len (stream_name);
18611   /* Construct the API message */
18612   M (PG_ENABLE_DISABLE, mp);
18613   mp->context = 0;
18614   mp->is_enabled = enable;
18615   if (stream_name_set != 0)
18616     {
18617       mp->stream_name_length = ntohl (name_len);
18618       clib_memcpy (mp->stream_name, stream_name, name_len);
18619     }
18620   vec_free (stream_name);
18621
18622   S (mp);
18623   W (ret);
18624   return ret;
18625 }
18626
18627 int
18628 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18629 {
18630   unformat_input_t *input = vam->input;
18631   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18632
18633   u16 *low_ports = 0;
18634   u16 *high_ports = 0;
18635   u16 this_low;
18636   u16 this_hi;
18637   ip4_address_t ip4_addr;
18638   ip6_address_t ip6_addr;
18639   u32 length;
18640   u32 tmp, tmp2;
18641   u8 prefix_set = 0;
18642   u32 vrf_id = ~0;
18643   u8 is_add = 1;
18644   u8 is_ipv6 = 0;
18645   int ret;
18646
18647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18648     {
18649       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18650         {
18651           prefix_set = 1;
18652         }
18653       else
18654         if (unformat
18655             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18656         {
18657           prefix_set = 1;
18658           is_ipv6 = 1;
18659         }
18660       else if (unformat (input, "vrf %d", &vrf_id))
18661         ;
18662       else if (unformat (input, "del"))
18663         is_add = 0;
18664       else if (unformat (input, "port %d", &tmp))
18665         {
18666           if (tmp == 0 || tmp > 65535)
18667             {
18668               errmsg ("port %d out of range", tmp);
18669               return -99;
18670             }
18671           this_low = tmp;
18672           this_hi = this_low + 1;
18673           vec_add1 (low_ports, this_low);
18674           vec_add1 (high_ports, this_hi);
18675         }
18676       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18677         {
18678           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18679             {
18680               errmsg ("incorrect range parameters");
18681               return -99;
18682             }
18683           this_low = tmp;
18684           /* Note: in debug CLI +1 is added to high before
18685              passing to real fn that does "the work"
18686              (ip_source_and_port_range_check_add_del).
18687              This fn is a wrapper around the binary API fn a
18688              control plane will call, which expects this increment
18689              to have occurred. Hence letting the binary API control
18690              plane fn do the increment for consistency between VAT
18691              and other control planes.
18692            */
18693           this_hi = tmp2;
18694           vec_add1 (low_ports, this_low);
18695           vec_add1 (high_ports, this_hi);
18696         }
18697       else
18698         break;
18699     }
18700
18701   if (prefix_set == 0)
18702     {
18703       errmsg ("<address>/<mask> not specified");
18704       return -99;
18705     }
18706
18707   if (vrf_id == ~0)
18708     {
18709       errmsg ("VRF ID required, not specified");
18710       return -99;
18711     }
18712
18713   if (vrf_id == 0)
18714     {
18715       errmsg
18716         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18717       return -99;
18718     }
18719
18720   if (vec_len (low_ports) == 0)
18721     {
18722       errmsg ("At least one port or port range required");
18723       return -99;
18724     }
18725
18726   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18727
18728   mp->is_add = is_add;
18729
18730   if (is_ipv6)
18731     {
18732       mp->is_ipv6 = 1;
18733       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18734     }
18735   else
18736     {
18737       mp->is_ipv6 = 0;
18738       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18739     }
18740
18741   mp->mask_length = length;
18742   mp->number_of_ranges = vec_len (low_ports);
18743
18744   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18745   vec_free (low_ports);
18746
18747   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18748   vec_free (high_ports);
18749
18750   mp->vrf_id = ntohl (vrf_id);
18751
18752   S (mp);
18753   W (ret);
18754   return ret;
18755 }
18756
18757 int
18758 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18759 {
18760   unformat_input_t *input = vam->input;
18761   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18762   u32 sw_if_index = ~0;
18763   int vrf_set = 0;
18764   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18765   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18766   u8 is_add = 1;
18767   int ret;
18768
18769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18770     {
18771       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18772         ;
18773       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18774         ;
18775       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18776         vrf_set = 1;
18777       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18778         vrf_set = 1;
18779       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18780         vrf_set = 1;
18781       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18782         vrf_set = 1;
18783       else if (unformat (input, "del"))
18784         is_add = 0;
18785       else
18786         break;
18787     }
18788
18789   if (sw_if_index == ~0)
18790     {
18791       errmsg ("Interface required but not specified");
18792       return -99;
18793     }
18794
18795   if (vrf_set == 0)
18796     {
18797       errmsg ("VRF ID required but not specified");
18798       return -99;
18799     }
18800
18801   if (tcp_out_vrf_id == 0
18802       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18803     {
18804       errmsg
18805         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18806       return -99;
18807     }
18808
18809   /* Construct the API message */
18810   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18811
18812   mp->sw_if_index = ntohl (sw_if_index);
18813   mp->is_add = is_add;
18814   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18815   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18816   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18817   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18818
18819   /* send it... */
18820   S (mp);
18821
18822   /* Wait for a reply... */
18823   W (ret);
18824   return ret;
18825 }
18826
18827 static int
18828 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18829 {
18830   unformat_input_t *i = vam->input;
18831   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18832   u32 local_sa_id = 0;
18833   u32 remote_sa_id = 0;
18834   ip4_address_t src_address;
18835   ip4_address_t dst_address;
18836   u8 is_add = 1;
18837   int ret;
18838
18839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18840     {
18841       if (unformat (i, "local_sa %d", &local_sa_id))
18842         ;
18843       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18844         ;
18845       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18846         ;
18847       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18848         ;
18849       else if (unformat (i, "del"))
18850         is_add = 0;
18851       else
18852         {
18853           clib_warning ("parse error '%U'", format_unformat_error, i);
18854           return -99;
18855         }
18856     }
18857
18858   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18859
18860   mp->local_sa_id = ntohl (local_sa_id);
18861   mp->remote_sa_id = ntohl (remote_sa_id);
18862   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18863   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18864   mp->is_add = is_add;
18865
18866   S (mp);
18867   W (ret);
18868   return ret;
18869 }
18870
18871 static int
18872 api_punt (vat_main_t * vam)
18873 {
18874   unformat_input_t *i = vam->input;
18875   vl_api_punt_t *mp;
18876   u32 ipv = ~0;
18877   u32 protocol = ~0;
18878   u32 port = ~0;
18879   int is_add = 1;
18880   int ret;
18881
18882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18883     {
18884       if (unformat (i, "ip %d", &ipv))
18885         ;
18886       else if (unformat (i, "protocol %d", &protocol))
18887         ;
18888       else if (unformat (i, "port %d", &port))
18889         ;
18890       else if (unformat (i, "del"))
18891         is_add = 0;
18892       else
18893         {
18894           clib_warning ("parse error '%U'", format_unformat_error, i);
18895           return -99;
18896         }
18897     }
18898
18899   M (PUNT, mp);
18900
18901   mp->is_add = (u8) is_add;
18902   mp->ipv = (u8) ipv;
18903   mp->l4_protocol = (u8) protocol;
18904   mp->l4_port = htons ((u16) port);
18905
18906   S (mp);
18907   W (ret);
18908   return ret;
18909 }
18910
18911 static void vl_api_ipsec_gre_tunnel_details_t_handler
18912   (vl_api_ipsec_gre_tunnel_details_t * mp)
18913 {
18914   vat_main_t *vam = &vat_main;
18915
18916   print (vam->ofp, "%11d%15U%15U%14d%14d",
18917          ntohl (mp->sw_if_index),
18918          format_ip4_address, &mp->src_address,
18919          format_ip4_address, &mp->dst_address,
18920          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18921 }
18922
18923 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18924   (vl_api_ipsec_gre_tunnel_details_t * mp)
18925 {
18926   vat_main_t *vam = &vat_main;
18927   vat_json_node_t *node = NULL;
18928   struct in_addr ip4;
18929
18930   if (VAT_JSON_ARRAY != vam->json_tree.type)
18931     {
18932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18933       vat_json_init_array (&vam->json_tree);
18934     }
18935   node = vat_json_array_add (&vam->json_tree);
18936
18937   vat_json_init_object (node);
18938   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18939   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18940   vat_json_object_add_ip4 (node, "src_address", ip4);
18941   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18942   vat_json_object_add_ip4 (node, "dst_address", ip4);
18943   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18944   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18945 }
18946
18947 static int
18948 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18949 {
18950   unformat_input_t *i = vam->input;
18951   vl_api_ipsec_gre_tunnel_dump_t *mp;
18952   vl_api_control_ping_t *mp_ping;
18953   u32 sw_if_index;
18954   u8 sw_if_index_set = 0;
18955   int ret;
18956
18957   /* Parse args required to build the message */
18958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18959     {
18960       if (unformat (i, "sw_if_index %d", &sw_if_index))
18961         sw_if_index_set = 1;
18962       else
18963         break;
18964     }
18965
18966   if (sw_if_index_set == 0)
18967     {
18968       sw_if_index = ~0;
18969     }
18970
18971   if (!vam->json_output)
18972     {
18973       print (vam->ofp, "%11s%15s%15s%14s%14s",
18974              "sw_if_index", "src_address", "dst_address",
18975              "local_sa_id", "remote_sa_id");
18976     }
18977
18978   /* Get list of gre-tunnel interfaces */
18979   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18980
18981   mp->sw_if_index = htonl (sw_if_index);
18982
18983   S (mp);
18984
18985   /* Use a control ping for synchronization */
18986   M (CONTROL_PING, mp_ping);
18987   S (mp_ping);
18988
18989   W (ret);
18990   return ret;
18991 }
18992
18993 static int
18994 api_delete_subif (vat_main_t * vam)
18995 {
18996   unformat_input_t *i = vam->input;
18997   vl_api_delete_subif_t *mp;
18998   u32 sw_if_index = ~0;
18999   int ret;
19000
19001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19002     {
19003       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19004         ;
19005       if (unformat (i, "sw_if_index %d", &sw_if_index))
19006         ;
19007       else
19008         break;
19009     }
19010
19011   if (sw_if_index == ~0)
19012     {
19013       errmsg ("missing sw_if_index");
19014       return -99;
19015     }
19016
19017   /* Construct the API message */
19018   M (DELETE_SUBIF, mp);
19019   mp->sw_if_index = ntohl (sw_if_index);
19020
19021   S (mp);
19022   W (ret);
19023   return ret;
19024 }
19025
19026 #define foreach_pbb_vtr_op      \
19027 _("disable",  L2_VTR_DISABLED)  \
19028 _("pop",  L2_VTR_POP_2)         \
19029 _("push",  L2_VTR_PUSH_2)
19030
19031 static int
19032 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19033 {
19034   unformat_input_t *i = vam->input;
19035   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19036   u32 sw_if_index = ~0, vtr_op = ~0;
19037   u16 outer_tag = ~0;
19038   u8 dmac[6], smac[6];
19039   u8 dmac_set = 0, smac_set = 0;
19040   u16 vlanid = 0;
19041   u32 sid = ~0;
19042   u32 tmp;
19043   int ret;
19044
19045   /* Shut up coverity */
19046   memset (dmac, 0, sizeof (dmac));
19047   memset (smac, 0, sizeof (smac));
19048
19049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19050     {
19051       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19052         ;
19053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19054         ;
19055       else if (unformat (i, "vtr_op %d", &vtr_op))
19056         ;
19057 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19058       foreach_pbb_vtr_op
19059 #undef _
19060         else if (unformat (i, "translate_pbb_stag"))
19061         {
19062           if (unformat (i, "%d", &tmp))
19063             {
19064               vtr_op = L2_VTR_TRANSLATE_2_1;
19065               outer_tag = tmp;
19066             }
19067           else
19068             {
19069               errmsg
19070                 ("translate_pbb_stag operation requires outer tag definition");
19071               return -99;
19072             }
19073         }
19074       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19075         dmac_set++;
19076       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19077         smac_set++;
19078       else if (unformat (i, "sid %d", &sid))
19079         ;
19080       else if (unformat (i, "vlanid %d", &tmp))
19081         vlanid = tmp;
19082       else
19083         {
19084           clib_warning ("parse error '%U'", format_unformat_error, i);
19085           return -99;
19086         }
19087     }
19088
19089   if ((sw_if_index == ~0) || (vtr_op == ~0))
19090     {
19091       errmsg ("missing sw_if_index or vtr operation");
19092       return -99;
19093     }
19094   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19095       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19096     {
19097       errmsg
19098         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19099       return -99;
19100     }
19101
19102   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19103   mp->sw_if_index = ntohl (sw_if_index);
19104   mp->vtr_op = ntohl (vtr_op);
19105   mp->outer_tag = ntohs (outer_tag);
19106   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19107   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19108   mp->b_vlanid = ntohs (vlanid);
19109   mp->i_sid = ntohl (sid);
19110
19111   S (mp);
19112   W (ret);
19113   return ret;
19114 }
19115
19116 static int
19117 api_flow_classify_set_interface (vat_main_t * vam)
19118 {
19119   unformat_input_t *i = vam->input;
19120   vl_api_flow_classify_set_interface_t *mp;
19121   u32 sw_if_index;
19122   int sw_if_index_set;
19123   u32 ip4_table_index = ~0;
19124   u32 ip6_table_index = ~0;
19125   u8 is_add = 1;
19126   int ret;
19127
19128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19129     {
19130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19131         sw_if_index_set = 1;
19132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19133         sw_if_index_set = 1;
19134       else if (unformat (i, "del"))
19135         is_add = 0;
19136       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19137         ;
19138       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19139         ;
19140       else
19141         {
19142           clib_warning ("parse error '%U'", format_unformat_error, i);
19143           return -99;
19144         }
19145     }
19146
19147   if (sw_if_index_set == 0)
19148     {
19149       errmsg ("missing interface name or sw_if_index");
19150       return -99;
19151     }
19152
19153   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19154
19155   mp->sw_if_index = ntohl (sw_if_index);
19156   mp->ip4_table_index = ntohl (ip4_table_index);
19157   mp->ip6_table_index = ntohl (ip6_table_index);
19158   mp->is_add = is_add;
19159
19160   S (mp);
19161   W (ret);
19162   return ret;
19163 }
19164
19165 static int
19166 api_flow_classify_dump (vat_main_t * vam)
19167 {
19168   unformat_input_t *i = vam->input;
19169   vl_api_flow_classify_dump_t *mp;
19170   vl_api_control_ping_t *mp_ping;
19171   u8 type = FLOW_CLASSIFY_N_TABLES;
19172   int ret;
19173
19174   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19175     ;
19176   else
19177     {
19178       errmsg ("classify table type must be specified");
19179       return -99;
19180     }
19181
19182   if (!vam->json_output)
19183     {
19184       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19185     }
19186
19187   M (FLOW_CLASSIFY_DUMP, mp);
19188   mp->type = type;
19189   /* send it... */
19190   S (mp);
19191
19192   /* Use a control ping for synchronization */
19193   M (CONTROL_PING, mp_ping);
19194   S (mp_ping);
19195
19196   /* Wait for a reply... */
19197   W (ret);
19198   return ret;
19199 }
19200
19201 static int
19202 api_feature_enable_disable (vat_main_t * vam)
19203 {
19204   unformat_input_t *i = vam->input;
19205   vl_api_feature_enable_disable_t *mp;
19206   u8 *arc_name = 0;
19207   u8 *feature_name = 0;
19208   u32 sw_if_index = ~0;
19209   u8 enable = 1;
19210   int ret;
19211
19212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19213     {
19214       if (unformat (i, "arc_name %s", &arc_name))
19215         ;
19216       else if (unformat (i, "feature_name %s", &feature_name))
19217         ;
19218       else
19219         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19220         ;
19221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19222         ;
19223       else if (unformat (i, "disable"))
19224         enable = 0;
19225       else
19226         break;
19227     }
19228
19229   if (arc_name == 0)
19230     {
19231       errmsg ("missing arc name");
19232       return -99;
19233     }
19234   if (vec_len (arc_name) > 63)
19235     {
19236       errmsg ("arc name too long");
19237     }
19238
19239   if (feature_name == 0)
19240     {
19241       errmsg ("missing feature name");
19242       return -99;
19243     }
19244   if (vec_len (feature_name) > 63)
19245     {
19246       errmsg ("feature name too long");
19247     }
19248
19249   if (sw_if_index == ~0)
19250     {
19251       errmsg ("missing interface name or sw_if_index");
19252       return -99;
19253     }
19254
19255   /* Construct the API message */
19256   M (FEATURE_ENABLE_DISABLE, mp);
19257   mp->sw_if_index = ntohl (sw_if_index);
19258   mp->enable = enable;
19259   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19260   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19261   vec_free (arc_name);
19262   vec_free (feature_name);
19263
19264   S (mp);
19265   W (ret);
19266   return ret;
19267 }
19268
19269 static int
19270 api_sw_interface_tag_add_del (vat_main_t * vam)
19271 {
19272   unformat_input_t *i = vam->input;
19273   vl_api_sw_interface_tag_add_del_t *mp;
19274   u32 sw_if_index = ~0;
19275   u8 *tag = 0;
19276   u8 enable = 1;
19277   int ret;
19278
19279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19280     {
19281       if (unformat (i, "tag %s", &tag))
19282         ;
19283       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19284         ;
19285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19286         ;
19287       else if (unformat (i, "del"))
19288         enable = 0;
19289       else
19290         break;
19291     }
19292
19293   if (sw_if_index == ~0)
19294     {
19295       errmsg ("missing interface name or sw_if_index");
19296       return -99;
19297     }
19298
19299   if (enable && (tag == 0))
19300     {
19301       errmsg ("no tag specified");
19302       return -99;
19303     }
19304
19305   /* Construct the API message */
19306   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19307   mp->sw_if_index = ntohl (sw_if_index);
19308   mp->is_add = enable;
19309   if (enable)
19310     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19311   vec_free (tag);
19312
19313   S (mp);
19314   W (ret);
19315   return ret;
19316 }
19317
19318 static void vl_api_l2_xconnect_details_t_handler
19319   (vl_api_l2_xconnect_details_t * mp)
19320 {
19321   vat_main_t *vam = &vat_main;
19322
19323   print (vam->ofp, "%15d%15d",
19324          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19325 }
19326
19327 static void vl_api_l2_xconnect_details_t_handler_json
19328   (vl_api_l2_xconnect_details_t * mp)
19329 {
19330   vat_main_t *vam = &vat_main;
19331   vat_json_node_t *node = NULL;
19332
19333   if (VAT_JSON_ARRAY != vam->json_tree.type)
19334     {
19335       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19336       vat_json_init_array (&vam->json_tree);
19337     }
19338   node = vat_json_array_add (&vam->json_tree);
19339
19340   vat_json_init_object (node);
19341   vat_json_object_add_uint (node, "rx_sw_if_index",
19342                             ntohl (mp->rx_sw_if_index));
19343   vat_json_object_add_uint (node, "tx_sw_if_index",
19344                             ntohl (mp->tx_sw_if_index));
19345 }
19346
19347 static int
19348 api_l2_xconnect_dump (vat_main_t * vam)
19349 {
19350   vl_api_l2_xconnect_dump_t *mp;
19351   vl_api_control_ping_t *mp_ping;
19352   int ret;
19353
19354   if (!vam->json_output)
19355     {
19356       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19357     }
19358
19359   M (L2_XCONNECT_DUMP, mp);
19360
19361   S (mp);
19362
19363   /* Use a control ping for synchronization */
19364   M (CONTROL_PING, mp_ping);
19365   S (mp_ping);
19366
19367   W (ret);
19368   return ret;
19369 }
19370
19371 static int
19372 api_sw_interface_set_mtu (vat_main_t * vam)
19373 {
19374   unformat_input_t *i = vam->input;
19375   vl_api_sw_interface_set_mtu_t *mp;
19376   u32 sw_if_index = ~0;
19377   u32 mtu = 0;
19378   int ret;
19379
19380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19381     {
19382       if (unformat (i, "mtu %d", &mtu))
19383         ;
19384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19385         ;
19386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19387         ;
19388       else
19389         break;
19390     }
19391
19392   if (sw_if_index == ~0)
19393     {
19394       errmsg ("missing interface name or sw_if_index");
19395       return -99;
19396     }
19397
19398   if (mtu == 0)
19399     {
19400       errmsg ("no mtu specified");
19401       return -99;
19402     }
19403
19404   /* Construct the API message */
19405   M (SW_INTERFACE_SET_MTU, mp);
19406   mp->sw_if_index = ntohl (sw_if_index);
19407   mp->mtu = ntohs ((u16) mtu);
19408
19409   S (mp);
19410   W (ret);
19411   return ret;
19412 }
19413
19414 static int
19415 api_p2p_ethernet_add (vat_main_t * vam)
19416 {
19417   unformat_input_t *i = vam->input;
19418   vl_api_p2p_ethernet_add_t *mp;
19419   u32 parent_if_index = ~0;
19420   u32 sub_id = ~0;
19421   u8 remote_mac[6];
19422   u8 mac_set = 0;
19423   int ret;
19424
19425   memset (remote_mac, 0, sizeof (remote_mac));
19426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19427     {
19428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19429         ;
19430       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19431         ;
19432       else
19433         if (unformat
19434             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19435         mac_set++;
19436       else if (unformat (i, "sub_id %d", &sub_id))
19437         ;
19438       else
19439         {
19440           clib_warning ("parse error '%U'", format_unformat_error, i);
19441           return -99;
19442         }
19443     }
19444
19445   if (parent_if_index == ~0)
19446     {
19447       errmsg ("missing interface name or sw_if_index");
19448       return -99;
19449     }
19450   if (mac_set == 0)
19451     {
19452       errmsg ("missing remote mac address");
19453       return -99;
19454     }
19455   if (sub_id == ~0)
19456     {
19457       errmsg ("missing sub-interface id");
19458       return -99;
19459     }
19460
19461   M (P2P_ETHERNET_ADD, mp);
19462   mp->parent_if_index = ntohl (parent_if_index);
19463   mp->subif_id = ntohl (sub_id);
19464   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19465
19466   S (mp);
19467   W (ret);
19468   return ret;
19469 }
19470
19471 static int
19472 api_p2p_ethernet_del (vat_main_t * vam)
19473 {
19474   unformat_input_t *i = vam->input;
19475   vl_api_p2p_ethernet_del_t *mp;
19476   u32 parent_if_index = ~0;
19477   u8 remote_mac[6];
19478   u8 mac_set = 0;
19479   int ret;
19480
19481   memset (remote_mac, 0, sizeof (remote_mac));
19482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19483     {
19484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19485         ;
19486       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19487         ;
19488       else
19489         if (unformat
19490             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19491         mac_set++;
19492       else
19493         {
19494           clib_warning ("parse error '%U'", format_unformat_error, i);
19495           return -99;
19496         }
19497     }
19498
19499   if (parent_if_index == ~0)
19500     {
19501       errmsg ("missing interface name or sw_if_index");
19502       return -99;
19503     }
19504   if (mac_set == 0)
19505     {
19506       errmsg ("missing remote mac address");
19507       return -99;
19508     }
19509
19510   M (P2P_ETHERNET_DEL, mp);
19511   mp->parent_if_index = ntohl (parent_if_index);
19512   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19513
19514   S (mp);
19515   W (ret);
19516   return ret;
19517 }
19518
19519 static int
19520 api_lldp_config (vat_main_t * vam)
19521 {
19522   unformat_input_t *i = vam->input;
19523   vl_api_lldp_config_t *mp;
19524   int tx_hold = 0;
19525   int tx_interval = 0;
19526   u8 *sys_name = NULL;
19527   int ret;
19528
19529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19530     {
19531       if (unformat (i, "system-name %s", &sys_name))
19532         ;
19533       else if (unformat (i, "tx-hold %d", &tx_hold))
19534         ;
19535       else if (unformat (i, "tx-interval %d", &tx_interval))
19536         ;
19537       else
19538         {
19539           clib_warning ("parse error '%U'", format_unformat_error, i);
19540           return -99;
19541         }
19542     }
19543
19544   vec_add1 (sys_name, 0);
19545
19546   M (LLDP_CONFIG, mp);
19547   mp->tx_hold = htonl (tx_hold);
19548   mp->tx_interval = htonl (tx_interval);
19549   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19550   vec_free (sys_name);
19551
19552   S (mp);
19553   W (ret);
19554   return ret;
19555 }
19556
19557 static int
19558 api_sw_interface_set_lldp (vat_main_t * vam)
19559 {
19560   unformat_input_t *i = vam->input;
19561   vl_api_sw_interface_set_lldp_t *mp;
19562   u32 sw_if_index = ~0;
19563   u32 enable = 1;
19564   u8 *port_desc = NULL;
19565   int ret;
19566
19567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19568     {
19569       if (unformat (i, "disable"))
19570         enable = 0;
19571       else
19572         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19573         ;
19574       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19575         ;
19576       else if (unformat (i, "port-desc %s", &port_desc))
19577         ;
19578       else
19579         break;
19580     }
19581
19582   if (sw_if_index == ~0)
19583     {
19584       errmsg ("missing interface name or sw_if_index");
19585       return -99;
19586     }
19587
19588   /* Construct the API message */
19589   vec_add1 (port_desc, 0);
19590   M (SW_INTERFACE_SET_LLDP, mp);
19591   mp->sw_if_index = ntohl (sw_if_index);
19592   mp->enable = enable;
19593   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19594   vec_free (port_desc);
19595
19596   S (mp);
19597   W (ret);
19598   return ret;
19599 }
19600
19601 static int
19602 q_or_quit (vat_main_t * vam)
19603 {
19604 #if VPP_API_TEST_BUILTIN == 0
19605   longjmp (vam->jump_buf, 1);
19606 #endif
19607   return 0;                     /* not so much */
19608 }
19609
19610 static int
19611 q (vat_main_t * vam)
19612 {
19613   return q_or_quit (vam);
19614 }
19615
19616 static int
19617 quit (vat_main_t * vam)
19618 {
19619   return q_or_quit (vam);
19620 }
19621
19622 static int
19623 comment (vat_main_t * vam)
19624 {
19625   return 0;
19626 }
19627
19628 static int
19629 cmd_cmp (void *a1, void *a2)
19630 {
19631   u8 **c1 = a1;
19632   u8 **c2 = a2;
19633
19634   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19635 }
19636
19637 static int
19638 help (vat_main_t * vam)
19639 {
19640   u8 **cmds = 0;
19641   u8 *name = 0;
19642   hash_pair_t *p;
19643   unformat_input_t *i = vam->input;
19644   int j;
19645
19646   if (unformat (i, "%s", &name))
19647     {
19648       uword *hs;
19649
19650       vec_add1 (name, 0);
19651
19652       hs = hash_get_mem (vam->help_by_name, name);
19653       if (hs)
19654         print (vam->ofp, "usage: %s %s", name, hs[0]);
19655       else
19656         print (vam->ofp, "No such msg / command '%s'", name);
19657       vec_free (name);
19658       return 0;
19659     }
19660
19661   print (vam->ofp, "Help is available for the following:");
19662
19663     /* *INDENT-OFF* */
19664     hash_foreach_pair (p, vam->function_by_name,
19665     ({
19666       vec_add1 (cmds, (u8 *)(p->key));
19667     }));
19668     /* *INDENT-ON* */
19669
19670   vec_sort_with_function (cmds, cmd_cmp);
19671
19672   for (j = 0; j < vec_len (cmds); j++)
19673     print (vam->ofp, "%s", cmds[j]);
19674
19675   vec_free (cmds);
19676   return 0;
19677 }
19678
19679 static int
19680 set (vat_main_t * vam)
19681 {
19682   u8 *name = 0, *value = 0;
19683   unformat_input_t *i = vam->input;
19684
19685   if (unformat (i, "%s", &name))
19686     {
19687       /* The input buffer is a vector, not a string. */
19688       value = vec_dup (i->buffer);
19689       vec_delete (value, i->index, 0);
19690       /* Almost certainly has a trailing newline */
19691       if (value[vec_len (value) - 1] == '\n')
19692         value[vec_len (value) - 1] = 0;
19693       /* Make sure it's a proper string, one way or the other */
19694       vec_add1 (value, 0);
19695       (void) clib_macro_set_value (&vam->macro_main,
19696                                    (char *) name, (char *) value);
19697     }
19698   else
19699     errmsg ("usage: set <name> <value>");
19700
19701   vec_free (name);
19702   vec_free (value);
19703   return 0;
19704 }
19705
19706 static int
19707 unset (vat_main_t * vam)
19708 {
19709   u8 *name = 0;
19710
19711   if (unformat (vam->input, "%s", &name))
19712     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19713       errmsg ("unset: %s wasn't set", name);
19714   vec_free (name);
19715   return 0;
19716 }
19717
19718 typedef struct
19719 {
19720   u8 *name;
19721   u8 *value;
19722 } macro_sort_t;
19723
19724
19725 static int
19726 macro_sort_cmp (void *a1, void *a2)
19727 {
19728   macro_sort_t *s1 = a1;
19729   macro_sort_t *s2 = a2;
19730
19731   return strcmp ((char *) (s1->name), (char *) (s2->name));
19732 }
19733
19734 static int
19735 dump_macro_table (vat_main_t * vam)
19736 {
19737   macro_sort_t *sort_me = 0, *sm;
19738   int i;
19739   hash_pair_t *p;
19740
19741     /* *INDENT-OFF* */
19742     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19743     ({
19744       vec_add2 (sort_me, sm, 1);
19745       sm->name = (u8 *)(p->key);
19746       sm->value = (u8 *) (p->value[0]);
19747     }));
19748     /* *INDENT-ON* */
19749
19750   vec_sort_with_function (sort_me, macro_sort_cmp);
19751
19752   if (vec_len (sort_me))
19753     print (vam->ofp, "%-15s%s", "Name", "Value");
19754   else
19755     print (vam->ofp, "The macro table is empty...");
19756
19757   for (i = 0; i < vec_len (sort_me); i++)
19758     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19759   return 0;
19760 }
19761
19762 static int
19763 dump_node_table (vat_main_t * vam)
19764 {
19765   int i, j;
19766   vlib_node_t *node, *next_node;
19767
19768   if (vec_len (vam->graph_nodes) == 0)
19769     {
19770       print (vam->ofp, "Node table empty, issue get_node_graph...");
19771       return 0;
19772     }
19773
19774   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19775     {
19776       node = vam->graph_nodes[i];
19777       print (vam->ofp, "[%d] %s", i, node->name);
19778       for (j = 0; j < vec_len (node->next_nodes); j++)
19779         {
19780           if (node->next_nodes[j] != ~0)
19781             {
19782               next_node = vam->graph_nodes[node->next_nodes[j]];
19783               print (vam->ofp, "  [%d] %s", j, next_node->name);
19784             }
19785         }
19786     }
19787   return 0;
19788 }
19789
19790 static int
19791 value_sort_cmp (void *a1, void *a2)
19792 {
19793   name_sort_t *n1 = a1;
19794   name_sort_t *n2 = a2;
19795
19796   if (n1->value < n2->value)
19797     return -1;
19798   if (n1->value > n2->value)
19799     return 1;
19800   return 0;
19801 }
19802
19803
19804 static int
19805 dump_msg_api_table (vat_main_t * vam)
19806 {
19807   api_main_t *am = &api_main;
19808   name_sort_t *nses = 0, *ns;
19809   hash_pair_t *hp;
19810   int i;
19811
19812   /* *INDENT-OFF* */
19813   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19814   ({
19815     vec_add2 (nses, ns, 1);
19816     ns->name = (u8 *)(hp->key);
19817     ns->value = (u32) hp->value[0];
19818   }));
19819   /* *INDENT-ON* */
19820
19821   vec_sort_with_function (nses, value_sort_cmp);
19822
19823   for (i = 0; i < vec_len (nses); i++)
19824     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19825   vec_free (nses);
19826   return 0;
19827 }
19828
19829 static int
19830 get_msg_id (vat_main_t * vam)
19831 {
19832   u8 *name_and_crc;
19833   u32 message_index;
19834
19835   if (unformat (vam->input, "%s", &name_and_crc))
19836     {
19837       message_index = vl_api_get_msg_index (name_and_crc);
19838       if (message_index == ~0)
19839         {
19840           print (vam->ofp, " '%s' not found", name_and_crc);
19841           return 0;
19842         }
19843       print (vam->ofp, " '%s' has message index %d",
19844              name_and_crc, message_index);
19845       return 0;
19846     }
19847   errmsg ("name_and_crc required...");
19848   return 0;
19849 }
19850
19851 static int
19852 search_node_table (vat_main_t * vam)
19853 {
19854   unformat_input_t *line_input = vam->input;
19855   u8 *node_to_find;
19856   int j;
19857   vlib_node_t *node, *next_node;
19858   uword *p;
19859
19860   if (vam->graph_node_index_by_name == 0)
19861     {
19862       print (vam->ofp, "Node table empty, issue get_node_graph...");
19863       return 0;
19864     }
19865
19866   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19867     {
19868       if (unformat (line_input, "%s", &node_to_find))
19869         {
19870           vec_add1 (node_to_find, 0);
19871           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19872           if (p == 0)
19873             {
19874               print (vam->ofp, "%s not found...", node_to_find);
19875               goto out;
19876             }
19877           node = vam->graph_nodes[p[0]];
19878           print (vam->ofp, "[%d] %s", p[0], node->name);
19879           for (j = 0; j < vec_len (node->next_nodes); j++)
19880             {
19881               if (node->next_nodes[j] != ~0)
19882                 {
19883                   next_node = vam->graph_nodes[node->next_nodes[j]];
19884                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19885                 }
19886             }
19887         }
19888
19889       else
19890         {
19891           clib_warning ("parse error '%U'", format_unformat_error,
19892                         line_input);
19893           return -99;
19894         }
19895
19896     out:
19897       vec_free (node_to_find);
19898
19899     }
19900
19901   return 0;
19902 }
19903
19904
19905 static int
19906 script (vat_main_t * vam)
19907 {
19908 #if (VPP_API_TEST_BUILTIN==0)
19909   u8 *s = 0;
19910   char *save_current_file;
19911   unformat_input_t save_input;
19912   jmp_buf save_jump_buf;
19913   u32 save_line_number;
19914
19915   FILE *new_fp, *save_ifp;
19916
19917   if (unformat (vam->input, "%s", &s))
19918     {
19919       new_fp = fopen ((char *) s, "r");
19920       if (new_fp == 0)
19921         {
19922           errmsg ("Couldn't open script file %s", s);
19923           vec_free (s);
19924           return -99;
19925         }
19926     }
19927   else
19928     {
19929       errmsg ("Missing script name");
19930       return -99;
19931     }
19932
19933   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19934   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19935   save_ifp = vam->ifp;
19936   save_line_number = vam->input_line_number;
19937   save_current_file = (char *) vam->current_file;
19938
19939   vam->input_line_number = 0;
19940   vam->ifp = new_fp;
19941   vam->current_file = s;
19942   do_one_file (vam);
19943
19944   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19945   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19946   vam->ifp = save_ifp;
19947   vam->input_line_number = save_line_number;
19948   vam->current_file = (u8 *) save_current_file;
19949   vec_free (s);
19950
19951   return 0;
19952 #else
19953   clib_warning ("use the exec command...");
19954   return -99;
19955 #endif
19956 }
19957
19958 static int
19959 echo (vat_main_t * vam)
19960 {
19961   print (vam->ofp, "%v", vam->input->buffer);
19962   return 0;
19963 }
19964
19965 /* List of API message constructors, CLI names map to api_xxx */
19966 #define foreach_vpe_api_msg                                             \
19967 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19968 _(sw_interface_dump,"")                                                 \
19969 _(sw_interface_set_flags,                                               \
19970   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19971 _(sw_interface_add_del_address,                                         \
19972   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19973 _(sw_interface_set_table,                                               \
19974   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19975 _(sw_interface_set_mpls_enable,                                         \
19976   "<intfc> | sw_if_index [disable | dis]")                              \
19977 _(sw_interface_set_vpath,                                               \
19978   "<intfc> | sw_if_index <id> enable | disable")                        \
19979 _(sw_interface_set_vxlan_bypass,                                        \
19980   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19981 _(sw_interface_set_l2_xconnect,                                         \
19982   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19983   "enable | disable")                                                   \
19984 _(sw_interface_set_l2_bridge,                                           \
19985   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19986   "[shg <split-horizon-group>] [bvi]\n"                                 \
19987   "enable | disable")                                                   \
19988 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19989 _(bridge_domain_add_del,                                                \
19990   "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") \
19991 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19992 _(l2fib_add_del,                                                        \
19993   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19994 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19995 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19996 _(l2_flags,                                                             \
19997   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19998 _(bridge_flags,                                                         \
19999   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20000 _(tap_connect,                                                          \
20001   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
20002 _(tap_modify,                                                           \
20003   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20004 _(tap_delete,                                                           \
20005   "<vpp-if-name> | sw_if_index <id>")                                   \
20006 _(sw_interface_tap_dump, "")                                            \
20007 _(ip_add_del_route,                                                     \
20008   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20009   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20010   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20011   "[multipath] [count <n>]")                                            \
20012 _(ip_mroute_add_del,                                                    \
20013   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20014   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20015 _(mpls_route_add_del,                                                   \
20016   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20017   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20018   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20019   "[multipath] [count <n>]")                                            \
20020 _(mpls_ip_bind_unbind,                                                  \
20021   "<label> <addr/len>")                                                 \
20022 _(mpls_tunnel_add_del,                                                  \
20023   " via <addr> [table-id <n>]\n"                                        \
20024   "sw_if_index <id>] [l2]  [del]")                                      \
20025 _(proxy_arp_add_del,                                                    \
20026   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20027 _(proxy_arp_intfc_enable_disable,                                       \
20028   "<intfc> | sw_if_index <id> enable | disable")                        \
20029 _(sw_interface_set_unnumbered,                                          \
20030   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20031 _(ip_neighbor_add_del,                                                  \
20032   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20033   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20034 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20035 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20036 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20037   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20038   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20039   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20040 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20041 _(reset_fib, "vrf <n> [ipv6]")                                          \
20042 _(dhcp_proxy_config,                                                    \
20043   "svr <v46-address> src <v46-address>\n"                               \
20044    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20045 _(dhcp_proxy_set_vss,                                                   \
20046   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20047 _(dhcp_proxy_dump, "ip6")                                               \
20048 _(dhcp_client_config,                                                   \
20049   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20050 _(set_ip_flow_hash,                                                     \
20051   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20052 _(sw_interface_ip6_enable_disable,                                      \
20053   "<intfc> | sw_if_index <id> enable | disable")                        \
20054 _(sw_interface_ip6_set_link_local_address,                              \
20055   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20056 _(ip6nd_proxy_add_del,                                                  \
20057   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20058 _(ip6nd_proxy_dump, "")                                                 \
20059 _(sw_interface_ip6nd_ra_prefix,                                         \
20060   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20061   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20062   "[nolink] [isno]")                                                    \
20063 _(sw_interface_ip6nd_ra_config,                                         \
20064   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20065   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20066   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20067 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20068 _(l2_patch_add_del,                                                     \
20069   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20070   "enable | disable")                                                   \
20071 _(sr_localsid_add_del,                                                  \
20072   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20073   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20074 _(classify_add_del_table,                                               \
20075   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20076   " [del] [del-chain] mask <mask-value>\n"                              \
20077   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20078   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20079 _(classify_add_del_session,                                             \
20080   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20081   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20082   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20083   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20084 _(classify_set_interface_ip_table,                                      \
20085   "<intfc> | sw_if_index <nn> table <nn>")                              \
20086 _(classify_set_interface_l2_tables,                                     \
20087   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20088   "  [other-table <nn>]")                                               \
20089 _(get_node_index, "node <node-name")                                    \
20090 _(add_node_next, "node <node-name> next <next-node-name>")              \
20091 _(l2tpv3_create_tunnel,                                                 \
20092   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20093   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20094   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20095 _(l2tpv3_set_tunnel_cookies,                                            \
20096   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20097   "[new_remote_cookie <nn>]\n")                                         \
20098 _(l2tpv3_interface_enable_disable,                                      \
20099   "<intfc> | sw_if_index <nn> enable | disable")                        \
20100 _(l2tpv3_set_lookup_key,                                                \
20101   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20102 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20103 _(vxlan_add_del_tunnel,                                                 \
20104   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20105   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20106   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20107 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20108 _(gre_add_del_tunnel,                                                   \
20109   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20110 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20111 _(l2_fib_clear_table, "")                                               \
20112 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20113 _(l2_interface_vlan_tag_rewrite,                                        \
20114   "<intfc> | sw_if_index <nn> \n"                                       \
20115   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20116   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20117 _(create_vhost_user_if,                                                 \
20118         "socket <filename> [server] [renumber <dev_instance>] "         \
20119         "[mac <mac_address>]")                                          \
20120 _(modify_vhost_user_if,                                                 \
20121         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20122         "[server] [renumber <dev_instance>]")                           \
20123 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20124 _(sw_interface_vhost_user_dump, "")                                     \
20125 _(show_version, "")                                                     \
20126 _(vxlan_gpe_add_del_tunnel,                                             \
20127   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20128   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20129   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20130   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20131 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20132 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20133 _(interface_name_renumber,                                              \
20134   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20135 _(input_acl_set_interface,                                              \
20136   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20137   "  [l2-table <nn>] [del]")                                            \
20138 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20139 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20140 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20141 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20142 _(ip_dump, "ipv4 | ipv6")                                               \
20143 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20144 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20145   "  spid_id <n> ")                                                     \
20146 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20147   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20148   "  integ_alg <alg> integ_key <hex>")                                  \
20149 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20150   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20151   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20152   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20153 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20154 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20155   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20156   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20157   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20158 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20159 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20160   "(auth_data 0x<data> | auth_data <data>)")                            \
20161 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20162   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20163 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20164   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20165   "(local|remote)")                                                     \
20166 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20167 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20168 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20169 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20170 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20171 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20172 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20173 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20174 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20175 _(delete_loopback,"sw_if_index <nn>")                                   \
20176 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20177 _(map_add_domain,                                                       \
20178   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20179   "ip6-src <ip6addr> "                                                  \
20180   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20181 _(map_del_domain, "index <n>")                                          \
20182 _(map_add_del_rule,                                                     \
20183   "index <n> psid <n> dst <ip6addr> [del]")                             \
20184 _(map_domain_dump, "")                                                  \
20185 _(map_rule_dump, "index <map-domain>")                                  \
20186 _(want_interface_events,  "enable|disable")                             \
20187 _(want_stats,"enable|disable")                                          \
20188 _(get_first_msg_id, "client <name>")                                    \
20189 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20190 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20191   "fib-id <nn> [ip4][ip6][default]")                                    \
20192 _(get_node_graph, " ")                                                  \
20193 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20194 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20195 _(ioam_disable, "")                                                     \
20196 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20197                             " sw_if_index <sw_if_index> p <priority> "  \
20198                             "w <weight>] [del]")                        \
20199 _(one_add_del_locator, "locator-set <locator_name> "                    \
20200                         "iface <intf> | sw_if_index <sw_if_index> "     \
20201                         "p <priority> w <weight> [del]")                \
20202 _(one_add_del_local_eid,"vni <vni> eid "                                \
20203                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20204                          "locator-set <locator_name> [del]"             \
20205                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20206 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20207 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20208 _(one_enable_disable, "enable|disable")                                 \
20209 _(one_map_register_enable_disable, "enable|disable")                    \
20210 _(one_map_register_fallback_threshold, "<value>")                       \
20211 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20212 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20213                                "[seid <seid>] "                         \
20214                                "rloc <locator> p <prio> "               \
20215                                "w <weight> [rloc <loc> ... ] "          \
20216                                "action <action> [del-all]")             \
20217 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20218                           "<local-eid>")                                \
20219 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20220 _(one_use_petr, "ip-address> | disable")                                \
20221 _(one_map_request_mode, "src-dst|dst-only")                             \
20222 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20223 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20224 _(one_locator_set_dump, "[local | remote]")                             \
20225 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20226 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20227                        "[local] | [remote]")                            \
20228 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20229 _(one_l2_arp_bd_get, "")                                                \
20230 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20231 _(one_stats_enable_disable, "enable|disalbe")                           \
20232 _(show_one_stats_enable_disable, "")                                    \
20233 _(one_eid_table_vni_dump, "")                                           \
20234 _(one_eid_table_map_dump, "l2|l3")                                      \
20235 _(one_map_resolver_dump, "")                                            \
20236 _(one_map_server_dump, "")                                              \
20237 _(one_adjacencies_get, "vni <vni>")                                     \
20238 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20239 _(show_one_rloc_probe_state, "")                                        \
20240 _(show_one_map_register_state, "")                                      \
20241 _(show_one_status, "")                                                  \
20242 _(one_stats_dump, "")                                                   \
20243 _(one_stats_flush, "")                                                  \
20244 _(one_get_map_request_itr_rlocs, "")                                    \
20245 _(one_map_register_set_ttl, "<ttl>")                                    \
20246 _(show_one_nsh_mapping, "")                                             \
20247 _(show_one_pitr, "")                                                    \
20248 _(show_one_use_petr, "")                                                \
20249 _(show_one_map_request_mode, "")                                        \
20250 _(show_one_map_register_ttl, "")                                        \
20251 _(show_one_map_register_fallback_threshold, "")                         \
20252 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20253                             " sw_if_index <sw_if_index> p <priority> "  \
20254                             "w <weight>] [del]")                        \
20255 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20256                         "iface <intf> | sw_if_index <sw_if_index> "     \
20257                         "p <priority> w <weight> [del]")                \
20258 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20259                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20260                          "locator-set <locator_name> [del]"             \
20261                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20262 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20263 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20264 _(lisp_enable_disable, "enable|disable")                                \
20265 _(lisp_map_register_enable_disable, "enable|disable")                   \
20266 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20267 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20268                                "[seid <seid>] "                         \
20269                                "rloc <locator> p <prio> "               \
20270                                "w <weight> [rloc <loc> ... ] "          \
20271                                "action <action> [del-all]")             \
20272 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20273                           "<local-eid>")                                \
20274 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20275 _(lisp_use_petr, "<ip-address> | disable")                              \
20276 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20277 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20278 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20279 _(lisp_locator_set_dump, "[local | remote]")                            \
20280 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20281 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20282                        "[local] | [remote]")                            \
20283 _(lisp_eid_table_vni_dump, "")                                          \
20284 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20285 _(lisp_map_resolver_dump, "")                                           \
20286 _(lisp_map_server_dump, "")                                             \
20287 _(lisp_adjacencies_get, "vni <vni>")                                    \
20288 _(gpe_fwd_entry_vnis_get, "")                                           \
20289 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20290 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20291                                 "[table <table-id>]")                   \
20292 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20293 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20294 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20295 _(gpe_get_encap_mode, "")                                               \
20296 _(lisp_gpe_add_del_iface, "up|down")                                    \
20297 _(lisp_gpe_enable_disable, "enable|disable")                            \
20298 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20299   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20300 _(show_lisp_rloc_probe_state, "")                                       \
20301 _(show_lisp_map_register_state, "")                                     \
20302 _(show_lisp_status, "")                                                 \
20303 _(lisp_get_map_request_itr_rlocs, "")                                   \
20304 _(show_lisp_pitr, "")                                                   \
20305 _(show_lisp_use_petr, "")                                               \
20306 _(show_lisp_map_request_mode, "")                                       \
20307 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20308 _(af_packet_delete, "name <host interface name>")                       \
20309 _(policer_add_del, "name <policer name> <params> [del]")                \
20310 _(policer_dump, "[name <policer name>]")                                \
20311 _(policer_classify_set_interface,                                       \
20312   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20313   "  [l2-table <nn>] [del]")                                            \
20314 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20315 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20316     "[master|slave]")                                                   \
20317 _(netmap_delete, "name <interface name>")                               \
20318 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20319 _(mpls_fib_dump, "")                                                    \
20320 _(classify_table_ids, "")                                               \
20321 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20322 _(classify_table_info, "table_id <nn>")                                 \
20323 _(classify_session_dump, "table_id <nn>")                               \
20324 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20325     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20326     "[template_interval <nn>] [udp_checksum]")                          \
20327 _(ipfix_exporter_dump, "")                                              \
20328 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20329 _(ipfix_classify_stream_dump, "")                                       \
20330 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20331 _(ipfix_classify_table_dump, "")                                        \
20332 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20333 _(sw_interface_span_dump, "[l2]")                                           \
20334 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20335 _(pg_create_interface, "if_id <nn>")                                    \
20336 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20337 _(pg_enable_disable, "[stream <id>] disable")                           \
20338 _(ip_source_and_port_range_check_add_del,                               \
20339   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20340 _(ip_source_and_port_range_check_interface_add_del,                     \
20341   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20342   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20343 _(ipsec_gre_add_del_tunnel,                                             \
20344   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20345 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20346 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20347 _(l2_interface_pbb_tag_rewrite,                                         \
20348   "<intfc> | sw_if_index <nn> \n"                                       \
20349   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20350   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20351 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20352 _(flow_classify_set_interface,                                          \
20353   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20354 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20355 _(ip_fib_dump, "")                                                      \
20356 _(ip_mfib_dump, "")                                                     \
20357 _(ip6_fib_dump, "")                                                     \
20358 _(ip6_mfib_dump, "")                                                    \
20359 _(feature_enable_disable, "arc_name <arc_name> "                        \
20360   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20361 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20362 "[disable]")                                                            \
20363 _(l2_xconnect_dump, "")                                                 \
20364 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20365 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20366 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20367 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20368 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20369 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20370 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]")
20371
20372 /* List of command functions, CLI names map directly to functions */
20373 #define foreach_cli_function                                    \
20374 _(comment, "usage: comment <ignore-rest-of-line>")              \
20375 _(dump_interface_table, "usage: dump_interface_table")          \
20376 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20377 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20378 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20379 _(dump_stats_table, "usage: dump_stats_table")                  \
20380 _(dump_macro_table, "usage: dump_macro_table ")                 \
20381 _(dump_node_table, "usage: dump_node_table")                    \
20382 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20383 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20384 _(echo, "usage: echo <message>")                                \
20385 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20386 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20387 _(help, "usage: help")                                          \
20388 _(q, "usage: quit")                                             \
20389 _(quit, "usage: quit")                                          \
20390 _(search_node_table, "usage: search_node_table <name>...")      \
20391 _(set, "usage: set <variable-name> <value>")                    \
20392 _(script, "usage: script <file-name>")                          \
20393 _(unset, "usage: unset <variable-name>")
20394 #define _(N,n)                                  \
20395     static void vl_api_##n##_t_handler_uni      \
20396     (vl_api_##n##_t * mp)                       \
20397     {                                           \
20398         vat_main_t * vam = &vat_main;           \
20399         if (vam->json_output) {                 \
20400             vl_api_##n##_t_handler_json(mp);    \
20401         } else {                                \
20402             vl_api_##n##_t_handler(mp);         \
20403         }                                       \
20404     }
20405 foreach_vpe_api_reply_msg;
20406 #if VPP_API_TEST_BUILTIN == 0
20407 foreach_standalone_reply_msg;
20408 #endif
20409 #undef _
20410
20411 void
20412 vat_api_hookup (vat_main_t * vam)
20413 {
20414 #define _(N,n)                                                  \
20415     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20416                            vl_api_##n##_t_handler_uni,          \
20417                            vl_noop_handler,                     \
20418                            vl_api_##n##_t_endian,               \
20419                            vl_api_##n##_t_print,                \
20420                            sizeof(vl_api_##n##_t), 1);
20421   foreach_vpe_api_reply_msg;
20422 #if VPP_API_TEST_BUILTIN == 0
20423   foreach_standalone_reply_msg;
20424 #endif
20425 #undef _
20426
20427 #if (VPP_API_TEST_BUILTIN==0)
20428   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20429
20430   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20431
20432   vam->function_by_name = hash_create_string (0, sizeof (uword));
20433
20434   vam->help_by_name = hash_create_string (0, sizeof (uword));
20435 #endif
20436
20437   /* API messages we can send */
20438 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20439   foreach_vpe_api_msg;
20440 #undef _
20441
20442   /* Help strings */
20443 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20444   foreach_vpe_api_msg;
20445 #undef _
20446
20447   /* CLI functions */
20448 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20449   foreach_cli_function;
20450 #undef _
20451
20452   /* Help strings */
20453 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20454   foreach_cli_function;
20455 #undef _
20456 }
20457
20458 #if VPP_API_TEST_BUILTIN
20459 static clib_error_t *
20460 vat_api_hookup_shim (vlib_main_t * vm)
20461 {
20462   vat_api_hookup (&vat_main);
20463   return 0;
20464 }
20465
20466 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20467 #endif
20468
20469 /*
20470  * fd.io coding-style-patch-verification: ON
20471  *
20472  * Local Variables:
20473  * eval: (c-set-style "gnu")
20474  * End:
20475  */