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