TCP source address automation
[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_event_t_handler
976   (vl_api_sw_interface_event_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_event_t_handler_json
988   (vl_api_sw_interface_event_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_table_add_del_reply)                               \
4619 _(ip_mroute_add_del_reply)                              \
4620 _(mpls_route_add_del_reply)                             \
4621 _(mpls_table_add_del_reply)                             \
4622 _(mpls_ip_bind_unbind_reply)                            \
4623 _(proxy_arp_add_del_reply)                              \
4624 _(proxy_arp_intfc_enable_disable_reply)                 \
4625 _(sw_interface_set_unnumbered_reply)                    \
4626 _(ip_neighbor_add_del_reply)                            \
4627 _(reset_vrf_reply)                                      \
4628 _(oam_add_del_reply)                                    \
4629 _(reset_fib_reply)                                      \
4630 _(dhcp_proxy_config_reply)                              \
4631 _(dhcp_proxy_set_vss_reply)                             \
4632 _(dhcp_client_config_reply)                             \
4633 _(set_ip_flow_hash_reply)                               \
4634 _(sw_interface_ip6_enable_disable_reply)                \
4635 _(sw_interface_ip6_set_link_local_address_reply)        \
4636 _(ip6nd_proxy_add_del_reply)                            \
4637 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4638 _(sw_interface_ip6nd_ra_config_reply)                   \
4639 _(set_arp_neighbor_limit_reply)                         \
4640 _(l2_patch_add_del_reply)                               \
4641 _(sr_policy_add_reply)                                  \
4642 _(sr_policy_mod_reply)                                  \
4643 _(sr_policy_del_reply)                                  \
4644 _(sr_localsid_add_del_reply)                            \
4645 _(sr_steering_add_del_reply)                            \
4646 _(classify_add_del_session_reply)                       \
4647 _(classify_set_interface_ip_table_reply)                \
4648 _(classify_set_interface_l2_tables_reply)               \
4649 _(l2tpv3_set_tunnel_cookies_reply)                      \
4650 _(l2tpv3_interface_enable_disable_reply)                \
4651 _(l2tpv3_set_lookup_key_reply)                          \
4652 _(l2_fib_clear_table_reply)                             \
4653 _(l2_interface_efp_filter_reply)                        \
4654 _(l2_interface_vlan_tag_rewrite_reply)                  \
4655 _(modify_vhost_user_if_reply)                           \
4656 _(delete_vhost_user_if_reply)                           \
4657 _(want_ip4_arp_events_reply)                            \
4658 _(want_ip6_nd_events_reply)                             \
4659 _(want_l2_macs_events_reply)                            \
4660 _(input_acl_set_interface_reply)                        \
4661 _(ipsec_spd_add_del_reply)                              \
4662 _(ipsec_interface_add_del_spd_reply)                    \
4663 _(ipsec_spd_add_del_entry_reply)                        \
4664 _(ipsec_sad_add_del_entry_reply)                        \
4665 _(ipsec_sa_set_key_reply)                               \
4666 _(ipsec_tunnel_if_add_del_reply)                        \
4667 _(ikev2_profile_add_del_reply)                          \
4668 _(ikev2_profile_set_auth_reply)                         \
4669 _(ikev2_profile_set_id_reply)                           \
4670 _(ikev2_profile_set_ts_reply)                           \
4671 _(ikev2_set_local_key_reply)                            \
4672 _(ikev2_set_responder_reply)                            \
4673 _(ikev2_set_ike_transforms_reply)                       \
4674 _(ikev2_set_esp_transforms_reply)                       \
4675 _(ikev2_set_sa_lifetime_reply)                          \
4676 _(ikev2_initiate_sa_init_reply)                         \
4677 _(ikev2_initiate_del_ike_sa_reply)                      \
4678 _(ikev2_initiate_del_child_sa_reply)                    \
4679 _(ikev2_initiate_rekey_child_sa_reply)                  \
4680 _(delete_loopback_reply)                                \
4681 _(bd_ip_mac_add_del_reply)                              \
4682 _(map_del_domain_reply)                                 \
4683 _(map_add_del_rule_reply)                               \
4684 _(want_interface_events_reply)                          \
4685 _(want_stats_reply)                                     \
4686 _(cop_interface_enable_disable_reply)                   \
4687 _(cop_whitelist_enable_disable_reply)                   \
4688 _(sw_interface_clear_stats_reply)                       \
4689 _(ioam_enable_reply)                              \
4690 _(ioam_disable_reply)                              \
4691 _(one_add_del_locator_reply)                            \
4692 _(one_add_del_local_eid_reply)                          \
4693 _(one_add_del_remote_mapping_reply)                     \
4694 _(one_add_del_adjacency_reply)                          \
4695 _(one_add_del_map_resolver_reply)                       \
4696 _(one_add_del_map_server_reply)                         \
4697 _(one_enable_disable_reply)                             \
4698 _(one_rloc_probe_enable_disable_reply)                  \
4699 _(one_map_register_enable_disable_reply)                \
4700 _(one_map_register_set_ttl_reply)                       \
4701 _(one_map_register_fallback_threshold_reply)            \
4702 _(one_pitr_set_locator_set_reply)                       \
4703 _(one_map_request_mode_reply)                           \
4704 _(one_add_del_map_request_itr_rlocs_reply)              \
4705 _(one_eid_table_add_del_map_reply)                      \
4706 _(one_use_petr_reply)                                   \
4707 _(one_stats_enable_disable_reply)                       \
4708 _(one_add_del_l2_arp_entry_reply)                       \
4709 _(one_stats_flush_reply)                                \
4710 _(gpe_enable_disable_reply)                             \
4711 _(gpe_set_encap_mode_reply)                             \
4712 _(gpe_add_del_iface_reply)                              \
4713 _(gpe_add_del_native_fwd_rpath_reply)                   \
4714 _(af_packet_delete_reply)                               \
4715 _(policer_classify_set_interface_reply)                 \
4716 _(netmap_create_reply)                                  \
4717 _(netmap_delete_reply)                                  \
4718 _(set_ipfix_exporter_reply)                             \
4719 _(set_ipfix_classify_stream_reply)                      \
4720 _(ipfix_classify_table_add_del_reply)                   \
4721 _(flow_classify_set_interface_reply)                    \
4722 _(sw_interface_span_enable_disable_reply)               \
4723 _(pg_capture_reply)                                     \
4724 _(pg_enable_disable_reply)                              \
4725 _(ip_source_and_port_range_check_add_del_reply)         \
4726 _(ip_source_and_port_range_check_interface_add_del_reply)\
4727 _(delete_subif_reply)                                   \
4728 _(l2_interface_pbb_tag_rewrite_reply)                   \
4729 _(punt_reply)                                           \
4730 _(feature_enable_disable_reply)                         \
4731 _(sw_interface_tag_add_del_reply)                       \
4732 _(sw_interface_set_mtu_reply)                           \
4733 _(p2p_ethernet_add_reply)                               \
4734 _(p2p_ethernet_del_reply)                               \
4735 _(lldp_config_reply)                                    \
4736 _(sw_interface_set_lldp_reply)                          \
4737 _(tcp_configure_src_addresses_reply)
4738
4739 #define _(n)                                    \
4740     static void vl_api_##n##_t_handler          \
4741     (vl_api_##n##_t * mp)                       \
4742     {                                           \
4743         vat_main_t * vam = &vat_main;           \
4744         i32 retval = ntohl(mp->retval);         \
4745         if (vam->async_mode) {                  \
4746             vam->async_errors += (retval < 0);  \
4747         } else {                                \
4748             vam->retval = retval;               \
4749             vam->result_ready = 1;              \
4750         }                                       \
4751     }
4752 foreach_standard_reply_retval_handler;
4753 #undef _
4754
4755 #define _(n)                                    \
4756     static void vl_api_##n##_t_handler_json     \
4757     (vl_api_##n##_t * mp)                       \
4758     {                                           \
4759         vat_main_t * vam = &vat_main;           \
4760         vat_json_node_t node;                   \
4761         vat_json_init_object(&node);            \
4762         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4763         vat_json_print(vam->ofp, &node);        \
4764         vam->retval = ntohl(mp->retval);        \
4765         vam->result_ready = 1;                  \
4766     }
4767 foreach_standard_reply_retval_handler;
4768 #undef _
4769
4770 /*
4771  * Table of message reply handlers, must include boilerplate handlers
4772  * we just generated
4773  */
4774
4775 #define foreach_vpe_api_reply_msg                                       \
4776 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4777 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4778 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4779 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4780 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4781 _(CLI_REPLY, cli_reply)                                                 \
4782 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4783 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4784   sw_interface_add_del_address_reply)                                   \
4785 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4786 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4787 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4788 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4789 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4790 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4791   sw_interface_set_l2_xconnect_reply)                                   \
4792 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4793   sw_interface_set_l2_bridge_reply)                                     \
4794 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4795 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4796 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4797 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4798 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4799 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4800 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4801 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4802 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4803 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4804 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4805 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4806 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4807 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
4808 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4809 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
4810 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4811 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4812 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4813 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4814   proxy_arp_intfc_enable_disable_reply)                                 \
4815 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4816 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4817   sw_interface_set_unnumbered_reply)                                    \
4818 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4819 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4820 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4821 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4822 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4823 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4824 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4825 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4826 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4827 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4828 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4829 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4830   sw_interface_ip6_enable_disable_reply)                                \
4831 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4832   sw_interface_ip6_set_link_local_address_reply)                        \
4833 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4834 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4835 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4836   sw_interface_ip6nd_ra_prefix_reply)                                   \
4837 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4838   sw_interface_ip6nd_ra_config_reply)                                   \
4839 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4840 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4841 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4842 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4843 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4844 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4845 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4846 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4847 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4848 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4849 classify_set_interface_ip_table_reply)                                  \
4850 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4851   classify_set_interface_l2_tables_reply)                               \
4852 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4853 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4854 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4855 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4856 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4857   l2tpv3_interface_enable_disable_reply)                                \
4858 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4859 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4860 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4861 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4862 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4863 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4864 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4865 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4866 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4867 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4868 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4869 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4870 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4871 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4872 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4873 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4874 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4875 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4876 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4877 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4878 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4879 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4880 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
4881 _(L2_MACS_EVENT, l2_macs_event)                                         \
4882 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4883 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4884 _(IP_DETAILS, ip_details)                                               \
4885 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4886 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4887 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4888 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4889 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4890 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4891 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4892 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4893 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4894 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4895 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4896 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4897 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4898 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4899 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4900 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4901 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4902 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4903 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4904 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4905 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4906 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4907 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4908 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4909 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4910 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4911 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4912 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4913 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4914 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4915 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4916 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4917 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4918 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4919 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4920 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4921 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4922 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4923 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4924 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4925 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4926 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4927 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4928 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4929 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4930   one_map_register_enable_disable_reply)                                \
4931 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
4932 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
4933   one_map_register_fallback_threshold_reply)                            \
4934 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4935   one_rloc_probe_enable_disable_reply)                                  \
4936 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4937 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4938 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4939 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4940 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4941 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4942 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4943 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4944 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4945 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4946 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4947 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4948 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4949 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4950 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4951 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4952   show_one_stats_enable_disable_reply)                                  \
4953 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4954 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4955 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4956 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4957 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4958 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4959 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4960 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4961 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4962 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4963 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4964 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4965   gpe_add_del_native_fwd_rpath_reply)                                   \
4966 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4967   gpe_fwd_entry_path_details)                                           \
4968 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4969 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4970   one_add_del_map_request_itr_rlocs_reply)                              \
4971 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4972   one_get_map_request_itr_rlocs_reply)                                  \
4973 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4974 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4975 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4976 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4977 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4978 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4979   show_one_map_register_state_reply)                                    \
4980 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
4981 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
4982   show_one_map_register_fallback_threshold_reply)                       \
4983 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4984 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4985 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4986 _(POLICER_DETAILS, policer_details)                                     \
4987 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4988 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4989 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4990 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4991 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4992 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4993 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4994 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4995 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4996 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4997 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4998 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4999 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5000 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5001 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5002 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5003 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5004 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5005 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5006 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5007 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5008 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5009 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5010 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5011 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5012  ip_source_and_port_range_check_add_del_reply)                          \
5013 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5014  ip_source_and_port_range_check_interface_add_del_reply)                \
5015 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5016 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5017 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5018 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5019 _(PUNT_REPLY, punt_reply)                                               \
5020 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5021 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5022 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5023 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5024 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5025 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5026 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5027 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5028 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5029 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5030 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5031 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5032 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply)
5033
5034 #define foreach_standalone_reply_msg                                    \
5035 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5036 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5037 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5038 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5039 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5040 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5041 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5042
5043 typedef struct
5044 {
5045   u8 *name;
5046   u32 value;
5047 } name_sort_t;
5048
5049
5050 #define STR_VTR_OP_CASE(op)     \
5051     case L2_VTR_ ## op:         \
5052         return "" # op;
5053
5054 static const char *
5055 str_vtr_op (u32 vtr_op)
5056 {
5057   switch (vtr_op)
5058     {
5059       STR_VTR_OP_CASE (DISABLED);
5060       STR_VTR_OP_CASE (PUSH_1);
5061       STR_VTR_OP_CASE (PUSH_2);
5062       STR_VTR_OP_CASE (POP_1);
5063       STR_VTR_OP_CASE (POP_2);
5064       STR_VTR_OP_CASE (TRANSLATE_1_1);
5065       STR_VTR_OP_CASE (TRANSLATE_1_2);
5066       STR_VTR_OP_CASE (TRANSLATE_2_1);
5067       STR_VTR_OP_CASE (TRANSLATE_2_2);
5068     }
5069
5070   return "UNKNOWN";
5071 }
5072
5073 static int
5074 dump_sub_interface_table (vat_main_t * vam)
5075 {
5076   const sw_interface_subif_t *sub = NULL;
5077
5078   if (vam->json_output)
5079     {
5080       clib_warning
5081         ("JSON output supported only for VPE API calls and dump_stats_table");
5082       return -99;
5083     }
5084
5085   print (vam->ofp,
5086          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5087          "Interface", "sw_if_index",
5088          "sub id", "dot1ad", "tags", "outer id",
5089          "inner id", "exact", "default", "outer any", "inner any");
5090
5091   vec_foreach (sub, vam->sw_if_subif_table)
5092   {
5093     print (vam->ofp,
5094            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5095            sub->interface_name,
5096            sub->sw_if_index,
5097            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5098            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5099            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5100            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5101     if (sub->vtr_op != L2_VTR_DISABLED)
5102       {
5103         print (vam->ofp,
5104                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5105                "tag1: %d tag2: %d ]",
5106                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5107                sub->vtr_tag1, sub->vtr_tag2);
5108       }
5109   }
5110
5111   return 0;
5112 }
5113
5114 static int
5115 name_sort_cmp (void *a1, void *a2)
5116 {
5117   name_sort_t *n1 = a1;
5118   name_sort_t *n2 = a2;
5119
5120   return strcmp ((char *) n1->name, (char *) n2->name);
5121 }
5122
5123 static int
5124 dump_interface_table (vat_main_t * vam)
5125 {
5126   hash_pair_t *p;
5127   name_sort_t *nses = 0, *ns;
5128
5129   if (vam->json_output)
5130     {
5131       clib_warning
5132         ("JSON output supported only for VPE API calls and dump_stats_table");
5133       return -99;
5134     }
5135
5136   /* *INDENT-OFF* */
5137   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5138   ({
5139     vec_add2 (nses, ns, 1);
5140     ns->name = (u8 *)(p->key);
5141     ns->value = (u32) p->value[0];
5142   }));
5143   /* *INDENT-ON* */
5144
5145   vec_sort_with_function (nses, name_sort_cmp);
5146
5147   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5148   vec_foreach (ns, nses)
5149   {
5150     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5151   }
5152   vec_free (nses);
5153   return 0;
5154 }
5155
5156 static int
5157 dump_ip_table (vat_main_t * vam, int is_ipv6)
5158 {
5159   const ip_details_t *det = NULL;
5160   const ip_address_details_t *address = NULL;
5161   u32 i = ~0;
5162
5163   print (vam->ofp, "%-12s", "sw_if_index");
5164
5165   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5166   {
5167     i++;
5168     if (!det->present)
5169       {
5170         continue;
5171       }
5172     print (vam->ofp, "%-12d", i);
5173     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5174     if (!det->addr)
5175       {
5176         continue;
5177       }
5178     vec_foreach (address, det->addr)
5179     {
5180       print (vam->ofp,
5181              "            %-30U%-13d",
5182              is_ipv6 ? format_ip6_address : format_ip4_address,
5183              address->ip, address->prefix_length);
5184     }
5185   }
5186
5187   return 0;
5188 }
5189
5190 static int
5191 dump_ipv4_table (vat_main_t * vam)
5192 {
5193   if (vam->json_output)
5194     {
5195       clib_warning
5196         ("JSON output supported only for VPE API calls and dump_stats_table");
5197       return -99;
5198     }
5199
5200   return dump_ip_table (vam, 0);
5201 }
5202
5203 static int
5204 dump_ipv6_table (vat_main_t * vam)
5205 {
5206   if (vam->json_output)
5207     {
5208       clib_warning
5209         ("JSON output supported only for VPE API calls and dump_stats_table");
5210       return -99;
5211     }
5212
5213   return dump_ip_table (vam, 1);
5214 }
5215
5216 static char *
5217 counter_type_to_str (u8 counter_type, u8 is_combined)
5218 {
5219   if (!is_combined)
5220     {
5221       switch (counter_type)
5222         {
5223         case VNET_INTERFACE_COUNTER_DROP:
5224           return "drop";
5225         case VNET_INTERFACE_COUNTER_PUNT:
5226           return "punt";
5227         case VNET_INTERFACE_COUNTER_IP4:
5228           return "ip4";
5229         case VNET_INTERFACE_COUNTER_IP6:
5230           return "ip6";
5231         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5232           return "rx-no-buf";
5233         case VNET_INTERFACE_COUNTER_RX_MISS:
5234           return "rx-miss";
5235         case VNET_INTERFACE_COUNTER_RX_ERROR:
5236           return "rx-error";
5237         case VNET_INTERFACE_COUNTER_TX_ERROR:
5238           return "tx-error";
5239         default:
5240           return "INVALID-COUNTER-TYPE";
5241         }
5242     }
5243   else
5244     {
5245       switch (counter_type)
5246         {
5247         case VNET_INTERFACE_COUNTER_RX:
5248           return "rx";
5249         case VNET_INTERFACE_COUNTER_TX:
5250           return "tx";
5251         default:
5252           return "INVALID-COUNTER-TYPE";
5253         }
5254     }
5255 }
5256
5257 static int
5258 dump_stats_table (vat_main_t * vam)
5259 {
5260   vat_json_node_t node;
5261   vat_json_node_t *msg_array;
5262   vat_json_node_t *msg;
5263   vat_json_node_t *counter_array;
5264   vat_json_node_t *counter;
5265   interface_counter_t c;
5266   u64 packets;
5267   ip4_fib_counter_t *c4;
5268   ip6_fib_counter_t *c6;
5269   ip4_nbr_counter_t *n4;
5270   ip6_nbr_counter_t *n6;
5271   int i, j;
5272
5273   if (!vam->json_output)
5274     {
5275       clib_warning ("dump_stats_table supported only in JSON format");
5276       return -99;
5277     }
5278
5279   vat_json_init_object (&node);
5280
5281   /* interface counters */
5282   msg_array = vat_json_object_add (&node, "interface_counters");
5283   vat_json_init_array (msg_array);
5284   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5285     {
5286       msg = vat_json_array_add (msg_array);
5287       vat_json_init_object (msg);
5288       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5289                                        (u8 *) counter_type_to_str (i, 0));
5290       vat_json_object_add_int (msg, "is_combined", 0);
5291       counter_array = vat_json_object_add (msg, "data");
5292       vat_json_init_array (counter_array);
5293       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5294         {
5295           packets = vam->simple_interface_counters[i][j];
5296           vat_json_array_add_uint (counter_array, packets);
5297         }
5298     }
5299   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5300     {
5301       msg = vat_json_array_add (msg_array);
5302       vat_json_init_object (msg);
5303       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5304                                        (u8 *) counter_type_to_str (i, 1));
5305       vat_json_object_add_int (msg, "is_combined", 1);
5306       counter_array = vat_json_object_add (msg, "data");
5307       vat_json_init_array (counter_array);
5308       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5309         {
5310           c = vam->combined_interface_counters[i][j];
5311           counter = vat_json_array_add (counter_array);
5312           vat_json_init_object (counter);
5313           vat_json_object_add_uint (counter, "packets", c.packets);
5314           vat_json_object_add_uint (counter, "bytes", c.bytes);
5315         }
5316     }
5317
5318   /* ip4 fib counters */
5319   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5320   vat_json_init_array (msg_array);
5321   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5322     {
5323       msg = vat_json_array_add (msg_array);
5324       vat_json_init_object (msg);
5325       vat_json_object_add_uint (msg, "vrf_id",
5326                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5327       counter_array = vat_json_object_add (msg, "c");
5328       vat_json_init_array (counter_array);
5329       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5330         {
5331           counter = vat_json_array_add (counter_array);
5332           vat_json_init_object (counter);
5333           c4 = &vam->ip4_fib_counters[i][j];
5334           vat_json_object_add_ip4 (counter, "address", c4->address);
5335           vat_json_object_add_uint (counter, "address_length",
5336                                     c4->address_length);
5337           vat_json_object_add_uint (counter, "packets", c4->packets);
5338           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5339         }
5340     }
5341
5342   /* ip6 fib counters */
5343   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5344   vat_json_init_array (msg_array);
5345   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5346     {
5347       msg = vat_json_array_add (msg_array);
5348       vat_json_init_object (msg);
5349       vat_json_object_add_uint (msg, "vrf_id",
5350                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5351       counter_array = vat_json_object_add (msg, "c");
5352       vat_json_init_array (counter_array);
5353       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5354         {
5355           counter = vat_json_array_add (counter_array);
5356           vat_json_init_object (counter);
5357           c6 = &vam->ip6_fib_counters[i][j];
5358           vat_json_object_add_ip6 (counter, "address", c6->address);
5359           vat_json_object_add_uint (counter, "address_length",
5360                                     c6->address_length);
5361           vat_json_object_add_uint (counter, "packets", c6->packets);
5362           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5363         }
5364     }
5365
5366   /* ip4 nbr counters */
5367   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5368   vat_json_init_array (msg_array);
5369   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5370     {
5371       msg = vat_json_array_add (msg_array);
5372       vat_json_init_object (msg);
5373       vat_json_object_add_uint (msg, "sw_if_index", i);
5374       counter_array = vat_json_object_add (msg, "c");
5375       vat_json_init_array (counter_array);
5376       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5377         {
5378           counter = vat_json_array_add (counter_array);
5379           vat_json_init_object (counter);
5380           n4 = &vam->ip4_nbr_counters[i][j];
5381           vat_json_object_add_ip4 (counter, "address", n4->address);
5382           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5383           vat_json_object_add_uint (counter, "packets", n4->packets);
5384           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5385         }
5386     }
5387
5388   /* ip6 nbr counters */
5389   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5390   vat_json_init_array (msg_array);
5391   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5392     {
5393       msg = vat_json_array_add (msg_array);
5394       vat_json_init_object (msg);
5395       vat_json_object_add_uint (msg, "sw_if_index", i);
5396       counter_array = vat_json_object_add (msg, "c");
5397       vat_json_init_array (counter_array);
5398       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5399         {
5400           counter = vat_json_array_add (counter_array);
5401           vat_json_init_object (counter);
5402           n6 = &vam->ip6_nbr_counters[i][j];
5403           vat_json_object_add_ip6 (counter, "address", n6->address);
5404           vat_json_object_add_uint (counter, "packets", n6->packets);
5405           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5406         }
5407     }
5408
5409   vat_json_print (vam->ofp, &node);
5410   vat_json_free (&node);
5411
5412   return 0;
5413 }
5414
5415 int
5416 exec (vat_main_t * vam)
5417 {
5418   api_main_t *am = &api_main;
5419   vl_api_cli_t *mp;
5420   f64 timeout;
5421   void *oldheap;
5422   u8 *cmd = 0;
5423   unformat_input_t *i = vam->input;
5424
5425   if (vec_len (i->buffer) == 0)
5426     return -1;
5427
5428   if (vam->exec_mode == 0 && unformat (i, "mode"))
5429     {
5430       vam->exec_mode = 1;
5431       return 0;
5432     }
5433   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5434     {
5435       vam->exec_mode = 0;
5436       return 0;
5437     }
5438
5439
5440   M (CLI, mp);
5441
5442   /*
5443    * Copy cmd into shared memory.
5444    * In order for the CLI command to work, it
5445    * must be a vector ending in \n, not a C-string ending
5446    * in \n\0.
5447    */
5448   pthread_mutex_lock (&am->vlib_rp->mutex);
5449   oldheap = svm_push_data_heap (am->vlib_rp);
5450
5451   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5452   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5453
5454   svm_pop_heap (oldheap);
5455   pthread_mutex_unlock (&am->vlib_rp->mutex);
5456
5457   mp->cmd_in_shmem = pointer_to_uword (cmd);
5458   S (mp);
5459   timeout = vat_time_now (vam) + 10.0;
5460
5461   while (vat_time_now (vam) < timeout)
5462     {
5463       if (vam->result_ready == 1)
5464         {
5465           u8 *free_me;
5466           if (vam->shmem_result != NULL)
5467             print (vam->ofp, "%s", vam->shmem_result);
5468           pthread_mutex_lock (&am->vlib_rp->mutex);
5469           oldheap = svm_push_data_heap (am->vlib_rp);
5470
5471           free_me = (u8 *) vam->shmem_result;
5472           vec_free (free_me);
5473
5474           svm_pop_heap (oldheap);
5475           pthread_mutex_unlock (&am->vlib_rp->mutex);
5476           return 0;
5477         }
5478     }
5479   return -99;
5480 }
5481
5482 /*
5483  * Future replacement of exec() that passes CLI buffers directly in
5484  * the API messages instead of an additional shared memory area.
5485  */
5486 static int
5487 exec_inband (vat_main_t * vam)
5488 {
5489   vl_api_cli_inband_t *mp;
5490   unformat_input_t *i = vam->input;
5491   int ret;
5492
5493   if (vec_len (i->buffer) == 0)
5494     return -1;
5495
5496   if (vam->exec_mode == 0 && unformat (i, "mode"))
5497     {
5498       vam->exec_mode = 1;
5499       return 0;
5500     }
5501   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5502     {
5503       vam->exec_mode = 0;
5504       return 0;
5505     }
5506
5507   /*
5508    * In order for the CLI command to work, it
5509    * must be a vector ending in \n, not a C-string ending
5510    * in \n\0.
5511    */
5512   u32 len = vec_len (vam->input->buffer);
5513   M2 (CLI_INBAND, mp, len);
5514   clib_memcpy (mp->cmd, vam->input->buffer, len);
5515   mp->length = htonl (len);
5516
5517   S (mp);
5518   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5519   return ret;
5520 }
5521
5522 static int
5523 api_create_loopback (vat_main_t * vam)
5524 {
5525   unformat_input_t *i = vam->input;
5526   vl_api_create_loopback_t *mp;
5527   vl_api_create_loopback_instance_t *mp_lbi;
5528   u8 mac_address[6];
5529   u8 mac_set = 0;
5530   u8 is_specified = 0;
5531   u32 user_instance = 0;
5532   int ret;
5533
5534   memset (mac_address, 0, sizeof (mac_address));
5535
5536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5537     {
5538       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5539         mac_set = 1;
5540       if (unformat (i, "instance %d", &user_instance))
5541         is_specified = 1;
5542       else
5543         break;
5544     }
5545
5546   if (is_specified)
5547     {
5548       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5549       mp_lbi->is_specified = is_specified;
5550       if (is_specified)
5551         mp_lbi->user_instance = htonl (user_instance);
5552       if (mac_set)
5553         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5554       S (mp_lbi);
5555     }
5556   else
5557     {
5558       /* Construct the API message */
5559       M (CREATE_LOOPBACK, mp);
5560       if (mac_set)
5561         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5562       S (mp);
5563     }
5564
5565   W (ret);
5566   return ret;
5567 }
5568
5569 static int
5570 api_delete_loopback (vat_main_t * vam)
5571 {
5572   unformat_input_t *i = vam->input;
5573   vl_api_delete_loopback_t *mp;
5574   u32 sw_if_index = ~0;
5575   int ret;
5576
5577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5578     {
5579       if (unformat (i, "sw_if_index %d", &sw_if_index))
5580         ;
5581       else
5582         break;
5583     }
5584
5585   if (sw_if_index == ~0)
5586     {
5587       errmsg ("missing sw_if_index");
5588       return -99;
5589     }
5590
5591   /* Construct the API message */
5592   M (DELETE_LOOPBACK, mp);
5593   mp->sw_if_index = ntohl (sw_if_index);
5594
5595   S (mp);
5596   W (ret);
5597   return ret;
5598 }
5599
5600 static int
5601 api_want_stats (vat_main_t * vam)
5602 {
5603   unformat_input_t *i = vam->input;
5604   vl_api_want_stats_t *mp;
5605   int enable = -1;
5606   int ret;
5607
5608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5609     {
5610       if (unformat (i, "enable"))
5611         enable = 1;
5612       else if (unformat (i, "disable"))
5613         enable = 0;
5614       else
5615         break;
5616     }
5617
5618   if (enable == -1)
5619     {
5620       errmsg ("missing enable|disable");
5621       return -99;
5622     }
5623
5624   M (WANT_STATS, mp);
5625   mp->enable_disable = enable;
5626
5627   S (mp);
5628   W (ret);
5629   return ret;
5630 }
5631
5632 static int
5633 api_want_interface_events (vat_main_t * vam)
5634 {
5635   unformat_input_t *i = vam->input;
5636   vl_api_want_interface_events_t *mp;
5637   int enable = -1;
5638   int ret;
5639
5640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5641     {
5642       if (unformat (i, "enable"))
5643         enable = 1;
5644       else if (unformat (i, "disable"))
5645         enable = 0;
5646       else
5647         break;
5648     }
5649
5650   if (enable == -1)
5651     {
5652       errmsg ("missing enable|disable");
5653       return -99;
5654     }
5655
5656   M (WANT_INTERFACE_EVENTS, mp);
5657   mp->enable_disable = enable;
5658
5659   vam->interface_event_display = enable;
5660
5661   S (mp);
5662   W (ret);
5663   return ret;
5664 }
5665
5666
5667 /* Note: non-static, called once to set up the initial intfc table */
5668 int
5669 api_sw_interface_dump (vat_main_t * vam)
5670 {
5671   vl_api_sw_interface_dump_t *mp;
5672   vl_api_control_ping_t *mp_ping;
5673   hash_pair_t *p;
5674   name_sort_t *nses = 0, *ns;
5675   sw_interface_subif_t *sub = NULL;
5676   int ret;
5677
5678   /* Toss the old name table */
5679   /* *INDENT-OFF* */
5680   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5681   ({
5682     vec_add2 (nses, ns, 1);
5683     ns->name = (u8 *)(p->key);
5684     ns->value = (u32) p->value[0];
5685   }));
5686   /* *INDENT-ON* */
5687
5688   hash_free (vam->sw_if_index_by_interface_name);
5689
5690   vec_foreach (ns, nses) vec_free (ns->name);
5691
5692   vec_free (nses);
5693
5694   vec_foreach (sub, vam->sw_if_subif_table)
5695   {
5696     vec_free (sub->interface_name);
5697   }
5698   vec_free (vam->sw_if_subif_table);
5699
5700   /* recreate the interface name hash table */
5701   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5702
5703   /* Get list of ethernets */
5704   M (SW_INTERFACE_DUMP, mp);
5705   mp->name_filter_valid = 1;
5706   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5707   S (mp);
5708
5709   /* and local / loopback interfaces */
5710   M (SW_INTERFACE_DUMP, mp);
5711   mp->name_filter_valid = 1;
5712   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5713   S (mp);
5714
5715   /* and packet-generator interfaces */
5716   M (SW_INTERFACE_DUMP, mp);
5717   mp->name_filter_valid = 1;
5718   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5719   S (mp);
5720
5721   /* and vxlan-gpe tunnel interfaces */
5722   M (SW_INTERFACE_DUMP, mp);
5723   mp->name_filter_valid = 1;
5724   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5725            sizeof (mp->name_filter) - 1);
5726   S (mp);
5727
5728   /* and vxlan tunnel interfaces */
5729   M (SW_INTERFACE_DUMP, mp);
5730   mp->name_filter_valid = 1;
5731   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5732   S (mp);
5733
5734   /* and host (af_packet) interfaces */
5735   M (SW_INTERFACE_DUMP, mp);
5736   mp->name_filter_valid = 1;
5737   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5738   S (mp);
5739
5740   /* and l2tpv3 tunnel interfaces */
5741   M (SW_INTERFACE_DUMP, mp);
5742   mp->name_filter_valid = 1;
5743   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5744            sizeof (mp->name_filter) - 1);
5745   S (mp);
5746
5747   /* and GRE tunnel interfaces */
5748   M (SW_INTERFACE_DUMP, mp);
5749   mp->name_filter_valid = 1;
5750   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5751   S (mp);
5752
5753   /* and LISP-GPE interfaces */
5754   M (SW_INTERFACE_DUMP, mp);
5755   mp->name_filter_valid = 1;
5756   strncpy ((char *) mp->name_filter, "lisp_gpe",
5757            sizeof (mp->name_filter) - 1);
5758   S (mp);
5759
5760   /* and IPSEC tunnel interfaces */
5761   M (SW_INTERFACE_DUMP, mp);
5762   mp->name_filter_valid = 1;
5763   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5764   S (mp);
5765
5766   /* Use a control ping for synchronization */
5767   M (CONTROL_PING, mp_ping);
5768   S (mp_ping);
5769
5770   W (ret);
5771   return ret;
5772 }
5773
5774 static int
5775 api_sw_interface_set_flags (vat_main_t * vam)
5776 {
5777   unformat_input_t *i = vam->input;
5778   vl_api_sw_interface_set_flags_t *mp;
5779   u32 sw_if_index;
5780   u8 sw_if_index_set = 0;
5781   u8 admin_up = 0;
5782   int ret;
5783
5784   /* Parse args required to build the message */
5785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5786     {
5787       if (unformat (i, "admin-up"))
5788         admin_up = 1;
5789       else if (unformat (i, "admin-down"))
5790         admin_up = 0;
5791       else
5792         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5793         sw_if_index_set = 1;
5794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5795         sw_if_index_set = 1;
5796       else
5797         break;
5798     }
5799
5800   if (sw_if_index_set == 0)
5801     {
5802       errmsg ("missing interface name or sw_if_index");
5803       return -99;
5804     }
5805
5806   /* Construct the API message */
5807   M (SW_INTERFACE_SET_FLAGS, mp);
5808   mp->sw_if_index = ntohl (sw_if_index);
5809   mp->admin_up_down = admin_up;
5810
5811   /* send it... */
5812   S (mp);
5813
5814   /* Wait for a reply, return the good/bad news... */
5815   W (ret);
5816   return ret;
5817 }
5818
5819 static int
5820 api_sw_interface_clear_stats (vat_main_t * vam)
5821 {
5822   unformat_input_t *i = vam->input;
5823   vl_api_sw_interface_clear_stats_t *mp;
5824   u32 sw_if_index;
5825   u8 sw_if_index_set = 0;
5826   int ret;
5827
5828   /* Parse args required to build the message */
5829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5830     {
5831       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5832         sw_if_index_set = 1;
5833       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5834         sw_if_index_set = 1;
5835       else
5836         break;
5837     }
5838
5839   /* Construct the API message */
5840   M (SW_INTERFACE_CLEAR_STATS, mp);
5841
5842   if (sw_if_index_set == 1)
5843     mp->sw_if_index = ntohl (sw_if_index);
5844   else
5845     mp->sw_if_index = ~0;
5846
5847   /* send it... */
5848   S (mp);
5849
5850   /* Wait for a reply, return the good/bad news... */
5851   W (ret);
5852   return ret;
5853 }
5854
5855 static int
5856 api_sw_interface_add_del_address (vat_main_t * vam)
5857 {
5858   unformat_input_t *i = vam->input;
5859   vl_api_sw_interface_add_del_address_t *mp;
5860   u32 sw_if_index;
5861   u8 sw_if_index_set = 0;
5862   u8 is_add = 1, del_all = 0;
5863   u32 address_length = 0;
5864   u8 v4_address_set = 0;
5865   u8 v6_address_set = 0;
5866   ip4_address_t v4address;
5867   ip6_address_t v6address;
5868   int ret;
5869
5870   /* Parse args required to build the message */
5871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5872     {
5873       if (unformat (i, "del-all"))
5874         del_all = 1;
5875       else if (unformat (i, "del"))
5876         is_add = 0;
5877       else
5878         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5879         sw_if_index_set = 1;
5880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5881         sw_if_index_set = 1;
5882       else if (unformat (i, "%U/%d",
5883                          unformat_ip4_address, &v4address, &address_length))
5884         v4_address_set = 1;
5885       else if (unformat (i, "%U/%d",
5886                          unformat_ip6_address, &v6address, &address_length))
5887         v6_address_set = 1;
5888       else
5889         break;
5890     }
5891
5892   if (sw_if_index_set == 0)
5893     {
5894       errmsg ("missing interface name or sw_if_index");
5895       return -99;
5896     }
5897   if (v4_address_set && v6_address_set)
5898     {
5899       errmsg ("both v4 and v6 addresses set");
5900       return -99;
5901     }
5902   if (!v4_address_set && !v6_address_set && !del_all)
5903     {
5904       errmsg ("no addresses set");
5905       return -99;
5906     }
5907
5908   /* Construct the API message */
5909   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5910
5911   mp->sw_if_index = ntohl (sw_if_index);
5912   mp->is_add = is_add;
5913   mp->del_all = del_all;
5914   if (v6_address_set)
5915     {
5916       mp->is_ipv6 = 1;
5917       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5918     }
5919   else
5920     {
5921       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5922     }
5923   mp->address_length = address_length;
5924
5925   /* send it... */
5926   S (mp);
5927
5928   /* Wait for a reply, return good/bad news  */
5929   W (ret);
5930   return ret;
5931 }
5932
5933 static int
5934 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5935 {
5936   unformat_input_t *i = vam->input;
5937   vl_api_sw_interface_set_mpls_enable_t *mp;
5938   u32 sw_if_index;
5939   u8 sw_if_index_set = 0;
5940   u8 enable = 1;
5941   int ret;
5942
5943   /* Parse args required to build the message */
5944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5945     {
5946       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5947         sw_if_index_set = 1;
5948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5949         sw_if_index_set = 1;
5950       else if (unformat (i, "disable"))
5951         enable = 0;
5952       else if (unformat (i, "dis"))
5953         enable = 0;
5954       else
5955         break;
5956     }
5957
5958   if (sw_if_index_set == 0)
5959     {
5960       errmsg ("missing interface name or sw_if_index");
5961       return -99;
5962     }
5963
5964   /* Construct the API message */
5965   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5966
5967   mp->sw_if_index = ntohl (sw_if_index);
5968   mp->enable = enable;
5969
5970   /* send it... */
5971   S (mp);
5972
5973   /* Wait for a reply... */
5974   W (ret);
5975   return ret;
5976 }
5977
5978 static int
5979 api_sw_interface_set_table (vat_main_t * vam)
5980 {
5981   unformat_input_t *i = vam->input;
5982   vl_api_sw_interface_set_table_t *mp;
5983   u32 sw_if_index, vrf_id = 0;
5984   u8 sw_if_index_set = 0;
5985   u8 is_ipv6 = 0;
5986   int ret;
5987
5988   /* Parse args required to build the message */
5989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5990     {
5991       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5992         sw_if_index_set = 1;
5993       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5994         sw_if_index_set = 1;
5995       else if (unformat (i, "vrf %d", &vrf_id))
5996         ;
5997       else if (unformat (i, "ipv6"))
5998         is_ipv6 = 1;
5999       else
6000         break;
6001     }
6002
6003   if (sw_if_index_set == 0)
6004     {
6005       errmsg ("missing interface name or sw_if_index");
6006       return -99;
6007     }
6008
6009   /* Construct the API message */
6010   M (SW_INTERFACE_SET_TABLE, mp);
6011
6012   mp->sw_if_index = ntohl (sw_if_index);
6013   mp->is_ipv6 = is_ipv6;
6014   mp->vrf_id = ntohl (vrf_id);
6015
6016   /* send it... */
6017   S (mp);
6018
6019   /* Wait for a reply... */
6020   W (ret);
6021   return ret;
6022 }
6023
6024 static void vl_api_sw_interface_get_table_reply_t_handler
6025   (vl_api_sw_interface_get_table_reply_t * mp)
6026 {
6027   vat_main_t *vam = &vat_main;
6028
6029   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6030
6031   vam->retval = ntohl (mp->retval);
6032   vam->result_ready = 1;
6033
6034 }
6035
6036 static void vl_api_sw_interface_get_table_reply_t_handler_json
6037   (vl_api_sw_interface_get_table_reply_t * mp)
6038 {
6039   vat_main_t *vam = &vat_main;
6040   vat_json_node_t node;
6041
6042   vat_json_init_object (&node);
6043   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6044   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6045
6046   vat_json_print (vam->ofp, &node);
6047   vat_json_free (&node);
6048
6049   vam->retval = ntohl (mp->retval);
6050   vam->result_ready = 1;
6051 }
6052
6053 static int
6054 api_sw_interface_get_table (vat_main_t * vam)
6055 {
6056   unformat_input_t *i = vam->input;
6057   vl_api_sw_interface_get_table_t *mp;
6058   u32 sw_if_index;
6059   u8 sw_if_index_set = 0;
6060   u8 is_ipv6 = 0;
6061   int ret;
6062
6063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6064     {
6065       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6066         sw_if_index_set = 1;
6067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6068         sw_if_index_set = 1;
6069       else if (unformat (i, "ipv6"))
6070         is_ipv6 = 1;
6071       else
6072         break;
6073     }
6074
6075   if (sw_if_index_set == 0)
6076     {
6077       errmsg ("missing interface name or sw_if_index");
6078       return -99;
6079     }
6080
6081   M (SW_INTERFACE_GET_TABLE, mp);
6082   mp->sw_if_index = htonl (sw_if_index);
6083   mp->is_ipv6 = is_ipv6;
6084
6085   S (mp);
6086   W (ret);
6087   return ret;
6088 }
6089
6090 static int
6091 api_sw_interface_set_vpath (vat_main_t * vam)
6092 {
6093   unformat_input_t *i = vam->input;
6094   vl_api_sw_interface_set_vpath_t *mp;
6095   u32 sw_if_index = 0;
6096   u8 sw_if_index_set = 0;
6097   u8 is_enable = 0;
6098   int ret;
6099
6100   /* Parse args required to build the message */
6101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6102     {
6103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6104         sw_if_index_set = 1;
6105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6106         sw_if_index_set = 1;
6107       else if (unformat (i, "enable"))
6108         is_enable = 1;
6109       else if (unformat (i, "disable"))
6110         is_enable = 0;
6111       else
6112         break;
6113     }
6114
6115   if (sw_if_index_set == 0)
6116     {
6117       errmsg ("missing interface name or sw_if_index");
6118       return -99;
6119     }
6120
6121   /* Construct the API message */
6122   M (SW_INTERFACE_SET_VPATH, mp);
6123
6124   mp->sw_if_index = ntohl (sw_if_index);
6125   mp->enable = is_enable;
6126
6127   /* send it... */
6128   S (mp);
6129
6130   /* Wait for a reply... */
6131   W (ret);
6132   return ret;
6133 }
6134
6135 static int
6136 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6137 {
6138   unformat_input_t *i = vam->input;
6139   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6140   u32 sw_if_index = 0;
6141   u8 sw_if_index_set = 0;
6142   u8 is_enable = 1;
6143   u8 is_ipv6 = 0;
6144   int ret;
6145
6146   /* Parse args required to build the message */
6147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6148     {
6149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6150         sw_if_index_set = 1;
6151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6152         sw_if_index_set = 1;
6153       else if (unformat (i, "enable"))
6154         is_enable = 1;
6155       else if (unformat (i, "disable"))
6156         is_enable = 0;
6157       else if (unformat (i, "ip4"))
6158         is_ipv6 = 0;
6159       else if (unformat (i, "ip6"))
6160         is_ipv6 = 1;
6161       else
6162         break;
6163     }
6164
6165   if (sw_if_index_set == 0)
6166     {
6167       errmsg ("missing interface name or sw_if_index");
6168       return -99;
6169     }
6170
6171   /* Construct the API message */
6172   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6173
6174   mp->sw_if_index = ntohl (sw_if_index);
6175   mp->enable = is_enable;
6176   mp->is_ipv6 = is_ipv6;
6177
6178   /* send it... */
6179   S (mp);
6180
6181   /* Wait for a reply... */
6182   W (ret);
6183   return ret;
6184 }
6185
6186
6187 static int
6188 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6189 {
6190   unformat_input_t *i = vam->input;
6191   vl_api_sw_interface_set_l2_xconnect_t *mp;
6192   u32 rx_sw_if_index;
6193   u8 rx_sw_if_index_set = 0;
6194   u32 tx_sw_if_index;
6195   u8 tx_sw_if_index_set = 0;
6196   u8 enable = 1;
6197   int ret;
6198
6199   /* Parse args required to build the message */
6200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6201     {
6202       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6203         rx_sw_if_index_set = 1;
6204       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6205         tx_sw_if_index_set = 1;
6206       else if (unformat (i, "rx"))
6207         {
6208           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6209             {
6210               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6211                             &rx_sw_if_index))
6212                 rx_sw_if_index_set = 1;
6213             }
6214           else
6215             break;
6216         }
6217       else if (unformat (i, "tx"))
6218         {
6219           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6220             {
6221               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6222                             &tx_sw_if_index))
6223                 tx_sw_if_index_set = 1;
6224             }
6225           else
6226             break;
6227         }
6228       else if (unformat (i, "enable"))
6229         enable = 1;
6230       else if (unformat (i, "disable"))
6231         enable = 0;
6232       else
6233         break;
6234     }
6235
6236   if (rx_sw_if_index_set == 0)
6237     {
6238       errmsg ("missing rx interface name or rx_sw_if_index");
6239       return -99;
6240     }
6241
6242   if (enable && (tx_sw_if_index_set == 0))
6243     {
6244       errmsg ("missing tx interface name or tx_sw_if_index");
6245       return -99;
6246     }
6247
6248   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6249
6250   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6251   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6252   mp->enable = enable;
6253
6254   S (mp);
6255   W (ret);
6256   return ret;
6257 }
6258
6259 static int
6260 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6261 {
6262   unformat_input_t *i = vam->input;
6263   vl_api_sw_interface_set_l2_bridge_t *mp;
6264   u32 rx_sw_if_index;
6265   u8 rx_sw_if_index_set = 0;
6266   u32 bd_id;
6267   u8 bd_id_set = 0;
6268   u8 bvi = 0;
6269   u32 shg = 0;
6270   u8 enable = 1;
6271   int ret;
6272
6273   /* Parse args required to build the message */
6274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6275     {
6276       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6277         rx_sw_if_index_set = 1;
6278       else if (unformat (i, "bd_id %d", &bd_id))
6279         bd_id_set = 1;
6280       else
6281         if (unformat
6282             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6283         rx_sw_if_index_set = 1;
6284       else if (unformat (i, "shg %d", &shg))
6285         ;
6286       else if (unformat (i, "bvi"))
6287         bvi = 1;
6288       else if (unformat (i, "enable"))
6289         enable = 1;
6290       else if (unformat (i, "disable"))
6291         enable = 0;
6292       else
6293         break;
6294     }
6295
6296   if (rx_sw_if_index_set == 0)
6297     {
6298       errmsg ("missing rx interface name or sw_if_index");
6299       return -99;
6300     }
6301
6302   if (enable && (bd_id_set == 0))
6303     {
6304       errmsg ("missing bridge domain");
6305       return -99;
6306     }
6307
6308   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6309
6310   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6311   mp->bd_id = ntohl (bd_id);
6312   mp->shg = (u8) shg;
6313   mp->bvi = bvi;
6314   mp->enable = enable;
6315
6316   S (mp);
6317   W (ret);
6318   return ret;
6319 }
6320
6321 static int
6322 api_bridge_domain_dump (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   vl_api_bridge_domain_dump_t *mp;
6326   vl_api_control_ping_t *mp_ping;
6327   u32 bd_id = ~0;
6328   int ret;
6329
6330   /* Parse args required to build the message */
6331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332     {
6333       if (unformat (i, "bd_id %d", &bd_id))
6334         ;
6335       else
6336         break;
6337     }
6338
6339   M (BRIDGE_DOMAIN_DUMP, mp);
6340   mp->bd_id = ntohl (bd_id);
6341   S (mp);
6342
6343   /* Use a control ping for synchronization */
6344   M (CONTROL_PING, mp_ping);
6345   S (mp_ping);
6346
6347   W (ret);
6348   return ret;
6349 }
6350
6351 static int
6352 api_bridge_domain_add_del (vat_main_t * vam)
6353 {
6354   unformat_input_t *i = vam->input;
6355   vl_api_bridge_domain_add_del_t *mp;
6356   u32 bd_id = ~0;
6357   u8 is_add = 1;
6358   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6359   u32 mac_age = 0;
6360   int ret;
6361
6362   /* Parse args required to build the message */
6363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6364     {
6365       if (unformat (i, "bd_id %d", &bd_id))
6366         ;
6367       else if (unformat (i, "flood %d", &flood))
6368         ;
6369       else if (unformat (i, "uu-flood %d", &uu_flood))
6370         ;
6371       else if (unformat (i, "forward %d", &forward))
6372         ;
6373       else if (unformat (i, "learn %d", &learn))
6374         ;
6375       else if (unformat (i, "arp-term %d", &arp_term))
6376         ;
6377       else if (unformat (i, "mac-age %d", &mac_age))
6378         ;
6379       else if (unformat (i, "del"))
6380         {
6381           is_add = 0;
6382           flood = uu_flood = forward = learn = 0;
6383         }
6384       else
6385         break;
6386     }
6387
6388   if (bd_id == ~0)
6389     {
6390       errmsg ("missing bridge domain");
6391       return -99;
6392     }
6393
6394   if (mac_age > 255)
6395     {
6396       errmsg ("mac age must be less than 256 ");
6397       return -99;
6398     }
6399
6400   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6401
6402   mp->bd_id = ntohl (bd_id);
6403   mp->flood = flood;
6404   mp->uu_flood = uu_flood;
6405   mp->forward = forward;
6406   mp->learn = learn;
6407   mp->arp_term = arp_term;
6408   mp->is_add = is_add;
6409   mp->mac_age = (u8) mac_age;
6410
6411   S (mp);
6412   W (ret);
6413   return ret;
6414 }
6415
6416 static int
6417 api_l2fib_flush_bd (vat_main_t * vam)
6418 {
6419   unformat_input_t *i = vam->input;
6420   vl_api_l2fib_flush_bd_t *mp;
6421   u32 bd_id = ~0;
6422   int ret;
6423
6424   /* Parse args required to build the message */
6425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6426     {
6427       if (unformat (i, "bd_id %d", &bd_id));
6428       else
6429         break;
6430     }
6431
6432   if (bd_id == ~0)
6433     {
6434       errmsg ("missing bridge domain");
6435       return -99;
6436     }
6437
6438   M (L2FIB_FLUSH_BD, mp);
6439
6440   mp->bd_id = htonl (bd_id);
6441
6442   S (mp);
6443   W (ret);
6444   return ret;
6445 }
6446
6447 static int
6448 api_l2fib_flush_int (vat_main_t * vam)
6449 {
6450   unformat_input_t *i = vam->input;
6451   vl_api_l2fib_flush_int_t *mp;
6452   u32 sw_if_index = ~0;
6453   int ret;
6454
6455   /* Parse args required to build the message */
6456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6457     {
6458       if (unformat (i, "sw_if_index %d", &sw_if_index));
6459       else
6460         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6461       else
6462         break;
6463     }
6464
6465   if (sw_if_index == ~0)
6466     {
6467       errmsg ("missing interface name or sw_if_index");
6468       return -99;
6469     }
6470
6471   M (L2FIB_FLUSH_INT, mp);
6472
6473   mp->sw_if_index = ntohl (sw_if_index);
6474
6475   S (mp);
6476   W (ret);
6477   return ret;
6478 }
6479
6480 static int
6481 api_l2fib_add_del (vat_main_t * vam)
6482 {
6483   unformat_input_t *i = vam->input;
6484   vl_api_l2fib_add_del_t *mp;
6485   f64 timeout;
6486   u64 mac = 0;
6487   u8 mac_set = 0;
6488   u32 bd_id;
6489   u8 bd_id_set = 0;
6490   u32 sw_if_index = ~0;
6491   u8 sw_if_index_set = 0;
6492   u8 is_add = 1;
6493   u8 static_mac = 0;
6494   u8 filter_mac = 0;
6495   u8 bvi_mac = 0;
6496   int count = 1;
6497   f64 before = 0;
6498   int j;
6499
6500   /* Parse args required to build the message */
6501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6502     {
6503       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6504         mac_set = 1;
6505       else if (unformat (i, "bd_id %d", &bd_id))
6506         bd_id_set = 1;
6507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6508         sw_if_index_set = 1;
6509       else if (unformat (i, "sw_if"))
6510         {
6511           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6512             {
6513               if (unformat
6514                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6515                 sw_if_index_set = 1;
6516             }
6517           else
6518             break;
6519         }
6520       else if (unformat (i, "static"))
6521         static_mac = 1;
6522       else if (unformat (i, "filter"))
6523         {
6524           filter_mac = 1;
6525           static_mac = 1;
6526         }
6527       else if (unformat (i, "bvi"))
6528         {
6529           bvi_mac = 1;
6530           static_mac = 1;
6531         }
6532       else if (unformat (i, "del"))
6533         is_add = 0;
6534       else if (unformat (i, "count %d", &count))
6535         ;
6536       else
6537         break;
6538     }
6539
6540   if (mac_set == 0)
6541     {
6542       errmsg ("missing mac address");
6543       return -99;
6544     }
6545
6546   if (bd_id_set == 0)
6547     {
6548       errmsg ("missing bridge domain");
6549       return -99;
6550     }
6551
6552   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6553     {
6554       errmsg ("missing interface name or sw_if_index");
6555       return -99;
6556     }
6557
6558   if (count > 1)
6559     {
6560       /* Turn on async mode */
6561       vam->async_mode = 1;
6562       vam->async_errors = 0;
6563       before = vat_time_now (vam);
6564     }
6565
6566   for (j = 0; j < count; j++)
6567     {
6568       M (L2FIB_ADD_DEL, mp);
6569
6570       mp->mac = mac;
6571       mp->bd_id = ntohl (bd_id);
6572       mp->is_add = is_add;
6573
6574       if (is_add)
6575         {
6576           mp->sw_if_index = ntohl (sw_if_index);
6577           mp->static_mac = static_mac;
6578           mp->filter_mac = filter_mac;
6579           mp->bvi_mac = bvi_mac;
6580         }
6581       increment_mac_address (&mac);
6582       /* send it... */
6583       S (mp);
6584     }
6585
6586   if (count > 1)
6587     {
6588       vl_api_control_ping_t *mp_ping;
6589       f64 after;
6590
6591       /* Shut off async mode */
6592       vam->async_mode = 0;
6593
6594       M (CONTROL_PING, mp_ping);
6595       S (mp_ping);
6596
6597       timeout = vat_time_now (vam) + 1.0;
6598       while (vat_time_now (vam) < timeout)
6599         if (vam->result_ready == 1)
6600           goto out;
6601       vam->retval = -99;
6602
6603     out:
6604       if (vam->retval == -99)
6605         errmsg ("timeout");
6606
6607       if (vam->async_errors > 0)
6608         {
6609           errmsg ("%d asynchronous errors", vam->async_errors);
6610           vam->retval = -98;
6611         }
6612       vam->async_errors = 0;
6613       after = vat_time_now (vam);
6614
6615       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6616              count, after - before, count / (after - before));
6617     }
6618   else
6619     {
6620       int ret;
6621
6622       /* Wait for a reply... */
6623       W (ret);
6624       return ret;
6625     }
6626   /* Return the good/bad news */
6627   return (vam->retval);
6628 }
6629
6630 static int
6631 api_bridge_domain_set_mac_age (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_bridge_domain_set_mac_age_t *mp;
6635   u32 bd_id = ~0;
6636   u32 mac_age = 0;
6637   int ret;
6638
6639   /* Parse args required to build the message */
6640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6641     {
6642       if (unformat (i, "bd_id %d", &bd_id));
6643       else if (unformat (i, "mac-age %d", &mac_age));
6644       else
6645         break;
6646     }
6647
6648   if (bd_id == ~0)
6649     {
6650       errmsg ("missing bridge domain");
6651       return -99;
6652     }
6653
6654   if (mac_age > 255)
6655     {
6656       errmsg ("mac age must be less than 256 ");
6657       return -99;
6658     }
6659
6660   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6661
6662   mp->bd_id = htonl (bd_id);
6663   mp->mac_age = (u8) mac_age;
6664
6665   S (mp);
6666   W (ret);
6667   return ret;
6668 }
6669
6670 static int
6671 api_l2_flags (vat_main_t * vam)
6672 {
6673   unformat_input_t *i = vam->input;
6674   vl_api_l2_flags_t *mp;
6675   u32 sw_if_index;
6676   u32 flags = 0;
6677   u8 sw_if_index_set = 0;
6678   u8 is_set = 0;
6679   int ret;
6680
6681   /* Parse args required to build the message */
6682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6683     {
6684       if (unformat (i, "sw_if_index %d", &sw_if_index))
6685         sw_if_index_set = 1;
6686       else if (unformat (i, "sw_if"))
6687         {
6688           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689             {
6690               if (unformat
6691                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6692                 sw_if_index_set = 1;
6693             }
6694           else
6695             break;
6696         }
6697       else if (unformat (i, "learn"))
6698         flags |= L2_LEARN;
6699       else if (unformat (i, "forward"))
6700         flags |= L2_FWD;
6701       else if (unformat (i, "flood"))
6702         flags |= L2_FLOOD;
6703       else if (unformat (i, "uu-flood"))
6704         flags |= L2_UU_FLOOD;
6705       else if (unformat (i, "arp-term"))
6706         flags |= L2_ARP_TERM;
6707       else if (unformat (i, "off"))
6708         is_set = 0;
6709       else if (unformat (i, "disable"))
6710         is_set = 0;
6711       else
6712         break;
6713     }
6714
6715   if (sw_if_index_set == 0)
6716     {
6717       errmsg ("missing interface name or sw_if_index");
6718       return -99;
6719     }
6720
6721   M (L2_FLAGS, mp);
6722
6723   mp->sw_if_index = ntohl (sw_if_index);
6724   mp->feature_bitmap = ntohl (flags);
6725   mp->is_set = is_set;
6726
6727   S (mp);
6728   W (ret);
6729   return ret;
6730 }
6731
6732 static int
6733 api_bridge_flags (vat_main_t * vam)
6734 {
6735   unformat_input_t *i = vam->input;
6736   vl_api_bridge_flags_t *mp;
6737   u32 bd_id;
6738   u8 bd_id_set = 0;
6739   u8 is_set = 1;
6740   u32 flags = 0;
6741   int ret;
6742
6743   /* Parse args required to build the message */
6744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6745     {
6746       if (unformat (i, "bd_id %d", &bd_id))
6747         bd_id_set = 1;
6748       else if (unformat (i, "learn"))
6749         flags |= L2_LEARN;
6750       else if (unformat (i, "forward"))
6751         flags |= L2_FWD;
6752       else if (unformat (i, "flood"))
6753         flags |= L2_FLOOD;
6754       else if (unformat (i, "uu-flood"))
6755         flags |= L2_UU_FLOOD;
6756       else if (unformat (i, "arp-term"))
6757         flags |= L2_ARP_TERM;
6758       else if (unformat (i, "off"))
6759         is_set = 0;
6760       else if (unformat (i, "disable"))
6761         is_set = 0;
6762       else
6763         break;
6764     }
6765
6766   if (bd_id_set == 0)
6767     {
6768       errmsg ("missing bridge domain");
6769       return -99;
6770     }
6771
6772   M (BRIDGE_FLAGS, mp);
6773
6774   mp->bd_id = ntohl (bd_id);
6775   mp->feature_bitmap = ntohl (flags);
6776   mp->is_set = is_set;
6777
6778   S (mp);
6779   W (ret);
6780   return ret;
6781 }
6782
6783 static int
6784 api_bd_ip_mac_add_del (vat_main_t * vam)
6785 {
6786   unformat_input_t *i = vam->input;
6787   vl_api_bd_ip_mac_add_del_t *mp;
6788   u32 bd_id;
6789   u8 is_ipv6 = 0;
6790   u8 is_add = 1;
6791   u8 bd_id_set = 0;
6792   u8 ip_set = 0;
6793   u8 mac_set = 0;
6794   ip4_address_t v4addr;
6795   ip6_address_t v6addr;
6796   u8 macaddr[6];
6797   int ret;
6798
6799
6800   /* Parse args required to build the message */
6801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6802     {
6803       if (unformat (i, "bd_id %d", &bd_id))
6804         {
6805           bd_id_set++;
6806         }
6807       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6808         {
6809           ip_set++;
6810         }
6811       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6812         {
6813           ip_set++;
6814           is_ipv6++;
6815         }
6816       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6817         {
6818           mac_set++;
6819         }
6820       else if (unformat (i, "del"))
6821         is_add = 0;
6822       else
6823         break;
6824     }
6825
6826   if (bd_id_set == 0)
6827     {
6828       errmsg ("missing bridge domain");
6829       return -99;
6830     }
6831   else if (ip_set == 0)
6832     {
6833       errmsg ("missing IP address");
6834       return -99;
6835     }
6836   else if (mac_set == 0)
6837     {
6838       errmsg ("missing MAC address");
6839       return -99;
6840     }
6841
6842   M (BD_IP_MAC_ADD_DEL, mp);
6843
6844   mp->bd_id = ntohl (bd_id);
6845   mp->is_ipv6 = is_ipv6;
6846   mp->is_add = is_add;
6847   if (is_ipv6)
6848     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6849   else
6850     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6851   clib_memcpy (mp->mac_address, macaddr, 6);
6852   S (mp);
6853   W (ret);
6854   return ret;
6855 }
6856
6857 static int
6858 api_tap_connect (vat_main_t * vam)
6859 {
6860   unformat_input_t *i = vam->input;
6861   vl_api_tap_connect_t *mp;
6862   u8 mac_address[6];
6863   u8 random_mac = 1;
6864   u8 name_set = 0;
6865   u8 *tap_name;
6866   u8 *tag = 0;
6867   ip4_address_t ip4_address;
6868   u32 ip4_mask_width;
6869   int ip4_address_set = 0;
6870   ip6_address_t ip6_address;
6871   u32 ip6_mask_width;
6872   int ip6_address_set = 0;
6873   int ret;
6874
6875   memset (mac_address, 0, sizeof (mac_address));
6876
6877   /* Parse args required to build the message */
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6881         {
6882           random_mac = 0;
6883         }
6884       else if (unformat (i, "random-mac"))
6885         random_mac = 1;
6886       else if (unformat (i, "tapname %s", &tap_name))
6887         name_set = 1;
6888       else if (unformat (i, "tag %s", &tag))
6889         ;
6890       else if (unformat (i, "address %U/%d",
6891                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6892         ip4_address_set = 1;
6893       else if (unformat (i, "address %U/%d",
6894                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6895         ip6_address_set = 1;
6896       else
6897         break;
6898     }
6899
6900   if (name_set == 0)
6901     {
6902       errmsg ("missing tap name");
6903       return -99;
6904     }
6905   if (vec_len (tap_name) > 63)
6906     {
6907       errmsg ("tap name too long");
6908       return -99;
6909     }
6910   vec_add1 (tap_name, 0);
6911
6912   if (vec_len (tag) > 63)
6913     {
6914       errmsg ("tag too long");
6915       return -99;
6916     }
6917
6918   /* Construct the API message */
6919   M (TAP_CONNECT, mp);
6920
6921   mp->use_random_mac = random_mac;
6922   clib_memcpy (mp->mac_address, mac_address, 6);
6923   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6924   if (tag)
6925     clib_memcpy (mp->tag, tag, vec_len (tag));
6926
6927   if (ip4_address_set)
6928     {
6929       mp->ip4_address_set = 1;
6930       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6931       mp->ip4_mask_width = ip4_mask_width;
6932     }
6933   if (ip6_address_set)
6934     {
6935       mp->ip6_address_set = 1;
6936       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6937       mp->ip6_mask_width = ip6_mask_width;
6938     }
6939
6940   vec_free (tap_name);
6941   vec_free (tag);
6942
6943   /* send it... */
6944   S (mp);
6945
6946   /* Wait for a reply... */
6947   W (ret);
6948   return ret;
6949 }
6950
6951 static int
6952 api_tap_modify (vat_main_t * vam)
6953 {
6954   unformat_input_t *i = vam->input;
6955   vl_api_tap_modify_t *mp;
6956   u8 mac_address[6];
6957   u8 random_mac = 1;
6958   u8 name_set = 0;
6959   u8 *tap_name;
6960   u32 sw_if_index = ~0;
6961   u8 sw_if_index_set = 0;
6962   int ret;
6963
6964   memset (mac_address, 0, sizeof (mac_address));
6965
6966   /* Parse args required to build the message */
6967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6968     {
6969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6970         sw_if_index_set = 1;
6971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6972         sw_if_index_set = 1;
6973       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6974         {
6975           random_mac = 0;
6976         }
6977       else if (unformat (i, "random-mac"))
6978         random_mac = 1;
6979       else if (unformat (i, "tapname %s", &tap_name))
6980         name_set = 1;
6981       else
6982         break;
6983     }
6984
6985   if (sw_if_index_set == 0)
6986     {
6987       errmsg ("missing vpp interface name");
6988       return -99;
6989     }
6990   if (name_set == 0)
6991     {
6992       errmsg ("missing tap name");
6993       return -99;
6994     }
6995   if (vec_len (tap_name) > 63)
6996     {
6997       errmsg ("tap name too long");
6998     }
6999   vec_add1 (tap_name, 0);
7000
7001   /* Construct the API message */
7002   M (TAP_MODIFY, mp);
7003
7004   mp->use_random_mac = random_mac;
7005   mp->sw_if_index = ntohl (sw_if_index);
7006   clib_memcpy (mp->mac_address, mac_address, 6);
7007   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7008   vec_free (tap_name);
7009
7010   /* send it... */
7011   S (mp);
7012
7013   /* Wait for a reply... */
7014   W (ret);
7015   return ret;
7016 }
7017
7018 static int
7019 api_tap_delete (vat_main_t * vam)
7020 {
7021   unformat_input_t *i = vam->input;
7022   vl_api_tap_delete_t *mp;
7023   u32 sw_if_index = ~0;
7024   u8 sw_if_index_set = 0;
7025   int ret;
7026
7027   /* Parse args required to build the message */
7028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7029     {
7030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7031         sw_if_index_set = 1;
7032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7033         sw_if_index_set = 1;
7034       else
7035         break;
7036     }
7037
7038   if (sw_if_index_set == 0)
7039     {
7040       errmsg ("missing vpp interface name");
7041       return -99;
7042     }
7043
7044   /* Construct the API message */
7045   M (TAP_DELETE, mp);
7046
7047   mp->sw_if_index = ntohl (sw_if_index);
7048
7049   /* send it... */
7050   S (mp);
7051
7052   /* Wait for a reply... */
7053   W (ret);
7054   return ret;
7055 }
7056
7057 static int
7058 api_ip_table_add_del (vat_main_t * vam)
7059 {
7060   unformat_input_t *i = vam->input;
7061   vl_api_ip_table_add_del_t *mp;
7062   u32 table_id = ~0;
7063   u8 is_ipv6 = 0;
7064   u8 is_add = 1;
7065   int ret = 0;
7066
7067   /* Parse args required to build the message */
7068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7069     {
7070       if (unformat (i, "ipv6"))
7071         is_ipv6 = 1;
7072       else if (unformat (i, "del"))
7073         is_add = 0;
7074       else if (unformat (i, "add"))
7075         is_add = 1;
7076       else if (unformat (i, "table %d", &table_id))
7077         ;
7078       else
7079         {
7080           clib_warning ("parse error '%U'", format_unformat_error, i);
7081           return -99;
7082         }
7083     }
7084
7085   if (~0 == table_id)
7086     {
7087       errmsg ("missing table-ID");
7088       return -99;
7089     }
7090
7091   /* Construct the API message */
7092   M (IP_TABLE_ADD_DEL, mp);
7093
7094   mp->table_id = ntohl (table_id);
7095   mp->is_ipv6 = is_ipv6;
7096   mp->is_add = is_add;
7097
7098   /* send it... */
7099   S (mp);
7100
7101   /* Wait for a reply... */
7102   W (ret);
7103
7104   return ret;
7105 }
7106
7107 static int
7108 api_ip_add_del_route (vat_main_t * vam)
7109 {
7110   unformat_input_t *i = vam->input;
7111   vl_api_ip_add_del_route_t *mp;
7112   u32 sw_if_index = ~0, vrf_id = 0;
7113   u8 is_ipv6 = 0;
7114   u8 is_local = 0, is_drop = 0;
7115   u8 is_unreach = 0, is_prohibit = 0;
7116   u8 create_vrf_if_needed = 0;
7117   u8 is_add = 1;
7118   u32 next_hop_weight = 1;
7119   u8 not_last = 0;
7120   u8 is_multipath = 0;
7121   u8 address_set = 0;
7122   u8 address_length_set = 0;
7123   u32 next_hop_table_id = 0;
7124   u32 resolve_attempts = 0;
7125   u32 dst_address_length = 0;
7126   u8 next_hop_set = 0;
7127   ip4_address_t v4_dst_address, v4_next_hop_address;
7128   ip6_address_t v6_dst_address, v6_next_hop_address;
7129   int count = 1;
7130   int j;
7131   f64 before = 0;
7132   u32 random_add_del = 0;
7133   u32 *random_vector = 0;
7134   uword *random_hash;
7135   u32 random_seed = 0xdeaddabe;
7136   u32 classify_table_index = ~0;
7137   u8 is_classify = 0;
7138   u8 resolve_host = 0, resolve_attached = 0;
7139   mpls_label_t *next_hop_out_label_stack = NULL;
7140   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7141   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7142
7143   /* Parse args required to build the message */
7144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7145     {
7146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7147         ;
7148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7149         ;
7150       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7151         {
7152           address_set = 1;
7153           is_ipv6 = 0;
7154         }
7155       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7156         {
7157           address_set = 1;
7158           is_ipv6 = 1;
7159         }
7160       else if (unformat (i, "/%d", &dst_address_length))
7161         {
7162           address_length_set = 1;
7163         }
7164
7165       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7166                                          &v4_next_hop_address))
7167         {
7168           next_hop_set = 1;
7169         }
7170       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7171                                          &v6_next_hop_address))
7172         {
7173           next_hop_set = 1;
7174         }
7175       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7176         ;
7177       else if (unformat (i, "weight %d", &next_hop_weight))
7178         ;
7179       else if (unformat (i, "drop"))
7180         {
7181           is_drop = 1;
7182         }
7183       else if (unformat (i, "null-send-unreach"))
7184         {
7185           is_unreach = 1;
7186         }
7187       else if (unformat (i, "null-send-prohibit"))
7188         {
7189           is_prohibit = 1;
7190         }
7191       else if (unformat (i, "local"))
7192         {
7193           is_local = 1;
7194         }
7195       else if (unformat (i, "classify %d", &classify_table_index))
7196         {
7197           is_classify = 1;
7198         }
7199       else if (unformat (i, "del"))
7200         is_add = 0;
7201       else if (unformat (i, "add"))
7202         is_add = 1;
7203       else if (unformat (i, "not-last"))
7204         not_last = 1;
7205       else if (unformat (i, "resolve-via-host"))
7206         resolve_host = 1;
7207       else if (unformat (i, "resolve-via-attached"))
7208         resolve_attached = 1;
7209       else if (unformat (i, "multipath"))
7210         is_multipath = 1;
7211       else if (unformat (i, "vrf %d", &vrf_id))
7212         ;
7213       else if (unformat (i, "create-vrf"))
7214         create_vrf_if_needed = 1;
7215       else if (unformat (i, "count %d", &count))
7216         ;
7217       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7218         ;
7219       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7220         ;
7221       else if (unformat (i, "out-label %d", &next_hop_out_label))
7222         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7223       else if (unformat (i, "via-label %d", &next_hop_via_label))
7224         ;
7225       else if (unformat (i, "random"))
7226         random_add_del = 1;
7227       else if (unformat (i, "seed %d", &random_seed))
7228         ;
7229       else
7230         {
7231           clib_warning ("parse error '%U'", format_unformat_error, i);
7232           return -99;
7233         }
7234     }
7235
7236   if (!next_hop_set && !is_drop && !is_local &&
7237       !is_classify && !is_unreach && !is_prohibit &&
7238       MPLS_LABEL_INVALID == next_hop_via_label)
7239     {
7240       errmsg
7241         ("next hop / local / drop / unreach / prohibit / classify not set");
7242       return -99;
7243     }
7244
7245   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7246     {
7247       errmsg ("next hop and next-hop via label set");
7248       return -99;
7249     }
7250   if (address_set == 0)
7251     {
7252       errmsg ("missing addresses");
7253       return -99;
7254     }
7255
7256   if (address_length_set == 0)
7257     {
7258       errmsg ("missing address length");
7259       return -99;
7260     }
7261
7262   /* Generate a pile of unique, random routes */
7263   if (random_add_del)
7264     {
7265       u32 this_random_address;
7266       random_hash = hash_create (count, sizeof (uword));
7267
7268       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7269       for (j = 0; j <= count; j++)
7270         {
7271           do
7272             {
7273               this_random_address = random_u32 (&random_seed);
7274               this_random_address =
7275                 clib_host_to_net_u32 (this_random_address);
7276             }
7277           while (hash_get (random_hash, this_random_address));
7278           vec_add1 (random_vector, this_random_address);
7279           hash_set (random_hash, this_random_address, 1);
7280         }
7281       hash_free (random_hash);
7282       v4_dst_address.as_u32 = random_vector[0];
7283     }
7284
7285   if (count > 1)
7286     {
7287       /* Turn on async mode */
7288       vam->async_mode = 1;
7289       vam->async_errors = 0;
7290       before = vat_time_now (vam);
7291     }
7292
7293   for (j = 0; j < count; j++)
7294     {
7295       /* Construct the API message */
7296       M2 (IP_ADD_DEL_ROUTE, mp,
7297           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7298
7299       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7300       mp->table_id = ntohl (vrf_id);
7301       mp->create_vrf_if_needed = create_vrf_if_needed;
7302
7303       mp->is_add = is_add;
7304       mp->is_drop = is_drop;
7305       mp->is_unreach = is_unreach;
7306       mp->is_prohibit = is_prohibit;
7307       mp->is_ipv6 = is_ipv6;
7308       mp->is_local = is_local;
7309       mp->is_classify = is_classify;
7310       mp->is_multipath = is_multipath;
7311       mp->is_resolve_host = resolve_host;
7312       mp->is_resolve_attached = resolve_attached;
7313       mp->not_last = not_last;
7314       mp->next_hop_weight = next_hop_weight;
7315       mp->dst_address_length = dst_address_length;
7316       mp->next_hop_table_id = ntohl (next_hop_table_id);
7317       mp->classify_table_index = ntohl (classify_table_index);
7318       mp->next_hop_via_label = ntohl (next_hop_via_label);
7319       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7320       if (0 != mp->next_hop_n_out_labels)
7321         {
7322           memcpy (mp->next_hop_out_label_stack,
7323                   next_hop_out_label_stack,
7324                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7325           vec_free (next_hop_out_label_stack);
7326         }
7327
7328       if (is_ipv6)
7329         {
7330           clib_memcpy (mp->dst_address, &v6_dst_address,
7331                        sizeof (v6_dst_address));
7332           if (next_hop_set)
7333             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7334                          sizeof (v6_next_hop_address));
7335           increment_v6_address (&v6_dst_address);
7336         }
7337       else
7338         {
7339           clib_memcpy (mp->dst_address, &v4_dst_address,
7340                        sizeof (v4_dst_address));
7341           if (next_hop_set)
7342             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7343                          sizeof (v4_next_hop_address));
7344           if (random_add_del)
7345             v4_dst_address.as_u32 = random_vector[j + 1];
7346           else
7347             increment_v4_address (&v4_dst_address);
7348         }
7349       /* send it... */
7350       S (mp);
7351       /* If we receive SIGTERM, stop now... */
7352       if (vam->do_exit)
7353         break;
7354     }
7355
7356   /* When testing multiple add/del ops, use a control-ping to sync */
7357   if (count > 1)
7358     {
7359       vl_api_control_ping_t *mp_ping;
7360       f64 after;
7361       f64 timeout;
7362
7363       /* Shut off async mode */
7364       vam->async_mode = 0;
7365
7366       M (CONTROL_PING, mp_ping);
7367       S (mp_ping);
7368
7369       timeout = vat_time_now (vam) + 1.0;
7370       while (vat_time_now (vam) < timeout)
7371         if (vam->result_ready == 1)
7372           goto out;
7373       vam->retval = -99;
7374
7375     out:
7376       if (vam->retval == -99)
7377         errmsg ("timeout");
7378
7379       if (vam->async_errors > 0)
7380         {
7381           errmsg ("%d asynchronous errors", vam->async_errors);
7382           vam->retval = -98;
7383         }
7384       vam->async_errors = 0;
7385       after = vat_time_now (vam);
7386
7387       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7388       if (j > 0)
7389         count = j;
7390
7391       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7392              count, after - before, count / (after - before));
7393     }
7394   else
7395     {
7396       int ret;
7397
7398       /* Wait for a reply... */
7399       W (ret);
7400       return ret;
7401     }
7402
7403   /* Return the good/bad news */
7404   return (vam->retval);
7405 }
7406
7407 static int
7408 api_ip_mroute_add_del (vat_main_t * vam)
7409 {
7410   unformat_input_t *i = vam->input;
7411   vl_api_ip_mroute_add_del_t *mp;
7412   u32 sw_if_index = ~0, vrf_id = 0;
7413   u8 is_ipv6 = 0;
7414   u8 is_local = 0;
7415   u8 create_vrf_if_needed = 0;
7416   u8 is_add = 1;
7417   u8 address_set = 0;
7418   u32 grp_address_length = 0;
7419   ip4_address_t v4_grp_address, v4_src_address;
7420   ip6_address_t v6_grp_address, v6_src_address;
7421   mfib_itf_flags_t iflags = 0;
7422   mfib_entry_flags_t eflags = 0;
7423   int ret;
7424
7425   /* Parse args required to build the message */
7426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7427     {
7428       if (unformat (i, "sw_if_index %d", &sw_if_index))
7429         ;
7430       else if (unformat (i, "%U %U",
7431                          unformat_ip4_address, &v4_src_address,
7432                          unformat_ip4_address, &v4_grp_address))
7433         {
7434           grp_address_length = 64;
7435           address_set = 1;
7436           is_ipv6 = 0;
7437         }
7438       else if (unformat (i, "%U %U",
7439                          unformat_ip6_address, &v6_src_address,
7440                          unformat_ip6_address, &v6_grp_address))
7441         {
7442           grp_address_length = 256;
7443           address_set = 1;
7444           is_ipv6 = 1;
7445         }
7446       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7447         {
7448           memset (&v4_src_address, 0, sizeof (v4_src_address));
7449           grp_address_length = 32;
7450           address_set = 1;
7451           is_ipv6 = 0;
7452         }
7453       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7454         {
7455           memset (&v6_src_address, 0, sizeof (v6_src_address));
7456           grp_address_length = 128;
7457           address_set = 1;
7458           is_ipv6 = 1;
7459         }
7460       else if (unformat (i, "/%d", &grp_address_length))
7461         ;
7462       else if (unformat (i, "local"))
7463         {
7464           is_local = 1;
7465         }
7466       else if (unformat (i, "del"))
7467         is_add = 0;
7468       else if (unformat (i, "add"))
7469         is_add = 1;
7470       else if (unformat (i, "vrf %d", &vrf_id))
7471         ;
7472       else if (unformat (i, "create-vrf"))
7473         create_vrf_if_needed = 1;
7474       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7475         ;
7476       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7477         ;
7478       else
7479         {
7480           clib_warning ("parse error '%U'", format_unformat_error, i);
7481           return -99;
7482         }
7483     }
7484
7485   if (address_set == 0)
7486     {
7487       errmsg ("missing addresses\n");
7488       return -99;
7489     }
7490
7491   /* Construct the API message */
7492   M (IP_MROUTE_ADD_DEL, mp);
7493
7494   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7495   mp->table_id = ntohl (vrf_id);
7496   mp->create_vrf_if_needed = create_vrf_if_needed;
7497
7498   mp->is_add = is_add;
7499   mp->is_ipv6 = is_ipv6;
7500   mp->is_local = is_local;
7501   mp->itf_flags = ntohl (iflags);
7502   mp->entry_flags = ntohl (eflags);
7503   mp->grp_address_length = grp_address_length;
7504   mp->grp_address_length = ntohs (mp->grp_address_length);
7505
7506   if (is_ipv6)
7507     {
7508       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7509       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7510     }
7511   else
7512     {
7513       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7514       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7515
7516     }
7517
7518   /* send it... */
7519   S (mp);
7520   /* Wait for a reply... */
7521   W (ret);
7522   return ret;
7523 }
7524
7525 static int
7526 api_mpls_table_add_del (vat_main_t * vam)
7527 {
7528   unformat_input_t *i = vam->input;
7529   vl_api_mpls_table_add_del_t *mp;
7530   u32 table_id = ~0;
7531   u8 is_add = 1;
7532   int ret = 0;
7533
7534   /* Parse args required to build the message */
7535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7536     {
7537       if (unformat (i, "table %d", &table_id))
7538         ;
7539       else if (unformat (i, "del"))
7540         is_add = 0;
7541       else if (unformat (i, "add"))
7542         is_add = 1;
7543       else
7544         {
7545           clib_warning ("parse error '%U'", format_unformat_error, i);
7546           return -99;
7547         }
7548     }
7549
7550   if (~0 == table_id)
7551     {
7552       errmsg ("missing table-ID");
7553       return -99;
7554     }
7555
7556   /* Construct the API message */
7557   M (MPLS_TABLE_ADD_DEL, mp);
7558
7559   mp->mt_table_id = ntohl (table_id);
7560   mp->mt_is_add = is_add;
7561
7562   /* send it... */
7563   S (mp);
7564
7565   /* Wait for a reply... */
7566   W (ret);
7567
7568   return ret;
7569 }
7570
7571 static int
7572 api_mpls_route_add_del (vat_main_t * vam)
7573 {
7574   unformat_input_t *i = vam->input;
7575   vl_api_mpls_route_add_del_t *mp;
7576   u32 sw_if_index = ~0, table_id = 0;
7577   u8 create_table_if_needed = 0;
7578   u8 is_add = 1;
7579   u32 next_hop_weight = 1;
7580   u8 is_multipath = 0;
7581   u32 next_hop_table_id = 0;
7582   u8 next_hop_set = 0;
7583   ip4_address_t v4_next_hop_address = {
7584     .as_u32 = 0,
7585   };
7586   ip6_address_t v6_next_hop_address = { {0} };
7587   int count = 1;
7588   int j;
7589   f64 before = 0;
7590   u32 classify_table_index = ~0;
7591   u8 is_classify = 0;
7592   u8 resolve_host = 0, resolve_attached = 0;
7593   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7594   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7595   mpls_label_t *next_hop_out_label_stack = NULL;
7596   mpls_label_t local_label = MPLS_LABEL_INVALID;
7597   u8 is_eos = 0;
7598   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
7599
7600   /* Parse args required to build the message */
7601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7602     {
7603       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7604         ;
7605       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7606         ;
7607       else if (unformat (i, "%d", &local_label))
7608         ;
7609       else if (unformat (i, "eos"))
7610         is_eos = 1;
7611       else if (unformat (i, "non-eos"))
7612         is_eos = 0;
7613       else if (unformat (i, "via %U", unformat_ip4_address,
7614                          &v4_next_hop_address))
7615         {
7616           next_hop_set = 1;
7617           next_hop_proto = DPO_PROTO_IP4;
7618         }
7619       else if (unformat (i, "via %U", unformat_ip6_address,
7620                          &v6_next_hop_address))
7621         {
7622           next_hop_set = 1;
7623           next_hop_proto = DPO_PROTO_IP6;
7624         }
7625       else if (unformat (i, "weight %d", &next_hop_weight))
7626         ;
7627       else if (unformat (i, "create-table"))
7628         create_table_if_needed = 1;
7629       else if (unformat (i, "classify %d", &classify_table_index))
7630         {
7631           is_classify = 1;
7632         }
7633       else if (unformat (i, "del"))
7634         is_add = 0;
7635       else if (unformat (i, "add"))
7636         is_add = 1;
7637       else if (unformat (i, "resolve-via-host"))
7638         resolve_host = 1;
7639       else if (unformat (i, "resolve-via-attached"))
7640         resolve_attached = 1;
7641       else if (unformat (i, "multipath"))
7642         is_multipath = 1;
7643       else if (unformat (i, "count %d", &count))
7644         ;
7645       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7646         {
7647           next_hop_set = 1;
7648           next_hop_proto = DPO_PROTO_IP4;
7649         }
7650       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7651         {
7652           next_hop_set = 1;
7653           next_hop_proto = DPO_PROTO_IP6;
7654         }
7655       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7656         ;
7657       else if (unformat (i, "via-label %d", &next_hop_via_label))
7658         ;
7659       else if (unformat (i, "out-label %d", &next_hop_out_label))
7660         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7661       else
7662         {
7663           clib_warning ("parse error '%U'", format_unformat_error, i);
7664           return -99;
7665         }
7666     }
7667
7668   if (!next_hop_set && !is_classify)
7669     {
7670       errmsg ("next hop / classify not set");
7671       return -99;
7672     }
7673
7674   if (MPLS_LABEL_INVALID == local_label)
7675     {
7676       errmsg ("missing label");
7677       return -99;
7678     }
7679
7680   if (count > 1)
7681     {
7682       /* Turn on async mode */
7683       vam->async_mode = 1;
7684       vam->async_errors = 0;
7685       before = vat_time_now (vam);
7686     }
7687
7688   for (j = 0; j < count; j++)
7689     {
7690       /* Construct the API message */
7691       M2 (MPLS_ROUTE_ADD_DEL, mp,
7692           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7693
7694       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7695       mp->mr_table_id = ntohl (table_id);
7696       mp->mr_create_table_if_needed = create_table_if_needed;
7697
7698       mp->mr_is_add = is_add;
7699       mp->mr_next_hop_proto = next_hop_proto;
7700       mp->mr_is_classify = is_classify;
7701       mp->mr_is_multipath = is_multipath;
7702       mp->mr_is_resolve_host = resolve_host;
7703       mp->mr_is_resolve_attached = resolve_attached;
7704       mp->mr_next_hop_weight = next_hop_weight;
7705       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7706       mp->mr_classify_table_index = ntohl (classify_table_index);
7707       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7708       mp->mr_label = ntohl (local_label);
7709       mp->mr_eos = is_eos;
7710
7711       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7712       if (0 != mp->mr_next_hop_n_out_labels)
7713         {
7714           memcpy (mp->mr_next_hop_out_label_stack,
7715                   next_hop_out_label_stack,
7716                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7717           vec_free (next_hop_out_label_stack);
7718         }
7719
7720       if (next_hop_set)
7721         {
7722           if (DPO_PROTO_IP4 == next_hop_proto)
7723             {
7724               clib_memcpy (mp->mr_next_hop,
7725                            &v4_next_hop_address,
7726                            sizeof (v4_next_hop_address));
7727             }
7728           else if (DPO_PROTO_IP6 == next_hop_proto)
7729
7730             {
7731               clib_memcpy (mp->mr_next_hop,
7732                            &v6_next_hop_address,
7733                            sizeof (v6_next_hop_address));
7734             }
7735         }
7736       local_label++;
7737
7738       /* send it... */
7739       S (mp);
7740       /* If we receive SIGTERM, stop now... */
7741       if (vam->do_exit)
7742         break;
7743     }
7744
7745   /* When testing multiple add/del ops, use a control-ping to sync */
7746   if (count > 1)
7747     {
7748       vl_api_control_ping_t *mp_ping;
7749       f64 after;
7750       f64 timeout;
7751
7752       /* Shut off async mode */
7753       vam->async_mode = 0;
7754
7755       M (CONTROL_PING, mp_ping);
7756       S (mp_ping);
7757
7758       timeout = vat_time_now (vam) + 1.0;
7759       while (vat_time_now (vam) < timeout)
7760         if (vam->result_ready == 1)
7761           goto out;
7762       vam->retval = -99;
7763
7764     out:
7765       if (vam->retval == -99)
7766         errmsg ("timeout");
7767
7768       if (vam->async_errors > 0)
7769         {
7770           errmsg ("%d asynchronous errors", vam->async_errors);
7771           vam->retval = -98;
7772         }
7773       vam->async_errors = 0;
7774       after = vat_time_now (vam);
7775
7776       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7777       if (j > 0)
7778         count = j;
7779
7780       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7781              count, after - before, count / (after - before));
7782     }
7783   else
7784     {
7785       int ret;
7786
7787       /* Wait for a reply... */
7788       W (ret);
7789       return ret;
7790     }
7791
7792   /* Return the good/bad news */
7793   return (vam->retval);
7794 }
7795
7796 static int
7797 api_mpls_ip_bind_unbind (vat_main_t * vam)
7798 {
7799   unformat_input_t *i = vam->input;
7800   vl_api_mpls_ip_bind_unbind_t *mp;
7801   u32 ip_table_id = 0;
7802   u8 create_table_if_needed = 0;
7803   u8 is_bind = 1;
7804   u8 is_ip4 = 1;
7805   ip4_address_t v4_address;
7806   ip6_address_t v6_address;
7807   u32 address_length;
7808   u8 address_set = 0;
7809   mpls_label_t local_label = MPLS_LABEL_INVALID;
7810   int ret;
7811
7812   /* Parse args required to build the message */
7813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7814     {
7815       if (unformat (i, "%U/%d", unformat_ip4_address,
7816                     &v4_address, &address_length))
7817         {
7818           is_ip4 = 1;
7819           address_set = 1;
7820         }
7821       else if (unformat (i, "%U/%d", unformat_ip6_address,
7822                          &v6_address, &address_length))
7823         {
7824           is_ip4 = 0;
7825           address_set = 1;
7826         }
7827       else if (unformat (i, "%d", &local_label))
7828         ;
7829       else if (unformat (i, "create-table"))
7830         create_table_if_needed = 1;
7831       else if (unformat (i, "table-id %d", &ip_table_id))
7832         ;
7833       else if (unformat (i, "unbind"))
7834         is_bind = 0;
7835       else if (unformat (i, "bind"))
7836         is_bind = 1;
7837       else
7838         {
7839           clib_warning ("parse error '%U'", format_unformat_error, i);
7840           return -99;
7841         }
7842     }
7843
7844   if (!address_set)
7845     {
7846       errmsg ("IP addres not set");
7847       return -99;
7848     }
7849
7850   if (MPLS_LABEL_INVALID == local_label)
7851     {
7852       errmsg ("missing label");
7853       return -99;
7854     }
7855
7856   /* Construct the API message */
7857   M (MPLS_IP_BIND_UNBIND, mp);
7858
7859   mp->mb_create_table_if_needed = create_table_if_needed;
7860   mp->mb_is_bind = is_bind;
7861   mp->mb_is_ip4 = is_ip4;
7862   mp->mb_ip_table_id = ntohl (ip_table_id);
7863   mp->mb_mpls_table_id = 0;
7864   mp->mb_label = ntohl (local_label);
7865   mp->mb_address_length = address_length;
7866
7867   if (is_ip4)
7868     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7869   else
7870     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7871
7872   /* send it... */
7873   S (mp);
7874
7875   /* Wait for a reply... */
7876   W (ret);
7877   return ret;
7878 }
7879
7880 static int
7881 api_proxy_arp_add_del (vat_main_t * vam)
7882 {
7883   unformat_input_t *i = vam->input;
7884   vl_api_proxy_arp_add_del_t *mp;
7885   u32 vrf_id = 0;
7886   u8 is_add = 1;
7887   ip4_address_t lo, hi;
7888   u8 range_set = 0;
7889   int ret;
7890
7891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7892     {
7893       if (unformat (i, "vrf %d", &vrf_id))
7894         ;
7895       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7896                          unformat_ip4_address, &hi))
7897         range_set = 1;
7898       else if (unformat (i, "del"))
7899         is_add = 0;
7900       else
7901         {
7902           clib_warning ("parse error '%U'", format_unformat_error, i);
7903           return -99;
7904         }
7905     }
7906
7907   if (range_set == 0)
7908     {
7909       errmsg ("address range not set");
7910       return -99;
7911     }
7912
7913   M (PROXY_ARP_ADD_DEL, mp);
7914
7915   mp->vrf_id = ntohl (vrf_id);
7916   mp->is_add = is_add;
7917   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7918   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7919
7920   S (mp);
7921   W (ret);
7922   return ret;
7923 }
7924
7925 static int
7926 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7927 {
7928   unformat_input_t *i = vam->input;
7929   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7930   u32 sw_if_index;
7931   u8 enable = 1;
7932   u8 sw_if_index_set = 0;
7933   int ret;
7934
7935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7936     {
7937       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7938         sw_if_index_set = 1;
7939       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7940         sw_if_index_set = 1;
7941       else if (unformat (i, "enable"))
7942         enable = 1;
7943       else if (unformat (i, "disable"))
7944         enable = 0;
7945       else
7946         {
7947           clib_warning ("parse error '%U'", format_unformat_error, i);
7948           return -99;
7949         }
7950     }
7951
7952   if (sw_if_index_set == 0)
7953     {
7954       errmsg ("missing interface name or sw_if_index");
7955       return -99;
7956     }
7957
7958   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7959
7960   mp->sw_if_index = ntohl (sw_if_index);
7961   mp->enable_disable = enable;
7962
7963   S (mp);
7964   W (ret);
7965   return ret;
7966 }
7967
7968 static int
7969 api_mpls_tunnel_add_del (vat_main_t * vam)
7970 {
7971   unformat_input_t *i = vam->input;
7972   vl_api_mpls_tunnel_add_del_t *mp;
7973
7974   u8 is_add = 1;
7975   u8 l2_only = 0;
7976   u32 sw_if_index = ~0;
7977   u32 next_hop_sw_if_index = ~0;
7978   u32 next_hop_proto_is_ip4 = 1;
7979
7980   u32 next_hop_table_id = 0;
7981   ip4_address_t v4_next_hop_address = {
7982     .as_u32 = 0,
7983   };
7984   ip6_address_t v6_next_hop_address = { {0} };
7985   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7986   int ret;
7987
7988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7989     {
7990       if (unformat (i, "add"))
7991         is_add = 1;
7992       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7993         is_add = 0;
7994       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7995         ;
7996       else if (unformat (i, "via %U",
7997                          unformat_ip4_address, &v4_next_hop_address))
7998         {
7999           next_hop_proto_is_ip4 = 1;
8000         }
8001       else if (unformat (i, "via %U",
8002                          unformat_ip6_address, &v6_next_hop_address))
8003         {
8004           next_hop_proto_is_ip4 = 0;
8005         }
8006       else if (unformat (i, "l2-only"))
8007         l2_only = 1;
8008       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8009         ;
8010       else if (unformat (i, "out-label %d", &next_hop_out_label))
8011         vec_add1 (labels, ntohl (next_hop_out_label));
8012       else
8013         {
8014           clib_warning ("parse error '%U'", format_unformat_error, i);
8015           return -99;
8016         }
8017     }
8018
8019   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8020
8021   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8022   mp->mt_sw_if_index = ntohl (sw_if_index);
8023   mp->mt_is_add = is_add;
8024   mp->mt_l2_only = l2_only;
8025   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8026   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8027
8028   mp->mt_next_hop_n_out_labels = vec_len (labels);
8029
8030   if (0 != mp->mt_next_hop_n_out_labels)
8031     {
8032       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8033                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8034       vec_free (labels);
8035     }
8036
8037   if (next_hop_proto_is_ip4)
8038     {
8039       clib_memcpy (mp->mt_next_hop,
8040                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8041     }
8042   else
8043     {
8044       clib_memcpy (mp->mt_next_hop,
8045                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8046     }
8047
8048   S (mp);
8049   W (ret);
8050   return ret;
8051 }
8052
8053 static int
8054 api_sw_interface_set_unnumbered (vat_main_t * vam)
8055 {
8056   unformat_input_t *i = vam->input;
8057   vl_api_sw_interface_set_unnumbered_t *mp;
8058   u32 sw_if_index;
8059   u32 unnum_sw_index = ~0;
8060   u8 is_add = 1;
8061   u8 sw_if_index_set = 0;
8062   int ret;
8063
8064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8065     {
8066       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8067         sw_if_index_set = 1;
8068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8069         sw_if_index_set = 1;
8070       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8071         ;
8072       else if (unformat (i, "del"))
8073         is_add = 0;
8074       else
8075         {
8076           clib_warning ("parse error '%U'", format_unformat_error, i);
8077           return -99;
8078         }
8079     }
8080
8081   if (sw_if_index_set == 0)
8082     {
8083       errmsg ("missing interface name or sw_if_index");
8084       return -99;
8085     }
8086
8087   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8088
8089   mp->sw_if_index = ntohl (sw_if_index);
8090   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8091   mp->is_add = is_add;
8092
8093   S (mp);
8094   W (ret);
8095   return ret;
8096 }
8097
8098 static int
8099 api_ip_neighbor_add_del (vat_main_t * vam)
8100 {
8101   unformat_input_t *i = vam->input;
8102   vl_api_ip_neighbor_add_del_t *mp;
8103   u32 sw_if_index;
8104   u8 sw_if_index_set = 0;
8105   u8 is_add = 1;
8106   u8 is_static = 0;
8107   u8 is_no_fib_entry = 0;
8108   u8 mac_address[6];
8109   u8 mac_set = 0;
8110   u8 v4_address_set = 0;
8111   u8 v6_address_set = 0;
8112   ip4_address_t v4address;
8113   ip6_address_t v6address;
8114   int ret;
8115
8116   memset (mac_address, 0, sizeof (mac_address));
8117
8118   /* Parse args required to build the message */
8119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8120     {
8121       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8122         {
8123           mac_set = 1;
8124         }
8125       else if (unformat (i, "del"))
8126         is_add = 0;
8127       else
8128         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8129         sw_if_index_set = 1;
8130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8131         sw_if_index_set = 1;
8132       else if (unformat (i, "is_static"))
8133         is_static = 1;
8134       else if (unformat (i, "no-fib-entry"))
8135         is_no_fib_entry = 1;
8136       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8137         v4_address_set = 1;
8138       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8139         v6_address_set = 1;
8140       else
8141         {
8142           clib_warning ("parse error '%U'", format_unformat_error, i);
8143           return -99;
8144         }
8145     }
8146
8147   if (sw_if_index_set == 0)
8148     {
8149       errmsg ("missing interface name or sw_if_index");
8150       return -99;
8151     }
8152   if (v4_address_set && v6_address_set)
8153     {
8154       errmsg ("both v4 and v6 addresses set");
8155       return -99;
8156     }
8157   if (!v4_address_set && !v6_address_set)
8158     {
8159       errmsg ("no address set");
8160       return -99;
8161     }
8162
8163   /* Construct the API message */
8164   M (IP_NEIGHBOR_ADD_DEL, mp);
8165
8166   mp->sw_if_index = ntohl (sw_if_index);
8167   mp->is_add = is_add;
8168   mp->is_static = is_static;
8169   mp->is_no_adj_fib = is_no_fib_entry;
8170   if (mac_set)
8171     clib_memcpy (mp->mac_address, mac_address, 6);
8172   if (v6_address_set)
8173     {
8174       mp->is_ipv6 = 1;
8175       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8176     }
8177   else
8178     {
8179       /* mp->is_ipv6 = 0; via memset in M macro above */
8180       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8181     }
8182
8183   /* send it... */
8184   S (mp);
8185
8186   /* Wait for a reply, return good/bad news  */
8187   W (ret);
8188   return ret;
8189 }
8190
8191 static int
8192 api_reset_vrf (vat_main_t * vam)
8193 {
8194   unformat_input_t *i = vam->input;
8195   vl_api_reset_vrf_t *mp;
8196   u32 vrf_id = 0;
8197   u8 is_ipv6 = 0;
8198   u8 vrf_id_set = 0;
8199   int ret;
8200
8201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8202     {
8203       if (unformat (i, "vrf %d", &vrf_id))
8204         vrf_id_set = 1;
8205       else if (unformat (i, "ipv6"))
8206         is_ipv6 = 1;
8207       else
8208         {
8209           clib_warning ("parse error '%U'", format_unformat_error, i);
8210           return -99;
8211         }
8212     }
8213
8214   if (vrf_id_set == 0)
8215     {
8216       errmsg ("missing vrf id");
8217       return -99;
8218     }
8219
8220   M (RESET_VRF, mp);
8221
8222   mp->vrf_id = ntohl (vrf_id);
8223   mp->is_ipv6 = is_ipv6;
8224
8225   S (mp);
8226   W (ret);
8227   return ret;
8228 }
8229
8230 static int
8231 api_create_vlan_subif (vat_main_t * vam)
8232 {
8233   unformat_input_t *i = vam->input;
8234   vl_api_create_vlan_subif_t *mp;
8235   u32 sw_if_index;
8236   u8 sw_if_index_set = 0;
8237   u32 vlan_id;
8238   u8 vlan_id_set = 0;
8239   int ret;
8240
8241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8242     {
8243       if (unformat (i, "sw_if_index %d", &sw_if_index))
8244         sw_if_index_set = 1;
8245       else
8246         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8247         sw_if_index_set = 1;
8248       else if (unformat (i, "vlan %d", &vlan_id))
8249         vlan_id_set = 1;
8250       else
8251         {
8252           clib_warning ("parse error '%U'", format_unformat_error, i);
8253           return -99;
8254         }
8255     }
8256
8257   if (sw_if_index_set == 0)
8258     {
8259       errmsg ("missing interface name or sw_if_index");
8260       return -99;
8261     }
8262
8263   if (vlan_id_set == 0)
8264     {
8265       errmsg ("missing vlan_id");
8266       return -99;
8267     }
8268   M (CREATE_VLAN_SUBIF, mp);
8269
8270   mp->sw_if_index = ntohl (sw_if_index);
8271   mp->vlan_id = ntohl (vlan_id);
8272
8273   S (mp);
8274   W (ret);
8275   return ret;
8276 }
8277
8278 #define foreach_create_subif_bit                \
8279 _(no_tags)                                      \
8280 _(one_tag)                                      \
8281 _(two_tags)                                     \
8282 _(dot1ad)                                       \
8283 _(exact_match)                                  \
8284 _(default_sub)                                  \
8285 _(outer_vlan_id_any)                            \
8286 _(inner_vlan_id_any)
8287
8288 static int
8289 api_create_subif (vat_main_t * vam)
8290 {
8291   unformat_input_t *i = vam->input;
8292   vl_api_create_subif_t *mp;
8293   u32 sw_if_index;
8294   u8 sw_if_index_set = 0;
8295   u32 sub_id;
8296   u8 sub_id_set = 0;
8297   u32 no_tags = 0;
8298   u32 one_tag = 0;
8299   u32 two_tags = 0;
8300   u32 dot1ad = 0;
8301   u32 exact_match = 0;
8302   u32 default_sub = 0;
8303   u32 outer_vlan_id_any = 0;
8304   u32 inner_vlan_id_any = 0;
8305   u32 tmp;
8306   u16 outer_vlan_id = 0;
8307   u16 inner_vlan_id = 0;
8308   int ret;
8309
8310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8311     {
8312       if (unformat (i, "sw_if_index %d", &sw_if_index))
8313         sw_if_index_set = 1;
8314       else
8315         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8316         sw_if_index_set = 1;
8317       else if (unformat (i, "sub_id %d", &sub_id))
8318         sub_id_set = 1;
8319       else if (unformat (i, "outer_vlan_id %d", &tmp))
8320         outer_vlan_id = tmp;
8321       else if (unformat (i, "inner_vlan_id %d", &tmp))
8322         inner_vlan_id = tmp;
8323
8324 #define _(a) else if (unformat (i, #a)) a = 1 ;
8325       foreach_create_subif_bit
8326 #undef _
8327         else
8328         {
8329           clib_warning ("parse error '%U'", format_unformat_error, i);
8330           return -99;
8331         }
8332     }
8333
8334   if (sw_if_index_set == 0)
8335     {
8336       errmsg ("missing interface name or sw_if_index");
8337       return -99;
8338     }
8339
8340   if (sub_id_set == 0)
8341     {
8342       errmsg ("missing sub_id");
8343       return -99;
8344     }
8345   M (CREATE_SUBIF, mp);
8346
8347   mp->sw_if_index = ntohl (sw_if_index);
8348   mp->sub_id = ntohl (sub_id);
8349
8350 #define _(a) mp->a = a;
8351   foreach_create_subif_bit;
8352 #undef _
8353
8354   mp->outer_vlan_id = ntohs (outer_vlan_id);
8355   mp->inner_vlan_id = ntohs (inner_vlan_id);
8356
8357   S (mp);
8358   W (ret);
8359   return ret;
8360 }
8361
8362 static int
8363 api_oam_add_del (vat_main_t * vam)
8364 {
8365   unformat_input_t *i = vam->input;
8366   vl_api_oam_add_del_t *mp;
8367   u32 vrf_id = 0;
8368   u8 is_add = 1;
8369   ip4_address_t src, dst;
8370   u8 src_set = 0;
8371   u8 dst_set = 0;
8372   int ret;
8373
8374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8375     {
8376       if (unformat (i, "vrf %d", &vrf_id))
8377         ;
8378       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8379         src_set = 1;
8380       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8381         dst_set = 1;
8382       else if (unformat (i, "del"))
8383         is_add = 0;
8384       else
8385         {
8386           clib_warning ("parse error '%U'", format_unformat_error, i);
8387           return -99;
8388         }
8389     }
8390
8391   if (src_set == 0)
8392     {
8393       errmsg ("missing src addr");
8394       return -99;
8395     }
8396
8397   if (dst_set == 0)
8398     {
8399       errmsg ("missing dst addr");
8400       return -99;
8401     }
8402
8403   M (OAM_ADD_DEL, mp);
8404
8405   mp->vrf_id = ntohl (vrf_id);
8406   mp->is_add = is_add;
8407   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8408   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8409
8410   S (mp);
8411   W (ret);
8412   return ret;
8413 }
8414
8415 static int
8416 api_reset_fib (vat_main_t * vam)
8417 {
8418   unformat_input_t *i = vam->input;
8419   vl_api_reset_fib_t *mp;
8420   u32 vrf_id = 0;
8421   u8 is_ipv6 = 0;
8422   u8 vrf_id_set = 0;
8423
8424   int ret;
8425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8426     {
8427       if (unformat (i, "vrf %d", &vrf_id))
8428         vrf_id_set = 1;
8429       else if (unformat (i, "ipv6"))
8430         is_ipv6 = 1;
8431       else
8432         {
8433           clib_warning ("parse error '%U'", format_unformat_error, i);
8434           return -99;
8435         }
8436     }
8437
8438   if (vrf_id_set == 0)
8439     {
8440       errmsg ("missing vrf id");
8441       return -99;
8442     }
8443
8444   M (RESET_FIB, mp);
8445
8446   mp->vrf_id = ntohl (vrf_id);
8447   mp->is_ipv6 = is_ipv6;
8448
8449   S (mp);
8450   W (ret);
8451   return ret;
8452 }
8453
8454 static int
8455 api_dhcp_proxy_config (vat_main_t * vam)
8456 {
8457   unformat_input_t *i = vam->input;
8458   vl_api_dhcp_proxy_config_t *mp;
8459   u32 rx_vrf_id = 0;
8460   u32 server_vrf_id = 0;
8461   u8 is_add = 1;
8462   u8 v4_address_set = 0;
8463   u8 v6_address_set = 0;
8464   ip4_address_t v4address;
8465   ip6_address_t v6address;
8466   u8 v4_src_address_set = 0;
8467   u8 v6_src_address_set = 0;
8468   ip4_address_t v4srcaddress;
8469   ip6_address_t v6srcaddress;
8470   int ret;
8471
8472   /* Parse args required to build the message */
8473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8474     {
8475       if (unformat (i, "del"))
8476         is_add = 0;
8477       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8478         ;
8479       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8480         ;
8481       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8482         v4_address_set = 1;
8483       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8484         v6_address_set = 1;
8485       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8486         v4_src_address_set = 1;
8487       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8488         v6_src_address_set = 1;
8489       else
8490         break;
8491     }
8492
8493   if (v4_address_set && v6_address_set)
8494     {
8495       errmsg ("both v4 and v6 server addresses set");
8496       return -99;
8497     }
8498   if (!v4_address_set && !v6_address_set)
8499     {
8500       errmsg ("no server addresses set");
8501       return -99;
8502     }
8503
8504   if (v4_src_address_set && v6_src_address_set)
8505     {
8506       errmsg ("both v4 and v6  src addresses set");
8507       return -99;
8508     }
8509   if (!v4_src_address_set && !v6_src_address_set)
8510     {
8511       errmsg ("no src addresses set");
8512       return -99;
8513     }
8514
8515   if (!(v4_src_address_set && v4_address_set) &&
8516       !(v6_src_address_set && v6_address_set))
8517     {
8518       errmsg ("no matching server and src addresses set");
8519       return -99;
8520     }
8521
8522   /* Construct the API message */
8523   M (DHCP_PROXY_CONFIG, mp);
8524
8525   mp->is_add = is_add;
8526   mp->rx_vrf_id = ntohl (rx_vrf_id);
8527   mp->server_vrf_id = ntohl (server_vrf_id);
8528   if (v6_address_set)
8529     {
8530       mp->is_ipv6 = 1;
8531       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8532       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8533     }
8534   else
8535     {
8536       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8537       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8538     }
8539
8540   /* send it... */
8541   S (mp);
8542
8543   /* Wait for a reply, return good/bad news  */
8544   W (ret);
8545   return ret;
8546 }
8547
8548 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8549 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8550
8551 static void
8552 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8553 {
8554   vat_main_t *vam = &vat_main;
8555   u32 i, count = mp->count;
8556   vl_api_dhcp_server_t *s;
8557
8558   if (mp->is_ipv6)
8559     print (vam->ofp,
8560            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8561            ntohl (mp->rx_vrf_id),
8562            format_ip6_address, mp->dhcp_src_address,
8563            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8564   else
8565     print (vam->ofp,
8566            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8567            ntohl (mp->rx_vrf_id),
8568            format_ip4_address, mp->dhcp_src_address,
8569            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8570
8571   for (i = 0; i < count; i++)
8572     {
8573       s = &mp->servers[i];
8574
8575       if (mp->is_ipv6)
8576         print (vam->ofp,
8577                " Server Table-ID %d, Server Address %U",
8578                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8579       else
8580         print (vam->ofp,
8581                " Server Table-ID %d, Server Address %U",
8582                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8583     }
8584 }
8585
8586 static void vl_api_dhcp_proxy_details_t_handler_json
8587   (vl_api_dhcp_proxy_details_t * mp)
8588 {
8589   vat_main_t *vam = &vat_main;
8590   vat_json_node_t *node = NULL;
8591   u32 i, count = mp->count;
8592   struct in_addr ip4;
8593   struct in6_addr ip6;
8594   vl_api_dhcp_server_t *s;
8595
8596   if (VAT_JSON_ARRAY != vam->json_tree.type)
8597     {
8598       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8599       vat_json_init_array (&vam->json_tree);
8600     }
8601   node = vat_json_array_add (&vam->json_tree);
8602
8603   vat_json_init_object (node);
8604   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8605   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8606   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8607
8608   if (mp->is_ipv6)
8609     {
8610       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8611       vat_json_object_add_ip6 (node, "src_address", ip6);
8612     }
8613   else
8614     {
8615       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8616       vat_json_object_add_ip4 (node, "src_address", ip4);
8617     }
8618
8619   for (i = 0; i < count; i++)
8620     {
8621       s = &mp->servers[i];
8622
8623       vat_json_object_add_uint (node, "server-table-id",
8624                                 ntohl (s->server_vrf_id));
8625
8626       if (mp->is_ipv6)
8627         {
8628           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8629           vat_json_object_add_ip4 (node, "src_address", ip4);
8630         }
8631       else
8632         {
8633           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8634           vat_json_object_add_ip6 (node, "server_address", ip6);
8635         }
8636     }
8637 }
8638
8639 static int
8640 api_dhcp_proxy_dump (vat_main_t * vam)
8641 {
8642   unformat_input_t *i = vam->input;
8643   vl_api_control_ping_t *mp_ping;
8644   vl_api_dhcp_proxy_dump_t *mp;
8645   u8 is_ipv6 = 0;
8646   int ret;
8647
8648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8649     {
8650       if (unformat (i, "ipv6"))
8651         is_ipv6 = 1;
8652       else
8653         {
8654           clib_warning ("parse error '%U'", format_unformat_error, i);
8655           return -99;
8656         }
8657     }
8658
8659   M (DHCP_PROXY_DUMP, mp);
8660
8661   mp->is_ip6 = is_ipv6;
8662   S (mp);
8663
8664   /* Use a control ping for synchronization */
8665   M (CONTROL_PING, mp_ping);
8666   S (mp_ping);
8667
8668   W (ret);
8669   return ret;
8670 }
8671
8672 static int
8673 api_dhcp_proxy_set_vss (vat_main_t * vam)
8674 {
8675   unformat_input_t *i = vam->input;
8676   vl_api_dhcp_proxy_set_vss_t *mp;
8677   u8 is_ipv6 = 0;
8678   u8 is_add = 1;
8679   u32 tbl_id;
8680   u8 tbl_id_set = 0;
8681   u32 oui;
8682   u8 oui_set = 0;
8683   u32 fib_id;
8684   u8 fib_id_set = 0;
8685   int ret;
8686
8687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8688     {
8689       if (unformat (i, "tbl_id %d", &tbl_id))
8690         tbl_id_set = 1;
8691       if (unformat (i, "fib_id %d", &fib_id))
8692         fib_id_set = 1;
8693       if (unformat (i, "oui %d", &oui))
8694         oui_set = 1;
8695       else if (unformat (i, "ipv6"))
8696         is_ipv6 = 1;
8697       else if (unformat (i, "del"))
8698         is_add = 0;
8699       else
8700         {
8701           clib_warning ("parse error '%U'", format_unformat_error, i);
8702           return -99;
8703         }
8704     }
8705
8706   if (tbl_id_set == 0)
8707     {
8708       errmsg ("missing tbl id");
8709       return -99;
8710     }
8711
8712   if (fib_id_set == 0)
8713     {
8714       errmsg ("missing fib id");
8715       return -99;
8716     }
8717   if (oui_set == 0)
8718     {
8719       errmsg ("missing oui");
8720       return -99;
8721     }
8722
8723   M (DHCP_PROXY_SET_VSS, mp);
8724   mp->tbl_id = ntohl (tbl_id);
8725   mp->fib_id = ntohl (fib_id);
8726   mp->oui = ntohl (oui);
8727   mp->is_ipv6 = is_ipv6;
8728   mp->is_add = is_add;
8729
8730   S (mp);
8731   W (ret);
8732   return ret;
8733 }
8734
8735 static int
8736 api_dhcp_client_config (vat_main_t * vam)
8737 {
8738   unformat_input_t *i = vam->input;
8739   vl_api_dhcp_client_config_t *mp;
8740   u32 sw_if_index;
8741   u8 sw_if_index_set = 0;
8742   u8 is_add = 1;
8743   u8 *hostname = 0;
8744   u8 disable_event = 0;
8745   int ret;
8746
8747   /* Parse args required to build the message */
8748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8749     {
8750       if (unformat (i, "del"))
8751         is_add = 0;
8752       else
8753         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8754         sw_if_index_set = 1;
8755       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8756         sw_if_index_set = 1;
8757       else if (unformat (i, "hostname %s", &hostname))
8758         ;
8759       else if (unformat (i, "disable_event"))
8760         disable_event = 1;
8761       else
8762         break;
8763     }
8764
8765   if (sw_if_index_set == 0)
8766     {
8767       errmsg ("missing interface name or sw_if_index");
8768       return -99;
8769     }
8770
8771   if (vec_len (hostname) > 63)
8772     {
8773       errmsg ("hostname too long");
8774     }
8775   vec_add1 (hostname, 0);
8776
8777   /* Construct the API message */
8778   M (DHCP_CLIENT_CONFIG, mp);
8779
8780   mp->sw_if_index = htonl (sw_if_index);
8781   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8782   vec_free (hostname);
8783   mp->is_add = is_add;
8784   mp->want_dhcp_event = disable_event ? 0 : 1;
8785   mp->pid = htonl (getpid ());
8786
8787   /* send it... */
8788   S (mp);
8789
8790   /* Wait for a reply, return good/bad news  */
8791   W (ret);
8792   return ret;
8793 }
8794
8795 static int
8796 api_set_ip_flow_hash (vat_main_t * vam)
8797 {
8798   unformat_input_t *i = vam->input;
8799   vl_api_set_ip_flow_hash_t *mp;
8800   u32 vrf_id = 0;
8801   u8 is_ipv6 = 0;
8802   u8 vrf_id_set = 0;
8803   u8 src = 0;
8804   u8 dst = 0;
8805   u8 sport = 0;
8806   u8 dport = 0;
8807   u8 proto = 0;
8808   u8 reverse = 0;
8809   int ret;
8810
8811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8812     {
8813       if (unformat (i, "vrf %d", &vrf_id))
8814         vrf_id_set = 1;
8815       else if (unformat (i, "ipv6"))
8816         is_ipv6 = 1;
8817       else if (unformat (i, "src"))
8818         src = 1;
8819       else if (unformat (i, "dst"))
8820         dst = 1;
8821       else if (unformat (i, "sport"))
8822         sport = 1;
8823       else if (unformat (i, "dport"))
8824         dport = 1;
8825       else if (unformat (i, "proto"))
8826         proto = 1;
8827       else if (unformat (i, "reverse"))
8828         reverse = 1;
8829
8830       else
8831         {
8832           clib_warning ("parse error '%U'", format_unformat_error, i);
8833           return -99;
8834         }
8835     }
8836
8837   if (vrf_id_set == 0)
8838     {
8839       errmsg ("missing vrf id");
8840       return -99;
8841     }
8842
8843   M (SET_IP_FLOW_HASH, mp);
8844   mp->src = src;
8845   mp->dst = dst;
8846   mp->sport = sport;
8847   mp->dport = dport;
8848   mp->proto = proto;
8849   mp->reverse = reverse;
8850   mp->vrf_id = ntohl (vrf_id);
8851   mp->is_ipv6 = is_ipv6;
8852
8853   S (mp);
8854   W (ret);
8855   return ret;
8856 }
8857
8858 static int
8859 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8860 {
8861   unformat_input_t *i = vam->input;
8862   vl_api_sw_interface_ip6_enable_disable_t *mp;
8863   u32 sw_if_index;
8864   u8 sw_if_index_set = 0;
8865   u8 enable = 0;
8866   int ret;
8867
8868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8869     {
8870       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8871         sw_if_index_set = 1;
8872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8873         sw_if_index_set = 1;
8874       else if (unformat (i, "enable"))
8875         enable = 1;
8876       else if (unformat (i, "disable"))
8877         enable = 0;
8878       else
8879         {
8880           clib_warning ("parse error '%U'", format_unformat_error, i);
8881           return -99;
8882         }
8883     }
8884
8885   if (sw_if_index_set == 0)
8886     {
8887       errmsg ("missing interface name or sw_if_index");
8888       return -99;
8889     }
8890
8891   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8892
8893   mp->sw_if_index = ntohl (sw_if_index);
8894   mp->enable = enable;
8895
8896   S (mp);
8897   W (ret);
8898   return ret;
8899 }
8900
8901 static int
8902 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8903 {
8904   unformat_input_t *i = vam->input;
8905   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8906   u32 sw_if_index;
8907   u8 sw_if_index_set = 0;
8908   u8 v6_address_set = 0;
8909   ip6_address_t v6address;
8910   int ret;
8911
8912   /* Parse args required to build the message */
8913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8914     {
8915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8916         sw_if_index_set = 1;
8917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8918         sw_if_index_set = 1;
8919       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8920         v6_address_set = 1;
8921       else
8922         break;
8923     }
8924
8925   if (sw_if_index_set == 0)
8926     {
8927       errmsg ("missing interface name or sw_if_index");
8928       return -99;
8929     }
8930   if (!v6_address_set)
8931     {
8932       errmsg ("no address set");
8933       return -99;
8934     }
8935
8936   /* Construct the API message */
8937   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8938
8939   mp->sw_if_index = ntohl (sw_if_index);
8940   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8941
8942   /* send it... */
8943   S (mp);
8944
8945   /* Wait for a reply, return good/bad news  */
8946   W (ret);
8947   return ret;
8948 }
8949
8950 static int
8951 api_ip6nd_proxy_add_del (vat_main_t * vam)
8952 {
8953   unformat_input_t *i = vam->input;
8954   vl_api_ip6nd_proxy_add_del_t *mp;
8955   u32 sw_if_index = ~0;
8956   u8 v6_address_set = 0;
8957   ip6_address_t v6address;
8958   u8 is_del = 0;
8959   int ret;
8960
8961   /* Parse args required to build the message */
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8965         ;
8966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8967         ;
8968       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8969         v6_address_set = 1;
8970       if (unformat (i, "del"))
8971         is_del = 1;
8972       else
8973         {
8974           clib_warning ("parse error '%U'", format_unformat_error, i);
8975           return -99;
8976         }
8977     }
8978
8979   if (sw_if_index == ~0)
8980     {
8981       errmsg ("missing interface name or sw_if_index");
8982       return -99;
8983     }
8984   if (!v6_address_set)
8985     {
8986       errmsg ("no address set");
8987       return -99;
8988     }
8989
8990   /* Construct the API message */
8991   M (IP6ND_PROXY_ADD_DEL, mp);
8992
8993   mp->is_del = is_del;
8994   mp->sw_if_index = ntohl (sw_if_index);
8995   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8996
8997   /* send it... */
8998   S (mp);
8999
9000   /* Wait for a reply, return good/bad news  */
9001   W (ret);
9002   return ret;
9003 }
9004
9005 static int
9006 api_ip6nd_proxy_dump (vat_main_t * vam)
9007 {
9008   vl_api_ip6nd_proxy_dump_t *mp;
9009   vl_api_control_ping_t *mp_ping;
9010   int ret;
9011
9012   M (IP6ND_PROXY_DUMP, mp);
9013
9014   S (mp);
9015
9016   /* Use a control ping for synchronization */
9017   M (CONTROL_PING, mp_ping);
9018   S (mp_ping);
9019
9020   W (ret);
9021   return ret;
9022 }
9023
9024 static void vl_api_ip6nd_proxy_details_t_handler
9025   (vl_api_ip6nd_proxy_details_t * mp)
9026 {
9027   vat_main_t *vam = &vat_main;
9028
9029   print (vam->ofp, "host %U sw_if_index %d",
9030          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9031 }
9032
9033 static void vl_api_ip6nd_proxy_details_t_handler_json
9034   (vl_api_ip6nd_proxy_details_t * mp)
9035 {
9036   vat_main_t *vam = &vat_main;
9037   struct in6_addr ip6;
9038   vat_json_node_t *node = NULL;
9039
9040   if (VAT_JSON_ARRAY != vam->json_tree.type)
9041     {
9042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9043       vat_json_init_array (&vam->json_tree);
9044     }
9045   node = vat_json_array_add (&vam->json_tree);
9046
9047   vat_json_init_object (node);
9048   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9049
9050   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9051   vat_json_object_add_ip6 (node, "host", ip6);
9052 }
9053
9054 static int
9055 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9056 {
9057   unformat_input_t *i = vam->input;
9058   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9059   u32 sw_if_index;
9060   u8 sw_if_index_set = 0;
9061   u32 address_length = 0;
9062   u8 v6_address_set = 0;
9063   ip6_address_t v6address;
9064   u8 use_default = 0;
9065   u8 no_advertise = 0;
9066   u8 off_link = 0;
9067   u8 no_autoconfig = 0;
9068   u8 no_onlink = 0;
9069   u8 is_no = 0;
9070   u32 val_lifetime = 0;
9071   u32 pref_lifetime = 0;
9072   int ret;
9073
9074   /* Parse args required to build the message */
9075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9076     {
9077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9078         sw_if_index_set = 1;
9079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9080         sw_if_index_set = 1;
9081       else if (unformat (i, "%U/%d",
9082                          unformat_ip6_address, &v6address, &address_length))
9083         v6_address_set = 1;
9084       else if (unformat (i, "val_life %d", &val_lifetime))
9085         ;
9086       else if (unformat (i, "pref_life %d", &pref_lifetime))
9087         ;
9088       else if (unformat (i, "def"))
9089         use_default = 1;
9090       else if (unformat (i, "noadv"))
9091         no_advertise = 1;
9092       else if (unformat (i, "offl"))
9093         off_link = 1;
9094       else if (unformat (i, "noauto"))
9095         no_autoconfig = 1;
9096       else if (unformat (i, "nolink"))
9097         no_onlink = 1;
9098       else if (unformat (i, "isno"))
9099         is_no = 1;
9100       else
9101         {
9102           clib_warning ("parse error '%U'", format_unformat_error, i);
9103           return -99;
9104         }
9105     }
9106
9107   if (sw_if_index_set == 0)
9108     {
9109       errmsg ("missing interface name or sw_if_index");
9110       return -99;
9111     }
9112   if (!v6_address_set)
9113     {
9114       errmsg ("no address set");
9115       return -99;
9116     }
9117
9118   /* Construct the API message */
9119   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9120
9121   mp->sw_if_index = ntohl (sw_if_index);
9122   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9123   mp->address_length = address_length;
9124   mp->use_default = use_default;
9125   mp->no_advertise = no_advertise;
9126   mp->off_link = off_link;
9127   mp->no_autoconfig = no_autoconfig;
9128   mp->no_onlink = no_onlink;
9129   mp->is_no = is_no;
9130   mp->val_lifetime = ntohl (val_lifetime);
9131   mp->pref_lifetime = ntohl (pref_lifetime);
9132
9133   /* send it... */
9134   S (mp);
9135
9136   /* Wait for a reply, return good/bad news  */
9137   W (ret);
9138   return ret;
9139 }
9140
9141 static int
9142 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9143 {
9144   unformat_input_t *i = vam->input;
9145   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9146   u32 sw_if_index;
9147   u8 sw_if_index_set = 0;
9148   u8 suppress = 0;
9149   u8 managed = 0;
9150   u8 other = 0;
9151   u8 ll_option = 0;
9152   u8 send_unicast = 0;
9153   u8 cease = 0;
9154   u8 is_no = 0;
9155   u8 default_router = 0;
9156   u32 max_interval = 0;
9157   u32 min_interval = 0;
9158   u32 lifetime = 0;
9159   u32 initial_count = 0;
9160   u32 initial_interval = 0;
9161   int ret;
9162
9163
9164   /* Parse args required to build the message */
9165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9166     {
9167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9168         sw_if_index_set = 1;
9169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9170         sw_if_index_set = 1;
9171       else if (unformat (i, "maxint %d", &max_interval))
9172         ;
9173       else if (unformat (i, "minint %d", &min_interval))
9174         ;
9175       else if (unformat (i, "life %d", &lifetime))
9176         ;
9177       else if (unformat (i, "count %d", &initial_count))
9178         ;
9179       else if (unformat (i, "interval %d", &initial_interval))
9180         ;
9181       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9182         suppress = 1;
9183       else if (unformat (i, "managed"))
9184         managed = 1;
9185       else if (unformat (i, "other"))
9186         other = 1;
9187       else if (unformat (i, "ll"))
9188         ll_option = 1;
9189       else if (unformat (i, "send"))
9190         send_unicast = 1;
9191       else if (unformat (i, "cease"))
9192         cease = 1;
9193       else if (unformat (i, "isno"))
9194         is_no = 1;
9195       else if (unformat (i, "def"))
9196         default_router = 1;
9197       else
9198         {
9199           clib_warning ("parse error '%U'", format_unformat_error, i);
9200           return -99;
9201         }
9202     }
9203
9204   if (sw_if_index_set == 0)
9205     {
9206       errmsg ("missing interface name or sw_if_index");
9207       return -99;
9208     }
9209
9210   /* Construct the API message */
9211   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9212
9213   mp->sw_if_index = ntohl (sw_if_index);
9214   mp->max_interval = ntohl (max_interval);
9215   mp->min_interval = ntohl (min_interval);
9216   mp->lifetime = ntohl (lifetime);
9217   mp->initial_count = ntohl (initial_count);
9218   mp->initial_interval = ntohl (initial_interval);
9219   mp->suppress = suppress;
9220   mp->managed = managed;
9221   mp->other = other;
9222   mp->ll_option = ll_option;
9223   mp->send_unicast = send_unicast;
9224   mp->cease = cease;
9225   mp->is_no = is_no;
9226   mp->default_router = default_router;
9227
9228   /* send it... */
9229   S (mp);
9230
9231   /* Wait for a reply, return good/bad news  */
9232   W (ret);
9233   return ret;
9234 }
9235
9236 static int
9237 api_set_arp_neighbor_limit (vat_main_t * vam)
9238 {
9239   unformat_input_t *i = vam->input;
9240   vl_api_set_arp_neighbor_limit_t *mp;
9241   u32 arp_nbr_limit;
9242   u8 limit_set = 0;
9243   u8 is_ipv6 = 0;
9244   int ret;
9245
9246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9247     {
9248       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9249         limit_set = 1;
9250       else if (unformat (i, "ipv6"))
9251         is_ipv6 = 1;
9252       else
9253         {
9254           clib_warning ("parse error '%U'", format_unformat_error, i);
9255           return -99;
9256         }
9257     }
9258
9259   if (limit_set == 0)
9260     {
9261       errmsg ("missing limit value");
9262       return -99;
9263     }
9264
9265   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9266
9267   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9268   mp->is_ipv6 = is_ipv6;
9269
9270   S (mp);
9271   W (ret);
9272   return ret;
9273 }
9274
9275 static int
9276 api_l2_patch_add_del (vat_main_t * vam)
9277 {
9278   unformat_input_t *i = vam->input;
9279   vl_api_l2_patch_add_del_t *mp;
9280   u32 rx_sw_if_index;
9281   u8 rx_sw_if_index_set = 0;
9282   u32 tx_sw_if_index;
9283   u8 tx_sw_if_index_set = 0;
9284   u8 is_add = 1;
9285   int ret;
9286
9287   /* Parse args required to build the message */
9288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9289     {
9290       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9291         rx_sw_if_index_set = 1;
9292       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9293         tx_sw_if_index_set = 1;
9294       else if (unformat (i, "rx"))
9295         {
9296           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9297             {
9298               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9299                             &rx_sw_if_index))
9300                 rx_sw_if_index_set = 1;
9301             }
9302           else
9303             break;
9304         }
9305       else if (unformat (i, "tx"))
9306         {
9307           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9308             {
9309               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9310                             &tx_sw_if_index))
9311                 tx_sw_if_index_set = 1;
9312             }
9313           else
9314             break;
9315         }
9316       else if (unformat (i, "del"))
9317         is_add = 0;
9318       else
9319         break;
9320     }
9321
9322   if (rx_sw_if_index_set == 0)
9323     {
9324       errmsg ("missing rx interface name or rx_sw_if_index");
9325       return -99;
9326     }
9327
9328   if (tx_sw_if_index_set == 0)
9329     {
9330       errmsg ("missing tx interface name or tx_sw_if_index");
9331       return -99;
9332     }
9333
9334   M (L2_PATCH_ADD_DEL, mp);
9335
9336   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9337   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9338   mp->is_add = is_add;
9339
9340   S (mp);
9341   W (ret);
9342   return ret;
9343 }
9344
9345 u8 is_del;
9346 u8 localsid_addr[16];
9347 u8 end_psp;
9348 u8 behavior;
9349 u32 sw_if_index;
9350 u32 vlan_index;
9351 u32 fib_table;
9352 u8 nh_addr[16];
9353
9354 static int
9355 api_sr_localsid_add_del (vat_main_t * vam)
9356 {
9357   unformat_input_t *i = vam->input;
9358   vl_api_sr_localsid_add_del_t *mp;
9359
9360   u8 is_del;
9361   ip6_address_t localsid;
9362   u8 end_psp = 0;
9363   u8 behavior = ~0;
9364   u32 sw_if_index;
9365   u32 fib_table = ~(u32) 0;
9366   ip6_address_t next_hop;
9367
9368   bool nexthop_set = 0;
9369
9370   int ret;
9371
9372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9373     {
9374       if (unformat (i, "del"))
9375         is_del = 1;
9376       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9377       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9378         nexthop_set = 1;
9379       else if (unformat (i, "behavior %u", &behavior));
9380       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9381       else if (unformat (i, "fib-table %u", &fib_table));
9382       else if (unformat (i, "end.psp %u", &behavior));
9383       else
9384         break;
9385     }
9386
9387   M (SR_LOCALSID_ADD_DEL, mp);
9388
9389   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9390   if (nexthop_set)
9391     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9392   mp->behavior = behavior;
9393   mp->sw_if_index = ntohl (sw_if_index);
9394   mp->fib_table = ntohl (fib_table);
9395   mp->end_psp = end_psp;
9396   mp->is_del = is_del;
9397
9398   S (mp);
9399   W (ret);
9400   return ret;
9401 }
9402
9403 static int
9404 api_ioam_enable (vat_main_t * vam)
9405 {
9406   unformat_input_t *input = vam->input;
9407   vl_api_ioam_enable_t *mp;
9408   u32 id = 0;
9409   int has_trace_option = 0;
9410   int has_pot_option = 0;
9411   int has_seqno_option = 0;
9412   int has_analyse_option = 0;
9413   int ret;
9414
9415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (input, "trace"))
9418         has_trace_option = 1;
9419       else if (unformat (input, "pot"))
9420         has_pot_option = 1;
9421       else if (unformat (input, "seqno"))
9422         has_seqno_option = 1;
9423       else if (unformat (input, "analyse"))
9424         has_analyse_option = 1;
9425       else
9426         break;
9427     }
9428   M (IOAM_ENABLE, mp);
9429   mp->id = htons (id);
9430   mp->seqno = has_seqno_option;
9431   mp->analyse = has_analyse_option;
9432   mp->pot_enable = has_pot_option;
9433   mp->trace_enable = has_trace_option;
9434
9435   S (mp);
9436   W (ret);
9437   return ret;
9438 }
9439
9440
9441 static int
9442 api_ioam_disable (vat_main_t * vam)
9443 {
9444   vl_api_ioam_disable_t *mp;
9445   int ret;
9446
9447   M (IOAM_DISABLE, mp);
9448   S (mp);
9449   W (ret);
9450   return ret;
9451 }
9452
9453 #define foreach_tcp_proto_field                 \
9454 _(src_port)                                     \
9455 _(dst_port)
9456
9457 #define foreach_udp_proto_field                 \
9458 _(src_port)                                     \
9459 _(dst_port)
9460
9461 #define foreach_ip4_proto_field                 \
9462 _(src_address)                                  \
9463 _(dst_address)                                  \
9464 _(tos)                                          \
9465 _(length)                                       \
9466 _(fragment_id)                                  \
9467 _(ttl)                                          \
9468 _(protocol)                                     \
9469 _(checksum)
9470
9471 typedef struct
9472 {
9473   u16 src_port, dst_port;
9474 } tcpudp_header_t;
9475
9476 #if VPP_API_TEST_BUILTIN == 0
9477 uword
9478 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9479 {
9480   u8 **maskp = va_arg (*args, u8 **);
9481   u8 *mask = 0;
9482   u8 found_something = 0;
9483   tcp_header_t *tcp;
9484
9485 #define _(a) u8 a=0;
9486   foreach_tcp_proto_field;
9487 #undef _
9488
9489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9490     {
9491       if (0);
9492 #define _(a) else if (unformat (input, #a)) a=1;
9493       foreach_tcp_proto_field
9494 #undef _
9495         else
9496         break;
9497     }
9498
9499 #define _(a) found_something += a;
9500   foreach_tcp_proto_field;
9501 #undef _
9502
9503   if (found_something == 0)
9504     return 0;
9505
9506   vec_validate (mask, sizeof (*tcp) - 1);
9507
9508   tcp = (tcp_header_t *) mask;
9509
9510 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9511   foreach_tcp_proto_field;
9512 #undef _
9513
9514   *maskp = mask;
9515   return 1;
9516 }
9517
9518 uword
9519 unformat_udp_mask (unformat_input_t * input, va_list * args)
9520 {
9521   u8 **maskp = va_arg (*args, u8 **);
9522   u8 *mask = 0;
9523   u8 found_something = 0;
9524   udp_header_t *udp;
9525
9526 #define _(a) u8 a=0;
9527   foreach_udp_proto_field;
9528 #undef _
9529
9530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9531     {
9532       if (0);
9533 #define _(a) else if (unformat (input, #a)) a=1;
9534       foreach_udp_proto_field
9535 #undef _
9536         else
9537         break;
9538     }
9539
9540 #define _(a) found_something += a;
9541   foreach_udp_proto_field;
9542 #undef _
9543
9544   if (found_something == 0)
9545     return 0;
9546
9547   vec_validate (mask, sizeof (*udp) - 1);
9548
9549   udp = (udp_header_t *) mask;
9550
9551 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9552   foreach_udp_proto_field;
9553 #undef _
9554
9555   *maskp = mask;
9556   return 1;
9557 }
9558
9559 uword
9560 unformat_l4_mask (unformat_input_t * input, va_list * args)
9561 {
9562   u8 **maskp = va_arg (*args, u8 **);
9563   u16 src_port = 0, dst_port = 0;
9564   tcpudp_header_t *tcpudp;
9565
9566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9567     {
9568       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9569         return 1;
9570       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9571         return 1;
9572       else if (unformat (input, "src_port"))
9573         src_port = 0xFFFF;
9574       else if (unformat (input, "dst_port"))
9575         dst_port = 0xFFFF;
9576       else
9577         return 0;
9578     }
9579
9580   if (!src_port && !dst_port)
9581     return 0;
9582
9583   u8 *mask = 0;
9584   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9585
9586   tcpudp = (tcpudp_header_t *) mask;
9587   tcpudp->src_port = src_port;
9588   tcpudp->dst_port = dst_port;
9589
9590   *maskp = mask;
9591
9592   return 1;
9593 }
9594
9595 uword
9596 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9597 {
9598   u8 **maskp = va_arg (*args, u8 **);
9599   u8 *mask = 0;
9600   u8 found_something = 0;
9601   ip4_header_t *ip;
9602
9603 #define _(a) u8 a=0;
9604   foreach_ip4_proto_field;
9605 #undef _
9606   u8 version = 0;
9607   u8 hdr_length = 0;
9608
9609
9610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9611     {
9612       if (unformat (input, "version"))
9613         version = 1;
9614       else if (unformat (input, "hdr_length"))
9615         hdr_length = 1;
9616       else if (unformat (input, "src"))
9617         src_address = 1;
9618       else if (unformat (input, "dst"))
9619         dst_address = 1;
9620       else if (unformat (input, "proto"))
9621         protocol = 1;
9622
9623 #define _(a) else if (unformat (input, #a)) a=1;
9624       foreach_ip4_proto_field
9625 #undef _
9626         else
9627         break;
9628     }
9629
9630 #define _(a) found_something += a;
9631   foreach_ip4_proto_field;
9632 #undef _
9633
9634   if (found_something == 0)
9635     return 0;
9636
9637   vec_validate (mask, sizeof (*ip) - 1);
9638
9639   ip = (ip4_header_t *) mask;
9640
9641 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9642   foreach_ip4_proto_field;
9643 #undef _
9644
9645   ip->ip_version_and_header_length = 0;
9646
9647   if (version)
9648     ip->ip_version_and_header_length |= 0xF0;
9649
9650   if (hdr_length)
9651     ip->ip_version_and_header_length |= 0x0F;
9652
9653   *maskp = mask;
9654   return 1;
9655 }
9656
9657 #define foreach_ip6_proto_field                 \
9658 _(src_address)                                  \
9659 _(dst_address)                                  \
9660 _(payload_length)                               \
9661 _(hop_limit)                                    \
9662 _(protocol)
9663
9664 uword
9665 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9666 {
9667   u8 **maskp = va_arg (*args, u8 **);
9668   u8 *mask = 0;
9669   u8 found_something = 0;
9670   ip6_header_t *ip;
9671   u32 ip_version_traffic_class_and_flow_label;
9672
9673 #define _(a) u8 a=0;
9674   foreach_ip6_proto_field;
9675 #undef _
9676   u8 version = 0;
9677   u8 traffic_class = 0;
9678   u8 flow_label = 0;
9679
9680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9681     {
9682       if (unformat (input, "version"))
9683         version = 1;
9684       else if (unformat (input, "traffic-class"))
9685         traffic_class = 1;
9686       else if (unformat (input, "flow-label"))
9687         flow_label = 1;
9688       else if (unformat (input, "src"))
9689         src_address = 1;
9690       else if (unformat (input, "dst"))
9691         dst_address = 1;
9692       else if (unformat (input, "proto"))
9693         protocol = 1;
9694
9695 #define _(a) else if (unformat (input, #a)) a=1;
9696       foreach_ip6_proto_field
9697 #undef _
9698         else
9699         break;
9700     }
9701
9702 #define _(a) found_something += a;
9703   foreach_ip6_proto_field;
9704 #undef _
9705
9706   if (found_something == 0)
9707     return 0;
9708
9709   vec_validate (mask, sizeof (*ip) - 1);
9710
9711   ip = (ip6_header_t *) mask;
9712
9713 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9714   foreach_ip6_proto_field;
9715 #undef _
9716
9717   ip_version_traffic_class_and_flow_label = 0;
9718
9719   if (version)
9720     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9721
9722   if (traffic_class)
9723     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9724
9725   if (flow_label)
9726     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9727
9728   ip->ip_version_traffic_class_and_flow_label =
9729     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9730
9731   *maskp = mask;
9732   return 1;
9733 }
9734
9735 uword
9736 unformat_l3_mask (unformat_input_t * input, va_list * args)
9737 {
9738   u8 **maskp = va_arg (*args, u8 **);
9739
9740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9741     {
9742       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9743         return 1;
9744       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9745         return 1;
9746       else
9747         break;
9748     }
9749   return 0;
9750 }
9751
9752 uword
9753 unformat_l2_mask (unformat_input_t * input, va_list * args)
9754 {
9755   u8 **maskp = va_arg (*args, u8 **);
9756   u8 *mask = 0;
9757   u8 src = 0;
9758   u8 dst = 0;
9759   u8 proto = 0;
9760   u8 tag1 = 0;
9761   u8 tag2 = 0;
9762   u8 ignore_tag1 = 0;
9763   u8 ignore_tag2 = 0;
9764   u8 cos1 = 0;
9765   u8 cos2 = 0;
9766   u8 dot1q = 0;
9767   u8 dot1ad = 0;
9768   int len = 14;
9769
9770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9771     {
9772       if (unformat (input, "src"))
9773         src = 1;
9774       else if (unformat (input, "dst"))
9775         dst = 1;
9776       else if (unformat (input, "proto"))
9777         proto = 1;
9778       else if (unformat (input, "tag1"))
9779         tag1 = 1;
9780       else if (unformat (input, "tag2"))
9781         tag2 = 1;
9782       else if (unformat (input, "ignore-tag1"))
9783         ignore_tag1 = 1;
9784       else if (unformat (input, "ignore-tag2"))
9785         ignore_tag2 = 1;
9786       else if (unformat (input, "cos1"))
9787         cos1 = 1;
9788       else if (unformat (input, "cos2"))
9789         cos2 = 1;
9790       else if (unformat (input, "dot1q"))
9791         dot1q = 1;
9792       else if (unformat (input, "dot1ad"))
9793         dot1ad = 1;
9794       else
9795         break;
9796     }
9797   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9798        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9799     return 0;
9800
9801   if (tag1 || ignore_tag1 || cos1 || dot1q)
9802     len = 18;
9803   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9804     len = 22;
9805
9806   vec_validate (mask, len - 1);
9807
9808   if (dst)
9809     memset (mask, 0xff, 6);
9810
9811   if (src)
9812     memset (mask + 6, 0xff, 6);
9813
9814   if (tag2 || dot1ad)
9815     {
9816       /* inner vlan tag */
9817       if (tag2)
9818         {
9819           mask[19] = 0xff;
9820           mask[18] = 0x0f;
9821         }
9822       if (cos2)
9823         mask[18] |= 0xe0;
9824       if (proto)
9825         mask[21] = mask[20] = 0xff;
9826       if (tag1)
9827         {
9828           mask[15] = 0xff;
9829           mask[14] = 0x0f;
9830         }
9831       if (cos1)
9832         mask[14] |= 0xe0;
9833       *maskp = mask;
9834       return 1;
9835     }
9836   if (tag1 | dot1q)
9837     {
9838       if (tag1)
9839         {
9840           mask[15] = 0xff;
9841           mask[14] = 0x0f;
9842         }
9843       if (cos1)
9844         mask[14] |= 0xe0;
9845       if (proto)
9846         mask[16] = mask[17] = 0xff;
9847
9848       *maskp = mask;
9849       return 1;
9850     }
9851   if (cos2)
9852     mask[18] |= 0xe0;
9853   if (cos1)
9854     mask[14] |= 0xe0;
9855   if (proto)
9856     mask[12] = mask[13] = 0xff;
9857
9858   *maskp = mask;
9859   return 1;
9860 }
9861
9862 uword
9863 unformat_classify_mask (unformat_input_t * input, va_list * args)
9864 {
9865   u8 **maskp = va_arg (*args, u8 **);
9866   u32 *skipp = va_arg (*args, u32 *);
9867   u32 *matchp = va_arg (*args, u32 *);
9868   u32 match;
9869   u8 *mask = 0;
9870   u8 *l2 = 0;
9871   u8 *l3 = 0;
9872   u8 *l4 = 0;
9873   int i;
9874
9875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9876     {
9877       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9878         ;
9879       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9880         ;
9881       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9882         ;
9883       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9884         ;
9885       else
9886         break;
9887     }
9888
9889   if (l4 && !l3)
9890     {
9891       vec_free (mask);
9892       vec_free (l2);
9893       vec_free (l4);
9894       return 0;
9895     }
9896
9897   if (mask || l2 || l3 || l4)
9898     {
9899       if (l2 || l3 || l4)
9900         {
9901           /* "With a free Ethernet header in every package" */
9902           if (l2 == 0)
9903             vec_validate (l2, 13);
9904           mask = l2;
9905           if (vec_len (l3))
9906             {
9907               vec_append (mask, l3);
9908               vec_free (l3);
9909             }
9910           if (vec_len (l4))
9911             {
9912               vec_append (mask, l4);
9913               vec_free (l4);
9914             }
9915         }
9916
9917       /* Scan forward looking for the first significant mask octet */
9918       for (i = 0; i < vec_len (mask); i++)
9919         if (mask[i])
9920           break;
9921
9922       /* compute (skip, match) params */
9923       *skipp = i / sizeof (u32x4);
9924       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9925
9926       /* Pad mask to an even multiple of the vector size */
9927       while (vec_len (mask) % sizeof (u32x4))
9928         vec_add1 (mask, 0);
9929
9930       match = vec_len (mask) / sizeof (u32x4);
9931
9932       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9933         {
9934           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9935           if (*tmp || *(tmp + 1))
9936             break;
9937           match--;
9938         }
9939       if (match == 0)
9940         clib_warning ("BUG: match 0");
9941
9942       _vec_len (mask) = match * sizeof (u32x4);
9943
9944       *matchp = match;
9945       *maskp = mask;
9946
9947       return 1;
9948     }
9949
9950   return 0;
9951 }
9952 #endif /* VPP_API_TEST_BUILTIN */
9953
9954 #define foreach_l2_next                         \
9955 _(drop, DROP)                                   \
9956 _(ethernet, ETHERNET_INPUT)                     \
9957 _(ip4, IP4_INPUT)                               \
9958 _(ip6, IP6_INPUT)
9959
9960 uword
9961 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9962 {
9963   u32 *miss_next_indexp = va_arg (*args, u32 *);
9964   u32 next_index = 0;
9965   u32 tmp;
9966
9967 #define _(n,N) \
9968   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9969   foreach_l2_next;
9970 #undef _
9971
9972   if (unformat (input, "%d", &tmp))
9973     {
9974       next_index = tmp;
9975       goto out;
9976     }
9977
9978   return 0;
9979
9980 out:
9981   *miss_next_indexp = next_index;
9982   return 1;
9983 }
9984
9985 #define foreach_ip_next                         \
9986 _(drop, DROP)                                   \
9987 _(local, LOCAL)                                 \
9988 _(rewrite, REWRITE)
9989
9990 uword
9991 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9992 {
9993   u32 *miss_next_indexp = va_arg (*args, u32 *);
9994   u32 next_index = 0;
9995   u32 tmp;
9996
9997 #define _(n,N) \
9998   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9999   foreach_ip_next;
10000 #undef _
10001
10002   if (unformat (input, "%d", &tmp))
10003     {
10004       next_index = tmp;
10005       goto out;
10006     }
10007
10008   return 0;
10009
10010 out:
10011   *miss_next_indexp = next_index;
10012   return 1;
10013 }
10014
10015 #define foreach_acl_next                        \
10016 _(deny, DENY)
10017
10018 uword
10019 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10020 {
10021   u32 *miss_next_indexp = va_arg (*args, u32 *);
10022   u32 next_index = 0;
10023   u32 tmp;
10024
10025 #define _(n,N) \
10026   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10027   foreach_acl_next;
10028 #undef _
10029
10030   if (unformat (input, "permit"))
10031     {
10032       next_index = ~0;
10033       goto out;
10034     }
10035   else if (unformat (input, "%d", &tmp))
10036     {
10037       next_index = tmp;
10038       goto out;
10039     }
10040
10041   return 0;
10042
10043 out:
10044   *miss_next_indexp = next_index;
10045   return 1;
10046 }
10047
10048 uword
10049 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10050 {
10051   u32 *r = va_arg (*args, u32 *);
10052
10053   if (unformat (input, "conform-color"))
10054     *r = POLICE_CONFORM;
10055   else if (unformat (input, "exceed-color"))
10056     *r = POLICE_EXCEED;
10057   else
10058     return 0;
10059
10060   return 1;
10061 }
10062
10063 static int
10064 api_classify_add_del_table (vat_main_t * vam)
10065 {
10066   unformat_input_t *i = vam->input;
10067   vl_api_classify_add_del_table_t *mp;
10068
10069   u32 nbuckets = 2;
10070   u32 skip = ~0;
10071   u32 match = ~0;
10072   int is_add = 1;
10073   int del_chain = 0;
10074   u32 table_index = ~0;
10075   u32 next_table_index = ~0;
10076   u32 miss_next_index = ~0;
10077   u32 memory_size = 32 << 20;
10078   u8 *mask = 0;
10079   u32 current_data_flag = 0;
10080   int current_data_offset = 0;
10081   int ret;
10082
10083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10084     {
10085       if (unformat (i, "del"))
10086         is_add = 0;
10087       else if (unformat (i, "del-chain"))
10088         {
10089           is_add = 0;
10090           del_chain = 1;
10091         }
10092       else if (unformat (i, "buckets %d", &nbuckets))
10093         ;
10094       else if (unformat (i, "memory_size %d", &memory_size))
10095         ;
10096       else if (unformat (i, "skip %d", &skip))
10097         ;
10098       else if (unformat (i, "match %d", &match))
10099         ;
10100       else if (unformat (i, "table %d", &table_index))
10101         ;
10102       else if (unformat (i, "mask %U", unformat_classify_mask,
10103                          &mask, &skip, &match))
10104         ;
10105       else if (unformat (i, "next-table %d", &next_table_index))
10106         ;
10107       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10108                          &miss_next_index))
10109         ;
10110       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10111                          &miss_next_index))
10112         ;
10113       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10114                          &miss_next_index))
10115         ;
10116       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10117         ;
10118       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10119         ;
10120       else
10121         break;
10122     }
10123
10124   if (is_add && mask == 0)
10125     {
10126       errmsg ("Mask required");
10127       return -99;
10128     }
10129
10130   if (is_add && skip == ~0)
10131     {
10132       errmsg ("skip count required");
10133       return -99;
10134     }
10135
10136   if (is_add && match == ~0)
10137     {
10138       errmsg ("match count required");
10139       return -99;
10140     }
10141
10142   if (!is_add && table_index == ~0)
10143     {
10144       errmsg ("table index required for delete");
10145       return -99;
10146     }
10147
10148   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10149
10150   mp->is_add = is_add;
10151   mp->del_chain = del_chain;
10152   mp->table_index = ntohl (table_index);
10153   mp->nbuckets = ntohl (nbuckets);
10154   mp->memory_size = ntohl (memory_size);
10155   mp->skip_n_vectors = ntohl (skip);
10156   mp->match_n_vectors = ntohl (match);
10157   mp->next_table_index = ntohl (next_table_index);
10158   mp->miss_next_index = ntohl (miss_next_index);
10159   mp->current_data_flag = ntohl (current_data_flag);
10160   mp->current_data_offset = ntohl (current_data_offset);
10161   clib_memcpy (mp->mask, mask, vec_len (mask));
10162
10163   vec_free (mask);
10164
10165   S (mp);
10166   W (ret);
10167   return ret;
10168 }
10169
10170 #if VPP_API_TEST_BUILTIN == 0
10171 uword
10172 unformat_l4_match (unformat_input_t * input, va_list * args)
10173 {
10174   u8 **matchp = va_arg (*args, u8 **);
10175
10176   u8 *proto_header = 0;
10177   int src_port = 0;
10178   int dst_port = 0;
10179
10180   tcpudp_header_t h;
10181
10182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10183     {
10184       if (unformat (input, "src_port %d", &src_port))
10185         ;
10186       else if (unformat (input, "dst_port %d", &dst_port))
10187         ;
10188       else
10189         return 0;
10190     }
10191
10192   h.src_port = clib_host_to_net_u16 (src_port);
10193   h.dst_port = clib_host_to_net_u16 (dst_port);
10194   vec_validate (proto_header, sizeof (h) - 1);
10195   memcpy (proto_header, &h, sizeof (h));
10196
10197   *matchp = proto_header;
10198
10199   return 1;
10200 }
10201
10202 uword
10203 unformat_ip4_match (unformat_input_t * input, va_list * args)
10204 {
10205   u8 **matchp = va_arg (*args, u8 **);
10206   u8 *match = 0;
10207   ip4_header_t *ip;
10208   int version = 0;
10209   u32 version_val;
10210   int hdr_length = 0;
10211   u32 hdr_length_val;
10212   int src = 0, dst = 0;
10213   ip4_address_t src_val, dst_val;
10214   int proto = 0;
10215   u32 proto_val;
10216   int tos = 0;
10217   u32 tos_val;
10218   int length = 0;
10219   u32 length_val;
10220   int fragment_id = 0;
10221   u32 fragment_id_val;
10222   int ttl = 0;
10223   int ttl_val;
10224   int checksum = 0;
10225   u32 checksum_val;
10226
10227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10228     {
10229       if (unformat (input, "version %d", &version_val))
10230         version = 1;
10231       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10232         hdr_length = 1;
10233       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10234         src = 1;
10235       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10236         dst = 1;
10237       else if (unformat (input, "proto %d", &proto_val))
10238         proto = 1;
10239       else if (unformat (input, "tos %d", &tos_val))
10240         tos = 1;
10241       else if (unformat (input, "length %d", &length_val))
10242         length = 1;
10243       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10244         fragment_id = 1;
10245       else if (unformat (input, "ttl %d", &ttl_val))
10246         ttl = 1;
10247       else if (unformat (input, "checksum %d", &checksum_val))
10248         checksum = 1;
10249       else
10250         break;
10251     }
10252
10253   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10254       + ttl + checksum == 0)
10255     return 0;
10256
10257   /*
10258    * Aligned because we use the real comparison functions
10259    */
10260   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10261
10262   ip = (ip4_header_t *) match;
10263
10264   /* These are realistically matched in practice */
10265   if (src)
10266     ip->src_address.as_u32 = src_val.as_u32;
10267
10268   if (dst)
10269     ip->dst_address.as_u32 = dst_val.as_u32;
10270
10271   if (proto)
10272     ip->protocol = proto_val;
10273
10274
10275   /* These are not, but they're included for completeness */
10276   if (version)
10277     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10278
10279   if (hdr_length)
10280     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10281
10282   if (tos)
10283     ip->tos = tos_val;
10284
10285   if (length)
10286     ip->length = clib_host_to_net_u16 (length_val);
10287
10288   if (ttl)
10289     ip->ttl = ttl_val;
10290
10291   if (checksum)
10292     ip->checksum = clib_host_to_net_u16 (checksum_val);
10293
10294   *matchp = match;
10295   return 1;
10296 }
10297
10298 uword
10299 unformat_ip6_match (unformat_input_t * input, va_list * args)
10300 {
10301   u8 **matchp = va_arg (*args, u8 **);
10302   u8 *match = 0;
10303   ip6_header_t *ip;
10304   int version = 0;
10305   u32 version_val;
10306   u8 traffic_class = 0;
10307   u32 traffic_class_val = 0;
10308   u8 flow_label = 0;
10309   u8 flow_label_val;
10310   int src = 0, dst = 0;
10311   ip6_address_t src_val, dst_val;
10312   int proto = 0;
10313   u32 proto_val;
10314   int payload_length = 0;
10315   u32 payload_length_val;
10316   int hop_limit = 0;
10317   int hop_limit_val;
10318   u32 ip_version_traffic_class_and_flow_label;
10319
10320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10321     {
10322       if (unformat (input, "version %d", &version_val))
10323         version = 1;
10324       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10325         traffic_class = 1;
10326       else if (unformat (input, "flow_label %d", &flow_label_val))
10327         flow_label = 1;
10328       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10329         src = 1;
10330       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10331         dst = 1;
10332       else if (unformat (input, "proto %d", &proto_val))
10333         proto = 1;
10334       else if (unformat (input, "payload_length %d", &payload_length_val))
10335         payload_length = 1;
10336       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10337         hop_limit = 1;
10338       else
10339         break;
10340     }
10341
10342   if (version + traffic_class + flow_label + src + dst + proto +
10343       payload_length + hop_limit == 0)
10344     return 0;
10345
10346   /*
10347    * Aligned because we use the real comparison functions
10348    */
10349   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10350
10351   ip = (ip6_header_t *) match;
10352
10353   if (src)
10354     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10355
10356   if (dst)
10357     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10358
10359   if (proto)
10360     ip->protocol = proto_val;
10361
10362   ip_version_traffic_class_and_flow_label = 0;
10363
10364   if (version)
10365     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10366
10367   if (traffic_class)
10368     ip_version_traffic_class_and_flow_label |=
10369       (traffic_class_val & 0xFF) << 20;
10370
10371   if (flow_label)
10372     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10373
10374   ip->ip_version_traffic_class_and_flow_label =
10375     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10376
10377   if (payload_length)
10378     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10379
10380   if (hop_limit)
10381     ip->hop_limit = hop_limit_val;
10382
10383   *matchp = match;
10384   return 1;
10385 }
10386
10387 uword
10388 unformat_l3_match (unformat_input_t * input, va_list * args)
10389 {
10390   u8 **matchp = va_arg (*args, u8 **);
10391
10392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10393     {
10394       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10395         return 1;
10396       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10397         return 1;
10398       else
10399         break;
10400     }
10401   return 0;
10402 }
10403
10404 uword
10405 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10406 {
10407   u8 *tagp = va_arg (*args, u8 *);
10408   u32 tag;
10409
10410   if (unformat (input, "%d", &tag))
10411     {
10412       tagp[0] = (tag >> 8) & 0x0F;
10413       tagp[1] = tag & 0xFF;
10414       return 1;
10415     }
10416
10417   return 0;
10418 }
10419
10420 uword
10421 unformat_l2_match (unformat_input_t * input, va_list * args)
10422 {
10423   u8 **matchp = va_arg (*args, u8 **);
10424   u8 *match = 0;
10425   u8 src = 0;
10426   u8 src_val[6];
10427   u8 dst = 0;
10428   u8 dst_val[6];
10429   u8 proto = 0;
10430   u16 proto_val;
10431   u8 tag1 = 0;
10432   u8 tag1_val[2];
10433   u8 tag2 = 0;
10434   u8 tag2_val[2];
10435   int len = 14;
10436   u8 ignore_tag1 = 0;
10437   u8 ignore_tag2 = 0;
10438   u8 cos1 = 0;
10439   u8 cos2 = 0;
10440   u32 cos1_val = 0;
10441   u32 cos2_val = 0;
10442
10443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10444     {
10445       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10446         src = 1;
10447       else
10448         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10449         dst = 1;
10450       else if (unformat (input, "proto %U",
10451                          unformat_ethernet_type_host_byte_order, &proto_val))
10452         proto = 1;
10453       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10454         tag1 = 1;
10455       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10456         tag2 = 1;
10457       else if (unformat (input, "ignore-tag1"))
10458         ignore_tag1 = 1;
10459       else if (unformat (input, "ignore-tag2"))
10460         ignore_tag2 = 1;
10461       else if (unformat (input, "cos1 %d", &cos1_val))
10462         cos1 = 1;
10463       else if (unformat (input, "cos2 %d", &cos2_val))
10464         cos2 = 1;
10465       else
10466         break;
10467     }
10468   if ((src + dst + proto + tag1 + tag2 +
10469        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10470     return 0;
10471
10472   if (tag1 || ignore_tag1 || cos1)
10473     len = 18;
10474   if (tag2 || ignore_tag2 || cos2)
10475     len = 22;
10476
10477   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10478
10479   if (dst)
10480     clib_memcpy (match, dst_val, 6);
10481
10482   if (src)
10483     clib_memcpy (match + 6, src_val, 6);
10484
10485   if (tag2)
10486     {
10487       /* inner vlan tag */
10488       match[19] = tag2_val[1];
10489       match[18] = tag2_val[0];
10490       if (cos2)
10491         match[18] |= (cos2_val & 0x7) << 5;
10492       if (proto)
10493         {
10494           match[21] = proto_val & 0xff;
10495           match[20] = proto_val >> 8;
10496         }
10497       if (tag1)
10498         {
10499           match[15] = tag1_val[1];
10500           match[14] = tag1_val[0];
10501         }
10502       if (cos1)
10503         match[14] |= (cos1_val & 0x7) << 5;
10504       *matchp = match;
10505       return 1;
10506     }
10507   if (tag1)
10508     {
10509       match[15] = tag1_val[1];
10510       match[14] = tag1_val[0];
10511       if (proto)
10512         {
10513           match[17] = proto_val & 0xff;
10514           match[16] = proto_val >> 8;
10515         }
10516       if (cos1)
10517         match[14] |= (cos1_val & 0x7) << 5;
10518
10519       *matchp = match;
10520       return 1;
10521     }
10522   if (cos2)
10523     match[18] |= (cos2_val & 0x7) << 5;
10524   if (cos1)
10525     match[14] |= (cos1_val & 0x7) << 5;
10526   if (proto)
10527     {
10528       match[13] = proto_val & 0xff;
10529       match[12] = proto_val >> 8;
10530     }
10531
10532   *matchp = match;
10533   return 1;
10534 }
10535 #endif
10536
10537 uword
10538 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10539 {
10540   u8 **matchp = va_arg (*args, u8 **);
10541   u32 skip_n_vectors = va_arg (*args, u32);
10542   u32 match_n_vectors = va_arg (*args, u32);
10543
10544   u8 *match = 0;
10545   u8 *l2 = 0;
10546   u8 *l3 = 0;
10547   u8 *l4 = 0;
10548
10549   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10550     {
10551       if (unformat (input, "hex %U", unformat_hex_string, &match))
10552         ;
10553       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10554         ;
10555       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10556         ;
10557       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10558         ;
10559       else
10560         break;
10561     }
10562
10563   if (l4 && !l3)
10564     {
10565       vec_free (match);
10566       vec_free (l2);
10567       vec_free (l4);
10568       return 0;
10569     }
10570
10571   if (match || l2 || l3 || l4)
10572     {
10573       if (l2 || l3 || l4)
10574         {
10575           /* "Win a free Ethernet header in every packet" */
10576           if (l2 == 0)
10577             vec_validate_aligned (l2, 13, sizeof (u32x4));
10578           match = l2;
10579           if (vec_len (l3))
10580             {
10581               vec_append_aligned (match, l3, sizeof (u32x4));
10582               vec_free (l3);
10583             }
10584           if (vec_len (l4))
10585             {
10586               vec_append_aligned (match, l4, sizeof (u32x4));
10587               vec_free (l4);
10588             }
10589         }
10590
10591       /* Make sure the vector is big enough even if key is all 0's */
10592       vec_validate_aligned
10593         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10594          sizeof (u32x4));
10595
10596       /* Set size, include skipped vectors */
10597       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10598
10599       *matchp = match;
10600
10601       return 1;
10602     }
10603
10604   return 0;
10605 }
10606
10607 static int
10608 api_classify_add_del_session (vat_main_t * vam)
10609 {
10610   unformat_input_t *i = vam->input;
10611   vl_api_classify_add_del_session_t *mp;
10612   int is_add = 1;
10613   u32 table_index = ~0;
10614   u32 hit_next_index = ~0;
10615   u32 opaque_index = ~0;
10616   u8 *match = 0;
10617   i32 advance = 0;
10618   u32 skip_n_vectors = 0;
10619   u32 match_n_vectors = 0;
10620   u32 action = 0;
10621   u32 metadata = 0;
10622   int ret;
10623
10624   /*
10625    * Warning: you have to supply skip_n and match_n
10626    * because the API client cant simply look at the classify
10627    * table object.
10628    */
10629
10630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10631     {
10632       if (unformat (i, "del"))
10633         is_add = 0;
10634       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10635                          &hit_next_index))
10636         ;
10637       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10638                          &hit_next_index))
10639         ;
10640       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10641                          &hit_next_index))
10642         ;
10643       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10644         ;
10645       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10646         ;
10647       else if (unformat (i, "opaque-index %d", &opaque_index))
10648         ;
10649       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10650         ;
10651       else if (unformat (i, "match_n %d", &match_n_vectors))
10652         ;
10653       else if (unformat (i, "match %U", api_unformat_classify_match,
10654                          &match, skip_n_vectors, match_n_vectors))
10655         ;
10656       else if (unformat (i, "advance %d", &advance))
10657         ;
10658       else if (unformat (i, "table-index %d", &table_index))
10659         ;
10660       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10661         action = 1;
10662       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10663         action = 2;
10664       else if (unformat (i, "action %d", &action))
10665         ;
10666       else if (unformat (i, "metadata %d", &metadata))
10667         ;
10668       else
10669         break;
10670     }
10671
10672   if (table_index == ~0)
10673     {
10674       errmsg ("Table index required");
10675       return -99;
10676     }
10677
10678   if (is_add && match == 0)
10679     {
10680       errmsg ("Match value required");
10681       return -99;
10682     }
10683
10684   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10685
10686   mp->is_add = is_add;
10687   mp->table_index = ntohl (table_index);
10688   mp->hit_next_index = ntohl (hit_next_index);
10689   mp->opaque_index = ntohl (opaque_index);
10690   mp->advance = ntohl (advance);
10691   mp->action = action;
10692   mp->metadata = ntohl (metadata);
10693   clib_memcpy (mp->match, match, vec_len (match));
10694   vec_free (match);
10695
10696   S (mp);
10697   W (ret);
10698   return ret;
10699 }
10700
10701 static int
10702 api_classify_set_interface_ip_table (vat_main_t * vam)
10703 {
10704   unformat_input_t *i = vam->input;
10705   vl_api_classify_set_interface_ip_table_t *mp;
10706   u32 sw_if_index;
10707   int sw_if_index_set;
10708   u32 table_index = ~0;
10709   u8 is_ipv6 = 0;
10710   int ret;
10711
10712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10713     {
10714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10715         sw_if_index_set = 1;
10716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10717         sw_if_index_set = 1;
10718       else if (unformat (i, "table %d", &table_index))
10719         ;
10720       else
10721         {
10722           clib_warning ("parse error '%U'", format_unformat_error, i);
10723           return -99;
10724         }
10725     }
10726
10727   if (sw_if_index_set == 0)
10728     {
10729       errmsg ("missing interface name or sw_if_index");
10730       return -99;
10731     }
10732
10733
10734   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10735
10736   mp->sw_if_index = ntohl (sw_if_index);
10737   mp->table_index = ntohl (table_index);
10738   mp->is_ipv6 = is_ipv6;
10739
10740   S (mp);
10741   W (ret);
10742   return ret;
10743 }
10744
10745 static int
10746 api_classify_set_interface_l2_tables (vat_main_t * vam)
10747 {
10748   unformat_input_t *i = vam->input;
10749   vl_api_classify_set_interface_l2_tables_t *mp;
10750   u32 sw_if_index;
10751   int sw_if_index_set;
10752   u32 ip4_table_index = ~0;
10753   u32 ip6_table_index = ~0;
10754   u32 other_table_index = ~0;
10755   u32 is_input = 1;
10756   int ret;
10757
10758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10759     {
10760       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10761         sw_if_index_set = 1;
10762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10763         sw_if_index_set = 1;
10764       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10765         ;
10766       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10767         ;
10768       else if (unformat (i, "other-table %d", &other_table_index))
10769         ;
10770       else if (unformat (i, "is-input %d", &is_input))
10771         ;
10772       else
10773         {
10774           clib_warning ("parse error '%U'", format_unformat_error, i);
10775           return -99;
10776         }
10777     }
10778
10779   if (sw_if_index_set == 0)
10780     {
10781       errmsg ("missing interface name or sw_if_index");
10782       return -99;
10783     }
10784
10785
10786   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10787
10788   mp->sw_if_index = ntohl (sw_if_index);
10789   mp->ip4_table_index = ntohl (ip4_table_index);
10790   mp->ip6_table_index = ntohl (ip6_table_index);
10791   mp->other_table_index = ntohl (other_table_index);
10792   mp->is_input = (u8) is_input;
10793
10794   S (mp);
10795   W (ret);
10796   return ret;
10797 }
10798
10799 static int
10800 api_set_ipfix_exporter (vat_main_t * vam)
10801 {
10802   unformat_input_t *i = vam->input;
10803   vl_api_set_ipfix_exporter_t *mp;
10804   ip4_address_t collector_address;
10805   u8 collector_address_set = 0;
10806   u32 collector_port = ~0;
10807   ip4_address_t src_address;
10808   u8 src_address_set = 0;
10809   u32 vrf_id = ~0;
10810   u32 path_mtu = ~0;
10811   u32 template_interval = ~0;
10812   u8 udp_checksum = 0;
10813   int ret;
10814
10815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10816     {
10817       if (unformat (i, "collector_address %U", unformat_ip4_address,
10818                     &collector_address))
10819         collector_address_set = 1;
10820       else if (unformat (i, "collector_port %d", &collector_port))
10821         ;
10822       else if (unformat (i, "src_address %U", unformat_ip4_address,
10823                          &src_address))
10824         src_address_set = 1;
10825       else if (unformat (i, "vrf_id %d", &vrf_id))
10826         ;
10827       else if (unformat (i, "path_mtu %d", &path_mtu))
10828         ;
10829       else if (unformat (i, "template_interval %d", &template_interval))
10830         ;
10831       else if (unformat (i, "udp_checksum"))
10832         udp_checksum = 1;
10833       else
10834         break;
10835     }
10836
10837   if (collector_address_set == 0)
10838     {
10839       errmsg ("collector_address required");
10840       return -99;
10841     }
10842
10843   if (src_address_set == 0)
10844     {
10845       errmsg ("src_address required");
10846       return -99;
10847     }
10848
10849   M (SET_IPFIX_EXPORTER, mp);
10850
10851   memcpy (mp->collector_address, collector_address.data,
10852           sizeof (collector_address.data));
10853   mp->collector_port = htons ((u16) collector_port);
10854   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10855   mp->vrf_id = htonl (vrf_id);
10856   mp->path_mtu = htonl (path_mtu);
10857   mp->template_interval = htonl (template_interval);
10858   mp->udp_checksum = udp_checksum;
10859
10860   S (mp);
10861   W (ret);
10862   return ret;
10863 }
10864
10865 static int
10866 api_set_ipfix_classify_stream (vat_main_t * vam)
10867 {
10868   unformat_input_t *i = vam->input;
10869   vl_api_set_ipfix_classify_stream_t *mp;
10870   u32 domain_id = 0;
10871   u32 src_port = UDP_DST_PORT_ipfix;
10872   int ret;
10873
10874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10875     {
10876       if (unformat (i, "domain %d", &domain_id))
10877         ;
10878       else if (unformat (i, "src_port %d", &src_port))
10879         ;
10880       else
10881         {
10882           errmsg ("unknown input `%U'", format_unformat_error, i);
10883           return -99;
10884         }
10885     }
10886
10887   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10888
10889   mp->domain_id = htonl (domain_id);
10890   mp->src_port = htons ((u16) src_port);
10891
10892   S (mp);
10893   W (ret);
10894   return ret;
10895 }
10896
10897 static int
10898 api_ipfix_classify_table_add_del (vat_main_t * vam)
10899 {
10900   unformat_input_t *i = vam->input;
10901   vl_api_ipfix_classify_table_add_del_t *mp;
10902   int is_add = -1;
10903   u32 classify_table_index = ~0;
10904   u8 ip_version = 0;
10905   u8 transport_protocol = 255;
10906   int ret;
10907
10908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10909     {
10910       if (unformat (i, "add"))
10911         is_add = 1;
10912       else if (unformat (i, "del"))
10913         is_add = 0;
10914       else if (unformat (i, "table %d", &classify_table_index))
10915         ;
10916       else if (unformat (i, "ip4"))
10917         ip_version = 4;
10918       else if (unformat (i, "ip6"))
10919         ip_version = 6;
10920       else if (unformat (i, "tcp"))
10921         transport_protocol = 6;
10922       else if (unformat (i, "udp"))
10923         transport_protocol = 17;
10924       else
10925         {
10926           errmsg ("unknown input `%U'", format_unformat_error, i);
10927           return -99;
10928         }
10929     }
10930
10931   if (is_add == -1)
10932     {
10933       errmsg ("expecting: add|del");
10934       return -99;
10935     }
10936   if (classify_table_index == ~0)
10937     {
10938       errmsg ("classifier table not specified");
10939       return -99;
10940     }
10941   if (ip_version == 0)
10942     {
10943       errmsg ("IP version not specified");
10944       return -99;
10945     }
10946
10947   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10948
10949   mp->is_add = is_add;
10950   mp->table_id = htonl (classify_table_index);
10951   mp->ip_version = ip_version;
10952   mp->transport_protocol = transport_protocol;
10953
10954   S (mp);
10955   W (ret);
10956   return ret;
10957 }
10958
10959 static int
10960 api_get_node_index (vat_main_t * vam)
10961 {
10962   unformat_input_t *i = vam->input;
10963   vl_api_get_node_index_t *mp;
10964   u8 *name = 0;
10965   int ret;
10966
10967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10968     {
10969       if (unformat (i, "node %s", &name))
10970         ;
10971       else
10972         break;
10973     }
10974   if (name == 0)
10975     {
10976       errmsg ("node name required");
10977       return -99;
10978     }
10979   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10980     {
10981       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10982       return -99;
10983     }
10984
10985   M (GET_NODE_INDEX, mp);
10986   clib_memcpy (mp->node_name, name, vec_len (name));
10987   vec_free (name);
10988
10989   S (mp);
10990   W (ret);
10991   return ret;
10992 }
10993
10994 static int
10995 api_get_next_index (vat_main_t * vam)
10996 {
10997   unformat_input_t *i = vam->input;
10998   vl_api_get_next_index_t *mp;
10999   u8 *node_name = 0, *next_node_name = 0;
11000   int ret;
11001
11002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11003     {
11004       if (unformat (i, "node-name %s", &node_name))
11005         ;
11006       else if (unformat (i, "next-node-name %s", &next_node_name))
11007         break;
11008     }
11009
11010   if (node_name == 0)
11011     {
11012       errmsg ("node name required");
11013       return -99;
11014     }
11015   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11016     {
11017       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11018       return -99;
11019     }
11020
11021   if (next_node_name == 0)
11022     {
11023       errmsg ("next node name required");
11024       return -99;
11025     }
11026   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11027     {
11028       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11029       return -99;
11030     }
11031
11032   M (GET_NEXT_INDEX, mp);
11033   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11034   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11035   vec_free (node_name);
11036   vec_free (next_node_name);
11037
11038   S (mp);
11039   W (ret);
11040   return ret;
11041 }
11042
11043 static int
11044 api_add_node_next (vat_main_t * vam)
11045 {
11046   unformat_input_t *i = vam->input;
11047   vl_api_add_node_next_t *mp;
11048   u8 *name = 0;
11049   u8 *next = 0;
11050   int ret;
11051
11052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11053     {
11054       if (unformat (i, "node %s", &name))
11055         ;
11056       else if (unformat (i, "next %s", &next))
11057         ;
11058       else
11059         break;
11060     }
11061   if (name == 0)
11062     {
11063       errmsg ("node name required");
11064       return -99;
11065     }
11066   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11067     {
11068       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11069       return -99;
11070     }
11071   if (next == 0)
11072     {
11073       errmsg ("next node required");
11074       return -99;
11075     }
11076   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11077     {
11078       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11079       return -99;
11080     }
11081
11082   M (ADD_NODE_NEXT, mp);
11083   clib_memcpy (mp->node_name, name, vec_len (name));
11084   clib_memcpy (mp->next_name, next, vec_len (next));
11085   vec_free (name);
11086   vec_free (next);
11087
11088   S (mp);
11089   W (ret);
11090   return ret;
11091 }
11092
11093 static int
11094 api_l2tpv3_create_tunnel (vat_main_t * vam)
11095 {
11096   unformat_input_t *i = vam->input;
11097   ip6_address_t client_address, our_address;
11098   int client_address_set = 0;
11099   int our_address_set = 0;
11100   u32 local_session_id = 0;
11101   u32 remote_session_id = 0;
11102   u64 local_cookie = 0;
11103   u64 remote_cookie = 0;
11104   u8 l2_sublayer_present = 0;
11105   vl_api_l2tpv3_create_tunnel_t *mp;
11106   int ret;
11107
11108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11109     {
11110       if (unformat (i, "client_address %U", unformat_ip6_address,
11111                     &client_address))
11112         client_address_set = 1;
11113       else if (unformat (i, "our_address %U", unformat_ip6_address,
11114                          &our_address))
11115         our_address_set = 1;
11116       else if (unformat (i, "local_session_id %d", &local_session_id))
11117         ;
11118       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11119         ;
11120       else if (unformat (i, "local_cookie %lld", &local_cookie))
11121         ;
11122       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11123         ;
11124       else if (unformat (i, "l2-sublayer-present"))
11125         l2_sublayer_present = 1;
11126       else
11127         break;
11128     }
11129
11130   if (client_address_set == 0)
11131     {
11132       errmsg ("client_address required");
11133       return -99;
11134     }
11135
11136   if (our_address_set == 0)
11137     {
11138       errmsg ("our_address required");
11139       return -99;
11140     }
11141
11142   M (L2TPV3_CREATE_TUNNEL, mp);
11143
11144   clib_memcpy (mp->client_address, client_address.as_u8,
11145                sizeof (mp->client_address));
11146
11147   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11148
11149   mp->local_session_id = ntohl (local_session_id);
11150   mp->remote_session_id = ntohl (remote_session_id);
11151   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11152   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11153   mp->l2_sublayer_present = l2_sublayer_present;
11154   mp->is_ipv6 = 1;
11155
11156   S (mp);
11157   W (ret);
11158   return ret;
11159 }
11160
11161 static int
11162 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11163 {
11164   unformat_input_t *i = vam->input;
11165   u32 sw_if_index;
11166   u8 sw_if_index_set = 0;
11167   u64 new_local_cookie = 0;
11168   u64 new_remote_cookie = 0;
11169   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11170   int ret;
11171
11172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11173     {
11174       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11175         sw_if_index_set = 1;
11176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11177         sw_if_index_set = 1;
11178       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11179         ;
11180       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11181         ;
11182       else
11183         break;
11184     }
11185
11186   if (sw_if_index_set == 0)
11187     {
11188       errmsg ("missing interface name or sw_if_index");
11189       return -99;
11190     }
11191
11192   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11193
11194   mp->sw_if_index = ntohl (sw_if_index);
11195   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11196   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11197
11198   S (mp);
11199   W (ret);
11200   return ret;
11201 }
11202
11203 static int
11204 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11205 {
11206   unformat_input_t *i = vam->input;
11207   vl_api_l2tpv3_interface_enable_disable_t *mp;
11208   u32 sw_if_index;
11209   u8 sw_if_index_set = 0;
11210   u8 enable_disable = 1;
11211   int ret;
11212
11213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11214     {
11215       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11216         sw_if_index_set = 1;
11217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11218         sw_if_index_set = 1;
11219       else if (unformat (i, "enable"))
11220         enable_disable = 1;
11221       else if (unformat (i, "disable"))
11222         enable_disable = 0;
11223       else
11224         break;
11225     }
11226
11227   if (sw_if_index_set == 0)
11228     {
11229       errmsg ("missing interface name or sw_if_index");
11230       return -99;
11231     }
11232
11233   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11234
11235   mp->sw_if_index = ntohl (sw_if_index);
11236   mp->enable_disable = enable_disable;
11237
11238   S (mp);
11239   W (ret);
11240   return ret;
11241 }
11242
11243 static int
11244 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11245 {
11246   unformat_input_t *i = vam->input;
11247   vl_api_l2tpv3_set_lookup_key_t *mp;
11248   u8 key = ~0;
11249   int ret;
11250
11251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11252     {
11253       if (unformat (i, "lookup_v6_src"))
11254         key = L2T_LOOKUP_SRC_ADDRESS;
11255       else if (unformat (i, "lookup_v6_dst"))
11256         key = L2T_LOOKUP_DST_ADDRESS;
11257       else if (unformat (i, "lookup_session_id"))
11258         key = L2T_LOOKUP_SESSION_ID;
11259       else
11260         break;
11261     }
11262
11263   if (key == (u8) ~ 0)
11264     {
11265       errmsg ("l2tp session lookup key unset");
11266       return -99;
11267     }
11268
11269   M (L2TPV3_SET_LOOKUP_KEY, mp);
11270
11271   mp->key = key;
11272
11273   S (mp);
11274   W (ret);
11275   return ret;
11276 }
11277
11278 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11279   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11280 {
11281   vat_main_t *vam = &vat_main;
11282
11283   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11284          format_ip6_address, mp->our_address,
11285          format_ip6_address, mp->client_address,
11286          clib_net_to_host_u32 (mp->sw_if_index));
11287
11288   print (vam->ofp,
11289          "   local cookies %016llx %016llx remote cookie %016llx",
11290          clib_net_to_host_u64 (mp->local_cookie[0]),
11291          clib_net_to_host_u64 (mp->local_cookie[1]),
11292          clib_net_to_host_u64 (mp->remote_cookie));
11293
11294   print (vam->ofp, "   local session-id %d remote session-id %d",
11295          clib_net_to_host_u32 (mp->local_session_id),
11296          clib_net_to_host_u32 (mp->remote_session_id));
11297
11298   print (vam->ofp, "   l2 specific sublayer %s\n",
11299          mp->l2_sublayer_present ? "preset" : "absent");
11300
11301 }
11302
11303 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11304   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11305 {
11306   vat_main_t *vam = &vat_main;
11307   vat_json_node_t *node = NULL;
11308   struct in6_addr addr;
11309
11310   if (VAT_JSON_ARRAY != vam->json_tree.type)
11311     {
11312       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11313       vat_json_init_array (&vam->json_tree);
11314     }
11315   node = vat_json_array_add (&vam->json_tree);
11316
11317   vat_json_init_object (node);
11318
11319   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11320   vat_json_object_add_ip6 (node, "our_address", addr);
11321   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11322   vat_json_object_add_ip6 (node, "client_address", addr);
11323
11324   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11325   vat_json_init_array (lc);
11326   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11327   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11328   vat_json_object_add_uint (node, "remote_cookie",
11329                             clib_net_to_host_u64 (mp->remote_cookie));
11330
11331   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11332   vat_json_object_add_uint (node, "local_session_id",
11333                             clib_net_to_host_u32 (mp->local_session_id));
11334   vat_json_object_add_uint (node, "remote_session_id",
11335                             clib_net_to_host_u32 (mp->remote_session_id));
11336   vat_json_object_add_string_copy (node, "l2_sublayer",
11337                                    mp->l2_sublayer_present ? (u8 *) "present"
11338                                    : (u8 *) "absent");
11339 }
11340
11341 static int
11342 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11343 {
11344   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11345   vl_api_control_ping_t *mp_ping;
11346   int ret;
11347
11348   /* Get list of l2tpv3-tunnel interfaces */
11349   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11350   S (mp);
11351
11352   /* Use a control ping for synchronization */
11353   M (CONTROL_PING, mp_ping);
11354   S (mp_ping);
11355
11356   W (ret);
11357   return ret;
11358 }
11359
11360
11361 static void vl_api_sw_interface_tap_details_t_handler
11362   (vl_api_sw_interface_tap_details_t * mp)
11363 {
11364   vat_main_t *vam = &vat_main;
11365
11366   print (vam->ofp, "%-16s %d",
11367          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11368 }
11369
11370 static void vl_api_sw_interface_tap_details_t_handler_json
11371   (vl_api_sw_interface_tap_details_t * mp)
11372 {
11373   vat_main_t *vam = &vat_main;
11374   vat_json_node_t *node = NULL;
11375
11376   if (VAT_JSON_ARRAY != vam->json_tree.type)
11377     {
11378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11379       vat_json_init_array (&vam->json_tree);
11380     }
11381   node = vat_json_array_add (&vam->json_tree);
11382
11383   vat_json_init_object (node);
11384   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11385   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11386 }
11387
11388 static int
11389 api_sw_interface_tap_dump (vat_main_t * vam)
11390 {
11391   vl_api_sw_interface_tap_dump_t *mp;
11392   vl_api_control_ping_t *mp_ping;
11393   int ret;
11394
11395   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11396   /* Get list of tap interfaces */
11397   M (SW_INTERFACE_TAP_DUMP, mp);
11398   S (mp);
11399
11400   /* Use a control ping for synchronization */
11401   M (CONTROL_PING, mp_ping);
11402   S (mp_ping);
11403
11404   W (ret);
11405   return ret;
11406 }
11407
11408 static uword unformat_vxlan_decap_next
11409   (unformat_input_t * input, va_list * args)
11410 {
11411   u32 *result = va_arg (*args, u32 *);
11412   u32 tmp;
11413
11414   if (unformat (input, "l2"))
11415     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11416   else if (unformat (input, "%d", &tmp))
11417     *result = tmp;
11418   else
11419     return 0;
11420   return 1;
11421 }
11422
11423 static int
11424 api_vxlan_add_del_tunnel (vat_main_t * vam)
11425 {
11426   unformat_input_t *line_input = vam->input;
11427   vl_api_vxlan_add_del_tunnel_t *mp;
11428   ip46_address_t src, dst;
11429   u8 is_add = 1;
11430   u8 ipv4_set = 0, ipv6_set = 0;
11431   u8 src_set = 0;
11432   u8 dst_set = 0;
11433   u8 grp_set = 0;
11434   u32 mcast_sw_if_index = ~0;
11435   u32 encap_vrf_id = 0;
11436   u32 decap_next_index = ~0;
11437   u32 vni = 0;
11438   int ret;
11439
11440   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11441   memset (&src, 0, sizeof src);
11442   memset (&dst, 0, sizeof dst);
11443
11444   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11445     {
11446       if (unformat (line_input, "del"))
11447         is_add = 0;
11448       else
11449         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11450         {
11451           ipv4_set = 1;
11452           src_set = 1;
11453         }
11454       else
11455         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11456         {
11457           ipv4_set = 1;
11458           dst_set = 1;
11459         }
11460       else
11461         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11462         {
11463           ipv6_set = 1;
11464           src_set = 1;
11465         }
11466       else
11467         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11468         {
11469           ipv6_set = 1;
11470           dst_set = 1;
11471         }
11472       else if (unformat (line_input, "group %U %U",
11473                          unformat_ip4_address, &dst.ip4,
11474                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11475         {
11476           grp_set = dst_set = 1;
11477           ipv4_set = 1;
11478         }
11479       else if (unformat (line_input, "group %U",
11480                          unformat_ip4_address, &dst.ip4))
11481         {
11482           grp_set = dst_set = 1;
11483           ipv4_set = 1;
11484         }
11485       else if (unformat (line_input, "group %U %U",
11486                          unformat_ip6_address, &dst.ip6,
11487                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11488         {
11489           grp_set = dst_set = 1;
11490           ipv6_set = 1;
11491         }
11492       else if (unformat (line_input, "group %U",
11493                          unformat_ip6_address, &dst.ip6))
11494         {
11495           grp_set = dst_set = 1;
11496           ipv6_set = 1;
11497         }
11498       else
11499         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11500         ;
11501       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11502         ;
11503       else if (unformat (line_input, "decap-next %U",
11504                          unformat_vxlan_decap_next, &decap_next_index))
11505         ;
11506       else if (unformat (line_input, "vni %d", &vni))
11507         ;
11508       else
11509         {
11510           errmsg ("parse error '%U'", format_unformat_error, line_input);
11511           return -99;
11512         }
11513     }
11514
11515   if (src_set == 0)
11516     {
11517       errmsg ("tunnel src address not specified");
11518       return -99;
11519     }
11520   if (dst_set == 0)
11521     {
11522       errmsg ("tunnel dst address not specified");
11523       return -99;
11524     }
11525
11526   if (grp_set && !ip46_address_is_multicast (&dst))
11527     {
11528       errmsg ("tunnel group address not multicast");
11529       return -99;
11530     }
11531   if (grp_set && mcast_sw_if_index == ~0)
11532     {
11533       errmsg ("tunnel nonexistent multicast device");
11534       return -99;
11535     }
11536   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11537     {
11538       errmsg ("tunnel dst address must be unicast");
11539       return -99;
11540     }
11541
11542
11543   if (ipv4_set && ipv6_set)
11544     {
11545       errmsg ("both IPv4 and IPv6 addresses specified");
11546       return -99;
11547     }
11548
11549   if ((vni == 0) || (vni >> 24))
11550     {
11551       errmsg ("vni not specified or out of range");
11552       return -99;
11553     }
11554
11555   M (VXLAN_ADD_DEL_TUNNEL, mp);
11556
11557   if (ipv6_set)
11558     {
11559       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11560       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11561     }
11562   else
11563     {
11564       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11565       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11566     }
11567   mp->encap_vrf_id = ntohl (encap_vrf_id);
11568   mp->decap_next_index = ntohl (decap_next_index);
11569   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11570   mp->vni = ntohl (vni);
11571   mp->is_add = is_add;
11572   mp->is_ipv6 = ipv6_set;
11573
11574   S (mp);
11575   W (ret);
11576   return ret;
11577 }
11578
11579 static void vl_api_vxlan_tunnel_details_t_handler
11580   (vl_api_vxlan_tunnel_details_t * mp)
11581 {
11582   vat_main_t *vam = &vat_main;
11583   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11584   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11585
11586   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11587          ntohl (mp->sw_if_index),
11588          format_ip46_address, &src, IP46_TYPE_ANY,
11589          format_ip46_address, &dst, IP46_TYPE_ANY,
11590          ntohl (mp->encap_vrf_id),
11591          ntohl (mp->decap_next_index), ntohl (mp->vni),
11592          ntohl (mp->mcast_sw_if_index));
11593 }
11594
11595 static void vl_api_vxlan_tunnel_details_t_handler_json
11596   (vl_api_vxlan_tunnel_details_t * mp)
11597 {
11598   vat_main_t *vam = &vat_main;
11599   vat_json_node_t *node = NULL;
11600
11601   if (VAT_JSON_ARRAY != vam->json_tree.type)
11602     {
11603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11604       vat_json_init_array (&vam->json_tree);
11605     }
11606   node = vat_json_array_add (&vam->json_tree);
11607
11608   vat_json_init_object (node);
11609   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11610   if (mp->is_ipv6)
11611     {
11612       struct in6_addr ip6;
11613
11614       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11615       vat_json_object_add_ip6 (node, "src_address", ip6);
11616       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11617       vat_json_object_add_ip6 (node, "dst_address", ip6);
11618     }
11619   else
11620     {
11621       struct in_addr ip4;
11622
11623       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11624       vat_json_object_add_ip4 (node, "src_address", ip4);
11625       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11626       vat_json_object_add_ip4 (node, "dst_address", ip4);
11627     }
11628   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11629   vat_json_object_add_uint (node, "decap_next_index",
11630                             ntohl (mp->decap_next_index));
11631   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11632   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11633   vat_json_object_add_uint (node, "mcast_sw_if_index",
11634                             ntohl (mp->mcast_sw_if_index));
11635 }
11636
11637 static int
11638 api_vxlan_tunnel_dump (vat_main_t * vam)
11639 {
11640   unformat_input_t *i = vam->input;
11641   vl_api_vxlan_tunnel_dump_t *mp;
11642   vl_api_control_ping_t *mp_ping;
11643   u32 sw_if_index;
11644   u8 sw_if_index_set = 0;
11645   int ret;
11646
11647   /* Parse args required to build the message */
11648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11649     {
11650       if (unformat (i, "sw_if_index %d", &sw_if_index))
11651         sw_if_index_set = 1;
11652       else
11653         break;
11654     }
11655
11656   if (sw_if_index_set == 0)
11657     {
11658       sw_if_index = ~0;
11659     }
11660
11661   if (!vam->json_output)
11662     {
11663       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11664              "sw_if_index", "src_address", "dst_address",
11665              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11666     }
11667
11668   /* Get list of vxlan-tunnel interfaces */
11669   M (VXLAN_TUNNEL_DUMP, mp);
11670
11671   mp->sw_if_index = htonl (sw_if_index);
11672
11673   S (mp);
11674
11675   /* Use a control ping for synchronization */
11676   M (CONTROL_PING, mp_ping);
11677   S (mp_ping);
11678
11679   W (ret);
11680   return ret;
11681 }
11682
11683 static int
11684 api_gre_add_del_tunnel (vat_main_t * vam)
11685 {
11686   unformat_input_t *line_input = vam->input;
11687   vl_api_gre_add_del_tunnel_t *mp;
11688   ip4_address_t src4, dst4;
11689   ip6_address_t src6, dst6;
11690   u8 is_add = 1;
11691   u8 ipv4_set = 0;
11692   u8 ipv6_set = 0;
11693   u8 teb = 0;
11694   u8 src_set = 0;
11695   u8 dst_set = 0;
11696   u32 outer_fib_id = 0;
11697   int ret;
11698
11699   memset (&src4, 0, sizeof src4);
11700   memset (&dst4, 0, sizeof dst4);
11701   memset (&src6, 0, sizeof src6);
11702   memset (&dst6, 0, sizeof dst6);
11703
11704   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11705     {
11706       if (unformat (line_input, "del"))
11707         is_add = 0;
11708       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11709         {
11710           src_set = 1;
11711           ipv4_set = 1;
11712         }
11713       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11714         {
11715           dst_set = 1;
11716           ipv4_set = 1;
11717         }
11718       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11719         {
11720           src_set = 1;
11721           ipv6_set = 1;
11722         }
11723       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11724         {
11725           dst_set = 1;
11726           ipv6_set = 1;
11727         }
11728       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11729         ;
11730       else if (unformat (line_input, "teb"))
11731         teb = 1;
11732       else
11733         {
11734           errmsg ("parse error '%U'", format_unformat_error, line_input);
11735           return -99;
11736         }
11737     }
11738
11739   if (src_set == 0)
11740     {
11741       errmsg ("tunnel src address not specified");
11742       return -99;
11743     }
11744   if (dst_set == 0)
11745     {
11746       errmsg ("tunnel dst address not specified");
11747       return -99;
11748     }
11749   if (ipv4_set && ipv6_set)
11750     {
11751       errmsg ("both IPv4 and IPv6 addresses specified");
11752       return -99;
11753     }
11754
11755
11756   M (GRE_ADD_DEL_TUNNEL, mp);
11757
11758   if (ipv4_set)
11759     {
11760       clib_memcpy (&mp->src_address, &src4, 4);
11761       clib_memcpy (&mp->dst_address, &dst4, 4);
11762     }
11763   else
11764     {
11765       clib_memcpy (&mp->src_address, &src6, 16);
11766       clib_memcpy (&mp->dst_address, &dst6, 16);
11767     }
11768   mp->outer_fib_id = ntohl (outer_fib_id);
11769   mp->is_add = is_add;
11770   mp->teb = teb;
11771   mp->is_ipv6 = ipv6_set;
11772
11773   S (mp);
11774   W (ret);
11775   return ret;
11776 }
11777
11778 static void vl_api_gre_tunnel_details_t_handler
11779   (vl_api_gre_tunnel_details_t * mp)
11780 {
11781   vat_main_t *vam = &vat_main;
11782   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11783   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11784
11785   print (vam->ofp, "%11d%24U%24U%6d%14d",
11786          ntohl (mp->sw_if_index),
11787          format_ip46_address, &src, IP46_TYPE_ANY,
11788          format_ip46_address, &dst, IP46_TYPE_ANY,
11789          mp->teb, ntohl (mp->outer_fib_id));
11790 }
11791
11792 static void vl_api_gre_tunnel_details_t_handler_json
11793   (vl_api_gre_tunnel_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796   vat_json_node_t *node = NULL;
11797   struct in_addr ip4;
11798   struct in6_addr ip6;
11799
11800   if (VAT_JSON_ARRAY != vam->json_tree.type)
11801     {
11802       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11803       vat_json_init_array (&vam->json_tree);
11804     }
11805   node = vat_json_array_add (&vam->json_tree);
11806
11807   vat_json_init_object (node);
11808   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11809   if (!mp->is_ipv6)
11810     {
11811       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11812       vat_json_object_add_ip4 (node, "src_address", ip4);
11813       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11814       vat_json_object_add_ip4 (node, "dst_address", ip4);
11815     }
11816   else
11817     {
11818       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11819       vat_json_object_add_ip6 (node, "src_address", ip6);
11820       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11821       vat_json_object_add_ip6 (node, "dst_address", ip6);
11822     }
11823   vat_json_object_add_uint (node, "teb", mp->teb);
11824   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11825   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11826 }
11827
11828 static int
11829 api_gre_tunnel_dump (vat_main_t * vam)
11830 {
11831   unformat_input_t *i = vam->input;
11832   vl_api_gre_tunnel_dump_t *mp;
11833   vl_api_control_ping_t *mp_ping;
11834   u32 sw_if_index;
11835   u8 sw_if_index_set = 0;
11836   int ret;
11837
11838   /* Parse args required to build the message */
11839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11840     {
11841       if (unformat (i, "sw_if_index %d", &sw_if_index))
11842         sw_if_index_set = 1;
11843       else
11844         break;
11845     }
11846
11847   if (sw_if_index_set == 0)
11848     {
11849       sw_if_index = ~0;
11850     }
11851
11852   if (!vam->json_output)
11853     {
11854       print (vam->ofp, "%11s%24s%24s%6s%14s",
11855              "sw_if_index", "src_address", "dst_address", "teb",
11856              "outer_fib_id");
11857     }
11858
11859   /* Get list of gre-tunnel interfaces */
11860   M (GRE_TUNNEL_DUMP, mp);
11861
11862   mp->sw_if_index = htonl (sw_if_index);
11863
11864   S (mp);
11865
11866   /* Use a control ping for synchronization */
11867   M (CONTROL_PING, mp_ping);
11868   S (mp_ping);
11869
11870   W (ret);
11871   return ret;
11872 }
11873
11874 static int
11875 api_l2_fib_clear_table (vat_main_t * vam)
11876 {
11877 //  unformat_input_t * i = vam->input;
11878   vl_api_l2_fib_clear_table_t *mp;
11879   int ret;
11880
11881   M (L2_FIB_CLEAR_TABLE, mp);
11882
11883   S (mp);
11884   W (ret);
11885   return ret;
11886 }
11887
11888 static int
11889 api_l2_interface_efp_filter (vat_main_t * vam)
11890 {
11891   unformat_input_t *i = vam->input;
11892   vl_api_l2_interface_efp_filter_t *mp;
11893   u32 sw_if_index;
11894   u8 enable = 1;
11895   u8 sw_if_index_set = 0;
11896   int ret;
11897
11898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11899     {
11900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11901         sw_if_index_set = 1;
11902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11903         sw_if_index_set = 1;
11904       else if (unformat (i, "enable"))
11905         enable = 1;
11906       else if (unformat (i, "disable"))
11907         enable = 0;
11908       else
11909         {
11910           clib_warning ("parse error '%U'", format_unformat_error, i);
11911           return -99;
11912         }
11913     }
11914
11915   if (sw_if_index_set == 0)
11916     {
11917       errmsg ("missing sw_if_index");
11918       return -99;
11919     }
11920
11921   M (L2_INTERFACE_EFP_FILTER, mp);
11922
11923   mp->sw_if_index = ntohl (sw_if_index);
11924   mp->enable_disable = enable;
11925
11926   S (mp);
11927   W (ret);
11928   return ret;
11929 }
11930
11931 #define foreach_vtr_op                          \
11932 _("disable",  L2_VTR_DISABLED)                  \
11933 _("push-1",  L2_VTR_PUSH_1)                     \
11934 _("push-2",  L2_VTR_PUSH_2)                     \
11935 _("pop-1",  L2_VTR_POP_1)                       \
11936 _("pop-2",  L2_VTR_POP_2)                       \
11937 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11938 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11939 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11940 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11941
11942 static int
11943 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11944 {
11945   unformat_input_t *i = vam->input;
11946   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11947   u32 sw_if_index;
11948   u8 sw_if_index_set = 0;
11949   u8 vtr_op_set = 0;
11950   u32 vtr_op = 0;
11951   u32 push_dot1q = 1;
11952   u32 tag1 = ~0;
11953   u32 tag2 = ~0;
11954   int ret;
11955
11956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11957     {
11958       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11959         sw_if_index_set = 1;
11960       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11961         sw_if_index_set = 1;
11962       else if (unformat (i, "vtr_op %d", &vtr_op))
11963         vtr_op_set = 1;
11964 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11965       foreach_vtr_op
11966 #undef _
11967         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11968         ;
11969       else if (unformat (i, "tag1 %d", &tag1))
11970         ;
11971       else if (unformat (i, "tag2 %d", &tag2))
11972         ;
11973       else
11974         {
11975           clib_warning ("parse error '%U'", format_unformat_error, i);
11976           return -99;
11977         }
11978     }
11979
11980   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11981     {
11982       errmsg ("missing vtr operation or sw_if_index");
11983       return -99;
11984     }
11985
11986   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11987   mp->sw_if_index = ntohl (sw_if_index);
11988   mp->vtr_op = ntohl (vtr_op);
11989   mp->push_dot1q = ntohl (push_dot1q);
11990   mp->tag1 = ntohl (tag1);
11991   mp->tag2 = ntohl (tag2);
11992
11993   S (mp);
11994   W (ret);
11995   return ret;
11996 }
11997
11998 static int
11999 api_create_vhost_user_if (vat_main_t * vam)
12000 {
12001   unformat_input_t *i = vam->input;
12002   vl_api_create_vhost_user_if_t *mp;
12003   u8 *file_name;
12004   u8 is_server = 0;
12005   u8 file_name_set = 0;
12006   u32 custom_dev_instance = ~0;
12007   u8 hwaddr[6];
12008   u8 use_custom_mac = 0;
12009   u8 *tag = 0;
12010   int ret;
12011
12012   /* Shut up coverity */
12013   memset (hwaddr, 0, sizeof (hwaddr));
12014
12015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12016     {
12017       if (unformat (i, "socket %s", &file_name))
12018         {
12019           file_name_set = 1;
12020         }
12021       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12022         ;
12023       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12024         use_custom_mac = 1;
12025       else if (unformat (i, "server"))
12026         is_server = 1;
12027       else if (unformat (i, "tag %s", &tag))
12028         ;
12029       else
12030         break;
12031     }
12032
12033   if (file_name_set == 0)
12034     {
12035       errmsg ("missing socket file name");
12036       return -99;
12037     }
12038
12039   if (vec_len (file_name) > 255)
12040     {
12041       errmsg ("socket file name too long");
12042       return -99;
12043     }
12044   vec_add1 (file_name, 0);
12045
12046   M (CREATE_VHOST_USER_IF, mp);
12047
12048   mp->is_server = is_server;
12049   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12050   vec_free (file_name);
12051   if (custom_dev_instance != ~0)
12052     {
12053       mp->renumber = 1;
12054       mp->custom_dev_instance = ntohl (custom_dev_instance);
12055     }
12056   mp->use_custom_mac = use_custom_mac;
12057   clib_memcpy (mp->mac_address, hwaddr, 6);
12058   if (tag)
12059     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12060   vec_free (tag);
12061
12062   S (mp);
12063   W (ret);
12064   return ret;
12065 }
12066
12067 static int
12068 api_modify_vhost_user_if (vat_main_t * vam)
12069 {
12070   unformat_input_t *i = vam->input;
12071   vl_api_modify_vhost_user_if_t *mp;
12072   u8 *file_name;
12073   u8 is_server = 0;
12074   u8 file_name_set = 0;
12075   u32 custom_dev_instance = ~0;
12076   u8 sw_if_index_set = 0;
12077   u32 sw_if_index = (u32) ~ 0;
12078   int ret;
12079
12080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12081     {
12082       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12083         sw_if_index_set = 1;
12084       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12085         sw_if_index_set = 1;
12086       else if (unformat (i, "socket %s", &file_name))
12087         {
12088           file_name_set = 1;
12089         }
12090       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12091         ;
12092       else if (unformat (i, "server"))
12093         is_server = 1;
12094       else
12095         break;
12096     }
12097
12098   if (sw_if_index_set == 0)
12099     {
12100       errmsg ("missing sw_if_index or interface name");
12101       return -99;
12102     }
12103
12104   if (file_name_set == 0)
12105     {
12106       errmsg ("missing socket file name");
12107       return -99;
12108     }
12109
12110   if (vec_len (file_name) > 255)
12111     {
12112       errmsg ("socket file name too long");
12113       return -99;
12114     }
12115   vec_add1 (file_name, 0);
12116
12117   M (MODIFY_VHOST_USER_IF, mp);
12118
12119   mp->sw_if_index = ntohl (sw_if_index);
12120   mp->is_server = is_server;
12121   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12122   vec_free (file_name);
12123   if (custom_dev_instance != ~0)
12124     {
12125       mp->renumber = 1;
12126       mp->custom_dev_instance = ntohl (custom_dev_instance);
12127     }
12128
12129   S (mp);
12130   W (ret);
12131   return ret;
12132 }
12133
12134 static int
12135 api_delete_vhost_user_if (vat_main_t * vam)
12136 {
12137   unformat_input_t *i = vam->input;
12138   vl_api_delete_vhost_user_if_t *mp;
12139   u32 sw_if_index = ~0;
12140   u8 sw_if_index_set = 0;
12141   int ret;
12142
12143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12144     {
12145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12146         sw_if_index_set = 1;
12147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12148         sw_if_index_set = 1;
12149       else
12150         break;
12151     }
12152
12153   if (sw_if_index_set == 0)
12154     {
12155       errmsg ("missing sw_if_index or interface name");
12156       return -99;
12157     }
12158
12159
12160   M (DELETE_VHOST_USER_IF, mp);
12161
12162   mp->sw_if_index = ntohl (sw_if_index);
12163
12164   S (mp);
12165   W (ret);
12166   return ret;
12167 }
12168
12169 static void vl_api_sw_interface_vhost_user_details_t_handler
12170   (vl_api_sw_interface_vhost_user_details_t * mp)
12171 {
12172   vat_main_t *vam = &vat_main;
12173
12174   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12175          (char *) mp->interface_name,
12176          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12177          clib_net_to_host_u64 (mp->features), mp->is_server,
12178          ntohl (mp->num_regions), (char *) mp->sock_filename);
12179   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12180 }
12181
12182 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12183   (vl_api_sw_interface_vhost_user_details_t * mp)
12184 {
12185   vat_main_t *vam = &vat_main;
12186   vat_json_node_t *node = NULL;
12187
12188   if (VAT_JSON_ARRAY != vam->json_tree.type)
12189     {
12190       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12191       vat_json_init_array (&vam->json_tree);
12192     }
12193   node = vat_json_array_add (&vam->json_tree);
12194
12195   vat_json_init_object (node);
12196   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12197   vat_json_object_add_string_copy (node, "interface_name",
12198                                    mp->interface_name);
12199   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12200                             ntohl (mp->virtio_net_hdr_sz));
12201   vat_json_object_add_uint (node, "features",
12202                             clib_net_to_host_u64 (mp->features));
12203   vat_json_object_add_uint (node, "is_server", mp->is_server);
12204   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12205   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12206   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12207 }
12208
12209 static int
12210 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12211 {
12212   vl_api_sw_interface_vhost_user_dump_t *mp;
12213   vl_api_control_ping_t *mp_ping;
12214   int ret;
12215   print (vam->ofp,
12216          "Interface name            idx hdr_sz features server regions filename");
12217
12218   /* Get list of vhost-user interfaces */
12219   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12220   S (mp);
12221
12222   /* Use a control ping for synchronization */
12223   M (CONTROL_PING, mp_ping);
12224   S (mp_ping);
12225
12226   W (ret);
12227   return ret;
12228 }
12229
12230 static int
12231 api_show_version (vat_main_t * vam)
12232 {
12233   vl_api_show_version_t *mp;
12234   int ret;
12235
12236   M (SHOW_VERSION, mp);
12237
12238   S (mp);
12239   W (ret);
12240   return ret;
12241 }
12242
12243
12244 static int
12245 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12246 {
12247   unformat_input_t *line_input = vam->input;
12248   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12249   ip4_address_t local4, remote4;
12250   ip6_address_t local6, remote6;
12251   u8 is_add = 1;
12252   u8 ipv4_set = 0, ipv6_set = 0;
12253   u8 local_set = 0;
12254   u8 remote_set = 0;
12255   u8 grp_set = 0;
12256   u32 mcast_sw_if_index = ~0;
12257   u32 encap_vrf_id = 0;
12258   u32 decap_vrf_id = 0;
12259   u8 protocol = ~0;
12260   u32 vni;
12261   u8 vni_set = 0;
12262   int ret;
12263
12264   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12265   memset (&local4, 0, sizeof local4);
12266   memset (&remote4, 0, sizeof remote4);
12267   memset (&local6, 0, sizeof local6);
12268   memset (&remote6, 0, sizeof remote6);
12269
12270   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12271     {
12272       if (unformat (line_input, "del"))
12273         is_add = 0;
12274       else if (unformat (line_input, "local %U",
12275                          unformat_ip4_address, &local4))
12276         {
12277           local_set = 1;
12278           ipv4_set = 1;
12279         }
12280       else if (unformat (line_input, "remote %U",
12281                          unformat_ip4_address, &remote4))
12282         {
12283           remote_set = 1;
12284           ipv4_set = 1;
12285         }
12286       else if (unformat (line_input, "local %U",
12287                          unformat_ip6_address, &local6))
12288         {
12289           local_set = 1;
12290           ipv6_set = 1;
12291         }
12292       else if (unformat (line_input, "remote %U",
12293                          unformat_ip6_address, &remote6))
12294         {
12295           remote_set = 1;
12296           ipv6_set = 1;
12297         }
12298       else if (unformat (line_input, "group %U %U",
12299                          unformat_ip4_address, &remote4,
12300                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12301         {
12302           grp_set = remote_set = 1;
12303           ipv4_set = 1;
12304         }
12305       else if (unformat (line_input, "group %U",
12306                          unformat_ip4_address, &remote4))
12307         {
12308           grp_set = remote_set = 1;
12309           ipv4_set = 1;
12310         }
12311       else if (unformat (line_input, "group %U %U",
12312                          unformat_ip6_address, &remote6,
12313                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12314         {
12315           grp_set = remote_set = 1;
12316           ipv6_set = 1;
12317         }
12318       else if (unformat (line_input, "group %U",
12319                          unformat_ip6_address, &remote6))
12320         {
12321           grp_set = remote_set = 1;
12322           ipv6_set = 1;
12323         }
12324       else
12325         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12326         ;
12327       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12328         ;
12329       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12330         ;
12331       else if (unformat (line_input, "vni %d", &vni))
12332         vni_set = 1;
12333       else if (unformat (line_input, "next-ip4"))
12334         protocol = 1;
12335       else if (unformat (line_input, "next-ip6"))
12336         protocol = 2;
12337       else if (unformat (line_input, "next-ethernet"))
12338         protocol = 3;
12339       else if (unformat (line_input, "next-nsh"))
12340         protocol = 4;
12341       else
12342         {
12343           errmsg ("parse error '%U'", format_unformat_error, line_input);
12344           return -99;
12345         }
12346     }
12347
12348   if (local_set == 0)
12349     {
12350       errmsg ("tunnel local address not specified");
12351       return -99;
12352     }
12353   if (remote_set == 0)
12354     {
12355       errmsg ("tunnel remote address not specified");
12356       return -99;
12357     }
12358   if (grp_set && mcast_sw_if_index == ~0)
12359     {
12360       errmsg ("tunnel nonexistent multicast device");
12361       return -99;
12362     }
12363   if (ipv4_set && ipv6_set)
12364     {
12365       errmsg ("both IPv4 and IPv6 addresses specified");
12366       return -99;
12367     }
12368
12369   if (vni_set == 0)
12370     {
12371       errmsg ("vni not specified");
12372       return -99;
12373     }
12374
12375   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12376
12377
12378   if (ipv6_set)
12379     {
12380       clib_memcpy (&mp->local, &local6, sizeof (local6));
12381       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12382     }
12383   else
12384     {
12385       clib_memcpy (&mp->local, &local4, sizeof (local4));
12386       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12387     }
12388
12389   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12390   mp->encap_vrf_id = ntohl (encap_vrf_id);
12391   mp->decap_vrf_id = ntohl (decap_vrf_id);
12392   mp->protocol = protocol;
12393   mp->vni = ntohl (vni);
12394   mp->is_add = is_add;
12395   mp->is_ipv6 = ipv6_set;
12396
12397   S (mp);
12398   W (ret);
12399   return ret;
12400 }
12401
12402 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12403   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12404 {
12405   vat_main_t *vam = &vat_main;
12406   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12407   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12408
12409   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12410          ntohl (mp->sw_if_index),
12411          format_ip46_address, &local, IP46_TYPE_ANY,
12412          format_ip46_address, &remote, IP46_TYPE_ANY,
12413          ntohl (mp->vni), mp->protocol,
12414          ntohl (mp->mcast_sw_if_index),
12415          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12416 }
12417
12418
12419 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12420   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12421 {
12422   vat_main_t *vam = &vat_main;
12423   vat_json_node_t *node = NULL;
12424   struct in_addr ip4;
12425   struct in6_addr ip6;
12426
12427   if (VAT_JSON_ARRAY != vam->json_tree.type)
12428     {
12429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12430       vat_json_init_array (&vam->json_tree);
12431     }
12432   node = vat_json_array_add (&vam->json_tree);
12433
12434   vat_json_init_object (node);
12435   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12436   if (mp->is_ipv6)
12437     {
12438       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12439       vat_json_object_add_ip6 (node, "local", ip6);
12440       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12441       vat_json_object_add_ip6 (node, "remote", ip6);
12442     }
12443   else
12444     {
12445       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12446       vat_json_object_add_ip4 (node, "local", ip4);
12447       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12448       vat_json_object_add_ip4 (node, "remote", ip4);
12449     }
12450   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12451   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12452   vat_json_object_add_uint (node, "mcast_sw_if_index",
12453                             ntohl (mp->mcast_sw_if_index));
12454   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12455   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12456   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12457 }
12458
12459 static int
12460 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12461 {
12462   unformat_input_t *i = vam->input;
12463   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12464   vl_api_control_ping_t *mp_ping;
12465   u32 sw_if_index;
12466   u8 sw_if_index_set = 0;
12467   int ret;
12468
12469   /* Parse args required to build the message */
12470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12471     {
12472       if (unformat (i, "sw_if_index %d", &sw_if_index))
12473         sw_if_index_set = 1;
12474       else
12475         break;
12476     }
12477
12478   if (sw_if_index_set == 0)
12479     {
12480       sw_if_index = ~0;
12481     }
12482
12483   if (!vam->json_output)
12484     {
12485       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12486              "sw_if_index", "local", "remote", "vni",
12487              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12488     }
12489
12490   /* Get list of vxlan-tunnel interfaces */
12491   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12492
12493   mp->sw_if_index = htonl (sw_if_index);
12494
12495   S (mp);
12496
12497   /* Use a control ping for synchronization */
12498   M (CONTROL_PING, mp_ping);
12499   S (mp_ping);
12500
12501   W (ret);
12502   return ret;
12503 }
12504
12505
12506 u8 *
12507 format_l2_fib_mac_address (u8 * s, va_list * args)
12508 {
12509   u8 *a = va_arg (*args, u8 *);
12510
12511   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12512                  a[2], a[3], a[4], a[5], a[6], a[7]);
12513 }
12514
12515 static void vl_api_l2_fib_table_details_t_handler
12516   (vl_api_l2_fib_table_details_t * mp)
12517 {
12518   vat_main_t *vam = &vat_main;
12519
12520   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12521          "       %d       %d     %d",
12522          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12523          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12524          mp->bvi_mac);
12525 }
12526
12527 static void vl_api_l2_fib_table_details_t_handler_json
12528   (vl_api_l2_fib_table_details_t * mp)
12529 {
12530   vat_main_t *vam = &vat_main;
12531   vat_json_node_t *node = NULL;
12532
12533   if (VAT_JSON_ARRAY != vam->json_tree.type)
12534     {
12535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12536       vat_json_init_array (&vam->json_tree);
12537     }
12538   node = vat_json_array_add (&vam->json_tree);
12539
12540   vat_json_init_object (node);
12541   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12542   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12543   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12544   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12545   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12546   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12547 }
12548
12549 static int
12550 api_l2_fib_table_dump (vat_main_t * vam)
12551 {
12552   unformat_input_t *i = vam->input;
12553   vl_api_l2_fib_table_dump_t *mp;
12554   vl_api_control_ping_t *mp_ping;
12555   u32 bd_id;
12556   u8 bd_id_set = 0;
12557   int ret;
12558
12559   /* Parse args required to build the message */
12560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12561     {
12562       if (unformat (i, "bd_id %d", &bd_id))
12563         bd_id_set = 1;
12564       else
12565         break;
12566     }
12567
12568   if (bd_id_set == 0)
12569     {
12570       errmsg ("missing bridge domain");
12571       return -99;
12572     }
12573
12574   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12575
12576   /* Get list of l2 fib entries */
12577   M (L2_FIB_TABLE_DUMP, mp);
12578
12579   mp->bd_id = ntohl (bd_id);
12580   S (mp);
12581
12582   /* Use a control ping for synchronization */
12583   M (CONTROL_PING, mp_ping);
12584   S (mp_ping);
12585
12586   W (ret);
12587   return ret;
12588 }
12589
12590
12591 static int
12592 api_interface_name_renumber (vat_main_t * vam)
12593 {
12594   unformat_input_t *line_input = vam->input;
12595   vl_api_interface_name_renumber_t *mp;
12596   u32 sw_if_index = ~0;
12597   u32 new_show_dev_instance = ~0;
12598   int ret;
12599
12600   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12601     {
12602       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12603                     &sw_if_index))
12604         ;
12605       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12606         ;
12607       else if (unformat (line_input, "new_show_dev_instance %d",
12608                          &new_show_dev_instance))
12609         ;
12610       else
12611         break;
12612     }
12613
12614   if (sw_if_index == ~0)
12615     {
12616       errmsg ("missing interface name or sw_if_index");
12617       return -99;
12618     }
12619
12620   if (new_show_dev_instance == ~0)
12621     {
12622       errmsg ("missing new_show_dev_instance");
12623       return -99;
12624     }
12625
12626   M (INTERFACE_NAME_RENUMBER, mp);
12627
12628   mp->sw_if_index = ntohl (sw_if_index);
12629   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12630
12631   S (mp);
12632   W (ret);
12633   return ret;
12634 }
12635
12636 static int
12637 api_want_ip4_arp_events (vat_main_t * vam)
12638 {
12639   unformat_input_t *line_input = vam->input;
12640   vl_api_want_ip4_arp_events_t *mp;
12641   ip4_address_t address;
12642   int address_set = 0;
12643   u32 enable_disable = 1;
12644   int ret;
12645
12646   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12647     {
12648       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12649         address_set = 1;
12650       else if (unformat (line_input, "del"))
12651         enable_disable = 0;
12652       else
12653         break;
12654     }
12655
12656   if (address_set == 0)
12657     {
12658       errmsg ("missing addresses");
12659       return -99;
12660     }
12661
12662   M (WANT_IP4_ARP_EVENTS, mp);
12663   mp->enable_disable = enable_disable;
12664   mp->pid = htonl (getpid ());
12665   mp->address = address.as_u32;
12666
12667   S (mp);
12668   W (ret);
12669   return ret;
12670 }
12671
12672 static int
12673 api_want_ip6_nd_events (vat_main_t * vam)
12674 {
12675   unformat_input_t *line_input = vam->input;
12676   vl_api_want_ip6_nd_events_t *mp;
12677   ip6_address_t address;
12678   int address_set = 0;
12679   u32 enable_disable = 1;
12680   int ret;
12681
12682   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12683     {
12684       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12685         address_set = 1;
12686       else if (unformat (line_input, "del"))
12687         enable_disable = 0;
12688       else
12689         break;
12690     }
12691
12692   if (address_set == 0)
12693     {
12694       errmsg ("missing addresses");
12695       return -99;
12696     }
12697
12698   M (WANT_IP6_ND_EVENTS, mp);
12699   mp->enable_disable = enable_disable;
12700   mp->pid = htonl (getpid ());
12701   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12702
12703   S (mp);
12704   W (ret);
12705   return ret;
12706 }
12707
12708 static int
12709 api_want_l2_macs_events (vat_main_t * vam)
12710 {
12711   unformat_input_t *line_input = vam->input;
12712   vl_api_want_l2_macs_events_t *mp;
12713   u8 enable_disable = 1;
12714   u32 scan_delay = 0;
12715   u32 max_macs_in_event = 0;
12716   u32 learn_limit = 0;
12717   int ret;
12718
12719   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12720     {
12721       if (unformat (line_input, "learn-limit %d", &learn_limit))
12722         ;
12723       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12724         ;
12725       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12726         ;
12727       else if (unformat (line_input, "disable"))
12728         enable_disable = 0;
12729       else
12730         break;
12731     }
12732
12733   M (WANT_L2_MACS_EVENTS, mp);
12734   mp->enable_disable = enable_disable;
12735   mp->pid = htonl (getpid ());
12736   mp->learn_limit = htonl (learn_limit);
12737   mp->scan_delay = (u8) scan_delay;
12738   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12739   S (mp);
12740   W (ret);
12741   return ret;
12742 }
12743
12744 static int
12745 api_input_acl_set_interface (vat_main_t * vam)
12746 {
12747   unformat_input_t *i = vam->input;
12748   vl_api_input_acl_set_interface_t *mp;
12749   u32 sw_if_index;
12750   int sw_if_index_set;
12751   u32 ip4_table_index = ~0;
12752   u32 ip6_table_index = ~0;
12753   u32 l2_table_index = ~0;
12754   u8 is_add = 1;
12755   int ret;
12756
12757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12758     {
12759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12760         sw_if_index_set = 1;
12761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12762         sw_if_index_set = 1;
12763       else if (unformat (i, "del"))
12764         is_add = 0;
12765       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12766         ;
12767       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12768         ;
12769       else if (unformat (i, "l2-table %d", &l2_table_index))
12770         ;
12771       else
12772         {
12773           clib_warning ("parse error '%U'", format_unformat_error, i);
12774           return -99;
12775         }
12776     }
12777
12778   if (sw_if_index_set == 0)
12779     {
12780       errmsg ("missing interface name or sw_if_index");
12781       return -99;
12782     }
12783
12784   M (INPUT_ACL_SET_INTERFACE, mp);
12785
12786   mp->sw_if_index = ntohl (sw_if_index);
12787   mp->ip4_table_index = ntohl (ip4_table_index);
12788   mp->ip6_table_index = ntohl (ip6_table_index);
12789   mp->l2_table_index = ntohl (l2_table_index);
12790   mp->is_add = is_add;
12791
12792   S (mp);
12793   W (ret);
12794   return ret;
12795 }
12796
12797 static int
12798 api_ip_address_dump (vat_main_t * vam)
12799 {
12800   unformat_input_t *i = vam->input;
12801   vl_api_ip_address_dump_t *mp;
12802   vl_api_control_ping_t *mp_ping;
12803   u32 sw_if_index = ~0;
12804   u8 sw_if_index_set = 0;
12805   u8 ipv4_set = 0;
12806   u8 ipv6_set = 0;
12807   int ret;
12808
12809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12810     {
12811       if (unformat (i, "sw_if_index %d", &sw_if_index))
12812         sw_if_index_set = 1;
12813       else
12814         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12815         sw_if_index_set = 1;
12816       else if (unformat (i, "ipv4"))
12817         ipv4_set = 1;
12818       else if (unformat (i, "ipv6"))
12819         ipv6_set = 1;
12820       else
12821         break;
12822     }
12823
12824   if (ipv4_set && ipv6_set)
12825     {
12826       errmsg ("ipv4 and ipv6 flags cannot be both set");
12827       return -99;
12828     }
12829
12830   if ((!ipv4_set) && (!ipv6_set))
12831     {
12832       errmsg ("no ipv4 nor ipv6 flag set");
12833       return -99;
12834     }
12835
12836   if (sw_if_index_set == 0)
12837     {
12838       errmsg ("missing interface name or sw_if_index");
12839       return -99;
12840     }
12841
12842   vam->current_sw_if_index = sw_if_index;
12843   vam->is_ipv6 = ipv6_set;
12844
12845   M (IP_ADDRESS_DUMP, mp);
12846   mp->sw_if_index = ntohl (sw_if_index);
12847   mp->is_ipv6 = ipv6_set;
12848   S (mp);
12849
12850   /* Use a control ping for synchronization */
12851   M (CONTROL_PING, mp_ping);
12852   S (mp_ping);
12853
12854   W (ret);
12855   return ret;
12856 }
12857
12858 static int
12859 api_ip_dump (vat_main_t * vam)
12860 {
12861   vl_api_ip_dump_t *mp;
12862   vl_api_control_ping_t *mp_ping;
12863   unformat_input_t *in = vam->input;
12864   int ipv4_set = 0;
12865   int ipv6_set = 0;
12866   int is_ipv6;
12867   int i;
12868   int ret;
12869
12870   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12871     {
12872       if (unformat (in, "ipv4"))
12873         ipv4_set = 1;
12874       else if (unformat (in, "ipv6"))
12875         ipv6_set = 1;
12876       else
12877         break;
12878     }
12879
12880   if (ipv4_set && ipv6_set)
12881     {
12882       errmsg ("ipv4 and ipv6 flags cannot be both set");
12883       return -99;
12884     }
12885
12886   if ((!ipv4_set) && (!ipv6_set))
12887     {
12888       errmsg ("no ipv4 nor ipv6 flag set");
12889       return -99;
12890     }
12891
12892   is_ipv6 = ipv6_set;
12893   vam->is_ipv6 = is_ipv6;
12894
12895   /* free old data */
12896   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12897     {
12898       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12899     }
12900   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12901
12902   M (IP_DUMP, mp);
12903   mp->is_ipv6 = ipv6_set;
12904   S (mp);
12905
12906   /* Use a control ping for synchronization */
12907   M (CONTROL_PING, mp_ping);
12908   S (mp_ping);
12909
12910   W (ret);
12911   return ret;
12912 }
12913
12914 static int
12915 api_ipsec_spd_add_del (vat_main_t * vam)
12916 {
12917   unformat_input_t *i = vam->input;
12918   vl_api_ipsec_spd_add_del_t *mp;
12919   u32 spd_id = ~0;
12920   u8 is_add = 1;
12921   int ret;
12922
12923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12924     {
12925       if (unformat (i, "spd_id %d", &spd_id))
12926         ;
12927       else if (unformat (i, "del"))
12928         is_add = 0;
12929       else
12930         {
12931           clib_warning ("parse error '%U'", format_unformat_error, i);
12932           return -99;
12933         }
12934     }
12935   if (spd_id == ~0)
12936     {
12937       errmsg ("spd_id must be set");
12938       return -99;
12939     }
12940
12941   M (IPSEC_SPD_ADD_DEL, mp);
12942
12943   mp->spd_id = ntohl (spd_id);
12944   mp->is_add = is_add;
12945
12946   S (mp);
12947   W (ret);
12948   return ret;
12949 }
12950
12951 static int
12952 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12953 {
12954   unformat_input_t *i = vam->input;
12955   vl_api_ipsec_interface_add_del_spd_t *mp;
12956   u32 sw_if_index;
12957   u8 sw_if_index_set = 0;
12958   u32 spd_id = (u32) ~ 0;
12959   u8 is_add = 1;
12960   int ret;
12961
12962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12963     {
12964       if (unformat (i, "del"))
12965         is_add = 0;
12966       else if (unformat (i, "spd_id %d", &spd_id))
12967         ;
12968       else
12969         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12970         sw_if_index_set = 1;
12971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12972         sw_if_index_set = 1;
12973       else
12974         {
12975           clib_warning ("parse error '%U'", format_unformat_error, i);
12976           return -99;
12977         }
12978
12979     }
12980
12981   if (spd_id == (u32) ~ 0)
12982     {
12983       errmsg ("spd_id must be set");
12984       return -99;
12985     }
12986
12987   if (sw_if_index_set == 0)
12988     {
12989       errmsg ("missing interface name or sw_if_index");
12990       return -99;
12991     }
12992
12993   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12994
12995   mp->spd_id = ntohl (spd_id);
12996   mp->sw_if_index = ntohl (sw_if_index);
12997   mp->is_add = is_add;
12998
12999   S (mp);
13000   W (ret);
13001   return ret;
13002 }
13003
13004 static int
13005 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13006 {
13007   unformat_input_t *i = vam->input;
13008   vl_api_ipsec_spd_add_del_entry_t *mp;
13009   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13010   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13011   i32 priority = 0;
13012   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13013   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13014   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13015   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13016   int ret;
13017
13018   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13019   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13020   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13021   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13022   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13023   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13024
13025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (i, "del"))
13028         is_add = 0;
13029       if (unformat (i, "outbound"))
13030         is_outbound = 1;
13031       if (unformat (i, "inbound"))
13032         is_outbound = 0;
13033       else if (unformat (i, "spd_id %d", &spd_id))
13034         ;
13035       else if (unformat (i, "sa_id %d", &sa_id))
13036         ;
13037       else if (unformat (i, "priority %d", &priority))
13038         ;
13039       else if (unformat (i, "protocol %d", &protocol))
13040         ;
13041       else if (unformat (i, "lport_start %d", &lport_start))
13042         ;
13043       else if (unformat (i, "lport_stop %d", &lport_stop))
13044         ;
13045       else if (unformat (i, "rport_start %d", &rport_start))
13046         ;
13047       else if (unformat (i, "rport_stop %d", &rport_stop))
13048         ;
13049       else
13050         if (unformat
13051             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13052         {
13053           is_ipv6 = 0;
13054           is_ip_any = 0;
13055         }
13056       else
13057         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13058         {
13059           is_ipv6 = 0;
13060           is_ip_any = 0;
13061         }
13062       else
13063         if (unformat
13064             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13065         {
13066           is_ipv6 = 0;
13067           is_ip_any = 0;
13068         }
13069       else
13070         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13071         {
13072           is_ipv6 = 0;
13073           is_ip_any = 0;
13074         }
13075       else
13076         if (unformat
13077             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13078         {
13079           is_ipv6 = 1;
13080           is_ip_any = 0;
13081         }
13082       else
13083         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13084         {
13085           is_ipv6 = 1;
13086           is_ip_any = 0;
13087         }
13088       else
13089         if (unformat
13090             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13091         {
13092           is_ipv6 = 1;
13093           is_ip_any = 0;
13094         }
13095       else
13096         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13097         {
13098           is_ipv6 = 1;
13099           is_ip_any = 0;
13100         }
13101       else
13102         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13103         {
13104           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13105             {
13106               clib_warning ("unsupported action: 'resolve'");
13107               return -99;
13108             }
13109         }
13110       else
13111         {
13112           clib_warning ("parse error '%U'", format_unformat_error, i);
13113           return -99;
13114         }
13115
13116     }
13117
13118   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13119
13120   mp->spd_id = ntohl (spd_id);
13121   mp->priority = ntohl (priority);
13122   mp->is_outbound = is_outbound;
13123
13124   mp->is_ipv6 = is_ipv6;
13125   if (is_ipv6 || is_ip_any)
13126     {
13127       clib_memcpy (mp->remote_address_start, &raddr6_start,
13128                    sizeof (ip6_address_t));
13129       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13130                    sizeof (ip6_address_t));
13131       clib_memcpy (mp->local_address_start, &laddr6_start,
13132                    sizeof (ip6_address_t));
13133       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13134                    sizeof (ip6_address_t));
13135     }
13136   else
13137     {
13138       clib_memcpy (mp->remote_address_start, &raddr4_start,
13139                    sizeof (ip4_address_t));
13140       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13141                    sizeof (ip4_address_t));
13142       clib_memcpy (mp->local_address_start, &laddr4_start,
13143                    sizeof (ip4_address_t));
13144       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13145                    sizeof (ip4_address_t));
13146     }
13147   mp->protocol = (u8) protocol;
13148   mp->local_port_start = ntohs ((u16) lport_start);
13149   mp->local_port_stop = ntohs ((u16) lport_stop);
13150   mp->remote_port_start = ntohs ((u16) rport_start);
13151   mp->remote_port_stop = ntohs ((u16) rport_stop);
13152   mp->policy = (u8) policy;
13153   mp->sa_id = ntohl (sa_id);
13154   mp->is_add = is_add;
13155   mp->is_ip_any = is_ip_any;
13156   S (mp);
13157   W (ret);
13158   return ret;
13159 }
13160
13161 static int
13162 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13163 {
13164   unformat_input_t *i = vam->input;
13165   vl_api_ipsec_sad_add_del_entry_t *mp;
13166   u32 sad_id = 0, spi = 0;
13167   u8 *ck = 0, *ik = 0;
13168   u8 is_add = 1;
13169
13170   u8 protocol = IPSEC_PROTOCOL_AH;
13171   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13172   u32 crypto_alg = 0, integ_alg = 0;
13173   ip4_address_t tun_src4;
13174   ip4_address_t tun_dst4;
13175   ip6_address_t tun_src6;
13176   ip6_address_t tun_dst6;
13177   int ret;
13178
13179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13180     {
13181       if (unformat (i, "del"))
13182         is_add = 0;
13183       else if (unformat (i, "sad_id %d", &sad_id))
13184         ;
13185       else if (unformat (i, "spi %d", &spi))
13186         ;
13187       else if (unformat (i, "esp"))
13188         protocol = IPSEC_PROTOCOL_ESP;
13189       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13190         {
13191           is_tunnel = 1;
13192           is_tunnel_ipv6 = 0;
13193         }
13194       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13195         {
13196           is_tunnel = 1;
13197           is_tunnel_ipv6 = 0;
13198         }
13199       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13200         {
13201           is_tunnel = 1;
13202           is_tunnel_ipv6 = 1;
13203         }
13204       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13205         {
13206           is_tunnel = 1;
13207           is_tunnel_ipv6 = 1;
13208         }
13209       else
13210         if (unformat
13211             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13212         {
13213           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13214               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13215             {
13216               clib_warning ("unsupported crypto-alg: '%U'",
13217                             format_ipsec_crypto_alg, crypto_alg);
13218               return -99;
13219             }
13220         }
13221       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13222         ;
13223       else
13224         if (unformat
13225             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13226         {
13227           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13228               integ_alg >= IPSEC_INTEG_N_ALG)
13229             {
13230               clib_warning ("unsupported integ-alg: '%U'",
13231                             format_ipsec_integ_alg, integ_alg);
13232               return -99;
13233             }
13234         }
13235       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13236         ;
13237       else
13238         {
13239           clib_warning ("parse error '%U'", format_unformat_error, i);
13240           return -99;
13241         }
13242
13243     }
13244
13245   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13246
13247   mp->sad_id = ntohl (sad_id);
13248   mp->is_add = is_add;
13249   mp->protocol = protocol;
13250   mp->spi = ntohl (spi);
13251   mp->is_tunnel = is_tunnel;
13252   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13253   mp->crypto_algorithm = crypto_alg;
13254   mp->integrity_algorithm = integ_alg;
13255   mp->crypto_key_length = vec_len (ck);
13256   mp->integrity_key_length = vec_len (ik);
13257
13258   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13259     mp->crypto_key_length = sizeof (mp->crypto_key);
13260
13261   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13262     mp->integrity_key_length = sizeof (mp->integrity_key);
13263
13264   if (ck)
13265     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13266   if (ik)
13267     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13268
13269   if (is_tunnel)
13270     {
13271       if (is_tunnel_ipv6)
13272         {
13273           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13274                        sizeof (ip6_address_t));
13275           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13276                        sizeof (ip6_address_t));
13277         }
13278       else
13279         {
13280           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13281                        sizeof (ip4_address_t));
13282           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13283                        sizeof (ip4_address_t));
13284         }
13285     }
13286
13287   S (mp);
13288   W (ret);
13289   return ret;
13290 }
13291
13292 static int
13293 api_ipsec_sa_set_key (vat_main_t * vam)
13294 {
13295   unformat_input_t *i = vam->input;
13296   vl_api_ipsec_sa_set_key_t *mp;
13297   u32 sa_id;
13298   u8 *ck = 0, *ik = 0;
13299   int ret;
13300
13301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13302     {
13303       if (unformat (i, "sa_id %d", &sa_id))
13304         ;
13305       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13306         ;
13307       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13308         ;
13309       else
13310         {
13311           clib_warning ("parse error '%U'", format_unformat_error, i);
13312           return -99;
13313         }
13314     }
13315
13316   M (IPSEC_SA_SET_KEY, mp);
13317
13318   mp->sa_id = ntohl (sa_id);
13319   mp->crypto_key_length = vec_len (ck);
13320   mp->integrity_key_length = vec_len (ik);
13321
13322   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13323     mp->crypto_key_length = sizeof (mp->crypto_key);
13324
13325   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13326     mp->integrity_key_length = sizeof (mp->integrity_key);
13327
13328   if (ck)
13329     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13330   if (ik)
13331     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13332
13333   S (mp);
13334   W (ret);
13335   return ret;
13336 }
13337
13338 static int
13339 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13340 {
13341   unformat_input_t *i = vam->input;
13342   vl_api_ipsec_tunnel_if_add_del_t *mp;
13343   u32 local_spi = 0, remote_spi = 0;
13344   u32 crypto_alg = 0, integ_alg = 0;
13345   u8 *lck = NULL, *rck = NULL;
13346   u8 *lik = NULL, *rik = NULL;
13347   ip4_address_t local_ip = { {0} };
13348   ip4_address_t remote_ip = { {0} };
13349   u8 is_add = 1;
13350   u8 esn = 0;
13351   u8 anti_replay = 0;
13352   int ret;
13353
13354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13355     {
13356       if (unformat (i, "del"))
13357         is_add = 0;
13358       else if (unformat (i, "esn"))
13359         esn = 1;
13360       else if (unformat (i, "anti_replay"))
13361         anti_replay = 1;
13362       else if (unformat (i, "local_spi %d", &local_spi))
13363         ;
13364       else if (unformat (i, "remote_spi %d", &remote_spi))
13365         ;
13366       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13367         ;
13368       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13369         ;
13370       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13371         ;
13372       else
13373         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13374         ;
13375       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13376         ;
13377       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13378         ;
13379       else
13380         if (unformat
13381             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13382         {
13383           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13384               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13385             {
13386               errmsg ("unsupported crypto-alg: '%U'\n",
13387                       format_ipsec_crypto_alg, crypto_alg);
13388               return -99;
13389             }
13390         }
13391       else
13392         if (unformat
13393             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13394         {
13395           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13396               integ_alg >= IPSEC_INTEG_N_ALG)
13397             {
13398               errmsg ("unsupported integ-alg: '%U'\n",
13399                       format_ipsec_integ_alg, integ_alg);
13400               return -99;
13401             }
13402         }
13403       else
13404         {
13405           errmsg ("parse error '%U'\n", format_unformat_error, i);
13406           return -99;
13407         }
13408     }
13409
13410   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13411
13412   mp->is_add = is_add;
13413   mp->esn = esn;
13414   mp->anti_replay = anti_replay;
13415
13416   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13417   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13418
13419   mp->local_spi = htonl (local_spi);
13420   mp->remote_spi = htonl (remote_spi);
13421   mp->crypto_alg = (u8) crypto_alg;
13422
13423   mp->local_crypto_key_len = 0;
13424   if (lck)
13425     {
13426       mp->local_crypto_key_len = vec_len (lck);
13427       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13428         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13429       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13430     }
13431
13432   mp->remote_crypto_key_len = 0;
13433   if (rck)
13434     {
13435       mp->remote_crypto_key_len = vec_len (rck);
13436       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13437         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13438       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13439     }
13440
13441   mp->integ_alg = (u8) integ_alg;
13442
13443   mp->local_integ_key_len = 0;
13444   if (lik)
13445     {
13446       mp->local_integ_key_len = vec_len (lik);
13447       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13448         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13449       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13450     }
13451
13452   mp->remote_integ_key_len = 0;
13453   if (rik)
13454     {
13455       mp->remote_integ_key_len = vec_len (rik);
13456       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13457         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13458       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13459     }
13460
13461   S (mp);
13462   W (ret);
13463   return ret;
13464 }
13465
13466 static int
13467 api_ikev2_profile_add_del (vat_main_t * vam)
13468 {
13469   unformat_input_t *i = vam->input;
13470   vl_api_ikev2_profile_add_del_t *mp;
13471   u8 is_add = 1;
13472   u8 *name = 0;
13473   int ret;
13474
13475   const char *valid_chars = "a-zA-Z0-9_";
13476
13477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13478     {
13479       if (unformat (i, "del"))
13480         is_add = 0;
13481       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13482         vec_add1 (name, 0);
13483       else
13484         {
13485           errmsg ("parse error '%U'", format_unformat_error, i);
13486           return -99;
13487         }
13488     }
13489
13490   if (!vec_len (name))
13491     {
13492       errmsg ("profile name must be specified");
13493       return -99;
13494     }
13495
13496   if (vec_len (name) > 64)
13497     {
13498       errmsg ("profile name too long");
13499       return -99;
13500     }
13501
13502   M (IKEV2_PROFILE_ADD_DEL, mp);
13503
13504   clib_memcpy (mp->name, name, vec_len (name));
13505   mp->is_add = is_add;
13506   vec_free (name);
13507
13508   S (mp);
13509   W (ret);
13510   return ret;
13511 }
13512
13513 static int
13514 api_ikev2_profile_set_auth (vat_main_t * vam)
13515 {
13516   unformat_input_t *i = vam->input;
13517   vl_api_ikev2_profile_set_auth_t *mp;
13518   u8 *name = 0;
13519   u8 *data = 0;
13520   u32 auth_method = 0;
13521   u8 is_hex = 0;
13522   int ret;
13523
13524   const char *valid_chars = "a-zA-Z0-9_";
13525
13526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13527     {
13528       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13529         vec_add1 (name, 0);
13530       else if (unformat (i, "auth_method %U",
13531                          unformat_ikev2_auth_method, &auth_method))
13532         ;
13533       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13534         is_hex = 1;
13535       else if (unformat (i, "auth_data %v", &data))
13536         ;
13537       else
13538         {
13539           errmsg ("parse error '%U'", format_unformat_error, i);
13540           return -99;
13541         }
13542     }
13543
13544   if (!vec_len (name))
13545     {
13546       errmsg ("profile name must be specified");
13547       return -99;
13548     }
13549
13550   if (vec_len (name) > 64)
13551     {
13552       errmsg ("profile name too long");
13553       return -99;
13554     }
13555
13556   if (!vec_len (data))
13557     {
13558       errmsg ("auth_data must be specified");
13559       return -99;
13560     }
13561
13562   if (!auth_method)
13563     {
13564       errmsg ("auth_method must be specified");
13565       return -99;
13566     }
13567
13568   M (IKEV2_PROFILE_SET_AUTH, mp);
13569
13570   mp->is_hex = is_hex;
13571   mp->auth_method = (u8) auth_method;
13572   mp->data_len = vec_len (data);
13573   clib_memcpy (mp->name, name, vec_len (name));
13574   clib_memcpy (mp->data, data, vec_len (data));
13575   vec_free (name);
13576   vec_free (data);
13577
13578   S (mp);
13579   W (ret);
13580   return ret;
13581 }
13582
13583 static int
13584 api_ikev2_profile_set_id (vat_main_t * vam)
13585 {
13586   unformat_input_t *i = vam->input;
13587   vl_api_ikev2_profile_set_id_t *mp;
13588   u8 *name = 0;
13589   u8 *data = 0;
13590   u8 is_local = 0;
13591   u32 id_type = 0;
13592   ip4_address_t ip4;
13593   int ret;
13594
13595   const char *valid_chars = "a-zA-Z0-9_";
13596
13597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13598     {
13599       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13600         vec_add1 (name, 0);
13601       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13602         ;
13603       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13604         {
13605           data = vec_new (u8, 4);
13606           clib_memcpy (data, ip4.as_u8, 4);
13607         }
13608       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13609         ;
13610       else if (unformat (i, "id_data %v", &data))
13611         ;
13612       else if (unformat (i, "local"))
13613         is_local = 1;
13614       else if (unformat (i, "remote"))
13615         is_local = 0;
13616       else
13617         {
13618           errmsg ("parse error '%U'", format_unformat_error, i);
13619           return -99;
13620         }
13621     }
13622
13623   if (!vec_len (name))
13624     {
13625       errmsg ("profile name must be specified");
13626       return -99;
13627     }
13628
13629   if (vec_len (name) > 64)
13630     {
13631       errmsg ("profile name too long");
13632       return -99;
13633     }
13634
13635   if (!vec_len (data))
13636     {
13637       errmsg ("id_data must be specified");
13638       return -99;
13639     }
13640
13641   if (!id_type)
13642     {
13643       errmsg ("id_type must be specified");
13644       return -99;
13645     }
13646
13647   M (IKEV2_PROFILE_SET_ID, mp);
13648
13649   mp->is_local = is_local;
13650   mp->id_type = (u8) id_type;
13651   mp->data_len = vec_len (data);
13652   clib_memcpy (mp->name, name, vec_len (name));
13653   clib_memcpy (mp->data, data, vec_len (data));
13654   vec_free (name);
13655   vec_free (data);
13656
13657   S (mp);
13658   W (ret);
13659   return ret;
13660 }
13661
13662 static int
13663 api_ikev2_profile_set_ts (vat_main_t * vam)
13664 {
13665   unformat_input_t *i = vam->input;
13666   vl_api_ikev2_profile_set_ts_t *mp;
13667   u8 *name = 0;
13668   u8 is_local = 0;
13669   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13670   ip4_address_t start_addr, end_addr;
13671
13672   const char *valid_chars = "a-zA-Z0-9_";
13673   int ret;
13674
13675   start_addr.as_u32 = 0;
13676   end_addr.as_u32 = (u32) ~ 0;
13677
13678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13679     {
13680       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13681         vec_add1 (name, 0);
13682       else if (unformat (i, "protocol %d", &proto))
13683         ;
13684       else if (unformat (i, "start_port %d", &start_port))
13685         ;
13686       else if (unformat (i, "end_port %d", &end_port))
13687         ;
13688       else
13689         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13690         ;
13691       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13692         ;
13693       else if (unformat (i, "local"))
13694         is_local = 1;
13695       else if (unformat (i, "remote"))
13696         is_local = 0;
13697       else
13698         {
13699           errmsg ("parse error '%U'", format_unformat_error, i);
13700           return -99;
13701         }
13702     }
13703
13704   if (!vec_len (name))
13705     {
13706       errmsg ("profile name must be specified");
13707       return -99;
13708     }
13709
13710   if (vec_len (name) > 64)
13711     {
13712       errmsg ("profile name too long");
13713       return -99;
13714     }
13715
13716   M (IKEV2_PROFILE_SET_TS, mp);
13717
13718   mp->is_local = is_local;
13719   mp->proto = (u8) proto;
13720   mp->start_port = (u16) start_port;
13721   mp->end_port = (u16) end_port;
13722   mp->start_addr = start_addr.as_u32;
13723   mp->end_addr = end_addr.as_u32;
13724   clib_memcpy (mp->name, name, vec_len (name));
13725   vec_free (name);
13726
13727   S (mp);
13728   W (ret);
13729   return ret;
13730 }
13731
13732 static int
13733 api_ikev2_set_local_key (vat_main_t * vam)
13734 {
13735   unformat_input_t *i = vam->input;
13736   vl_api_ikev2_set_local_key_t *mp;
13737   u8 *file = 0;
13738   int ret;
13739
13740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13741     {
13742       if (unformat (i, "file %v", &file))
13743         vec_add1 (file, 0);
13744       else
13745         {
13746           errmsg ("parse error '%U'", format_unformat_error, i);
13747           return -99;
13748         }
13749     }
13750
13751   if (!vec_len (file))
13752     {
13753       errmsg ("RSA key file must be specified");
13754       return -99;
13755     }
13756
13757   if (vec_len (file) > 256)
13758     {
13759       errmsg ("file name too long");
13760       return -99;
13761     }
13762
13763   M (IKEV2_SET_LOCAL_KEY, mp);
13764
13765   clib_memcpy (mp->key_file, file, vec_len (file));
13766   vec_free (file);
13767
13768   S (mp);
13769   W (ret);
13770   return ret;
13771 }
13772
13773 static int
13774 api_ikev2_set_responder (vat_main_t * vam)
13775 {
13776   unformat_input_t *i = vam->input;
13777   vl_api_ikev2_set_responder_t *mp;
13778   int ret;
13779   u8 *name = 0;
13780   u32 sw_if_index = ~0;
13781   ip4_address_t address;
13782
13783   const char *valid_chars = "a-zA-Z0-9_";
13784
13785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13786     {
13787       if (unformat
13788           (i, "%U interface %d address %U", unformat_token, valid_chars,
13789            &name, &sw_if_index, unformat_ip4_address, &address))
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_RESPONDER, mp);
13811
13812   clib_memcpy (mp->name, name, vec_len (name));
13813   vec_free (name);
13814
13815   mp->sw_if_index = sw_if_index;
13816   clib_memcpy (mp->address, &address, sizeof (address));
13817
13818   S (mp);
13819   W (ret);
13820   return ret;
13821 }
13822
13823 static int
13824 api_ikev2_set_ike_transforms (vat_main_t * vam)
13825 {
13826   unformat_input_t *i = vam->input;
13827   vl_api_ikev2_set_ike_transforms_t *mp;
13828   int ret;
13829   u8 *name = 0;
13830   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13831
13832   const char *valid_chars = "a-zA-Z0-9_";
13833
13834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13835     {
13836       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13837                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13838         vec_add1 (name, 0);
13839       else
13840         {
13841           errmsg ("parse error '%U'", format_unformat_error, i);
13842           return -99;
13843         }
13844     }
13845
13846   if (!vec_len (name))
13847     {
13848       errmsg ("profile name must be specified");
13849       return -99;
13850     }
13851
13852   if (vec_len (name) > 64)
13853     {
13854       errmsg ("profile name too long");
13855       return -99;
13856     }
13857
13858   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13859
13860   clib_memcpy (mp->name, name, vec_len (name));
13861   vec_free (name);
13862   mp->crypto_alg = crypto_alg;
13863   mp->crypto_key_size = crypto_key_size;
13864   mp->integ_alg = integ_alg;
13865   mp->dh_group = dh_group;
13866
13867   S (mp);
13868   W (ret);
13869   return ret;
13870 }
13871
13872
13873 static int
13874 api_ikev2_set_esp_transforms (vat_main_t * vam)
13875 {
13876   unformat_input_t *i = vam->input;
13877   vl_api_ikev2_set_esp_transforms_t *mp;
13878   int ret;
13879   u8 *name = 0;
13880   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13881
13882   const char *valid_chars = "a-zA-Z0-9_";
13883
13884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13885     {
13886       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13887                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
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_SET_ESP_TRANSFORMS, mp);
13909
13910   clib_memcpy (mp->name, name, vec_len (name));
13911   vec_free (name);
13912   mp->crypto_alg = crypto_alg;
13913   mp->crypto_key_size = crypto_key_size;
13914   mp->integ_alg = integ_alg;
13915   mp->dh_group = dh_group;
13916
13917   S (mp);
13918   W (ret);
13919   return ret;
13920 }
13921
13922 static int
13923 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13924 {
13925   unformat_input_t *i = vam->input;
13926   vl_api_ikev2_set_sa_lifetime_t *mp;
13927   int ret;
13928   u8 *name = 0;
13929   u64 lifetime, lifetime_maxdata;
13930   u32 lifetime_jitter, handover;
13931
13932   const char *valid_chars = "a-zA-Z0-9_";
13933
13934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13935     {
13936       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13937                     &lifetime, &lifetime_jitter, &handover,
13938                     &lifetime_maxdata))
13939         vec_add1 (name, 0);
13940       else
13941         {
13942           errmsg ("parse error '%U'", format_unformat_error, i);
13943           return -99;
13944         }
13945     }
13946
13947   if (!vec_len (name))
13948     {
13949       errmsg ("profile name must be specified");
13950       return -99;
13951     }
13952
13953   if (vec_len (name) > 64)
13954     {
13955       errmsg ("profile name too long");
13956       return -99;
13957     }
13958
13959   M (IKEV2_SET_SA_LIFETIME, mp);
13960
13961   clib_memcpy (mp->name, name, vec_len (name));
13962   vec_free (name);
13963   mp->lifetime = lifetime;
13964   mp->lifetime_jitter = lifetime_jitter;
13965   mp->handover = handover;
13966   mp->lifetime_maxdata = lifetime_maxdata;
13967
13968   S (mp);
13969   W (ret);
13970   return ret;
13971 }
13972
13973 static int
13974 api_ikev2_initiate_sa_init (vat_main_t * vam)
13975 {
13976   unformat_input_t *i = vam->input;
13977   vl_api_ikev2_initiate_sa_init_t *mp;
13978   int ret;
13979   u8 *name = 0;
13980
13981   const char *valid_chars = "a-zA-Z0-9_";
13982
13983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13984     {
13985       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13986         vec_add1 (name, 0);
13987       else
13988         {
13989           errmsg ("parse error '%U'", format_unformat_error, i);
13990           return -99;
13991         }
13992     }
13993
13994   if (!vec_len (name))
13995     {
13996       errmsg ("profile name must be specified");
13997       return -99;
13998     }
13999
14000   if (vec_len (name) > 64)
14001     {
14002       errmsg ("profile name too long");
14003       return -99;
14004     }
14005
14006   M (IKEV2_INITIATE_SA_INIT, mp);
14007
14008   clib_memcpy (mp->name, name, vec_len (name));
14009   vec_free (name);
14010
14011   S (mp);
14012   W (ret);
14013   return ret;
14014 }
14015
14016 static int
14017 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14018 {
14019   unformat_input_t *i = vam->input;
14020   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14021   int ret;
14022   u64 ispi;
14023
14024
14025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14026     {
14027       if (unformat (i, "%lx", &ispi))
14028         ;
14029       else
14030         {
14031           errmsg ("parse error '%U'", format_unformat_error, i);
14032           return -99;
14033         }
14034     }
14035
14036   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14037
14038   mp->ispi = ispi;
14039
14040   S (mp);
14041   W (ret);
14042   return ret;
14043 }
14044
14045 static int
14046 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14047 {
14048   unformat_input_t *i = vam->input;
14049   vl_api_ikev2_initiate_del_child_sa_t *mp;
14050   int ret;
14051   u32 ispi;
14052
14053
14054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14055     {
14056       if (unformat (i, "%x", &ispi))
14057         ;
14058       else
14059         {
14060           errmsg ("parse error '%U'", format_unformat_error, i);
14061           return -99;
14062         }
14063     }
14064
14065   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14066
14067   mp->ispi = ispi;
14068
14069   S (mp);
14070   W (ret);
14071   return ret;
14072 }
14073
14074 static int
14075 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14076 {
14077   unformat_input_t *i = vam->input;
14078   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14079   int ret;
14080   u32 ispi;
14081
14082
14083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14084     {
14085       if (unformat (i, "%x", &ispi))
14086         ;
14087       else
14088         {
14089           errmsg ("parse error '%U'", format_unformat_error, i);
14090           return -99;
14091         }
14092     }
14093
14094   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14095
14096   mp->ispi = ispi;
14097
14098   S (mp);
14099   W (ret);
14100   return ret;
14101 }
14102
14103 /*
14104  * MAP
14105  */
14106 static int
14107 api_map_add_domain (vat_main_t * vam)
14108 {
14109   unformat_input_t *i = vam->input;
14110   vl_api_map_add_domain_t *mp;
14111
14112   ip4_address_t ip4_prefix;
14113   ip6_address_t ip6_prefix;
14114   ip6_address_t ip6_src;
14115   u32 num_m_args = 0;
14116   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14117     0, psid_length = 0;
14118   u8 is_translation = 0;
14119   u32 mtu = 0;
14120   u32 ip6_src_len = 128;
14121   int ret;
14122
14123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14124     {
14125       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14126                     &ip4_prefix, &ip4_prefix_len))
14127         num_m_args++;
14128       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14129                          &ip6_prefix, &ip6_prefix_len))
14130         num_m_args++;
14131       else
14132         if (unformat
14133             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14134              &ip6_src_len))
14135         num_m_args++;
14136       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14137         num_m_args++;
14138       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14139         num_m_args++;
14140       else if (unformat (i, "psid-offset %d", &psid_offset))
14141         num_m_args++;
14142       else if (unformat (i, "psid-len %d", &psid_length))
14143         num_m_args++;
14144       else if (unformat (i, "mtu %d", &mtu))
14145         num_m_args++;
14146       else if (unformat (i, "map-t"))
14147         is_translation = 1;
14148       else
14149         {
14150           clib_warning ("parse error '%U'", format_unformat_error, i);
14151           return -99;
14152         }
14153     }
14154
14155   if (num_m_args < 3)
14156     {
14157       errmsg ("mandatory argument(s) missing");
14158       return -99;
14159     }
14160
14161   /* Construct the API message */
14162   M (MAP_ADD_DOMAIN, mp);
14163
14164   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14165   mp->ip4_prefix_len = ip4_prefix_len;
14166
14167   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14168   mp->ip6_prefix_len = ip6_prefix_len;
14169
14170   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14171   mp->ip6_src_prefix_len = ip6_src_len;
14172
14173   mp->ea_bits_len = ea_bits_len;
14174   mp->psid_offset = psid_offset;
14175   mp->psid_length = psid_length;
14176   mp->is_translation = is_translation;
14177   mp->mtu = htons (mtu);
14178
14179   /* send it... */
14180   S (mp);
14181
14182   /* Wait for a reply, return good/bad news  */
14183   W (ret);
14184   return ret;
14185 }
14186
14187 static int
14188 api_map_del_domain (vat_main_t * vam)
14189 {
14190   unformat_input_t *i = vam->input;
14191   vl_api_map_del_domain_t *mp;
14192
14193   u32 num_m_args = 0;
14194   u32 index;
14195   int ret;
14196
14197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14198     {
14199       if (unformat (i, "index %d", &index))
14200         num_m_args++;
14201       else
14202         {
14203           clib_warning ("parse error '%U'", format_unformat_error, i);
14204           return -99;
14205         }
14206     }
14207
14208   if (num_m_args != 1)
14209     {
14210       errmsg ("mandatory argument(s) missing");
14211       return -99;
14212     }
14213
14214   /* Construct the API message */
14215   M (MAP_DEL_DOMAIN, mp);
14216
14217   mp->index = ntohl (index);
14218
14219   /* send it... */
14220   S (mp);
14221
14222   /* Wait for a reply, return good/bad news  */
14223   W (ret);
14224   return ret;
14225 }
14226
14227 static int
14228 api_map_add_del_rule (vat_main_t * vam)
14229 {
14230   unformat_input_t *i = vam->input;
14231   vl_api_map_add_del_rule_t *mp;
14232   u8 is_add = 1;
14233   ip6_address_t ip6_dst;
14234   u32 num_m_args = 0, index, psid = 0;
14235   int ret;
14236
14237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14238     {
14239       if (unformat (i, "index %d", &index))
14240         num_m_args++;
14241       else if (unformat (i, "psid %d", &psid))
14242         num_m_args++;
14243       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14244         num_m_args++;
14245       else if (unformat (i, "del"))
14246         {
14247           is_add = 0;
14248         }
14249       else
14250         {
14251           clib_warning ("parse error '%U'", format_unformat_error, i);
14252           return -99;
14253         }
14254     }
14255
14256   /* Construct the API message */
14257   M (MAP_ADD_DEL_RULE, mp);
14258
14259   mp->index = ntohl (index);
14260   mp->is_add = is_add;
14261   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14262   mp->psid = ntohs (psid);
14263
14264   /* send it... */
14265   S (mp);
14266
14267   /* Wait for a reply, return good/bad news  */
14268   W (ret);
14269   return ret;
14270 }
14271
14272 static int
14273 api_map_domain_dump (vat_main_t * vam)
14274 {
14275   vl_api_map_domain_dump_t *mp;
14276   vl_api_control_ping_t *mp_ping;
14277   int ret;
14278
14279   /* Construct the API message */
14280   M (MAP_DOMAIN_DUMP, mp);
14281
14282   /* send it... */
14283   S (mp);
14284
14285   /* Use a control ping for synchronization */
14286   M (CONTROL_PING, mp_ping);
14287   S (mp_ping);
14288
14289   W (ret);
14290   return ret;
14291 }
14292
14293 static int
14294 api_map_rule_dump (vat_main_t * vam)
14295 {
14296   unformat_input_t *i = vam->input;
14297   vl_api_map_rule_dump_t *mp;
14298   vl_api_control_ping_t *mp_ping;
14299   u32 domain_index = ~0;
14300   int ret;
14301
14302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14303     {
14304       if (unformat (i, "index %u", &domain_index))
14305         ;
14306       else
14307         break;
14308     }
14309
14310   if (domain_index == ~0)
14311     {
14312       clib_warning ("parse error: domain index expected");
14313       return -99;
14314     }
14315
14316   /* Construct the API message */
14317   M (MAP_RULE_DUMP, mp);
14318
14319   mp->domain_index = htonl (domain_index);
14320
14321   /* send it... */
14322   S (mp);
14323
14324   /* Use a control ping for synchronization */
14325   M (CONTROL_PING, mp_ping);
14326   S (mp_ping);
14327
14328   W (ret);
14329   return ret;
14330 }
14331
14332 static void vl_api_map_add_domain_reply_t_handler
14333   (vl_api_map_add_domain_reply_t * mp)
14334 {
14335   vat_main_t *vam = &vat_main;
14336   i32 retval = ntohl (mp->retval);
14337
14338   if (vam->async_mode)
14339     {
14340       vam->async_errors += (retval < 0);
14341     }
14342   else
14343     {
14344       vam->retval = retval;
14345       vam->result_ready = 1;
14346     }
14347 }
14348
14349 static void vl_api_map_add_domain_reply_t_handler_json
14350   (vl_api_map_add_domain_reply_t * mp)
14351 {
14352   vat_main_t *vam = &vat_main;
14353   vat_json_node_t node;
14354
14355   vat_json_init_object (&node);
14356   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14357   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14358
14359   vat_json_print (vam->ofp, &node);
14360   vat_json_free (&node);
14361
14362   vam->retval = ntohl (mp->retval);
14363   vam->result_ready = 1;
14364 }
14365
14366 static int
14367 api_get_first_msg_id (vat_main_t * vam)
14368 {
14369   vl_api_get_first_msg_id_t *mp;
14370   unformat_input_t *i = vam->input;
14371   u8 *name;
14372   u8 name_set = 0;
14373   int ret;
14374
14375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14376     {
14377       if (unformat (i, "client %s", &name))
14378         name_set = 1;
14379       else
14380         break;
14381     }
14382
14383   if (name_set == 0)
14384     {
14385       errmsg ("missing client name");
14386       return -99;
14387     }
14388   vec_add1 (name, 0);
14389
14390   if (vec_len (name) > 63)
14391     {
14392       errmsg ("client name too long");
14393       return -99;
14394     }
14395
14396   M (GET_FIRST_MSG_ID, mp);
14397   clib_memcpy (mp->name, name, vec_len (name));
14398   S (mp);
14399   W (ret);
14400   return ret;
14401 }
14402
14403 static int
14404 api_cop_interface_enable_disable (vat_main_t * vam)
14405 {
14406   unformat_input_t *line_input = vam->input;
14407   vl_api_cop_interface_enable_disable_t *mp;
14408   u32 sw_if_index = ~0;
14409   u8 enable_disable = 1;
14410   int ret;
14411
14412   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14413     {
14414       if (unformat (line_input, "disable"))
14415         enable_disable = 0;
14416       if (unformat (line_input, "enable"))
14417         enable_disable = 1;
14418       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14419                          vam, &sw_if_index))
14420         ;
14421       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14422         ;
14423       else
14424         break;
14425     }
14426
14427   if (sw_if_index == ~0)
14428     {
14429       errmsg ("missing interface name or sw_if_index");
14430       return -99;
14431     }
14432
14433   /* Construct the API message */
14434   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14435   mp->sw_if_index = ntohl (sw_if_index);
14436   mp->enable_disable = enable_disable;
14437
14438   /* send it... */
14439   S (mp);
14440   /* Wait for the reply */
14441   W (ret);
14442   return ret;
14443 }
14444
14445 static int
14446 api_cop_whitelist_enable_disable (vat_main_t * vam)
14447 {
14448   unformat_input_t *line_input = vam->input;
14449   vl_api_cop_whitelist_enable_disable_t *mp;
14450   u32 sw_if_index = ~0;
14451   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14452   u32 fib_id = 0;
14453   int ret;
14454
14455   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14456     {
14457       if (unformat (line_input, "ip4"))
14458         ip4 = 1;
14459       else if (unformat (line_input, "ip6"))
14460         ip6 = 1;
14461       else if (unformat (line_input, "default"))
14462         default_cop = 1;
14463       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14464                          vam, &sw_if_index))
14465         ;
14466       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14467         ;
14468       else if (unformat (line_input, "fib-id %d", &fib_id))
14469         ;
14470       else
14471         break;
14472     }
14473
14474   if (sw_if_index == ~0)
14475     {
14476       errmsg ("missing interface name or sw_if_index");
14477       return -99;
14478     }
14479
14480   /* Construct the API message */
14481   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14482   mp->sw_if_index = ntohl (sw_if_index);
14483   mp->fib_id = ntohl (fib_id);
14484   mp->ip4 = ip4;
14485   mp->ip6 = ip6;
14486   mp->default_cop = default_cop;
14487
14488   /* send it... */
14489   S (mp);
14490   /* Wait for the reply */
14491   W (ret);
14492   return ret;
14493 }
14494
14495 static int
14496 api_get_node_graph (vat_main_t * vam)
14497 {
14498   vl_api_get_node_graph_t *mp;
14499   int ret;
14500
14501   M (GET_NODE_GRAPH, mp);
14502
14503   /* send it... */
14504   S (mp);
14505   /* Wait for the reply */
14506   W (ret);
14507   return ret;
14508 }
14509
14510 /* *INDENT-OFF* */
14511 /** Used for parsing LISP eids */
14512 typedef CLIB_PACKED(struct{
14513   u8 addr[16];   /**< eid address */
14514   u32 len;       /**< prefix length if IP */
14515   u8 type;      /**< type of eid */
14516 }) lisp_eid_vat_t;
14517 /* *INDENT-ON* */
14518
14519 static uword
14520 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14521 {
14522   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14523
14524   memset (a, 0, sizeof (a[0]));
14525
14526   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14527     {
14528       a->type = 0;              /* ipv4 type */
14529     }
14530   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14531     {
14532       a->type = 1;              /* ipv6 type */
14533     }
14534   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14535     {
14536       a->type = 2;              /* mac type */
14537     }
14538   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14539     {
14540       a->type = 3;              /* NSH type */
14541       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14542       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14543     }
14544   else
14545     {
14546       return 0;
14547     }
14548
14549   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14550     {
14551       return 0;
14552     }
14553
14554   return 1;
14555 }
14556
14557 static int
14558 lisp_eid_size_vat (u8 type)
14559 {
14560   switch (type)
14561     {
14562     case 0:
14563       return 4;
14564     case 1:
14565       return 16;
14566     case 2:
14567       return 6;
14568     case 3:
14569       return 5;
14570     }
14571   return 0;
14572 }
14573
14574 static void
14575 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14576 {
14577   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14578 }
14579
14580 static int
14581 api_one_add_del_locator_set (vat_main_t * vam)
14582 {
14583   unformat_input_t *input = vam->input;
14584   vl_api_one_add_del_locator_set_t *mp;
14585   u8 is_add = 1;
14586   u8 *locator_set_name = NULL;
14587   u8 locator_set_name_set = 0;
14588   vl_api_local_locator_t locator, *locators = 0;
14589   u32 sw_if_index, priority, weight;
14590   u32 data_len = 0;
14591
14592   int ret;
14593   /* Parse args required to build the message */
14594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14595     {
14596       if (unformat (input, "del"))
14597         {
14598           is_add = 0;
14599         }
14600       else if (unformat (input, "locator-set %s", &locator_set_name))
14601         {
14602           locator_set_name_set = 1;
14603         }
14604       else if (unformat (input, "sw_if_index %u p %u w %u",
14605                          &sw_if_index, &priority, &weight))
14606         {
14607           locator.sw_if_index = htonl (sw_if_index);
14608           locator.priority = priority;
14609           locator.weight = weight;
14610           vec_add1 (locators, locator);
14611         }
14612       else
14613         if (unformat
14614             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14615              &sw_if_index, &priority, &weight))
14616         {
14617           locator.sw_if_index = htonl (sw_if_index);
14618           locator.priority = priority;
14619           locator.weight = weight;
14620           vec_add1 (locators, locator);
14621         }
14622       else
14623         break;
14624     }
14625
14626   if (locator_set_name_set == 0)
14627     {
14628       errmsg ("missing locator-set name");
14629       vec_free (locators);
14630       return -99;
14631     }
14632
14633   if (vec_len (locator_set_name) > 64)
14634     {
14635       errmsg ("locator-set name too long");
14636       vec_free (locator_set_name);
14637       vec_free (locators);
14638       return -99;
14639     }
14640   vec_add1 (locator_set_name, 0);
14641
14642   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14643
14644   /* Construct the API message */
14645   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14646
14647   mp->is_add = is_add;
14648   clib_memcpy (mp->locator_set_name, locator_set_name,
14649                vec_len (locator_set_name));
14650   vec_free (locator_set_name);
14651
14652   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14653   if (locators)
14654     clib_memcpy (mp->locators, locators, data_len);
14655   vec_free (locators);
14656
14657   /* send it... */
14658   S (mp);
14659
14660   /* Wait for a reply... */
14661   W (ret);
14662   return ret;
14663 }
14664
14665 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14666
14667 static int
14668 api_one_add_del_locator (vat_main_t * vam)
14669 {
14670   unformat_input_t *input = vam->input;
14671   vl_api_one_add_del_locator_t *mp;
14672   u32 tmp_if_index = ~0;
14673   u32 sw_if_index = ~0;
14674   u8 sw_if_index_set = 0;
14675   u8 sw_if_index_if_name_set = 0;
14676   u32 priority = ~0;
14677   u8 priority_set = 0;
14678   u32 weight = ~0;
14679   u8 weight_set = 0;
14680   u8 is_add = 1;
14681   u8 *locator_set_name = NULL;
14682   u8 locator_set_name_set = 0;
14683   int ret;
14684
14685   /* Parse args required to build the message */
14686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14687     {
14688       if (unformat (input, "del"))
14689         {
14690           is_add = 0;
14691         }
14692       else if (unformat (input, "locator-set %s", &locator_set_name))
14693         {
14694           locator_set_name_set = 1;
14695         }
14696       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14697                          &tmp_if_index))
14698         {
14699           sw_if_index_if_name_set = 1;
14700           sw_if_index = tmp_if_index;
14701         }
14702       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14703         {
14704           sw_if_index_set = 1;
14705           sw_if_index = tmp_if_index;
14706         }
14707       else if (unformat (input, "p %d", &priority))
14708         {
14709           priority_set = 1;
14710         }
14711       else if (unformat (input, "w %d", &weight))
14712         {
14713           weight_set = 1;
14714         }
14715       else
14716         break;
14717     }
14718
14719   if (locator_set_name_set == 0)
14720     {
14721       errmsg ("missing locator-set name");
14722       return -99;
14723     }
14724
14725   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14726     {
14727       errmsg ("missing sw_if_index");
14728       vec_free (locator_set_name);
14729       return -99;
14730     }
14731
14732   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14733     {
14734       errmsg ("cannot use both params interface name and sw_if_index");
14735       vec_free (locator_set_name);
14736       return -99;
14737     }
14738
14739   if (priority_set == 0)
14740     {
14741       errmsg ("missing locator-set priority");
14742       vec_free (locator_set_name);
14743       return -99;
14744     }
14745
14746   if (weight_set == 0)
14747     {
14748       errmsg ("missing locator-set weight");
14749       vec_free (locator_set_name);
14750       return -99;
14751     }
14752
14753   if (vec_len (locator_set_name) > 64)
14754     {
14755       errmsg ("locator-set name too long");
14756       vec_free (locator_set_name);
14757       return -99;
14758     }
14759   vec_add1 (locator_set_name, 0);
14760
14761   /* Construct the API message */
14762   M (ONE_ADD_DEL_LOCATOR, mp);
14763
14764   mp->is_add = is_add;
14765   mp->sw_if_index = ntohl (sw_if_index);
14766   mp->priority = priority;
14767   mp->weight = weight;
14768   clib_memcpy (mp->locator_set_name, locator_set_name,
14769                vec_len (locator_set_name));
14770   vec_free (locator_set_name);
14771
14772   /* send it... */
14773   S (mp);
14774
14775   /* Wait for a reply... */
14776   W (ret);
14777   return ret;
14778 }
14779
14780 #define api_lisp_add_del_locator api_one_add_del_locator
14781
14782 uword
14783 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14784 {
14785   u32 *key_id = va_arg (*args, u32 *);
14786   u8 *s = 0;
14787
14788   if (unformat (input, "%s", &s))
14789     {
14790       if (!strcmp ((char *) s, "sha1"))
14791         key_id[0] = HMAC_SHA_1_96;
14792       else if (!strcmp ((char *) s, "sha256"))
14793         key_id[0] = HMAC_SHA_256_128;
14794       else
14795         {
14796           clib_warning ("invalid key_id: '%s'", s);
14797           key_id[0] = HMAC_NO_KEY;
14798         }
14799     }
14800   else
14801     return 0;
14802
14803   vec_free (s);
14804   return 1;
14805 }
14806
14807 static int
14808 api_one_add_del_local_eid (vat_main_t * vam)
14809 {
14810   unformat_input_t *input = vam->input;
14811   vl_api_one_add_del_local_eid_t *mp;
14812   u8 is_add = 1;
14813   u8 eid_set = 0;
14814   lisp_eid_vat_t _eid, *eid = &_eid;
14815   u8 *locator_set_name = 0;
14816   u8 locator_set_name_set = 0;
14817   u32 vni = 0;
14818   u16 key_id = 0;
14819   u8 *key = 0;
14820   int ret;
14821
14822   /* Parse args required to build the message */
14823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14824     {
14825       if (unformat (input, "del"))
14826         {
14827           is_add = 0;
14828         }
14829       else if (unformat (input, "vni %d", &vni))
14830         {
14831           ;
14832         }
14833       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14834         {
14835           eid_set = 1;
14836         }
14837       else if (unformat (input, "locator-set %s", &locator_set_name))
14838         {
14839           locator_set_name_set = 1;
14840         }
14841       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14842         ;
14843       else if (unformat (input, "secret-key %_%v%_", &key))
14844         ;
14845       else
14846         break;
14847     }
14848
14849   if (locator_set_name_set == 0)
14850     {
14851       errmsg ("missing locator-set name");
14852       return -99;
14853     }
14854
14855   if (0 == eid_set)
14856     {
14857       errmsg ("EID address not set!");
14858       vec_free (locator_set_name);
14859       return -99;
14860     }
14861
14862   if (key && (0 == key_id))
14863     {
14864       errmsg ("invalid key_id!");
14865       return -99;
14866     }
14867
14868   if (vec_len (key) > 64)
14869     {
14870       errmsg ("key too long");
14871       vec_free (key);
14872       return -99;
14873     }
14874
14875   if (vec_len (locator_set_name) > 64)
14876     {
14877       errmsg ("locator-set name too long");
14878       vec_free (locator_set_name);
14879       return -99;
14880     }
14881   vec_add1 (locator_set_name, 0);
14882
14883   /* Construct the API message */
14884   M (ONE_ADD_DEL_LOCAL_EID, mp);
14885
14886   mp->is_add = is_add;
14887   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14888   mp->eid_type = eid->type;
14889   mp->prefix_len = eid->len;
14890   mp->vni = clib_host_to_net_u32 (vni);
14891   mp->key_id = clib_host_to_net_u16 (key_id);
14892   clib_memcpy (mp->locator_set_name, locator_set_name,
14893                vec_len (locator_set_name));
14894   clib_memcpy (mp->key, key, vec_len (key));
14895
14896   vec_free (locator_set_name);
14897   vec_free (key);
14898
14899   /* send it... */
14900   S (mp);
14901
14902   /* Wait for a reply... */
14903   W (ret);
14904   return ret;
14905 }
14906
14907 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14908
14909 static int
14910 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14911 {
14912   u32 dp_table = 0, vni = 0;;
14913   unformat_input_t *input = vam->input;
14914   vl_api_gpe_add_del_fwd_entry_t *mp;
14915   u8 is_add = 1;
14916   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14917   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14918   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14919   u32 action = ~0, w;
14920   ip4_address_t rmt_rloc4, lcl_rloc4;
14921   ip6_address_t rmt_rloc6, lcl_rloc6;
14922   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14923   int ret;
14924
14925   memset (&rloc, 0, sizeof (rloc));
14926
14927   /* Parse args required to build the message */
14928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14929     {
14930       if (unformat (input, "del"))
14931         is_add = 0;
14932       else if (unformat (input, "add"))
14933         is_add = 1;
14934       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14935         {
14936           rmt_eid_set = 1;
14937         }
14938       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14939         {
14940           lcl_eid_set = 1;
14941         }
14942       else if (unformat (input, "vrf %d", &dp_table))
14943         ;
14944       else if (unformat (input, "bd %d", &dp_table))
14945         ;
14946       else if (unformat (input, "vni %d", &vni))
14947         ;
14948       else if (unformat (input, "w %d", &w))
14949         {
14950           if (!curr_rloc)
14951             {
14952               errmsg ("No RLOC configured for setting priority/weight!");
14953               return -99;
14954             }
14955           curr_rloc->weight = w;
14956         }
14957       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14958                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14959         {
14960           rloc.is_ip4 = 1;
14961
14962           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14963           rloc.weight = 0;
14964           vec_add1 (lcl_locs, rloc);
14965
14966           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14967           vec_add1 (rmt_locs, rloc);
14968           /* weight saved in rmt loc */
14969           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14970         }
14971       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14972                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14973         {
14974           rloc.is_ip4 = 0;
14975           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14976           rloc.weight = 0;
14977           vec_add1 (lcl_locs, rloc);
14978
14979           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14980           vec_add1 (rmt_locs, rloc);
14981           /* weight saved in rmt loc */
14982           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14983         }
14984       else if (unformat (input, "action %d", &action))
14985         {
14986           ;
14987         }
14988       else
14989         {
14990           clib_warning ("parse error '%U'", format_unformat_error, input);
14991           return -99;
14992         }
14993     }
14994
14995   if (!rmt_eid_set)
14996     {
14997       errmsg ("remote eid addresses not set");
14998       return -99;
14999     }
15000
15001   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15002     {
15003       errmsg ("eid types don't match");
15004       return -99;
15005     }
15006
15007   if (0 == rmt_locs && (u32) ~ 0 == action)
15008     {
15009       errmsg ("action not set for negative mapping");
15010       return -99;
15011     }
15012
15013   /* Construct the API message */
15014   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15015       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15016
15017   mp->is_add = is_add;
15018   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15019   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15020   mp->eid_type = rmt_eid->type;
15021   mp->dp_table = clib_host_to_net_u32 (dp_table);
15022   mp->vni = clib_host_to_net_u32 (vni);
15023   mp->rmt_len = rmt_eid->len;
15024   mp->lcl_len = lcl_eid->len;
15025   mp->action = action;
15026
15027   if (0 != rmt_locs && 0 != lcl_locs)
15028     {
15029       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15030       clib_memcpy (mp->locs, lcl_locs,
15031                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15032
15033       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15034       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15035                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15036     }
15037   vec_free (lcl_locs);
15038   vec_free (rmt_locs);
15039
15040   /* send it... */
15041   S (mp);
15042
15043   /* Wait for a reply... */
15044   W (ret);
15045   return ret;
15046 }
15047
15048 static int
15049 api_one_add_del_map_server (vat_main_t * vam)
15050 {
15051   unformat_input_t *input = vam->input;
15052   vl_api_one_add_del_map_server_t *mp;
15053   u8 is_add = 1;
15054   u8 ipv4_set = 0;
15055   u8 ipv6_set = 0;
15056   ip4_address_t ipv4;
15057   ip6_address_t ipv6;
15058   int ret;
15059
15060   /* Parse args required to build the message */
15061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15062     {
15063       if (unformat (input, "del"))
15064         {
15065           is_add = 0;
15066         }
15067       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15068         {
15069           ipv4_set = 1;
15070         }
15071       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15072         {
15073           ipv6_set = 1;
15074         }
15075       else
15076         break;
15077     }
15078
15079   if (ipv4_set && ipv6_set)
15080     {
15081       errmsg ("both eid v4 and v6 addresses set");
15082       return -99;
15083     }
15084
15085   if (!ipv4_set && !ipv6_set)
15086     {
15087       errmsg ("eid addresses not set");
15088       return -99;
15089     }
15090
15091   /* Construct the API message */
15092   M (ONE_ADD_DEL_MAP_SERVER, mp);
15093
15094   mp->is_add = is_add;
15095   if (ipv6_set)
15096     {
15097       mp->is_ipv6 = 1;
15098       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15099     }
15100   else
15101     {
15102       mp->is_ipv6 = 0;
15103       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15104     }
15105
15106   /* send it... */
15107   S (mp);
15108
15109   /* Wait for a reply... */
15110   W (ret);
15111   return ret;
15112 }
15113
15114 #define api_lisp_add_del_map_server api_one_add_del_map_server
15115
15116 static int
15117 api_one_add_del_map_resolver (vat_main_t * vam)
15118 {
15119   unformat_input_t *input = vam->input;
15120   vl_api_one_add_del_map_resolver_t *mp;
15121   u8 is_add = 1;
15122   u8 ipv4_set = 0;
15123   u8 ipv6_set = 0;
15124   ip4_address_t ipv4;
15125   ip6_address_t ipv6;
15126   int ret;
15127
15128   /* Parse args required to build the message */
15129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15130     {
15131       if (unformat (input, "del"))
15132         {
15133           is_add = 0;
15134         }
15135       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15136         {
15137           ipv4_set = 1;
15138         }
15139       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15140         {
15141           ipv6_set = 1;
15142         }
15143       else
15144         break;
15145     }
15146
15147   if (ipv4_set && ipv6_set)
15148     {
15149       errmsg ("both eid v4 and v6 addresses set");
15150       return -99;
15151     }
15152
15153   if (!ipv4_set && !ipv6_set)
15154     {
15155       errmsg ("eid addresses not set");
15156       return -99;
15157     }
15158
15159   /* Construct the API message */
15160   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15161
15162   mp->is_add = is_add;
15163   if (ipv6_set)
15164     {
15165       mp->is_ipv6 = 1;
15166       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15167     }
15168   else
15169     {
15170       mp->is_ipv6 = 0;
15171       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15172     }
15173
15174   /* send it... */
15175   S (mp);
15176
15177   /* Wait for a reply... */
15178   W (ret);
15179   return ret;
15180 }
15181
15182 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15183
15184 static int
15185 api_lisp_gpe_enable_disable (vat_main_t * vam)
15186 {
15187   unformat_input_t *input = vam->input;
15188   vl_api_gpe_enable_disable_t *mp;
15189   u8 is_set = 0;
15190   u8 is_en = 1;
15191   int ret;
15192
15193   /* Parse args required to build the message */
15194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15195     {
15196       if (unformat (input, "enable"))
15197         {
15198           is_set = 1;
15199           is_en = 1;
15200         }
15201       else if (unformat (input, "disable"))
15202         {
15203           is_set = 1;
15204           is_en = 0;
15205         }
15206       else
15207         break;
15208     }
15209
15210   if (is_set == 0)
15211     {
15212       errmsg ("Value not set");
15213       return -99;
15214     }
15215
15216   /* Construct the API message */
15217   M (GPE_ENABLE_DISABLE, mp);
15218
15219   mp->is_en = is_en;
15220
15221   /* send it... */
15222   S (mp);
15223
15224   /* Wait for a reply... */
15225   W (ret);
15226   return ret;
15227 }
15228
15229 static int
15230 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15231 {
15232   unformat_input_t *input = vam->input;
15233   vl_api_one_rloc_probe_enable_disable_t *mp;
15234   u8 is_set = 0;
15235   u8 is_en = 0;
15236   int ret;
15237
15238   /* Parse args required to build the message */
15239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15240     {
15241       if (unformat (input, "enable"))
15242         {
15243           is_set = 1;
15244           is_en = 1;
15245         }
15246       else if (unformat (input, "disable"))
15247         is_set = 1;
15248       else
15249         break;
15250     }
15251
15252   if (!is_set)
15253     {
15254       errmsg ("Value not set");
15255       return -99;
15256     }
15257
15258   /* Construct the API message */
15259   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15260
15261   mp->is_enabled = is_en;
15262
15263   /* send it... */
15264   S (mp);
15265
15266   /* Wait for a reply... */
15267   W (ret);
15268   return ret;
15269 }
15270
15271 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15272
15273 static int
15274 api_one_map_register_enable_disable (vat_main_t * vam)
15275 {
15276   unformat_input_t *input = vam->input;
15277   vl_api_one_map_register_enable_disable_t *mp;
15278   u8 is_set = 0;
15279   u8 is_en = 0;
15280   int ret;
15281
15282   /* Parse args required to build the message */
15283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15284     {
15285       if (unformat (input, "enable"))
15286         {
15287           is_set = 1;
15288           is_en = 1;
15289         }
15290       else if (unformat (input, "disable"))
15291         is_set = 1;
15292       else
15293         break;
15294     }
15295
15296   if (!is_set)
15297     {
15298       errmsg ("Value not set");
15299       return -99;
15300     }
15301
15302   /* Construct the API message */
15303   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15304
15305   mp->is_enabled = is_en;
15306
15307   /* send it... */
15308   S (mp);
15309
15310   /* Wait for a reply... */
15311   W (ret);
15312   return ret;
15313 }
15314
15315 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15316
15317 static int
15318 api_one_enable_disable (vat_main_t * vam)
15319 {
15320   unformat_input_t *input = vam->input;
15321   vl_api_one_enable_disable_t *mp;
15322   u8 is_set = 0;
15323   u8 is_en = 0;
15324   int ret;
15325
15326   /* Parse args required to build the message */
15327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15328     {
15329       if (unformat (input, "enable"))
15330         {
15331           is_set = 1;
15332           is_en = 1;
15333         }
15334       else if (unformat (input, "disable"))
15335         {
15336           is_set = 1;
15337         }
15338       else
15339         break;
15340     }
15341
15342   if (!is_set)
15343     {
15344       errmsg ("Value not set");
15345       return -99;
15346     }
15347
15348   /* Construct the API message */
15349   M (ONE_ENABLE_DISABLE, mp);
15350
15351   mp->is_en = is_en;
15352
15353   /* send it... */
15354   S (mp);
15355
15356   /* Wait for a reply... */
15357   W (ret);
15358   return ret;
15359 }
15360
15361 #define api_lisp_enable_disable api_one_enable_disable
15362
15363 static int
15364 api_show_one_map_register_state (vat_main_t * vam)
15365 {
15366   vl_api_show_one_map_register_state_t *mp;
15367   int ret;
15368
15369   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15370
15371   /* send */
15372   S (mp);
15373
15374   /* wait for reply */
15375   W (ret);
15376   return ret;
15377 }
15378
15379 #define api_show_lisp_map_register_state api_show_one_map_register_state
15380
15381 static int
15382 api_show_one_rloc_probe_state (vat_main_t * vam)
15383 {
15384   vl_api_show_one_rloc_probe_state_t *mp;
15385   int ret;
15386
15387   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15388
15389   /* send */
15390   S (mp);
15391
15392   /* wait for reply */
15393   W (ret);
15394   return ret;
15395 }
15396
15397 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15398
15399 static int
15400 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15401 {
15402   vl_api_one_add_del_l2_arp_entry_t *mp;
15403   unformat_input_t *input = vam->input;
15404   u8 is_add = 1;
15405   u8 mac_set = 0;
15406   u8 bd_set = 0;
15407   u8 ip_set = 0;
15408   u8 mac[6] = { 0, };
15409   u32 ip4 = 0, bd = ~0;
15410   int ret;
15411
15412   /* Parse args required to build the message */
15413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15414     {
15415       if (unformat (input, "del"))
15416         is_add = 0;
15417       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15418         mac_set = 1;
15419       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15420         ip_set = 1;
15421       else if (unformat (input, "bd %d", &bd))
15422         bd_set = 1;
15423       else
15424         {
15425           errmsg ("parse error '%U'", format_unformat_error, input);
15426           return -99;
15427         }
15428     }
15429
15430   if (!bd_set || !ip_set || (!mac_set && is_add))
15431     {
15432       errmsg ("Missing BD, IP or MAC!");
15433       return -99;
15434     }
15435
15436   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15437   mp->is_add = is_add;
15438   clib_memcpy (mp->mac, mac, 6);
15439   mp->bd = clib_host_to_net_u32 (bd);
15440   mp->ip4 = ip4;
15441
15442   /* send */
15443   S (mp);
15444
15445   /* wait for reply */
15446   W (ret);
15447   return ret;
15448 }
15449
15450 static int
15451 api_one_l2_arp_bd_get (vat_main_t * vam)
15452 {
15453   vl_api_one_l2_arp_bd_get_t *mp;
15454   int ret;
15455
15456   M (ONE_L2_ARP_BD_GET, mp);
15457
15458   /* send */
15459   S (mp);
15460
15461   /* wait for reply */
15462   W (ret);
15463   return ret;
15464 }
15465
15466 static int
15467 api_one_l2_arp_entries_get (vat_main_t * vam)
15468 {
15469   vl_api_one_l2_arp_entries_get_t *mp;
15470   unformat_input_t *input = vam->input;
15471   u8 bd_set = 0;
15472   u32 bd = ~0;
15473   int ret;
15474
15475   /* Parse args required to build the message */
15476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15477     {
15478       if (unformat (input, "bd %d", &bd))
15479         bd_set = 1;
15480       else
15481         {
15482           errmsg ("parse error '%U'", format_unformat_error, input);
15483           return -99;
15484         }
15485     }
15486
15487   if (!bd_set)
15488     {
15489       errmsg ("Expected bridge domain!");
15490       return -99;
15491     }
15492
15493   M (ONE_L2_ARP_ENTRIES_GET, mp);
15494   mp->bd = clib_host_to_net_u32 (bd);
15495
15496   /* send */
15497   S (mp);
15498
15499   /* wait for reply */
15500   W (ret);
15501   return ret;
15502 }
15503
15504 static int
15505 api_one_stats_enable_disable (vat_main_t * vam)
15506 {
15507   vl_api_one_stats_enable_disable_t *mp;
15508   unformat_input_t *input = vam->input;
15509   u8 is_set = 0;
15510   u8 is_en = 0;
15511   int ret;
15512
15513   /* Parse args required to build the message */
15514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15515     {
15516       if (unformat (input, "enable"))
15517         {
15518           is_set = 1;
15519           is_en = 1;
15520         }
15521       else if (unformat (input, "disable"))
15522         {
15523           is_set = 1;
15524         }
15525       else
15526         break;
15527     }
15528
15529   if (!is_set)
15530     {
15531       errmsg ("Value not set");
15532       return -99;
15533     }
15534
15535   M (ONE_STATS_ENABLE_DISABLE, mp);
15536   mp->is_en = is_en;
15537
15538   /* send */
15539   S (mp);
15540
15541   /* wait for reply */
15542   W (ret);
15543   return ret;
15544 }
15545
15546 static int
15547 api_show_one_stats_enable_disable (vat_main_t * vam)
15548 {
15549   vl_api_show_one_stats_enable_disable_t *mp;
15550   int ret;
15551
15552   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15553
15554   /* send */
15555   S (mp);
15556
15557   /* wait for reply */
15558   W (ret);
15559   return ret;
15560 }
15561
15562 static int
15563 api_show_one_map_request_mode (vat_main_t * vam)
15564 {
15565   vl_api_show_one_map_request_mode_t *mp;
15566   int ret;
15567
15568   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15569
15570   /* send */
15571   S (mp);
15572
15573   /* wait for reply */
15574   W (ret);
15575   return ret;
15576 }
15577
15578 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15579
15580 static int
15581 api_one_map_request_mode (vat_main_t * vam)
15582 {
15583   unformat_input_t *input = vam->input;
15584   vl_api_one_map_request_mode_t *mp;
15585   u8 mode = 0;
15586   int ret;
15587
15588   /* Parse args required to build the message */
15589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15590     {
15591       if (unformat (input, "dst-only"))
15592         mode = 0;
15593       else if (unformat (input, "src-dst"))
15594         mode = 1;
15595       else
15596         {
15597           errmsg ("parse error '%U'", format_unformat_error, input);
15598           return -99;
15599         }
15600     }
15601
15602   M (ONE_MAP_REQUEST_MODE, mp);
15603
15604   mp->mode = mode;
15605
15606   /* send */
15607   S (mp);
15608
15609   /* wait for reply */
15610   W (ret);
15611   return ret;
15612 }
15613
15614 #define api_lisp_map_request_mode api_one_map_request_mode
15615
15616 /**
15617  * Enable/disable ONE proxy ITR.
15618  *
15619  * @param vam vpp API test context
15620  * @return return code
15621  */
15622 static int
15623 api_one_pitr_set_locator_set (vat_main_t * vam)
15624 {
15625   u8 ls_name_set = 0;
15626   unformat_input_t *input = vam->input;
15627   vl_api_one_pitr_set_locator_set_t *mp;
15628   u8 is_add = 1;
15629   u8 *ls_name = 0;
15630   int ret;
15631
15632   /* Parse args required to build the message */
15633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15634     {
15635       if (unformat (input, "del"))
15636         is_add = 0;
15637       else if (unformat (input, "locator-set %s", &ls_name))
15638         ls_name_set = 1;
15639       else
15640         {
15641           errmsg ("parse error '%U'", format_unformat_error, input);
15642           return -99;
15643         }
15644     }
15645
15646   if (!ls_name_set)
15647     {
15648       errmsg ("locator-set name not set!");
15649       return -99;
15650     }
15651
15652   M (ONE_PITR_SET_LOCATOR_SET, mp);
15653
15654   mp->is_add = is_add;
15655   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15656   vec_free (ls_name);
15657
15658   /* send */
15659   S (mp);
15660
15661   /* wait for reply */
15662   W (ret);
15663   return ret;
15664 }
15665
15666 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15667
15668 static int
15669 api_one_nsh_set_locator_set (vat_main_t * vam)
15670 {
15671   u8 ls_name_set = 0;
15672   unformat_input_t *input = vam->input;
15673   vl_api_one_nsh_set_locator_set_t *mp;
15674   u8 is_add = 1;
15675   u8 *ls_name = 0;
15676   int ret;
15677
15678   /* Parse args required to build the message */
15679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15680     {
15681       if (unformat (input, "del"))
15682         is_add = 0;
15683       else if (unformat (input, "ls %s", &ls_name))
15684         ls_name_set = 1;
15685       else
15686         {
15687           errmsg ("parse error '%U'", format_unformat_error, input);
15688           return -99;
15689         }
15690     }
15691
15692   if (!ls_name_set && is_add)
15693     {
15694       errmsg ("locator-set name not set!");
15695       return -99;
15696     }
15697
15698   M (ONE_NSH_SET_LOCATOR_SET, mp);
15699
15700   mp->is_add = is_add;
15701   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15702   vec_free (ls_name);
15703
15704   /* send */
15705   S (mp);
15706
15707   /* wait for reply */
15708   W (ret);
15709   return ret;
15710 }
15711
15712 static int
15713 api_show_one_pitr (vat_main_t * vam)
15714 {
15715   vl_api_show_one_pitr_t *mp;
15716   int ret;
15717
15718   if (!vam->json_output)
15719     {
15720       print (vam->ofp, "%=20s", "lisp status:");
15721     }
15722
15723   M (SHOW_ONE_PITR, mp);
15724   /* send it... */
15725   S (mp);
15726
15727   /* Wait for a reply... */
15728   W (ret);
15729   return ret;
15730 }
15731
15732 #define api_show_lisp_pitr api_show_one_pitr
15733
15734 static int
15735 api_one_use_petr (vat_main_t * vam)
15736 {
15737   unformat_input_t *input = vam->input;
15738   vl_api_one_use_petr_t *mp;
15739   u8 is_add = 0;
15740   ip_address_t ip;
15741   int ret;
15742
15743   memset (&ip, 0, sizeof (ip));
15744
15745   /* Parse args required to build the message */
15746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15747     {
15748       if (unformat (input, "disable"))
15749         is_add = 0;
15750       else
15751         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15752         {
15753           is_add = 1;
15754           ip_addr_version (&ip) = IP4;
15755         }
15756       else
15757         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15758         {
15759           is_add = 1;
15760           ip_addr_version (&ip) = IP6;
15761         }
15762       else
15763         {
15764           errmsg ("parse error '%U'", format_unformat_error, input);
15765           return -99;
15766         }
15767     }
15768
15769   M (ONE_USE_PETR, mp);
15770
15771   mp->is_add = is_add;
15772   if (is_add)
15773     {
15774       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15775       if (mp->is_ip4)
15776         clib_memcpy (mp->address, &ip, 4);
15777       else
15778         clib_memcpy (mp->address, &ip, 16);
15779     }
15780
15781   /* send */
15782   S (mp);
15783
15784   /* wait for reply */
15785   W (ret);
15786   return ret;
15787 }
15788
15789 #define api_lisp_use_petr api_one_use_petr
15790
15791 static int
15792 api_show_one_nsh_mapping (vat_main_t * vam)
15793 {
15794   vl_api_show_one_use_petr_t *mp;
15795   int ret;
15796
15797   if (!vam->json_output)
15798     {
15799       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15800     }
15801
15802   M (SHOW_ONE_NSH_MAPPING, mp);
15803   /* send it... */
15804   S (mp);
15805
15806   /* Wait for a reply... */
15807   W (ret);
15808   return ret;
15809 }
15810
15811 static int
15812 api_show_one_use_petr (vat_main_t * vam)
15813 {
15814   vl_api_show_one_use_petr_t *mp;
15815   int ret;
15816
15817   if (!vam->json_output)
15818     {
15819       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15820     }
15821
15822   M (SHOW_ONE_USE_PETR, mp);
15823   /* send it... */
15824   S (mp);
15825
15826   /* Wait for a reply... */
15827   W (ret);
15828   return ret;
15829 }
15830
15831 #define api_show_lisp_use_petr api_show_one_use_petr
15832
15833 /**
15834  * Add/delete mapping between vni and vrf
15835  */
15836 static int
15837 api_one_eid_table_add_del_map (vat_main_t * vam)
15838 {
15839   unformat_input_t *input = vam->input;
15840   vl_api_one_eid_table_add_del_map_t *mp;
15841   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15842   u32 vni, vrf, bd_index;
15843   int ret;
15844
15845   /* Parse args required to build the message */
15846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15847     {
15848       if (unformat (input, "del"))
15849         is_add = 0;
15850       else if (unformat (input, "vrf %d", &vrf))
15851         vrf_set = 1;
15852       else if (unformat (input, "bd_index %d", &bd_index))
15853         bd_index_set = 1;
15854       else if (unformat (input, "vni %d", &vni))
15855         vni_set = 1;
15856       else
15857         break;
15858     }
15859
15860   if (!vni_set || (!vrf_set && !bd_index_set))
15861     {
15862       errmsg ("missing arguments!");
15863       return -99;
15864     }
15865
15866   if (vrf_set && bd_index_set)
15867     {
15868       errmsg ("error: both vrf and bd entered!");
15869       return -99;
15870     }
15871
15872   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15873
15874   mp->is_add = is_add;
15875   mp->vni = htonl (vni);
15876   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15877   mp->is_l2 = bd_index_set;
15878
15879   /* send */
15880   S (mp);
15881
15882   /* wait for reply */
15883   W (ret);
15884   return ret;
15885 }
15886
15887 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15888
15889 uword
15890 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15891 {
15892   u32 *action = va_arg (*args, u32 *);
15893   u8 *s = 0;
15894
15895   if (unformat (input, "%s", &s))
15896     {
15897       if (!strcmp ((char *) s, "no-action"))
15898         action[0] = 0;
15899       else if (!strcmp ((char *) s, "natively-forward"))
15900         action[0] = 1;
15901       else if (!strcmp ((char *) s, "send-map-request"))
15902         action[0] = 2;
15903       else if (!strcmp ((char *) s, "drop"))
15904         action[0] = 3;
15905       else
15906         {
15907           clib_warning ("invalid action: '%s'", s);
15908           action[0] = 3;
15909         }
15910     }
15911   else
15912     return 0;
15913
15914   vec_free (s);
15915   return 1;
15916 }
15917
15918 /**
15919  * Add/del remote mapping to/from ONE control plane
15920  *
15921  * @param vam vpp API test context
15922  * @return return code
15923  */
15924 static int
15925 api_one_add_del_remote_mapping (vat_main_t * vam)
15926 {
15927   unformat_input_t *input = vam->input;
15928   vl_api_one_add_del_remote_mapping_t *mp;
15929   u32 vni = 0;
15930   lisp_eid_vat_t _eid, *eid = &_eid;
15931   lisp_eid_vat_t _seid, *seid = &_seid;
15932   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15933   u32 action = ~0, p, w, data_len;
15934   ip4_address_t rloc4;
15935   ip6_address_t rloc6;
15936   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15937   int ret;
15938
15939   memset (&rloc, 0, sizeof (rloc));
15940
15941   /* Parse args required to build the message */
15942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15943     {
15944       if (unformat (input, "del-all"))
15945         {
15946           del_all = 1;
15947         }
15948       else if (unformat (input, "del"))
15949         {
15950           is_add = 0;
15951         }
15952       else if (unformat (input, "add"))
15953         {
15954           is_add = 1;
15955         }
15956       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15957         {
15958           eid_set = 1;
15959         }
15960       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15961         {
15962           seid_set = 1;
15963         }
15964       else if (unformat (input, "vni %d", &vni))
15965         {
15966           ;
15967         }
15968       else if (unformat (input, "p %d w %d", &p, &w))
15969         {
15970           if (!curr_rloc)
15971             {
15972               errmsg ("No RLOC configured for setting priority/weight!");
15973               return -99;
15974             }
15975           curr_rloc->priority = p;
15976           curr_rloc->weight = w;
15977         }
15978       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15979         {
15980           rloc.is_ip4 = 1;
15981           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15982           vec_add1 (rlocs, rloc);
15983           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15984         }
15985       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15986         {
15987           rloc.is_ip4 = 0;
15988           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15989           vec_add1 (rlocs, rloc);
15990           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15991         }
15992       else if (unformat (input, "action %U",
15993                          unformat_negative_mapping_action, &action))
15994         {
15995           ;
15996         }
15997       else
15998         {
15999           clib_warning ("parse error '%U'", format_unformat_error, input);
16000           return -99;
16001         }
16002     }
16003
16004   if (0 == eid_set)
16005     {
16006       errmsg ("missing params!");
16007       return -99;
16008     }
16009
16010   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16011     {
16012       errmsg ("no action set for negative map-reply!");
16013       return -99;
16014     }
16015
16016   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16017
16018   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16019   mp->is_add = is_add;
16020   mp->vni = htonl (vni);
16021   mp->action = (u8) action;
16022   mp->is_src_dst = seid_set;
16023   mp->eid_len = eid->len;
16024   mp->seid_len = seid->len;
16025   mp->del_all = del_all;
16026   mp->eid_type = eid->type;
16027   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16028   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16029
16030   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16031   clib_memcpy (mp->rlocs, rlocs, data_len);
16032   vec_free (rlocs);
16033
16034   /* send it... */
16035   S (mp);
16036
16037   /* Wait for a reply... */
16038   W (ret);
16039   return ret;
16040 }
16041
16042 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16043
16044 /**
16045  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16046  * forwarding entries in data-plane accordingly.
16047  *
16048  * @param vam vpp API test context
16049  * @return return code
16050  */
16051 static int
16052 api_one_add_del_adjacency (vat_main_t * vam)
16053 {
16054   unformat_input_t *input = vam->input;
16055   vl_api_one_add_del_adjacency_t *mp;
16056   u32 vni = 0;
16057   ip4_address_t leid4, reid4;
16058   ip6_address_t leid6, reid6;
16059   u8 reid_mac[6] = { 0 };
16060   u8 leid_mac[6] = { 0 };
16061   u8 reid_type, leid_type;
16062   u32 leid_len = 0, reid_len = 0, len;
16063   u8 is_add = 1;
16064   int ret;
16065
16066   leid_type = reid_type = (u8) ~ 0;
16067
16068   /* Parse args required to build the message */
16069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16070     {
16071       if (unformat (input, "del"))
16072         {
16073           is_add = 0;
16074         }
16075       else if (unformat (input, "add"))
16076         {
16077           is_add = 1;
16078         }
16079       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16080                          &reid4, &len))
16081         {
16082           reid_type = 0;        /* ipv4 */
16083           reid_len = len;
16084         }
16085       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16086                          &reid6, &len))
16087         {
16088           reid_type = 1;        /* ipv6 */
16089           reid_len = len;
16090         }
16091       else if (unformat (input, "reid %U", unformat_ethernet_address,
16092                          reid_mac))
16093         {
16094           reid_type = 2;        /* mac */
16095         }
16096       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16097                          &leid4, &len))
16098         {
16099           leid_type = 0;        /* ipv4 */
16100           leid_len = len;
16101         }
16102       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16103                          &leid6, &len))
16104         {
16105           leid_type = 1;        /* ipv6 */
16106           leid_len = len;
16107         }
16108       else if (unformat (input, "leid %U", unformat_ethernet_address,
16109                          leid_mac))
16110         {
16111           leid_type = 2;        /* mac */
16112         }
16113       else if (unformat (input, "vni %d", &vni))
16114         {
16115           ;
16116         }
16117       else
16118         {
16119           errmsg ("parse error '%U'", format_unformat_error, input);
16120           return -99;
16121         }
16122     }
16123
16124   if ((u8) ~ 0 == reid_type)
16125     {
16126       errmsg ("missing params!");
16127       return -99;
16128     }
16129
16130   if (leid_type != reid_type)
16131     {
16132       errmsg ("remote and local EIDs are of different types!");
16133       return -99;
16134     }
16135
16136   M (ONE_ADD_DEL_ADJACENCY, mp);
16137   mp->is_add = is_add;
16138   mp->vni = htonl (vni);
16139   mp->leid_len = leid_len;
16140   mp->reid_len = reid_len;
16141   mp->eid_type = reid_type;
16142
16143   switch (mp->eid_type)
16144     {
16145     case 0:
16146       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16147       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16148       break;
16149     case 1:
16150       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16151       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16152       break;
16153     case 2:
16154       clib_memcpy (mp->leid, leid_mac, 6);
16155       clib_memcpy (mp->reid, reid_mac, 6);
16156       break;
16157     default:
16158       errmsg ("unknown EID type %d!", mp->eid_type);
16159       return 0;
16160     }
16161
16162   /* send it... */
16163   S (mp);
16164
16165   /* Wait for a reply... */
16166   W (ret);
16167   return ret;
16168 }
16169
16170 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16171
16172 uword
16173 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16174 {
16175   u32 *mode = va_arg (*args, u32 *);
16176
16177   if (unformat (input, "lisp"))
16178     *mode = 0;
16179   else if (unformat (input, "vxlan"))
16180     *mode = 1;
16181   else
16182     return 0;
16183
16184   return 1;
16185 }
16186
16187 static int
16188 api_gpe_get_encap_mode (vat_main_t * vam)
16189 {
16190   vl_api_gpe_get_encap_mode_t *mp;
16191   int ret;
16192
16193   /* Construct the API message */
16194   M (GPE_GET_ENCAP_MODE, mp);
16195
16196   /* send it... */
16197   S (mp);
16198
16199   /* Wait for a reply... */
16200   W (ret);
16201   return ret;
16202 }
16203
16204 static int
16205 api_gpe_set_encap_mode (vat_main_t * vam)
16206 {
16207   unformat_input_t *input = vam->input;
16208   vl_api_gpe_set_encap_mode_t *mp;
16209   int ret;
16210   u32 mode = 0;
16211
16212   /* Parse args required to build the message */
16213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16214     {
16215       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16216         ;
16217       else
16218         break;
16219     }
16220
16221   /* Construct the API message */
16222   M (GPE_SET_ENCAP_MODE, mp);
16223
16224   mp->mode = mode;
16225
16226   /* send it... */
16227   S (mp);
16228
16229   /* Wait for a reply... */
16230   W (ret);
16231   return ret;
16232 }
16233
16234 static int
16235 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16236 {
16237   unformat_input_t *input = vam->input;
16238   vl_api_gpe_add_del_iface_t *mp;
16239   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16240   u32 dp_table = 0, vni = 0;
16241   int ret;
16242
16243   /* Parse args required to build the message */
16244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (input, "up"))
16247         {
16248           action_set = 1;
16249           is_add = 1;
16250         }
16251       else if (unformat (input, "down"))
16252         {
16253           action_set = 1;
16254           is_add = 0;
16255         }
16256       else if (unformat (input, "table_id %d", &dp_table))
16257         {
16258           dp_table_set = 1;
16259         }
16260       else if (unformat (input, "bd_id %d", &dp_table))
16261         {
16262           dp_table_set = 1;
16263           is_l2 = 1;
16264         }
16265       else if (unformat (input, "vni %d", &vni))
16266         {
16267           vni_set = 1;
16268         }
16269       else
16270         break;
16271     }
16272
16273   if (action_set == 0)
16274     {
16275       errmsg ("Action not set");
16276       return -99;
16277     }
16278   if (dp_table_set == 0 || vni_set == 0)
16279     {
16280       errmsg ("vni and dp_table must be set");
16281       return -99;
16282     }
16283
16284   /* Construct the API message */
16285   M (GPE_ADD_DEL_IFACE, mp);
16286
16287   mp->is_add = is_add;
16288   mp->dp_table = clib_host_to_net_u32 (dp_table);
16289   mp->is_l2 = is_l2;
16290   mp->vni = clib_host_to_net_u32 (vni);
16291
16292   /* send it... */
16293   S (mp);
16294
16295   /* Wait for a reply... */
16296   W (ret);
16297   return ret;
16298 }
16299
16300 static int
16301 api_one_map_register_fallback_threshold (vat_main_t * vam)
16302 {
16303   unformat_input_t *input = vam->input;
16304   vl_api_one_map_register_fallback_threshold_t *mp;
16305   u32 value = 0;
16306   u8 is_set = 0;
16307   int ret;
16308
16309   /* Parse args required to build the message */
16310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16311     {
16312       if (unformat (input, "%u", &value))
16313         is_set = 1;
16314       else
16315         {
16316           clib_warning ("parse error '%U'", format_unformat_error, input);
16317           return -99;
16318         }
16319     }
16320
16321   if (!is_set)
16322     {
16323       errmsg ("fallback threshold value is missing!");
16324       return -99;
16325     }
16326
16327   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16328   mp->value = clib_host_to_net_u32 (value);
16329
16330   /* send it... */
16331   S (mp);
16332
16333   /* Wait for a reply... */
16334   W (ret);
16335   return ret;
16336 }
16337
16338 static int
16339 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16340 {
16341   vl_api_show_one_map_register_fallback_threshold_t *mp;
16342   int ret;
16343
16344   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16345
16346   /* send it... */
16347   S (mp);
16348
16349   /* Wait for a reply... */
16350   W (ret);
16351   return ret;
16352 }
16353
16354 static int
16355 api_one_map_register_set_ttl (vat_main_t * vam)
16356 {
16357   unformat_input_t *input = vam->input;
16358   vl_api_one_map_register_set_ttl_t *mp;
16359   u32 ttl = 0;
16360   u8 is_set = 0;
16361   int ret;
16362
16363   /* Parse args required to build the message */
16364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16365     {
16366       if (unformat (input, "%u", &ttl))
16367         is_set = 1;
16368       else
16369         {
16370           clib_warning ("parse error '%U'", format_unformat_error, input);
16371           return -99;
16372         }
16373     }
16374
16375   if (!is_set)
16376     {
16377       errmsg ("TTL value missing!");
16378       return -99;
16379     }
16380
16381   M (ONE_MAP_REGISTER_SET_TTL, mp);
16382   mp->ttl = clib_host_to_net_u32 (ttl);
16383
16384   /* send it... */
16385   S (mp);
16386
16387   /* Wait for a reply... */
16388   W (ret);
16389   return ret;
16390 }
16391
16392 static int
16393 api_show_one_map_register_ttl (vat_main_t * vam)
16394 {
16395   vl_api_show_one_map_register_ttl_t *mp;
16396   int ret;
16397
16398   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16399
16400   /* send it... */
16401   S (mp);
16402
16403   /* Wait for a reply... */
16404   W (ret);
16405   return ret;
16406 }
16407
16408 /**
16409  * Add/del map request itr rlocs from ONE control plane and updates
16410  *
16411  * @param vam vpp API test context
16412  * @return return code
16413  */
16414 static int
16415 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16416 {
16417   unformat_input_t *input = vam->input;
16418   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16419   u8 *locator_set_name = 0;
16420   u8 locator_set_name_set = 0;
16421   u8 is_add = 1;
16422   int ret;
16423
16424   /* Parse args required to build the message */
16425   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16426     {
16427       if (unformat (input, "del"))
16428         {
16429           is_add = 0;
16430         }
16431       else if (unformat (input, "%_%v%_", &locator_set_name))
16432         {
16433           locator_set_name_set = 1;
16434         }
16435       else
16436         {
16437           clib_warning ("parse error '%U'", format_unformat_error, input);
16438           return -99;
16439         }
16440     }
16441
16442   if (is_add && !locator_set_name_set)
16443     {
16444       errmsg ("itr-rloc is not set!");
16445       return -99;
16446     }
16447
16448   if (is_add && vec_len (locator_set_name) > 64)
16449     {
16450       errmsg ("itr-rloc locator-set name too long");
16451       vec_free (locator_set_name);
16452       return -99;
16453     }
16454
16455   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16456   mp->is_add = is_add;
16457   if (is_add)
16458     {
16459       clib_memcpy (mp->locator_set_name, locator_set_name,
16460                    vec_len (locator_set_name));
16461     }
16462   else
16463     {
16464       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16465     }
16466   vec_free (locator_set_name);
16467
16468   /* send it... */
16469   S (mp);
16470
16471   /* Wait for a reply... */
16472   W (ret);
16473   return ret;
16474 }
16475
16476 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16477
16478 static int
16479 api_one_locator_dump (vat_main_t * vam)
16480 {
16481   unformat_input_t *input = vam->input;
16482   vl_api_one_locator_dump_t *mp;
16483   vl_api_control_ping_t *mp_ping;
16484   u8 is_index_set = 0, is_name_set = 0;
16485   u8 *ls_name = 0;
16486   u32 ls_index = ~0;
16487   int ret;
16488
16489   /* Parse args required to build the message */
16490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16491     {
16492       if (unformat (input, "ls_name %_%v%_", &ls_name))
16493         {
16494           is_name_set = 1;
16495         }
16496       else if (unformat (input, "ls_index %d", &ls_index))
16497         {
16498           is_index_set = 1;
16499         }
16500       else
16501         {
16502           errmsg ("parse error '%U'", format_unformat_error, input);
16503           return -99;
16504         }
16505     }
16506
16507   if (!is_index_set && !is_name_set)
16508     {
16509       errmsg ("error: expected one of index or name!");
16510       return -99;
16511     }
16512
16513   if (is_index_set && is_name_set)
16514     {
16515       errmsg ("error: only one param expected!");
16516       return -99;
16517     }
16518
16519   if (vec_len (ls_name) > 62)
16520     {
16521       errmsg ("error: locator set name too long!");
16522       return -99;
16523     }
16524
16525   if (!vam->json_output)
16526     {
16527       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16528     }
16529
16530   M (ONE_LOCATOR_DUMP, mp);
16531   mp->is_index_set = is_index_set;
16532
16533   if (is_index_set)
16534     mp->ls_index = clib_host_to_net_u32 (ls_index);
16535   else
16536     {
16537       vec_add1 (ls_name, 0);
16538       strncpy ((char *) mp->ls_name, (char *) ls_name,
16539                sizeof (mp->ls_name) - 1);
16540     }
16541
16542   /* send it... */
16543   S (mp);
16544
16545   /* Use a control ping for synchronization */
16546   M (CONTROL_PING, mp_ping);
16547   S (mp_ping);
16548
16549   /* Wait for a reply... */
16550   W (ret);
16551   return ret;
16552 }
16553
16554 #define api_lisp_locator_dump api_one_locator_dump
16555
16556 static int
16557 api_one_locator_set_dump (vat_main_t * vam)
16558 {
16559   vl_api_one_locator_set_dump_t *mp;
16560   vl_api_control_ping_t *mp_ping;
16561   unformat_input_t *input = vam->input;
16562   u8 filter = 0;
16563   int ret;
16564
16565   /* Parse args required to build the message */
16566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16567     {
16568       if (unformat (input, "local"))
16569         {
16570           filter = 1;
16571         }
16572       else if (unformat (input, "remote"))
16573         {
16574           filter = 2;
16575         }
16576       else
16577         {
16578           errmsg ("parse error '%U'", format_unformat_error, input);
16579           return -99;
16580         }
16581     }
16582
16583   if (!vam->json_output)
16584     {
16585       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16586     }
16587
16588   M (ONE_LOCATOR_SET_DUMP, mp);
16589
16590   mp->filter = filter;
16591
16592   /* send it... */
16593   S (mp);
16594
16595   /* Use a control ping for synchronization */
16596   M (CONTROL_PING, mp_ping);
16597   S (mp_ping);
16598
16599   /* Wait for a reply... */
16600   W (ret);
16601   return ret;
16602 }
16603
16604 #define api_lisp_locator_set_dump api_one_locator_set_dump
16605
16606 static int
16607 api_one_eid_table_map_dump (vat_main_t * vam)
16608 {
16609   u8 is_l2 = 0;
16610   u8 mode_set = 0;
16611   unformat_input_t *input = vam->input;
16612   vl_api_one_eid_table_map_dump_t *mp;
16613   vl_api_control_ping_t *mp_ping;
16614   int ret;
16615
16616   /* Parse args required to build the message */
16617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16618     {
16619       if (unformat (input, "l2"))
16620         {
16621           is_l2 = 1;
16622           mode_set = 1;
16623         }
16624       else if (unformat (input, "l3"))
16625         {
16626           is_l2 = 0;
16627           mode_set = 1;
16628         }
16629       else
16630         {
16631           errmsg ("parse error '%U'", format_unformat_error, input);
16632           return -99;
16633         }
16634     }
16635
16636   if (!mode_set)
16637     {
16638       errmsg ("expected one of 'l2' or 'l3' parameter!");
16639       return -99;
16640     }
16641
16642   if (!vam->json_output)
16643     {
16644       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16645     }
16646
16647   M (ONE_EID_TABLE_MAP_DUMP, mp);
16648   mp->is_l2 = is_l2;
16649
16650   /* send it... */
16651   S (mp);
16652
16653   /* Use a control ping for synchronization */
16654   M (CONTROL_PING, mp_ping);
16655   S (mp_ping);
16656
16657   /* Wait for a reply... */
16658   W (ret);
16659   return ret;
16660 }
16661
16662 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16663
16664 static int
16665 api_one_eid_table_vni_dump (vat_main_t * vam)
16666 {
16667   vl_api_one_eid_table_vni_dump_t *mp;
16668   vl_api_control_ping_t *mp_ping;
16669   int ret;
16670
16671   if (!vam->json_output)
16672     {
16673       print (vam->ofp, "VNI");
16674     }
16675
16676   M (ONE_EID_TABLE_VNI_DUMP, mp);
16677
16678   /* send it... */
16679   S (mp);
16680
16681   /* Use a control ping for synchronization */
16682   M (CONTROL_PING, mp_ping);
16683   S (mp_ping);
16684
16685   /* Wait for a reply... */
16686   W (ret);
16687   return ret;
16688 }
16689
16690 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16691
16692 static int
16693 api_one_eid_table_dump (vat_main_t * vam)
16694 {
16695   unformat_input_t *i = vam->input;
16696   vl_api_one_eid_table_dump_t *mp;
16697   vl_api_control_ping_t *mp_ping;
16698   struct in_addr ip4;
16699   struct in6_addr ip6;
16700   u8 mac[6];
16701   u8 eid_type = ~0, eid_set = 0;
16702   u32 prefix_length = ~0, t, vni = 0;
16703   u8 filter = 0;
16704   int ret;
16705   lisp_nsh_api_t nsh;
16706
16707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16708     {
16709       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16710         {
16711           eid_set = 1;
16712           eid_type = 0;
16713           prefix_length = t;
16714         }
16715       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16716         {
16717           eid_set = 1;
16718           eid_type = 1;
16719           prefix_length = t;
16720         }
16721       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16722         {
16723           eid_set = 1;
16724           eid_type = 2;
16725         }
16726       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16727         {
16728           eid_set = 1;
16729           eid_type = 3;
16730         }
16731       else if (unformat (i, "vni %d", &t))
16732         {
16733           vni = t;
16734         }
16735       else if (unformat (i, "local"))
16736         {
16737           filter = 1;
16738         }
16739       else if (unformat (i, "remote"))
16740         {
16741           filter = 2;
16742         }
16743       else
16744         {
16745           errmsg ("parse error '%U'", format_unformat_error, i);
16746           return -99;
16747         }
16748     }
16749
16750   if (!vam->json_output)
16751     {
16752       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16753              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16754     }
16755
16756   M (ONE_EID_TABLE_DUMP, mp);
16757
16758   mp->filter = filter;
16759   if (eid_set)
16760     {
16761       mp->eid_set = 1;
16762       mp->vni = htonl (vni);
16763       mp->eid_type = eid_type;
16764       switch (eid_type)
16765         {
16766         case 0:
16767           mp->prefix_length = prefix_length;
16768           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16769           break;
16770         case 1:
16771           mp->prefix_length = prefix_length;
16772           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16773           break;
16774         case 2:
16775           clib_memcpy (mp->eid, mac, sizeof (mac));
16776           break;
16777         case 3:
16778           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16779           break;
16780         default:
16781           errmsg ("unknown EID type %d!", eid_type);
16782           return -99;
16783         }
16784     }
16785
16786   /* send it... */
16787   S (mp);
16788
16789   /* Use a control ping for synchronization */
16790   M (CONTROL_PING, mp_ping);
16791   S (mp_ping);
16792
16793   /* Wait for a reply... */
16794   W (ret);
16795   return ret;
16796 }
16797
16798 #define api_lisp_eid_table_dump api_one_eid_table_dump
16799
16800 static int
16801 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16802 {
16803   unformat_input_t *i = vam->input;
16804   vl_api_gpe_fwd_entries_get_t *mp;
16805   u8 vni_set = 0;
16806   u32 vni = ~0;
16807   int ret;
16808
16809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16810     {
16811       if (unformat (i, "vni %d", &vni))
16812         {
16813           vni_set = 1;
16814         }
16815       else
16816         {
16817           errmsg ("parse error '%U'", format_unformat_error, i);
16818           return -99;
16819         }
16820     }
16821
16822   if (!vni_set)
16823     {
16824       errmsg ("vni not set!");
16825       return -99;
16826     }
16827
16828   if (!vam->json_output)
16829     {
16830       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16831              "leid", "reid");
16832     }
16833
16834   M (GPE_FWD_ENTRIES_GET, mp);
16835   mp->vni = clib_host_to_net_u32 (vni);
16836
16837   /* send it... */
16838   S (mp);
16839
16840   /* Wait for a reply... */
16841   W (ret);
16842   return ret;
16843 }
16844
16845 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16846 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16847 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16848 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16849 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16850 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16851 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16852 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16853
16854 static int
16855 api_one_adjacencies_get (vat_main_t * vam)
16856 {
16857   unformat_input_t *i = vam->input;
16858   vl_api_one_adjacencies_get_t *mp;
16859   u8 vni_set = 0;
16860   u32 vni = ~0;
16861   int ret;
16862
16863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16864     {
16865       if (unformat (i, "vni %d", &vni))
16866         {
16867           vni_set = 1;
16868         }
16869       else
16870         {
16871           errmsg ("parse error '%U'", format_unformat_error, i);
16872           return -99;
16873         }
16874     }
16875
16876   if (!vni_set)
16877     {
16878       errmsg ("vni not set!");
16879       return -99;
16880     }
16881
16882   if (!vam->json_output)
16883     {
16884       print (vam->ofp, "%s %40s", "leid", "reid");
16885     }
16886
16887   M (ONE_ADJACENCIES_GET, mp);
16888   mp->vni = clib_host_to_net_u32 (vni);
16889
16890   /* send it... */
16891   S (mp);
16892
16893   /* Wait for a reply... */
16894   W (ret);
16895   return ret;
16896 }
16897
16898 #define api_lisp_adjacencies_get api_one_adjacencies_get
16899
16900 static int
16901 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16902 {
16903   unformat_input_t *i = vam->input;
16904   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16905   int ret;
16906   u8 ip_family_set = 0, is_ip4 = 1;
16907
16908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16909     {
16910       if (unformat (i, "ip4"))
16911         {
16912           ip_family_set = 1;
16913           is_ip4 = 1;
16914         }
16915       else if (unformat (i, "ip6"))
16916         {
16917           ip_family_set = 1;
16918           is_ip4 = 0;
16919         }
16920       else
16921         {
16922           errmsg ("parse error '%U'", format_unformat_error, i);
16923           return -99;
16924         }
16925     }
16926
16927   if (!ip_family_set)
16928     {
16929       errmsg ("ip family not set!");
16930       return -99;
16931     }
16932
16933   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16934   mp->is_ip4 = is_ip4;
16935
16936   /* send it... */
16937   S (mp);
16938
16939   /* Wait for a reply... */
16940   W (ret);
16941   return ret;
16942 }
16943
16944 static int
16945 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16946 {
16947   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16948   int ret;
16949
16950   if (!vam->json_output)
16951     {
16952       print (vam->ofp, "VNIs");
16953     }
16954
16955   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16956
16957   /* send it... */
16958   S (mp);
16959
16960   /* Wait for a reply... */
16961   W (ret);
16962   return ret;
16963 }
16964
16965 static int
16966 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16967 {
16968   unformat_input_t *i = vam->input;
16969   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16970   int ret = 0;
16971   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16972   struct in_addr ip4;
16973   struct in6_addr ip6;
16974   u32 table_id = 0, nh_sw_if_index = ~0;
16975
16976   memset (&ip4, 0, sizeof (ip4));
16977   memset (&ip6, 0, sizeof (ip6));
16978
16979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16980     {
16981       if (unformat (i, "del"))
16982         is_add = 0;
16983       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16984                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16985         {
16986           ip_set = 1;
16987           is_ip4 = 1;
16988         }
16989       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16990                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16991         {
16992           ip_set = 1;
16993           is_ip4 = 0;
16994         }
16995       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16996         {
16997           ip_set = 1;
16998           is_ip4 = 1;
16999           nh_sw_if_index = ~0;
17000         }
17001       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17002         {
17003           ip_set = 1;
17004           is_ip4 = 0;
17005           nh_sw_if_index = ~0;
17006         }
17007       else if (unformat (i, "table %d", &table_id))
17008         ;
17009       else
17010         {
17011           errmsg ("parse error '%U'", format_unformat_error, i);
17012           return -99;
17013         }
17014     }
17015
17016   if (!ip_set)
17017     {
17018       errmsg ("nh addr not set!");
17019       return -99;
17020     }
17021
17022   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17023   mp->is_add = is_add;
17024   mp->table_id = clib_host_to_net_u32 (table_id);
17025   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17026   mp->is_ip4 = is_ip4;
17027   if (is_ip4)
17028     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17029   else
17030     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17031
17032   /* send it... */
17033   S (mp);
17034
17035   /* Wait for a reply... */
17036   W (ret);
17037   return ret;
17038 }
17039
17040 static int
17041 api_one_map_server_dump (vat_main_t * vam)
17042 {
17043   vl_api_one_map_server_dump_t *mp;
17044   vl_api_control_ping_t *mp_ping;
17045   int ret;
17046
17047   if (!vam->json_output)
17048     {
17049       print (vam->ofp, "%=20s", "Map server");
17050     }
17051
17052   M (ONE_MAP_SERVER_DUMP, mp);
17053   /* send it... */
17054   S (mp);
17055
17056   /* Use a control ping for synchronization */
17057   M (CONTROL_PING, mp_ping);
17058   S (mp_ping);
17059
17060   /* Wait for a reply... */
17061   W (ret);
17062   return ret;
17063 }
17064
17065 #define api_lisp_map_server_dump api_one_map_server_dump
17066
17067 static int
17068 api_one_map_resolver_dump (vat_main_t * vam)
17069 {
17070   vl_api_one_map_resolver_dump_t *mp;
17071   vl_api_control_ping_t *mp_ping;
17072   int ret;
17073
17074   if (!vam->json_output)
17075     {
17076       print (vam->ofp, "%=20s", "Map resolver");
17077     }
17078
17079   M (ONE_MAP_RESOLVER_DUMP, mp);
17080   /* send it... */
17081   S (mp);
17082
17083   /* Use a control ping for synchronization */
17084   M (CONTROL_PING, mp_ping);
17085   S (mp_ping);
17086
17087   /* Wait for a reply... */
17088   W (ret);
17089   return ret;
17090 }
17091
17092 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17093
17094 static int
17095 api_one_stats_flush (vat_main_t * vam)
17096 {
17097   vl_api_one_stats_flush_t *mp;
17098   int ret = 0;
17099
17100   M (ONE_STATS_FLUSH, mp);
17101   S (mp);
17102   W (ret);
17103   return ret;
17104 }
17105
17106 static int
17107 api_one_stats_dump (vat_main_t * vam)
17108 {
17109   vl_api_one_stats_dump_t *mp;
17110   vl_api_control_ping_t *mp_ping;
17111   int ret;
17112
17113   M (ONE_STATS_DUMP, mp);
17114   /* send it... */
17115   S (mp);
17116
17117   /* Use a control ping for synchronization */
17118   M (CONTROL_PING, mp_ping);
17119   S (mp_ping);
17120
17121   /* Wait for a reply... */
17122   W (ret);
17123   return ret;
17124 }
17125
17126 static int
17127 api_show_one_status (vat_main_t * vam)
17128 {
17129   vl_api_show_one_status_t *mp;
17130   int ret;
17131
17132   if (!vam->json_output)
17133     {
17134       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17135     }
17136
17137   M (SHOW_ONE_STATUS, mp);
17138   /* send it... */
17139   S (mp);
17140   /* Wait for a reply... */
17141   W (ret);
17142   return ret;
17143 }
17144
17145 #define api_show_lisp_status api_show_one_status
17146
17147 static int
17148 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17149 {
17150   vl_api_gpe_fwd_entry_path_dump_t *mp;
17151   vl_api_control_ping_t *mp_ping;
17152   unformat_input_t *i = vam->input;
17153   u32 fwd_entry_index = ~0;
17154   int ret;
17155
17156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17157     {
17158       if (unformat (i, "index %d", &fwd_entry_index))
17159         ;
17160       else
17161         break;
17162     }
17163
17164   if (~0 == fwd_entry_index)
17165     {
17166       errmsg ("no index specified!");
17167       return -99;
17168     }
17169
17170   if (!vam->json_output)
17171     {
17172       print (vam->ofp, "first line");
17173     }
17174
17175   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17176
17177   /* send it... */
17178   S (mp);
17179   /* Use a control ping for synchronization */
17180   M (CONTROL_PING, mp_ping);
17181   S (mp_ping);
17182
17183   /* Wait for a reply... */
17184   W (ret);
17185   return ret;
17186 }
17187
17188 static int
17189 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17190 {
17191   vl_api_one_get_map_request_itr_rlocs_t *mp;
17192   int ret;
17193
17194   if (!vam->json_output)
17195     {
17196       print (vam->ofp, "%=20s", "itr-rlocs:");
17197     }
17198
17199   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17200   /* send it... */
17201   S (mp);
17202   /* Wait for a reply... */
17203   W (ret);
17204   return ret;
17205 }
17206
17207 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17208
17209 static int
17210 api_af_packet_create (vat_main_t * vam)
17211 {
17212   unformat_input_t *i = vam->input;
17213   vl_api_af_packet_create_t *mp;
17214   u8 *host_if_name = 0;
17215   u8 hw_addr[6];
17216   u8 random_hw_addr = 1;
17217   int ret;
17218
17219   memset (hw_addr, 0, sizeof (hw_addr));
17220
17221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17222     {
17223       if (unformat (i, "name %s", &host_if_name))
17224         vec_add1 (host_if_name, 0);
17225       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17226         random_hw_addr = 0;
17227       else
17228         break;
17229     }
17230
17231   if (!vec_len (host_if_name))
17232     {
17233       errmsg ("host-interface name must be specified");
17234       return -99;
17235     }
17236
17237   if (vec_len (host_if_name) > 64)
17238     {
17239       errmsg ("host-interface name too long");
17240       return -99;
17241     }
17242
17243   M (AF_PACKET_CREATE, mp);
17244
17245   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17246   clib_memcpy (mp->hw_addr, hw_addr, 6);
17247   mp->use_random_hw_addr = random_hw_addr;
17248   vec_free (host_if_name);
17249
17250   S (mp);
17251
17252   /* *INDENT-OFF* */
17253   W2 (ret,
17254       ({
17255         if (ret == 0)
17256           fprintf (vam->ofp ? vam->ofp : stderr,
17257                    " new sw_if_index = %d\n", vam->sw_if_index);
17258       }));
17259   /* *INDENT-ON* */
17260   return ret;
17261 }
17262
17263 static int
17264 api_af_packet_delete (vat_main_t * vam)
17265 {
17266   unformat_input_t *i = vam->input;
17267   vl_api_af_packet_delete_t *mp;
17268   u8 *host_if_name = 0;
17269   int ret;
17270
17271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17272     {
17273       if (unformat (i, "name %s", &host_if_name))
17274         vec_add1 (host_if_name, 0);
17275       else
17276         break;
17277     }
17278
17279   if (!vec_len (host_if_name))
17280     {
17281       errmsg ("host-interface name must be specified");
17282       return -99;
17283     }
17284
17285   if (vec_len (host_if_name) > 64)
17286     {
17287       errmsg ("host-interface name too long");
17288       return -99;
17289     }
17290
17291   M (AF_PACKET_DELETE, mp);
17292
17293   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17294   vec_free (host_if_name);
17295
17296   S (mp);
17297   W (ret);
17298   return ret;
17299 }
17300
17301 static int
17302 api_policer_add_del (vat_main_t * vam)
17303 {
17304   unformat_input_t *i = vam->input;
17305   vl_api_policer_add_del_t *mp;
17306   u8 is_add = 1;
17307   u8 *name = 0;
17308   u32 cir = 0;
17309   u32 eir = 0;
17310   u64 cb = 0;
17311   u64 eb = 0;
17312   u8 rate_type = 0;
17313   u8 round_type = 0;
17314   u8 type = 0;
17315   u8 color_aware = 0;
17316   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17317   int ret;
17318
17319   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17320   conform_action.dscp = 0;
17321   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17322   exceed_action.dscp = 0;
17323   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17324   violate_action.dscp = 0;
17325
17326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17327     {
17328       if (unformat (i, "del"))
17329         is_add = 0;
17330       else if (unformat (i, "name %s", &name))
17331         vec_add1 (name, 0);
17332       else if (unformat (i, "cir %u", &cir))
17333         ;
17334       else if (unformat (i, "eir %u", &eir))
17335         ;
17336       else if (unformat (i, "cb %u", &cb))
17337         ;
17338       else if (unformat (i, "eb %u", &eb))
17339         ;
17340       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17341                          &rate_type))
17342         ;
17343       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17344                          &round_type))
17345         ;
17346       else if (unformat (i, "type %U", unformat_policer_type, &type))
17347         ;
17348       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17349                          &conform_action))
17350         ;
17351       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17352                          &exceed_action))
17353         ;
17354       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17355                          &violate_action))
17356         ;
17357       else if (unformat (i, "color-aware"))
17358         color_aware = 1;
17359       else
17360         break;
17361     }
17362
17363   if (!vec_len (name))
17364     {
17365       errmsg ("policer name must be specified");
17366       return -99;
17367     }
17368
17369   if (vec_len (name) > 64)
17370     {
17371       errmsg ("policer name too long");
17372       return -99;
17373     }
17374
17375   M (POLICER_ADD_DEL, mp);
17376
17377   clib_memcpy (mp->name, name, vec_len (name));
17378   vec_free (name);
17379   mp->is_add = is_add;
17380   mp->cir = cir;
17381   mp->eir = eir;
17382   mp->cb = cb;
17383   mp->eb = eb;
17384   mp->rate_type = rate_type;
17385   mp->round_type = round_type;
17386   mp->type = type;
17387   mp->conform_action_type = conform_action.action_type;
17388   mp->conform_dscp = conform_action.dscp;
17389   mp->exceed_action_type = exceed_action.action_type;
17390   mp->exceed_dscp = exceed_action.dscp;
17391   mp->violate_action_type = violate_action.action_type;
17392   mp->violate_dscp = violate_action.dscp;
17393   mp->color_aware = color_aware;
17394
17395   S (mp);
17396   W (ret);
17397   return ret;
17398 }
17399
17400 static int
17401 api_policer_dump (vat_main_t * vam)
17402 {
17403   unformat_input_t *i = vam->input;
17404   vl_api_policer_dump_t *mp;
17405   vl_api_control_ping_t *mp_ping;
17406   u8 *match_name = 0;
17407   u8 match_name_valid = 0;
17408   int ret;
17409
17410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17411     {
17412       if (unformat (i, "name %s", &match_name))
17413         {
17414           vec_add1 (match_name, 0);
17415           match_name_valid = 1;
17416         }
17417       else
17418         break;
17419     }
17420
17421   M (POLICER_DUMP, mp);
17422   mp->match_name_valid = match_name_valid;
17423   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17424   vec_free (match_name);
17425   /* send it... */
17426   S (mp);
17427
17428   /* Use a control ping for synchronization */
17429   M (CONTROL_PING, mp_ping);
17430   S (mp_ping);
17431
17432   /* Wait for a reply... */
17433   W (ret);
17434   return ret;
17435 }
17436
17437 static int
17438 api_policer_classify_set_interface (vat_main_t * vam)
17439 {
17440   unformat_input_t *i = vam->input;
17441   vl_api_policer_classify_set_interface_t *mp;
17442   u32 sw_if_index;
17443   int sw_if_index_set;
17444   u32 ip4_table_index = ~0;
17445   u32 ip6_table_index = ~0;
17446   u32 l2_table_index = ~0;
17447   u8 is_add = 1;
17448   int ret;
17449
17450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17451     {
17452       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17453         sw_if_index_set = 1;
17454       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17455         sw_if_index_set = 1;
17456       else if (unformat (i, "del"))
17457         is_add = 0;
17458       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17459         ;
17460       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17461         ;
17462       else if (unformat (i, "l2-table %d", &l2_table_index))
17463         ;
17464       else
17465         {
17466           clib_warning ("parse error '%U'", format_unformat_error, i);
17467           return -99;
17468         }
17469     }
17470
17471   if (sw_if_index_set == 0)
17472     {
17473       errmsg ("missing interface name or sw_if_index");
17474       return -99;
17475     }
17476
17477   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17478
17479   mp->sw_if_index = ntohl (sw_if_index);
17480   mp->ip4_table_index = ntohl (ip4_table_index);
17481   mp->ip6_table_index = ntohl (ip6_table_index);
17482   mp->l2_table_index = ntohl (l2_table_index);
17483   mp->is_add = is_add;
17484
17485   S (mp);
17486   W (ret);
17487   return ret;
17488 }
17489
17490 static int
17491 api_policer_classify_dump (vat_main_t * vam)
17492 {
17493   unformat_input_t *i = vam->input;
17494   vl_api_policer_classify_dump_t *mp;
17495   vl_api_control_ping_t *mp_ping;
17496   u8 type = POLICER_CLASSIFY_N_TABLES;
17497   int ret;
17498
17499   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17500     ;
17501   else
17502     {
17503       errmsg ("classify table type must be specified");
17504       return -99;
17505     }
17506
17507   if (!vam->json_output)
17508     {
17509       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17510     }
17511
17512   M (POLICER_CLASSIFY_DUMP, mp);
17513   mp->type = type;
17514   /* send it... */
17515   S (mp);
17516
17517   /* Use a control ping for synchronization */
17518   M (CONTROL_PING, mp_ping);
17519   S (mp_ping);
17520
17521   /* Wait for a reply... */
17522   W (ret);
17523   return ret;
17524 }
17525
17526 static int
17527 api_netmap_create (vat_main_t * vam)
17528 {
17529   unformat_input_t *i = vam->input;
17530   vl_api_netmap_create_t *mp;
17531   u8 *if_name = 0;
17532   u8 hw_addr[6];
17533   u8 random_hw_addr = 1;
17534   u8 is_pipe = 0;
17535   u8 is_master = 0;
17536   int ret;
17537
17538   memset (hw_addr, 0, sizeof (hw_addr));
17539
17540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17541     {
17542       if (unformat (i, "name %s", &if_name))
17543         vec_add1 (if_name, 0);
17544       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17545         random_hw_addr = 0;
17546       else if (unformat (i, "pipe"))
17547         is_pipe = 1;
17548       else if (unformat (i, "master"))
17549         is_master = 1;
17550       else if (unformat (i, "slave"))
17551         is_master = 0;
17552       else
17553         break;
17554     }
17555
17556   if (!vec_len (if_name))
17557     {
17558       errmsg ("interface name must be specified");
17559       return -99;
17560     }
17561
17562   if (vec_len (if_name) > 64)
17563     {
17564       errmsg ("interface name too long");
17565       return -99;
17566     }
17567
17568   M (NETMAP_CREATE, mp);
17569
17570   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17571   clib_memcpy (mp->hw_addr, hw_addr, 6);
17572   mp->use_random_hw_addr = random_hw_addr;
17573   mp->is_pipe = is_pipe;
17574   mp->is_master = is_master;
17575   vec_free (if_name);
17576
17577   S (mp);
17578   W (ret);
17579   return ret;
17580 }
17581
17582 static int
17583 api_netmap_delete (vat_main_t * vam)
17584 {
17585   unformat_input_t *i = vam->input;
17586   vl_api_netmap_delete_t *mp;
17587   u8 *if_name = 0;
17588   int ret;
17589
17590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17591     {
17592       if (unformat (i, "name %s", &if_name))
17593         vec_add1 (if_name, 0);
17594       else
17595         break;
17596     }
17597
17598   if (!vec_len (if_name))
17599     {
17600       errmsg ("interface name must be specified");
17601       return -99;
17602     }
17603
17604   if (vec_len (if_name) > 64)
17605     {
17606       errmsg ("interface name too long");
17607       return -99;
17608     }
17609
17610   M (NETMAP_DELETE, mp);
17611
17612   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17613   vec_free (if_name);
17614
17615   S (mp);
17616   W (ret);
17617   return ret;
17618 }
17619
17620 static void
17621 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17622 {
17623   if (fp->afi == IP46_TYPE_IP6)
17624     print (vam->ofp,
17625            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17626            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17627            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17628            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17629            format_ip6_address, fp->next_hop);
17630   else if (fp->afi == IP46_TYPE_IP4)
17631     print (vam->ofp,
17632            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17633            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17634            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17635            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17636            format_ip4_address, fp->next_hop);
17637 }
17638
17639 static void
17640 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17641                                  vl_api_fib_path2_t * fp)
17642 {
17643   struct in_addr ip4;
17644   struct in6_addr ip6;
17645
17646   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17647   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17648   vat_json_object_add_uint (node, "is_local", fp->is_local);
17649   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17650   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17651   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17652   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17653   if (fp->afi == IP46_TYPE_IP4)
17654     {
17655       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17656       vat_json_object_add_ip4 (node, "next_hop", ip4);
17657     }
17658   else if (fp->afi == IP46_TYPE_IP6)
17659     {
17660       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17661       vat_json_object_add_ip6 (node, "next_hop", ip6);
17662     }
17663 }
17664
17665 static void
17666 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17667 {
17668   vat_main_t *vam = &vat_main;
17669   int count = ntohl (mp->mt_count);
17670   vl_api_fib_path2_t *fp;
17671   i32 i;
17672
17673   print (vam->ofp, "[%d]: sw_if_index %d via:",
17674          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17675   fp = mp->mt_paths;
17676   for (i = 0; i < count; i++)
17677     {
17678       vl_api_mpls_fib_path_print (vam, fp);
17679       fp++;
17680     }
17681
17682   print (vam->ofp, "");
17683 }
17684
17685 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17686 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17687
17688 static void
17689 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17690 {
17691   vat_main_t *vam = &vat_main;
17692   vat_json_node_t *node = NULL;
17693   int count = ntohl (mp->mt_count);
17694   vl_api_fib_path2_t *fp;
17695   i32 i;
17696
17697   if (VAT_JSON_ARRAY != vam->json_tree.type)
17698     {
17699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17700       vat_json_init_array (&vam->json_tree);
17701     }
17702   node = vat_json_array_add (&vam->json_tree);
17703
17704   vat_json_init_object (node);
17705   vat_json_object_add_uint (node, "tunnel_index",
17706                             ntohl (mp->mt_tunnel_index));
17707   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17708
17709   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17710
17711   fp = mp->mt_paths;
17712   for (i = 0; i < count; i++)
17713     {
17714       vl_api_mpls_fib_path_json_print (node, fp);
17715       fp++;
17716     }
17717 }
17718
17719 static int
17720 api_mpls_tunnel_dump (vat_main_t * vam)
17721 {
17722   vl_api_mpls_tunnel_dump_t *mp;
17723   vl_api_control_ping_t *mp_ping;
17724   i32 index = -1;
17725   int ret;
17726
17727   /* Parse args required to build the message */
17728   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17729     {
17730       if (!unformat (vam->input, "tunnel_index %d", &index))
17731         {
17732           index = -1;
17733           break;
17734         }
17735     }
17736
17737   print (vam->ofp, "  tunnel_index %d", index);
17738
17739   M (MPLS_TUNNEL_DUMP, mp);
17740   mp->tunnel_index = htonl (index);
17741   S (mp);
17742
17743   /* Use a control ping for synchronization */
17744   M (CONTROL_PING, mp_ping);
17745   S (mp_ping);
17746
17747   W (ret);
17748   return ret;
17749 }
17750
17751 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17752 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17753
17754
17755 static void
17756 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17757 {
17758   vat_main_t *vam = &vat_main;
17759   int count = ntohl (mp->count);
17760   vl_api_fib_path2_t *fp;
17761   int i;
17762
17763   print (vam->ofp,
17764          "table-id %d, label %u, ess_bit %u",
17765          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17766   fp = mp->path;
17767   for (i = 0; i < count; i++)
17768     {
17769       vl_api_mpls_fib_path_print (vam, fp);
17770       fp++;
17771     }
17772 }
17773
17774 static void vl_api_mpls_fib_details_t_handler_json
17775   (vl_api_mpls_fib_details_t * mp)
17776 {
17777   vat_main_t *vam = &vat_main;
17778   int count = ntohl (mp->count);
17779   vat_json_node_t *node = NULL;
17780   vl_api_fib_path2_t *fp;
17781   int i;
17782
17783   if (VAT_JSON_ARRAY != vam->json_tree.type)
17784     {
17785       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17786       vat_json_init_array (&vam->json_tree);
17787     }
17788   node = vat_json_array_add (&vam->json_tree);
17789
17790   vat_json_init_object (node);
17791   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17792   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17793   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17794   vat_json_object_add_uint (node, "path_count", count);
17795   fp = mp->path;
17796   for (i = 0; i < count; i++)
17797     {
17798       vl_api_mpls_fib_path_json_print (node, fp);
17799       fp++;
17800     }
17801 }
17802
17803 static int
17804 api_mpls_fib_dump (vat_main_t * vam)
17805 {
17806   vl_api_mpls_fib_dump_t *mp;
17807   vl_api_control_ping_t *mp_ping;
17808   int ret;
17809
17810   M (MPLS_FIB_DUMP, mp);
17811   S (mp);
17812
17813   /* Use a control ping for synchronization */
17814   M (CONTROL_PING, mp_ping);
17815   S (mp_ping);
17816
17817   W (ret);
17818   return ret;
17819 }
17820
17821 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17822 #define vl_api_ip_fib_details_t_print vl_noop_handler
17823
17824 static void
17825 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17826 {
17827   vat_main_t *vam = &vat_main;
17828   int count = ntohl (mp->count);
17829   vl_api_fib_path_t *fp;
17830   int i;
17831
17832   print (vam->ofp,
17833          "table-id %d, prefix %U/%d",
17834          ntohl (mp->table_id), format_ip4_address, mp->address,
17835          mp->address_length);
17836   fp = mp->path;
17837   for (i = 0; i < count; i++)
17838     {
17839       if (fp->afi == IP46_TYPE_IP6)
17840         print (vam->ofp,
17841                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17842                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17843                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17844                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17845                format_ip6_address, fp->next_hop);
17846       else if (fp->afi == IP46_TYPE_IP4)
17847         print (vam->ofp,
17848                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17849                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17850                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17851                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17852                format_ip4_address, fp->next_hop);
17853       fp++;
17854     }
17855 }
17856
17857 static void vl_api_ip_fib_details_t_handler_json
17858   (vl_api_ip_fib_details_t * mp)
17859 {
17860   vat_main_t *vam = &vat_main;
17861   int count = ntohl (mp->count);
17862   vat_json_node_t *node = NULL;
17863   struct in_addr ip4;
17864   struct in6_addr ip6;
17865   vl_api_fib_path_t *fp;
17866   int i;
17867
17868   if (VAT_JSON_ARRAY != vam->json_tree.type)
17869     {
17870       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17871       vat_json_init_array (&vam->json_tree);
17872     }
17873   node = vat_json_array_add (&vam->json_tree);
17874
17875   vat_json_init_object (node);
17876   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17877   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17878   vat_json_object_add_ip4 (node, "prefix", ip4);
17879   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17880   vat_json_object_add_uint (node, "path_count", count);
17881   fp = mp->path;
17882   for (i = 0; i < count; i++)
17883     {
17884       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17885       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17886       vat_json_object_add_uint (node, "is_local", fp->is_local);
17887       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17888       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17889       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17890       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17891       if (fp->afi == IP46_TYPE_IP4)
17892         {
17893           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17894           vat_json_object_add_ip4 (node, "next_hop", ip4);
17895         }
17896       else if (fp->afi == IP46_TYPE_IP6)
17897         {
17898           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17899           vat_json_object_add_ip6 (node, "next_hop", ip6);
17900         }
17901     }
17902 }
17903
17904 static int
17905 api_ip_fib_dump (vat_main_t * vam)
17906 {
17907   vl_api_ip_fib_dump_t *mp;
17908   vl_api_control_ping_t *mp_ping;
17909   int ret;
17910
17911   M (IP_FIB_DUMP, mp);
17912   S (mp);
17913
17914   /* Use a control ping for synchronization */
17915   M (CONTROL_PING, mp_ping);
17916   S (mp_ping);
17917
17918   W (ret);
17919   return ret;
17920 }
17921
17922 static int
17923 api_ip_mfib_dump (vat_main_t * vam)
17924 {
17925   vl_api_ip_mfib_dump_t *mp;
17926   vl_api_control_ping_t *mp_ping;
17927   int ret;
17928
17929   M (IP_MFIB_DUMP, mp);
17930   S (mp);
17931
17932   /* Use a control ping for synchronization */
17933   M (CONTROL_PING, mp_ping);
17934   S (mp_ping);
17935
17936   W (ret);
17937   return ret;
17938 }
17939
17940 static void vl_api_ip_neighbor_details_t_handler
17941   (vl_api_ip_neighbor_details_t * mp)
17942 {
17943   vat_main_t *vam = &vat_main;
17944
17945   print (vam->ofp, "%c %U %U",
17946          (mp->is_static) ? 'S' : 'D',
17947          format_ethernet_address, &mp->mac_address,
17948          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17949          &mp->ip_address);
17950 }
17951
17952 static void vl_api_ip_neighbor_details_t_handler_json
17953   (vl_api_ip_neighbor_details_t * mp)
17954 {
17955
17956   vat_main_t *vam = &vat_main;
17957   vat_json_node_t *node;
17958   struct in_addr ip4;
17959   struct in6_addr ip6;
17960
17961   if (VAT_JSON_ARRAY != vam->json_tree.type)
17962     {
17963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17964       vat_json_init_array (&vam->json_tree);
17965     }
17966   node = vat_json_array_add (&vam->json_tree);
17967
17968   vat_json_init_object (node);
17969   vat_json_object_add_string_copy (node, "flag",
17970                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17971                                    "dynamic");
17972
17973   vat_json_object_add_string_copy (node, "link_layer",
17974                                    format (0, "%U", format_ethernet_address,
17975                                            &mp->mac_address));
17976
17977   if (mp->is_ipv6)
17978     {
17979       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17980       vat_json_object_add_ip6 (node, "ip_address", ip6);
17981     }
17982   else
17983     {
17984       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17985       vat_json_object_add_ip4 (node, "ip_address", ip4);
17986     }
17987 }
17988
17989 static int
17990 api_ip_neighbor_dump (vat_main_t * vam)
17991 {
17992   unformat_input_t *i = vam->input;
17993   vl_api_ip_neighbor_dump_t *mp;
17994   vl_api_control_ping_t *mp_ping;
17995   u8 is_ipv6 = 0;
17996   u32 sw_if_index = ~0;
17997   int ret;
17998
17999   /* Parse args required to build the message */
18000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18001     {
18002       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18003         ;
18004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18005         ;
18006       else if (unformat (i, "ip6"))
18007         is_ipv6 = 1;
18008       else
18009         break;
18010     }
18011
18012   if (sw_if_index == ~0)
18013     {
18014       errmsg ("missing interface name or sw_if_index");
18015       return -99;
18016     }
18017
18018   M (IP_NEIGHBOR_DUMP, mp);
18019   mp->is_ipv6 = (u8) is_ipv6;
18020   mp->sw_if_index = ntohl (sw_if_index);
18021   S (mp);
18022
18023   /* Use a control ping for synchronization */
18024   M (CONTROL_PING, mp_ping);
18025   S (mp_ping);
18026
18027   W (ret);
18028   return ret;
18029 }
18030
18031 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
18032 #define vl_api_ip6_fib_details_t_print vl_noop_handler
18033
18034 static void
18035 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
18036 {
18037   vat_main_t *vam = &vat_main;
18038   int count = ntohl (mp->count);
18039   vl_api_fib_path_t *fp;
18040   int i;
18041
18042   print (vam->ofp,
18043          "table-id %d, prefix %U/%d",
18044          ntohl (mp->table_id), format_ip6_address, mp->address,
18045          mp->address_length);
18046   fp = mp->path;
18047   for (i = 0; i < count; i++)
18048     {
18049       if (fp->afi == IP46_TYPE_IP6)
18050         print (vam->ofp,
18051                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18052                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18053                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18054                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18055                format_ip6_address, fp->next_hop);
18056       else if (fp->afi == IP46_TYPE_IP4)
18057         print (vam->ofp,
18058                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18059                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18060                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18061                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18062                format_ip4_address, fp->next_hop);
18063       fp++;
18064     }
18065 }
18066
18067 static void vl_api_ip6_fib_details_t_handler_json
18068   (vl_api_ip6_fib_details_t * mp)
18069 {
18070   vat_main_t *vam = &vat_main;
18071   int count = ntohl (mp->count);
18072   vat_json_node_t *node = NULL;
18073   struct in_addr ip4;
18074   struct in6_addr ip6;
18075   vl_api_fib_path_t *fp;
18076   int i;
18077
18078   if (VAT_JSON_ARRAY != vam->json_tree.type)
18079     {
18080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18081       vat_json_init_array (&vam->json_tree);
18082     }
18083   node = vat_json_array_add (&vam->json_tree);
18084
18085   vat_json_init_object (node);
18086   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18087   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
18088   vat_json_object_add_ip6 (node, "prefix", ip6);
18089   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18090   vat_json_object_add_uint (node, "path_count", count);
18091   fp = mp->path;
18092   for (i = 0; i < count; i++)
18093     {
18094       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18095       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18096       vat_json_object_add_uint (node, "is_local", fp->is_local);
18097       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18098       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18099       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18100       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18101       if (fp->afi == IP46_TYPE_IP4)
18102         {
18103           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18104           vat_json_object_add_ip4 (node, "next_hop", ip4);
18105         }
18106       else if (fp->afi == IP46_TYPE_IP6)
18107         {
18108           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18109           vat_json_object_add_ip6 (node, "next_hop", ip6);
18110         }
18111     }
18112 }
18113
18114 static int
18115 api_ip6_fib_dump (vat_main_t * vam)
18116 {
18117   vl_api_ip6_fib_dump_t *mp;
18118   vl_api_control_ping_t *mp_ping;
18119   int ret;
18120
18121   M (IP6_FIB_DUMP, mp);
18122   S (mp);
18123
18124   /* Use a control ping for synchronization */
18125   M (CONTROL_PING, mp_ping);
18126   S (mp_ping);
18127
18128   W (ret);
18129   return ret;
18130 }
18131
18132 static int
18133 api_ip6_mfib_dump (vat_main_t * vam)
18134 {
18135   vl_api_ip6_mfib_dump_t *mp;
18136   vl_api_control_ping_t *mp_ping;
18137   int ret;
18138
18139   M (IP6_MFIB_DUMP, mp);
18140   S (mp);
18141
18142   /* Use a control ping for synchronization */
18143   M (CONTROL_PING, mp_ping);
18144   S (mp_ping);
18145
18146   W (ret);
18147   return ret;
18148 }
18149
18150 int
18151 api_classify_table_ids (vat_main_t * vam)
18152 {
18153   vl_api_classify_table_ids_t *mp;
18154   int ret;
18155
18156   /* Construct the API message */
18157   M (CLASSIFY_TABLE_IDS, mp);
18158   mp->context = 0;
18159
18160   S (mp);
18161   W (ret);
18162   return ret;
18163 }
18164
18165 int
18166 api_classify_table_by_interface (vat_main_t * vam)
18167 {
18168   unformat_input_t *input = vam->input;
18169   vl_api_classify_table_by_interface_t *mp;
18170
18171   u32 sw_if_index = ~0;
18172   int ret;
18173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18174     {
18175       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18176         ;
18177       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18178         ;
18179       else
18180         break;
18181     }
18182   if (sw_if_index == ~0)
18183     {
18184       errmsg ("missing interface name or sw_if_index");
18185       return -99;
18186     }
18187
18188   /* Construct the API message */
18189   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18190   mp->context = 0;
18191   mp->sw_if_index = ntohl (sw_if_index);
18192
18193   S (mp);
18194   W (ret);
18195   return ret;
18196 }
18197
18198 int
18199 api_classify_table_info (vat_main_t * vam)
18200 {
18201   unformat_input_t *input = vam->input;
18202   vl_api_classify_table_info_t *mp;
18203
18204   u32 table_id = ~0;
18205   int ret;
18206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18207     {
18208       if (unformat (input, "table_id %d", &table_id))
18209         ;
18210       else
18211         break;
18212     }
18213   if (table_id == ~0)
18214     {
18215       errmsg ("missing table id");
18216       return -99;
18217     }
18218
18219   /* Construct the API message */
18220   M (CLASSIFY_TABLE_INFO, mp);
18221   mp->context = 0;
18222   mp->table_id = ntohl (table_id);
18223
18224   S (mp);
18225   W (ret);
18226   return ret;
18227 }
18228
18229 int
18230 api_classify_session_dump (vat_main_t * vam)
18231 {
18232   unformat_input_t *input = vam->input;
18233   vl_api_classify_session_dump_t *mp;
18234   vl_api_control_ping_t *mp_ping;
18235
18236   u32 table_id = ~0;
18237   int ret;
18238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18239     {
18240       if (unformat (input, "table_id %d", &table_id))
18241         ;
18242       else
18243         break;
18244     }
18245   if (table_id == ~0)
18246     {
18247       errmsg ("missing table id");
18248       return -99;
18249     }
18250
18251   /* Construct the API message */
18252   M (CLASSIFY_SESSION_DUMP, mp);
18253   mp->context = 0;
18254   mp->table_id = ntohl (table_id);
18255   S (mp);
18256
18257   /* Use a control ping for synchronization */
18258   M (CONTROL_PING, mp_ping);
18259   S (mp_ping);
18260
18261   W (ret);
18262   return ret;
18263 }
18264
18265 static void
18266 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18267 {
18268   vat_main_t *vam = &vat_main;
18269
18270   print (vam->ofp, "collector_address %U, collector_port %d, "
18271          "src_address %U, vrf_id %d, path_mtu %u, "
18272          "template_interval %u, udp_checksum %d",
18273          format_ip4_address, mp->collector_address,
18274          ntohs (mp->collector_port),
18275          format_ip4_address, mp->src_address,
18276          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18277          ntohl (mp->template_interval), mp->udp_checksum);
18278
18279   vam->retval = 0;
18280   vam->result_ready = 1;
18281 }
18282
18283 static void
18284   vl_api_ipfix_exporter_details_t_handler_json
18285   (vl_api_ipfix_exporter_details_t * mp)
18286 {
18287   vat_main_t *vam = &vat_main;
18288   vat_json_node_t node;
18289   struct in_addr collector_address;
18290   struct in_addr src_address;
18291
18292   vat_json_init_object (&node);
18293   clib_memcpy (&collector_address, &mp->collector_address,
18294                sizeof (collector_address));
18295   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18296   vat_json_object_add_uint (&node, "collector_port",
18297                             ntohs (mp->collector_port));
18298   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18299   vat_json_object_add_ip4 (&node, "src_address", src_address);
18300   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18301   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18302   vat_json_object_add_uint (&node, "template_interval",
18303                             ntohl (mp->template_interval));
18304   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18305
18306   vat_json_print (vam->ofp, &node);
18307   vat_json_free (&node);
18308   vam->retval = 0;
18309   vam->result_ready = 1;
18310 }
18311
18312 int
18313 api_ipfix_exporter_dump (vat_main_t * vam)
18314 {
18315   vl_api_ipfix_exporter_dump_t *mp;
18316   int ret;
18317
18318   /* Construct the API message */
18319   M (IPFIX_EXPORTER_DUMP, mp);
18320   mp->context = 0;
18321
18322   S (mp);
18323   W (ret);
18324   return ret;
18325 }
18326
18327 static int
18328 api_ipfix_classify_stream_dump (vat_main_t * vam)
18329 {
18330   vl_api_ipfix_classify_stream_dump_t *mp;
18331   int ret;
18332
18333   /* Construct the API message */
18334   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18335   mp->context = 0;
18336
18337   S (mp);
18338   W (ret);
18339   return ret;
18340   /* NOTREACHED */
18341   return 0;
18342 }
18343
18344 static void
18345   vl_api_ipfix_classify_stream_details_t_handler
18346   (vl_api_ipfix_classify_stream_details_t * mp)
18347 {
18348   vat_main_t *vam = &vat_main;
18349   print (vam->ofp, "domain_id %d, src_port %d",
18350          ntohl (mp->domain_id), ntohs (mp->src_port));
18351   vam->retval = 0;
18352   vam->result_ready = 1;
18353 }
18354
18355 static void
18356   vl_api_ipfix_classify_stream_details_t_handler_json
18357   (vl_api_ipfix_classify_stream_details_t * mp)
18358 {
18359   vat_main_t *vam = &vat_main;
18360   vat_json_node_t node;
18361
18362   vat_json_init_object (&node);
18363   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18364   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18365
18366   vat_json_print (vam->ofp, &node);
18367   vat_json_free (&node);
18368   vam->retval = 0;
18369   vam->result_ready = 1;
18370 }
18371
18372 static int
18373 api_ipfix_classify_table_dump (vat_main_t * vam)
18374 {
18375   vl_api_ipfix_classify_table_dump_t *mp;
18376   vl_api_control_ping_t *mp_ping;
18377   int ret;
18378
18379   if (!vam->json_output)
18380     {
18381       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18382              "transport_protocol");
18383     }
18384
18385   /* Construct the API message */
18386   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18387
18388   /* send it... */
18389   S (mp);
18390
18391   /* Use a control ping for synchronization */
18392   M (CONTROL_PING, mp_ping);
18393   S (mp_ping);
18394
18395   W (ret);
18396   return ret;
18397 }
18398
18399 static void
18400   vl_api_ipfix_classify_table_details_t_handler
18401   (vl_api_ipfix_classify_table_details_t * mp)
18402 {
18403   vat_main_t *vam = &vat_main;
18404   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18405          mp->transport_protocol);
18406 }
18407
18408 static void
18409   vl_api_ipfix_classify_table_details_t_handler_json
18410   (vl_api_ipfix_classify_table_details_t * mp)
18411 {
18412   vat_json_node_t *node = NULL;
18413   vat_main_t *vam = &vat_main;
18414
18415   if (VAT_JSON_ARRAY != vam->json_tree.type)
18416     {
18417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18418       vat_json_init_array (&vam->json_tree);
18419     }
18420
18421   node = vat_json_array_add (&vam->json_tree);
18422   vat_json_init_object (node);
18423
18424   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18425   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18426   vat_json_object_add_uint (node, "transport_protocol",
18427                             mp->transport_protocol);
18428 }
18429
18430 static int
18431 api_sw_interface_span_enable_disable (vat_main_t * vam)
18432 {
18433   unformat_input_t *i = vam->input;
18434   vl_api_sw_interface_span_enable_disable_t *mp;
18435   u32 src_sw_if_index = ~0;
18436   u32 dst_sw_if_index = ~0;
18437   u8 state = 3;
18438   int ret;
18439   u8 is_l2 = 0;
18440
18441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18442     {
18443       if (unformat
18444           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18445         ;
18446       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18447         ;
18448       else
18449         if (unformat
18450             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18451         ;
18452       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18453         ;
18454       else if (unformat (i, "disable"))
18455         state = 0;
18456       else if (unformat (i, "rx"))
18457         state = 1;
18458       else if (unformat (i, "tx"))
18459         state = 2;
18460       else if (unformat (i, "both"))
18461         state = 3;
18462       else if (unformat (i, "l2"))
18463         is_l2 = 1;
18464       else
18465         break;
18466     }
18467
18468   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18469
18470   mp->sw_if_index_from = htonl (src_sw_if_index);
18471   mp->sw_if_index_to = htonl (dst_sw_if_index);
18472   mp->state = state;
18473   mp->is_l2 = is_l2;
18474
18475   S (mp);
18476   W (ret);
18477   return ret;
18478 }
18479
18480 static void
18481 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18482                                             * mp)
18483 {
18484   vat_main_t *vam = &vat_main;
18485   u8 *sw_if_from_name = 0;
18486   u8 *sw_if_to_name = 0;
18487   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18488   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18489   char *states[] = { "none", "rx", "tx", "both" };
18490   hash_pair_t *p;
18491
18492   /* *INDENT-OFF* */
18493   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18494   ({
18495     if ((u32) p->value[0] == sw_if_index_from)
18496       {
18497         sw_if_from_name = (u8 *)(p->key);
18498         if (sw_if_to_name)
18499           break;
18500       }
18501     if ((u32) p->value[0] == sw_if_index_to)
18502       {
18503         sw_if_to_name = (u8 *)(p->key);
18504         if (sw_if_from_name)
18505           break;
18506       }
18507   }));
18508   /* *INDENT-ON* */
18509   print (vam->ofp, "%20s => %20s (%s)",
18510          sw_if_from_name, sw_if_to_name, states[mp->state]);
18511 }
18512
18513 static void
18514   vl_api_sw_interface_span_details_t_handler_json
18515   (vl_api_sw_interface_span_details_t * mp)
18516 {
18517   vat_main_t *vam = &vat_main;
18518   vat_json_node_t *node = NULL;
18519   u8 *sw_if_from_name = 0;
18520   u8 *sw_if_to_name = 0;
18521   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18522   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18523   hash_pair_t *p;
18524
18525   /* *INDENT-OFF* */
18526   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18527   ({
18528     if ((u32) p->value[0] == sw_if_index_from)
18529       {
18530         sw_if_from_name = (u8 *)(p->key);
18531         if (sw_if_to_name)
18532           break;
18533       }
18534     if ((u32) p->value[0] == sw_if_index_to)
18535       {
18536         sw_if_to_name = (u8 *)(p->key);
18537         if (sw_if_from_name)
18538           break;
18539       }
18540   }));
18541   /* *INDENT-ON* */
18542
18543   if (VAT_JSON_ARRAY != vam->json_tree.type)
18544     {
18545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18546       vat_json_init_array (&vam->json_tree);
18547     }
18548   node = vat_json_array_add (&vam->json_tree);
18549
18550   vat_json_init_object (node);
18551   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18552   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18553   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18554   if (0 != sw_if_to_name)
18555     {
18556       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18557     }
18558   vat_json_object_add_uint (node, "state", mp->state);
18559 }
18560
18561 static int
18562 api_sw_interface_span_dump (vat_main_t * vam)
18563 {
18564   unformat_input_t *input = vam->input;
18565   vl_api_sw_interface_span_dump_t *mp;
18566   vl_api_control_ping_t *mp_ping;
18567   u8 is_l2 = 0;
18568   int ret;
18569
18570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18571     {
18572       if (unformat (input, "l2"))
18573         is_l2 = 1;
18574       else
18575         break;
18576     }
18577
18578   M (SW_INTERFACE_SPAN_DUMP, mp);
18579   mp->is_l2 = is_l2;
18580   S (mp);
18581
18582   /* Use a control ping for synchronization */
18583   M (CONTROL_PING, mp_ping);
18584   S (mp_ping);
18585
18586   W (ret);
18587   return ret;
18588 }
18589
18590 int
18591 api_pg_create_interface (vat_main_t * vam)
18592 {
18593   unformat_input_t *input = vam->input;
18594   vl_api_pg_create_interface_t *mp;
18595
18596   u32 if_id = ~0;
18597   int ret;
18598   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18599     {
18600       if (unformat (input, "if_id %d", &if_id))
18601         ;
18602       else
18603         break;
18604     }
18605   if (if_id == ~0)
18606     {
18607       errmsg ("missing pg interface index");
18608       return -99;
18609     }
18610
18611   /* Construct the API message */
18612   M (PG_CREATE_INTERFACE, mp);
18613   mp->context = 0;
18614   mp->interface_id = ntohl (if_id);
18615
18616   S (mp);
18617   W (ret);
18618   return ret;
18619 }
18620
18621 int
18622 api_pg_capture (vat_main_t * vam)
18623 {
18624   unformat_input_t *input = vam->input;
18625   vl_api_pg_capture_t *mp;
18626
18627   u32 if_id = ~0;
18628   u8 enable = 1;
18629   u32 count = 1;
18630   u8 pcap_file_set = 0;
18631   u8 *pcap_file = 0;
18632   int ret;
18633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18634     {
18635       if (unformat (input, "if_id %d", &if_id))
18636         ;
18637       else if (unformat (input, "pcap %s", &pcap_file))
18638         pcap_file_set = 1;
18639       else if (unformat (input, "count %d", &count))
18640         ;
18641       else if (unformat (input, "disable"))
18642         enable = 0;
18643       else
18644         break;
18645     }
18646   if (if_id == ~0)
18647     {
18648       errmsg ("missing pg interface index");
18649       return -99;
18650     }
18651   if (pcap_file_set > 0)
18652     {
18653       if (vec_len (pcap_file) > 255)
18654         {
18655           errmsg ("pcap file name is too long");
18656           return -99;
18657         }
18658     }
18659
18660   u32 name_len = vec_len (pcap_file);
18661   /* Construct the API message */
18662   M (PG_CAPTURE, mp);
18663   mp->context = 0;
18664   mp->interface_id = ntohl (if_id);
18665   mp->is_enabled = enable;
18666   mp->count = ntohl (count);
18667   mp->pcap_name_length = ntohl (name_len);
18668   if (pcap_file_set != 0)
18669     {
18670       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18671     }
18672   vec_free (pcap_file);
18673
18674   S (mp);
18675   W (ret);
18676   return ret;
18677 }
18678
18679 int
18680 api_pg_enable_disable (vat_main_t * vam)
18681 {
18682   unformat_input_t *input = vam->input;
18683   vl_api_pg_enable_disable_t *mp;
18684
18685   u8 enable = 1;
18686   u8 stream_name_set = 0;
18687   u8 *stream_name = 0;
18688   int ret;
18689   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18690     {
18691       if (unformat (input, "stream %s", &stream_name))
18692         stream_name_set = 1;
18693       else if (unformat (input, "disable"))
18694         enable = 0;
18695       else
18696         break;
18697     }
18698
18699   if (stream_name_set > 0)
18700     {
18701       if (vec_len (stream_name) > 255)
18702         {
18703           errmsg ("stream name too long");
18704           return -99;
18705         }
18706     }
18707
18708   u32 name_len = vec_len (stream_name);
18709   /* Construct the API message */
18710   M (PG_ENABLE_DISABLE, mp);
18711   mp->context = 0;
18712   mp->is_enabled = enable;
18713   if (stream_name_set != 0)
18714     {
18715       mp->stream_name_length = ntohl (name_len);
18716       clib_memcpy (mp->stream_name, stream_name, name_len);
18717     }
18718   vec_free (stream_name);
18719
18720   S (mp);
18721   W (ret);
18722   return ret;
18723 }
18724
18725 int
18726 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18727 {
18728   unformat_input_t *input = vam->input;
18729   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18730
18731   u16 *low_ports = 0;
18732   u16 *high_ports = 0;
18733   u16 this_low;
18734   u16 this_hi;
18735   ip4_address_t ip4_addr;
18736   ip6_address_t ip6_addr;
18737   u32 length;
18738   u32 tmp, tmp2;
18739   u8 prefix_set = 0;
18740   u32 vrf_id = ~0;
18741   u8 is_add = 1;
18742   u8 is_ipv6 = 0;
18743   int ret;
18744
18745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18746     {
18747       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18748         {
18749           prefix_set = 1;
18750         }
18751       else
18752         if (unformat
18753             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18754         {
18755           prefix_set = 1;
18756           is_ipv6 = 1;
18757         }
18758       else if (unformat (input, "vrf %d", &vrf_id))
18759         ;
18760       else if (unformat (input, "del"))
18761         is_add = 0;
18762       else if (unformat (input, "port %d", &tmp))
18763         {
18764           if (tmp == 0 || tmp > 65535)
18765             {
18766               errmsg ("port %d out of range", tmp);
18767               return -99;
18768             }
18769           this_low = tmp;
18770           this_hi = this_low + 1;
18771           vec_add1 (low_ports, this_low);
18772           vec_add1 (high_ports, this_hi);
18773         }
18774       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18775         {
18776           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18777             {
18778               errmsg ("incorrect range parameters");
18779               return -99;
18780             }
18781           this_low = tmp;
18782           /* Note: in debug CLI +1 is added to high before
18783              passing to real fn that does "the work"
18784              (ip_source_and_port_range_check_add_del).
18785              This fn is a wrapper around the binary API fn a
18786              control plane will call, which expects this increment
18787              to have occurred. Hence letting the binary API control
18788              plane fn do the increment for consistency between VAT
18789              and other control planes.
18790            */
18791           this_hi = tmp2;
18792           vec_add1 (low_ports, this_low);
18793           vec_add1 (high_ports, this_hi);
18794         }
18795       else
18796         break;
18797     }
18798
18799   if (prefix_set == 0)
18800     {
18801       errmsg ("<address>/<mask> not specified");
18802       return -99;
18803     }
18804
18805   if (vrf_id == ~0)
18806     {
18807       errmsg ("VRF ID required, not specified");
18808       return -99;
18809     }
18810
18811   if (vrf_id == 0)
18812     {
18813       errmsg
18814         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18815       return -99;
18816     }
18817
18818   if (vec_len (low_ports) == 0)
18819     {
18820       errmsg ("At least one port or port range required");
18821       return -99;
18822     }
18823
18824   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18825
18826   mp->is_add = is_add;
18827
18828   if (is_ipv6)
18829     {
18830       mp->is_ipv6 = 1;
18831       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18832     }
18833   else
18834     {
18835       mp->is_ipv6 = 0;
18836       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18837     }
18838
18839   mp->mask_length = length;
18840   mp->number_of_ranges = vec_len (low_ports);
18841
18842   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18843   vec_free (low_ports);
18844
18845   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18846   vec_free (high_ports);
18847
18848   mp->vrf_id = ntohl (vrf_id);
18849
18850   S (mp);
18851   W (ret);
18852   return ret;
18853 }
18854
18855 int
18856 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18857 {
18858   unformat_input_t *input = vam->input;
18859   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18860   u32 sw_if_index = ~0;
18861   int vrf_set = 0;
18862   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18863   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18864   u8 is_add = 1;
18865   int ret;
18866
18867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18868     {
18869       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18870         ;
18871       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18872         ;
18873       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18874         vrf_set = 1;
18875       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18876         vrf_set = 1;
18877       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18878         vrf_set = 1;
18879       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18880         vrf_set = 1;
18881       else if (unformat (input, "del"))
18882         is_add = 0;
18883       else
18884         break;
18885     }
18886
18887   if (sw_if_index == ~0)
18888     {
18889       errmsg ("Interface required but not specified");
18890       return -99;
18891     }
18892
18893   if (vrf_set == 0)
18894     {
18895       errmsg ("VRF ID required but not specified");
18896       return -99;
18897     }
18898
18899   if (tcp_out_vrf_id == 0
18900       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18901     {
18902       errmsg
18903         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18904       return -99;
18905     }
18906
18907   /* Construct the API message */
18908   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18909
18910   mp->sw_if_index = ntohl (sw_if_index);
18911   mp->is_add = is_add;
18912   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18913   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18914   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18915   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18916
18917   /* send it... */
18918   S (mp);
18919
18920   /* Wait for a reply... */
18921   W (ret);
18922   return ret;
18923 }
18924
18925 static int
18926 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18927 {
18928   unformat_input_t *i = vam->input;
18929   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18930   u32 local_sa_id = 0;
18931   u32 remote_sa_id = 0;
18932   ip4_address_t src_address;
18933   ip4_address_t dst_address;
18934   u8 is_add = 1;
18935   int ret;
18936
18937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18938     {
18939       if (unformat (i, "local_sa %d", &local_sa_id))
18940         ;
18941       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18942         ;
18943       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18944         ;
18945       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18946         ;
18947       else if (unformat (i, "del"))
18948         is_add = 0;
18949       else
18950         {
18951           clib_warning ("parse error '%U'", format_unformat_error, i);
18952           return -99;
18953         }
18954     }
18955
18956   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18957
18958   mp->local_sa_id = ntohl (local_sa_id);
18959   mp->remote_sa_id = ntohl (remote_sa_id);
18960   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18961   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18962   mp->is_add = is_add;
18963
18964   S (mp);
18965   W (ret);
18966   return ret;
18967 }
18968
18969 static int
18970 api_punt (vat_main_t * vam)
18971 {
18972   unformat_input_t *i = vam->input;
18973   vl_api_punt_t *mp;
18974   u32 ipv = ~0;
18975   u32 protocol = ~0;
18976   u32 port = ~0;
18977   int is_add = 1;
18978   int ret;
18979
18980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18981     {
18982       if (unformat (i, "ip %d", &ipv))
18983         ;
18984       else if (unformat (i, "protocol %d", &protocol))
18985         ;
18986       else if (unformat (i, "port %d", &port))
18987         ;
18988       else if (unformat (i, "del"))
18989         is_add = 0;
18990       else
18991         {
18992           clib_warning ("parse error '%U'", format_unformat_error, i);
18993           return -99;
18994         }
18995     }
18996
18997   M (PUNT, mp);
18998
18999   mp->is_add = (u8) is_add;
19000   mp->ipv = (u8) ipv;
19001   mp->l4_protocol = (u8) protocol;
19002   mp->l4_port = htons ((u16) port);
19003
19004   S (mp);
19005   W (ret);
19006   return ret;
19007 }
19008
19009 static void vl_api_ipsec_gre_tunnel_details_t_handler
19010   (vl_api_ipsec_gre_tunnel_details_t * mp)
19011 {
19012   vat_main_t *vam = &vat_main;
19013
19014   print (vam->ofp, "%11d%15U%15U%14d%14d",
19015          ntohl (mp->sw_if_index),
19016          format_ip4_address, &mp->src_address,
19017          format_ip4_address, &mp->dst_address,
19018          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
19019 }
19020
19021 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
19022   (vl_api_ipsec_gre_tunnel_details_t * mp)
19023 {
19024   vat_main_t *vam = &vat_main;
19025   vat_json_node_t *node = NULL;
19026   struct in_addr ip4;
19027
19028   if (VAT_JSON_ARRAY != vam->json_tree.type)
19029     {
19030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19031       vat_json_init_array (&vam->json_tree);
19032     }
19033   node = vat_json_array_add (&vam->json_tree);
19034
19035   vat_json_init_object (node);
19036   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19037   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
19038   vat_json_object_add_ip4 (node, "src_address", ip4);
19039   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
19040   vat_json_object_add_ip4 (node, "dst_address", ip4);
19041   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
19042   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
19043 }
19044
19045 static int
19046 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
19047 {
19048   unformat_input_t *i = vam->input;
19049   vl_api_ipsec_gre_tunnel_dump_t *mp;
19050   vl_api_control_ping_t *mp_ping;
19051   u32 sw_if_index;
19052   u8 sw_if_index_set = 0;
19053   int ret;
19054
19055   /* Parse args required to build the message */
19056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19057     {
19058       if (unformat (i, "sw_if_index %d", &sw_if_index))
19059         sw_if_index_set = 1;
19060       else
19061         break;
19062     }
19063
19064   if (sw_if_index_set == 0)
19065     {
19066       sw_if_index = ~0;
19067     }
19068
19069   if (!vam->json_output)
19070     {
19071       print (vam->ofp, "%11s%15s%15s%14s%14s",
19072              "sw_if_index", "src_address", "dst_address",
19073              "local_sa_id", "remote_sa_id");
19074     }
19075
19076   /* Get list of gre-tunnel interfaces */
19077   M (IPSEC_GRE_TUNNEL_DUMP, mp);
19078
19079   mp->sw_if_index = htonl (sw_if_index);
19080
19081   S (mp);
19082
19083   /* Use a control ping for synchronization */
19084   M (CONTROL_PING, mp_ping);
19085   S (mp_ping);
19086
19087   W (ret);
19088   return ret;
19089 }
19090
19091 static int
19092 api_delete_subif (vat_main_t * vam)
19093 {
19094   unformat_input_t *i = vam->input;
19095   vl_api_delete_subif_t *mp;
19096   u32 sw_if_index = ~0;
19097   int ret;
19098
19099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19100     {
19101       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19102         ;
19103       if (unformat (i, "sw_if_index %d", &sw_if_index))
19104         ;
19105       else
19106         break;
19107     }
19108
19109   if (sw_if_index == ~0)
19110     {
19111       errmsg ("missing sw_if_index");
19112       return -99;
19113     }
19114
19115   /* Construct the API message */
19116   M (DELETE_SUBIF, mp);
19117   mp->sw_if_index = ntohl (sw_if_index);
19118
19119   S (mp);
19120   W (ret);
19121   return ret;
19122 }
19123
19124 #define foreach_pbb_vtr_op      \
19125 _("disable",  L2_VTR_DISABLED)  \
19126 _("pop",  L2_VTR_POP_2)         \
19127 _("push",  L2_VTR_PUSH_2)
19128
19129 static int
19130 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19131 {
19132   unformat_input_t *i = vam->input;
19133   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19134   u32 sw_if_index = ~0, vtr_op = ~0;
19135   u16 outer_tag = ~0;
19136   u8 dmac[6], smac[6];
19137   u8 dmac_set = 0, smac_set = 0;
19138   u16 vlanid = 0;
19139   u32 sid = ~0;
19140   u32 tmp;
19141   int ret;
19142
19143   /* Shut up coverity */
19144   memset (dmac, 0, sizeof (dmac));
19145   memset (smac, 0, sizeof (smac));
19146
19147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19148     {
19149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19150         ;
19151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19152         ;
19153       else if (unformat (i, "vtr_op %d", &vtr_op))
19154         ;
19155 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19156       foreach_pbb_vtr_op
19157 #undef _
19158         else if (unformat (i, "translate_pbb_stag"))
19159         {
19160           if (unformat (i, "%d", &tmp))
19161             {
19162               vtr_op = L2_VTR_TRANSLATE_2_1;
19163               outer_tag = tmp;
19164             }
19165           else
19166             {
19167               errmsg
19168                 ("translate_pbb_stag operation requires outer tag definition");
19169               return -99;
19170             }
19171         }
19172       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19173         dmac_set++;
19174       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19175         smac_set++;
19176       else if (unformat (i, "sid %d", &sid))
19177         ;
19178       else if (unformat (i, "vlanid %d", &tmp))
19179         vlanid = tmp;
19180       else
19181         {
19182           clib_warning ("parse error '%U'", format_unformat_error, i);
19183           return -99;
19184         }
19185     }
19186
19187   if ((sw_if_index == ~0) || (vtr_op == ~0))
19188     {
19189       errmsg ("missing sw_if_index or vtr operation");
19190       return -99;
19191     }
19192   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19193       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19194     {
19195       errmsg
19196         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19197       return -99;
19198     }
19199
19200   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19201   mp->sw_if_index = ntohl (sw_if_index);
19202   mp->vtr_op = ntohl (vtr_op);
19203   mp->outer_tag = ntohs (outer_tag);
19204   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19205   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19206   mp->b_vlanid = ntohs (vlanid);
19207   mp->i_sid = ntohl (sid);
19208
19209   S (mp);
19210   W (ret);
19211   return ret;
19212 }
19213
19214 static int
19215 api_flow_classify_set_interface (vat_main_t * vam)
19216 {
19217   unformat_input_t *i = vam->input;
19218   vl_api_flow_classify_set_interface_t *mp;
19219   u32 sw_if_index;
19220   int sw_if_index_set;
19221   u32 ip4_table_index = ~0;
19222   u32 ip6_table_index = ~0;
19223   u8 is_add = 1;
19224   int ret;
19225
19226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19227     {
19228       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19229         sw_if_index_set = 1;
19230       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19231         sw_if_index_set = 1;
19232       else if (unformat (i, "del"))
19233         is_add = 0;
19234       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19235         ;
19236       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19237         ;
19238       else
19239         {
19240           clib_warning ("parse error '%U'", format_unformat_error, i);
19241           return -99;
19242         }
19243     }
19244
19245   if (sw_if_index_set == 0)
19246     {
19247       errmsg ("missing interface name or sw_if_index");
19248       return -99;
19249     }
19250
19251   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19252
19253   mp->sw_if_index = ntohl (sw_if_index);
19254   mp->ip4_table_index = ntohl (ip4_table_index);
19255   mp->ip6_table_index = ntohl (ip6_table_index);
19256   mp->is_add = is_add;
19257
19258   S (mp);
19259   W (ret);
19260   return ret;
19261 }
19262
19263 static int
19264 api_flow_classify_dump (vat_main_t * vam)
19265 {
19266   unformat_input_t *i = vam->input;
19267   vl_api_flow_classify_dump_t *mp;
19268   vl_api_control_ping_t *mp_ping;
19269   u8 type = FLOW_CLASSIFY_N_TABLES;
19270   int ret;
19271
19272   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19273     ;
19274   else
19275     {
19276       errmsg ("classify table type must be specified");
19277       return -99;
19278     }
19279
19280   if (!vam->json_output)
19281     {
19282       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19283     }
19284
19285   M (FLOW_CLASSIFY_DUMP, mp);
19286   mp->type = type;
19287   /* send it... */
19288   S (mp);
19289
19290   /* Use a control ping for synchronization */
19291   M (CONTROL_PING, mp_ping);
19292   S (mp_ping);
19293
19294   /* Wait for a reply... */
19295   W (ret);
19296   return ret;
19297 }
19298
19299 static int
19300 api_feature_enable_disable (vat_main_t * vam)
19301 {
19302   unformat_input_t *i = vam->input;
19303   vl_api_feature_enable_disable_t *mp;
19304   u8 *arc_name = 0;
19305   u8 *feature_name = 0;
19306   u32 sw_if_index = ~0;
19307   u8 enable = 1;
19308   int ret;
19309
19310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19311     {
19312       if (unformat (i, "arc_name %s", &arc_name))
19313         ;
19314       else if (unformat (i, "feature_name %s", &feature_name))
19315         ;
19316       else
19317         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19318         ;
19319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19320         ;
19321       else if (unformat (i, "disable"))
19322         enable = 0;
19323       else
19324         break;
19325     }
19326
19327   if (arc_name == 0)
19328     {
19329       errmsg ("missing arc name");
19330       return -99;
19331     }
19332   if (vec_len (arc_name) > 63)
19333     {
19334       errmsg ("arc name too long");
19335     }
19336
19337   if (feature_name == 0)
19338     {
19339       errmsg ("missing feature name");
19340       return -99;
19341     }
19342   if (vec_len (feature_name) > 63)
19343     {
19344       errmsg ("feature name too long");
19345     }
19346
19347   if (sw_if_index == ~0)
19348     {
19349       errmsg ("missing interface name or sw_if_index");
19350       return -99;
19351     }
19352
19353   /* Construct the API message */
19354   M (FEATURE_ENABLE_DISABLE, mp);
19355   mp->sw_if_index = ntohl (sw_if_index);
19356   mp->enable = enable;
19357   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19358   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19359   vec_free (arc_name);
19360   vec_free (feature_name);
19361
19362   S (mp);
19363   W (ret);
19364   return ret;
19365 }
19366
19367 static int
19368 api_sw_interface_tag_add_del (vat_main_t * vam)
19369 {
19370   unformat_input_t *i = vam->input;
19371   vl_api_sw_interface_tag_add_del_t *mp;
19372   u32 sw_if_index = ~0;
19373   u8 *tag = 0;
19374   u8 enable = 1;
19375   int ret;
19376
19377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19378     {
19379       if (unformat (i, "tag %s", &tag))
19380         ;
19381       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19382         ;
19383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19384         ;
19385       else if (unformat (i, "del"))
19386         enable = 0;
19387       else
19388         break;
19389     }
19390
19391   if (sw_if_index == ~0)
19392     {
19393       errmsg ("missing interface name or sw_if_index");
19394       return -99;
19395     }
19396
19397   if (enable && (tag == 0))
19398     {
19399       errmsg ("no tag specified");
19400       return -99;
19401     }
19402
19403   /* Construct the API message */
19404   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19405   mp->sw_if_index = ntohl (sw_if_index);
19406   mp->is_add = enable;
19407   if (enable)
19408     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19409   vec_free (tag);
19410
19411   S (mp);
19412   W (ret);
19413   return ret;
19414 }
19415
19416 static void vl_api_l2_xconnect_details_t_handler
19417   (vl_api_l2_xconnect_details_t * mp)
19418 {
19419   vat_main_t *vam = &vat_main;
19420
19421   print (vam->ofp, "%15d%15d",
19422          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19423 }
19424
19425 static void vl_api_l2_xconnect_details_t_handler_json
19426   (vl_api_l2_xconnect_details_t * mp)
19427 {
19428   vat_main_t *vam = &vat_main;
19429   vat_json_node_t *node = NULL;
19430
19431   if (VAT_JSON_ARRAY != vam->json_tree.type)
19432     {
19433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19434       vat_json_init_array (&vam->json_tree);
19435     }
19436   node = vat_json_array_add (&vam->json_tree);
19437
19438   vat_json_init_object (node);
19439   vat_json_object_add_uint (node, "rx_sw_if_index",
19440                             ntohl (mp->rx_sw_if_index));
19441   vat_json_object_add_uint (node, "tx_sw_if_index",
19442                             ntohl (mp->tx_sw_if_index));
19443 }
19444
19445 static int
19446 api_l2_xconnect_dump (vat_main_t * vam)
19447 {
19448   vl_api_l2_xconnect_dump_t *mp;
19449   vl_api_control_ping_t *mp_ping;
19450   int ret;
19451
19452   if (!vam->json_output)
19453     {
19454       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19455     }
19456
19457   M (L2_XCONNECT_DUMP, mp);
19458
19459   S (mp);
19460
19461   /* Use a control ping for synchronization */
19462   M (CONTROL_PING, mp_ping);
19463   S (mp_ping);
19464
19465   W (ret);
19466   return ret;
19467 }
19468
19469 static int
19470 api_sw_interface_set_mtu (vat_main_t * vam)
19471 {
19472   unformat_input_t *i = vam->input;
19473   vl_api_sw_interface_set_mtu_t *mp;
19474   u32 sw_if_index = ~0;
19475   u32 mtu = 0;
19476   int ret;
19477
19478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19479     {
19480       if (unformat (i, "mtu %d", &mtu))
19481         ;
19482       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19483         ;
19484       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19485         ;
19486       else
19487         break;
19488     }
19489
19490   if (sw_if_index == ~0)
19491     {
19492       errmsg ("missing interface name or sw_if_index");
19493       return -99;
19494     }
19495
19496   if (mtu == 0)
19497     {
19498       errmsg ("no mtu specified");
19499       return -99;
19500     }
19501
19502   /* Construct the API message */
19503   M (SW_INTERFACE_SET_MTU, mp);
19504   mp->sw_if_index = ntohl (sw_if_index);
19505   mp->mtu = ntohs ((u16) mtu);
19506
19507   S (mp);
19508   W (ret);
19509   return ret;
19510 }
19511
19512 static int
19513 api_p2p_ethernet_add (vat_main_t * vam)
19514 {
19515   unformat_input_t *i = vam->input;
19516   vl_api_p2p_ethernet_add_t *mp;
19517   u32 parent_if_index = ~0;
19518   u32 sub_id = ~0;
19519   u8 remote_mac[6];
19520   u8 mac_set = 0;
19521   int ret;
19522
19523   memset (remote_mac, 0, sizeof (remote_mac));
19524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19525     {
19526       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19527         ;
19528       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19529         ;
19530       else
19531         if (unformat
19532             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19533         mac_set++;
19534       else if (unformat (i, "sub_id %d", &sub_id))
19535         ;
19536       else
19537         {
19538           clib_warning ("parse error '%U'", format_unformat_error, i);
19539           return -99;
19540         }
19541     }
19542
19543   if (parent_if_index == ~0)
19544     {
19545       errmsg ("missing interface name or sw_if_index");
19546       return -99;
19547     }
19548   if (mac_set == 0)
19549     {
19550       errmsg ("missing remote mac address");
19551       return -99;
19552     }
19553   if (sub_id == ~0)
19554     {
19555       errmsg ("missing sub-interface id");
19556       return -99;
19557     }
19558
19559   M (P2P_ETHERNET_ADD, mp);
19560   mp->parent_if_index = ntohl (parent_if_index);
19561   mp->subif_id = ntohl (sub_id);
19562   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19563
19564   S (mp);
19565   W (ret);
19566   return ret;
19567 }
19568
19569 static int
19570 api_p2p_ethernet_del (vat_main_t * vam)
19571 {
19572   unformat_input_t *i = vam->input;
19573   vl_api_p2p_ethernet_del_t *mp;
19574   u32 parent_if_index = ~0;
19575   u8 remote_mac[6];
19576   u8 mac_set = 0;
19577   int ret;
19578
19579   memset (remote_mac, 0, sizeof (remote_mac));
19580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19581     {
19582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19583         ;
19584       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19585         ;
19586       else
19587         if (unformat
19588             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19589         mac_set++;
19590       else
19591         {
19592           clib_warning ("parse error '%U'", format_unformat_error, i);
19593           return -99;
19594         }
19595     }
19596
19597   if (parent_if_index == ~0)
19598     {
19599       errmsg ("missing interface name or sw_if_index");
19600       return -99;
19601     }
19602   if (mac_set == 0)
19603     {
19604       errmsg ("missing remote mac address");
19605       return -99;
19606     }
19607
19608   M (P2P_ETHERNET_DEL, mp);
19609   mp->parent_if_index = ntohl (parent_if_index);
19610   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19611
19612   S (mp);
19613   W (ret);
19614   return ret;
19615 }
19616
19617 static int
19618 api_lldp_config (vat_main_t * vam)
19619 {
19620   unformat_input_t *i = vam->input;
19621   vl_api_lldp_config_t *mp;
19622   int tx_hold = 0;
19623   int tx_interval = 0;
19624   u8 *sys_name = NULL;
19625   int ret;
19626
19627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19628     {
19629       if (unformat (i, "system-name %s", &sys_name))
19630         ;
19631       else if (unformat (i, "tx-hold %d", &tx_hold))
19632         ;
19633       else if (unformat (i, "tx-interval %d", &tx_interval))
19634         ;
19635       else
19636         {
19637           clib_warning ("parse error '%U'", format_unformat_error, i);
19638           return -99;
19639         }
19640     }
19641
19642   vec_add1 (sys_name, 0);
19643
19644   M (LLDP_CONFIG, mp);
19645   mp->tx_hold = htonl (tx_hold);
19646   mp->tx_interval = htonl (tx_interval);
19647   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19648   vec_free (sys_name);
19649
19650   S (mp);
19651   W (ret);
19652   return ret;
19653 }
19654
19655 static int
19656 api_sw_interface_set_lldp (vat_main_t * vam)
19657 {
19658   unformat_input_t *i = vam->input;
19659   vl_api_sw_interface_set_lldp_t *mp;
19660   u32 sw_if_index = ~0;
19661   u32 enable = 1;
19662   u8 *port_desc = NULL;
19663   int ret;
19664
19665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19666     {
19667       if (unformat (i, "disable"))
19668         enable = 0;
19669       else
19670         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19671         ;
19672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19673         ;
19674       else if (unformat (i, "port-desc %s", &port_desc))
19675         ;
19676       else
19677         break;
19678     }
19679
19680   if (sw_if_index == ~0)
19681     {
19682       errmsg ("missing interface name or sw_if_index");
19683       return -99;
19684     }
19685
19686   /* Construct the API message */
19687   vec_add1 (port_desc, 0);
19688   M (SW_INTERFACE_SET_LLDP, mp);
19689   mp->sw_if_index = ntohl (sw_if_index);
19690   mp->enable = enable;
19691   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19692   vec_free (port_desc);
19693
19694   S (mp);
19695   W (ret);
19696   return ret;
19697 }
19698
19699 static int
19700 api_tcp_configure_src_addresses (vat_main_t * vam)
19701 {
19702   vl_api_tcp_configure_src_addresses_t *mp;
19703   unformat_input_t *i = vam->input;
19704   ip4_address_t v4first, v4last;
19705   ip6_address_t v6first, v6last;
19706   u8 range_set = 0;
19707   u32 vrf_id = 0;
19708   int ret;
19709
19710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19711     {
19712       if (unformat (i, "%U - %U",
19713                     unformat_ip4_address, &v4first,
19714                     unformat_ip4_address, &v4last))
19715         {
19716           if (range_set)
19717             {
19718               errmsg ("one range per message (range already set)");
19719               return -99;
19720             }
19721           range_set = 1;
19722         }
19723       else if (unformat (i, "%U - %U",
19724                          unformat_ip6_address, &v6first,
19725                          unformat_ip6_address, &v6last))
19726         {
19727           if (range_set)
19728             {
19729               errmsg ("one range per message (range already set)");
19730               return -99;
19731             }
19732           range_set = 2;
19733         }
19734       else if (unformat (i, "vrf %d", &vrf_id))
19735         ;
19736       else
19737         break;
19738     }
19739
19740   if (range_set == 0)
19741     {
19742       errmsg ("address range not set");
19743       return -99;
19744     }
19745
19746   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19747   mp->vrf_id = ntohl (vrf_id);
19748   /* ipv6? */
19749   if (range_set == 2)
19750     {
19751       mp->is_ipv6 = 1;
19752       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
19753       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
19754     }
19755   else
19756     {
19757       mp->is_ipv6 = 0;
19758       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
19759       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
19760     }
19761   S (mp);
19762   W (ret);
19763   return ret;
19764 }
19765
19766 static int
19767 q_or_quit (vat_main_t * vam)
19768 {
19769 #if VPP_API_TEST_BUILTIN == 0
19770   longjmp (vam->jump_buf, 1);
19771 #endif
19772   return 0;                     /* not so much */
19773 }
19774
19775 static int
19776 q (vat_main_t * vam)
19777 {
19778   return q_or_quit (vam);
19779 }
19780
19781 static int
19782 quit (vat_main_t * vam)
19783 {
19784   return q_or_quit (vam);
19785 }
19786
19787 static int
19788 comment (vat_main_t * vam)
19789 {
19790   return 0;
19791 }
19792
19793 static int
19794 cmd_cmp (void *a1, void *a2)
19795 {
19796   u8 **c1 = a1;
19797   u8 **c2 = a2;
19798
19799   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19800 }
19801
19802 static int
19803 help (vat_main_t * vam)
19804 {
19805   u8 **cmds = 0;
19806   u8 *name = 0;
19807   hash_pair_t *p;
19808   unformat_input_t *i = vam->input;
19809   int j;
19810
19811   if (unformat (i, "%s", &name))
19812     {
19813       uword *hs;
19814
19815       vec_add1 (name, 0);
19816
19817       hs = hash_get_mem (vam->help_by_name, name);
19818       if (hs)
19819         print (vam->ofp, "usage: %s %s", name, hs[0]);
19820       else
19821         print (vam->ofp, "No such msg / command '%s'", name);
19822       vec_free (name);
19823       return 0;
19824     }
19825
19826   print (vam->ofp, "Help is available for the following:");
19827
19828     /* *INDENT-OFF* */
19829     hash_foreach_pair (p, vam->function_by_name,
19830     ({
19831       vec_add1 (cmds, (u8 *)(p->key));
19832     }));
19833     /* *INDENT-ON* */
19834
19835   vec_sort_with_function (cmds, cmd_cmp);
19836
19837   for (j = 0; j < vec_len (cmds); j++)
19838     print (vam->ofp, "%s", cmds[j]);
19839
19840   vec_free (cmds);
19841   return 0;
19842 }
19843
19844 static int
19845 set (vat_main_t * vam)
19846 {
19847   u8 *name = 0, *value = 0;
19848   unformat_input_t *i = vam->input;
19849
19850   if (unformat (i, "%s", &name))
19851     {
19852       /* The input buffer is a vector, not a string. */
19853       value = vec_dup (i->buffer);
19854       vec_delete (value, i->index, 0);
19855       /* Almost certainly has a trailing newline */
19856       if (value[vec_len (value) - 1] == '\n')
19857         value[vec_len (value) - 1] = 0;
19858       /* Make sure it's a proper string, one way or the other */
19859       vec_add1 (value, 0);
19860       (void) clib_macro_set_value (&vam->macro_main,
19861                                    (char *) name, (char *) value);
19862     }
19863   else
19864     errmsg ("usage: set <name> <value>");
19865
19866   vec_free (name);
19867   vec_free (value);
19868   return 0;
19869 }
19870
19871 static int
19872 unset (vat_main_t * vam)
19873 {
19874   u8 *name = 0;
19875
19876   if (unformat (vam->input, "%s", &name))
19877     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19878       errmsg ("unset: %s wasn't set", name);
19879   vec_free (name);
19880   return 0;
19881 }
19882
19883 typedef struct
19884 {
19885   u8 *name;
19886   u8 *value;
19887 } macro_sort_t;
19888
19889
19890 static int
19891 macro_sort_cmp (void *a1, void *a2)
19892 {
19893   macro_sort_t *s1 = a1;
19894   macro_sort_t *s2 = a2;
19895
19896   return strcmp ((char *) (s1->name), (char *) (s2->name));
19897 }
19898
19899 static int
19900 dump_macro_table (vat_main_t * vam)
19901 {
19902   macro_sort_t *sort_me = 0, *sm;
19903   int i;
19904   hash_pair_t *p;
19905
19906     /* *INDENT-OFF* */
19907     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19908     ({
19909       vec_add2 (sort_me, sm, 1);
19910       sm->name = (u8 *)(p->key);
19911       sm->value = (u8 *) (p->value[0]);
19912     }));
19913     /* *INDENT-ON* */
19914
19915   vec_sort_with_function (sort_me, macro_sort_cmp);
19916
19917   if (vec_len (sort_me))
19918     print (vam->ofp, "%-15s%s", "Name", "Value");
19919   else
19920     print (vam->ofp, "The macro table is empty...");
19921
19922   for (i = 0; i < vec_len (sort_me); i++)
19923     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19924   return 0;
19925 }
19926
19927 static int
19928 dump_node_table (vat_main_t * vam)
19929 {
19930   int i, j;
19931   vlib_node_t *node, *next_node;
19932
19933   if (vec_len (vam->graph_nodes) == 0)
19934     {
19935       print (vam->ofp, "Node table empty, issue get_node_graph...");
19936       return 0;
19937     }
19938
19939   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19940     {
19941       node = vam->graph_nodes[i];
19942       print (vam->ofp, "[%d] %s", i, node->name);
19943       for (j = 0; j < vec_len (node->next_nodes); j++)
19944         {
19945           if (node->next_nodes[j] != ~0)
19946             {
19947               next_node = vam->graph_nodes[node->next_nodes[j]];
19948               print (vam->ofp, "  [%d] %s", j, next_node->name);
19949             }
19950         }
19951     }
19952   return 0;
19953 }
19954
19955 static int
19956 value_sort_cmp (void *a1, void *a2)
19957 {
19958   name_sort_t *n1 = a1;
19959   name_sort_t *n2 = a2;
19960
19961   if (n1->value < n2->value)
19962     return -1;
19963   if (n1->value > n2->value)
19964     return 1;
19965   return 0;
19966 }
19967
19968
19969 static int
19970 dump_msg_api_table (vat_main_t * vam)
19971 {
19972   api_main_t *am = &api_main;
19973   name_sort_t *nses = 0, *ns;
19974   hash_pair_t *hp;
19975   int i;
19976
19977   /* *INDENT-OFF* */
19978   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19979   ({
19980     vec_add2 (nses, ns, 1);
19981     ns->name = (u8 *)(hp->key);
19982     ns->value = (u32) hp->value[0];
19983   }));
19984   /* *INDENT-ON* */
19985
19986   vec_sort_with_function (nses, value_sort_cmp);
19987
19988   for (i = 0; i < vec_len (nses); i++)
19989     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19990   vec_free (nses);
19991   return 0;
19992 }
19993
19994 static int
19995 get_msg_id (vat_main_t * vam)
19996 {
19997   u8 *name_and_crc;
19998   u32 message_index;
19999
20000   if (unformat (vam->input, "%s", &name_and_crc))
20001     {
20002       message_index = vl_api_get_msg_index (name_and_crc);
20003       if (message_index == ~0)
20004         {
20005           print (vam->ofp, " '%s' not found", name_and_crc);
20006           return 0;
20007         }
20008       print (vam->ofp, " '%s' has message index %d",
20009              name_and_crc, message_index);
20010       return 0;
20011     }
20012   errmsg ("name_and_crc required...");
20013   return 0;
20014 }
20015
20016 static int
20017 search_node_table (vat_main_t * vam)
20018 {
20019   unformat_input_t *line_input = vam->input;
20020   u8 *node_to_find;
20021   int j;
20022   vlib_node_t *node, *next_node;
20023   uword *p;
20024
20025   if (vam->graph_node_index_by_name == 0)
20026     {
20027       print (vam->ofp, "Node table empty, issue get_node_graph...");
20028       return 0;
20029     }
20030
20031   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20032     {
20033       if (unformat (line_input, "%s", &node_to_find))
20034         {
20035           vec_add1 (node_to_find, 0);
20036           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20037           if (p == 0)
20038             {
20039               print (vam->ofp, "%s not found...", node_to_find);
20040               goto out;
20041             }
20042           node = vam->graph_nodes[p[0]];
20043           print (vam->ofp, "[%d] %s", p[0], node->name);
20044           for (j = 0; j < vec_len (node->next_nodes); j++)
20045             {
20046               if (node->next_nodes[j] != ~0)
20047                 {
20048                   next_node = vam->graph_nodes[node->next_nodes[j]];
20049                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20050                 }
20051             }
20052         }
20053
20054       else
20055         {
20056           clib_warning ("parse error '%U'", format_unformat_error,
20057                         line_input);
20058           return -99;
20059         }
20060
20061     out:
20062       vec_free (node_to_find);
20063
20064     }
20065
20066   return 0;
20067 }
20068
20069
20070 static int
20071 script (vat_main_t * vam)
20072 {
20073 #if (VPP_API_TEST_BUILTIN==0)
20074   u8 *s = 0;
20075   char *save_current_file;
20076   unformat_input_t save_input;
20077   jmp_buf save_jump_buf;
20078   u32 save_line_number;
20079
20080   FILE *new_fp, *save_ifp;
20081
20082   if (unformat (vam->input, "%s", &s))
20083     {
20084       new_fp = fopen ((char *) s, "r");
20085       if (new_fp == 0)
20086         {
20087           errmsg ("Couldn't open script file %s", s);
20088           vec_free (s);
20089           return -99;
20090         }
20091     }
20092   else
20093     {
20094       errmsg ("Missing script name");
20095       return -99;
20096     }
20097
20098   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20099   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20100   save_ifp = vam->ifp;
20101   save_line_number = vam->input_line_number;
20102   save_current_file = (char *) vam->current_file;
20103
20104   vam->input_line_number = 0;
20105   vam->ifp = new_fp;
20106   vam->current_file = s;
20107   do_one_file (vam);
20108
20109   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
20110   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20111   vam->ifp = save_ifp;
20112   vam->input_line_number = save_line_number;
20113   vam->current_file = (u8 *) save_current_file;
20114   vec_free (s);
20115
20116   return 0;
20117 #else
20118   clib_warning ("use the exec command...");
20119   return -99;
20120 #endif
20121 }
20122
20123 static int
20124 echo (vat_main_t * vam)
20125 {
20126   print (vam->ofp, "%v", vam->input->buffer);
20127   return 0;
20128 }
20129
20130 /* List of API message constructors, CLI names map to api_xxx */
20131 #define foreach_vpe_api_msg                                             \
20132 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20133 _(sw_interface_dump,"")                                                 \
20134 _(sw_interface_set_flags,                                               \
20135   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20136 _(sw_interface_add_del_address,                                         \
20137   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20138 _(sw_interface_set_table,                                               \
20139   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20140 _(sw_interface_set_mpls_enable,                                         \
20141   "<intfc> | sw_if_index [disable | dis]")                              \
20142 _(sw_interface_set_vpath,                                               \
20143   "<intfc> | sw_if_index <id> enable | disable")                        \
20144 _(sw_interface_set_vxlan_bypass,                                        \
20145   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20146 _(sw_interface_set_l2_xconnect,                                         \
20147   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20148   "enable | disable")                                                   \
20149 _(sw_interface_set_l2_bridge,                                           \
20150   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20151   "[shg <split-horizon-group>] [bvi]\n"                                 \
20152   "enable | disable")                                                   \
20153 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20154 _(bridge_domain_add_del,                                                \
20155   "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") \
20156 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20157 _(l2fib_add_del,                                                        \
20158   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20159 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20160 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20161 _(l2_flags,                                                             \
20162   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20163 _(bridge_flags,                                                         \
20164   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20165 _(tap_connect,                                                          \
20166   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
20167 _(tap_modify,                                                           \
20168   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20169 _(tap_delete,                                                           \
20170   "<vpp-if-name> | sw_if_index <id>")                                   \
20171 _(sw_interface_tap_dump, "")                                            \
20172 _(ip_table_add_del,                                                     \
20173   "table-id <n> [ipv6]\n")                                              \
20174 _(ip_add_del_route,                                                     \
20175   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20176   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20177   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20178   "[multipath] [count <n>]")                                            \
20179 _(ip_mroute_add_del,                                                    \
20180   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20181   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20182 _(mpls_table_add_del,                                                   \
20183   "table-id <n>\n")                                                     \
20184 _(mpls_route_add_del,                                                   \
20185   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20186   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20187   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20188   "[multipath] [count <n>]")                                            \
20189 _(mpls_ip_bind_unbind,                                                  \
20190   "<label> <addr/len>")                                                 \
20191 _(mpls_tunnel_add_del,                                                  \
20192   " via <addr> [table-id <n>]\n"                                        \
20193   "sw_if_index <id>] [l2]  [del]")                                      \
20194 _(proxy_arp_add_del,                                                    \
20195   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20196 _(proxy_arp_intfc_enable_disable,                                       \
20197   "<intfc> | sw_if_index <id> enable | disable")                        \
20198 _(sw_interface_set_unnumbered,                                          \
20199   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20200 _(ip_neighbor_add_del,                                                  \
20201   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20202   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20203 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20204 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20205 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20206   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20207   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20208   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20209 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20210 _(reset_fib, "vrf <n> [ipv6]")                                          \
20211 _(dhcp_proxy_config,                                                    \
20212   "svr <v46-address> src <v46-address>\n"                               \
20213    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20214 _(dhcp_proxy_set_vss,                                                   \
20215   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20216 _(dhcp_proxy_dump, "ip6")                                               \
20217 _(dhcp_client_config,                                                   \
20218   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20219 _(set_ip_flow_hash,                                                     \
20220   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20221 _(sw_interface_ip6_enable_disable,                                      \
20222   "<intfc> | sw_if_index <id> enable | disable")                        \
20223 _(sw_interface_ip6_set_link_local_address,                              \
20224   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20225 _(ip6nd_proxy_add_del,                                                  \
20226   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20227 _(ip6nd_proxy_dump, "")                                                 \
20228 _(sw_interface_ip6nd_ra_prefix,                                         \
20229   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20230   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20231   "[nolink] [isno]")                                                    \
20232 _(sw_interface_ip6nd_ra_config,                                         \
20233   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20234   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20235   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20236 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20237 _(l2_patch_add_del,                                                     \
20238   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20239   "enable | disable")                                                   \
20240 _(sr_localsid_add_del,                                                  \
20241   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20242   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20243 _(classify_add_del_table,                                               \
20244   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20245   " [del] [del-chain] mask <mask-value>\n"                              \
20246   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20247   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20248 _(classify_add_del_session,                                             \
20249   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20250   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20251   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20252   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20253 _(classify_set_interface_ip_table,                                      \
20254   "<intfc> | sw_if_index <nn> table <nn>")                              \
20255 _(classify_set_interface_l2_tables,                                     \
20256   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20257   "  [other-table <nn>]")                                               \
20258 _(get_node_index, "node <node-name")                                    \
20259 _(add_node_next, "node <node-name> next <next-node-name>")              \
20260 _(l2tpv3_create_tunnel,                                                 \
20261   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20262   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20263   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20264 _(l2tpv3_set_tunnel_cookies,                                            \
20265   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20266   "[new_remote_cookie <nn>]\n")                                         \
20267 _(l2tpv3_interface_enable_disable,                                      \
20268   "<intfc> | sw_if_index <nn> enable | disable")                        \
20269 _(l2tpv3_set_lookup_key,                                                \
20270   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20271 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20272 _(vxlan_add_del_tunnel,                                                 \
20273   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20274   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20275   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20276 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20277 _(gre_add_del_tunnel,                                                   \
20278   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20279 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20280 _(l2_fib_clear_table, "")                                               \
20281 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20282 _(l2_interface_vlan_tag_rewrite,                                        \
20283   "<intfc> | sw_if_index <nn> \n"                                       \
20284   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20285   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20286 _(create_vhost_user_if,                                                 \
20287         "socket <filename> [server] [renumber <dev_instance>] "         \
20288         "[mac <mac_address>]")                                          \
20289 _(modify_vhost_user_if,                                                 \
20290         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20291         "[server] [renumber <dev_instance>]")                           \
20292 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20293 _(sw_interface_vhost_user_dump, "")                                     \
20294 _(show_version, "")                                                     \
20295 _(vxlan_gpe_add_del_tunnel,                                             \
20296   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20297   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20298   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20299   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20300 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20301 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20302 _(interface_name_renumber,                                              \
20303   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20304 _(input_acl_set_interface,                                              \
20305   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20306   "  [l2-table <nn>] [del]")                                            \
20307 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20308 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20309 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20310 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20311 _(ip_dump, "ipv4 | ipv6")                                               \
20312 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20313 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20314   "  spid_id <n> ")                                                     \
20315 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20316   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20317   "  integ_alg <alg> integ_key <hex>")                                  \
20318 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20319   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20320   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20321   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20322 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20323 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20324   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20325   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20326   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20327 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20328 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20329   "(auth_data 0x<data> | auth_data <data>)")                            \
20330 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20331   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20332 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20333   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20334   "(local|remote)")                                                     \
20335 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20336 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20337 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20338 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20339 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20340 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20341 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20342 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20343 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20344 _(delete_loopback,"sw_if_index <nn>")                                   \
20345 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20346 _(map_add_domain,                                                       \
20347   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20348   "ip6-src <ip6addr> "                                                  \
20349   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20350 _(map_del_domain, "index <n>")                                          \
20351 _(map_add_del_rule,                                                     \
20352   "index <n> psid <n> dst <ip6addr> [del]")                             \
20353 _(map_domain_dump, "")                                                  \
20354 _(map_rule_dump, "index <map-domain>")                                  \
20355 _(want_interface_events,  "enable|disable")                             \
20356 _(want_stats,"enable|disable")                                          \
20357 _(get_first_msg_id, "client <name>")                                    \
20358 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20359 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20360   "fib-id <nn> [ip4][ip6][default]")                                    \
20361 _(get_node_graph, " ")                                                  \
20362 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20363 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20364 _(ioam_disable, "")                                                     \
20365 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20366                             " sw_if_index <sw_if_index> p <priority> "  \
20367                             "w <weight>] [del]")                        \
20368 _(one_add_del_locator, "locator-set <locator_name> "                    \
20369                         "iface <intf> | sw_if_index <sw_if_index> "     \
20370                         "p <priority> w <weight> [del]")                \
20371 _(one_add_del_local_eid,"vni <vni> eid "                                \
20372                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20373                          "locator-set <locator_name> [del]"             \
20374                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20375 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20376 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20377 _(one_enable_disable, "enable|disable")                                 \
20378 _(one_map_register_enable_disable, "enable|disable")                    \
20379 _(one_map_register_fallback_threshold, "<value>")                       \
20380 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20381 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20382                                "[seid <seid>] "                         \
20383                                "rloc <locator> p <prio> "               \
20384                                "w <weight> [rloc <loc> ... ] "          \
20385                                "action <action> [del-all]")             \
20386 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20387                           "<local-eid>")                                \
20388 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20389 _(one_use_petr, "ip-address> | disable")                                \
20390 _(one_map_request_mode, "src-dst|dst-only")                             \
20391 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20392 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20393 _(one_locator_set_dump, "[local | remote]")                             \
20394 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20395 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20396                        "[local] | [remote]")                            \
20397 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20398 _(one_l2_arp_bd_get, "")                                                \
20399 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20400 _(one_stats_enable_disable, "enable|disalbe")                           \
20401 _(show_one_stats_enable_disable, "")                                    \
20402 _(one_eid_table_vni_dump, "")                                           \
20403 _(one_eid_table_map_dump, "l2|l3")                                      \
20404 _(one_map_resolver_dump, "")                                            \
20405 _(one_map_server_dump, "")                                              \
20406 _(one_adjacencies_get, "vni <vni>")                                     \
20407 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20408 _(show_one_rloc_probe_state, "")                                        \
20409 _(show_one_map_register_state, "")                                      \
20410 _(show_one_status, "")                                                  \
20411 _(one_stats_dump, "")                                                   \
20412 _(one_stats_flush, "")                                                  \
20413 _(one_get_map_request_itr_rlocs, "")                                    \
20414 _(one_map_register_set_ttl, "<ttl>")                                    \
20415 _(show_one_nsh_mapping, "")                                             \
20416 _(show_one_pitr, "")                                                    \
20417 _(show_one_use_petr, "")                                                \
20418 _(show_one_map_request_mode, "")                                        \
20419 _(show_one_map_register_ttl, "")                                        \
20420 _(show_one_map_register_fallback_threshold, "")                         \
20421 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20422                             " sw_if_index <sw_if_index> p <priority> "  \
20423                             "w <weight>] [del]")                        \
20424 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20425                         "iface <intf> | sw_if_index <sw_if_index> "     \
20426                         "p <priority> w <weight> [del]")                \
20427 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20428                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20429                          "locator-set <locator_name> [del]"             \
20430                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20431 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20432 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20433 _(lisp_enable_disable, "enable|disable")                                \
20434 _(lisp_map_register_enable_disable, "enable|disable")                   \
20435 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20436 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20437                                "[seid <seid>] "                         \
20438                                "rloc <locator> p <prio> "               \
20439                                "w <weight> [rloc <loc> ... ] "          \
20440                                "action <action> [del-all]")             \
20441 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20442                           "<local-eid>")                                \
20443 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20444 _(lisp_use_petr, "<ip-address> | disable")                              \
20445 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20446 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20447 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20448 _(lisp_locator_set_dump, "[local | remote]")                            \
20449 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20450 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20451                        "[local] | [remote]")                            \
20452 _(lisp_eid_table_vni_dump, "")                                          \
20453 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20454 _(lisp_map_resolver_dump, "")                                           \
20455 _(lisp_map_server_dump, "")                                             \
20456 _(lisp_adjacencies_get, "vni <vni>")                                    \
20457 _(gpe_fwd_entry_vnis_get, "")                                           \
20458 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20459 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20460                                 "[table <table-id>]")                   \
20461 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20462 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20463 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20464 _(gpe_get_encap_mode, "")                                               \
20465 _(lisp_gpe_add_del_iface, "up|down")                                    \
20466 _(lisp_gpe_enable_disable, "enable|disable")                            \
20467 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20468   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20469 _(show_lisp_rloc_probe_state, "")                                       \
20470 _(show_lisp_map_register_state, "")                                     \
20471 _(show_lisp_status, "")                                                 \
20472 _(lisp_get_map_request_itr_rlocs, "")                                   \
20473 _(show_lisp_pitr, "")                                                   \
20474 _(show_lisp_use_petr, "")                                               \
20475 _(show_lisp_map_request_mode, "")                                       \
20476 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20477 _(af_packet_delete, "name <host interface name>")                       \
20478 _(policer_add_del, "name <policer name> <params> [del]")                \
20479 _(policer_dump, "[name <policer name>]")                                \
20480 _(policer_classify_set_interface,                                       \
20481   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20482   "  [l2-table <nn>] [del]")                                            \
20483 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20484 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20485     "[master|slave]")                                                   \
20486 _(netmap_delete, "name <interface name>")                               \
20487 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20488 _(mpls_fib_dump, "")                                                    \
20489 _(classify_table_ids, "")                                               \
20490 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20491 _(classify_table_info, "table_id <nn>")                                 \
20492 _(classify_session_dump, "table_id <nn>")                               \
20493 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20494     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20495     "[template_interval <nn>] [udp_checksum]")                          \
20496 _(ipfix_exporter_dump, "")                                              \
20497 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20498 _(ipfix_classify_stream_dump, "")                                       \
20499 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20500 _(ipfix_classify_table_dump, "")                                        \
20501 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20502 _(sw_interface_span_dump, "[l2]")                                           \
20503 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20504 _(pg_create_interface, "if_id <nn>")                                    \
20505 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20506 _(pg_enable_disable, "[stream <id>] disable")                           \
20507 _(ip_source_and_port_range_check_add_del,                               \
20508   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20509 _(ip_source_and_port_range_check_interface_add_del,                     \
20510   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20511   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20512 _(ipsec_gre_add_del_tunnel,                                             \
20513   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20514 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20515 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20516 _(l2_interface_pbb_tag_rewrite,                                         \
20517   "<intfc> | sw_if_index <nn> \n"                                       \
20518   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20519   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20520 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20521 _(flow_classify_set_interface,                                          \
20522   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20523 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20524 _(ip_fib_dump, "")                                                      \
20525 _(ip_mfib_dump, "")                                                     \
20526 _(ip6_fib_dump, "")                                                     \
20527 _(ip6_mfib_dump, "")                                                    \
20528 _(feature_enable_disable, "arc_name <arc_name> "                        \
20529   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20530 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20531 "[disable]")                                                            \
20532 _(l2_xconnect_dump, "")                                                 \
20533 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20534 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20535 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20536 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20537 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20538 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20539 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
20540 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")
20541
20542 /* List of command functions, CLI names map directly to functions */
20543 #define foreach_cli_function                                    \
20544 _(comment, "usage: comment <ignore-rest-of-line>")              \
20545 _(dump_interface_table, "usage: dump_interface_table")          \
20546 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20547 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20548 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20549 _(dump_stats_table, "usage: dump_stats_table")                  \
20550 _(dump_macro_table, "usage: dump_macro_table ")                 \
20551 _(dump_node_table, "usage: dump_node_table")                    \
20552 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20553 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20554 _(echo, "usage: echo <message>")                                \
20555 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20556 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20557 _(help, "usage: help")                                          \
20558 _(q, "usage: quit")                                             \
20559 _(quit, "usage: quit")                                          \
20560 _(search_node_table, "usage: search_node_table <name>...")      \
20561 _(set, "usage: set <variable-name> <value>")                    \
20562 _(script, "usage: script <file-name>")                          \
20563 _(unset, "usage: unset <variable-name>")
20564 #define _(N,n)                                  \
20565     static void vl_api_##n##_t_handler_uni      \
20566     (vl_api_##n##_t * mp)                       \
20567     {                                           \
20568         vat_main_t * vam = &vat_main;           \
20569         if (vam->json_output) {                 \
20570             vl_api_##n##_t_handler_json(mp);    \
20571         } else {                                \
20572             vl_api_##n##_t_handler(mp);         \
20573         }                                       \
20574     }
20575 foreach_vpe_api_reply_msg;
20576 #if VPP_API_TEST_BUILTIN == 0
20577 foreach_standalone_reply_msg;
20578 #endif
20579 #undef _
20580
20581 void
20582 vat_api_hookup (vat_main_t * vam)
20583 {
20584 #define _(N,n)                                                  \
20585     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20586                            vl_api_##n##_t_handler_uni,          \
20587                            vl_noop_handler,                     \
20588                            vl_api_##n##_t_endian,               \
20589                            vl_api_##n##_t_print,                \
20590                            sizeof(vl_api_##n##_t), 1);
20591   foreach_vpe_api_reply_msg;
20592 #if VPP_API_TEST_BUILTIN == 0
20593   foreach_standalone_reply_msg;
20594 #endif
20595 #undef _
20596
20597 #if (VPP_API_TEST_BUILTIN==0)
20598   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20599
20600   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20601
20602   vam->function_by_name = hash_create_string (0, sizeof (uword));
20603
20604   vam->help_by_name = hash_create_string (0, sizeof (uword));
20605 #endif
20606
20607   /* API messages we can send */
20608 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20609   foreach_vpe_api_msg;
20610 #undef _
20611
20612   /* Help strings */
20613 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20614   foreach_vpe_api_msg;
20615 #undef _
20616
20617   /* CLI functions */
20618 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20619   foreach_cli_function;
20620 #undef _
20621
20622   /* Help strings */
20623 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20624   foreach_cli_function;
20625 #undef _
20626 }
20627
20628 #if VPP_API_TEST_BUILTIN
20629 static clib_error_t *
20630 vat_api_hookup_shim (vlib_main_t * vm)
20631 {
20632   vat_api_hookup (&vat_main);
20633   return 0;
20634 }
20635
20636 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20637 #endif
20638
20639 /*
20640  * fd.io coding-style-patch-verification: ON
20641  *
20642  * Local Variables:
20643  * eval: (c-set-style "gnu")
20644  * End:
20645  */