79be42c8ba7c5819da3e1893573cf40ccafbb9bb
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
1289 /*
1290  * Special-case: build the bridge domain table, maintain
1291  * the next bd id vbl.
1292  */
1293 static void vl_api_bridge_domain_details_t_handler
1294   (vl_api_bridge_domain_details_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1298   int i;
1299
1300   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304          ntohl (mp->bd_id), mp->learn, mp->forward,
1305          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307   if (n_sw_ifs)
1308     {
1309       vl_api_bridge_domain_sw_if_t *sw_ifs;
1310       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1311              "Interface Name");
1312
1313       sw_ifs = mp->sw_if_details;
1314       for (i = 0; i < n_sw_ifs; i++)
1315         {
1316           u8 *sw_if_name = 0;
1317           u32 sw_if_index;
1318           hash_pair_t *p;
1319
1320           sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322           /* *INDENT-OFF* */
1323           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324                              ({
1325                                if ((u32) p->value[0] == sw_if_index)
1326                                  {
1327                                    sw_if_name = (u8 *)(p->key);
1328                                    break;
1329                                  }
1330                              }));
1331           /* *INDENT-ON* */
1332           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1333                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334                  "sw_if_index not found!");
1335
1336           sw_ifs++;
1337         }
1338     }
1339 }
1340
1341 static void vl_api_bridge_domain_details_t_handler_json
1342   (vl_api_bridge_domain_details_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   vat_json_node_t *node, *array = NULL;
1346   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1347
1348   if (VAT_JSON_ARRAY != vam->json_tree.type)
1349     {
1350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351       vat_json_init_array (&vam->json_tree);
1352     }
1353   node = vat_json_array_add (&vam->json_tree);
1354
1355   vat_json_init_object (node);
1356   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357   vat_json_object_add_uint (node, "flood", mp->flood);
1358   vat_json_object_add_uint (node, "forward", mp->forward);
1359   vat_json_object_add_uint (node, "learn", mp->learn);
1360   vat_json_object_add_uint (node, "bvi_sw_if_index",
1361                             ntohl (mp->bvi_sw_if_index));
1362   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1363   array = vat_json_object_add (node, "sw_if");
1364   vat_json_init_array (array);
1365
1366
1367
1368   if (n_sw_ifs)
1369     {
1370       vl_api_bridge_domain_sw_if_t *sw_ifs;
1371       int i;
1372
1373       sw_ifs = mp->sw_if_details;
1374       for (i = 0; i < n_sw_ifs; i++)
1375         {
1376           node = vat_json_array_add (array);
1377           vat_json_init_object (node);
1378           vat_json_object_add_uint (node, "sw_if_index",
1379                                     ntohl (sw_ifs->sw_if_index));
1380           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381           sw_ifs++;
1382         }
1383     }
1384 }
1385
1386 static void vl_api_control_ping_reply_t_handler
1387   (vl_api_control_ping_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->result_ready = 1;
1399     }
1400 }
1401
1402 static void vl_api_control_ping_reply_t_handler_json
1403   (vl_api_control_ping_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   i32 retval = ntohl (mp->retval);
1407
1408   if (VAT_JSON_NONE != vam->json_tree.type)
1409     {
1410       vat_json_print (vam->ofp, &vam->json_tree);
1411       vat_json_free (&vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414   else
1415     {
1416       /* just print [] */
1417       vat_json_init_array (&vam->json_tree);
1418       vat_json_print (vam->ofp, &vam->json_tree);
1419       vam->json_tree.type = VAT_JSON_NONE;
1420     }
1421
1422   vam->retval = retval;
1423   vam->result_ready = 1;
1424 }
1425
1426 static void
1427   vl_api_bridge_domain_set_mac_age_reply_t_handler
1428   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   i32 retval = ntohl (mp->retval);
1432   if (vam->async_mode)
1433     {
1434       vam->async_errors += (retval < 0);
1435     }
1436   else
1437     {
1438       vam->retval = retval;
1439       vam->result_ready = 1;
1440     }
1441 }
1442
1443 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   vat_json_node_t node;
1448
1449   vat_json_init_object (&node);
1450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452   vat_json_print (vam->ofp, &node);
1453   vat_json_free (&node);
1454
1455   vam->retval = ntohl (mp->retval);
1456   vam->result_ready = 1;
1457 }
1458
1459 static void
1460 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   i32 retval = ntohl (mp->retval);
1464   if (vam->async_mode)
1465     {
1466       vam->async_errors += (retval < 0);
1467     }
1468   else
1469     {
1470       vam->retval = retval;
1471       vam->result_ready = 1;
1472     }
1473 }
1474
1475 static void vl_api_l2_flags_reply_t_handler_json
1476   (vl_api_l2_flags_reply_t * mp)
1477 {
1478   vat_main_t *vam = &vat_main;
1479   vat_json_node_t node;
1480
1481   vat_json_init_object (&node);
1482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484                             ntohl (mp->resulting_feature_bitmap));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491 }
1492
1493 static void vl_api_bridge_flags_reply_t_handler
1494   (vl_api_bridge_flags_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_flags_reply_t_handler_json
1510   (vl_api_bridge_flags_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518                             ntohl (mp->resulting_feature_bitmap));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void vl_api_tap_connect_reply_t_handler
1528   (vl_api_tap_connect_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->sw_if_index = ntohl (mp->sw_if_index);
1540       vam->result_ready = 1;
1541     }
1542
1543 }
1544
1545 static void vl_api_tap_connect_reply_t_handler_json
1546   (vl_api_tap_connect_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t node;
1550
1551   vat_json_init_object (&node);
1552   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560
1561 }
1562
1563 static void
1564 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565 {
1566   vat_main_t *vam = &vat_main;
1567   i32 retval = ntohl (mp->retval);
1568   if (vam->async_mode)
1569     {
1570       vam->async_errors += (retval < 0);
1571     }
1572   else
1573     {
1574       vam->retval = retval;
1575       vam->sw_if_index = ntohl (mp->sw_if_index);
1576       vam->result_ready = 1;
1577     }
1578 }
1579
1580 static void vl_api_tap_modify_reply_t_handler_json
1581   (vl_api_tap_modify_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595 }
1596
1597 static void
1598 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_tap_delete_reply_t_handler_json
1614   (vl_api_tap_delete_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627 }
1628
1629 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654                             ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->sw_if_index = ntohl (mp->sw_if_index);
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1698   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1714   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "fwd_entry_index",
1722                             clib_net_to_host_u32 (mp->fwd_entry_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_one_add_del_locator_set_reply_t_handler
1732   (vl_api_one_add_del_locator_set_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1748   (vl_api_one_add_del_locator_set_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1765   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->sw_if_index = ntohl (mp->sw_if_index);
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1782   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void vl_api_gre_add_del_tunnel_reply_t_handler
1799   (vl_api_gre_add_del_tunnel_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->sw_if_index = ntohl (mp->sw_if_index);
1811       vam->result_ready = 1;
1812     }
1813 }
1814
1815 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1816   (vl_api_gre_add_del_tunnel_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   vat_json_node_t node;
1820
1821   vat_json_init_object (&node);
1822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1823   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1824
1825   vat_json_print (vam->ofp, &node);
1826   vat_json_free (&node);
1827
1828   vam->retval = ntohl (mp->retval);
1829   vam->result_ready = 1;
1830 }
1831
1832 static void vl_api_create_vhost_user_if_reply_t_handler
1833   (vl_api_create_vhost_user_if_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->sw_if_index = ntohl (mp->sw_if_index);
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_create_vhost_user_if_reply_t_handler_json
1850   (vl_api_create_vhost_user_if_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void vl_api_ip_address_details_t_handler
1867   (vl_api_ip_address_details_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   static ip_address_details_t empty_ip_address_details = { {0} };
1871   ip_address_details_t *address = NULL;
1872   ip_details_t *current_ip_details = NULL;
1873   ip_details_t *details = NULL;
1874
1875   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1876
1877   if (!details || vam->current_sw_if_index >= vec_len (details)
1878       || !details[vam->current_sw_if_index].present)
1879     {
1880       errmsg ("ip address details arrived but not stored");
1881       errmsg ("ip_dump should be called first");
1882       return;
1883     }
1884
1885   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1886
1887 #define addresses (current_ip_details->addr)
1888
1889   vec_validate_init_empty (addresses, vec_len (addresses),
1890                            empty_ip_address_details);
1891
1892   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1893
1894   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1895   address->prefix_length = mp->prefix_length;
1896 #undef addresses
1897 }
1898
1899 static void vl_api_ip_address_details_t_handler_json
1900   (vl_api_ip_address_details_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   vat_json_node_t *node = NULL;
1904   struct in6_addr ip6;
1905   struct in_addr ip4;
1906
1907   if (VAT_JSON_ARRAY != vam->json_tree.type)
1908     {
1909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1910       vat_json_init_array (&vam->json_tree);
1911     }
1912   node = vat_json_array_add (&vam->json_tree);
1913
1914   vat_json_init_object (node);
1915   if (vam->is_ipv6)
1916     {
1917       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1918       vat_json_object_add_ip6 (node, "ip", ip6);
1919     }
1920   else
1921     {
1922       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1923       vat_json_object_add_ip4 (node, "ip", ip4);
1924     }
1925   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1926 }
1927
1928 static void
1929 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1930 {
1931   vat_main_t *vam = &vat_main;
1932   static ip_details_t empty_ip_details = { 0 };
1933   ip_details_t *ip = NULL;
1934   u32 sw_if_index = ~0;
1935
1936   sw_if_index = ntohl (mp->sw_if_index);
1937
1938   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1939                            sw_if_index, empty_ip_details);
1940
1941   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1942                          sw_if_index);
1943
1944   ip->present = 1;
1945 }
1946
1947 static void
1948 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1949 {
1950   vat_main_t *vam = &vat_main;
1951
1952   if (VAT_JSON_ARRAY != vam->json_tree.type)
1953     {
1954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1955       vat_json_init_array (&vam->json_tree);
1956     }
1957   vat_json_array_add_uint (&vam->json_tree,
1958                            clib_net_to_host_u32 (mp->sw_if_index));
1959 }
1960
1961 static void vl_api_map_domain_details_t_handler_json
1962   (vl_api_map_domain_details_t * mp)
1963 {
1964   vat_json_node_t *node = NULL;
1965   vat_main_t *vam = &vat_main;
1966   struct in6_addr ip6;
1967   struct in_addr ip4;
1968
1969   if (VAT_JSON_ARRAY != vam->json_tree.type)
1970     {
1971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1972       vat_json_init_array (&vam->json_tree);
1973     }
1974
1975   node = vat_json_array_add (&vam->json_tree);
1976   vat_json_init_object (node);
1977
1978   vat_json_object_add_uint (node, "domain_index",
1979                             clib_net_to_host_u32 (mp->domain_index));
1980   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1981   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1982   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1983   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1984   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1985   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1986   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1987   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1988   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1989   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1990   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1991   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1992   vat_json_object_add_uint (node, "flags", mp->flags);
1993   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1994   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1995 }
1996
1997 static void vl_api_map_domain_details_t_handler
1998   (vl_api_map_domain_details_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001
2002   if (mp->is_translation)
2003     {
2004       print (vam->ofp,
2005              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2006              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2007              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2008              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2009              clib_net_to_host_u32 (mp->domain_index));
2010     }
2011   else
2012     {
2013       print (vam->ofp,
2014              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2015              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2016              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2017              format_ip6_address, mp->ip6_src,
2018              clib_net_to_host_u32 (mp->domain_index));
2019     }
2020   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2021          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2022          mp->is_translation ? "map-t" : "");
2023 }
2024
2025 static void vl_api_map_rule_details_t_handler_json
2026   (vl_api_map_rule_details_t * mp)
2027 {
2028   struct in6_addr ip6;
2029   vat_json_node_t *node = NULL;
2030   vat_main_t *vam = &vat_main;
2031
2032   if (VAT_JSON_ARRAY != vam->json_tree.type)
2033     {
2034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2035       vat_json_init_array (&vam->json_tree);
2036     }
2037
2038   node = vat_json_array_add (&vam->json_tree);
2039   vat_json_init_object (node);
2040
2041   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2042   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2043   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2044 }
2045
2046 static void
2047 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2048 {
2049   vat_main_t *vam = &vat_main;
2050   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2051          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2052 }
2053
2054 static void
2055 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2056 {
2057   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2058           "router_addr %U host_mac %U",
2059           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2060           format_ip4_address, &mp->host_address,
2061           format_ip4_address, &mp->router_address,
2062           format_ethernet_address, mp->host_mac);
2063 }
2064
2065 static void vl_api_dhcp_compl_event_t_handler_json
2066   (vl_api_dhcp_compl_event_t * mp)
2067 {
2068   /* JSON output not supported */
2069 }
2070
2071 static void
2072 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2073                               u32 counter)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   static u64 default_counter = 0;
2077
2078   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2079                            NULL);
2080   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2081                            sw_if_index, default_counter);
2082   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2083 }
2084
2085 static void
2086 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2087                                 interface_counter_t counter)
2088 {
2089   vat_main_t *vam = &vat_main;
2090   static interface_counter_t default_counter = { 0, };
2091
2092   vec_validate_init_empty (vam->combined_interface_counters,
2093                            vnet_counter_type, NULL);
2094   vec_validate_init_empty (vam->combined_interface_counters
2095                            [vnet_counter_type], sw_if_index, default_counter);
2096   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2097 }
2098
2099 static void vl_api_vnet_interface_simple_counters_t_handler
2100   (vl_api_vnet_interface_simple_counters_t * mp)
2101 {
2102   /* not supported */
2103 }
2104
2105 static void vl_api_vnet_interface_combined_counters_t_handler
2106   (vl_api_vnet_interface_combined_counters_t * mp)
2107 {
2108   /* not supported */
2109 }
2110
2111 static void vl_api_vnet_interface_simple_counters_t_handler_json
2112   (vl_api_vnet_interface_simple_counters_t * mp)
2113 {
2114   u64 *v_packets;
2115   u64 packets;
2116   u32 count;
2117   u32 first_sw_if_index;
2118   int i;
2119
2120   count = ntohl (mp->count);
2121   first_sw_if_index = ntohl (mp->first_sw_if_index);
2122
2123   v_packets = (u64 *) & mp->data;
2124   for (i = 0; i < count; i++)
2125     {
2126       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2127       set_simple_interface_counter (mp->vnet_counter_type,
2128                                     first_sw_if_index + i, packets);
2129       v_packets++;
2130     }
2131 }
2132
2133 static void vl_api_vnet_interface_combined_counters_t_handler_json
2134   (vl_api_vnet_interface_combined_counters_t * mp)
2135 {
2136   interface_counter_t counter;
2137   vlib_counter_t *v;
2138   u32 first_sw_if_index;
2139   int i;
2140   u32 count;
2141
2142   count = ntohl (mp->count);
2143   first_sw_if_index = ntohl (mp->first_sw_if_index);
2144
2145   v = (vlib_counter_t *) & mp->data;
2146   for (i = 0; i < count; i++)
2147     {
2148       counter.packets =
2149         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2150       counter.bytes =
2151         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2152       set_combined_interface_counter (mp->vnet_counter_type,
2153                                       first_sw_if_index + i, counter);
2154       v++;
2155     }
2156 }
2157
2158 static u32
2159 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2160 {
2161   vat_main_t *vam = &vat_main;
2162   u32 i;
2163
2164   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2165     {
2166       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2167         {
2168           return i;
2169         }
2170     }
2171   return ~0;
2172 }
2173
2174 static u32
2175 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2176 {
2177   vat_main_t *vam = &vat_main;
2178   u32 i;
2179
2180   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2181     {
2182       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2183         {
2184           return i;
2185         }
2186     }
2187   return ~0;
2188 }
2189
2190 static void vl_api_vnet_ip4_fib_counters_t_handler
2191   (vl_api_vnet_ip4_fib_counters_t * mp)
2192 {
2193   /* not supported */
2194 }
2195
2196 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2197   (vl_api_vnet_ip4_fib_counters_t * mp)
2198 {
2199   vat_main_t *vam = &vat_main;
2200   vl_api_ip4_fib_counter_t *v;
2201   ip4_fib_counter_t *counter;
2202   struct in_addr ip4;
2203   u32 vrf_id;
2204   u32 vrf_index;
2205   u32 count;
2206   int i;
2207
2208   vrf_id = ntohl (mp->vrf_id);
2209   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2210   if (~0 == vrf_index)
2211     {
2212       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2213       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2214       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2215       vec_validate (vam->ip4_fib_counters, vrf_index);
2216       vam->ip4_fib_counters[vrf_index] = NULL;
2217     }
2218
2219   vec_free (vam->ip4_fib_counters[vrf_index]);
2220   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2221   count = ntohl (mp->count);
2222   for (i = 0; i < count; i++)
2223     {
2224       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2225       counter = &vam->ip4_fib_counters[vrf_index][i];
2226       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2227       counter->address = ip4;
2228       counter->address_length = v->address_length;
2229       counter->packets = clib_net_to_host_u64 (v->packets);
2230       counter->bytes = clib_net_to_host_u64 (v->bytes);
2231       v++;
2232     }
2233 }
2234
2235 static void vl_api_vnet_ip4_nbr_counters_t_handler
2236   (vl_api_vnet_ip4_nbr_counters_t * mp)
2237 {
2238   /* not supported */
2239 }
2240
2241 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2242   (vl_api_vnet_ip4_nbr_counters_t * mp)
2243 {
2244   vat_main_t *vam = &vat_main;
2245   vl_api_ip4_nbr_counter_t *v;
2246   ip4_nbr_counter_t *counter;
2247   u32 sw_if_index;
2248   u32 count;
2249   int i;
2250
2251   sw_if_index = ntohl (mp->sw_if_index);
2252   count = ntohl (mp->count);
2253   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2254
2255   if (mp->begin)
2256     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2257
2258   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2259   for (i = 0; i < count; i++)
2260     {
2261       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2262       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2263       counter->address.s_addr = v->address;
2264       counter->packets = clib_net_to_host_u64 (v->packets);
2265       counter->bytes = clib_net_to_host_u64 (v->bytes);
2266       counter->linkt = v->link_type;
2267       v++;
2268     }
2269 }
2270
2271 static void vl_api_vnet_ip6_fib_counters_t_handler
2272   (vl_api_vnet_ip6_fib_counters_t * mp)
2273 {
2274   /* not supported */
2275 }
2276
2277 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2278   (vl_api_vnet_ip6_fib_counters_t * mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   vl_api_ip6_fib_counter_t *v;
2282   ip6_fib_counter_t *counter;
2283   struct in6_addr ip6;
2284   u32 vrf_id;
2285   u32 vrf_index;
2286   u32 count;
2287   int i;
2288
2289   vrf_id = ntohl (mp->vrf_id);
2290   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2291   if (~0 == vrf_index)
2292     {
2293       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2294       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2295       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2296       vec_validate (vam->ip6_fib_counters, vrf_index);
2297       vam->ip6_fib_counters[vrf_index] = NULL;
2298     }
2299
2300   vec_free (vam->ip6_fib_counters[vrf_index]);
2301   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2302   count = ntohl (mp->count);
2303   for (i = 0; i < count; i++)
2304     {
2305       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2306       counter = &vam->ip6_fib_counters[vrf_index][i];
2307       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2308       counter->address = ip6;
2309       counter->address_length = v->address_length;
2310       counter->packets = clib_net_to_host_u64 (v->packets);
2311       counter->bytes = clib_net_to_host_u64 (v->bytes);
2312       v++;
2313     }
2314 }
2315
2316 static void vl_api_vnet_ip6_nbr_counters_t_handler
2317   (vl_api_vnet_ip6_nbr_counters_t * mp)
2318 {
2319   /* not supported */
2320 }
2321
2322 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2323   (vl_api_vnet_ip6_nbr_counters_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   vl_api_ip6_nbr_counter_t *v;
2327   ip6_nbr_counter_t *counter;
2328   struct in6_addr ip6;
2329   u32 sw_if_index;
2330   u32 count;
2331   int i;
2332
2333   sw_if_index = ntohl (mp->sw_if_index);
2334   count = ntohl (mp->count);
2335   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2336
2337   if (mp->begin)
2338     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2339
2340   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2341   for (i = 0; i < count; i++)
2342     {
2343       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2344       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2345       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2346       counter->address = ip6;
2347       counter->packets = clib_net_to_host_u64 (v->packets);
2348       counter->bytes = clib_net_to_host_u64 (v->bytes);
2349       v++;
2350     }
2351 }
2352
2353 static void vl_api_get_first_msg_id_reply_t_handler
2354   (vl_api_get_first_msg_id_reply_t * mp)
2355 {
2356   vat_main_t *vam = &vat_main;
2357   i32 retval = ntohl (mp->retval);
2358
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->result_ready = 1;
2367     }
2368   if (retval >= 0)
2369     {
2370       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2371     }
2372 }
2373
2374 static void vl_api_get_first_msg_id_reply_t_handler_json
2375   (vl_api_get_first_msg_id_reply_t * mp)
2376 {
2377   vat_main_t *vam = &vat_main;
2378   vat_json_node_t node;
2379
2380   vat_json_init_object (&node);
2381   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2382   vat_json_object_add_uint (&node, "first_msg_id",
2383                             (uint) ntohs (mp->first_msg_id));
2384
2385   vat_json_print (vam->ofp, &node);
2386   vat_json_free (&node);
2387
2388   vam->retval = ntohl (mp->retval);
2389   vam->result_ready = 1;
2390 }
2391
2392 static void vl_api_get_node_graph_reply_t_handler
2393   (vl_api_get_node_graph_reply_t * mp)
2394 {
2395   vat_main_t *vam = &vat_main;
2396   api_main_t *am = &api_main;
2397   i32 retval = ntohl (mp->retval);
2398   u8 *pvt_copy, *reply;
2399   void *oldheap;
2400   vlib_node_t *node;
2401   int i;
2402
2403   if (vam->async_mode)
2404     {
2405       vam->async_errors += (retval < 0);
2406     }
2407   else
2408     {
2409       vam->retval = retval;
2410       vam->result_ready = 1;
2411     }
2412
2413   /* "Should never happen..." */
2414   if (retval != 0)
2415     return;
2416
2417   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2418   pvt_copy = vec_dup (reply);
2419
2420   /* Toss the shared-memory original... */
2421   pthread_mutex_lock (&am->vlib_rp->mutex);
2422   oldheap = svm_push_data_heap (am->vlib_rp);
2423
2424   vec_free (reply);
2425
2426   svm_pop_heap (oldheap);
2427   pthread_mutex_unlock (&am->vlib_rp->mutex);
2428
2429   if (vam->graph_nodes)
2430     {
2431       hash_free (vam->graph_node_index_by_name);
2432
2433       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2434         {
2435           node = vam->graph_nodes[i];
2436           vec_free (node->name);
2437           vec_free (node->next_nodes);
2438           vec_free (node);
2439         }
2440       vec_free (vam->graph_nodes);
2441     }
2442
2443   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2444   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2445   vec_free (pvt_copy);
2446
2447   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2448     {
2449       node = vam->graph_nodes[i];
2450       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2451     }
2452 }
2453
2454 static void vl_api_get_node_graph_reply_t_handler_json
2455   (vl_api_get_node_graph_reply_t * mp)
2456 {
2457   vat_main_t *vam = &vat_main;
2458   api_main_t *am = &api_main;
2459   void *oldheap;
2460   vat_json_node_t node;
2461   u8 *reply;
2462
2463   /* $$$$ make this real? */
2464   vat_json_init_object (&node);
2465   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2466   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2467
2468   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2469
2470   /* Toss the shared-memory original... */
2471   pthread_mutex_lock (&am->vlib_rp->mutex);
2472   oldheap = svm_push_data_heap (am->vlib_rp);
2473
2474   vec_free (reply);
2475
2476   svm_pop_heap (oldheap);
2477   pthread_mutex_unlock (&am->vlib_rp->mutex);
2478
2479   vat_json_print (vam->ofp, &node);
2480   vat_json_free (&node);
2481
2482   vam->retval = ntohl (mp->retval);
2483   vam->result_ready = 1;
2484 }
2485
2486 static void
2487 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   u8 *s = 0;
2491
2492   if (mp->local)
2493     {
2494       s = format (s, "%=16d%=16d%=16d",
2495                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2496     }
2497   else
2498     {
2499       s = format (s, "%=16U%=16d%=16d",
2500                   mp->is_ipv6 ? format_ip6_address :
2501                   format_ip4_address,
2502                   mp->ip_address, mp->priority, mp->weight);
2503     }
2504
2505   print (vam->ofp, "%v", s);
2506   vec_free (s);
2507 }
2508
2509 static void
2510 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   vat_json_node_t *node = NULL;
2514   struct in6_addr ip6;
2515   struct in_addr ip4;
2516
2517   if (VAT_JSON_ARRAY != vam->json_tree.type)
2518     {
2519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2520       vat_json_init_array (&vam->json_tree);
2521     }
2522   node = vat_json_array_add (&vam->json_tree);
2523   vat_json_init_object (node);
2524
2525   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2526   vat_json_object_add_uint (node, "priority", mp->priority);
2527   vat_json_object_add_uint (node, "weight", mp->weight);
2528
2529   if (mp->local)
2530     vat_json_object_add_uint (node, "sw_if_index",
2531                               clib_net_to_host_u32 (mp->sw_if_index));
2532   else
2533     {
2534       if (mp->is_ipv6)
2535         {
2536           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2537           vat_json_object_add_ip6 (node, "address", ip6);
2538         }
2539       else
2540         {
2541           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2542           vat_json_object_add_ip4 (node, "address", ip4);
2543         }
2544     }
2545 }
2546
2547 static void
2548 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2549                                           mp)
2550 {
2551   vat_main_t *vam = &vat_main;
2552   u8 *ls_name = 0;
2553
2554   ls_name = format (0, "%s", mp->ls_name);
2555
2556   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2557          ls_name);
2558   vec_free (ls_name);
2559 }
2560
2561 static void
2562   vl_api_one_locator_set_details_t_handler_json
2563   (vl_api_one_locator_set_details_t * mp)
2564 {
2565   vat_main_t *vam = &vat_main;
2566   vat_json_node_t *node = 0;
2567   u8 *ls_name = 0;
2568
2569   ls_name = format (0, "%s", mp->ls_name);
2570   vec_add1 (ls_name, 0);
2571
2572   if (VAT_JSON_ARRAY != vam->json_tree.type)
2573     {
2574       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2575       vat_json_init_array (&vam->json_tree);
2576     }
2577   node = vat_json_array_add (&vam->json_tree);
2578
2579   vat_json_init_object (node);
2580   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2581   vat_json_object_add_uint (node, "ls_index",
2582                             clib_net_to_host_u32 (mp->ls_index));
2583   vec_free (ls_name);
2584 }
2585
2586 static u8 *
2587 format_lisp_flat_eid (u8 * s, va_list * args)
2588 {
2589   u32 type = va_arg (*args, u32);
2590   u8 *eid = va_arg (*args, u8 *);
2591   u32 eid_len = va_arg (*args, u32);
2592
2593   switch (type)
2594     {
2595     case 0:
2596       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2597     case 1:
2598       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2599     case 2:
2600       return format (s, "%U", format_ethernet_address, eid);
2601     }
2602   return 0;
2603 }
2604
2605 static u8 *
2606 format_lisp_eid_vat (u8 * s, va_list * args)
2607 {
2608   u32 type = va_arg (*args, u32);
2609   u8 *eid = va_arg (*args, u8 *);
2610   u32 eid_len = va_arg (*args, u32);
2611   u8 *seid = va_arg (*args, u8 *);
2612   u32 seid_len = va_arg (*args, u32);
2613   u32 is_src_dst = va_arg (*args, u32);
2614
2615   if (is_src_dst)
2616     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2617
2618   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2619
2620   return s;
2621 }
2622
2623 static void
2624 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2625 {
2626   vat_main_t *vam = &vat_main;
2627   u8 *s = 0, *eid = 0;
2628
2629   if (~0 == mp->locator_set_index)
2630     s = format (0, "action: %d", mp->action);
2631   else
2632     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2633
2634   eid = format (0, "%U", format_lisp_eid_vat,
2635                 mp->eid_type,
2636                 mp->eid,
2637                 mp->eid_prefix_len,
2638                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2639   vec_add1 (eid, 0);
2640
2641   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2642          clib_net_to_host_u32 (mp->vni),
2643          eid,
2644          mp->is_local ? "local" : "remote",
2645          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2646          clib_net_to_host_u16 (mp->key_id), mp->key);
2647
2648   vec_free (s);
2649   vec_free (eid);
2650 }
2651
2652 static void
2653 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2654                                              * mp)
2655 {
2656   vat_main_t *vam = &vat_main;
2657   vat_json_node_t *node = 0;
2658   u8 *eid = 0;
2659
2660   if (VAT_JSON_ARRAY != vam->json_tree.type)
2661     {
2662       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2663       vat_json_init_array (&vam->json_tree);
2664     }
2665   node = vat_json_array_add (&vam->json_tree);
2666
2667   vat_json_init_object (node);
2668   if (~0 == mp->locator_set_index)
2669     vat_json_object_add_uint (node, "action", mp->action);
2670   else
2671     vat_json_object_add_uint (node, "locator_set_index",
2672                               clib_net_to_host_u32 (mp->locator_set_index));
2673
2674   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2675   eid = format (0, "%U", format_lisp_eid_vat,
2676                 mp->eid_type,
2677                 mp->eid,
2678                 mp->eid_prefix_len,
2679                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2680   vec_add1 (eid, 0);
2681   vat_json_object_add_string_copy (node, "eid", eid);
2682   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2683   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2684   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2685
2686   if (mp->key_id)
2687     {
2688       vat_json_object_add_uint (node, "key_id",
2689                                 clib_net_to_host_u16 (mp->key_id));
2690       vat_json_object_add_string_copy (node, "key", mp->key);
2691     }
2692   vec_free (eid);
2693 }
2694
2695 static void
2696 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2697 {
2698   vat_main_t *vam = &vat_main;
2699   u8 *seid = 0, *deid = 0;
2700   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2701
2702   deid = format (0, "%U", format_lisp_eid_vat,
2703                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2704
2705   seid = format (0, "%U", format_lisp_eid_vat,
2706                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2707
2708   vec_add1 (deid, 0);
2709   vec_add1 (seid, 0);
2710
2711   if (mp->is_ip4)
2712     format_ip_address_fcn = format_ip4_address;
2713   else
2714     format_ip_address_fcn = format_ip6_address;
2715
2716
2717   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2718          clib_net_to_host_u32 (mp->vni),
2719          seid, deid,
2720          format_ip_address_fcn, mp->lloc,
2721          format_ip_address_fcn, mp->rloc,
2722          clib_net_to_host_u32 (mp->pkt_count),
2723          clib_net_to_host_u32 (mp->bytes));
2724
2725   vec_free (deid);
2726   vec_free (seid);
2727 }
2728
2729 static void
2730 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2731 {
2732   struct in6_addr ip6;
2733   struct in_addr ip4;
2734   vat_main_t *vam = &vat_main;
2735   vat_json_node_t *node = 0;
2736   u8 *deid = 0, *seid = 0;
2737
2738   if (VAT_JSON_ARRAY != vam->json_tree.type)
2739     {
2740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2741       vat_json_init_array (&vam->json_tree);
2742     }
2743   node = vat_json_array_add (&vam->json_tree);
2744
2745   vat_json_init_object (node);
2746   deid = format (0, "%U", format_lisp_eid_vat,
2747                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2748
2749   seid = format (0, "%U", format_lisp_eid_vat,
2750                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2751
2752   vec_add1 (deid, 0);
2753   vec_add1 (seid, 0);
2754
2755   vat_json_object_add_string_copy (node, "seid", seid);
2756   vat_json_object_add_string_copy (node, "deid", deid);
2757   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2758
2759   if (mp->is_ip4)
2760     {
2761       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2762       vat_json_object_add_ip4 (node, "lloc", ip4);
2763       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2764       vat_json_object_add_ip4 (node, "rloc", ip4);
2765     }
2766   else
2767     {
2768       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2769       vat_json_object_add_ip6 (node, "lloc", ip6);
2770       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2771       vat_json_object_add_ip6 (node, "rloc", ip6);
2772     }
2773   vat_json_object_add_uint (node, "pkt_count",
2774                             clib_net_to_host_u32 (mp->pkt_count));
2775   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2776
2777   vec_free (deid);
2778   vec_free (seid);
2779 }
2780
2781 static void
2782   vl_api_one_eid_table_map_details_t_handler
2783   (vl_api_one_eid_table_map_details_t * mp)
2784 {
2785   vat_main_t *vam = &vat_main;
2786
2787   u8 *line = format (0, "%=10d%=10d",
2788                      clib_net_to_host_u32 (mp->vni),
2789                      clib_net_to_host_u32 (mp->dp_table));
2790   print (vam->ofp, "%v", line);
2791   vec_free (line);
2792 }
2793
2794 static void
2795   vl_api_one_eid_table_map_details_t_handler_json
2796   (vl_api_one_eid_table_map_details_t * mp)
2797 {
2798   vat_main_t *vam = &vat_main;
2799   vat_json_node_t *node = NULL;
2800
2801   if (VAT_JSON_ARRAY != vam->json_tree.type)
2802     {
2803       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2804       vat_json_init_array (&vam->json_tree);
2805     }
2806   node = vat_json_array_add (&vam->json_tree);
2807   vat_json_init_object (node);
2808   vat_json_object_add_uint (node, "dp_table",
2809                             clib_net_to_host_u32 (mp->dp_table));
2810   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2811 }
2812
2813 static void
2814   vl_api_one_eid_table_vni_details_t_handler
2815   (vl_api_one_eid_table_vni_details_t * mp)
2816 {
2817   vat_main_t *vam = &vat_main;
2818
2819   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2820   print (vam->ofp, "%v", line);
2821   vec_free (line);
2822 }
2823
2824 static void
2825   vl_api_one_eid_table_vni_details_t_handler_json
2826   (vl_api_one_eid_table_vni_details_t * mp)
2827 {
2828   vat_main_t *vam = &vat_main;
2829   vat_json_node_t *node = NULL;
2830
2831   if (VAT_JSON_ARRAY != vam->json_tree.type)
2832     {
2833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2834       vat_json_init_array (&vam->json_tree);
2835     }
2836   node = vat_json_array_add (&vam->json_tree);
2837   vat_json_init_object (node);
2838   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2839 }
2840
2841 static void
2842   vl_api_show_one_map_register_state_reply_t_handler
2843   (vl_api_show_one_map_register_state_reply_t * mp)
2844 {
2845   vat_main_t *vam = &vat_main;
2846   int retval = clib_net_to_host_u32 (mp->retval);
2847
2848   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2849
2850   vam->retval = retval;
2851   vam->result_ready = 1;
2852 }
2853
2854 static void
2855   vl_api_show_one_map_register_state_reply_t_handler_json
2856   (vl_api_show_one_map_register_state_reply_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   vat_json_node_t _node, *node = &_node;
2860   int retval = clib_net_to_host_u32 (mp->retval);
2861
2862   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2863
2864   vat_json_init_object (node);
2865   vat_json_object_add_string_copy (node, "state", s);
2866
2867   vat_json_print (vam->ofp, node);
2868   vat_json_free (node);
2869
2870   vam->retval = retval;
2871   vam->result_ready = 1;
2872   vec_free (s);
2873 }
2874
2875 static void
2876   vl_api_show_one_rloc_probe_state_reply_t_handler
2877   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   int retval = clib_net_to_host_u32 (mp->retval);
2881
2882   if (retval)
2883     goto end;
2884
2885   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2886 end:
2887   vam->retval = retval;
2888   vam->result_ready = 1;
2889 }
2890
2891 static void
2892   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2893   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2894 {
2895   vat_main_t *vam = &vat_main;
2896   vat_json_node_t _node, *node = &_node;
2897   int retval = clib_net_to_host_u32 (mp->retval);
2898
2899   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2900   vat_json_init_object (node);
2901   vat_json_object_add_string_copy (node, "state", s);
2902
2903   vat_json_print (vam->ofp, node);
2904   vat_json_free (node);
2905
2906   vam->retval = retval;
2907   vam->result_ready = 1;
2908   vec_free (s);
2909 }
2910
2911 static void
2912   vl_api_show_one_stats_enable_disable_reply_t_handler
2913   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2914 {
2915   vat_main_t *vam = &vat_main;
2916   int retval = clib_net_to_host_u32 (mp->retval);
2917
2918   if (retval)
2919     goto end;
2920
2921   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2922 end:
2923   vam->retval = retval;
2924   vam->result_ready = 1;
2925 }
2926
2927 static void
2928   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2929   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2930 {
2931   vat_main_t *vam = &vat_main;
2932   vat_json_node_t _node, *node = &_node;
2933   int retval = clib_net_to_host_u32 (mp->retval);
2934
2935   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2936   vat_json_init_object (node);
2937   vat_json_object_add_string_copy (node, "state", s);
2938
2939   vat_json_print (vam->ofp, node);
2940   vat_json_free (node);
2941
2942   vam->retval = retval;
2943   vam->result_ready = 1;
2944   vec_free (s);
2945 }
2946
2947 static void
2948 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2949 {
2950   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2951   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2952   e->vni = clib_net_to_host_u32 (e->vni);
2953 }
2954
2955 static void
2956   gpe_fwd_entries_get_reply_t_net_to_host
2957   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2958 {
2959   u32 i;
2960
2961   mp->count = clib_net_to_host_u32 (mp->count);
2962   for (i = 0; i < mp->count; i++)
2963     {
2964       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2965     }
2966 }
2967
2968 static u8 *
2969 format_gpe_encap_mode (u8 * s, va_list * args)
2970 {
2971   u32 mode = va_arg (*args, u32);
2972
2973   switch (mode)
2974     {
2975     case 0:
2976       return format (s, "lisp");
2977     case 1:
2978       return format (s, "vxlan");
2979     }
2980   return 0;
2981 }
2982
2983 static void
2984   vl_api_gpe_get_encap_mode_reply_t_handler
2985   (vl_api_gpe_get_encap_mode_reply_t * mp)
2986 {
2987   vat_main_t *vam = &vat_main;
2988
2989   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2990   vam->retval = ntohl (mp->retval);
2991   vam->result_ready = 1;
2992 }
2993
2994 static void
2995   vl_api_gpe_get_encap_mode_reply_t_handler_json
2996   (vl_api_gpe_get_encap_mode_reply_t * mp)
2997 {
2998   vat_main_t *vam = &vat_main;
2999   vat_json_node_t node;
3000
3001   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3002   vec_add1 (encap_mode, 0);
3003
3004   vat_json_init_object (&node);
3005   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3006
3007   vec_free (encap_mode);
3008   vat_json_print (vam->ofp, &node);
3009   vat_json_free (&node);
3010
3011   vam->retval = ntohl (mp->retval);
3012   vam->result_ready = 1;
3013 }
3014
3015 static void
3016   vl_api_gpe_fwd_entry_path_details_t_handler
3017   (vl_api_gpe_fwd_entry_path_details_t * mp)
3018 {
3019   vat_main_t *vam = &vat_main;
3020   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3021
3022   if (mp->lcl_loc.is_ip4)
3023     format_ip_address_fcn = format_ip4_address;
3024   else
3025     format_ip_address_fcn = format_ip6_address;
3026
3027   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3028          format_ip_address_fcn, &mp->lcl_loc,
3029          format_ip_address_fcn, &mp->rmt_loc);
3030 }
3031
3032 static void
3033 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3034 {
3035   struct in6_addr ip6;
3036   struct in_addr ip4;
3037
3038   if (loc->is_ip4)
3039     {
3040       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3041       vat_json_object_add_ip4 (n, "address", ip4);
3042     }
3043   else
3044     {
3045       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3046       vat_json_object_add_ip6 (n, "address", ip6);
3047     }
3048   vat_json_object_add_uint (n, "weight", loc->weight);
3049 }
3050
3051 static void
3052   vl_api_gpe_fwd_entry_path_details_t_handler_json
3053   (vl_api_gpe_fwd_entry_path_details_t * mp)
3054 {
3055   vat_main_t *vam = &vat_main;
3056   vat_json_node_t *node = NULL;
3057   vat_json_node_t *loc_node;
3058
3059   if (VAT_JSON_ARRAY != vam->json_tree.type)
3060     {
3061       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3062       vat_json_init_array (&vam->json_tree);
3063     }
3064   node = vat_json_array_add (&vam->json_tree);
3065   vat_json_init_object (node);
3066
3067   loc_node = vat_json_object_add (node, "local_locator");
3068   vat_json_init_object (loc_node);
3069   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3070
3071   loc_node = vat_json_object_add (node, "remote_locator");
3072   vat_json_init_object (loc_node);
3073   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3074 }
3075
3076 static void
3077   vl_api_gpe_fwd_entries_get_reply_t_handler
3078   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3079 {
3080   vat_main_t *vam = &vat_main;
3081   u32 i;
3082   int retval = clib_net_to_host_u32 (mp->retval);
3083   vl_api_gpe_fwd_entry_t *e;
3084
3085   if (retval)
3086     goto end;
3087
3088   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3089
3090   for (i = 0; i < mp->count; i++)
3091     {
3092       e = &mp->entries[i];
3093       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3094              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3095              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3096     }
3097
3098 end:
3099   vam->retval = retval;
3100   vam->result_ready = 1;
3101 }
3102
3103 static void
3104   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3105   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3106 {
3107   u8 *s = 0;
3108   vat_main_t *vam = &vat_main;
3109   vat_json_node_t *e = 0, root;
3110   u32 i;
3111   int retval = clib_net_to_host_u32 (mp->retval);
3112   vl_api_gpe_fwd_entry_t *fwd;
3113
3114   if (retval)
3115     goto end;
3116
3117   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3118   vat_json_init_array (&root);
3119
3120   for (i = 0; i < mp->count; i++)
3121     {
3122       e = vat_json_array_add (&root);
3123       fwd = &mp->entries[i];
3124
3125       vat_json_init_object (e);
3126       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3127       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3128       vat_json_object_add_int (e, "vni", fwd->vni);
3129       vat_json_object_add_int (e, "action", fwd->action);
3130
3131       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3132                   fwd->leid_prefix_len);
3133       vec_add1 (s, 0);
3134       vat_json_object_add_string_copy (e, "leid", s);
3135       vec_free (s);
3136
3137       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3138                   fwd->reid_prefix_len);
3139       vec_add1 (s, 0);
3140       vat_json_object_add_string_copy (e, "reid", s);
3141       vec_free (s);
3142     }
3143
3144   vat_json_print (vam->ofp, &root);
3145   vat_json_free (&root);
3146
3147 end:
3148   vam->retval = retval;
3149   vam->result_ready = 1;
3150 }
3151
3152 static void
3153   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3154   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3155 {
3156   vat_main_t *vam = &vat_main;
3157   u32 i, n;
3158   int retval = clib_net_to_host_u32 (mp->retval);
3159
3160   if (retval)
3161     goto end;
3162
3163   n = clib_net_to_host_u32 (mp->count);
3164
3165   for (i = 0; i < n; i++)
3166     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3167
3168 end:
3169   vam->retval = retval;
3170   vam->result_ready = 1;
3171 }
3172
3173 static void
3174   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3175   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t root;
3179   u32 i, n;
3180   int retval = clib_net_to_host_u32 (mp->retval);
3181
3182   if (retval)
3183     goto end;
3184
3185   n = clib_net_to_host_u32 (mp->count);
3186   vat_json_init_array (&root);
3187
3188   for (i = 0; i < n; i++)
3189     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3190
3191   vat_json_print (vam->ofp, &root);
3192   vat_json_free (&root);
3193
3194 end:
3195   vam->retval = retval;
3196   vam->result_ready = 1;
3197 }
3198
3199 static void
3200   vl_api_one_l2_arp_entries_get_reply_t_handler
3201   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3202 {
3203   vat_main_t *vam = &vat_main;
3204   u32 i, n;
3205   int retval = clib_net_to_host_u32 (mp->retval);
3206
3207   if (retval)
3208     goto end;
3209
3210   n = clib_net_to_host_u32 (mp->count);
3211
3212   for (i = 0; i < n; i++)
3213     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3214            format_ethernet_address, mp->entries[i].mac);
3215
3216 end:
3217   vam->retval = retval;
3218   vam->result_ready = 1;
3219 }
3220
3221 static void
3222   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3223   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3224 {
3225   u8 *s = 0;
3226   vat_main_t *vam = &vat_main;
3227   vat_json_node_t *e = 0, root;
3228   u32 i, n;
3229   int retval = clib_net_to_host_u32 (mp->retval);
3230   vl_api_one_l2_arp_entry_t *arp_entry;
3231
3232   if (retval)
3233     goto end;
3234
3235   n = clib_net_to_host_u32 (mp->count);
3236   vat_json_init_array (&root);
3237
3238   for (i = 0; i < n; i++)
3239     {
3240       e = vat_json_array_add (&root);
3241       arp_entry = &mp->entries[i];
3242
3243       vat_json_init_object (e);
3244       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3245       vec_add1 (s, 0);
3246
3247       vat_json_object_add_string_copy (e, "mac", s);
3248       vec_free (s);
3249
3250       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3251       vec_add1 (s, 0);
3252       vat_json_object_add_string_copy (e, "ip4", s);
3253       vec_free (s);
3254     }
3255
3256   vat_json_print (vam->ofp, &root);
3257   vat_json_free (&root);
3258
3259 end:
3260   vam->retval = retval;
3261   vam->result_ready = 1;
3262 }
3263
3264 static void
3265   vl_api_one_l2_arp_bd_get_reply_t_handler
3266   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269   u32 i, n;
3270   int retval = clib_net_to_host_u32 (mp->retval);
3271
3272   if (retval)
3273     goto end;
3274
3275   n = clib_net_to_host_u32 (mp->count);
3276
3277   for (i = 0; i < n; i++)
3278     {
3279       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3280     }
3281
3282 end:
3283   vam->retval = retval;
3284   vam->result_ready = 1;
3285 }
3286
3287 static void
3288   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3289   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   vat_json_node_t root;
3293   u32 i, n;
3294   int retval = clib_net_to_host_u32 (mp->retval);
3295
3296   if (retval)
3297     goto end;
3298
3299   n = clib_net_to_host_u32 (mp->count);
3300   vat_json_init_array (&root);
3301
3302   for (i = 0; i < n; i++)
3303     {
3304       vat_json_array_add_uint (&root,
3305                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3306     }
3307
3308   vat_json_print (vam->ofp, &root);
3309   vat_json_free (&root);
3310
3311 end:
3312   vam->retval = retval;
3313   vam->result_ready = 1;
3314 }
3315
3316 static void
3317   vl_api_one_adjacencies_get_reply_t_handler
3318   (vl_api_one_adjacencies_get_reply_t * mp)
3319 {
3320   vat_main_t *vam = &vat_main;
3321   u32 i, n;
3322   int retval = clib_net_to_host_u32 (mp->retval);
3323   vl_api_one_adjacency_t *a;
3324
3325   if (retval)
3326     goto end;
3327
3328   n = clib_net_to_host_u32 (mp->count);
3329
3330   for (i = 0; i < n; i++)
3331     {
3332       a = &mp->adjacencies[i];
3333       print (vam->ofp, "%U %40U",
3334              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3335              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3336     }
3337
3338 end:
3339   vam->retval = retval;
3340   vam->result_ready = 1;
3341 }
3342
3343 static void
3344   vl_api_one_adjacencies_get_reply_t_handler_json
3345   (vl_api_one_adjacencies_get_reply_t * mp)
3346 {
3347   u8 *s = 0;
3348   vat_main_t *vam = &vat_main;
3349   vat_json_node_t *e = 0, root;
3350   u32 i, n;
3351   int retval = clib_net_to_host_u32 (mp->retval);
3352   vl_api_one_adjacency_t *a;
3353
3354   if (retval)
3355     goto end;
3356
3357   n = clib_net_to_host_u32 (mp->count);
3358   vat_json_init_array (&root);
3359
3360   for (i = 0; i < n; i++)
3361     {
3362       e = vat_json_array_add (&root);
3363       a = &mp->adjacencies[i];
3364
3365       vat_json_init_object (e);
3366       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3367                   a->leid_prefix_len);
3368       vec_add1 (s, 0);
3369       vat_json_object_add_string_copy (e, "leid", s);
3370       vec_free (s);
3371
3372       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3373                   a->reid_prefix_len);
3374       vec_add1 (s, 0);
3375       vat_json_object_add_string_copy (e, "reid", s);
3376       vec_free (s);
3377     }
3378
3379   vat_json_print (vam->ofp, &root);
3380   vat_json_free (&root);
3381
3382 end:
3383   vam->retval = retval;
3384   vam->result_ready = 1;
3385 }
3386
3387 static void
3388 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3389 {
3390   vat_main_t *vam = &vat_main;
3391
3392   print (vam->ofp, "%=20U",
3393          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3394          mp->ip_address);
3395 }
3396
3397 static void
3398   vl_api_one_map_server_details_t_handler_json
3399   (vl_api_one_map_server_details_t * mp)
3400 {
3401   vat_main_t *vam = &vat_main;
3402   vat_json_node_t *node = NULL;
3403   struct in6_addr ip6;
3404   struct in_addr ip4;
3405
3406   if (VAT_JSON_ARRAY != vam->json_tree.type)
3407     {
3408       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3409       vat_json_init_array (&vam->json_tree);
3410     }
3411   node = vat_json_array_add (&vam->json_tree);
3412
3413   vat_json_init_object (node);
3414   if (mp->is_ipv6)
3415     {
3416       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3417       vat_json_object_add_ip6 (node, "map-server", ip6);
3418     }
3419   else
3420     {
3421       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3422       vat_json_object_add_ip4 (node, "map-server", ip4);
3423     }
3424 }
3425
3426 static void
3427 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3428                                            * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431
3432   print (vam->ofp, "%=20U",
3433          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3434          mp->ip_address);
3435 }
3436
3437 static void
3438   vl_api_one_map_resolver_details_t_handler_json
3439   (vl_api_one_map_resolver_details_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t *node = NULL;
3443   struct in6_addr ip6;
3444   struct in_addr ip4;
3445
3446   if (VAT_JSON_ARRAY != vam->json_tree.type)
3447     {
3448       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3449       vat_json_init_array (&vam->json_tree);
3450     }
3451   node = vat_json_array_add (&vam->json_tree);
3452
3453   vat_json_init_object (node);
3454   if (mp->is_ipv6)
3455     {
3456       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3457       vat_json_object_add_ip6 (node, "map resolver", ip6);
3458     }
3459   else
3460     {
3461       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3462       vat_json_object_add_ip4 (node, "map resolver", ip4);
3463     }
3464 }
3465
3466 static void
3467 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3468 {
3469   vat_main_t *vam = &vat_main;
3470   i32 retval = ntohl (mp->retval);
3471
3472   if (0 <= retval)
3473     {
3474       print (vam->ofp, "feature: %s\ngpe: %s",
3475              mp->feature_status ? "enabled" : "disabled",
3476              mp->gpe_status ? "enabled" : "disabled");
3477     }
3478
3479   vam->retval = retval;
3480   vam->result_ready = 1;
3481 }
3482
3483 static void
3484   vl_api_show_one_status_reply_t_handler_json
3485   (vl_api_show_one_status_reply_t * mp)
3486 {
3487   vat_main_t *vam = &vat_main;
3488   vat_json_node_t node;
3489   u8 *gpe_status = NULL;
3490   u8 *feature_status = NULL;
3491
3492   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3493   feature_status = format (0, "%s",
3494                            mp->feature_status ? "enabled" : "disabled");
3495   vec_add1 (gpe_status, 0);
3496   vec_add1 (feature_status, 0);
3497
3498   vat_json_init_object (&node);
3499   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3500   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3501
3502   vec_free (gpe_status);
3503   vec_free (feature_status);
3504
3505   vat_json_print (vam->ofp, &node);
3506   vat_json_free (&node);
3507
3508   vam->retval = ntohl (mp->retval);
3509   vam->result_ready = 1;
3510 }
3511
3512 static void
3513   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3514   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3515 {
3516   vat_main_t *vam = &vat_main;
3517   i32 retval = ntohl (mp->retval);
3518
3519   if (retval >= 0)
3520     {
3521       print (vam->ofp, "%=20s", mp->locator_set_name);
3522     }
3523
3524   vam->retval = retval;
3525   vam->result_ready = 1;
3526 }
3527
3528 static void
3529   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3530   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3531 {
3532   vat_main_t *vam = &vat_main;
3533   vat_json_node_t *node = NULL;
3534
3535   if (VAT_JSON_ARRAY != vam->json_tree.type)
3536     {
3537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3538       vat_json_init_array (&vam->json_tree);
3539     }
3540   node = vat_json_array_add (&vam->json_tree);
3541
3542   vat_json_init_object (node);
3543   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3544
3545   vat_json_print (vam->ofp, node);
3546   vat_json_free (node);
3547
3548   vam->retval = ntohl (mp->retval);
3549   vam->result_ready = 1;
3550 }
3551
3552 static u8 *
3553 format_lisp_map_request_mode (u8 * s, va_list * args)
3554 {
3555   u32 mode = va_arg (*args, u32);
3556
3557   switch (mode)
3558     {
3559     case 0:
3560       return format (0, "dst-only");
3561     case 1:
3562       return format (0, "src-dst");
3563     }
3564   return 0;
3565 }
3566
3567 static void
3568   vl_api_show_one_map_request_mode_reply_t_handler
3569   (vl_api_show_one_map_request_mode_reply_t * mp)
3570 {
3571   vat_main_t *vam = &vat_main;
3572   i32 retval = ntohl (mp->retval);
3573
3574   if (0 <= retval)
3575     {
3576       u32 mode = mp->mode;
3577       print (vam->ofp, "map_request_mode: %U",
3578              format_lisp_map_request_mode, mode);
3579     }
3580
3581   vam->retval = retval;
3582   vam->result_ready = 1;
3583 }
3584
3585 static void
3586   vl_api_show_one_map_request_mode_reply_t_handler_json
3587   (vl_api_show_one_map_request_mode_reply_t * mp)
3588 {
3589   vat_main_t *vam = &vat_main;
3590   vat_json_node_t node;
3591   u8 *s = 0;
3592   u32 mode;
3593
3594   mode = mp->mode;
3595   s = format (0, "%U", format_lisp_map_request_mode, mode);
3596   vec_add1 (s, 0);
3597
3598   vat_json_init_object (&node);
3599   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3600   vat_json_print (vam->ofp, &node);
3601   vat_json_free (&node);
3602
3603   vec_free (s);
3604   vam->retval = ntohl (mp->retval);
3605   vam->result_ready = 1;
3606 }
3607
3608 static void
3609   vl_api_show_one_use_petr_reply_t_handler
3610   (vl_api_show_one_use_petr_reply_t * mp)
3611 {
3612   vat_main_t *vam = &vat_main;
3613   i32 retval = ntohl (mp->retval);
3614
3615   if (0 <= retval)
3616     {
3617       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3618       if (mp->status)
3619         {
3620           print (vam->ofp, "Proxy-ETR address; %U",
3621                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3622                  mp->address);
3623         }
3624     }
3625
3626   vam->retval = retval;
3627   vam->result_ready = 1;
3628 }
3629
3630 static void
3631   vl_api_show_one_use_petr_reply_t_handler_json
3632   (vl_api_show_one_use_petr_reply_t * mp)
3633 {
3634   vat_main_t *vam = &vat_main;
3635   vat_json_node_t node;
3636   u8 *status = 0;
3637   struct in_addr ip4;
3638   struct in6_addr ip6;
3639
3640   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3641   vec_add1 (status, 0);
3642
3643   vat_json_init_object (&node);
3644   vat_json_object_add_string_copy (&node, "status", status);
3645   if (mp->status)
3646     {
3647       if (mp->is_ip4)
3648         {
3649           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3650           vat_json_object_add_ip6 (&node, "address", ip6);
3651         }
3652       else
3653         {
3654           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3655           vat_json_object_add_ip4 (&node, "address", ip4);
3656         }
3657     }
3658
3659   vec_free (status);
3660
3661   vat_json_print (vam->ofp, &node);
3662   vat_json_free (&node);
3663
3664   vam->retval = ntohl (mp->retval);
3665   vam->result_ready = 1;
3666 }
3667
3668 static void
3669 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   i32 retval = ntohl (mp->retval);
3673
3674   if (0 <= retval)
3675     {
3676       print (vam->ofp, "%-20s%-16s",
3677              mp->status ? "enabled" : "disabled",
3678              mp->status ? (char *) mp->locator_set_name : "");
3679     }
3680
3681   vam->retval = retval;
3682   vam->result_ready = 1;
3683 }
3684
3685 static void
3686 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689   vat_json_node_t node;
3690   u8 *status = 0;
3691
3692   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3693   vec_add1 (status, 0);
3694
3695   vat_json_init_object (&node);
3696   vat_json_object_add_string_copy (&node, "status", status);
3697   if (mp->status)
3698     {
3699       vat_json_object_add_string_copy (&node, "locator_set",
3700                                        mp->locator_set_name);
3701     }
3702
3703   vec_free (status);
3704
3705   vat_json_print (vam->ofp, &node);
3706   vat_json_free (&node);
3707
3708   vam->retval = ntohl (mp->retval);
3709   vam->result_ready = 1;
3710 }
3711
3712 static u8 *
3713 format_policer_type (u8 * s, va_list * va)
3714 {
3715   u32 i = va_arg (*va, u32);
3716
3717   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3718     s = format (s, "1r2c");
3719   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3720     s = format (s, "1r3c");
3721   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3722     s = format (s, "2r3c-2698");
3723   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3724     s = format (s, "2r3c-4115");
3725   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3726     s = format (s, "2r3c-mef5cf1");
3727   else
3728     s = format (s, "ILLEGAL");
3729   return s;
3730 }
3731
3732 static u8 *
3733 format_policer_rate_type (u8 * s, va_list * va)
3734 {
3735   u32 i = va_arg (*va, u32);
3736
3737   if (i == SSE2_QOS_RATE_KBPS)
3738     s = format (s, "kbps");
3739   else if (i == SSE2_QOS_RATE_PPS)
3740     s = format (s, "pps");
3741   else
3742     s = format (s, "ILLEGAL");
3743   return s;
3744 }
3745
3746 static u8 *
3747 format_policer_round_type (u8 * s, va_list * va)
3748 {
3749   u32 i = va_arg (*va, u32);
3750
3751   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3752     s = format (s, "closest");
3753   else if (i == SSE2_QOS_ROUND_TO_UP)
3754     s = format (s, "up");
3755   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3756     s = format (s, "down");
3757   else
3758     s = format (s, "ILLEGAL");
3759   return s;
3760 }
3761
3762 static u8 *
3763 format_policer_action_type (u8 * s, va_list * va)
3764 {
3765   u32 i = va_arg (*va, u32);
3766
3767   if (i == SSE2_QOS_ACTION_DROP)
3768     s = format (s, "drop");
3769   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3770     s = format (s, "transmit");
3771   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3772     s = format (s, "mark-and-transmit");
3773   else
3774     s = format (s, "ILLEGAL");
3775   return s;
3776 }
3777
3778 static u8 *
3779 format_dscp (u8 * s, va_list * va)
3780 {
3781   u32 i = va_arg (*va, u32);
3782   char *t = 0;
3783
3784   switch (i)
3785     {
3786 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3787       foreach_vnet_dscp
3788 #undef _
3789     default:
3790       return format (s, "ILLEGAL");
3791     }
3792   s = format (s, "%s", t);
3793   return s;
3794 }
3795
3796 static void
3797 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3801
3802   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3803     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3804   else
3805     conform_dscp_str = format (0, "");
3806
3807   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3808     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3809   else
3810     exceed_dscp_str = format (0, "");
3811
3812   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3813     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3814   else
3815     violate_dscp_str = format (0, "");
3816
3817   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3818          "rate type %U, round type %U, %s rate, %s color-aware, "
3819          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3820          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3821          "conform action %U%s, exceed action %U%s, violate action %U%s",
3822          mp->name,
3823          format_policer_type, mp->type,
3824          ntohl (mp->cir),
3825          ntohl (mp->eir),
3826          clib_net_to_host_u64 (mp->cb),
3827          clib_net_to_host_u64 (mp->eb),
3828          format_policer_rate_type, mp->rate_type,
3829          format_policer_round_type, mp->round_type,
3830          mp->single_rate ? "single" : "dual",
3831          mp->color_aware ? "is" : "not",
3832          ntohl (mp->cir_tokens_per_period),
3833          ntohl (mp->pir_tokens_per_period),
3834          ntohl (mp->scale),
3835          ntohl (mp->current_limit),
3836          ntohl (mp->current_bucket),
3837          ntohl (mp->extended_limit),
3838          ntohl (mp->extended_bucket),
3839          clib_net_to_host_u64 (mp->last_update_time),
3840          format_policer_action_type, mp->conform_action_type,
3841          conform_dscp_str,
3842          format_policer_action_type, mp->exceed_action_type,
3843          exceed_dscp_str,
3844          format_policer_action_type, mp->violate_action_type,
3845          violate_dscp_str);
3846
3847   vec_free (conform_dscp_str);
3848   vec_free (exceed_dscp_str);
3849   vec_free (violate_dscp_str);
3850 }
3851
3852 static void vl_api_policer_details_t_handler_json
3853   (vl_api_policer_details_t * mp)
3854 {
3855   vat_main_t *vam = &vat_main;
3856   vat_json_node_t *node;
3857   u8 *rate_type_str, *round_type_str, *type_str;
3858   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3859
3860   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3861   round_type_str =
3862     format (0, "%U", format_policer_round_type, mp->round_type);
3863   type_str = format (0, "%U", format_policer_type, mp->type);
3864   conform_action_str = format (0, "%U", format_policer_action_type,
3865                                mp->conform_action_type);
3866   exceed_action_str = format (0, "%U", format_policer_action_type,
3867                               mp->exceed_action_type);
3868   violate_action_str = format (0, "%U", format_policer_action_type,
3869                                mp->violate_action_type);
3870
3871   if (VAT_JSON_ARRAY != vam->json_tree.type)
3872     {
3873       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3874       vat_json_init_array (&vam->json_tree);
3875     }
3876   node = vat_json_array_add (&vam->json_tree);
3877
3878   vat_json_init_object (node);
3879   vat_json_object_add_string_copy (node, "name", mp->name);
3880   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3881   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3882   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3883   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3884   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3885   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3886   vat_json_object_add_string_copy (node, "type", type_str);
3887   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3888   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3889   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3890   vat_json_object_add_uint (node, "cir_tokens_per_period",
3891                             ntohl (mp->cir_tokens_per_period));
3892   vat_json_object_add_uint (node, "eir_tokens_per_period",
3893                             ntohl (mp->pir_tokens_per_period));
3894   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3895   vat_json_object_add_uint (node, "current_bucket",
3896                             ntohl (mp->current_bucket));
3897   vat_json_object_add_uint (node, "extended_limit",
3898                             ntohl (mp->extended_limit));
3899   vat_json_object_add_uint (node, "extended_bucket",
3900                             ntohl (mp->extended_bucket));
3901   vat_json_object_add_uint (node, "last_update_time",
3902                             ntohl (mp->last_update_time));
3903   vat_json_object_add_string_copy (node, "conform_action",
3904                                    conform_action_str);
3905   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3906     {
3907       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3908       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3909       vec_free (dscp_str);
3910     }
3911   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3912   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3913     {
3914       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3915       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3916       vec_free (dscp_str);
3917     }
3918   vat_json_object_add_string_copy (node, "violate_action",
3919                                    violate_action_str);
3920   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3921     {
3922       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3923       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3924       vec_free (dscp_str);
3925     }
3926
3927   vec_free (rate_type_str);
3928   vec_free (round_type_str);
3929   vec_free (type_str);
3930   vec_free (conform_action_str);
3931   vec_free (exceed_action_str);
3932   vec_free (violate_action_str);
3933 }
3934
3935 static void
3936 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3937                                            mp)
3938 {
3939   vat_main_t *vam = &vat_main;
3940   int i, count = ntohl (mp->count);
3941
3942   if (count > 0)
3943     print (vam->ofp, "classify table ids (%d) : ", count);
3944   for (i = 0; i < count; i++)
3945     {
3946       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3947       print (vam->ofp, (i < count - 1) ? "," : "");
3948     }
3949   vam->retval = ntohl (mp->retval);
3950   vam->result_ready = 1;
3951 }
3952
3953 static void
3954   vl_api_classify_table_ids_reply_t_handler_json
3955   (vl_api_classify_table_ids_reply_t * mp)
3956 {
3957   vat_main_t *vam = &vat_main;
3958   int i, count = ntohl (mp->count);
3959
3960   if (count > 0)
3961     {
3962       vat_json_node_t node;
3963
3964       vat_json_init_object (&node);
3965       for (i = 0; i < count; i++)
3966         {
3967           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3968         }
3969       vat_json_print (vam->ofp, &node);
3970       vat_json_free (&node);
3971     }
3972   vam->retval = ntohl (mp->retval);
3973   vam->result_ready = 1;
3974 }
3975
3976 static void
3977   vl_api_classify_table_by_interface_reply_t_handler
3978   (vl_api_classify_table_by_interface_reply_t * mp)
3979 {
3980   vat_main_t *vam = &vat_main;
3981   u32 table_id;
3982
3983   table_id = ntohl (mp->l2_table_id);
3984   if (table_id != ~0)
3985     print (vam->ofp, "l2 table id : %d", table_id);
3986   else
3987     print (vam->ofp, "l2 table id : No input ACL tables configured");
3988   table_id = ntohl (mp->ip4_table_id);
3989   if (table_id != ~0)
3990     print (vam->ofp, "ip4 table id : %d", table_id);
3991   else
3992     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3993   table_id = ntohl (mp->ip6_table_id);
3994   if (table_id != ~0)
3995     print (vam->ofp, "ip6 table id : %d", table_id);
3996   else
3997     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3998   vam->retval = ntohl (mp->retval);
3999   vam->result_ready = 1;
4000 }
4001
4002 static void
4003   vl_api_classify_table_by_interface_reply_t_handler_json
4004   (vl_api_classify_table_by_interface_reply_t * mp)
4005 {
4006   vat_main_t *vam = &vat_main;
4007   vat_json_node_t node;
4008
4009   vat_json_init_object (&node);
4010
4011   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4012   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4013   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4014
4015   vat_json_print (vam->ofp, &node);
4016   vat_json_free (&node);
4017
4018   vam->retval = ntohl (mp->retval);
4019   vam->result_ready = 1;
4020 }
4021
4022 static void vl_api_policer_add_del_reply_t_handler
4023   (vl_api_policer_add_del_reply_t * mp)
4024 {
4025   vat_main_t *vam = &vat_main;
4026   i32 retval = ntohl (mp->retval);
4027   if (vam->async_mode)
4028     {
4029       vam->async_errors += (retval < 0);
4030     }
4031   else
4032     {
4033       vam->retval = retval;
4034       vam->result_ready = 1;
4035       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4036         /*
4037          * Note: this is just barely thread-safe, depends on
4038          * the main thread spinning waiting for an answer...
4039          */
4040         errmsg ("policer index %d", ntohl (mp->policer_index));
4041     }
4042 }
4043
4044 static void vl_api_policer_add_del_reply_t_handler_json
4045   (vl_api_policer_add_del_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   vat_json_node_t node;
4049
4050   vat_json_init_object (&node);
4051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4052   vat_json_object_add_uint (&node, "policer_index",
4053                             ntohl (mp->policer_index));
4054
4055   vat_json_print (vam->ofp, &node);
4056   vat_json_free (&node);
4057
4058   vam->retval = ntohl (mp->retval);
4059   vam->result_ready = 1;
4060 }
4061
4062 /* Format hex dump. */
4063 u8 *
4064 format_hex_bytes (u8 * s, va_list * va)
4065 {
4066   u8 *bytes = va_arg (*va, u8 *);
4067   int n_bytes = va_arg (*va, int);
4068   uword i;
4069
4070   /* Print short or long form depending on byte count. */
4071   uword short_form = n_bytes <= 32;
4072   uword indent = format_get_indent (s);
4073
4074   if (n_bytes == 0)
4075     return s;
4076
4077   for (i = 0; i < n_bytes; i++)
4078     {
4079       if (!short_form && (i % 32) == 0)
4080         s = format (s, "%08x: ", i);
4081       s = format (s, "%02x", bytes[i]);
4082       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4083         s = format (s, "\n%U", format_white_space, indent);
4084     }
4085
4086   return s;
4087 }
4088
4089 static void
4090 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4091                                             * mp)
4092 {
4093   vat_main_t *vam = &vat_main;
4094   i32 retval = ntohl (mp->retval);
4095   if (retval == 0)
4096     {
4097       print (vam->ofp, "classify table info :");
4098       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4099              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4100              ntohl (mp->miss_next_index));
4101       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4102              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4103              ntohl (mp->match_n_vectors));
4104       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4105              ntohl (mp->mask_length));
4106     }
4107   vam->retval = retval;
4108   vam->result_ready = 1;
4109 }
4110
4111 static void
4112   vl_api_classify_table_info_reply_t_handler_json
4113   (vl_api_classify_table_info_reply_t * mp)
4114 {
4115   vat_main_t *vam = &vat_main;
4116   vat_json_node_t node;
4117
4118   i32 retval = ntohl (mp->retval);
4119   if (retval == 0)
4120     {
4121       vat_json_init_object (&node);
4122
4123       vat_json_object_add_int (&node, "sessions",
4124                                ntohl (mp->active_sessions));
4125       vat_json_object_add_int (&node, "nexttbl",
4126                                ntohl (mp->next_table_index));
4127       vat_json_object_add_int (&node, "nextnode",
4128                                ntohl (mp->miss_next_index));
4129       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4130       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4131       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4132       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4133                       ntohl (mp->mask_length), 0);
4134       vat_json_object_add_string_copy (&node, "mask", s);
4135
4136       vat_json_print (vam->ofp, &node);
4137       vat_json_free (&node);
4138     }
4139   vam->retval = ntohl (mp->retval);
4140   vam->result_ready = 1;
4141 }
4142
4143 static void
4144 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4145                                            mp)
4146 {
4147   vat_main_t *vam = &vat_main;
4148
4149   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4150          ntohl (mp->hit_next_index), ntohl (mp->advance),
4151          ntohl (mp->opaque_index));
4152   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4153          ntohl (mp->match_length));
4154 }
4155
4156 static void
4157   vl_api_classify_session_details_t_handler_json
4158   (vl_api_classify_session_details_t * mp)
4159 {
4160   vat_main_t *vam = &vat_main;
4161   vat_json_node_t *node = NULL;
4162
4163   if (VAT_JSON_ARRAY != vam->json_tree.type)
4164     {
4165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4166       vat_json_init_array (&vam->json_tree);
4167     }
4168   node = vat_json_array_add (&vam->json_tree);
4169
4170   vat_json_init_object (node);
4171   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4172   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4173   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4174   u8 *s =
4175     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4176             0);
4177   vat_json_object_add_string_copy (node, "match", s);
4178 }
4179
4180 static void vl_api_pg_create_interface_reply_t_handler
4181   (vl_api_pg_create_interface_reply_t * mp)
4182 {
4183   vat_main_t *vam = &vat_main;
4184
4185   vam->retval = ntohl (mp->retval);
4186   vam->result_ready = 1;
4187 }
4188
4189 static void vl_api_pg_create_interface_reply_t_handler_json
4190   (vl_api_pg_create_interface_reply_t * mp)
4191 {
4192   vat_main_t *vam = &vat_main;
4193   vat_json_node_t node;
4194
4195   i32 retval = ntohl (mp->retval);
4196   if (retval == 0)
4197     {
4198       vat_json_init_object (&node);
4199
4200       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4201
4202       vat_json_print (vam->ofp, &node);
4203       vat_json_free (&node);
4204     }
4205   vam->retval = ntohl (mp->retval);
4206   vam->result_ready = 1;
4207 }
4208
4209 static void vl_api_policer_classify_details_t_handler
4210   (vl_api_policer_classify_details_t * mp)
4211 {
4212   vat_main_t *vam = &vat_main;
4213
4214   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4215          ntohl (mp->table_index));
4216 }
4217
4218 static void vl_api_policer_classify_details_t_handler_json
4219   (vl_api_policer_classify_details_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   vat_json_node_t *node;
4223
4224   if (VAT_JSON_ARRAY != vam->json_tree.type)
4225     {
4226       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4227       vat_json_init_array (&vam->json_tree);
4228     }
4229   node = vat_json_array_add (&vam->json_tree);
4230
4231   vat_json_init_object (node);
4232   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4233   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4234 }
4235
4236 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4237   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   i32 retval = ntohl (mp->retval);
4241   if (vam->async_mode)
4242     {
4243       vam->async_errors += (retval < 0);
4244     }
4245   else
4246     {
4247       vam->retval = retval;
4248       vam->sw_if_index = ntohl (mp->sw_if_index);
4249       vam->result_ready = 1;
4250     }
4251 }
4252
4253 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4254   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4255 {
4256   vat_main_t *vam = &vat_main;
4257   vat_json_node_t node;
4258
4259   vat_json_init_object (&node);
4260   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4261   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4262
4263   vat_json_print (vam->ofp, &node);
4264   vat_json_free (&node);
4265
4266   vam->retval = ntohl (mp->retval);
4267   vam->result_ready = 1;
4268 }
4269
4270 static void vl_api_flow_classify_details_t_handler
4271   (vl_api_flow_classify_details_t * mp)
4272 {
4273   vat_main_t *vam = &vat_main;
4274
4275   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4276          ntohl (mp->table_index));
4277 }
4278
4279 static void vl_api_flow_classify_details_t_handler_json
4280   (vl_api_flow_classify_details_t * mp)
4281 {
4282   vat_main_t *vam = &vat_main;
4283   vat_json_node_t *node;
4284
4285   if (VAT_JSON_ARRAY != vam->json_tree.type)
4286     {
4287       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4288       vat_json_init_array (&vam->json_tree);
4289     }
4290   node = vat_json_array_add (&vam->json_tree);
4291
4292   vat_json_init_object (node);
4293   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4294   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4295 }
4296
4297 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4298 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4299 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4300 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4301 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4302 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4303 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4304 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4305 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4306 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4307 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4308 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4309 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4310 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4311 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4312 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4313 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4314 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4315
4316 /*
4317  * Generate boilerplate reply handlers, which
4318  * dig the return value out of the xxx_reply_t API message,
4319  * stick it into vam->retval, and set vam->result_ready
4320  *
4321  * Could also do this by pointing N message decode slots at
4322  * a single function, but that could break in subtle ways.
4323  */
4324
4325 #define foreach_standard_reply_retval_handler           \
4326 _(sw_interface_set_flags_reply)                         \
4327 _(sw_interface_add_del_address_reply)                   \
4328 _(sw_interface_set_table_reply)                         \
4329 _(sw_interface_set_mpls_enable_reply)                   \
4330 _(sw_interface_set_vpath_reply)                         \
4331 _(sw_interface_set_vxlan_bypass_reply)                  \
4332 _(sw_interface_set_l2_bridge_reply)                     \
4333 _(bridge_domain_add_del_reply)                          \
4334 _(sw_interface_set_l2_xconnect_reply)                   \
4335 _(l2fib_add_del_reply)                                  \
4336 _(l2fib_flush_int_reply)                                \
4337 _(l2fib_flush_bd_reply)                                 \
4338 _(ip_add_del_route_reply)                               \
4339 _(ip_mroute_add_del_reply)                              \
4340 _(mpls_route_add_del_reply)                             \
4341 _(mpls_ip_bind_unbind_reply)                            \
4342 _(proxy_arp_add_del_reply)                              \
4343 _(proxy_arp_intfc_enable_disable_reply)                 \
4344 _(sw_interface_set_unnumbered_reply)                    \
4345 _(ip_neighbor_add_del_reply)                            \
4346 _(reset_vrf_reply)                                      \
4347 _(oam_add_del_reply)                                    \
4348 _(reset_fib_reply)                                      \
4349 _(dhcp_proxy_config_reply)                              \
4350 _(dhcp_proxy_set_vss_reply)                             \
4351 _(dhcp_client_config_reply)                             \
4352 _(set_ip_flow_hash_reply)                               \
4353 _(sw_interface_ip6_enable_disable_reply)                \
4354 _(sw_interface_ip6_set_link_local_address_reply)        \
4355 _(ip6nd_proxy_add_del_reply)                            \
4356 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4357 _(sw_interface_ip6nd_ra_config_reply)                   \
4358 _(set_arp_neighbor_limit_reply)                         \
4359 _(l2_patch_add_del_reply)                               \
4360 _(sr_policy_add_reply)                                  \
4361 _(sr_policy_mod_reply)                                  \
4362 _(sr_policy_del_reply)                                  \
4363 _(sr_localsid_add_del_reply)                            \
4364 _(sr_steering_add_del_reply)                            \
4365 _(classify_add_del_session_reply)                       \
4366 _(classify_set_interface_ip_table_reply)                \
4367 _(classify_set_interface_l2_tables_reply)               \
4368 _(l2tpv3_set_tunnel_cookies_reply)                      \
4369 _(l2tpv3_interface_enable_disable_reply)                \
4370 _(l2tpv3_set_lookup_key_reply)                          \
4371 _(l2_fib_clear_table_reply)                             \
4372 _(l2_interface_efp_filter_reply)                        \
4373 _(l2_interface_vlan_tag_rewrite_reply)                  \
4374 _(modify_vhost_user_if_reply)                           \
4375 _(delete_vhost_user_if_reply)                           \
4376 _(want_ip4_arp_events_reply)                            \
4377 _(want_ip6_nd_events_reply)                             \
4378 _(input_acl_set_interface_reply)                        \
4379 _(ipsec_spd_add_del_reply)                              \
4380 _(ipsec_interface_add_del_spd_reply)                    \
4381 _(ipsec_spd_add_del_entry_reply)                        \
4382 _(ipsec_sad_add_del_entry_reply)                        \
4383 _(ipsec_sa_set_key_reply)                               \
4384 _(ipsec_tunnel_if_add_del_reply)                        \
4385 _(ikev2_profile_add_del_reply)                          \
4386 _(ikev2_profile_set_auth_reply)                         \
4387 _(ikev2_profile_set_id_reply)                           \
4388 _(ikev2_profile_set_ts_reply)                           \
4389 _(ikev2_set_local_key_reply)                            \
4390 _(ikev2_set_responder_reply)                            \
4391 _(ikev2_set_ike_transforms_reply)                       \
4392 _(ikev2_set_esp_transforms_reply)                       \
4393 _(ikev2_set_sa_lifetime_reply)                          \
4394 _(ikev2_initiate_sa_init_reply)                         \
4395 _(ikev2_initiate_del_ike_sa_reply)                      \
4396 _(ikev2_initiate_del_child_sa_reply)                    \
4397 _(ikev2_initiate_rekey_child_sa_reply)                  \
4398 _(delete_loopback_reply)                                \
4399 _(bd_ip_mac_add_del_reply)                              \
4400 _(map_del_domain_reply)                                 \
4401 _(map_add_del_rule_reply)                               \
4402 _(want_interface_events_reply)                          \
4403 _(want_stats_reply)                                     \
4404 _(cop_interface_enable_disable_reply)                   \
4405 _(cop_whitelist_enable_disable_reply)                   \
4406 _(sw_interface_clear_stats_reply)                       \
4407 _(ioam_enable_reply)                              \
4408 _(ioam_disable_reply)                              \
4409 _(one_add_del_locator_reply)                            \
4410 _(one_add_del_local_eid_reply)                          \
4411 _(one_add_del_remote_mapping_reply)                     \
4412 _(one_add_del_adjacency_reply)                          \
4413 _(one_add_del_map_resolver_reply)                       \
4414 _(one_add_del_map_server_reply)                         \
4415 _(one_enable_disable_reply)                             \
4416 _(one_rloc_probe_enable_disable_reply)                  \
4417 _(one_map_register_enable_disable_reply)                \
4418 _(one_pitr_set_locator_set_reply)                       \
4419 _(one_map_request_mode_reply)                           \
4420 _(one_add_del_map_request_itr_rlocs_reply)              \
4421 _(one_eid_table_add_del_map_reply)                      \
4422 _(one_use_petr_reply)                                   \
4423 _(one_stats_enable_disable_reply)                       \
4424 _(one_add_del_l2_arp_entry_reply)                       \
4425 _(one_stats_flush_reply)                                \
4426 _(gpe_enable_disable_reply)                             \
4427 _(gpe_set_encap_mode_reply)                             \
4428 _(gpe_add_del_iface_reply)                              \
4429 _(vxlan_gpe_add_del_tunnel_reply)                       \
4430 _(af_packet_delete_reply)                               \
4431 _(policer_classify_set_interface_reply)                 \
4432 _(netmap_create_reply)                                  \
4433 _(netmap_delete_reply)                                  \
4434 _(set_ipfix_exporter_reply)                             \
4435 _(set_ipfix_classify_stream_reply)                      \
4436 _(ipfix_classify_table_add_del_reply)                   \
4437 _(flow_classify_set_interface_reply)                    \
4438 _(sw_interface_span_enable_disable_reply)               \
4439 _(pg_capture_reply)                                     \
4440 _(pg_enable_disable_reply)                              \
4441 _(ip_source_and_port_range_check_add_del_reply)         \
4442 _(ip_source_and_port_range_check_interface_add_del_reply)\
4443 _(delete_subif_reply)                                   \
4444 _(l2_interface_pbb_tag_rewrite_reply)                   \
4445 _(punt_reply)                                           \
4446 _(feature_enable_disable_reply)                         \
4447 _(sw_interface_tag_add_del_reply)                       \
4448 _(sw_interface_set_mtu_reply)
4449
4450 #define _(n)                                    \
4451     static void vl_api_##n##_t_handler          \
4452     (vl_api_##n##_t * mp)                       \
4453     {                                           \
4454         vat_main_t * vam = &vat_main;           \
4455         i32 retval = ntohl(mp->retval);         \
4456         if (vam->async_mode) {                  \
4457             vam->async_errors += (retval < 0);  \
4458         } else {                                \
4459             vam->retval = retval;               \
4460             vam->result_ready = 1;              \
4461         }                                       \
4462     }
4463 foreach_standard_reply_retval_handler;
4464 #undef _
4465
4466 #define _(n)                                    \
4467     static void vl_api_##n##_t_handler_json     \
4468     (vl_api_##n##_t * mp)                       \
4469     {                                           \
4470         vat_main_t * vam = &vat_main;           \
4471         vat_json_node_t node;                   \
4472         vat_json_init_object(&node);            \
4473         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4474         vat_json_print(vam->ofp, &node);        \
4475         vam->retval = ntohl(mp->retval);        \
4476         vam->result_ready = 1;                  \
4477     }
4478 foreach_standard_reply_retval_handler;
4479 #undef _
4480
4481 /*
4482  * Table of message reply handlers, must include boilerplate handlers
4483  * we just generated
4484  */
4485
4486 #define foreach_vpe_api_reply_msg                                       \
4487 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4488 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4489 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4490 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4491 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4492 _(CLI_REPLY, cli_reply)                                                 \
4493 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4494 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4495   sw_interface_add_del_address_reply)                                   \
4496 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4497 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4498 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4499 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4500 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4501   sw_interface_set_l2_xconnect_reply)                                   \
4502 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4503   sw_interface_set_l2_bridge_reply)                                     \
4504 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4505 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4506 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4507 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4508 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4509 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4510 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4511 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4512 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4513 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4514 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4515 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4516 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4517 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4518 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4519 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4520 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4521 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4522   proxy_arp_intfc_enable_disable_reply)                                 \
4523 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4524 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4525   sw_interface_set_unnumbered_reply)                                    \
4526 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4527 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4528 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4529 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4530 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4531 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4532 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4533 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4534 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4535 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4536 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4537 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4538   sw_interface_ip6_enable_disable_reply)                                \
4539 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4540   sw_interface_ip6_set_link_local_address_reply)                        \
4541 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4542 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4543 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4544   sw_interface_ip6nd_ra_prefix_reply)                                   \
4545 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4546   sw_interface_ip6nd_ra_config_reply)                                   \
4547 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4548 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4549 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4550 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4551 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4552 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4553 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4554 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4555 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4556 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4557 classify_set_interface_ip_table_reply)                                  \
4558 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4559   classify_set_interface_l2_tables_reply)                               \
4560 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4561 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4562 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4563 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4564 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4565   l2tpv3_interface_enable_disable_reply)                                \
4566 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4567 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4568 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4569 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4570 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4571 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4572 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4573 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4574 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4575 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4576 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4577 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4578 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4579 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4580 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4581 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4582 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4583 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4584 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4585 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4586 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4587 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4588 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4589 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4590 _(IP_DETAILS, ip_details)                                               \
4591 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4592 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4593 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4594 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4595 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4596 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4597 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4598 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4599 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4600 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4601 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4602 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4603 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4604 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4605 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4606 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4607 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4608 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4609 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4610 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4611 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4612 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4613 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4614 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4615 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4616 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4617 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4618 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4619 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4620 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4621 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4622 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4623 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4624 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4625 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4626 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4627 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4628 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4629 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4630 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4631 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4632 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4633 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4634 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4635 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4636   one_map_register_enable_disable_reply)                                \
4637 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4638   one_rloc_probe_enable_disable_reply)                                  \
4639 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4640 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4641 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4642 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4643 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4644 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4645 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4646 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4647 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4648 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4649 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4650 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4651 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4652 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4653 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4654 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4655   show_one_stats_enable_disable_reply)                                  \
4656 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4657 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4658 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4659 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4660 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4661 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4662 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4663 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4664 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4665 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4666 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4667   gpe_fwd_entry_path_details)                                           \
4668 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4669 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4670   one_add_del_map_request_itr_rlocs_reply)                              \
4671 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4672   one_get_map_request_itr_rlocs_reply)                                  \
4673 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4674 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4675 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4676 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4677 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4678   show_one_map_register_state_reply)                                    \
4679 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4680 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4681 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4682 _(POLICER_DETAILS, policer_details)                                     \
4683 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4684 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4685 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4686 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4687 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4688 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4689 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4690 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4691 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4692 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4693 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4694 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4695 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4696 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4697 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4698 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4699 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4700 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4701 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4702 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4703 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4704 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4705 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4706 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4707 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4708  ip_source_and_port_range_check_add_del_reply)                          \
4709 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4710  ip_source_and_port_range_check_interface_add_del_reply)                \
4711 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4712 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4713 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4714 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4715 _(PUNT_REPLY, punt_reply)                                               \
4716 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4717 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4718 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4719 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4720 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4721 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4722 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4723 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4724
4725 #define foreach_standalone_reply_msg                                    \
4726 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4727 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4728 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4729 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4730 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4731 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4732 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4733
4734 typedef struct
4735 {
4736   u8 *name;
4737   u32 value;
4738 } name_sort_t;
4739
4740
4741 #define STR_VTR_OP_CASE(op)     \
4742     case L2_VTR_ ## op:         \
4743         return "" # op;
4744
4745 static const char *
4746 str_vtr_op (u32 vtr_op)
4747 {
4748   switch (vtr_op)
4749     {
4750       STR_VTR_OP_CASE (DISABLED);
4751       STR_VTR_OP_CASE (PUSH_1);
4752       STR_VTR_OP_CASE (PUSH_2);
4753       STR_VTR_OP_CASE (POP_1);
4754       STR_VTR_OP_CASE (POP_2);
4755       STR_VTR_OP_CASE (TRANSLATE_1_1);
4756       STR_VTR_OP_CASE (TRANSLATE_1_2);
4757       STR_VTR_OP_CASE (TRANSLATE_2_1);
4758       STR_VTR_OP_CASE (TRANSLATE_2_2);
4759     }
4760
4761   return "UNKNOWN";
4762 }
4763
4764 static int
4765 dump_sub_interface_table (vat_main_t * vam)
4766 {
4767   const sw_interface_subif_t *sub = NULL;
4768
4769   if (vam->json_output)
4770     {
4771       clib_warning
4772         ("JSON output supported only for VPE API calls and dump_stats_table");
4773       return -99;
4774     }
4775
4776   print (vam->ofp,
4777          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4778          "Interface", "sw_if_index",
4779          "sub id", "dot1ad", "tags", "outer id",
4780          "inner id", "exact", "default", "outer any", "inner any");
4781
4782   vec_foreach (sub, vam->sw_if_subif_table)
4783   {
4784     print (vam->ofp,
4785            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4786            sub->interface_name,
4787            sub->sw_if_index,
4788            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4789            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4790            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4791            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4792     if (sub->vtr_op != L2_VTR_DISABLED)
4793       {
4794         print (vam->ofp,
4795                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4796                "tag1: %d tag2: %d ]",
4797                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4798                sub->vtr_tag1, sub->vtr_tag2);
4799       }
4800   }
4801
4802   return 0;
4803 }
4804
4805 static int
4806 name_sort_cmp (void *a1, void *a2)
4807 {
4808   name_sort_t *n1 = a1;
4809   name_sort_t *n2 = a2;
4810
4811   return strcmp ((char *) n1->name, (char *) n2->name);
4812 }
4813
4814 static int
4815 dump_interface_table (vat_main_t * vam)
4816 {
4817   hash_pair_t *p;
4818   name_sort_t *nses = 0, *ns;
4819
4820   if (vam->json_output)
4821     {
4822       clib_warning
4823         ("JSON output supported only for VPE API calls and dump_stats_table");
4824       return -99;
4825     }
4826
4827   /* *INDENT-OFF* */
4828   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4829   ({
4830     vec_add2 (nses, ns, 1);
4831     ns->name = (u8 *)(p->key);
4832     ns->value = (u32) p->value[0];
4833   }));
4834   /* *INDENT-ON* */
4835
4836   vec_sort_with_function (nses, name_sort_cmp);
4837
4838   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4839   vec_foreach (ns, nses)
4840   {
4841     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4842   }
4843   vec_free (nses);
4844   return 0;
4845 }
4846
4847 static int
4848 dump_ip_table (vat_main_t * vam, int is_ipv6)
4849 {
4850   const ip_details_t *det = NULL;
4851   const ip_address_details_t *address = NULL;
4852   u32 i = ~0;
4853
4854   print (vam->ofp, "%-12s", "sw_if_index");
4855
4856   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4857   {
4858     i++;
4859     if (!det->present)
4860       {
4861         continue;
4862       }
4863     print (vam->ofp, "%-12d", i);
4864     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4865     if (!det->addr)
4866       {
4867         continue;
4868       }
4869     vec_foreach (address, det->addr)
4870     {
4871       print (vam->ofp,
4872              "            %-30U%-13d",
4873              is_ipv6 ? format_ip6_address : format_ip4_address,
4874              address->ip, address->prefix_length);
4875     }
4876   }
4877
4878   return 0;
4879 }
4880
4881 static int
4882 dump_ipv4_table (vat_main_t * vam)
4883 {
4884   if (vam->json_output)
4885     {
4886       clib_warning
4887         ("JSON output supported only for VPE API calls and dump_stats_table");
4888       return -99;
4889     }
4890
4891   return dump_ip_table (vam, 0);
4892 }
4893
4894 static int
4895 dump_ipv6_table (vat_main_t * vam)
4896 {
4897   if (vam->json_output)
4898     {
4899       clib_warning
4900         ("JSON output supported only for VPE API calls and dump_stats_table");
4901       return -99;
4902     }
4903
4904   return dump_ip_table (vam, 1);
4905 }
4906
4907 static char *
4908 counter_type_to_str (u8 counter_type, u8 is_combined)
4909 {
4910   if (!is_combined)
4911     {
4912       switch (counter_type)
4913         {
4914         case VNET_INTERFACE_COUNTER_DROP:
4915           return "drop";
4916         case VNET_INTERFACE_COUNTER_PUNT:
4917           return "punt";
4918         case VNET_INTERFACE_COUNTER_IP4:
4919           return "ip4";
4920         case VNET_INTERFACE_COUNTER_IP6:
4921           return "ip6";
4922         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4923           return "rx-no-buf";
4924         case VNET_INTERFACE_COUNTER_RX_MISS:
4925           return "rx-miss";
4926         case VNET_INTERFACE_COUNTER_RX_ERROR:
4927           return "rx-error";
4928         case VNET_INTERFACE_COUNTER_TX_ERROR:
4929           return "tx-error";
4930         default:
4931           return "INVALID-COUNTER-TYPE";
4932         }
4933     }
4934   else
4935     {
4936       switch (counter_type)
4937         {
4938         case VNET_INTERFACE_COUNTER_RX:
4939           return "rx";
4940         case VNET_INTERFACE_COUNTER_TX:
4941           return "tx";
4942         default:
4943           return "INVALID-COUNTER-TYPE";
4944         }
4945     }
4946 }
4947
4948 static int
4949 dump_stats_table (vat_main_t * vam)
4950 {
4951   vat_json_node_t node;
4952   vat_json_node_t *msg_array;
4953   vat_json_node_t *msg;
4954   vat_json_node_t *counter_array;
4955   vat_json_node_t *counter;
4956   interface_counter_t c;
4957   u64 packets;
4958   ip4_fib_counter_t *c4;
4959   ip6_fib_counter_t *c6;
4960   ip4_nbr_counter_t *n4;
4961   ip6_nbr_counter_t *n6;
4962   int i, j;
4963
4964   if (!vam->json_output)
4965     {
4966       clib_warning ("dump_stats_table supported only in JSON format");
4967       return -99;
4968     }
4969
4970   vat_json_init_object (&node);
4971
4972   /* interface counters */
4973   msg_array = vat_json_object_add (&node, "interface_counters");
4974   vat_json_init_array (msg_array);
4975   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4976     {
4977       msg = vat_json_array_add (msg_array);
4978       vat_json_init_object (msg);
4979       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4980                                        (u8 *) counter_type_to_str (i, 0));
4981       vat_json_object_add_int (msg, "is_combined", 0);
4982       counter_array = vat_json_object_add (msg, "data");
4983       vat_json_init_array (counter_array);
4984       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4985         {
4986           packets = vam->simple_interface_counters[i][j];
4987           vat_json_array_add_uint (counter_array, packets);
4988         }
4989     }
4990   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4991     {
4992       msg = vat_json_array_add (msg_array);
4993       vat_json_init_object (msg);
4994       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4995                                        (u8 *) counter_type_to_str (i, 1));
4996       vat_json_object_add_int (msg, "is_combined", 1);
4997       counter_array = vat_json_object_add (msg, "data");
4998       vat_json_init_array (counter_array);
4999       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5000         {
5001           c = vam->combined_interface_counters[i][j];
5002           counter = vat_json_array_add (counter_array);
5003           vat_json_init_object (counter);
5004           vat_json_object_add_uint (counter, "packets", c.packets);
5005           vat_json_object_add_uint (counter, "bytes", c.bytes);
5006         }
5007     }
5008
5009   /* ip4 fib counters */
5010   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5011   vat_json_init_array (msg_array);
5012   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5013     {
5014       msg = vat_json_array_add (msg_array);
5015       vat_json_init_object (msg);
5016       vat_json_object_add_uint (msg, "vrf_id",
5017                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5018       counter_array = vat_json_object_add (msg, "c");
5019       vat_json_init_array (counter_array);
5020       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5021         {
5022           counter = vat_json_array_add (counter_array);
5023           vat_json_init_object (counter);
5024           c4 = &vam->ip4_fib_counters[i][j];
5025           vat_json_object_add_ip4 (counter, "address", c4->address);
5026           vat_json_object_add_uint (counter, "address_length",
5027                                     c4->address_length);
5028           vat_json_object_add_uint (counter, "packets", c4->packets);
5029           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5030         }
5031     }
5032
5033   /* ip6 fib counters */
5034   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5035   vat_json_init_array (msg_array);
5036   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5037     {
5038       msg = vat_json_array_add (msg_array);
5039       vat_json_init_object (msg);
5040       vat_json_object_add_uint (msg, "vrf_id",
5041                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5042       counter_array = vat_json_object_add (msg, "c");
5043       vat_json_init_array (counter_array);
5044       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5045         {
5046           counter = vat_json_array_add (counter_array);
5047           vat_json_init_object (counter);
5048           c6 = &vam->ip6_fib_counters[i][j];
5049           vat_json_object_add_ip6 (counter, "address", c6->address);
5050           vat_json_object_add_uint (counter, "address_length",
5051                                     c6->address_length);
5052           vat_json_object_add_uint (counter, "packets", c6->packets);
5053           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5054         }
5055     }
5056
5057   /* ip4 nbr counters */
5058   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5059   vat_json_init_array (msg_array);
5060   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5061     {
5062       msg = vat_json_array_add (msg_array);
5063       vat_json_init_object (msg);
5064       vat_json_object_add_uint (msg, "sw_if_index", i);
5065       counter_array = vat_json_object_add (msg, "c");
5066       vat_json_init_array (counter_array);
5067       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5068         {
5069           counter = vat_json_array_add (counter_array);
5070           vat_json_init_object (counter);
5071           n4 = &vam->ip4_nbr_counters[i][j];
5072           vat_json_object_add_ip4 (counter, "address", n4->address);
5073           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5074           vat_json_object_add_uint (counter, "packets", n4->packets);
5075           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5076         }
5077     }
5078
5079   /* ip6 nbr counters */
5080   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5081   vat_json_init_array (msg_array);
5082   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5083     {
5084       msg = vat_json_array_add (msg_array);
5085       vat_json_init_object (msg);
5086       vat_json_object_add_uint (msg, "sw_if_index", i);
5087       counter_array = vat_json_object_add (msg, "c");
5088       vat_json_init_array (counter_array);
5089       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5090         {
5091           counter = vat_json_array_add (counter_array);
5092           vat_json_init_object (counter);
5093           n6 = &vam->ip6_nbr_counters[i][j];
5094           vat_json_object_add_ip6 (counter, "address", n6->address);
5095           vat_json_object_add_uint (counter, "packets", n6->packets);
5096           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5097         }
5098     }
5099
5100   vat_json_print (vam->ofp, &node);
5101   vat_json_free (&node);
5102
5103   return 0;
5104 }
5105
5106 int
5107 exec (vat_main_t * vam)
5108 {
5109   api_main_t *am = &api_main;
5110   vl_api_cli_t *mp;
5111   f64 timeout;
5112   void *oldheap;
5113   u8 *cmd = 0;
5114   unformat_input_t *i = vam->input;
5115
5116   if (vec_len (i->buffer) == 0)
5117     return -1;
5118
5119   if (vam->exec_mode == 0 && unformat (i, "mode"))
5120     {
5121       vam->exec_mode = 1;
5122       return 0;
5123     }
5124   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5125     {
5126       vam->exec_mode = 0;
5127       return 0;
5128     }
5129
5130
5131   M (CLI, mp);
5132
5133   /*
5134    * Copy cmd into shared memory.
5135    * In order for the CLI command to work, it
5136    * must be a vector ending in \n, not a C-string ending
5137    * in \n\0.
5138    */
5139   pthread_mutex_lock (&am->vlib_rp->mutex);
5140   oldheap = svm_push_data_heap (am->vlib_rp);
5141
5142   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5143   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5144
5145   svm_pop_heap (oldheap);
5146   pthread_mutex_unlock (&am->vlib_rp->mutex);
5147
5148   mp->cmd_in_shmem = pointer_to_uword (cmd);
5149   S (mp);
5150   timeout = vat_time_now (vam) + 10.0;
5151
5152   while (vat_time_now (vam) < timeout)
5153     {
5154       if (vam->result_ready == 1)
5155         {
5156           u8 *free_me;
5157           if (vam->shmem_result != NULL)
5158             print (vam->ofp, "%s", vam->shmem_result);
5159           pthread_mutex_lock (&am->vlib_rp->mutex);
5160           oldheap = svm_push_data_heap (am->vlib_rp);
5161
5162           free_me = (u8 *) vam->shmem_result;
5163           vec_free (free_me);
5164
5165           svm_pop_heap (oldheap);
5166           pthread_mutex_unlock (&am->vlib_rp->mutex);
5167           return 0;
5168         }
5169     }
5170   return -99;
5171 }
5172
5173 /*
5174  * Future replacement of exec() that passes CLI buffers directly in
5175  * the API messages instead of an additional shared memory area.
5176  */
5177 static int
5178 exec_inband (vat_main_t * vam)
5179 {
5180   vl_api_cli_inband_t *mp;
5181   unformat_input_t *i = vam->input;
5182   int ret;
5183
5184   if (vec_len (i->buffer) == 0)
5185     return -1;
5186
5187   if (vam->exec_mode == 0 && unformat (i, "mode"))
5188     {
5189       vam->exec_mode = 1;
5190       return 0;
5191     }
5192   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5193     {
5194       vam->exec_mode = 0;
5195       return 0;
5196     }
5197
5198   /*
5199    * In order for the CLI command to work, it
5200    * must be a vector ending in \n, not a C-string ending
5201    * in \n\0.
5202    */
5203   u32 len = vec_len (vam->input->buffer);
5204   M2 (CLI_INBAND, mp, len);
5205   clib_memcpy (mp->cmd, vam->input->buffer, len);
5206   mp->length = htonl (len);
5207
5208   S (mp);
5209   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5210   return ret;
5211 }
5212
5213 static int
5214 api_create_loopback (vat_main_t * vam)
5215 {
5216   unformat_input_t *i = vam->input;
5217   vl_api_create_loopback_t *mp;
5218   vl_api_create_loopback_instance_t *mp_lbi;
5219   u8 mac_address[6];
5220   u8 mac_set = 0;
5221   u8 is_specified = 0;
5222   u32 user_instance = 0;
5223   int ret;
5224
5225   memset (mac_address, 0, sizeof (mac_address));
5226
5227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5228     {
5229       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5230         mac_set = 1;
5231       if (unformat (i, "instance %d", &user_instance))
5232         is_specified = 1;
5233       else
5234         break;
5235     }
5236
5237   if (is_specified)
5238     {
5239       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5240       mp_lbi->is_specified = is_specified;
5241       if (is_specified)
5242         mp_lbi->user_instance = htonl (user_instance);
5243       if (mac_set)
5244         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5245       S (mp_lbi);
5246     }
5247   else
5248     {
5249       /* Construct the API message */
5250       M (CREATE_LOOPBACK, mp);
5251       if (mac_set)
5252         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5253       S (mp);
5254     }
5255
5256   W (ret);
5257   return ret;
5258 }
5259
5260 static int
5261 api_delete_loopback (vat_main_t * vam)
5262 {
5263   unformat_input_t *i = vam->input;
5264   vl_api_delete_loopback_t *mp;
5265   u32 sw_if_index = ~0;
5266   int ret;
5267
5268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5269     {
5270       if (unformat (i, "sw_if_index %d", &sw_if_index))
5271         ;
5272       else
5273         break;
5274     }
5275
5276   if (sw_if_index == ~0)
5277     {
5278       errmsg ("missing sw_if_index");
5279       return -99;
5280     }
5281
5282   /* Construct the API message */
5283   M (DELETE_LOOPBACK, mp);
5284   mp->sw_if_index = ntohl (sw_if_index);
5285
5286   S (mp);
5287   W (ret);
5288   return ret;
5289 }
5290
5291 static int
5292 api_want_stats (vat_main_t * vam)
5293 {
5294   unformat_input_t *i = vam->input;
5295   vl_api_want_stats_t *mp;
5296   int enable = -1;
5297   int ret;
5298
5299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5300     {
5301       if (unformat (i, "enable"))
5302         enable = 1;
5303       else if (unformat (i, "disable"))
5304         enable = 0;
5305       else
5306         break;
5307     }
5308
5309   if (enable == -1)
5310     {
5311       errmsg ("missing enable|disable");
5312       return -99;
5313     }
5314
5315   M (WANT_STATS, mp);
5316   mp->enable_disable = enable;
5317
5318   S (mp);
5319   W (ret);
5320   return ret;
5321 }
5322
5323 static int
5324 api_want_interface_events (vat_main_t * vam)
5325 {
5326   unformat_input_t *i = vam->input;
5327   vl_api_want_interface_events_t *mp;
5328   int enable = -1;
5329   int ret;
5330
5331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5332     {
5333       if (unformat (i, "enable"))
5334         enable = 1;
5335       else if (unformat (i, "disable"))
5336         enable = 0;
5337       else
5338         break;
5339     }
5340
5341   if (enable == -1)
5342     {
5343       errmsg ("missing enable|disable");
5344       return -99;
5345     }
5346
5347   M (WANT_INTERFACE_EVENTS, mp);
5348   mp->enable_disable = enable;
5349
5350   vam->interface_event_display = enable;
5351
5352   S (mp);
5353   W (ret);
5354   return ret;
5355 }
5356
5357
5358 /* Note: non-static, called once to set up the initial intfc table */
5359 int
5360 api_sw_interface_dump (vat_main_t * vam)
5361 {
5362   vl_api_sw_interface_dump_t *mp;
5363   vl_api_control_ping_t *mp_ping;
5364   hash_pair_t *p;
5365   name_sort_t *nses = 0, *ns;
5366   sw_interface_subif_t *sub = NULL;
5367   int ret;
5368
5369   /* Toss the old name table */
5370   /* *INDENT-OFF* */
5371   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5372   ({
5373     vec_add2 (nses, ns, 1);
5374     ns->name = (u8 *)(p->key);
5375     ns->value = (u32) p->value[0];
5376   }));
5377   /* *INDENT-ON* */
5378
5379   hash_free (vam->sw_if_index_by_interface_name);
5380
5381   vec_foreach (ns, nses) vec_free (ns->name);
5382
5383   vec_free (nses);
5384
5385   vec_foreach (sub, vam->sw_if_subif_table)
5386   {
5387     vec_free (sub->interface_name);
5388   }
5389   vec_free (vam->sw_if_subif_table);
5390
5391   /* recreate the interface name hash table */
5392   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5393
5394   /* Get list of ethernets */
5395   M (SW_INTERFACE_DUMP, mp);
5396   mp->name_filter_valid = 1;
5397   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5398   S (mp);
5399
5400   /* and local / loopback interfaces */
5401   M (SW_INTERFACE_DUMP, mp);
5402   mp->name_filter_valid = 1;
5403   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5404   S (mp);
5405
5406   /* and packet-generator interfaces */
5407   M (SW_INTERFACE_DUMP, mp);
5408   mp->name_filter_valid = 1;
5409   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5410   S (mp);
5411
5412   /* and vxlan-gpe tunnel interfaces */
5413   M (SW_INTERFACE_DUMP, mp);
5414   mp->name_filter_valid = 1;
5415   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5416            sizeof (mp->name_filter) - 1);
5417   S (mp);
5418
5419   /* and vxlan tunnel interfaces */
5420   M (SW_INTERFACE_DUMP, mp);
5421   mp->name_filter_valid = 1;
5422   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5423   S (mp);
5424
5425   /* and host (af_packet) interfaces */
5426   M (SW_INTERFACE_DUMP, mp);
5427   mp->name_filter_valid = 1;
5428   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5429   S (mp);
5430
5431   /* and l2tpv3 tunnel interfaces */
5432   M (SW_INTERFACE_DUMP, mp);
5433   mp->name_filter_valid = 1;
5434   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5435            sizeof (mp->name_filter) - 1);
5436   S (mp);
5437
5438   /* and GRE tunnel interfaces */
5439   M (SW_INTERFACE_DUMP, mp);
5440   mp->name_filter_valid = 1;
5441   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5442   S (mp);
5443
5444   /* and LISP-GPE interfaces */
5445   M (SW_INTERFACE_DUMP, mp);
5446   mp->name_filter_valid = 1;
5447   strncpy ((char *) mp->name_filter, "lisp_gpe",
5448            sizeof (mp->name_filter) - 1);
5449   S (mp);
5450
5451   /* and IPSEC tunnel interfaces */
5452   M (SW_INTERFACE_DUMP, mp);
5453   mp->name_filter_valid = 1;
5454   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5455   S (mp);
5456
5457   /* Use a control ping for synchronization */
5458   M (CONTROL_PING, mp_ping);
5459   S (mp_ping);
5460
5461   W (ret);
5462   return ret;
5463 }
5464
5465 static int
5466 api_sw_interface_set_flags (vat_main_t * vam)
5467 {
5468   unformat_input_t *i = vam->input;
5469   vl_api_sw_interface_set_flags_t *mp;
5470   u32 sw_if_index;
5471   u8 sw_if_index_set = 0;
5472   u8 admin_up = 0, link_up = 0;
5473   int ret;
5474
5475   /* Parse args required to build the message */
5476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5477     {
5478       if (unformat (i, "admin-up"))
5479         admin_up = 1;
5480       else if (unformat (i, "admin-down"))
5481         admin_up = 0;
5482       else if (unformat (i, "link-up"))
5483         link_up = 1;
5484       else if (unformat (i, "link-down"))
5485         link_up = 0;
5486       else
5487         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5488         sw_if_index_set = 1;
5489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5490         sw_if_index_set = 1;
5491       else
5492         break;
5493     }
5494
5495   if (sw_if_index_set == 0)
5496     {
5497       errmsg ("missing interface name or sw_if_index");
5498       return -99;
5499     }
5500
5501   /* Construct the API message */
5502   M (SW_INTERFACE_SET_FLAGS, mp);
5503   mp->sw_if_index = ntohl (sw_if_index);
5504   mp->admin_up_down = admin_up;
5505   mp->link_up_down = link_up;
5506
5507   /* send it... */
5508   S (mp);
5509
5510   /* Wait for a reply, return the good/bad news... */
5511   W (ret);
5512   return ret;
5513 }
5514
5515 static int
5516 api_sw_interface_clear_stats (vat_main_t * vam)
5517 {
5518   unformat_input_t *i = vam->input;
5519   vl_api_sw_interface_clear_stats_t *mp;
5520   u32 sw_if_index;
5521   u8 sw_if_index_set = 0;
5522   int ret;
5523
5524   /* Parse args required to build the message */
5525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5526     {
5527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5528         sw_if_index_set = 1;
5529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5530         sw_if_index_set = 1;
5531       else
5532         break;
5533     }
5534
5535   /* Construct the API message */
5536   M (SW_INTERFACE_CLEAR_STATS, mp);
5537
5538   if (sw_if_index_set == 1)
5539     mp->sw_if_index = ntohl (sw_if_index);
5540   else
5541     mp->sw_if_index = ~0;
5542
5543   /* send it... */
5544   S (mp);
5545
5546   /* Wait for a reply, return the good/bad news... */
5547   W (ret);
5548   return ret;
5549 }
5550
5551 static int
5552 api_sw_interface_add_del_address (vat_main_t * vam)
5553 {
5554   unformat_input_t *i = vam->input;
5555   vl_api_sw_interface_add_del_address_t *mp;
5556   u32 sw_if_index;
5557   u8 sw_if_index_set = 0;
5558   u8 is_add = 1, del_all = 0;
5559   u32 address_length = 0;
5560   u8 v4_address_set = 0;
5561   u8 v6_address_set = 0;
5562   ip4_address_t v4address;
5563   ip6_address_t v6address;
5564   int ret;
5565
5566   /* Parse args required to build the message */
5567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5568     {
5569       if (unformat (i, "del-all"))
5570         del_all = 1;
5571       else if (unformat (i, "del"))
5572         is_add = 0;
5573       else
5574         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5575         sw_if_index_set = 1;
5576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5577         sw_if_index_set = 1;
5578       else if (unformat (i, "%U/%d",
5579                          unformat_ip4_address, &v4address, &address_length))
5580         v4_address_set = 1;
5581       else if (unformat (i, "%U/%d",
5582                          unformat_ip6_address, &v6address, &address_length))
5583         v6_address_set = 1;
5584       else
5585         break;
5586     }
5587
5588   if (sw_if_index_set == 0)
5589     {
5590       errmsg ("missing interface name or sw_if_index");
5591       return -99;
5592     }
5593   if (v4_address_set && v6_address_set)
5594     {
5595       errmsg ("both v4 and v6 addresses set");
5596       return -99;
5597     }
5598   if (!v4_address_set && !v6_address_set && !del_all)
5599     {
5600       errmsg ("no addresses set");
5601       return -99;
5602     }
5603
5604   /* Construct the API message */
5605   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5606
5607   mp->sw_if_index = ntohl (sw_if_index);
5608   mp->is_add = is_add;
5609   mp->del_all = del_all;
5610   if (v6_address_set)
5611     {
5612       mp->is_ipv6 = 1;
5613       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5614     }
5615   else
5616     {
5617       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5618     }
5619   mp->address_length = address_length;
5620
5621   /* send it... */
5622   S (mp);
5623
5624   /* Wait for a reply, return good/bad news  */
5625   W (ret);
5626   return ret;
5627 }
5628
5629 static int
5630 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5631 {
5632   unformat_input_t *i = vam->input;
5633   vl_api_sw_interface_set_mpls_enable_t *mp;
5634   u32 sw_if_index;
5635   u8 sw_if_index_set = 0;
5636   u8 enable = 1;
5637   int ret;
5638
5639   /* Parse args required to build the message */
5640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5641     {
5642       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5643         sw_if_index_set = 1;
5644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5645         sw_if_index_set = 1;
5646       else if (unformat (i, "disable"))
5647         enable = 0;
5648       else if (unformat (i, "dis"))
5649         enable = 0;
5650       else
5651         break;
5652     }
5653
5654   if (sw_if_index_set == 0)
5655     {
5656       errmsg ("missing interface name or sw_if_index");
5657       return -99;
5658     }
5659
5660   /* Construct the API message */
5661   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5662
5663   mp->sw_if_index = ntohl (sw_if_index);
5664   mp->enable = enable;
5665
5666   /* send it... */
5667   S (mp);
5668
5669   /* Wait for a reply... */
5670   W (ret);
5671   return ret;
5672 }
5673
5674 static int
5675 api_sw_interface_set_table (vat_main_t * vam)
5676 {
5677   unformat_input_t *i = vam->input;
5678   vl_api_sw_interface_set_table_t *mp;
5679   u32 sw_if_index, vrf_id = 0;
5680   u8 sw_if_index_set = 0;
5681   u8 is_ipv6 = 0;
5682   int ret;
5683
5684   /* Parse args required to build the message */
5685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5686     {
5687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5688         sw_if_index_set = 1;
5689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5690         sw_if_index_set = 1;
5691       else if (unformat (i, "vrf %d", &vrf_id))
5692         ;
5693       else if (unformat (i, "ipv6"))
5694         is_ipv6 = 1;
5695       else
5696         break;
5697     }
5698
5699   if (sw_if_index_set == 0)
5700     {
5701       errmsg ("missing interface name or sw_if_index");
5702       return -99;
5703     }
5704
5705   /* Construct the API message */
5706   M (SW_INTERFACE_SET_TABLE, mp);
5707
5708   mp->sw_if_index = ntohl (sw_if_index);
5709   mp->is_ipv6 = is_ipv6;
5710   mp->vrf_id = ntohl (vrf_id);
5711
5712   /* send it... */
5713   S (mp);
5714
5715   /* Wait for a reply... */
5716   W (ret);
5717   return ret;
5718 }
5719
5720 static void vl_api_sw_interface_get_table_reply_t_handler
5721   (vl_api_sw_interface_get_table_reply_t * mp)
5722 {
5723   vat_main_t *vam = &vat_main;
5724
5725   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5726
5727   vam->retval = ntohl (mp->retval);
5728   vam->result_ready = 1;
5729
5730 }
5731
5732 static void vl_api_sw_interface_get_table_reply_t_handler_json
5733   (vl_api_sw_interface_get_table_reply_t * mp)
5734 {
5735   vat_main_t *vam = &vat_main;
5736   vat_json_node_t node;
5737
5738   vat_json_init_object (&node);
5739   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5740   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5741
5742   vat_json_print (vam->ofp, &node);
5743   vat_json_free (&node);
5744
5745   vam->retval = ntohl (mp->retval);
5746   vam->result_ready = 1;
5747 }
5748
5749 static int
5750 api_sw_interface_get_table (vat_main_t * vam)
5751 {
5752   unformat_input_t *i = vam->input;
5753   vl_api_sw_interface_get_table_t *mp;
5754   u32 sw_if_index;
5755   u8 sw_if_index_set = 0;
5756   u8 is_ipv6 = 0;
5757   int ret;
5758
5759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5760     {
5761       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5762         sw_if_index_set = 1;
5763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5764         sw_if_index_set = 1;
5765       else if (unformat (i, "ipv6"))
5766         is_ipv6 = 1;
5767       else
5768         break;
5769     }
5770
5771   if (sw_if_index_set == 0)
5772     {
5773       errmsg ("missing interface name or sw_if_index");
5774       return -99;
5775     }
5776
5777   M (SW_INTERFACE_GET_TABLE, mp);
5778   mp->sw_if_index = htonl (sw_if_index);
5779   mp->is_ipv6 = is_ipv6;
5780
5781   S (mp);
5782   W (ret);
5783   return ret;
5784 }
5785
5786 static int
5787 api_sw_interface_set_vpath (vat_main_t * vam)
5788 {
5789   unformat_input_t *i = vam->input;
5790   vl_api_sw_interface_set_vpath_t *mp;
5791   u32 sw_if_index = 0;
5792   u8 sw_if_index_set = 0;
5793   u8 is_enable = 0;
5794   int ret;
5795
5796   /* Parse args required to build the message */
5797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5798     {
5799       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5800         sw_if_index_set = 1;
5801       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5802         sw_if_index_set = 1;
5803       else if (unformat (i, "enable"))
5804         is_enable = 1;
5805       else if (unformat (i, "disable"))
5806         is_enable = 0;
5807       else
5808         break;
5809     }
5810
5811   if (sw_if_index_set == 0)
5812     {
5813       errmsg ("missing interface name or sw_if_index");
5814       return -99;
5815     }
5816
5817   /* Construct the API message */
5818   M (SW_INTERFACE_SET_VPATH, mp);
5819
5820   mp->sw_if_index = ntohl (sw_if_index);
5821   mp->enable = is_enable;
5822
5823   /* send it... */
5824   S (mp);
5825
5826   /* Wait for a reply... */
5827   W (ret);
5828   return ret;
5829 }
5830
5831 static int
5832 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5833 {
5834   unformat_input_t *i = vam->input;
5835   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5836   u32 sw_if_index = 0;
5837   u8 sw_if_index_set = 0;
5838   u8 is_enable = 1;
5839   u8 is_ipv6 = 0;
5840   int ret;
5841
5842   /* Parse args required to build the message */
5843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5844     {
5845       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5846         sw_if_index_set = 1;
5847       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5848         sw_if_index_set = 1;
5849       else if (unformat (i, "enable"))
5850         is_enable = 1;
5851       else if (unformat (i, "disable"))
5852         is_enable = 0;
5853       else if (unformat (i, "ip4"))
5854         is_ipv6 = 0;
5855       else if (unformat (i, "ip6"))
5856         is_ipv6 = 1;
5857       else
5858         break;
5859     }
5860
5861   if (sw_if_index_set == 0)
5862     {
5863       errmsg ("missing interface name or sw_if_index");
5864       return -99;
5865     }
5866
5867   /* Construct the API message */
5868   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5869
5870   mp->sw_if_index = ntohl (sw_if_index);
5871   mp->enable = is_enable;
5872   mp->is_ipv6 = is_ipv6;
5873
5874   /* send it... */
5875   S (mp);
5876
5877   /* Wait for a reply... */
5878   W (ret);
5879   return ret;
5880 }
5881
5882 static int
5883 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5884 {
5885   unformat_input_t *i = vam->input;
5886   vl_api_sw_interface_set_l2_xconnect_t *mp;
5887   u32 rx_sw_if_index;
5888   u8 rx_sw_if_index_set = 0;
5889   u32 tx_sw_if_index;
5890   u8 tx_sw_if_index_set = 0;
5891   u8 enable = 1;
5892   int ret;
5893
5894   /* Parse args required to build the message */
5895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896     {
5897       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5898         rx_sw_if_index_set = 1;
5899       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5900         tx_sw_if_index_set = 1;
5901       else if (unformat (i, "rx"))
5902         {
5903           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5904             {
5905               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5906                             &rx_sw_if_index))
5907                 rx_sw_if_index_set = 1;
5908             }
5909           else
5910             break;
5911         }
5912       else if (unformat (i, "tx"))
5913         {
5914           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5915             {
5916               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5917                             &tx_sw_if_index))
5918                 tx_sw_if_index_set = 1;
5919             }
5920           else
5921             break;
5922         }
5923       else if (unformat (i, "enable"))
5924         enable = 1;
5925       else if (unformat (i, "disable"))
5926         enable = 0;
5927       else
5928         break;
5929     }
5930
5931   if (rx_sw_if_index_set == 0)
5932     {
5933       errmsg ("missing rx interface name or rx_sw_if_index");
5934       return -99;
5935     }
5936
5937   if (enable && (tx_sw_if_index_set == 0))
5938     {
5939       errmsg ("missing tx interface name or tx_sw_if_index");
5940       return -99;
5941     }
5942
5943   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5944
5945   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5946   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5947   mp->enable = enable;
5948
5949   S (mp);
5950   W (ret);
5951   return ret;
5952 }
5953
5954 static int
5955 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5956 {
5957   unformat_input_t *i = vam->input;
5958   vl_api_sw_interface_set_l2_bridge_t *mp;
5959   u32 rx_sw_if_index;
5960   u8 rx_sw_if_index_set = 0;
5961   u32 bd_id;
5962   u8 bd_id_set = 0;
5963   u8 bvi = 0;
5964   u32 shg = 0;
5965   u8 enable = 1;
5966   int ret;
5967
5968   /* Parse args required to build the message */
5969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5970     {
5971       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5972         rx_sw_if_index_set = 1;
5973       else if (unformat (i, "bd_id %d", &bd_id))
5974         bd_id_set = 1;
5975       else
5976         if (unformat
5977             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5978         rx_sw_if_index_set = 1;
5979       else if (unformat (i, "shg %d", &shg))
5980         ;
5981       else if (unformat (i, "bvi"))
5982         bvi = 1;
5983       else if (unformat (i, "enable"))
5984         enable = 1;
5985       else if (unformat (i, "disable"))
5986         enable = 0;
5987       else
5988         break;
5989     }
5990
5991   if (rx_sw_if_index_set == 0)
5992     {
5993       errmsg ("missing rx interface name or sw_if_index");
5994       return -99;
5995     }
5996
5997   if (enable && (bd_id_set == 0))
5998     {
5999       errmsg ("missing bridge domain");
6000       return -99;
6001     }
6002
6003   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6004
6005   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6006   mp->bd_id = ntohl (bd_id);
6007   mp->shg = (u8) shg;
6008   mp->bvi = bvi;
6009   mp->enable = enable;
6010
6011   S (mp);
6012   W (ret);
6013   return ret;
6014 }
6015
6016 static int
6017 api_bridge_domain_dump (vat_main_t * vam)
6018 {
6019   unformat_input_t *i = vam->input;
6020   vl_api_bridge_domain_dump_t *mp;
6021   vl_api_control_ping_t *mp_ping;
6022   u32 bd_id = ~0;
6023   int ret;
6024
6025   /* Parse args required to build the message */
6026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6027     {
6028       if (unformat (i, "bd_id %d", &bd_id))
6029         ;
6030       else
6031         break;
6032     }
6033
6034   M (BRIDGE_DOMAIN_DUMP, mp);
6035   mp->bd_id = ntohl (bd_id);
6036   S (mp);
6037
6038   /* Use a control ping for synchronization */
6039   M (CONTROL_PING, mp_ping);
6040   S (mp_ping);
6041
6042   W (ret);
6043   return ret;
6044 }
6045
6046 static int
6047 api_bridge_domain_add_del (vat_main_t * vam)
6048 {
6049   unformat_input_t *i = vam->input;
6050   vl_api_bridge_domain_add_del_t *mp;
6051   u32 bd_id = ~0;
6052   u8 is_add = 1;
6053   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6054   u32 mac_age = 0;
6055   int ret;
6056
6057   /* Parse args required to build the message */
6058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6059     {
6060       if (unformat (i, "bd_id %d", &bd_id))
6061         ;
6062       else if (unformat (i, "flood %d", &flood))
6063         ;
6064       else if (unformat (i, "uu-flood %d", &uu_flood))
6065         ;
6066       else if (unformat (i, "forward %d", &forward))
6067         ;
6068       else if (unformat (i, "learn %d", &learn))
6069         ;
6070       else if (unformat (i, "arp-term %d", &arp_term))
6071         ;
6072       else if (unformat (i, "mac-age %d", &mac_age))
6073         ;
6074       else if (unformat (i, "del"))
6075         {
6076           is_add = 0;
6077           flood = uu_flood = forward = learn = 0;
6078         }
6079       else
6080         break;
6081     }
6082
6083   if (bd_id == ~0)
6084     {
6085       errmsg ("missing bridge domain");
6086       return -99;
6087     }
6088
6089   if (mac_age > 255)
6090     {
6091       errmsg ("mac age must be less than 256 ");
6092       return -99;
6093     }
6094
6095   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6096
6097   mp->bd_id = ntohl (bd_id);
6098   mp->flood = flood;
6099   mp->uu_flood = uu_flood;
6100   mp->forward = forward;
6101   mp->learn = learn;
6102   mp->arp_term = arp_term;
6103   mp->is_add = is_add;
6104   mp->mac_age = (u8) mac_age;
6105
6106   S (mp);
6107   W (ret);
6108   return ret;
6109 }
6110
6111 static int
6112 api_l2fib_flush_bd (vat_main_t * vam)
6113 {
6114   unformat_input_t *i = vam->input;
6115   vl_api_l2fib_flush_bd_t *mp;
6116   u32 bd_id = ~0;
6117   int ret;
6118
6119   /* Parse args required to build the message */
6120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6121     {
6122       if (unformat (i, "bd_id %d", &bd_id));
6123       else
6124         break;
6125     }
6126
6127   if (bd_id == ~0)
6128     {
6129       errmsg ("missing bridge domain");
6130       return -99;
6131     }
6132
6133   M (L2FIB_FLUSH_BD, mp);
6134
6135   mp->bd_id = htonl (bd_id);
6136
6137   S (mp);
6138   W (ret);
6139   return ret;
6140 }
6141
6142 static int
6143 api_l2fib_flush_int (vat_main_t * vam)
6144 {
6145   unformat_input_t *i = vam->input;
6146   vl_api_l2fib_flush_int_t *mp;
6147   u32 sw_if_index = ~0;
6148   int ret;
6149
6150   /* Parse args required to build the message */
6151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6152     {
6153       if (unformat (i, "sw_if_index %d", &sw_if_index));
6154       else
6155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6156       else
6157         break;
6158     }
6159
6160   if (sw_if_index == ~0)
6161     {
6162       errmsg ("missing interface name or sw_if_index");
6163       return -99;
6164     }
6165
6166   M (L2FIB_FLUSH_INT, mp);
6167
6168   mp->sw_if_index = ntohl (sw_if_index);
6169
6170   S (mp);
6171   W (ret);
6172   return ret;
6173 }
6174
6175 static int
6176 api_l2fib_add_del (vat_main_t * vam)
6177 {
6178   unformat_input_t *i = vam->input;
6179   vl_api_l2fib_add_del_t *mp;
6180   f64 timeout;
6181   u64 mac = 0;
6182   u8 mac_set = 0;
6183   u32 bd_id;
6184   u8 bd_id_set = 0;
6185   u32 sw_if_index = ~0;
6186   u8 sw_if_index_set = 0;
6187   u8 is_add = 1;
6188   u8 static_mac = 0;
6189   u8 filter_mac = 0;
6190   u8 bvi_mac = 0;
6191   int count = 1;
6192   f64 before = 0;
6193   int j;
6194
6195   /* Parse args required to build the message */
6196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6197     {
6198       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6199         mac_set = 1;
6200       else if (unformat (i, "bd_id %d", &bd_id))
6201         bd_id_set = 1;
6202       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6203         sw_if_index_set = 1;
6204       else if (unformat (i, "sw_if"))
6205         {
6206           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6207             {
6208               if (unformat
6209                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6210                 sw_if_index_set = 1;
6211             }
6212           else
6213             break;
6214         }
6215       else if (unformat (i, "static"))
6216         static_mac = 1;
6217       else if (unformat (i, "filter"))
6218         {
6219           filter_mac = 1;
6220           static_mac = 1;
6221         }
6222       else if (unformat (i, "bvi"))
6223         {
6224           bvi_mac = 1;
6225           static_mac = 1;
6226         }
6227       else if (unformat (i, "del"))
6228         is_add = 0;
6229       else if (unformat (i, "count %d", &count))
6230         ;
6231       else
6232         break;
6233     }
6234
6235   if (mac_set == 0)
6236     {
6237       errmsg ("missing mac address");
6238       return -99;
6239     }
6240
6241   if (bd_id_set == 0)
6242     {
6243       errmsg ("missing bridge domain");
6244       return -99;
6245     }
6246
6247   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6248     {
6249       errmsg ("missing interface name or sw_if_index");
6250       return -99;
6251     }
6252
6253   if (count > 1)
6254     {
6255       /* Turn on async mode */
6256       vam->async_mode = 1;
6257       vam->async_errors = 0;
6258       before = vat_time_now (vam);
6259     }
6260
6261   for (j = 0; j < count; j++)
6262     {
6263       M (L2FIB_ADD_DEL, mp);
6264
6265       mp->mac = mac;
6266       mp->bd_id = ntohl (bd_id);
6267       mp->is_add = is_add;
6268
6269       if (is_add)
6270         {
6271           mp->sw_if_index = ntohl (sw_if_index);
6272           mp->static_mac = static_mac;
6273           mp->filter_mac = filter_mac;
6274           mp->bvi_mac = bvi_mac;
6275         }
6276       increment_mac_address (&mac);
6277       /* send it... */
6278       S (mp);
6279     }
6280
6281   if (count > 1)
6282     {
6283       vl_api_control_ping_t *mp_ping;
6284       f64 after;
6285
6286       /* Shut off async mode */
6287       vam->async_mode = 0;
6288
6289       M (CONTROL_PING, mp_ping);
6290       S (mp_ping);
6291
6292       timeout = vat_time_now (vam) + 1.0;
6293       while (vat_time_now (vam) < timeout)
6294         if (vam->result_ready == 1)
6295           goto out;
6296       vam->retval = -99;
6297
6298     out:
6299       if (vam->retval == -99)
6300         errmsg ("timeout");
6301
6302       if (vam->async_errors > 0)
6303         {
6304           errmsg ("%d asynchronous errors", vam->async_errors);
6305           vam->retval = -98;
6306         }
6307       vam->async_errors = 0;
6308       after = vat_time_now (vam);
6309
6310       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6311              count, after - before, count / (after - before));
6312     }
6313   else
6314     {
6315       int ret;
6316
6317       /* Wait for a reply... */
6318       W (ret);
6319       return ret;
6320     }
6321   /* Return the good/bad news */
6322   return (vam->retval);
6323 }
6324
6325 static int
6326 api_bridge_domain_set_mac_age (vat_main_t * vam)
6327 {
6328   unformat_input_t *i = vam->input;
6329   vl_api_bridge_domain_set_mac_age_t *mp;
6330   u32 bd_id = ~0;
6331   u32 mac_age = 0;
6332   int ret;
6333
6334   /* Parse args required to build the message */
6335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6336     {
6337       if (unformat (i, "bd_id %d", &bd_id));
6338       else if (unformat (i, "mac-age %d", &mac_age));
6339       else
6340         break;
6341     }
6342
6343   if (bd_id == ~0)
6344     {
6345       errmsg ("missing bridge domain");
6346       return -99;
6347     }
6348
6349   if (mac_age > 255)
6350     {
6351       errmsg ("mac age must be less than 256 ");
6352       return -99;
6353     }
6354
6355   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6356
6357   mp->bd_id = htonl (bd_id);
6358   mp->mac_age = (u8) mac_age;
6359
6360   S (mp);
6361   W (ret);
6362   return ret;
6363 }
6364
6365 static int
6366 api_l2_flags (vat_main_t * vam)
6367 {
6368   unformat_input_t *i = vam->input;
6369   vl_api_l2_flags_t *mp;
6370   u32 sw_if_index;
6371   u32 feature_bitmap = 0;
6372   u8 sw_if_index_set = 0;
6373   int ret;
6374
6375   /* Parse args required to build the message */
6376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6377     {
6378       if (unformat (i, "sw_if_index %d", &sw_if_index))
6379         sw_if_index_set = 1;
6380       else if (unformat (i, "sw_if"))
6381         {
6382           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6383             {
6384               if (unformat
6385                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6386                 sw_if_index_set = 1;
6387             }
6388           else
6389             break;
6390         }
6391       else if (unformat (i, "learn"))
6392         feature_bitmap |= L2INPUT_FEAT_LEARN;
6393       else if (unformat (i, "forward"))
6394         feature_bitmap |= L2INPUT_FEAT_FWD;
6395       else if (unformat (i, "flood"))
6396         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6397       else if (unformat (i, "uu-flood"))
6398         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6399       else
6400         break;
6401     }
6402
6403   if (sw_if_index_set == 0)
6404     {
6405       errmsg ("missing interface name or sw_if_index");
6406       return -99;
6407     }
6408
6409   M (L2_FLAGS, mp);
6410
6411   mp->sw_if_index = ntohl (sw_if_index);
6412   mp->feature_bitmap = ntohl (feature_bitmap);
6413
6414   S (mp);
6415   W (ret);
6416   return ret;
6417 }
6418
6419 static int
6420 api_bridge_flags (vat_main_t * vam)
6421 {
6422   unformat_input_t *i = vam->input;
6423   vl_api_bridge_flags_t *mp;
6424   u32 bd_id;
6425   u8 bd_id_set = 0;
6426   u8 is_set = 1;
6427   u32 flags = 0;
6428   int ret;
6429
6430   /* Parse args required to build the message */
6431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6432     {
6433       if (unformat (i, "bd_id %d", &bd_id))
6434         bd_id_set = 1;
6435       else if (unformat (i, "learn"))
6436         flags |= L2_LEARN;
6437       else if (unformat (i, "forward"))
6438         flags |= L2_FWD;
6439       else if (unformat (i, "flood"))
6440         flags |= L2_FLOOD;
6441       else if (unformat (i, "uu-flood"))
6442         flags |= L2_UU_FLOOD;
6443       else if (unformat (i, "arp-term"))
6444         flags |= L2_ARP_TERM;
6445       else if (unformat (i, "off"))
6446         is_set = 0;
6447       else if (unformat (i, "disable"))
6448         is_set = 0;
6449       else
6450         break;
6451     }
6452
6453   if (bd_id_set == 0)
6454     {
6455       errmsg ("missing bridge domain");
6456       return -99;
6457     }
6458
6459   M (BRIDGE_FLAGS, mp);
6460
6461   mp->bd_id = ntohl (bd_id);
6462   mp->feature_bitmap = ntohl (flags);
6463   mp->is_set = is_set;
6464
6465   S (mp);
6466   W (ret);
6467   return ret;
6468 }
6469
6470 static int
6471 api_bd_ip_mac_add_del (vat_main_t * vam)
6472 {
6473   unformat_input_t *i = vam->input;
6474   vl_api_bd_ip_mac_add_del_t *mp;
6475   u32 bd_id;
6476   u8 is_ipv6 = 0;
6477   u8 is_add = 1;
6478   u8 bd_id_set = 0;
6479   u8 ip_set = 0;
6480   u8 mac_set = 0;
6481   ip4_address_t v4addr;
6482   ip6_address_t v6addr;
6483   u8 macaddr[6];
6484   int ret;
6485
6486
6487   /* Parse args required to build the message */
6488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6489     {
6490       if (unformat (i, "bd_id %d", &bd_id))
6491         {
6492           bd_id_set++;
6493         }
6494       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6495         {
6496           ip_set++;
6497         }
6498       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6499         {
6500           ip_set++;
6501           is_ipv6++;
6502         }
6503       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6504         {
6505           mac_set++;
6506         }
6507       else if (unformat (i, "del"))
6508         is_add = 0;
6509       else
6510         break;
6511     }
6512
6513   if (bd_id_set == 0)
6514     {
6515       errmsg ("missing bridge domain");
6516       return -99;
6517     }
6518   else if (ip_set == 0)
6519     {
6520       errmsg ("missing IP address");
6521       return -99;
6522     }
6523   else if (mac_set == 0)
6524     {
6525       errmsg ("missing MAC address");
6526       return -99;
6527     }
6528
6529   M (BD_IP_MAC_ADD_DEL, mp);
6530
6531   mp->bd_id = ntohl (bd_id);
6532   mp->is_ipv6 = is_ipv6;
6533   mp->is_add = is_add;
6534   if (is_ipv6)
6535     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6536   else
6537     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6538   clib_memcpy (mp->mac_address, macaddr, 6);
6539   S (mp);
6540   W (ret);
6541   return ret;
6542 }
6543
6544 static int
6545 api_tap_connect (vat_main_t * vam)
6546 {
6547   unformat_input_t *i = vam->input;
6548   vl_api_tap_connect_t *mp;
6549   u8 mac_address[6];
6550   u8 random_mac = 1;
6551   u8 name_set = 0;
6552   u8 *tap_name;
6553   u8 *tag = 0;
6554   ip4_address_t ip4_address;
6555   u32 ip4_mask_width;
6556   int ip4_address_set = 0;
6557   ip6_address_t ip6_address;
6558   u32 ip6_mask_width;
6559   int ip6_address_set = 0;
6560   int ret;
6561
6562   memset (mac_address, 0, sizeof (mac_address));
6563
6564   /* Parse args required to build the message */
6565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6566     {
6567       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6568         {
6569           random_mac = 0;
6570         }
6571       else if (unformat (i, "random-mac"))
6572         random_mac = 1;
6573       else if (unformat (i, "tapname %s", &tap_name))
6574         name_set = 1;
6575       else if (unformat (i, "tag %s", &tag))
6576         ;
6577       else if (unformat (i, "address %U/%d",
6578                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6579         ip4_address_set = 1;
6580       else if (unformat (i, "address %U/%d",
6581                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6582         ip6_address_set = 1;
6583       else
6584         break;
6585     }
6586
6587   if (name_set == 0)
6588     {
6589       errmsg ("missing tap name");
6590       return -99;
6591     }
6592   if (vec_len (tap_name) > 63)
6593     {
6594       errmsg ("tap name too long");
6595       return -99;
6596     }
6597   vec_add1 (tap_name, 0);
6598
6599   if (vec_len (tag) > 63)
6600     {
6601       errmsg ("tag too long");
6602       return -99;
6603     }
6604
6605   /* Construct the API message */
6606   M (TAP_CONNECT, mp);
6607
6608   mp->use_random_mac = random_mac;
6609   clib_memcpy (mp->mac_address, mac_address, 6);
6610   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6611   if (tag)
6612     clib_memcpy (mp->tag, tag, vec_len (tag));
6613
6614   if (ip4_address_set)
6615     {
6616       mp->ip4_address_set = 1;
6617       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6618       mp->ip4_mask_width = ip4_mask_width;
6619     }
6620   if (ip6_address_set)
6621     {
6622       mp->ip6_address_set = 1;
6623       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6624       mp->ip6_mask_width = ip6_mask_width;
6625     }
6626
6627   vec_free (tap_name);
6628   vec_free (tag);
6629
6630   /* send it... */
6631   S (mp);
6632
6633   /* Wait for a reply... */
6634   W (ret);
6635   return ret;
6636 }
6637
6638 static int
6639 api_tap_modify (vat_main_t * vam)
6640 {
6641   unformat_input_t *i = vam->input;
6642   vl_api_tap_modify_t *mp;
6643   u8 mac_address[6];
6644   u8 random_mac = 1;
6645   u8 name_set = 0;
6646   u8 *tap_name;
6647   u32 sw_if_index = ~0;
6648   u8 sw_if_index_set = 0;
6649   int ret;
6650
6651   memset (mac_address, 0, sizeof (mac_address));
6652
6653   /* Parse args required to build the message */
6654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6655     {
6656       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6657         sw_if_index_set = 1;
6658       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6659         sw_if_index_set = 1;
6660       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6661         {
6662           random_mac = 0;
6663         }
6664       else if (unformat (i, "random-mac"))
6665         random_mac = 1;
6666       else if (unformat (i, "tapname %s", &tap_name))
6667         name_set = 1;
6668       else
6669         break;
6670     }
6671
6672   if (sw_if_index_set == 0)
6673     {
6674       errmsg ("missing vpp interface name");
6675       return -99;
6676     }
6677   if (name_set == 0)
6678     {
6679       errmsg ("missing tap name");
6680       return -99;
6681     }
6682   if (vec_len (tap_name) > 63)
6683     {
6684       errmsg ("tap name too long");
6685     }
6686   vec_add1 (tap_name, 0);
6687
6688   /* Construct the API message */
6689   M (TAP_MODIFY, mp);
6690
6691   mp->use_random_mac = random_mac;
6692   mp->sw_if_index = ntohl (sw_if_index);
6693   clib_memcpy (mp->mac_address, mac_address, 6);
6694   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6695   vec_free (tap_name);
6696
6697   /* send it... */
6698   S (mp);
6699
6700   /* Wait for a reply... */
6701   W (ret);
6702   return ret;
6703 }
6704
6705 static int
6706 api_tap_delete (vat_main_t * vam)
6707 {
6708   unformat_input_t *i = vam->input;
6709   vl_api_tap_delete_t *mp;
6710   u32 sw_if_index = ~0;
6711   u8 sw_if_index_set = 0;
6712   int ret;
6713
6714   /* Parse args required to build the message */
6715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6716     {
6717       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6718         sw_if_index_set = 1;
6719       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6720         sw_if_index_set = 1;
6721       else
6722         break;
6723     }
6724
6725   if (sw_if_index_set == 0)
6726     {
6727       errmsg ("missing vpp interface name");
6728       return -99;
6729     }
6730
6731   /* Construct the API message */
6732   M (TAP_DELETE, mp);
6733
6734   mp->sw_if_index = ntohl (sw_if_index);
6735
6736   /* send it... */
6737   S (mp);
6738
6739   /* Wait for a reply... */
6740   W (ret);
6741   return ret;
6742 }
6743
6744 static int
6745 api_ip_add_del_route (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_ip_add_del_route_t *mp;
6749   u32 sw_if_index = ~0, vrf_id = 0;
6750   u8 is_ipv6 = 0;
6751   u8 is_local = 0, is_drop = 0;
6752   u8 is_unreach = 0, is_prohibit = 0;
6753   u8 create_vrf_if_needed = 0;
6754   u8 is_add = 1;
6755   u32 next_hop_weight = 1;
6756   u8 not_last = 0;
6757   u8 is_multipath = 0;
6758   u8 address_set = 0;
6759   u8 address_length_set = 0;
6760   u32 next_hop_table_id = 0;
6761   u32 resolve_attempts = 0;
6762   u32 dst_address_length = 0;
6763   u8 next_hop_set = 0;
6764   ip4_address_t v4_dst_address, v4_next_hop_address;
6765   ip6_address_t v6_dst_address, v6_next_hop_address;
6766   int count = 1;
6767   int j;
6768   f64 before = 0;
6769   u32 random_add_del = 0;
6770   u32 *random_vector = 0;
6771   uword *random_hash;
6772   u32 random_seed = 0xdeaddabe;
6773   u32 classify_table_index = ~0;
6774   u8 is_classify = 0;
6775   u8 resolve_host = 0, resolve_attached = 0;
6776   mpls_label_t *next_hop_out_label_stack = NULL;
6777   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6778   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6779
6780   /* Parse args required to build the message */
6781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6782     {
6783       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6784         ;
6785       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6786         ;
6787       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6788         {
6789           address_set = 1;
6790           is_ipv6 = 0;
6791         }
6792       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6793         {
6794           address_set = 1;
6795           is_ipv6 = 1;
6796         }
6797       else if (unformat (i, "/%d", &dst_address_length))
6798         {
6799           address_length_set = 1;
6800         }
6801
6802       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6803                                          &v4_next_hop_address))
6804         {
6805           next_hop_set = 1;
6806         }
6807       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6808                                          &v6_next_hop_address))
6809         {
6810           next_hop_set = 1;
6811         }
6812       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6813         ;
6814       else if (unformat (i, "weight %d", &next_hop_weight))
6815         ;
6816       else if (unformat (i, "drop"))
6817         {
6818           is_drop = 1;
6819         }
6820       else if (unformat (i, "null-send-unreach"))
6821         {
6822           is_unreach = 1;
6823         }
6824       else if (unformat (i, "null-send-prohibit"))
6825         {
6826           is_prohibit = 1;
6827         }
6828       else if (unformat (i, "local"))
6829         {
6830           is_local = 1;
6831         }
6832       else if (unformat (i, "classify %d", &classify_table_index))
6833         {
6834           is_classify = 1;
6835         }
6836       else if (unformat (i, "del"))
6837         is_add = 0;
6838       else if (unformat (i, "add"))
6839         is_add = 1;
6840       else if (unformat (i, "not-last"))
6841         not_last = 1;
6842       else if (unformat (i, "resolve-via-host"))
6843         resolve_host = 1;
6844       else if (unformat (i, "resolve-via-attached"))
6845         resolve_attached = 1;
6846       else if (unformat (i, "multipath"))
6847         is_multipath = 1;
6848       else if (unformat (i, "vrf %d", &vrf_id))
6849         ;
6850       else if (unformat (i, "create-vrf"))
6851         create_vrf_if_needed = 1;
6852       else if (unformat (i, "count %d", &count))
6853         ;
6854       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6855         ;
6856       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6857         ;
6858       else if (unformat (i, "out-label %d", &next_hop_out_label))
6859         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6860       else if (unformat (i, "via-label %d", &next_hop_via_label))
6861         ;
6862       else if (unformat (i, "random"))
6863         random_add_del = 1;
6864       else if (unformat (i, "seed %d", &random_seed))
6865         ;
6866       else
6867         {
6868           clib_warning ("parse error '%U'", format_unformat_error, i);
6869           return -99;
6870         }
6871     }
6872
6873   if (!next_hop_set && !is_drop && !is_local &&
6874       !is_classify && !is_unreach && !is_prohibit &&
6875       MPLS_LABEL_INVALID == next_hop_via_label)
6876     {
6877       errmsg
6878         ("next hop / local / drop / unreach / prohibit / classify not set");
6879       return -99;
6880     }
6881
6882   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6883     {
6884       errmsg ("next hop and next-hop via label set");
6885       return -99;
6886     }
6887   if (address_set == 0)
6888     {
6889       errmsg ("missing addresses");
6890       return -99;
6891     }
6892
6893   if (address_length_set == 0)
6894     {
6895       errmsg ("missing address length");
6896       return -99;
6897     }
6898
6899   /* Generate a pile of unique, random routes */
6900   if (random_add_del)
6901     {
6902       u32 this_random_address;
6903       random_hash = hash_create (count, sizeof (uword));
6904
6905       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6906       for (j = 0; j <= count; j++)
6907         {
6908           do
6909             {
6910               this_random_address = random_u32 (&random_seed);
6911               this_random_address =
6912                 clib_host_to_net_u32 (this_random_address);
6913             }
6914           while (hash_get (random_hash, this_random_address));
6915           vec_add1 (random_vector, this_random_address);
6916           hash_set (random_hash, this_random_address, 1);
6917         }
6918       hash_free (random_hash);
6919       v4_dst_address.as_u32 = random_vector[0];
6920     }
6921
6922   if (count > 1)
6923     {
6924       /* Turn on async mode */
6925       vam->async_mode = 1;
6926       vam->async_errors = 0;
6927       before = vat_time_now (vam);
6928     }
6929
6930   for (j = 0; j < count; j++)
6931     {
6932       /* Construct the API message */
6933       M2 (IP_ADD_DEL_ROUTE, mp,
6934           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6935
6936       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6937       mp->table_id = ntohl (vrf_id);
6938       mp->create_vrf_if_needed = create_vrf_if_needed;
6939
6940       mp->is_add = is_add;
6941       mp->is_drop = is_drop;
6942       mp->is_unreach = is_unreach;
6943       mp->is_prohibit = is_prohibit;
6944       mp->is_ipv6 = is_ipv6;
6945       mp->is_local = is_local;
6946       mp->is_classify = is_classify;
6947       mp->is_multipath = is_multipath;
6948       mp->is_resolve_host = resolve_host;
6949       mp->is_resolve_attached = resolve_attached;
6950       mp->not_last = not_last;
6951       mp->next_hop_weight = next_hop_weight;
6952       mp->dst_address_length = dst_address_length;
6953       mp->next_hop_table_id = ntohl (next_hop_table_id);
6954       mp->classify_table_index = ntohl (classify_table_index);
6955       mp->next_hop_via_label = ntohl (next_hop_via_label);
6956       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6957       if (0 != mp->next_hop_n_out_labels)
6958         {
6959           memcpy (mp->next_hop_out_label_stack,
6960                   next_hop_out_label_stack,
6961                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6962           vec_free (next_hop_out_label_stack);
6963         }
6964
6965       if (is_ipv6)
6966         {
6967           clib_memcpy (mp->dst_address, &v6_dst_address,
6968                        sizeof (v6_dst_address));
6969           if (next_hop_set)
6970             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6971                          sizeof (v6_next_hop_address));
6972           increment_v6_address (&v6_dst_address);
6973         }
6974       else
6975         {
6976           clib_memcpy (mp->dst_address, &v4_dst_address,
6977                        sizeof (v4_dst_address));
6978           if (next_hop_set)
6979             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6980                          sizeof (v4_next_hop_address));
6981           if (random_add_del)
6982             v4_dst_address.as_u32 = random_vector[j + 1];
6983           else
6984             increment_v4_address (&v4_dst_address);
6985         }
6986       /* send it... */
6987       S (mp);
6988       /* If we receive SIGTERM, stop now... */
6989       if (vam->do_exit)
6990         break;
6991     }
6992
6993   /* When testing multiple add/del ops, use a control-ping to sync */
6994   if (count > 1)
6995     {
6996       vl_api_control_ping_t *mp_ping;
6997       f64 after;
6998       f64 timeout;
6999
7000       /* Shut off async mode */
7001       vam->async_mode = 0;
7002
7003       M (CONTROL_PING, mp_ping);
7004       S (mp_ping);
7005
7006       timeout = vat_time_now (vam) + 1.0;
7007       while (vat_time_now (vam) < timeout)
7008         if (vam->result_ready == 1)
7009           goto out;
7010       vam->retval = -99;
7011
7012     out:
7013       if (vam->retval == -99)
7014         errmsg ("timeout");
7015
7016       if (vam->async_errors > 0)
7017         {
7018           errmsg ("%d asynchronous errors", vam->async_errors);
7019           vam->retval = -98;
7020         }
7021       vam->async_errors = 0;
7022       after = vat_time_now (vam);
7023
7024       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7025       if (j > 0)
7026         count = j;
7027
7028       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7029              count, after - before, count / (after - before));
7030     }
7031   else
7032     {
7033       int ret;
7034
7035       /* Wait for a reply... */
7036       W (ret);
7037       return ret;
7038     }
7039
7040   /* Return the good/bad news */
7041   return (vam->retval);
7042 }
7043
7044 static int
7045 api_ip_mroute_add_del (vat_main_t * vam)
7046 {
7047   unformat_input_t *i = vam->input;
7048   vl_api_ip_mroute_add_del_t *mp;
7049   u32 sw_if_index = ~0, vrf_id = 0;
7050   u8 is_ipv6 = 0;
7051   u8 is_local = 0;
7052   u8 create_vrf_if_needed = 0;
7053   u8 is_add = 1;
7054   u8 address_set = 0;
7055   u32 grp_address_length = 0;
7056   ip4_address_t v4_grp_address, v4_src_address;
7057   ip6_address_t v6_grp_address, v6_src_address;
7058   mfib_itf_flags_t iflags = 0;
7059   mfib_entry_flags_t eflags = 0;
7060   int ret;
7061
7062   /* Parse args required to build the message */
7063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7064     {
7065       if (unformat (i, "sw_if_index %d", &sw_if_index))
7066         ;
7067       else if (unformat (i, "%U %U",
7068                          unformat_ip4_address, &v4_src_address,
7069                          unformat_ip4_address, &v4_grp_address))
7070         {
7071           grp_address_length = 64;
7072           address_set = 1;
7073           is_ipv6 = 0;
7074         }
7075       else if (unformat (i, "%U %U",
7076                          unformat_ip6_address, &v6_src_address,
7077                          unformat_ip6_address, &v6_grp_address))
7078         {
7079           grp_address_length = 256;
7080           address_set = 1;
7081           is_ipv6 = 1;
7082         }
7083       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7084         {
7085           memset (&v4_src_address, 0, sizeof (v4_src_address));
7086           grp_address_length = 32;
7087           address_set = 1;
7088           is_ipv6 = 0;
7089         }
7090       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7091         {
7092           memset (&v6_src_address, 0, sizeof (v6_src_address));
7093           grp_address_length = 128;
7094           address_set = 1;
7095           is_ipv6 = 1;
7096         }
7097       else if (unformat (i, "/%d", &grp_address_length))
7098         ;
7099       else if (unformat (i, "local"))
7100         {
7101           is_local = 1;
7102         }
7103       else if (unformat (i, "del"))
7104         is_add = 0;
7105       else if (unformat (i, "add"))
7106         is_add = 1;
7107       else if (unformat (i, "vrf %d", &vrf_id))
7108         ;
7109       else if (unformat (i, "create-vrf"))
7110         create_vrf_if_needed = 1;
7111       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7112         ;
7113       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7114         ;
7115       else
7116         {
7117           clib_warning ("parse error '%U'", format_unformat_error, i);
7118           return -99;
7119         }
7120     }
7121
7122   if (address_set == 0)
7123     {
7124       errmsg ("missing addresses\n");
7125       return -99;
7126     }
7127
7128   /* Construct the API message */
7129   M (IP_MROUTE_ADD_DEL, mp);
7130
7131   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7132   mp->table_id = ntohl (vrf_id);
7133   mp->create_vrf_if_needed = create_vrf_if_needed;
7134
7135   mp->is_add = is_add;
7136   mp->is_ipv6 = is_ipv6;
7137   mp->is_local = is_local;
7138   mp->itf_flags = ntohl (iflags);
7139   mp->entry_flags = ntohl (eflags);
7140   mp->grp_address_length = grp_address_length;
7141   mp->grp_address_length = ntohs (mp->grp_address_length);
7142
7143   if (is_ipv6)
7144     {
7145       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7146       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7147     }
7148   else
7149     {
7150       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7151       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7152
7153     }
7154
7155   /* send it... */
7156   S (mp);
7157   /* Wait for a reply... */
7158   W (ret);
7159   return ret;
7160 }
7161
7162 static int
7163 api_mpls_route_add_del (vat_main_t * vam)
7164 {
7165   unformat_input_t *i = vam->input;
7166   vl_api_mpls_route_add_del_t *mp;
7167   u32 sw_if_index = ~0, table_id = 0;
7168   u8 create_table_if_needed = 0;
7169   u8 is_add = 1;
7170   u32 next_hop_weight = 1;
7171   u8 is_multipath = 0;
7172   u32 next_hop_table_id = 0;
7173   u8 next_hop_set = 0;
7174   ip4_address_t v4_next_hop_address = {
7175     .as_u32 = 0,
7176   };
7177   ip6_address_t v6_next_hop_address = { {0} };
7178   int count = 1;
7179   int j;
7180   f64 before = 0;
7181   u32 classify_table_index = ~0;
7182   u8 is_classify = 0;
7183   u8 resolve_host = 0, resolve_attached = 0;
7184   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7185   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7186   mpls_label_t *next_hop_out_label_stack = NULL;
7187   mpls_label_t local_label = MPLS_LABEL_INVALID;
7188   u8 is_eos = 0;
7189   u8 next_hop_proto_is_ip4 = 1;
7190
7191   /* Parse args required to build the message */
7192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7193     {
7194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7195         ;
7196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7197         ;
7198       else if (unformat (i, "%d", &local_label))
7199         ;
7200       else if (unformat (i, "eos"))
7201         is_eos = 1;
7202       else if (unformat (i, "non-eos"))
7203         is_eos = 0;
7204       else if (unformat (i, "via %U", unformat_ip4_address,
7205                          &v4_next_hop_address))
7206         {
7207           next_hop_set = 1;
7208           next_hop_proto_is_ip4 = 1;
7209         }
7210       else if (unformat (i, "via %U", unformat_ip6_address,
7211                          &v6_next_hop_address))
7212         {
7213           next_hop_set = 1;
7214           next_hop_proto_is_ip4 = 0;
7215         }
7216       else if (unformat (i, "weight %d", &next_hop_weight))
7217         ;
7218       else if (unformat (i, "create-table"))
7219         create_table_if_needed = 1;
7220       else if (unformat (i, "classify %d", &classify_table_index))
7221         {
7222           is_classify = 1;
7223         }
7224       else if (unformat (i, "del"))
7225         is_add = 0;
7226       else if (unformat (i, "add"))
7227         is_add = 1;
7228       else if (unformat (i, "resolve-via-host"))
7229         resolve_host = 1;
7230       else if (unformat (i, "resolve-via-attached"))
7231         resolve_attached = 1;
7232       else if (unformat (i, "multipath"))
7233         is_multipath = 1;
7234       else if (unformat (i, "count %d", &count))
7235         ;
7236       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7237         {
7238           next_hop_set = 1;
7239           next_hop_proto_is_ip4 = 1;
7240         }
7241       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7242         {
7243           next_hop_set = 1;
7244           next_hop_proto_is_ip4 = 0;
7245         }
7246       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7247         ;
7248       else if (unformat (i, "via-label %d", &next_hop_via_label))
7249         ;
7250       else if (unformat (i, "out-label %d", &next_hop_out_label))
7251         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7252       else
7253         {
7254           clib_warning ("parse error '%U'", format_unformat_error, i);
7255           return -99;
7256         }
7257     }
7258
7259   if (!next_hop_set && !is_classify)
7260     {
7261       errmsg ("next hop / classify not set");
7262       return -99;
7263     }
7264
7265   if (MPLS_LABEL_INVALID == local_label)
7266     {
7267       errmsg ("missing label");
7268       return -99;
7269     }
7270
7271   if (count > 1)
7272     {
7273       /* Turn on async mode */
7274       vam->async_mode = 1;
7275       vam->async_errors = 0;
7276       before = vat_time_now (vam);
7277     }
7278
7279   for (j = 0; j < count; j++)
7280     {
7281       /* Construct the API message */
7282       M2 (MPLS_ROUTE_ADD_DEL, mp,
7283           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7284
7285       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7286       mp->mr_table_id = ntohl (table_id);
7287       mp->mr_create_table_if_needed = create_table_if_needed;
7288
7289       mp->mr_is_add = is_add;
7290       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7291       mp->mr_is_classify = is_classify;
7292       mp->mr_is_multipath = is_multipath;
7293       mp->mr_is_resolve_host = resolve_host;
7294       mp->mr_is_resolve_attached = resolve_attached;
7295       mp->mr_next_hop_weight = next_hop_weight;
7296       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7297       mp->mr_classify_table_index = ntohl (classify_table_index);
7298       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7299       mp->mr_label = ntohl (local_label);
7300       mp->mr_eos = is_eos;
7301
7302       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7303       if (0 != mp->mr_next_hop_n_out_labels)
7304         {
7305           memcpy (mp->mr_next_hop_out_label_stack,
7306                   next_hop_out_label_stack,
7307                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7308           vec_free (next_hop_out_label_stack);
7309         }
7310
7311       if (next_hop_set)
7312         {
7313           if (next_hop_proto_is_ip4)
7314             {
7315               clib_memcpy (mp->mr_next_hop,
7316                            &v4_next_hop_address,
7317                            sizeof (v4_next_hop_address));
7318             }
7319           else
7320             {
7321               clib_memcpy (mp->mr_next_hop,
7322                            &v6_next_hop_address,
7323                            sizeof (v6_next_hop_address));
7324             }
7325         }
7326       local_label++;
7327
7328       /* send it... */
7329       S (mp);
7330       /* If we receive SIGTERM, stop now... */
7331       if (vam->do_exit)
7332         break;
7333     }
7334
7335   /* When testing multiple add/del ops, use a control-ping to sync */
7336   if (count > 1)
7337     {
7338       vl_api_control_ping_t *mp_ping;
7339       f64 after;
7340       f64 timeout;
7341
7342       /* Shut off async mode */
7343       vam->async_mode = 0;
7344
7345       M (CONTROL_PING, mp_ping);
7346       S (mp_ping);
7347
7348       timeout = vat_time_now (vam) + 1.0;
7349       while (vat_time_now (vam) < timeout)
7350         if (vam->result_ready == 1)
7351           goto out;
7352       vam->retval = -99;
7353
7354     out:
7355       if (vam->retval == -99)
7356         errmsg ("timeout");
7357
7358       if (vam->async_errors > 0)
7359         {
7360           errmsg ("%d asynchronous errors", vam->async_errors);
7361           vam->retval = -98;
7362         }
7363       vam->async_errors = 0;
7364       after = vat_time_now (vam);
7365
7366       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7367       if (j > 0)
7368         count = j;
7369
7370       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7371              count, after - before, count / (after - before));
7372     }
7373   else
7374     {
7375       int ret;
7376
7377       /* Wait for a reply... */
7378       W (ret);
7379       return ret;
7380     }
7381
7382   /* Return the good/bad news */
7383   return (vam->retval);
7384 }
7385
7386 static int
7387 api_mpls_ip_bind_unbind (vat_main_t * vam)
7388 {
7389   unformat_input_t *i = vam->input;
7390   vl_api_mpls_ip_bind_unbind_t *mp;
7391   u32 ip_table_id = 0;
7392   u8 create_table_if_needed = 0;
7393   u8 is_bind = 1;
7394   u8 is_ip4 = 1;
7395   ip4_address_t v4_address;
7396   ip6_address_t v6_address;
7397   u32 address_length;
7398   u8 address_set = 0;
7399   mpls_label_t local_label = MPLS_LABEL_INVALID;
7400   int ret;
7401
7402   /* Parse args required to build the message */
7403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7404     {
7405       if (unformat (i, "%U/%d", unformat_ip4_address,
7406                     &v4_address, &address_length))
7407         {
7408           is_ip4 = 1;
7409           address_set = 1;
7410         }
7411       else if (unformat (i, "%U/%d", unformat_ip6_address,
7412                          &v6_address, &address_length))
7413         {
7414           is_ip4 = 0;
7415           address_set = 1;
7416         }
7417       else if (unformat (i, "%d", &local_label))
7418         ;
7419       else if (unformat (i, "create-table"))
7420         create_table_if_needed = 1;
7421       else if (unformat (i, "table-id %d", &ip_table_id))
7422         ;
7423       else if (unformat (i, "unbind"))
7424         is_bind = 0;
7425       else if (unformat (i, "bind"))
7426         is_bind = 1;
7427       else
7428         {
7429           clib_warning ("parse error '%U'", format_unformat_error, i);
7430           return -99;
7431         }
7432     }
7433
7434   if (!address_set)
7435     {
7436       errmsg ("IP addres not set");
7437       return -99;
7438     }
7439
7440   if (MPLS_LABEL_INVALID == local_label)
7441     {
7442       errmsg ("missing label");
7443       return -99;
7444     }
7445
7446   /* Construct the API message */
7447   M (MPLS_IP_BIND_UNBIND, mp);
7448
7449   mp->mb_create_table_if_needed = create_table_if_needed;
7450   mp->mb_is_bind = is_bind;
7451   mp->mb_is_ip4 = is_ip4;
7452   mp->mb_ip_table_id = ntohl (ip_table_id);
7453   mp->mb_mpls_table_id = 0;
7454   mp->mb_label = ntohl (local_label);
7455   mp->mb_address_length = address_length;
7456
7457   if (is_ip4)
7458     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7459   else
7460     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7461
7462   /* send it... */
7463   S (mp);
7464
7465   /* Wait for a reply... */
7466   W (ret);
7467   return ret;
7468 }
7469
7470 static int
7471 api_proxy_arp_add_del (vat_main_t * vam)
7472 {
7473   unformat_input_t *i = vam->input;
7474   vl_api_proxy_arp_add_del_t *mp;
7475   u32 vrf_id = 0;
7476   u8 is_add = 1;
7477   ip4_address_t lo, hi;
7478   u8 range_set = 0;
7479   int ret;
7480
7481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7482     {
7483       if (unformat (i, "vrf %d", &vrf_id))
7484         ;
7485       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7486                          unformat_ip4_address, &hi))
7487         range_set = 1;
7488       else if (unformat (i, "del"))
7489         is_add = 0;
7490       else
7491         {
7492           clib_warning ("parse error '%U'", format_unformat_error, i);
7493           return -99;
7494         }
7495     }
7496
7497   if (range_set == 0)
7498     {
7499       errmsg ("address range not set");
7500       return -99;
7501     }
7502
7503   M (PROXY_ARP_ADD_DEL, mp);
7504
7505   mp->vrf_id = ntohl (vrf_id);
7506   mp->is_add = is_add;
7507   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7508   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7509
7510   S (mp);
7511   W (ret);
7512   return ret;
7513 }
7514
7515 static int
7516 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7517 {
7518   unformat_input_t *i = vam->input;
7519   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7520   u32 sw_if_index;
7521   u8 enable = 1;
7522   u8 sw_if_index_set = 0;
7523   int ret;
7524
7525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7526     {
7527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7528         sw_if_index_set = 1;
7529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7530         sw_if_index_set = 1;
7531       else if (unformat (i, "enable"))
7532         enable = 1;
7533       else if (unformat (i, "disable"))
7534         enable = 0;
7535       else
7536         {
7537           clib_warning ("parse error '%U'", format_unformat_error, i);
7538           return -99;
7539         }
7540     }
7541
7542   if (sw_if_index_set == 0)
7543     {
7544       errmsg ("missing interface name or sw_if_index");
7545       return -99;
7546     }
7547
7548   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7549
7550   mp->sw_if_index = ntohl (sw_if_index);
7551   mp->enable_disable = enable;
7552
7553   S (mp);
7554   W (ret);
7555   return ret;
7556 }
7557
7558 static int
7559 api_mpls_tunnel_add_del (vat_main_t * vam)
7560 {
7561   unformat_input_t *i = vam->input;
7562   vl_api_mpls_tunnel_add_del_t *mp;
7563
7564   u8 is_add = 1;
7565   u8 l2_only = 0;
7566   u32 sw_if_index = ~0;
7567   u32 next_hop_sw_if_index = ~0;
7568   u32 next_hop_proto_is_ip4 = 1;
7569
7570   u32 next_hop_table_id = 0;
7571   ip4_address_t v4_next_hop_address = {
7572     .as_u32 = 0,
7573   };
7574   ip6_address_t v6_next_hop_address = { {0} };
7575   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7576   int ret;
7577
7578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7579     {
7580       if (unformat (i, "add"))
7581         is_add = 1;
7582       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7583         is_add = 0;
7584       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7585         ;
7586       else if (unformat (i, "via %U",
7587                          unformat_ip4_address, &v4_next_hop_address))
7588         {
7589           next_hop_proto_is_ip4 = 1;
7590         }
7591       else if (unformat (i, "via %U",
7592                          unformat_ip6_address, &v6_next_hop_address))
7593         {
7594           next_hop_proto_is_ip4 = 0;
7595         }
7596       else if (unformat (i, "l2-only"))
7597         l2_only = 1;
7598       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7599         ;
7600       else if (unformat (i, "out-label %d", &next_hop_out_label))
7601         vec_add1 (labels, ntohl (next_hop_out_label));
7602       else
7603         {
7604           clib_warning ("parse error '%U'", format_unformat_error, i);
7605           return -99;
7606         }
7607     }
7608
7609   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7610
7611   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7612   mp->mt_sw_if_index = ntohl (sw_if_index);
7613   mp->mt_is_add = is_add;
7614   mp->mt_l2_only = l2_only;
7615   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7616   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7617
7618   mp->mt_next_hop_n_out_labels = vec_len (labels);
7619
7620   if (0 != mp->mt_next_hop_n_out_labels)
7621     {
7622       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7623                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7624       vec_free (labels);
7625     }
7626
7627   if (next_hop_proto_is_ip4)
7628     {
7629       clib_memcpy (mp->mt_next_hop,
7630                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7631     }
7632   else
7633     {
7634       clib_memcpy (mp->mt_next_hop,
7635                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7636     }
7637
7638   S (mp);
7639   W (ret);
7640   return ret;
7641 }
7642
7643 static int
7644 api_sw_interface_set_unnumbered (vat_main_t * vam)
7645 {
7646   unformat_input_t *i = vam->input;
7647   vl_api_sw_interface_set_unnumbered_t *mp;
7648   u32 sw_if_index;
7649   u32 unnum_sw_index = ~0;
7650   u8 is_add = 1;
7651   u8 sw_if_index_set = 0;
7652   int ret;
7653
7654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7655     {
7656       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7657         sw_if_index_set = 1;
7658       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7659         sw_if_index_set = 1;
7660       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7661         ;
7662       else if (unformat (i, "del"))
7663         is_add = 0;
7664       else
7665         {
7666           clib_warning ("parse error '%U'", format_unformat_error, i);
7667           return -99;
7668         }
7669     }
7670
7671   if (sw_if_index_set == 0)
7672     {
7673       errmsg ("missing interface name or sw_if_index");
7674       return -99;
7675     }
7676
7677   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7678
7679   mp->sw_if_index = ntohl (sw_if_index);
7680   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7681   mp->is_add = is_add;
7682
7683   S (mp);
7684   W (ret);
7685   return ret;
7686 }
7687
7688 static int
7689 api_ip_neighbor_add_del (vat_main_t * vam)
7690 {
7691   unformat_input_t *i = vam->input;
7692   vl_api_ip_neighbor_add_del_t *mp;
7693   u32 sw_if_index;
7694   u8 sw_if_index_set = 0;
7695   u8 is_add = 1;
7696   u8 is_static = 0;
7697   u8 is_no_fib_entry = 0;
7698   u8 mac_address[6];
7699   u8 mac_set = 0;
7700   u8 v4_address_set = 0;
7701   u8 v6_address_set = 0;
7702   ip4_address_t v4address;
7703   ip6_address_t v6address;
7704   int ret;
7705
7706   memset (mac_address, 0, sizeof (mac_address));
7707
7708   /* Parse args required to build the message */
7709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7710     {
7711       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7712         {
7713           mac_set = 1;
7714         }
7715       else if (unformat (i, "del"))
7716         is_add = 0;
7717       else
7718         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7719         sw_if_index_set = 1;
7720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7721         sw_if_index_set = 1;
7722       else if (unformat (i, "is_static"))
7723         is_static = 1;
7724       else if (unformat (i, "no-fib-entry"))
7725         is_no_fib_entry = 1;
7726       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7727         v4_address_set = 1;
7728       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7729         v6_address_set = 1;
7730       else
7731         {
7732           clib_warning ("parse error '%U'", format_unformat_error, i);
7733           return -99;
7734         }
7735     }
7736
7737   if (sw_if_index_set == 0)
7738     {
7739       errmsg ("missing interface name or sw_if_index");
7740       return -99;
7741     }
7742   if (v4_address_set && v6_address_set)
7743     {
7744       errmsg ("both v4 and v6 addresses set");
7745       return -99;
7746     }
7747   if (!v4_address_set && !v6_address_set)
7748     {
7749       errmsg ("no address set");
7750       return -99;
7751     }
7752
7753   /* Construct the API message */
7754   M (IP_NEIGHBOR_ADD_DEL, mp);
7755
7756   mp->sw_if_index = ntohl (sw_if_index);
7757   mp->is_add = is_add;
7758   mp->is_static = is_static;
7759   mp->is_no_adj_fib = is_no_fib_entry;
7760   if (mac_set)
7761     clib_memcpy (mp->mac_address, mac_address, 6);
7762   if (v6_address_set)
7763     {
7764       mp->is_ipv6 = 1;
7765       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7766     }
7767   else
7768     {
7769       /* mp->is_ipv6 = 0; via memset in M macro above */
7770       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7771     }
7772
7773   /* send it... */
7774   S (mp);
7775
7776   /* Wait for a reply, return good/bad news  */
7777   W (ret);
7778   return ret;
7779 }
7780
7781 static int
7782 api_reset_vrf (vat_main_t * vam)
7783 {
7784   unformat_input_t *i = vam->input;
7785   vl_api_reset_vrf_t *mp;
7786   u32 vrf_id = 0;
7787   u8 is_ipv6 = 0;
7788   u8 vrf_id_set = 0;
7789   int ret;
7790
7791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7792     {
7793       if (unformat (i, "vrf %d", &vrf_id))
7794         vrf_id_set = 1;
7795       else if (unformat (i, "ipv6"))
7796         is_ipv6 = 1;
7797       else
7798         {
7799           clib_warning ("parse error '%U'", format_unformat_error, i);
7800           return -99;
7801         }
7802     }
7803
7804   if (vrf_id_set == 0)
7805     {
7806       errmsg ("missing vrf id");
7807       return -99;
7808     }
7809
7810   M (RESET_VRF, mp);
7811
7812   mp->vrf_id = ntohl (vrf_id);
7813   mp->is_ipv6 = is_ipv6;
7814
7815   S (mp);
7816   W (ret);
7817   return ret;
7818 }
7819
7820 static int
7821 api_create_vlan_subif (vat_main_t * vam)
7822 {
7823   unformat_input_t *i = vam->input;
7824   vl_api_create_vlan_subif_t *mp;
7825   u32 sw_if_index;
7826   u8 sw_if_index_set = 0;
7827   u32 vlan_id;
7828   u8 vlan_id_set = 0;
7829   int ret;
7830
7831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7832     {
7833       if (unformat (i, "sw_if_index %d", &sw_if_index))
7834         sw_if_index_set = 1;
7835       else
7836         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7837         sw_if_index_set = 1;
7838       else if (unformat (i, "vlan %d", &vlan_id))
7839         vlan_id_set = 1;
7840       else
7841         {
7842           clib_warning ("parse error '%U'", format_unformat_error, i);
7843           return -99;
7844         }
7845     }
7846
7847   if (sw_if_index_set == 0)
7848     {
7849       errmsg ("missing interface name or sw_if_index");
7850       return -99;
7851     }
7852
7853   if (vlan_id_set == 0)
7854     {
7855       errmsg ("missing vlan_id");
7856       return -99;
7857     }
7858   M (CREATE_VLAN_SUBIF, mp);
7859
7860   mp->sw_if_index = ntohl (sw_if_index);
7861   mp->vlan_id = ntohl (vlan_id);
7862
7863   S (mp);
7864   W (ret);
7865   return ret;
7866 }
7867
7868 #define foreach_create_subif_bit                \
7869 _(no_tags)                                      \
7870 _(one_tag)                                      \
7871 _(two_tags)                                     \
7872 _(dot1ad)                                       \
7873 _(exact_match)                                  \
7874 _(default_sub)                                  \
7875 _(outer_vlan_id_any)                            \
7876 _(inner_vlan_id_any)
7877
7878 static int
7879 api_create_subif (vat_main_t * vam)
7880 {
7881   unformat_input_t *i = vam->input;
7882   vl_api_create_subif_t *mp;
7883   u32 sw_if_index;
7884   u8 sw_if_index_set = 0;
7885   u32 sub_id;
7886   u8 sub_id_set = 0;
7887   u32 no_tags = 0;
7888   u32 one_tag = 0;
7889   u32 two_tags = 0;
7890   u32 dot1ad = 0;
7891   u32 exact_match = 0;
7892   u32 default_sub = 0;
7893   u32 outer_vlan_id_any = 0;
7894   u32 inner_vlan_id_any = 0;
7895   u32 tmp;
7896   u16 outer_vlan_id = 0;
7897   u16 inner_vlan_id = 0;
7898   int ret;
7899
7900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7901     {
7902       if (unformat (i, "sw_if_index %d", &sw_if_index))
7903         sw_if_index_set = 1;
7904       else
7905         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7906         sw_if_index_set = 1;
7907       else if (unformat (i, "sub_id %d", &sub_id))
7908         sub_id_set = 1;
7909       else if (unformat (i, "outer_vlan_id %d", &tmp))
7910         outer_vlan_id = tmp;
7911       else if (unformat (i, "inner_vlan_id %d", &tmp))
7912         inner_vlan_id = tmp;
7913
7914 #define _(a) else if (unformat (i, #a)) a = 1 ;
7915       foreach_create_subif_bit
7916 #undef _
7917         else
7918         {
7919           clib_warning ("parse error '%U'", format_unformat_error, i);
7920           return -99;
7921         }
7922     }
7923
7924   if (sw_if_index_set == 0)
7925     {
7926       errmsg ("missing interface name or sw_if_index");
7927       return -99;
7928     }
7929
7930   if (sub_id_set == 0)
7931     {
7932       errmsg ("missing sub_id");
7933       return -99;
7934     }
7935   M (CREATE_SUBIF, mp);
7936
7937   mp->sw_if_index = ntohl (sw_if_index);
7938   mp->sub_id = ntohl (sub_id);
7939
7940 #define _(a) mp->a = a;
7941   foreach_create_subif_bit;
7942 #undef _
7943
7944   mp->outer_vlan_id = ntohs (outer_vlan_id);
7945   mp->inner_vlan_id = ntohs (inner_vlan_id);
7946
7947   S (mp);
7948   W (ret);
7949   return ret;
7950 }
7951
7952 static int
7953 api_oam_add_del (vat_main_t * vam)
7954 {
7955   unformat_input_t *i = vam->input;
7956   vl_api_oam_add_del_t *mp;
7957   u32 vrf_id = 0;
7958   u8 is_add = 1;
7959   ip4_address_t src, dst;
7960   u8 src_set = 0;
7961   u8 dst_set = 0;
7962   int ret;
7963
7964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7965     {
7966       if (unformat (i, "vrf %d", &vrf_id))
7967         ;
7968       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7969         src_set = 1;
7970       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7971         dst_set = 1;
7972       else if (unformat (i, "del"))
7973         is_add = 0;
7974       else
7975         {
7976           clib_warning ("parse error '%U'", format_unformat_error, i);
7977           return -99;
7978         }
7979     }
7980
7981   if (src_set == 0)
7982     {
7983       errmsg ("missing src addr");
7984       return -99;
7985     }
7986
7987   if (dst_set == 0)
7988     {
7989       errmsg ("missing dst addr");
7990       return -99;
7991     }
7992
7993   M (OAM_ADD_DEL, mp);
7994
7995   mp->vrf_id = ntohl (vrf_id);
7996   mp->is_add = is_add;
7997   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7998   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7999
8000   S (mp);
8001   W (ret);
8002   return ret;
8003 }
8004
8005 static int
8006 api_reset_fib (vat_main_t * vam)
8007 {
8008   unformat_input_t *i = vam->input;
8009   vl_api_reset_fib_t *mp;
8010   u32 vrf_id = 0;
8011   u8 is_ipv6 = 0;
8012   u8 vrf_id_set = 0;
8013
8014   int ret;
8015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8016     {
8017       if (unformat (i, "vrf %d", &vrf_id))
8018         vrf_id_set = 1;
8019       else if (unformat (i, "ipv6"))
8020         is_ipv6 = 1;
8021       else
8022         {
8023           clib_warning ("parse error '%U'", format_unformat_error, i);
8024           return -99;
8025         }
8026     }
8027
8028   if (vrf_id_set == 0)
8029     {
8030       errmsg ("missing vrf id");
8031       return -99;
8032     }
8033
8034   M (RESET_FIB, mp);
8035
8036   mp->vrf_id = ntohl (vrf_id);
8037   mp->is_ipv6 = is_ipv6;
8038
8039   S (mp);
8040   W (ret);
8041   return ret;
8042 }
8043
8044 static int
8045 api_dhcp_proxy_config (vat_main_t * vam)
8046 {
8047   unformat_input_t *i = vam->input;
8048   vl_api_dhcp_proxy_config_t *mp;
8049   u32 rx_vrf_id = 0;
8050   u32 server_vrf_id = 0;
8051   u8 is_add = 1;
8052   u8 v4_address_set = 0;
8053   u8 v6_address_set = 0;
8054   ip4_address_t v4address;
8055   ip6_address_t v6address;
8056   u8 v4_src_address_set = 0;
8057   u8 v6_src_address_set = 0;
8058   ip4_address_t v4srcaddress;
8059   ip6_address_t v6srcaddress;
8060   int ret;
8061
8062   /* Parse args required to build the message */
8063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8064     {
8065       if (unformat (i, "del"))
8066         is_add = 0;
8067       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8068         ;
8069       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8070         ;
8071       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8072         v4_address_set = 1;
8073       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8074         v6_address_set = 1;
8075       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8076         v4_src_address_set = 1;
8077       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8078         v6_src_address_set = 1;
8079       else
8080         break;
8081     }
8082
8083   if (v4_address_set && v6_address_set)
8084     {
8085       errmsg ("both v4 and v6 server addresses set");
8086       return -99;
8087     }
8088   if (!v4_address_set && !v6_address_set)
8089     {
8090       errmsg ("no server addresses set");
8091       return -99;
8092     }
8093
8094   if (v4_src_address_set && v6_src_address_set)
8095     {
8096       errmsg ("both v4 and v6  src addresses set");
8097       return -99;
8098     }
8099   if (!v4_src_address_set && !v6_src_address_set)
8100     {
8101       errmsg ("no src addresses set");
8102       return -99;
8103     }
8104
8105   if (!(v4_src_address_set && v4_address_set) &&
8106       !(v6_src_address_set && v6_address_set))
8107     {
8108       errmsg ("no matching server and src addresses set");
8109       return -99;
8110     }
8111
8112   /* Construct the API message */
8113   M (DHCP_PROXY_CONFIG, mp);
8114
8115   mp->is_add = is_add;
8116   mp->rx_vrf_id = ntohl (rx_vrf_id);
8117   mp->server_vrf_id = ntohl (server_vrf_id);
8118   if (v6_address_set)
8119     {
8120       mp->is_ipv6 = 1;
8121       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8122       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8123     }
8124   else
8125     {
8126       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8127       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8128     }
8129
8130   /* send it... */
8131   S (mp);
8132
8133   /* Wait for a reply, return good/bad news  */
8134   W (ret);
8135   return ret;
8136 }
8137
8138 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8139 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8140
8141 static void
8142 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8143 {
8144   vat_main_t *vam = &vat_main;
8145   u32 i, count = mp->count;
8146   vl_api_dhcp_server_t *s;
8147
8148   if (mp->is_ipv6)
8149     print (vam->ofp,
8150            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8151            ntohl (mp->rx_vrf_id),
8152            format_ip6_address, mp->dhcp_src_address,
8153            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8154   else
8155     print (vam->ofp,
8156            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8157            ntohl (mp->rx_vrf_id),
8158            format_ip4_address, mp->dhcp_src_address,
8159            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8160
8161   for (i = 0; i < count; i++)
8162     {
8163       s = &mp->servers[i];
8164
8165       if (mp->is_ipv6)
8166         print (vam->ofp,
8167                " Server Table-ID %d, Server Address %U",
8168                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8169       else
8170         print (vam->ofp,
8171                " Server Table-ID %d, Server Address %U",
8172                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8173     }
8174 }
8175
8176 static void vl_api_dhcp_proxy_details_t_handler_json
8177   (vl_api_dhcp_proxy_details_t * mp)
8178 {
8179   vat_main_t *vam = &vat_main;
8180   vat_json_node_t *node = NULL;
8181   u32 i, count = mp->count;
8182   struct in_addr ip4;
8183   struct in6_addr ip6;
8184   vl_api_dhcp_server_t *s;
8185
8186   if (VAT_JSON_ARRAY != vam->json_tree.type)
8187     {
8188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8189       vat_json_init_array (&vam->json_tree);
8190     }
8191   node = vat_json_array_add (&vam->json_tree);
8192
8193   vat_json_init_object (node);
8194   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8195   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8196   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8197
8198   if (mp->is_ipv6)
8199     {
8200       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8201       vat_json_object_add_ip6 (node, "src_address", ip6);
8202     }
8203   else
8204     {
8205       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8206       vat_json_object_add_ip4 (node, "src_address", ip4);
8207     }
8208
8209   for (i = 0; i < count; i++)
8210     {
8211       s = &mp->servers[i];
8212
8213       vat_json_object_add_uint (node, "server-table-id",
8214                                 ntohl (s->server_vrf_id));
8215
8216       if (mp->is_ipv6)
8217         {
8218           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8219           vat_json_object_add_ip4 (node, "src_address", ip4);
8220         }
8221       else
8222         {
8223           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8224           vat_json_object_add_ip6 (node, "server_address", ip6);
8225         }
8226     }
8227 }
8228
8229 static int
8230 api_dhcp_proxy_dump (vat_main_t * vam)
8231 {
8232   unformat_input_t *i = vam->input;
8233   vl_api_control_ping_t *mp_ping;
8234   vl_api_dhcp_proxy_dump_t *mp;
8235   u8 is_ipv6 = 0;
8236   int ret;
8237
8238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8239     {
8240       if (unformat (i, "ipv6"))
8241         is_ipv6 = 1;
8242       else
8243         {
8244           clib_warning ("parse error '%U'", format_unformat_error, i);
8245           return -99;
8246         }
8247     }
8248
8249   M (DHCP_PROXY_DUMP, mp);
8250
8251   mp->is_ip6 = is_ipv6;
8252   S (mp);
8253
8254   /* Use a control ping for synchronization */
8255   M (CONTROL_PING, mp_ping);
8256   S (mp_ping);
8257
8258   W (ret);
8259   return ret;
8260 }
8261
8262 static int
8263 api_dhcp_proxy_set_vss (vat_main_t * vam)
8264 {
8265   unformat_input_t *i = vam->input;
8266   vl_api_dhcp_proxy_set_vss_t *mp;
8267   u8 is_ipv6 = 0;
8268   u8 is_add = 1;
8269   u32 tbl_id;
8270   u8 tbl_id_set = 0;
8271   u32 oui;
8272   u8 oui_set = 0;
8273   u32 fib_id;
8274   u8 fib_id_set = 0;
8275   int ret;
8276
8277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8278     {
8279       if (unformat (i, "tbl_id %d", &tbl_id))
8280         tbl_id_set = 1;
8281       if (unformat (i, "fib_id %d", &fib_id))
8282         fib_id_set = 1;
8283       if (unformat (i, "oui %d", &oui))
8284         oui_set = 1;
8285       else if (unformat (i, "ipv6"))
8286         is_ipv6 = 1;
8287       else if (unformat (i, "del"))
8288         is_add = 0;
8289       else
8290         {
8291           clib_warning ("parse error '%U'", format_unformat_error, i);
8292           return -99;
8293         }
8294     }
8295
8296   if (tbl_id_set == 0)
8297     {
8298       errmsg ("missing tbl id");
8299       return -99;
8300     }
8301
8302   if (fib_id_set == 0)
8303     {
8304       errmsg ("missing fib id");
8305       return -99;
8306     }
8307   if (oui_set == 0)
8308     {
8309       errmsg ("missing oui");
8310       return -99;
8311     }
8312
8313   M (DHCP_PROXY_SET_VSS, mp);
8314   mp->tbl_id = ntohl (tbl_id);
8315   mp->fib_id = ntohl (fib_id);
8316   mp->oui = ntohl (oui);
8317   mp->is_ipv6 = is_ipv6;
8318   mp->is_add = is_add;
8319
8320   S (mp);
8321   W (ret);
8322   return ret;
8323 }
8324
8325 static int
8326 api_dhcp_client_config (vat_main_t * vam)
8327 {
8328   unformat_input_t *i = vam->input;
8329   vl_api_dhcp_client_config_t *mp;
8330   u32 sw_if_index;
8331   u8 sw_if_index_set = 0;
8332   u8 is_add = 1;
8333   u8 *hostname = 0;
8334   u8 disable_event = 0;
8335   int ret;
8336
8337   /* Parse args required to build the message */
8338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8339     {
8340       if (unformat (i, "del"))
8341         is_add = 0;
8342       else
8343         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8344         sw_if_index_set = 1;
8345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8346         sw_if_index_set = 1;
8347       else if (unformat (i, "hostname %s", &hostname))
8348         ;
8349       else if (unformat (i, "disable_event"))
8350         disable_event = 1;
8351       else
8352         break;
8353     }
8354
8355   if (sw_if_index_set == 0)
8356     {
8357       errmsg ("missing interface name or sw_if_index");
8358       return -99;
8359     }
8360
8361   if (vec_len (hostname) > 63)
8362     {
8363       errmsg ("hostname too long");
8364     }
8365   vec_add1 (hostname, 0);
8366
8367   /* Construct the API message */
8368   M (DHCP_CLIENT_CONFIG, mp);
8369
8370   mp->sw_if_index = htonl (sw_if_index);
8371   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8372   vec_free (hostname);
8373   mp->is_add = is_add;
8374   mp->want_dhcp_event = disable_event ? 0 : 1;
8375   mp->pid = htonl (getpid ());
8376
8377   /* send it... */
8378   S (mp);
8379
8380   /* Wait for a reply, return good/bad news  */
8381   W (ret);
8382   return ret;
8383 }
8384
8385 static int
8386 api_set_ip_flow_hash (vat_main_t * vam)
8387 {
8388   unformat_input_t *i = vam->input;
8389   vl_api_set_ip_flow_hash_t *mp;
8390   u32 vrf_id = 0;
8391   u8 is_ipv6 = 0;
8392   u8 vrf_id_set = 0;
8393   u8 src = 0;
8394   u8 dst = 0;
8395   u8 sport = 0;
8396   u8 dport = 0;
8397   u8 proto = 0;
8398   u8 reverse = 0;
8399   int ret;
8400
8401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8402     {
8403       if (unformat (i, "vrf %d", &vrf_id))
8404         vrf_id_set = 1;
8405       else if (unformat (i, "ipv6"))
8406         is_ipv6 = 1;
8407       else if (unformat (i, "src"))
8408         src = 1;
8409       else if (unformat (i, "dst"))
8410         dst = 1;
8411       else if (unformat (i, "sport"))
8412         sport = 1;
8413       else if (unformat (i, "dport"))
8414         dport = 1;
8415       else if (unformat (i, "proto"))
8416         proto = 1;
8417       else if (unformat (i, "reverse"))
8418         reverse = 1;
8419
8420       else
8421         {
8422           clib_warning ("parse error '%U'", format_unformat_error, i);
8423           return -99;
8424         }
8425     }
8426
8427   if (vrf_id_set == 0)
8428     {
8429       errmsg ("missing vrf id");
8430       return -99;
8431     }
8432
8433   M (SET_IP_FLOW_HASH, mp);
8434   mp->src = src;
8435   mp->dst = dst;
8436   mp->sport = sport;
8437   mp->dport = dport;
8438   mp->proto = proto;
8439   mp->reverse = reverse;
8440   mp->vrf_id = ntohl (vrf_id);
8441   mp->is_ipv6 = is_ipv6;
8442
8443   S (mp);
8444   W (ret);
8445   return ret;
8446 }
8447
8448 static int
8449 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8450 {
8451   unformat_input_t *i = vam->input;
8452   vl_api_sw_interface_ip6_enable_disable_t *mp;
8453   u32 sw_if_index;
8454   u8 sw_if_index_set = 0;
8455   u8 enable = 0;
8456   int ret;
8457
8458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8459     {
8460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8461         sw_if_index_set = 1;
8462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8463         sw_if_index_set = 1;
8464       else if (unformat (i, "enable"))
8465         enable = 1;
8466       else if (unformat (i, "disable"))
8467         enable = 0;
8468       else
8469         {
8470           clib_warning ("parse error '%U'", format_unformat_error, i);
8471           return -99;
8472         }
8473     }
8474
8475   if (sw_if_index_set == 0)
8476     {
8477       errmsg ("missing interface name or sw_if_index");
8478       return -99;
8479     }
8480
8481   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8482
8483   mp->sw_if_index = ntohl (sw_if_index);
8484   mp->enable = enable;
8485
8486   S (mp);
8487   W (ret);
8488   return ret;
8489 }
8490
8491 static int
8492 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8493 {
8494   unformat_input_t *i = vam->input;
8495   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8496   u32 sw_if_index;
8497   u8 sw_if_index_set = 0;
8498   u8 v6_address_set = 0;
8499   ip6_address_t v6address;
8500   int ret;
8501
8502   /* Parse args required to build the message */
8503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8504     {
8505       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8506         sw_if_index_set = 1;
8507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8508         sw_if_index_set = 1;
8509       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8510         v6_address_set = 1;
8511       else
8512         break;
8513     }
8514
8515   if (sw_if_index_set == 0)
8516     {
8517       errmsg ("missing interface name or sw_if_index");
8518       return -99;
8519     }
8520   if (!v6_address_set)
8521     {
8522       errmsg ("no address set");
8523       return -99;
8524     }
8525
8526   /* Construct the API message */
8527   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8528
8529   mp->sw_if_index = ntohl (sw_if_index);
8530   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8531
8532   /* send it... */
8533   S (mp);
8534
8535   /* Wait for a reply, return good/bad news  */
8536   W (ret);
8537   return ret;
8538 }
8539
8540 static int
8541 api_ip6nd_proxy_add_del (vat_main_t * vam)
8542 {
8543   unformat_input_t *i = vam->input;
8544   vl_api_ip6nd_proxy_add_del_t *mp;
8545   u32 sw_if_index = ~0;
8546   u8 v6_address_set = 0;
8547   ip6_address_t v6address;
8548   u8 is_del = 0;
8549   int ret;
8550
8551   /* Parse args required to build the message */
8552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8553     {
8554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8555         ;
8556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8557         ;
8558       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8559         v6_address_set = 1;
8560       if (unformat (i, "del"))
8561         is_del = 1;
8562       else
8563         {
8564           clib_warning ("parse error '%U'", format_unformat_error, i);
8565           return -99;
8566         }
8567     }
8568
8569   if (sw_if_index == ~0)
8570     {
8571       errmsg ("missing interface name or sw_if_index");
8572       return -99;
8573     }
8574   if (!v6_address_set)
8575     {
8576       errmsg ("no address set");
8577       return -99;
8578     }
8579
8580   /* Construct the API message */
8581   M (IP6ND_PROXY_ADD_DEL, mp);
8582
8583   mp->is_del = is_del;
8584   mp->sw_if_index = ntohl (sw_if_index);
8585   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8586
8587   /* send it... */
8588   S (mp);
8589
8590   /* Wait for a reply, return good/bad news  */
8591   W (ret);
8592   return ret;
8593 }
8594
8595 static int
8596 api_ip6nd_proxy_dump (vat_main_t * vam)
8597 {
8598   vl_api_ip6nd_proxy_dump_t *mp;
8599   vl_api_control_ping_t *mp_ping;
8600   int ret;
8601
8602   M (IP6ND_PROXY_DUMP, mp);
8603
8604   S (mp);
8605
8606   /* Use a control ping for synchronization */
8607   M (CONTROL_PING, mp_ping);
8608   S (mp_ping);
8609
8610   W (ret);
8611   return ret;
8612 }
8613
8614 static void vl_api_ip6nd_proxy_details_t_handler
8615   (vl_api_ip6nd_proxy_details_t * mp)
8616 {
8617   vat_main_t *vam = &vat_main;
8618
8619   print (vam->ofp, "host %U sw_if_index %d",
8620          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8621 }
8622
8623 static void vl_api_ip6nd_proxy_details_t_handler_json
8624   (vl_api_ip6nd_proxy_details_t * mp)
8625 {
8626   vat_main_t *vam = &vat_main;
8627   struct in6_addr ip6;
8628   vat_json_node_t *node = NULL;
8629
8630   if (VAT_JSON_ARRAY != vam->json_tree.type)
8631     {
8632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8633       vat_json_init_array (&vam->json_tree);
8634     }
8635   node = vat_json_array_add (&vam->json_tree);
8636
8637   vat_json_init_object (node);
8638   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8639
8640   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8641   vat_json_object_add_ip6 (node, "host", ip6);
8642 }
8643
8644 static int
8645 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8646 {
8647   unformat_input_t *i = vam->input;
8648   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8649   u32 sw_if_index;
8650   u8 sw_if_index_set = 0;
8651   u32 address_length = 0;
8652   u8 v6_address_set = 0;
8653   ip6_address_t v6address;
8654   u8 use_default = 0;
8655   u8 no_advertise = 0;
8656   u8 off_link = 0;
8657   u8 no_autoconfig = 0;
8658   u8 no_onlink = 0;
8659   u8 is_no = 0;
8660   u32 val_lifetime = 0;
8661   u32 pref_lifetime = 0;
8662   int ret;
8663
8664   /* Parse args required to build the message */
8665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8666     {
8667       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8668         sw_if_index_set = 1;
8669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8670         sw_if_index_set = 1;
8671       else if (unformat (i, "%U/%d",
8672                          unformat_ip6_address, &v6address, &address_length))
8673         v6_address_set = 1;
8674       else if (unformat (i, "val_life %d", &val_lifetime))
8675         ;
8676       else if (unformat (i, "pref_life %d", &pref_lifetime))
8677         ;
8678       else if (unformat (i, "def"))
8679         use_default = 1;
8680       else if (unformat (i, "noadv"))
8681         no_advertise = 1;
8682       else if (unformat (i, "offl"))
8683         off_link = 1;
8684       else if (unformat (i, "noauto"))
8685         no_autoconfig = 1;
8686       else if (unformat (i, "nolink"))
8687         no_onlink = 1;
8688       else if (unformat (i, "isno"))
8689         is_no = 1;
8690       else
8691         {
8692           clib_warning ("parse error '%U'", format_unformat_error, i);
8693           return -99;
8694         }
8695     }
8696
8697   if (sw_if_index_set == 0)
8698     {
8699       errmsg ("missing interface name or sw_if_index");
8700       return -99;
8701     }
8702   if (!v6_address_set)
8703     {
8704       errmsg ("no address set");
8705       return -99;
8706     }
8707
8708   /* Construct the API message */
8709   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8710
8711   mp->sw_if_index = ntohl (sw_if_index);
8712   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8713   mp->address_length = address_length;
8714   mp->use_default = use_default;
8715   mp->no_advertise = no_advertise;
8716   mp->off_link = off_link;
8717   mp->no_autoconfig = no_autoconfig;
8718   mp->no_onlink = no_onlink;
8719   mp->is_no = is_no;
8720   mp->val_lifetime = ntohl (val_lifetime);
8721   mp->pref_lifetime = ntohl (pref_lifetime);
8722
8723   /* send it... */
8724   S (mp);
8725
8726   /* Wait for a reply, return good/bad news  */
8727   W (ret);
8728   return ret;
8729 }
8730
8731 static int
8732 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8733 {
8734   unformat_input_t *i = vam->input;
8735   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8736   u32 sw_if_index;
8737   u8 sw_if_index_set = 0;
8738   u8 suppress = 0;
8739   u8 managed = 0;
8740   u8 other = 0;
8741   u8 ll_option = 0;
8742   u8 send_unicast = 0;
8743   u8 cease = 0;
8744   u8 is_no = 0;
8745   u8 default_router = 0;
8746   u32 max_interval = 0;
8747   u32 min_interval = 0;
8748   u32 lifetime = 0;
8749   u32 initial_count = 0;
8750   u32 initial_interval = 0;
8751   int ret;
8752
8753
8754   /* Parse args required to build the message */
8755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8756     {
8757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8758         sw_if_index_set = 1;
8759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8760         sw_if_index_set = 1;
8761       else if (unformat (i, "maxint %d", &max_interval))
8762         ;
8763       else if (unformat (i, "minint %d", &min_interval))
8764         ;
8765       else if (unformat (i, "life %d", &lifetime))
8766         ;
8767       else if (unformat (i, "count %d", &initial_count))
8768         ;
8769       else if (unformat (i, "interval %d", &initial_interval))
8770         ;
8771       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8772         suppress = 1;
8773       else if (unformat (i, "managed"))
8774         managed = 1;
8775       else if (unformat (i, "other"))
8776         other = 1;
8777       else if (unformat (i, "ll"))
8778         ll_option = 1;
8779       else if (unformat (i, "send"))
8780         send_unicast = 1;
8781       else if (unformat (i, "cease"))
8782         cease = 1;
8783       else if (unformat (i, "isno"))
8784         is_no = 1;
8785       else if (unformat (i, "def"))
8786         default_router = 1;
8787       else
8788         {
8789           clib_warning ("parse error '%U'", format_unformat_error, i);
8790           return -99;
8791         }
8792     }
8793
8794   if (sw_if_index_set == 0)
8795     {
8796       errmsg ("missing interface name or sw_if_index");
8797       return -99;
8798     }
8799
8800   /* Construct the API message */
8801   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8802
8803   mp->sw_if_index = ntohl (sw_if_index);
8804   mp->max_interval = ntohl (max_interval);
8805   mp->min_interval = ntohl (min_interval);
8806   mp->lifetime = ntohl (lifetime);
8807   mp->initial_count = ntohl (initial_count);
8808   mp->initial_interval = ntohl (initial_interval);
8809   mp->suppress = suppress;
8810   mp->managed = managed;
8811   mp->other = other;
8812   mp->ll_option = ll_option;
8813   mp->send_unicast = send_unicast;
8814   mp->cease = cease;
8815   mp->is_no = is_no;
8816   mp->default_router = default_router;
8817
8818   /* send it... */
8819   S (mp);
8820
8821   /* Wait for a reply, return good/bad news  */
8822   W (ret);
8823   return ret;
8824 }
8825
8826 static int
8827 api_set_arp_neighbor_limit (vat_main_t * vam)
8828 {
8829   unformat_input_t *i = vam->input;
8830   vl_api_set_arp_neighbor_limit_t *mp;
8831   u32 arp_nbr_limit;
8832   u8 limit_set = 0;
8833   u8 is_ipv6 = 0;
8834   int ret;
8835
8836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8837     {
8838       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8839         limit_set = 1;
8840       else if (unformat (i, "ipv6"))
8841         is_ipv6 = 1;
8842       else
8843         {
8844           clib_warning ("parse error '%U'", format_unformat_error, i);
8845           return -99;
8846         }
8847     }
8848
8849   if (limit_set == 0)
8850     {
8851       errmsg ("missing limit value");
8852       return -99;
8853     }
8854
8855   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8856
8857   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8858   mp->is_ipv6 = is_ipv6;
8859
8860   S (mp);
8861   W (ret);
8862   return ret;
8863 }
8864
8865 static int
8866 api_l2_patch_add_del (vat_main_t * vam)
8867 {
8868   unformat_input_t *i = vam->input;
8869   vl_api_l2_patch_add_del_t *mp;
8870   u32 rx_sw_if_index;
8871   u8 rx_sw_if_index_set = 0;
8872   u32 tx_sw_if_index;
8873   u8 tx_sw_if_index_set = 0;
8874   u8 is_add = 1;
8875   int ret;
8876
8877   /* Parse args required to build the message */
8878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8879     {
8880       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8881         rx_sw_if_index_set = 1;
8882       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8883         tx_sw_if_index_set = 1;
8884       else if (unformat (i, "rx"))
8885         {
8886           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8887             {
8888               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8889                             &rx_sw_if_index))
8890                 rx_sw_if_index_set = 1;
8891             }
8892           else
8893             break;
8894         }
8895       else if (unformat (i, "tx"))
8896         {
8897           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8898             {
8899               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8900                             &tx_sw_if_index))
8901                 tx_sw_if_index_set = 1;
8902             }
8903           else
8904             break;
8905         }
8906       else if (unformat (i, "del"))
8907         is_add = 0;
8908       else
8909         break;
8910     }
8911
8912   if (rx_sw_if_index_set == 0)
8913     {
8914       errmsg ("missing rx interface name or rx_sw_if_index");
8915       return -99;
8916     }
8917
8918   if (tx_sw_if_index_set == 0)
8919     {
8920       errmsg ("missing tx interface name or tx_sw_if_index");
8921       return -99;
8922     }
8923
8924   M (L2_PATCH_ADD_DEL, mp);
8925
8926   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8927   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8928   mp->is_add = is_add;
8929
8930   S (mp);
8931   W (ret);
8932   return ret;
8933 }
8934
8935 u8 is_del;
8936 u8 localsid_addr[16];
8937 u8 end_psp;
8938 u8 behavior;
8939 u32 sw_if_index;
8940 u32 vlan_index;
8941 u32 fib_table;
8942 u8 nh_addr[16];
8943
8944 static int
8945 api_sr_localsid_add_del (vat_main_t * vam)
8946 {
8947   unformat_input_t *i = vam->input;
8948   vl_api_sr_localsid_add_del_t *mp;
8949
8950   u8 is_del;
8951   ip6_address_t localsid;
8952   u8 end_psp = 0;
8953   u8 behavior = ~0;
8954   u32 sw_if_index;
8955   u32 fib_table = ~(u32) 0;
8956   ip6_address_t next_hop;
8957
8958   bool nexthop_set = 0;
8959
8960   int ret;
8961
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "del"))
8965         is_del = 1;
8966       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8967       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8968         nexthop_set = 1;
8969       else if (unformat (i, "behavior %u", &behavior));
8970       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8971       else if (unformat (i, "fib-table %u", &fib_table));
8972       else if (unformat (i, "end.psp %u", &behavior));
8973       else
8974         break;
8975     }
8976
8977   M (SR_LOCALSID_ADD_DEL, mp);
8978
8979   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8980   if (nexthop_set)
8981     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8982   mp->behavior = behavior;
8983   mp->sw_if_index = ntohl (sw_if_index);
8984   mp->fib_table = ntohl (fib_table);
8985   mp->end_psp = end_psp;
8986   mp->is_del = is_del;
8987
8988   S (mp);
8989   W (ret);
8990   return ret;
8991 }
8992
8993 static int
8994 api_ioam_enable (vat_main_t * vam)
8995 {
8996   unformat_input_t *input = vam->input;
8997   vl_api_ioam_enable_t *mp;
8998   u32 id = 0;
8999   int has_trace_option = 0;
9000   int has_pot_option = 0;
9001   int has_seqno_option = 0;
9002   int has_analyse_option = 0;
9003   int ret;
9004
9005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9006     {
9007       if (unformat (input, "trace"))
9008         has_trace_option = 1;
9009       else if (unformat (input, "pot"))
9010         has_pot_option = 1;
9011       else if (unformat (input, "seqno"))
9012         has_seqno_option = 1;
9013       else if (unformat (input, "analyse"))
9014         has_analyse_option = 1;
9015       else
9016         break;
9017     }
9018   M (IOAM_ENABLE, mp);
9019   mp->id = htons (id);
9020   mp->seqno = has_seqno_option;
9021   mp->analyse = has_analyse_option;
9022   mp->pot_enable = has_pot_option;
9023   mp->trace_enable = has_trace_option;
9024
9025   S (mp);
9026   W (ret);
9027   return ret;
9028 }
9029
9030
9031 static int
9032 api_ioam_disable (vat_main_t * vam)
9033 {
9034   vl_api_ioam_disable_t *mp;
9035   int ret;
9036
9037   M (IOAM_DISABLE, mp);
9038   S (mp);
9039   W (ret);
9040   return ret;
9041 }
9042
9043 #define foreach_tcp_proto_field                 \
9044 _(src_port)                                     \
9045 _(dst_port)
9046
9047 #define foreach_udp_proto_field                 \
9048 _(src_port)                                     \
9049 _(dst_port)
9050
9051 #define foreach_ip4_proto_field                 \
9052 _(src_address)                                  \
9053 _(dst_address)                                  \
9054 _(tos)                                          \
9055 _(length)                                       \
9056 _(fragment_id)                                  \
9057 _(ttl)                                          \
9058 _(protocol)                                     \
9059 _(checksum)
9060
9061 typedef struct
9062 {
9063   u16 src_port, dst_port;
9064 } tcpudp_header_t;
9065
9066 #if VPP_API_TEST_BUILTIN == 0
9067 uword
9068 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9069 {
9070   u8 **maskp = va_arg (*args, u8 **);
9071   u8 *mask = 0;
9072   u8 found_something = 0;
9073   tcp_header_t *tcp;
9074
9075 #define _(a) u8 a=0;
9076   foreach_tcp_proto_field;
9077 #undef _
9078
9079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9080     {
9081       if (0);
9082 #define _(a) else if (unformat (input, #a)) a=1;
9083       foreach_tcp_proto_field
9084 #undef _
9085         else
9086         break;
9087     }
9088
9089 #define _(a) found_something += a;
9090   foreach_tcp_proto_field;
9091 #undef _
9092
9093   if (found_something == 0)
9094     return 0;
9095
9096   vec_validate (mask, sizeof (*tcp) - 1);
9097
9098   tcp = (tcp_header_t *) mask;
9099
9100 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9101   foreach_tcp_proto_field;
9102 #undef _
9103
9104   *maskp = mask;
9105   return 1;
9106 }
9107
9108 uword
9109 unformat_udp_mask (unformat_input_t * input, va_list * args)
9110 {
9111   u8 **maskp = va_arg (*args, u8 **);
9112   u8 *mask = 0;
9113   u8 found_something = 0;
9114   udp_header_t *udp;
9115
9116 #define _(a) u8 a=0;
9117   foreach_udp_proto_field;
9118 #undef _
9119
9120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9121     {
9122       if (0);
9123 #define _(a) else if (unformat (input, #a)) a=1;
9124       foreach_udp_proto_field
9125 #undef _
9126         else
9127         break;
9128     }
9129
9130 #define _(a) found_something += a;
9131   foreach_udp_proto_field;
9132 #undef _
9133
9134   if (found_something == 0)
9135     return 0;
9136
9137   vec_validate (mask, sizeof (*udp) - 1);
9138
9139   udp = (udp_header_t *) mask;
9140
9141 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9142   foreach_udp_proto_field;
9143 #undef _
9144
9145   *maskp = mask;
9146   return 1;
9147 }
9148
9149 uword
9150 unformat_l4_mask (unformat_input_t * input, va_list * args)
9151 {
9152   u8 **maskp = va_arg (*args, u8 **);
9153   u16 src_port = 0, dst_port = 0;
9154   tcpudp_header_t *tcpudp;
9155
9156   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9157     {
9158       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9159         return 1;
9160       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9161         return 1;
9162       else if (unformat (input, "src_port"))
9163         src_port = 0xFFFF;
9164       else if (unformat (input, "dst_port"))
9165         dst_port = 0xFFFF;
9166       else
9167         return 0;
9168     }
9169
9170   if (!src_port && !dst_port)
9171     return 0;
9172
9173   u8 *mask = 0;
9174   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9175
9176   tcpudp = (tcpudp_header_t *) mask;
9177   tcpudp->src_port = src_port;
9178   tcpudp->dst_port = dst_port;
9179
9180   *maskp = mask;
9181
9182   return 1;
9183 }
9184
9185 uword
9186 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9187 {
9188   u8 **maskp = va_arg (*args, u8 **);
9189   u8 *mask = 0;
9190   u8 found_something = 0;
9191   ip4_header_t *ip;
9192
9193 #define _(a) u8 a=0;
9194   foreach_ip4_proto_field;
9195 #undef _
9196   u8 version = 0;
9197   u8 hdr_length = 0;
9198
9199
9200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9201     {
9202       if (unformat (input, "version"))
9203         version = 1;
9204       else if (unformat (input, "hdr_length"))
9205         hdr_length = 1;
9206       else if (unformat (input, "src"))
9207         src_address = 1;
9208       else if (unformat (input, "dst"))
9209         dst_address = 1;
9210       else if (unformat (input, "proto"))
9211         protocol = 1;
9212
9213 #define _(a) else if (unformat (input, #a)) a=1;
9214       foreach_ip4_proto_field
9215 #undef _
9216         else
9217         break;
9218     }
9219
9220 #define _(a) found_something += a;
9221   foreach_ip4_proto_field;
9222 #undef _
9223
9224   if (found_something == 0)
9225     return 0;
9226
9227   vec_validate (mask, sizeof (*ip) - 1);
9228
9229   ip = (ip4_header_t *) mask;
9230
9231 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9232   foreach_ip4_proto_field;
9233 #undef _
9234
9235   ip->ip_version_and_header_length = 0;
9236
9237   if (version)
9238     ip->ip_version_and_header_length |= 0xF0;
9239
9240   if (hdr_length)
9241     ip->ip_version_and_header_length |= 0x0F;
9242
9243   *maskp = mask;
9244   return 1;
9245 }
9246
9247 #define foreach_ip6_proto_field                 \
9248 _(src_address)                                  \
9249 _(dst_address)                                  \
9250 _(payload_length)                               \
9251 _(hop_limit)                                    \
9252 _(protocol)
9253
9254 uword
9255 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9256 {
9257   u8 **maskp = va_arg (*args, u8 **);
9258   u8 *mask = 0;
9259   u8 found_something = 0;
9260   ip6_header_t *ip;
9261   u32 ip_version_traffic_class_and_flow_label;
9262
9263 #define _(a) u8 a=0;
9264   foreach_ip6_proto_field;
9265 #undef _
9266   u8 version = 0;
9267   u8 traffic_class = 0;
9268   u8 flow_label = 0;
9269
9270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9271     {
9272       if (unformat (input, "version"))
9273         version = 1;
9274       else if (unformat (input, "traffic-class"))
9275         traffic_class = 1;
9276       else if (unformat (input, "flow-label"))
9277         flow_label = 1;
9278       else if (unformat (input, "src"))
9279         src_address = 1;
9280       else if (unformat (input, "dst"))
9281         dst_address = 1;
9282       else if (unformat (input, "proto"))
9283         protocol = 1;
9284
9285 #define _(a) else if (unformat (input, #a)) a=1;
9286       foreach_ip6_proto_field
9287 #undef _
9288         else
9289         break;
9290     }
9291
9292 #define _(a) found_something += a;
9293   foreach_ip6_proto_field;
9294 #undef _
9295
9296   if (found_something == 0)
9297     return 0;
9298
9299   vec_validate (mask, sizeof (*ip) - 1);
9300
9301   ip = (ip6_header_t *) mask;
9302
9303 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9304   foreach_ip6_proto_field;
9305 #undef _
9306
9307   ip_version_traffic_class_and_flow_label = 0;
9308
9309   if (version)
9310     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9311
9312   if (traffic_class)
9313     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9314
9315   if (flow_label)
9316     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9317
9318   ip->ip_version_traffic_class_and_flow_label =
9319     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9320
9321   *maskp = mask;
9322   return 1;
9323 }
9324
9325 uword
9326 unformat_l3_mask (unformat_input_t * input, va_list * args)
9327 {
9328   u8 **maskp = va_arg (*args, u8 **);
9329
9330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9331     {
9332       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9333         return 1;
9334       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9335         return 1;
9336       else
9337         break;
9338     }
9339   return 0;
9340 }
9341
9342 uword
9343 unformat_l2_mask (unformat_input_t * input, va_list * args)
9344 {
9345   u8 **maskp = va_arg (*args, u8 **);
9346   u8 *mask = 0;
9347   u8 src = 0;
9348   u8 dst = 0;
9349   u8 proto = 0;
9350   u8 tag1 = 0;
9351   u8 tag2 = 0;
9352   u8 ignore_tag1 = 0;
9353   u8 ignore_tag2 = 0;
9354   u8 cos1 = 0;
9355   u8 cos2 = 0;
9356   u8 dot1q = 0;
9357   u8 dot1ad = 0;
9358   int len = 14;
9359
9360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9361     {
9362       if (unformat (input, "src"))
9363         src = 1;
9364       else if (unformat (input, "dst"))
9365         dst = 1;
9366       else if (unformat (input, "proto"))
9367         proto = 1;
9368       else if (unformat (input, "tag1"))
9369         tag1 = 1;
9370       else if (unformat (input, "tag2"))
9371         tag2 = 1;
9372       else if (unformat (input, "ignore-tag1"))
9373         ignore_tag1 = 1;
9374       else if (unformat (input, "ignore-tag2"))
9375         ignore_tag2 = 1;
9376       else if (unformat (input, "cos1"))
9377         cos1 = 1;
9378       else if (unformat (input, "cos2"))
9379         cos2 = 1;
9380       else if (unformat (input, "dot1q"))
9381         dot1q = 1;
9382       else if (unformat (input, "dot1ad"))
9383         dot1ad = 1;
9384       else
9385         break;
9386     }
9387   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9388        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9389     return 0;
9390
9391   if (tag1 || ignore_tag1 || cos1 || dot1q)
9392     len = 18;
9393   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9394     len = 22;
9395
9396   vec_validate (mask, len - 1);
9397
9398   if (dst)
9399     memset (mask, 0xff, 6);
9400
9401   if (src)
9402     memset (mask + 6, 0xff, 6);
9403
9404   if (tag2 || dot1ad)
9405     {
9406       /* inner vlan tag */
9407       if (tag2)
9408         {
9409           mask[19] = 0xff;
9410           mask[18] = 0x0f;
9411         }
9412       if (cos2)
9413         mask[18] |= 0xe0;
9414       if (proto)
9415         mask[21] = mask[20] = 0xff;
9416       if (tag1)
9417         {
9418           mask[15] = 0xff;
9419           mask[14] = 0x0f;
9420         }
9421       if (cos1)
9422         mask[14] |= 0xe0;
9423       *maskp = mask;
9424       return 1;
9425     }
9426   if (tag1 | dot1q)
9427     {
9428       if (tag1)
9429         {
9430           mask[15] = 0xff;
9431           mask[14] = 0x0f;
9432         }
9433       if (cos1)
9434         mask[14] |= 0xe0;
9435       if (proto)
9436         mask[16] = mask[17] = 0xff;
9437
9438       *maskp = mask;
9439       return 1;
9440     }
9441   if (cos2)
9442     mask[18] |= 0xe0;
9443   if (cos1)
9444     mask[14] |= 0xe0;
9445   if (proto)
9446     mask[12] = mask[13] = 0xff;
9447
9448   *maskp = mask;
9449   return 1;
9450 }
9451
9452 uword
9453 unformat_classify_mask (unformat_input_t * input, va_list * args)
9454 {
9455   u8 **maskp = va_arg (*args, u8 **);
9456   u32 *skipp = va_arg (*args, u32 *);
9457   u32 *matchp = va_arg (*args, u32 *);
9458   u32 match;
9459   u8 *mask = 0;
9460   u8 *l2 = 0;
9461   u8 *l3 = 0;
9462   u8 *l4 = 0;
9463   int i;
9464
9465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9466     {
9467       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9468         ;
9469       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9470         ;
9471       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9472         ;
9473       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9474         ;
9475       else
9476         break;
9477     }
9478
9479   if (l4 && !l3)
9480     {
9481       vec_free (mask);
9482       vec_free (l2);
9483       vec_free (l4);
9484       return 0;
9485     }
9486
9487   if (mask || l2 || l3 || l4)
9488     {
9489       if (l2 || l3 || l4)
9490         {
9491           /* "With a free Ethernet header in every package" */
9492           if (l2 == 0)
9493             vec_validate (l2, 13);
9494           mask = l2;
9495           if (vec_len (l3))
9496             {
9497               vec_append (mask, l3);
9498               vec_free (l3);
9499             }
9500           if (vec_len (l4))
9501             {
9502               vec_append (mask, l4);
9503               vec_free (l4);
9504             }
9505         }
9506
9507       /* Scan forward looking for the first significant mask octet */
9508       for (i = 0; i < vec_len (mask); i++)
9509         if (mask[i])
9510           break;
9511
9512       /* compute (skip, match) params */
9513       *skipp = i / sizeof (u32x4);
9514       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9515
9516       /* Pad mask to an even multiple of the vector size */
9517       while (vec_len (mask) % sizeof (u32x4))
9518         vec_add1 (mask, 0);
9519
9520       match = vec_len (mask) / sizeof (u32x4);
9521
9522       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9523         {
9524           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9525           if (*tmp || *(tmp + 1))
9526             break;
9527           match--;
9528         }
9529       if (match == 0)
9530         clib_warning ("BUG: match 0");
9531
9532       _vec_len (mask) = match * sizeof (u32x4);
9533
9534       *matchp = match;
9535       *maskp = mask;
9536
9537       return 1;
9538     }
9539
9540   return 0;
9541 }
9542 #endif /* VPP_API_TEST_BUILTIN */
9543
9544 #define foreach_l2_next                         \
9545 _(drop, DROP)                                   \
9546 _(ethernet, ETHERNET_INPUT)                     \
9547 _(ip4, IP4_INPUT)                               \
9548 _(ip6, IP6_INPUT)
9549
9550 uword
9551 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9552 {
9553   u32 *miss_next_indexp = va_arg (*args, u32 *);
9554   u32 next_index = 0;
9555   u32 tmp;
9556
9557 #define _(n,N) \
9558   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9559   foreach_l2_next;
9560 #undef _
9561
9562   if (unformat (input, "%d", &tmp))
9563     {
9564       next_index = tmp;
9565       goto out;
9566     }
9567
9568   return 0;
9569
9570 out:
9571   *miss_next_indexp = next_index;
9572   return 1;
9573 }
9574
9575 #define foreach_ip_next                         \
9576 _(drop, DROP)                                   \
9577 _(local, LOCAL)                                 \
9578 _(rewrite, REWRITE)
9579
9580 uword
9581 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9582 {
9583   u32 *miss_next_indexp = va_arg (*args, u32 *);
9584   u32 next_index = 0;
9585   u32 tmp;
9586
9587 #define _(n,N) \
9588   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9589   foreach_ip_next;
9590 #undef _
9591
9592   if (unformat (input, "%d", &tmp))
9593     {
9594       next_index = tmp;
9595       goto out;
9596     }
9597
9598   return 0;
9599
9600 out:
9601   *miss_next_indexp = next_index;
9602   return 1;
9603 }
9604
9605 #define foreach_acl_next                        \
9606 _(deny, DENY)
9607
9608 uword
9609 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9610 {
9611   u32 *miss_next_indexp = va_arg (*args, u32 *);
9612   u32 next_index = 0;
9613   u32 tmp;
9614
9615 #define _(n,N) \
9616   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9617   foreach_acl_next;
9618 #undef _
9619
9620   if (unformat (input, "permit"))
9621     {
9622       next_index = ~0;
9623       goto out;
9624     }
9625   else if (unformat (input, "%d", &tmp))
9626     {
9627       next_index = tmp;
9628       goto out;
9629     }
9630
9631   return 0;
9632
9633 out:
9634   *miss_next_indexp = next_index;
9635   return 1;
9636 }
9637
9638 uword
9639 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9640 {
9641   u32 *r = va_arg (*args, u32 *);
9642
9643   if (unformat (input, "conform-color"))
9644     *r = POLICE_CONFORM;
9645   else if (unformat (input, "exceed-color"))
9646     *r = POLICE_EXCEED;
9647   else
9648     return 0;
9649
9650   return 1;
9651 }
9652
9653 static int
9654 api_classify_add_del_table (vat_main_t * vam)
9655 {
9656   unformat_input_t *i = vam->input;
9657   vl_api_classify_add_del_table_t *mp;
9658
9659   u32 nbuckets = 2;
9660   u32 skip = ~0;
9661   u32 match = ~0;
9662   int is_add = 1;
9663   int del_chain = 0;
9664   u32 table_index = ~0;
9665   u32 next_table_index = ~0;
9666   u32 miss_next_index = ~0;
9667   u32 memory_size = 32 << 20;
9668   u8 *mask = 0;
9669   u32 current_data_flag = 0;
9670   int current_data_offset = 0;
9671   int ret;
9672
9673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9674     {
9675       if (unformat (i, "del"))
9676         is_add = 0;
9677       else if (unformat (i, "del-chain"))
9678         {
9679           is_add = 0;
9680           del_chain = 1;
9681         }
9682       else if (unformat (i, "buckets %d", &nbuckets))
9683         ;
9684       else if (unformat (i, "memory_size %d", &memory_size))
9685         ;
9686       else if (unformat (i, "skip %d", &skip))
9687         ;
9688       else if (unformat (i, "match %d", &match))
9689         ;
9690       else if (unformat (i, "table %d", &table_index))
9691         ;
9692       else if (unformat (i, "mask %U", unformat_classify_mask,
9693                          &mask, &skip, &match))
9694         ;
9695       else if (unformat (i, "next-table %d", &next_table_index))
9696         ;
9697       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9698                          &miss_next_index))
9699         ;
9700       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9701                          &miss_next_index))
9702         ;
9703       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9704                          &miss_next_index))
9705         ;
9706       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9707         ;
9708       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9709         ;
9710       else
9711         break;
9712     }
9713
9714   if (is_add && mask == 0)
9715     {
9716       errmsg ("Mask required");
9717       return -99;
9718     }
9719
9720   if (is_add && skip == ~0)
9721     {
9722       errmsg ("skip count required");
9723       return -99;
9724     }
9725
9726   if (is_add && match == ~0)
9727     {
9728       errmsg ("match count required");
9729       return -99;
9730     }
9731
9732   if (!is_add && table_index == ~0)
9733     {
9734       errmsg ("table index required for delete");
9735       return -99;
9736     }
9737
9738   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9739
9740   mp->is_add = is_add;
9741   mp->del_chain = del_chain;
9742   mp->table_index = ntohl (table_index);
9743   mp->nbuckets = ntohl (nbuckets);
9744   mp->memory_size = ntohl (memory_size);
9745   mp->skip_n_vectors = ntohl (skip);
9746   mp->match_n_vectors = ntohl (match);
9747   mp->next_table_index = ntohl (next_table_index);
9748   mp->miss_next_index = ntohl (miss_next_index);
9749   mp->current_data_flag = ntohl (current_data_flag);
9750   mp->current_data_offset = ntohl (current_data_offset);
9751   clib_memcpy (mp->mask, mask, vec_len (mask));
9752
9753   vec_free (mask);
9754
9755   S (mp);
9756   W (ret);
9757   return ret;
9758 }
9759
9760 #if VPP_API_TEST_BUILTIN == 0
9761 uword
9762 unformat_l4_match (unformat_input_t * input, va_list * args)
9763 {
9764   u8 **matchp = va_arg (*args, u8 **);
9765
9766   u8 *proto_header = 0;
9767   int src_port = 0;
9768   int dst_port = 0;
9769
9770   tcpudp_header_t h;
9771
9772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9773     {
9774       if (unformat (input, "src_port %d", &src_port))
9775         ;
9776       else if (unformat (input, "dst_port %d", &dst_port))
9777         ;
9778       else
9779         return 0;
9780     }
9781
9782   h.src_port = clib_host_to_net_u16 (src_port);
9783   h.dst_port = clib_host_to_net_u16 (dst_port);
9784   vec_validate (proto_header, sizeof (h) - 1);
9785   memcpy (proto_header, &h, sizeof (h));
9786
9787   *matchp = proto_header;
9788
9789   return 1;
9790 }
9791
9792 uword
9793 unformat_ip4_match (unformat_input_t * input, va_list * args)
9794 {
9795   u8 **matchp = va_arg (*args, u8 **);
9796   u8 *match = 0;
9797   ip4_header_t *ip;
9798   int version = 0;
9799   u32 version_val;
9800   int hdr_length = 0;
9801   u32 hdr_length_val;
9802   int src = 0, dst = 0;
9803   ip4_address_t src_val, dst_val;
9804   int proto = 0;
9805   u32 proto_val;
9806   int tos = 0;
9807   u32 tos_val;
9808   int length = 0;
9809   u32 length_val;
9810   int fragment_id = 0;
9811   u32 fragment_id_val;
9812   int ttl = 0;
9813   int ttl_val;
9814   int checksum = 0;
9815   u32 checksum_val;
9816
9817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9818     {
9819       if (unformat (input, "version %d", &version_val))
9820         version = 1;
9821       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9822         hdr_length = 1;
9823       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9824         src = 1;
9825       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9826         dst = 1;
9827       else if (unformat (input, "proto %d", &proto_val))
9828         proto = 1;
9829       else if (unformat (input, "tos %d", &tos_val))
9830         tos = 1;
9831       else if (unformat (input, "length %d", &length_val))
9832         length = 1;
9833       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9834         fragment_id = 1;
9835       else if (unformat (input, "ttl %d", &ttl_val))
9836         ttl = 1;
9837       else if (unformat (input, "checksum %d", &checksum_val))
9838         checksum = 1;
9839       else
9840         break;
9841     }
9842
9843   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9844       + ttl + checksum == 0)
9845     return 0;
9846
9847   /*
9848    * Aligned because we use the real comparison functions
9849    */
9850   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9851
9852   ip = (ip4_header_t *) match;
9853
9854   /* These are realistically matched in practice */
9855   if (src)
9856     ip->src_address.as_u32 = src_val.as_u32;
9857
9858   if (dst)
9859     ip->dst_address.as_u32 = dst_val.as_u32;
9860
9861   if (proto)
9862     ip->protocol = proto_val;
9863
9864
9865   /* These are not, but they're included for completeness */
9866   if (version)
9867     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9868
9869   if (hdr_length)
9870     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9871
9872   if (tos)
9873     ip->tos = tos_val;
9874
9875   if (length)
9876     ip->length = clib_host_to_net_u16 (length_val);
9877
9878   if (ttl)
9879     ip->ttl = ttl_val;
9880
9881   if (checksum)
9882     ip->checksum = clib_host_to_net_u16 (checksum_val);
9883
9884   *matchp = match;
9885   return 1;
9886 }
9887
9888 uword
9889 unformat_ip6_match (unformat_input_t * input, va_list * args)
9890 {
9891   u8 **matchp = va_arg (*args, u8 **);
9892   u8 *match = 0;
9893   ip6_header_t *ip;
9894   int version = 0;
9895   u32 version_val;
9896   u8 traffic_class = 0;
9897   u32 traffic_class_val = 0;
9898   u8 flow_label = 0;
9899   u8 flow_label_val;
9900   int src = 0, dst = 0;
9901   ip6_address_t src_val, dst_val;
9902   int proto = 0;
9903   u32 proto_val;
9904   int payload_length = 0;
9905   u32 payload_length_val;
9906   int hop_limit = 0;
9907   int hop_limit_val;
9908   u32 ip_version_traffic_class_and_flow_label;
9909
9910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9911     {
9912       if (unformat (input, "version %d", &version_val))
9913         version = 1;
9914       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9915         traffic_class = 1;
9916       else if (unformat (input, "flow_label %d", &flow_label_val))
9917         flow_label = 1;
9918       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9919         src = 1;
9920       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9921         dst = 1;
9922       else if (unformat (input, "proto %d", &proto_val))
9923         proto = 1;
9924       else if (unformat (input, "payload_length %d", &payload_length_val))
9925         payload_length = 1;
9926       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9927         hop_limit = 1;
9928       else
9929         break;
9930     }
9931
9932   if (version + traffic_class + flow_label + src + dst + proto +
9933       payload_length + hop_limit == 0)
9934     return 0;
9935
9936   /*
9937    * Aligned because we use the real comparison functions
9938    */
9939   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9940
9941   ip = (ip6_header_t *) match;
9942
9943   if (src)
9944     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9945
9946   if (dst)
9947     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9948
9949   if (proto)
9950     ip->protocol = proto_val;
9951
9952   ip_version_traffic_class_and_flow_label = 0;
9953
9954   if (version)
9955     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9956
9957   if (traffic_class)
9958     ip_version_traffic_class_and_flow_label |=
9959       (traffic_class_val & 0xFF) << 20;
9960
9961   if (flow_label)
9962     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9963
9964   ip->ip_version_traffic_class_and_flow_label =
9965     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9966
9967   if (payload_length)
9968     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9969
9970   if (hop_limit)
9971     ip->hop_limit = hop_limit_val;
9972
9973   *matchp = match;
9974   return 1;
9975 }
9976
9977 uword
9978 unformat_l3_match (unformat_input_t * input, va_list * args)
9979 {
9980   u8 **matchp = va_arg (*args, u8 **);
9981
9982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9983     {
9984       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9985         return 1;
9986       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9987         return 1;
9988       else
9989         break;
9990     }
9991   return 0;
9992 }
9993
9994 uword
9995 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9996 {
9997   u8 *tagp = va_arg (*args, u8 *);
9998   u32 tag;
9999
10000   if (unformat (input, "%d", &tag))
10001     {
10002       tagp[0] = (tag >> 8) & 0x0F;
10003       tagp[1] = tag & 0xFF;
10004       return 1;
10005     }
10006
10007   return 0;
10008 }
10009
10010 uword
10011 unformat_l2_match (unformat_input_t * input, va_list * args)
10012 {
10013   u8 **matchp = va_arg (*args, u8 **);
10014   u8 *match = 0;
10015   u8 src = 0;
10016   u8 src_val[6];
10017   u8 dst = 0;
10018   u8 dst_val[6];
10019   u8 proto = 0;
10020   u16 proto_val;
10021   u8 tag1 = 0;
10022   u8 tag1_val[2];
10023   u8 tag2 = 0;
10024   u8 tag2_val[2];
10025   int len = 14;
10026   u8 ignore_tag1 = 0;
10027   u8 ignore_tag2 = 0;
10028   u8 cos1 = 0;
10029   u8 cos2 = 0;
10030   u32 cos1_val = 0;
10031   u32 cos2_val = 0;
10032
10033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10034     {
10035       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10036         src = 1;
10037       else
10038         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10039         dst = 1;
10040       else if (unformat (input, "proto %U",
10041                          unformat_ethernet_type_host_byte_order, &proto_val))
10042         proto = 1;
10043       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10044         tag1 = 1;
10045       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10046         tag2 = 1;
10047       else if (unformat (input, "ignore-tag1"))
10048         ignore_tag1 = 1;
10049       else if (unformat (input, "ignore-tag2"))
10050         ignore_tag2 = 1;
10051       else if (unformat (input, "cos1 %d", &cos1_val))
10052         cos1 = 1;
10053       else if (unformat (input, "cos2 %d", &cos2_val))
10054         cos2 = 1;
10055       else
10056         break;
10057     }
10058   if ((src + dst + proto + tag1 + tag2 +
10059        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10060     return 0;
10061
10062   if (tag1 || ignore_tag1 || cos1)
10063     len = 18;
10064   if (tag2 || ignore_tag2 || cos2)
10065     len = 22;
10066
10067   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10068
10069   if (dst)
10070     clib_memcpy (match, dst_val, 6);
10071
10072   if (src)
10073     clib_memcpy (match + 6, src_val, 6);
10074
10075   if (tag2)
10076     {
10077       /* inner vlan tag */
10078       match[19] = tag2_val[1];
10079       match[18] = tag2_val[0];
10080       if (cos2)
10081         match[18] |= (cos2_val & 0x7) << 5;
10082       if (proto)
10083         {
10084           match[21] = proto_val & 0xff;
10085           match[20] = proto_val >> 8;
10086         }
10087       if (tag1)
10088         {
10089           match[15] = tag1_val[1];
10090           match[14] = tag1_val[0];
10091         }
10092       if (cos1)
10093         match[14] |= (cos1_val & 0x7) << 5;
10094       *matchp = match;
10095       return 1;
10096     }
10097   if (tag1)
10098     {
10099       match[15] = tag1_val[1];
10100       match[14] = tag1_val[0];
10101       if (proto)
10102         {
10103           match[17] = proto_val & 0xff;
10104           match[16] = proto_val >> 8;
10105         }
10106       if (cos1)
10107         match[14] |= (cos1_val & 0x7) << 5;
10108
10109       *matchp = match;
10110       return 1;
10111     }
10112   if (cos2)
10113     match[18] |= (cos2_val & 0x7) << 5;
10114   if (cos1)
10115     match[14] |= (cos1_val & 0x7) << 5;
10116   if (proto)
10117     {
10118       match[13] = proto_val & 0xff;
10119       match[12] = proto_val >> 8;
10120     }
10121
10122   *matchp = match;
10123   return 1;
10124 }
10125 #endif
10126
10127 uword
10128 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10129 {
10130   u8 **matchp = va_arg (*args, u8 **);
10131   u32 skip_n_vectors = va_arg (*args, u32);
10132   u32 match_n_vectors = va_arg (*args, u32);
10133
10134   u8 *match = 0;
10135   u8 *l2 = 0;
10136   u8 *l3 = 0;
10137   u8 *l4 = 0;
10138
10139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10140     {
10141       if (unformat (input, "hex %U", unformat_hex_string, &match))
10142         ;
10143       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10144         ;
10145       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10146         ;
10147       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10148         ;
10149       else
10150         break;
10151     }
10152
10153   if (l4 && !l3)
10154     {
10155       vec_free (match);
10156       vec_free (l2);
10157       vec_free (l4);
10158       return 0;
10159     }
10160
10161   if (match || l2 || l3 || l4)
10162     {
10163       if (l2 || l3 || l4)
10164         {
10165           /* "Win a free Ethernet header in every packet" */
10166           if (l2 == 0)
10167             vec_validate_aligned (l2, 13, sizeof (u32x4));
10168           match = l2;
10169           if (vec_len (l3))
10170             {
10171               vec_append_aligned (match, l3, sizeof (u32x4));
10172               vec_free (l3);
10173             }
10174           if (vec_len (l4))
10175             {
10176               vec_append_aligned (match, l4, sizeof (u32x4));
10177               vec_free (l4);
10178             }
10179         }
10180
10181       /* Make sure the vector is big enough even if key is all 0's */
10182       vec_validate_aligned
10183         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10184          sizeof (u32x4));
10185
10186       /* Set size, include skipped vectors */
10187       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10188
10189       *matchp = match;
10190
10191       return 1;
10192     }
10193
10194   return 0;
10195 }
10196
10197 static int
10198 api_classify_add_del_session (vat_main_t * vam)
10199 {
10200   unformat_input_t *i = vam->input;
10201   vl_api_classify_add_del_session_t *mp;
10202   int is_add = 1;
10203   u32 table_index = ~0;
10204   u32 hit_next_index = ~0;
10205   u32 opaque_index = ~0;
10206   u8 *match = 0;
10207   i32 advance = 0;
10208   u32 skip_n_vectors = 0;
10209   u32 match_n_vectors = 0;
10210   u32 action = 0;
10211   u32 metadata = 0;
10212   int ret;
10213
10214   /*
10215    * Warning: you have to supply skip_n and match_n
10216    * because the API client cant simply look at the classify
10217    * table object.
10218    */
10219
10220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10221     {
10222       if (unformat (i, "del"))
10223         is_add = 0;
10224       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10225                          &hit_next_index))
10226         ;
10227       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10228                          &hit_next_index))
10229         ;
10230       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10231                          &hit_next_index))
10232         ;
10233       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10234         ;
10235       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10236         ;
10237       else if (unformat (i, "opaque-index %d", &opaque_index))
10238         ;
10239       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10240         ;
10241       else if (unformat (i, "match_n %d", &match_n_vectors))
10242         ;
10243       else if (unformat (i, "match %U", api_unformat_classify_match,
10244                          &match, skip_n_vectors, match_n_vectors))
10245         ;
10246       else if (unformat (i, "advance %d", &advance))
10247         ;
10248       else if (unformat (i, "table-index %d", &table_index))
10249         ;
10250       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10251         action = 1;
10252       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10253         action = 2;
10254       else if (unformat (i, "action %d", &action))
10255         ;
10256       else if (unformat (i, "metadata %d", &metadata))
10257         ;
10258       else
10259         break;
10260     }
10261
10262   if (table_index == ~0)
10263     {
10264       errmsg ("Table index required");
10265       return -99;
10266     }
10267
10268   if (is_add && match == 0)
10269     {
10270       errmsg ("Match value required");
10271       return -99;
10272     }
10273
10274   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10275
10276   mp->is_add = is_add;
10277   mp->table_index = ntohl (table_index);
10278   mp->hit_next_index = ntohl (hit_next_index);
10279   mp->opaque_index = ntohl (opaque_index);
10280   mp->advance = ntohl (advance);
10281   mp->action = action;
10282   mp->metadata = ntohl (metadata);
10283   clib_memcpy (mp->match, match, vec_len (match));
10284   vec_free (match);
10285
10286   S (mp);
10287   W (ret);
10288   return ret;
10289 }
10290
10291 static int
10292 api_classify_set_interface_ip_table (vat_main_t * vam)
10293 {
10294   unformat_input_t *i = vam->input;
10295   vl_api_classify_set_interface_ip_table_t *mp;
10296   u32 sw_if_index;
10297   int sw_if_index_set;
10298   u32 table_index = ~0;
10299   u8 is_ipv6 = 0;
10300   int ret;
10301
10302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10303     {
10304       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10305         sw_if_index_set = 1;
10306       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10307         sw_if_index_set = 1;
10308       else if (unformat (i, "table %d", &table_index))
10309         ;
10310       else
10311         {
10312           clib_warning ("parse error '%U'", format_unformat_error, i);
10313           return -99;
10314         }
10315     }
10316
10317   if (sw_if_index_set == 0)
10318     {
10319       errmsg ("missing interface name or sw_if_index");
10320       return -99;
10321     }
10322
10323
10324   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10325
10326   mp->sw_if_index = ntohl (sw_if_index);
10327   mp->table_index = ntohl (table_index);
10328   mp->is_ipv6 = is_ipv6;
10329
10330   S (mp);
10331   W (ret);
10332   return ret;
10333 }
10334
10335 static int
10336 api_classify_set_interface_l2_tables (vat_main_t * vam)
10337 {
10338   unformat_input_t *i = vam->input;
10339   vl_api_classify_set_interface_l2_tables_t *mp;
10340   u32 sw_if_index;
10341   int sw_if_index_set;
10342   u32 ip4_table_index = ~0;
10343   u32 ip6_table_index = ~0;
10344   u32 other_table_index = ~0;
10345   u32 is_input = 1;
10346   int ret;
10347
10348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10349     {
10350       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10351         sw_if_index_set = 1;
10352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10353         sw_if_index_set = 1;
10354       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10355         ;
10356       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10357         ;
10358       else if (unformat (i, "other-table %d", &other_table_index))
10359         ;
10360       else if (unformat (i, "is-input %d", &is_input))
10361         ;
10362       else
10363         {
10364           clib_warning ("parse error '%U'", format_unformat_error, i);
10365           return -99;
10366         }
10367     }
10368
10369   if (sw_if_index_set == 0)
10370     {
10371       errmsg ("missing interface name or sw_if_index");
10372       return -99;
10373     }
10374
10375
10376   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10377
10378   mp->sw_if_index = ntohl (sw_if_index);
10379   mp->ip4_table_index = ntohl (ip4_table_index);
10380   mp->ip6_table_index = ntohl (ip6_table_index);
10381   mp->other_table_index = ntohl (other_table_index);
10382   mp->is_input = (u8) is_input;
10383
10384   S (mp);
10385   W (ret);
10386   return ret;
10387 }
10388
10389 static int
10390 api_set_ipfix_exporter (vat_main_t * vam)
10391 {
10392   unformat_input_t *i = vam->input;
10393   vl_api_set_ipfix_exporter_t *mp;
10394   ip4_address_t collector_address;
10395   u8 collector_address_set = 0;
10396   u32 collector_port = ~0;
10397   ip4_address_t src_address;
10398   u8 src_address_set = 0;
10399   u32 vrf_id = ~0;
10400   u32 path_mtu = ~0;
10401   u32 template_interval = ~0;
10402   u8 udp_checksum = 0;
10403   int ret;
10404
10405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10406     {
10407       if (unformat (i, "collector_address %U", unformat_ip4_address,
10408                     &collector_address))
10409         collector_address_set = 1;
10410       else if (unformat (i, "collector_port %d", &collector_port))
10411         ;
10412       else if (unformat (i, "src_address %U", unformat_ip4_address,
10413                          &src_address))
10414         src_address_set = 1;
10415       else if (unformat (i, "vrf_id %d", &vrf_id))
10416         ;
10417       else if (unformat (i, "path_mtu %d", &path_mtu))
10418         ;
10419       else if (unformat (i, "template_interval %d", &template_interval))
10420         ;
10421       else if (unformat (i, "udp_checksum"))
10422         udp_checksum = 1;
10423       else
10424         break;
10425     }
10426
10427   if (collector_address_set == 0)
10428     {
10429       errmsg ("collector_address required");
10430       return -99;
10431     }
10432
10433   if (src_address_set == 0)
10434     {
10435       errmsg ("src_address required");
10436       return -99;
10437     }
10438
10439   M (SET_IPFIX_EXPORTER, mp);
10440
10441   memcpy (mp->collector_address, collector_address.data,
10442           sizeof (collector_address.data));
10443   mp->collector_port = htons ((u16) collector_port);
10444   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10445   mp->vrf_id = htonl (vrf_id);
10446   mp->path_mtu = htonl (path_mtu);
10447   mp->template_interval = htonl (template_interval);
10448   mp->udp_checksum = udp_checksum;
10449
10450   S (mp);
10451   W (ret);
10452   return ret;
10453 }
10454
10455 static int
10456 api_set_ipfix_classify_stream (vat_main_t * vam)
10457 {
10458   unformat_input_t *i = vam->input;
10459   vl_api_set_ipfix_classify_stream_t *mp;
10460   u32 domain_id = 0;
10461   u32 src_port = UDP_DST_PORT_ipfix;
10462   int ret;
10463
10464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10465     {
10466       if (unformat (i, "domain %d", &domain_id))
10467         ;
10468       else if (unformat (i, "src_port %d", &src_port))
10469         ;
10470       else
10471         {
10472           errmsg ("unknown input `%U'", format_unformat_error, i);
10473           return -99;
10474         }
10475     }
10476
10477   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10478
10479   mp->domain_id = htonl (domain_id);
10480   mp->src_port = htons ((u16) src_port);
10481
10482   S (mp);
10483   W (ret);
10484   return ret;
10485 }
10486
10487 static int
10488 api_ipfix_classify_table_add_del (vat_main_t * vam)
10489 {
10490   unformat_input_t *i = vam->input;
10491   vl_api_ipfix_classify_table_add_del_t *mp;
10492   int is_add = -1;
10493   u32 classify_table_index = ~0;
10494   u8 ip_version = 0;
10495   u8 transport_protocol = 255;
10496   int ret;
10497
10498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10499     {
10500       if (unformat (i, "add"))
10501         is_add = 1;
10502       else if (unformat (i, "del"))
10503         is_add = 0;
10504       else if (unformat (i, "table %d", &classify_table_index))
10505         ;
10506       else if (unformat (i, "ip4"))
10507         ip_version = 4;
10508       else if (unformat (i, "ip6"))
10509         ip_version = 6;
10510       else if (unformat (i, "tcp"))
10511         transport_protocol = 6;
10512       else if (unformat (i, "udp"))
10513         transport_protocol = 17;
10514       else
10515         {
10516           errmsg ("unknown input `%U'", format_unformat_error, i);
10517           return -99;
10518         }
10519     }
10520
10521   if (is_add == -1)
10522     {
10523       errmsg ("expecting: add|del");
10524       return -99;
10525     }
10526   if (classify_table_index == ~0)
10527     {
10528       errmsg ("classifier table not specified");
10529       return -99;
10530     }
10531   if (ip_version == 0)
10532     {
10533       errmsg ("IP version not specified");
10534       return -99;
10535     }
10536
10537   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10538
10539   mp->is_add = is_add;
10540   mp->table_id = htonl (classify_table_index);
10541   mp->ip_version = ip_version;
10542   mp->transport_protocol = transport_protocol;
10543
10544   S (mp);
10545   W (ret);
10546   return ret;
10547 }
10548
10549 static int
10550 api_get_node_index (vat_main_t * vam)
10551 {
10552   unformat_input_t *i = vam->input;
10553   vl_api_get_node_index_t *mp;
10554   u8 *name = 0;
10555   int ret;
10556
10557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10558     {
10559       if (unformat (i, "node %s", &name))
10560         ;
10561       else
10562         break;
10563     }
10564   if (name == 0)
10565     {
10566       errmsg ("node name required");
10567       return -99;
10568     }
10569   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10570     {
10571       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10572       return -99;
10573     }
10574
10575   M (GET_NODE_INDEX, mp);
10576   clib_memcpy (mp->node_name, name, vec_len (name));
10577   vec_free (name);
10578
10579   S (mp);
10580   W (ret);
10581   return ret;
10582 }
10583
10584 static int
10585 api_get_next_index (vat_main_t * vam)
10586 {
10587   unformat_input_t *i = vam->input;
10588   vl_api_get_next_index_t *mp;
10589   u8 *node_name = 0, *next_node_name = 0;
10590   int ret;
10591
10592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10593     {
10594       if (unformat (i, "node-name %s", &node_name))
10595         ;
10596       else if (unformat (i, "next-node-name %s", &next_node_name))
10597         break;
10598     }
10599
10600   if (node_name == 0)
10601     {
10602       errmsg ("node name required");
10603       return -99;
10604     }
10605   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10606     {
10607       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10608       return -99;
10609     }
10610
10611   if (next_node_name == 0)
10612     {
10613       errmsg ("next node name required");
10614       return -99;
10615     }
10616   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10617     {
10618       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10619       return -99;
10620     }
10621
10622   M (GET_NEXT_INDEX, mp);
10623   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10624   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10625   vec_free (node_name);
10626   vec_free (next_node_name);
10627
10628   S (mp);
10629   W (ret);
10630   return ret;
10631 }
10632
10633 static int
10634 api_add_node_next (vat_main_t * vam)
10635 {
10636   unformat_input_t *i = vam->input;
10637   vl_api_add_node_next_t *mp;
10638   u8 *name = 0;
10639   u8 *next = 0;
10640   int ret;
10641
10642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10643     {
10644       if (unformat (i, "node %s", &name))
10645         ;
10646       else if (unformat (i, "next %s", &next))
10647         ;
10648       else
10649         break;
10650     }
10651   if (name == 0)
10652     {
10653       errmsg ("node name required");
10654       return -99;
10655     }
10656   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10657     {
10658       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10659       return -99;
10660     }
10661   if (next == 0)
10662     {
10663       errmsg ("next node required");
10664       return -99;
10665     }
10666   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10667     {
10668       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10669       return -99;
10670     }
10671
10672   M (ADD_NODE_NEXT, mp);
10673   clib_memcpy (mp->node_name, name, vec_len (name));
10674   clib_memcpy (mp->next_name, next, vec_len (next));
10675   vec_free (name);
10676   vec_free (next);
10677
10678   S (mp);
10679   W (ret);
10680   return ret;
10681 }
10682
10683 static int
10684 api_l2tpv3_create_tunnel (vat_main_t * vam)
10685 {
10686   unformat_input_t *i = vam->input;
10687   ip6_address_t client_address, our_address;
10688   int client_address_set = 0;
10689   int our_address_set = 0;
10690   u32 local_session_id = 0;
10691   u32 remote_session_id = 0;
10692   u64 local_cookie = 0;
10693   u64 remote_cookie = 0;
10694   u8 l2_sublayer_present = 0;
10695   vl_api_l2tpv3_create_tunnel_t *mp;
10696   int ret;
10697
10698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10699     {
10700       if (unformat (i, "client_address %U", unformat_ip6_address,
10701                     &client_address))
10702         client_address_set = 1;
10703       else if (unformat (i, "our_address %U", unformat_ip6_address,
10704                          &our_address))
10705         our_address_set = 1;
10706       else if (unformat (i, "local_session_id %d", &local_session_id))
10707         ;
10708       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10709         ;
10710       else if (unformat (i, "local_cookie %lld", &local_cookie))
10711         ;
10712       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10713         ;
10714       else if (unformat (i, "l2-sublayer-present"))
10715         l2_sublayer_present = 1;
10716       else
10717         break;
10718     }
10719
10720   if (client_address_set == 0)
10721     {
10722       errmsg ("client_address required");
10723       return -99;
10724     }
10725
10726   if (our_address_set == 0)
10727     {
10728       errmsg ("our_address required");
10729       return -99;
10730     }
10731
10732   M (L2TPV3_CREATE_TUNNEL, mp);
10733
10734   clib_memcpy (mp->client_address, client_address.as_u8,
10735                sizeof (mp->client_address));
10736
10737   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10738
10739   mp->local_session_id = ntohl (local_session_id);
10740   mp->remote_session_id = ntohl (remote_session_id);
10741   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10742   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10743   mp->l2_sublayer_present = l2_sublayer_present;
10744   mp->is_ipv6 = 1;
10745
10746   S (mp);
10747   W (ret);
10748   return ret;
10749 }
10750
10751 static int
10752 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10753 {
10754   unformat_input_t *i = vam->input;
10755   u32 sw_if_index;
10756   u8 sw_if_index_set = 0;
10757   u64 new_local_cookie = 0;
10758   u64 new_remote_cookie = 0;
10759   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10760   int ret;
10761
10762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10763     {
10764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10765         sw_if_index_set = 1;
10766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10767         sw_if_index_set = 1;
10768       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10769         ;
10770       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10771         ;
10772       else
10773         break;
10774     }
10775
10776   if (sw_if_index_set == 0)
10777     {
10778       errmsg ("missing interface name or sw_if_index");
10779       return -99;
10780     }
10781
10782   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10783
10784   mp->sw_if_index = ntohl (sw_if_index);
10785   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10786   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10787
10788   S (mp);
10789   W (ret);
10790   return ret;
10791 }
10792
10793 static int
10794 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10795 {
10796   unformat_input_t *i = vam->input;
10797   vl_api_l2tpv3_interface_enable_disable_t *mp;
10798   u32 sw_if_index;
10799   u8 sw_if_index_set = 0;
10800   u8 enable_disable = 1;
10801   int ret;
10802
10803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10804     {
10805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10806         sw_if_index_set = 1;
10807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10808         sw_if_index_set = 1;
10809       else if (unformat (i, "enable"))
10810         enable_disable = 1;
10811       else if (unformat (i, "disable"))
10812         enable_disable = 0;
10813       else
10814         break;
10815     }
10816
10817   if (sw_if_index_set == 0)
10818     {
10819       errmsg ("missing interface name or sw_if_index");
10820       return -99;
10821     }
10822
10823   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10824
10825   mp->sw_if_index = ntohl (sw_if_index);
10826   mp->enable_disable = enable_disable;
10827
10828   S (mp);
10829   W (ret);
10830   return ret;
10831 }
10832
10833 static int
10834 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10835 {
10836   unformat_input_t *i = vam->input;
10837   vl_api_l2tpv3_set_lookup_key_t *mp;
10838   u8 key = ~0;
10839   int ret;
10840
10841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10842     {
10843       if (unformat (i, "lookup_v6_src"))
10844         key = L2T_LOOKUP_SRC_ADDRESS;
10845       else if (unformat (i, "lookup_v6_dst"))
10846         key = L2T_LOOKUP_DST_ADDRESS;
10847       else if (unformat (i, "lookup_session_id"))
10848         key = L2T_LOOKUP_SESSION_ID;
10849       else
10850         break;
10851     }
10852
10853   if (key == (u8) ~ 0)
10854     {
10855       errmsg ("l2tp session lookup key unset");
10856       return -99;
10857     }
10858
10859   M (L2TPV3_SET_LOOKUP_KEY, mp);
10860
10861   mp->key = key;
10862
10863   S (mp);
10864   W (ret);
10865   return ret;
10866 }
10867
10868 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10869   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10870 {
10871   vat_main_t *vam = &vat_main;
10872
10873   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10874          format_ip6_address, mp->our_address,
10875          format_ip6_address, mp->client_address,
10876          clib_net_to_host_u32 (mp->sw_if_index));
10877
10878   print (vam->ofp,
10879          "   local cookies %016llx %016llx remote cookie %016llx",
10880          clib_net_to_host_u64 (mp->local_cookie[0]),
10881          clib_net_to_host_u64 (mp->local_cookie[1]),
10882          clib_net_to_host_u64 (mp->remote_cookie));
10883
10884   print (vam->ofp, "   local session-id %d remote session-id %d",
10885          clib_net_to_host_u32 (mp->local_session_id),
10886          clib_net_to_host_u32 (mp->remote_session_id));
10887
10888   print (vam->ofp, "   l2 specific sublayer %s\n",
10889          mp->l2_sublayer_present ? "preset" : "absent");
10890
10891 }
10892
10893 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10894   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10895 {
10896   vat_main_t *vam = &vat_main;
10897   vat_json_node_t *node = NULL;
10898   struct in6_addr addr;
10899
10900   if (VAT_JSON_ARRAY != vam->json_tree.type)
10901     {
10902       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10903       vat_json_init_array (&vam->json_tree);
10904     }
10905   node = vat_json_array_add (&vam->json_tree);
10906
10907   vat_json_init_object (node);
10908
10909   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10910   vat_json_object_add_ip6 (node, "our_address", addr);
10911   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10912   vat_json_object_add_ip6 (node, "client_address", addr);
10913
10914   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10915   vat_json_init_array (lc);
10916   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10917   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10918   vat_json_object_add_uint (node, "remote_cookie",
10919                             clib_net_to_host_u64 (mp->remote_cookie));
10920
10921   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10922   vat_json_object_add_uint (node, "local_session_id",
10923                             clib_net_to_host_u32 (mp->local_session_id));
10924   vat_json_object_add_uint (node, "remote_session_id",
10925                             clib_net_to_host_u32 (mp->remote_session_id));
10926   vat_json_object_add_string_copy (node, "l2_sublayer",
10927                                    mp->l2_sublayer_present ? (u8 *) "present"
10928                                    : (u8 *) "absent");
10929 }
10930
10931 static int
10932 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10933 {
10934   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10935   vl_api_control_ping_t *mp_ping;
10936   int ret;
10937
10938   /* Get list of l2tpv3-tunnel interfaces */
10939   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10940   S (mp);
10941
10942   /* Use a control ping for synchronization */
10943   M (CONTROL_PING, mp_ping);
10944   S (mp_ping);
10945
10946   W (ret);
10947   return ret;
10948 }
10949
10950
10951 static void vl_api_sw_interface_tap_details_t_handler
10952   (vl_api_sw_interface_tap_details_t * mp)
10953 {
10954   vat_main_t *vam = &vat_main;
10955
10956   print (vam->ofp, "%-16s %d",
10957          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10958 }
10959
10960 static void vl_api_sw_interface_tap_details_t_handler_json
10961   (vl_api_sw_interface_tap_details_t * mp)
10962 {
10963   vat_main_t *vam = &vat_main;
10964   vat_json_node_t *node = NULL;
10965
10966   if (VAT_JSON_ARRAY != vam->json_tree.type)
10967     {
10968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10969       vat_json_init_array (&vam->json_tree);
10970     }
10971   node = vat_json_array_add (&vam->json_tree);
10972
10973   vat_json_init_object (node);
10974   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10975   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10976 }
10977
10978 static int
10979 api_sw_interface_tap_dump (vat_main_t * vam)
10980 {
10981   vl_api_sw_interface_tap_dump_t *mp;
10982   vl_api_control_ping_t *mp_ping;
10983   int ret;
10984
10985   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10986   /* Get list of tap interfaces */
10987   M (SW_INTERFACE_TAP_DUMP, mp);
10988   S (mp);
10989
10990   /* Use a control ping for synchronization */
10991   M (CONTROL_PING, mp_ping);
10992   S (mp_ping);
10993
10994   W (ret);
10995   return ret;
10996 }
10997
10998 static uword unformat_vxlan_decap_next
10999   (unformat_input_t * input, va_list * args)
11000 {
11001   u32 *result = va_arg (*args, u32 *);
11002   u32 tmp;
11003
11004   if (unformat (input, "l2"))
11005     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11006   else if (unformat (input, "%d", &tmp))
11007     *result = tmp;
11008   else
11009     return 0;
11010   return 1;
11011 }
11012
11013 static int
11014 api_vxlan_add_del_tunnel (vat_main_t * vam)
11015 {
11016   unformat_input_t *line_input = vam->input;
11017   vl_api_vxlan_add_del_tunnel_t *mp;
11018   ip46_address_t src, dst;
11019   u8 is_add = 1;
11020   u8 ipv4_set = 0, ipv6_set = 0;
11021   u8 src_set = 0;
11022   u8 dst_set = 0;
11023   u8 grp_set = 0;
11024   u32 mcast_sw_if_index = ~0;
11025   u32 encap_vrf_id = 0;
11026   u32 decap_next_index = ~0;
11027   u32 vni = 0;
11028   int ret;
11029
11030   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11031   memset (&src, 0, sizeof src);
11032   memset (&dst, 0, sizeof dst);
11033
11034   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11035     {
11036       if (unformat (line_input, "del"))
11037         is_add = 0;
11038       else
11039         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11040         {
11041           ipv4_set = 1;
11042           src_set = 1;
11043         }
11044       else
11045         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11046         {
11047           ipv4_set = 1;
11048           dst_set = 1;
11049         }
11050       else
11051         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11052         {
11053           ipv6_set = 1;
11054           src_set = 1;
11055         }
11056       else
11057         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11058         {
11059           ipv6_set = 1;
11060           dst_set = 1;
11061         }
11062       else if (unformat (line_input, "group %U %U",
11063                          unformat_ip4_address, &dst.ip4,
11064                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11065         {
11066           grp_set = dst_set = 1;
11067           ipv4_set = 1;
11068         }
11069       else if (unformat (line_input, "group %U",
11070                          unformat_ip4_address, &dst.ip4))
11071         {
11072           grp_set = dst_set = 1;
11073           ipv4_set = 1;
11074         }
11075       else if (unformat (line_input, "group %U %U",
11076                          unformat_ip6_address, &dst.ip6,
11077                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11078         {
11079           grp_set = dst_set = 1;
11080           ipv6_set = 1;
11081         }
11082       else if (unformat (line_input, "group %U",
11083                          unformat_ip6_address, &dst.ip6))
11084         {
11085           grp_set = dst_set = 1;
11086           ipv6_set = 1;
11087         }
11088       else
11089         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11090         ;
11091       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11092         ;
11093       else if (unformat (line_input, "decap-next %U",
11094                          unformat_vxlan_decap_next, &decap_next_index))
11095         ;
11096       else if (unformat (line_input, "vni %d", &vni))
11097         ;
11098       else
11099         {
11100           errmsg ("parse error '%U'", format_unformat_error, line_input);
11101           return -99;
11102         }
11103     }
11104
11105   if (src_set == 0)
11106     {
11107       errmsg ("tunnel src address not specified");
11108       return -99;
11109     }
11110   if (dst_set == 0)
11111     {
11112       errmsg ("tunnel dst address not specified");
11113       return -99;
11114     }
11115
11116   if (grp_set && !ip46_address_is_multicast (&dst))
11117     {
11118       errmsg ("tunnel group address not multicast");
11119       return -99;
11120     }
11121   if (grp_set && mcast_sw_if_index == ~0)
11122     {
11123       errmsg ("tunnel nonexistent multicast device");
11124       return -99;
11125     }
11126   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11127     {
11128       errmsg ("tunnel dst address must be unicast");
11129       return -99;
11130     }
11131
11132
11133   if (ipv4_set && ipv6_set)
11134     {
11135       errmsg ("both IPv4 and IPv6 addresses specified");
11136       return -99;
11137     }
11138
11139   if ((vni == 0) || (vni >> 24))
11140     {
11141       errmsg ("vni not specified or out of range");
11142       return -99;
11143     }
11144
11145   M (VXLAN_ADD_DEL_TUNNEL, mp);
11146
11147   if (ipv6_set)
11148     {
11149       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11150       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11151     }
11152   else
11153     {
11154       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11155       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11156     }
11157   mp->encap_vrf_id = ntohl (encap_vrf_id);
11158   mp->decap_next_index = ntohl (decap_next_index);
11159   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11160   mp->vni = ntohl (vni);
11161   mp->is_add = is_add;
11162   mp->is_ipv6 = ipv6_set;
11163
11164   S (mp);
11165   W (ret);
11166   return ret;
11167 }
11168
11169 static void vl_api_vxlan_tunnel_details_t_handler
11170   (vl_api_vxlan_tunnel_details_t * mp)
11171 {
11172   vat_main_t *vam = &vat_main;
11173   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11174   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11175
11176   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11177          ntohl (mp->sw_if_index),
11178          format_ip46_address, &src, IP46_TYPE_ANY,
11179          format_ip46_address, &dst, IP46_TYPE_ANY,
11180          ntohl (mp->encap_vrf_id),
11181          ntohl (mp->decap_next_index), ntohl (mp->vni),
11182          ntohl (mp->mcast_sw_if_index));
11183 }
11184
11185 static void vl_api_vxlan_tunnel_details_t_handler_json
11186   (vl_api_vxlan_tunnel_details_t * mp)
11187 {
11188   vat_main_t *vam = &vat_main;
11189   vat_json_node_t *node = NULL;
11190
11191   if (VAT_JSON_ARRAY != vam->json_tree.type)
11192     {
11193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11194       vat_json_init_array (&vam->json_tree);
11195     }
11196   node = vat_json_array_add (&vam->json_tree);
11197
11198   vat_json_init_object (node);
11199   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11200   if (mp->is_ipv6)
11201     {
11202       struct in6_addr ip6;
11203
11204       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11205       vat_json_object_add_ip6 (node, "src_address", ip6);
11206       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11207       vat_json_object_add_ip6 (node, "dst_address", ip6);
11208     }
11209   else
11210     {
11211       struct in_addr ip4;
11212
11213       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11214       vat_json_object_add_ip4 (node, "src_address", ip4);
11215       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11216       vat_json_object_add_ip4 (node, "dst_address", ip4);
11217     }
11218   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11219   vat_json_object_add_uint (node, "decap_next_index",
11220                             ntohl (mp->decap_next_index));
11221   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11222   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11223   vat_json_object_add_uint (node, "mcast_sw_if_index",
11224                             ntohl (mp->mcast_sw_if_index));
11225 }
11226
11227 static int
11228 api_vxlan_tunnel_dump (vat_main_t * vam)
11229 {
11230   unformat_input_t *i = vam->input;
11231   vl_api_vxlan_tunnel_dump_t *mp;
11232   vl_api_control_ping_t *mp_ping;
11233   u32 sw_if_index;
11234   u8 sw_if_index_set = 0;
11235   int ret;
11236
11237   /* Parse args required to build the message */
11238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11239     {
11240       if (unformat (i, "sw_if_index %d", &sw_if_index))
11241         sw_if_index_set = 1;
11242       else
11243         break;
11244     }
11245
11246   if (sw_if_index_set == 0)
11247     {
11248       sw_if_index = ~0;
11249     }
11250
11251   if (!vam->json_output)
11252     {
11253       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11254              "sw_if_index", "src_address", "dst_address",
11255              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11256     }
11257
11258   /* Get list of vxlan-tunnel interfaces */
11259   M (VXLAN_TUNNEL_DUMP, mp);
11260
11261   mp->sw_if_index = htonl (sw_if_index);
11262
11263   S (mp);
11264
11265   /* Use a control ping for synchronization */
11266   M (CONTROL_PING, mp_ping);
11267   S (mp_ping);
11268
11269   W (ret);
11270   return ret;
11271 }
11272
11273 static int
11274 api_gre_add_del_tunnel (vat_main_t * vam)
11275 {
11276   unformat_input_t *line_input = vam->input;
11277   vl_api_gre_add_del_tunnel_t *mp;
11278   ip4_address_t src4, dst4;
11279   ip6_address_t src6, dst6;
11280   u8 is_add = 1;
11281   u8 ipv4_set = 0;
11282   u8 ipv6_set = 0;
11283   u8 teb = 0;
11284   u8 src_set = 0;
11285   u8 dst_set = 0;
11286   u32 outer_fib_id = 0;
11287   int ret;
11288
11289   memset (&src4, 0, sizeof src4);
11290   memset (&dst4, 0, sizeof dst4);
11291   memset (&src6, 0, sizeof src6);
11292   memset (&dst6, 0, sizeof dst6);
11293
11294   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11295     {
11296       if (unformat (line_input, "del"))
11297         is_add = 0;
11298       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11299         {
11300           src_set = 1;
11301           ipv4_set = 1;
11302         }
11303       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11304         {
11305           dst_set = 1;
11306           ipv4_set = 1;
11307         }
11308       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11309         {
11310           src_set = 1;
11311           ipv6_set = 1;
11312         }
11313       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11314         {
11315           dst_set = 1;
11316           ipv6_set = 1;
11317         }
11318       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11319         ;
11320       else if (unformat (line_input, "teb"))
11321         teb = 1;
11322       else
11323         {
11324           errmsg ("parse error '%U'", format_unformat_error, line_input);
11325           return -99;
11326         }
11327     }
11328
11329   if (src_set == 0)
11330     {
11331       errmsg ("tunnel src address not specified");
11332       return -99;
11333     }
11334   if (dst_set == 0)
11335     {
11336       errmsg ("tunnel dst address not specified");
11337       return -99;
11338     }
11339   if (ipv4_set && ipv6_set)
11340     {
11341       errmsg ("both IPv4 and IPv6 addresses specified");
11342       return -99;
11343     }
11344
11345
11346   M (GRE_ADD_DEL_TUNNEL, mp);
11347
11348   if (ipv4_set)
11349     {
11350       clib_memcpy (&mp->src_address, &src4, 4);
11351       clib_memcpy (&mp->dst_address, &dst4, 4);
11352     }
11353   else
11354     {
11355       clib_memcpy (&mp->src_address, &src6, 16);
11356       clib_memcpy (&mp->dst_address, &dst6, 16);
11357     }
11358   mp->outer_fib_id = ntohl (outer_fib_id);
11359   mp->is_add = is_add;
11360   mp->teb = teb;
11361   mp->is_ipv6 = ipv6_set;
11362
11363   S (mp);
11364   W (ret);
11365   return ret;
11366 }
11367
11368 static void vl_api_gre_tunnel_details_t_handler
11369   (vl_api_gre_tunnel_details_t * mp)
11370 {
11371   vat_main_t *vam = &vat_main;
11372   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11373   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11374
11375   print (vam->ofp, "%11d%24U%24U%6d%14d",
11376          ntohl (mp->sw_if_index),
11377          format_ip46_address, &src, IP46_TYPE_ANY,
11378          format_ip46_address, &dst, IP46_TYPE_ANY,
11379          mp->teb, ntohl (mp->outer_fib_id));
11380 }
11381
11382 static void vl_api_gre_tunnel_details_t_handler_json
11383   (vl_api_gre_tunnel_details_t * mp)
11384 {
11385   vat_main_t *vam = &vat_main;
11386   vat_json_node_t *node = NULL;
11387   struct in_addr ip4;
11388   struct in6_addr ip6;
11389
11390   if (VAT_JSON_ARRAY != vam->json_tree.type)
11391     {
11392       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11393       vat_json_init_array (&vam->json_tree);
11394     }
11395   node = vat_json_array_add (&vam->json_tree);
11396
11397   vat_json_init_object (node);
11398   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11399   if (!mp->is_ipv6)
11400     {
11401       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11402       vat_json_object_add_ip4 (node, "src_address", ip4);
11403       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11404       vat_json_object_add_ip4 (node, "dst_address", ip4);
11405     }
11406   else
11407     {
11408       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11409       vat_json_object_add_ip6 (node, "src_address", ip6);
11410       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11411       vat_json_object_add_ip6 (node, "dst_address", ip6);
11412     }
11413   vat_json_object_add_uint (node, "teb", mp->teb);
11414   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11415   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11416 }
11417
11418 static int
11419 api_gre_tunnel_dump (vat_main_t * vam)
11420 {
11421   unformat_input_t *i = vam->input;
11422   vl_api_gre_tunnel_dump_t *mp;
11423   vl_api_control_ping_t *mp_ping;
11424   u32 sw_if_index;
11425   u8 sw_if_index_set = 0;
11426   int ret;
11427
11428   /* Parse args required to build the message */
11429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11430     {
11431       if (unformat (i, "sw_if_index %d", &sw_if_index))
11432         sw_if_index_set = 1;
11433       else
11434         break;
11435     }
11436
11437   if (sw_if_index_set == 0)
11438     {
11439       sw_if_index = ~0;
11440     }
11441
11442   if (!vam->json_output)
11443     {
11444       print (vam->ofp, "%11s%24s%24s%6s%14s",
11445              "sw_if_index", "src_address", "dst_address", "teb",
11446              "outer_fib_id");
11447     }
11448
11449   /* Get list of gre-tunnel interfaces */
11450   M (GRE_TUNNEL_DUMP, mp);
11451
11452   mp->sw_if_index = htonl (sw_if_index);
11453
11454   S (mp);
11455
11456   /* Use a control ping for synchronization */
11457   M (CONTROL_PING, mp_ping);
11458   S (mp_ping);
11459
11460   W (ret);
11461   return ret;
11462 }
11463
11464 static int
11465 api_l2_fib_clear_table (vat_main_t * vam)
11466 {
11467 //  unformat_input_t * i = vam->input;
11468   vl_api_l2_fib_clear_table_t *mp;
11469   int ret;
11470
11471   M (L2_FIB_CLEAR_TABLE, mp);
11472
11473   S (mp);
11474   W (ret);
11475   return ret;
11476 }
11477
11478 static int
11479 api_l2_interface_efp_filter (vat_main_t * vam)
11480 {
11481   unformat_input_t *i = vam->input;
11482   vl_api_l2_interface_efp_filter_t *mp;
11483   u32 sw_if_index;
11484   u8 enable = 1;
11485   u8 sw_if_index_set = 0;
11486   int ret;
11487
11488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11489     {
11490       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11491         sw_if_index_set = 1;
11492       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11493         sw_if_index_set = 1;
11494       else if (unformat (i, "enable"))
11495         enable = 1;
11496       else if (unformat (i, "disable"))
11497         enable = 0;
11498       else
11499         {
11500           clib_warning ("parse error '%U'", format_unformat_error, i);
11501           return -99;
11502         }
11503     }
11504
11505   if (sw_if_index_set == 0)
11506     {
11507       errmsg ("missing sw_if_index");
11508       return -99;
11509     }
11510
11511   M (L2_INTERFACE_EFP_FILTER, mp);
11512
11513   mp->sw_if_index = ntohl (sw_if_index);
11514   mp->enable_disable = enable;
11515
11516   S (mp);
11517   W (ret);
11518   return ret;
11519 }
11520
11521 #define foreach_vtr_op                          \
11522 _("disable",  L2_VTR_DISABLED)                  \
11523 _("push-1",  L2_VTR_PUSH_1)                     \
11524 _("push-2",  L2_VTR_PUSH_2)                     \
11525 _("pop-1",  L2_VTR_POP_1)                       \
11526 _("pop-2",  L2_VTR_POP_2)                       \
11527 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11528 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11529 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11530 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11531
11532 static int
11533 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11534 {
11535   unformat_input_t *i = vam->input;
11536   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11537   u32 sw_if_index;
11538   u8 sw_if_index_set = 0;
11539   u8 vtr_op_set = 0;
11540   u32 vtr_op = 0;
11541   u32 push_dot1q = 1;
11542   u32 tag1 = ~0;
11543   u32 tag2 = ~0;
11544   int ret;
11545
11546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11547     {
11548       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11549         sw_if_index_set = 1;
11550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11551         sw_if_index_set = 1;
11552       else if (unformat (i, "vtr_op %d", &vtr_op))
11553         vtr_op_set = 1;
11554 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11555       foreach_vtr_op
11556 #undef _
11557         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11558         ;
11559       else if (unformat (i, "tag1 %d", &tag1))
11560         ;
11561       else if (unformat (i, "tag2 %d", &tag2))
11562         ;
11563       else
11564         {
11565           clib_warning ("parse error '%U'", format_unformat_error, i);
11566           return -99;
11567         }
11568     }
11569
11570   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11571     {
11572       errmsg ("missing vtr operation or sw_if_index");
11573       return -99;
11574     }
11575
11576   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11577   mp->sw_if_index = ntohl (sw_if_index);
11578   mp->vtr_op = ntohl (vtr_op);
11579   mp->push_dot1q = ntohl (push_dot1q);
11580   mp->tag1 = ntohl (tag1);
11581   mp->tag2 = ntohl (tag2);
11582
11583   S (mp);
11584   W (ret);
11585   return ret;
11586 }
11587
11588 static int
11589 api_create_vhost_user_if (vat_main_t * vam)
11590 {
11591   unformat_input_t *i = vam->input;
11592   vl_api_create_vhost_user_if_t *mp;
11593   u8 *file_name;
11594   u8 is_server = 0;
11595   u8 file_name_set = 0;
11596   u32 custom_dev_instance = ~0;
11597   u8 hwaddr[6];
11598   u8 use_custom_mac = 0;
11599   u8 *tag = 0;
11600   int ret;
11601
11602   /* Shut up coverity */
11603   memset (hwaddr, 0, sizeof (hwaddr));
11604
11605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11606     {
11607       if (unformat (i, "socket %s", &file_name))
11608         {
11609           file_name_set = 1;
11610         }
11611       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11612         ;
11613       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11614         use_custom_mac = 1;
11615       else if (unformat (i, "server"))
11616         is_server = 1;
11617       else if (unformat (i, "tag %s", &tag))
11618         ;
11619       else
11620         break;
11621     }
11622
11623   if (file_name_set == 0)
11624     {
11625       errmsg ("missing socket file name");
11626       return -99;
11627     }
11628
11629   if (vec_len (file_name) > 255)
11630     {
11631       errmsg ("socket file name too long");
11632       return -99;
11633     }
11634   vec_add1 (file_name, 0);
11635
11636   M (CREATE_VHOST_USER_IF, mp);
11637
11638   mp->is_server = is_server;
11639   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11640   vec_free (file_name);
11641   if (custom_dev_instance != ~0)
11642     {
11643       mp->renumber = 1;
11644       mp->custom_dev_instance = ntohl (custom_dev_instance);
11645     }
11646   mp->use_custom_mac = use_custom_mac;
11647   clib_memcpy (mp->mac_address, hwaddr, 6);
11648   if (tag)
11649     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11650   vec_free (tag);
11651
11652   S (mp);
11653   W (ret);
11654   return ret;
11655 }
11656
11657 static int
11658 api_modify_vhost_user_if (vat_main_t * vam)
11659 {
11660   unformat_input_t *i = vam->input;
11661   vl_api_modify_vhost_user_if_t *mp;
11662   u8 *file_name;
11663   u8 is_server = 0;
11664   u8 file_name_set = 0;
11665   u32 custom_dev_instance = ~0;
11666   u8 sw_if_index_set = 0;
11667   u32 sw_if_index = (u32) ~ 0;
11668   int ret;
11669
11670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11671     {
11672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11673         sw_if_index_set = 1;
11674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11675         sw_if_index_set = 1;
11676       else if (unformat (i, "socket %s", &file_name))
11677         {
11678           file_name_set = 1;
11679         }
11680       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11681         ;
11682       else if (unformat (i, "server"))
11683         is_server = 1;
11684       else
11685         break;
11686     }
11687
11688   if (sw_if_index_set == 0)
11689     {
11690       errmsg ("missing sw_if_index or interface name");
11691       return -99;
11692     }
11693
11694   if (file_name_set == 0)
11695     {
11696       errmsg ("missing socket file name");
11697       return -99;
11698     }
11699
11700   if (vec_len (file_name) > 255)
11701     {
11702       errmsg ("socket file name too long");
11703       return -99;
11704     }
11705   vec_add1 (file_name, 0);
11706
11707   M (MODIFY_VHOST_USER_IF, mp);
11708
11709   mp->sw_if_index = ntohl (sw_if_index);
11710   mp->is_server = is_server;
11711   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11712   vec_free (file_name);
11713   if (custom_dev_instance != ~0)
11714     {
11715       mp->renumber = 1;
11716       mp->custom_dev_instance = ntohl (custom_dev_instance);
11717     }
11718
11719   S (mp);
11720   W (ret);
11721   return ret;
11722 }
11723
11724 static int
11725 api_delete_vhost_user_if (vat_main_t * vam)
11726 {
11727   unformat_input_t *i = vam->input;
11728   vl_api_delete_vhost_user_if_t *mp;
11729   u32 sw_if_index = ~0;
11730   u8 sw_if_index_set = 0;
11731   int ret;
11732
11733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11734     {
11735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11736         sw_if_index_set = 1;
11737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11738         sw_if_index_set = 1;
11739       else
11740         break;
11741     }
11742
11743   if (sw_if_index_set == 0)
11744     {
11745       errmsg ("missing sw_if_index or interface name");
11746       return -99;
11747     }
11748
11749
11750   M (DELETE_VHOST_USER_IF, mp);
11751
11752   mp->sw_if_index = ntohl (sw_if_index);
11753
11754   S (mp);
11755   W (ret);
11756   return ret;
11757 }
11758
11759 static void vl_api_sw_interface_vhost_user_details_t_handler
11760   (vl_api_sw_interface_vhost_user_details_t * mp)
11761 {
11762   vat_main_t *vam = &vat_main;
11763
11764   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11765          (char *) mp->interface_name,
11766          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11767          clib_net_to_host_u64 (mp->features), mp->is_server,
11768          ntohl (mp->num_regions), (char *) mp->sock_filename);
11769   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11770 }
11771
11772 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11773   (vl_api_sw_interface_vhost_user_details_t * mp)
11774 {
11775   vat_main_t *vam = &vat_main;
11776   vat_json_node_t *node = NULL;
11777
11778   if (VAT_JSON_ARRAY != vam->json_tree.type)
11779     {
11780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11781       vat_json_init_array (&vam->json_tree);
11782     }
11783   node = vat_json_array_add (&vam->json_tree);
11784
11785   vat_json_init_object (node);
11786   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11787   vat_json_object_add_string_copy (node, "interface_name",
11788                                    mp->interface_name);
11789   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11790                             ntohl (mp->virtio_net_hdr_sz));
11791   vat_json_object_add_uint (node, "features",
11792                             clib_net_to_host_u64 (mp->features));
11793   vat_json_object_add_uint (node, "is_server", mp->is_server);
11794   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11795   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11796   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11797 }
11798
11799 static int
11800 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11801 {
11802   vl_api_sw_interface_vhost_user_dump_t *mp;
11803   vl_api_control_ping_t *mp_ping;
11804   int ret;
11805   print (vam->ofp,
11806          "Interface name            idx hdr_sz features server regions filename");
11807
11808   /* Get list of vhost-user interfaces */
11809   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11810   S (mp);
11811
11812   /* Use a control ping for synchronization */
11813   M (CONTROL_PING, mp_ping);
11814   S (mp_ping);
11815
11816   W (ret);
11817   return ret;
11818 }
11819
11820 static int
11821 api_show_version (vat_main_t * vam)
11822 {
11823   vl_api_show_version_t *mp;
11824   int ret;
11825
11826   M (SHOW_VERSION, mp);
11827
11828   S (mp);
11829   W (ret);
11830   return ret;
11831 }
11832
11833
11834 static int
11835 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11836 {
11837   unformat_input_t *line_input = vam->input;
11838   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11839   ip4_address_t local4, remote4;
11840   ip6_address_t local6, remote6;
11841   u8 is_add = 1;
11842   u8 ipv4_set = 0, ipv6_set = 0;
11843   u8 local_set = 0;
11844   u8 remote_set = 0;
11845   u32 encap_vrf_id = 0;
11846   u32 decap_vrf_id = 0;
11847   u8 protocol = ~0;
11848   u32 vni;
11849   u8 vni_set = 0;
11850   int ret;
11851
11852   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11853     {
11854       if (unformat (line_input, "del"))
11855         is_add = 0;
11856       else if (unformat (line_input, "local %U",
11857                          unformat_ip4_address, &local4))
11858         {
11859           local_set = 1;
11860           ipv4_set = 1;
11861         }
11862       else if (unformat (line_input, "remote %U",
11863                          unformat_ip4_address, &remote4))
11864         {
11865           remote_set = 1;
11866           ipv4_set = 1;
11867         }
11868       else if (unformat (line_input, "local %U",
11869                          unformat_ip6_address, &local6))
11870         {
11871           local_set = 1;
11872           ipv6_set = 1;
11873         }
11874       else if (unformat (line_input, "remote %U",
11875                          unformat_ip6_address, &remote6))
11876         {
11877           remote_set = 1;
11878           ipv6_set = 1;
11879         }
11880       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11881         ;
11882       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11883         ;
11884       else if (unformat (line_input, "vni %d", &vni))
11885         vni_set = 1;
11886       else if (unformat (line_input, "next-ip4"))
11887         protocol = 1;
11888       else if (unformat (line_input, "next-ip6"))
11889         protocol = 2;
11890       else if (unformat (line_input, "next-ethernet"))
11891         protocol = 3;
11892       else if (unformat (line_input, "next-nsh"))
11893         protocol = 4;
11894       else
11895         {
11896           errmsg ("parse error '%U'", format_unformat_error, line_input);
11897           return -99;
11898         }
11899     }
11900
11901   if (local_set == 0)
11902     {
11903       errmsg ("tunnel local address not specified");
11904       return -99;
11905     }
11906   if (remote_set == 0)
11907     {
11908       errmsg ("tunnel remote address not specified");
11909       return -99;
11910     }
11911   if (ipv4_set && ipv6_set)
11912     {
11913       errmsg ("both IPv4 and IPv6 addresses specified");
11914       return -99;
11915     }
11916
11917   if (vni_set == 0)
11918     {
11919       errmsg ("vni not specified");
11920       return -99;
11921     }
11922
11923   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11924
11925
11926   if (ipv6_set)
11927     {
11928       clib_memcpy (&mp->local, &local6, sizeof (local6));
11929       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11930     }
11931   else
11932     {
11933       clib_memcpy (&mp->local, &local4, sizeof (local4));
11934       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11935     }
11936
11937   mp->encap_vrf_id = ntohl (encap_vrf_id);
11938   mp->decap_vrf_id = ntohl (decap_vrf_id);
11939   mp->protocol = protocol;
11940   mp->vni = ntohl (vni);
11941   mp->is_add = is_add;
11942   mp->is_ipv6 = ipv6_set;
11943
11944   S (mp);
11945   W (ret);
11946   return ret;
11947 }
11948
11949 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11950   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11951 {
11952   vat_main_t *vam = &vat_main;
11953
11954   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11955          ntohl (mp->sw_if_index),
11956          format_ip46_address, &(mp->local[0]),
11957          format_ip46_address, &(mp->remote[0]),
11958          ntohl (mp->vni),
11959          ntohl (mp->protocol),
11960          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11961 }
11962
11963 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11964   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11965 {
11966   vat_main_t *vam = &vat_main;
11967   vat_json_node_t *node = NULL;
11968   struct in_addr ip4;
11969   struct in6_addr ip6;
11970
11971   if (VAT_JSON_ARRAY != vam->json_tree.type)
11972     {
11973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11974       vat_json_init_array (&vam->json_tree);
11975     }
11976   node = vat_json_array_add (&vam->json_tree);
11977
11978   vat_json_init_object (node);
11979   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11980   if (mp->is_ipv6)
11981     {
11982       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11983       vat_json_object_add_ip6 (node, "local", ip6);
11984       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11985       vat_json_object_add_ip6 (node, "remote", ip6);
11986     }
11987   else
11988     {
11989       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11990       vat_json_object_add_ip4 (node, "local", ip4);
11991       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11992       vat_json_object_add_ip4 (node, "remote", ip4);
11993     }
11994   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11995   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11996   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11997   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11998   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11999 }
12000
12001 static int
12002 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12003 {
12004   unformat_input_t *i = vam->input;
12005   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12006   vl_api_control_ping_t *mp_ping;
12007   u32 sw_if_index;
12008   u8 sw_if_index_set = 0;
12009   int ret;
12010
12011   /* Parse args required to build the message */
12012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12013     {
12014       if (unformat (i, "sw_if_index %d", &sw_if_index))
12015         sw_if_index_set = 1;
12016       else
12017         break;
12018     }
12019
12020   if (sw_if_index_set == 0)
12021     {
12022       sw_if_index = ~0;
12023     }
12024
12025   if (!vam->json_output)
12026     {
12027       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
12028              "sw_if_index", "local", "remote", "vni",
12029              "protocol", "encap_vrf_id", "decap_vrf_id");
12030     }
12031
12032   /* Get list of vxlan-tunnel interfaces */
12033   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12034
12035   mp->sw_if_index = htonl (sw_if_index);
12036
12037   S (mp);
12038
12039   /* Use a control ping for synchronization */
12040   M (CONTROL_PING, mp_ping);
12041   S (mp_ping);
12042
12043   W (ret);
12044   return ret;
12045 }
12046
12047 u8 *
12048 format_l2_fib_mac_address (u8 * s, va_list * args)
12049 {
12050   u8 *a = va_arg (*args, u8 *);
12051
12052   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12053                  a[2], a[3], a[4], a[5], a[6], a[7]);
12054 }
12055
12056 static void vl_api_l2_fib_table_details_t_handler
12057   (vl_api_l2_fib_table_details_t * mp)
12058 {
12059   vat_main_t *vam = &vat_main;
12060
12061   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12062          "       %d       %d     %d",
12063          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12064          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12065          mp->bvi_mac);
12066 }
12067
12068 static void vl_api_l2_fib_table_details_t_handler_json
12069   (vl_api_l2_fib_table_details_t * mp)
12070 {
12071   vat_main_t *vam = &vat_main;
12072   vat_json_node_t *node = NULL;
12073
12074   if (VAT_JSON_ARRAY != vam->json_tree.type)
12075     {
12076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12077       vat_json_init_array (&vam->json_tree);
12078     }
12079   node = vat_json_array_add (&vam->json_tree);
12080
12081   vat_json_init_object (node);
12082   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12083   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12084   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12085   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12086   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12087   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12088 }
12089
12090 static int
12091 api_l2_fib_table_dump (vat_main_t * vam)
12092 {
12093   unformat_input_t *i = vam->input;
12094   vl_api_l2_fib_table_dump_t *mp;
12095   vl_api_control_ping_t *mp_ping;
12096   u32 bd_id;
12097   u8 bd_id_set = 0;
12098   int ret;
12099
12100   /* Parse args required to build the message */
12101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12102     {
12103       if (unformat (i, "bd_id %d", &bd_id))
12104         bd_id_set = 1;
12105       else
12106         break;
12107     }
12108
12109   if (bd_id_set == 0)
12110     {
12111       errmsg ("missing bridge domain");
12112       return -99;
12113     }
12114
12115   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12116
12117   /* Get list of l2 fib entries */
12118   M (L2_FIB_TABLE_DUMP, mp);
12119
12120   mp->bd_id = ntohl (bd_id);
12121   S (mp);
12122
12123   /* Use a control ping for synchronization */
12124   M (CONTROL_PING, mp_ping);
12125   S (mp_ping);
12126
12127   W (ret);
12128   return ret;
12129 }
12130
12131
12132 static int
12133 api_interface_name_renumber (vat_main_t * vam)
12134 {
12135   unformat_input_t *line_input = vam->input;
12136   vl_api_interface_name_renumber_t *mp;
12137   u32 sw_if_index = ~0;
12138   u32 new_show_dev_instance = ~0;
12139   int ret;
12140
12141   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12142     {
12143       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12144                     &sw_if_index))
12145         ;
12146       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12147         ;
12148       else if (unformat (line_input, "new_show_dev_instance %d",
12149                          &new_show_dev_instance))
12150         ;
12151       else
12152         break;
12153     }
12154
12155   if (sw_if_index == ~0)
12156     {
12157       errmsg ("missing interface name or sw_if_index");
12158       return -99;
12159     }
12160
12161   if (new_show_dev_instance == ~0)
12162     {
12163       errmsg ("missing new_show_dev_instance");
12164       return -99;
12165     }
12166
12167   M (INTERFACE_NAME_RENUMBER, mp);
12168
12169   mp->sw_if_index = ntohl (sw_if_index);
12170   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12171
12172   S (mp);
12173   W (ret);
12174   return ret;
12175 }
12176
12177 static int
12178 api_want_ip4_arp_events (vat_main_t * vam)
12179 {
12180   unformat_input_t *line_input = vam->input;
12181   vl_api_want_ip4_arp_events_t *mp;
12182   ip4_address_t address;
12183   int address_set = 0;
12184   u32 enable_disable = 1;
12185   int ret;
12186
12187   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12188     {
12189       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12190         address_set = 1;
12191       else if (unformat (line_input, "del"))
12192         enable_disable = 0;
12193       else
12194         break;
12195     }
12196
12197   if (address_set == 0)
12198     {
12199       errmsg ("missing addresses");
12200       return -99;
12201     }
12202
12203   M (WANT_IP4_ARP_EVENTS, mp);
12204   mp->enable_disable = enable_disable;
12205   mp->pid = htonl (getpid ());
12206   mp->address = address.as_u32;
12207
12208   S (mp);
12209   W (ret);
12210   return ret;
12211 }
12212
12213 static int
12214 api_want_ip6_nd_events (vat_main_t * vam)
12215 {
12216   unformat_input_t *line_input = vam->input;
12217   vl_api_want_ip6_nd_events_t *mp;
12218   ip6_address_t address;
12219   int address_set = 0;
12220   u32 enable_disable = 1;
12221   int ret;
12222
12223   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12224     {
12225       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12226         address_set = 1;
12227       else if (unformat (line_input, "del"))
12228         enable_disable = 0;
12229       else
12230         break;
12231     }
12232
12233   if (address_set == 0)
12234     {
12235       errmsg ("missing addresses");
12236       return -99;
12237     }
12238
12239   M (WANT_IP6_ND_EVENTS, mp);
12240   mp->enable_disable = enable_disable;
12241   mp->pid = htonl (getpid ());
12242   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12243
12244   S (mp);
12245   W (ret);
12246   return ret;
12247 }
12248
12249 static int
12250 api_input_acl_set_interface (vat_main_t * vam)
12251 {
12252   unformat_input_t *i = vam->input;
12253   vl_api_input_acl_set_interface_t *mp;
12254   u32 sw_if_index;
12255   int sw_if_index_set;
12256   u32 ip4_table_index = ~0;
12257   u32 ip6_table_index = ~0;
12258   u32 l2_table_index = ~0;
12259   u8 is_add = 1;
12260   int ret;
12261
12262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12263     {
12264       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12265         sw_if_index_set = 1;
12266       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12267         sw_if_index_set = 1;
12268       else if (unformat (i, "del"))
12269         is_add = 0;
12270       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12271         ;
12272       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12273         ;
12274       else if (unformat (i, "l2-table %d", &l2_table_index))
12275         ;
12276       else
12277         {
12278           clib_warning ("parse error '%U'", format_unformat_error, i);
12279           return -99;
12280         }
12281     }
12282
12283   if (sw_if_index_set == 0)
12284     {
12285       errmsg ("missing interface name or sw_if_index");
12286       return -99;
12287     }
12288
12289   M (INPUT_ACL_SET_INTERFACE, mp);
12290
12291   mp->sw_if_index = ntohl (sw_if_index);
12292   mp->ip4_table_index = ntohl (ip4_table_index);
12293   mp->ip6_table_index = ntohl (ip6_table_index);
12294   mp->l2_table_index = ntohl (l2_table_index);
12295   mp->is_add = is_add;
12296
12297   S (mp);
12298   W (ret);
12299   return ret;
12300 }
12301
12302 static int
12303 api_ip_address_dump (vat_main_t * vam)
12304 {
12305   unformat_input_t *i = vam->input;
12306   vl_api_ip_address_dump_t *mp;
12307   vl_api_control_ping_t *mp_ping;
12308   u32 sw_if_index = ~0;
12309   u8 sw_if_index_set = 0;
12310   u8 ipv4_set = 0;
12311   u8 ipv6_set = 0;
12312   int ret;
12313
12314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12315     {
12316       if (unformat (i, "sw_if_index %d", &sw_if_index))
12317         sw_if_index_set = 1;
12318       else
12319         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12320         sw_if_index_set = 1;
12321       else if (unformat (i, "ipv4"))
12322         ipv4_set = 1;
12323       else if (unformat (i, "ipv6"))
12324         ipv6_set = 1;
12325       else
12326         break;
12327     }
12328
12329   if (ipv4_set && ipv6_set)
12330     {
12331       errmsg ("ipv4 and ipv6 flags cannot be both set");
12332       return -99;
12333     }
12334
12335   if ((!ipv4_set) && (!ipv6_set))
12336     {
12337       errmsg ("no ipv4 nor ipv6 flag set");
12338       return -99;
12339     }
12340
12341   if (sw_if_index_set == 0)
12342     {
12343       errmsg ("missing interface name or sw_if_index");
12344       return -99;
12345     }
12346
12347   vam->current_sw_if_index = sw_if_index;
12348   vam->is_ipv6 = ipv6_set;
12349
12350   M (IP_ADDRESS_DUMP, mp);
12351   mp->sw_if_index = ntohl (sw_if_index);
12352   mp->is_ipv6 = ipv6_set;
12353   S (mp);
12354
12355   /* Use a control ping for synchronization */
12356   M (CONTROL_PING, mp_ping);
12357   S (mp_ping);
12358
12359   W (ret);
12360   return ret;
12361 }
12362
12363 static int
12364 api_ip_dump (vat_main_t * vam)
12365 {
12366   vl_api_ip_dump_t *mp;
12367   vl_api_control_ping_t *mp_ping;
12368   unformat_input_t *in = vam->input;
12369   int ipv4_set = 0;
12370   int ipv6_set = 0;
12371   int is_ipv6;
12372   int i;
12373   int ret;
12374
12375   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12376     {
12377       if (unformat (in, "ipv4"))
12378         ipv4_set = 1;
12379       else if (unformat (in, "ipv6"))
12380         ipv6_set = 1;
12381       else
12382         break;
12383     }
12384
12385   if (ipv4_set && ipv6_set)
12386     {
12387       errmsg ("ipv4 and ipv6 flags cannot be both set");
12388       return -99;
12389     }
12390
12391   if ((!ipv4_set) && (!ipv6_set))
12392     {
12393       errmsg ("no ipv4 nor ipv6 flag set");
12394       return -99;
12395     }
12396
12397   is_ipv6 = ipv6_set;
12398   vam->is_ipv6 = is_ipv6;
12399
12400   /* free old data */
12401   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12402     {
12403       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12404     }
12405   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12406
12407   M (IP_DUMP, mp);
12408   mp->is_ipv6 = ipv6_set;
12409   S (mp);
12410
12411   /* Use a control ping for synchronization */
12412   M (CONTROL_PING, mp_ping);
12413   S (mp_ping);
12414
12415   W (ret);
12416   return ret;
12417 }
12418
12419 static int
12420 api_ipsec_spd_add_del (vat_main_t * vam)
12421 {
12422   unformat_input_t *i = vam->input;
12423   vl_api_ipsec_spd_add_del_t *mp;
12424   u32 spd_id = ~0;
12425   u8 is_add = 1;
12426   int ret;
12427
12428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12429     {
12430       if (unformat (i, "spd_id %d", &spd_id))
12431         ;
12432       else if (unformat (i, "del"))
12433         is_add = 0;
12434       else
12435         {
12436           clib_warning ("parse error '%U'", format_unformat_error, i);
12437           return -99;
12438         }
12439     }
12440   if (spd_id == ~0)
12441     {
12442       errmsg ("spd_id must be set");
12443       return -99;
12444     }
12445
12446   M (IPSEC_SPD_ADD_DEL, mp);
12447
12448   mp->spd_id = ntohl (spd_id);
12449   mp->is_add = is_add;
12450
12451   S (mp);
12452   W (ret);
12453   return ret;
12454 }
12455
12456 static int
12457 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12458 {
12459   unformat_input_t *i = vam->input;
12460   vl_api_ipsec_interface_add_del_spd_t *mp;
12461   u32 sw_if_index;
12462   u8 sw_if_index_set = 0;
12463   u32 spd_id = (u32) ~ 0;
12464   u8 is_add = 1;
12465   int ret;
12466
12467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12468     {
12469       if (unformat (i, "del"))
12470         is_add = 0;
12471       else if (unformat (i, "spd_id %d", &spd_id))
12472         ;
12473       else
12474         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12475         sw_if_index_set = 1;
12476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12477         sw_if_index_set = 1;
12478       else
12479         {
12480           clib_warning ("parse error '%U'", format_unformat_error, i);
12481           return -99;
12482         }
12483
12484     }
12485
12486   if (spd_id == (u32) ~ 0)
12487     {
12488       errmsg ("spd_id must be set");
12489       return -99;
12490     }
12491
12492   if (sw_if_index_set == 0)
12493     {
12494       errmsg ("missing interface name or sw_if_index");
12495       return -99;
12496     }
12497
12498   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12499
12500   mp->spd_id = ntohl (spd_id);
12501   mp->sw_if_index = ntohl (sw_if_index);
12502   mp->is_add = is_add;
12503
12504   S (mp);
12505   W (ret);
12506   return ret;
12507 }
12508
12509 static int
12510 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12511 {
12512   unformat_input_t *i = vam->input;
12513   vl_api_ipsec_spd_add_del_entry_t *mp;
12514   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12515   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12516   i32 priority = 0;
12517   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12518   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12519   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12520   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12521   int ret;
12522
12523   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12524   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12525   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12526   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12527   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12528   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12529
12530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12531     {
12532       if (unformat (i, "del"))
12533         is_add = 0;
12534       if (unformat (i, "outbound"))
12535         is_outbound = 1;
12536       if (unformat (i, "inbound"))
12537         is_outbound = 0;
12538       else if (unformat (i, "spd_id %d", &spd_id))
12539         ;
12540       else if (unformat (i, "sa_id %d", &sa_id))
12541         ;
12542       else if (unformat (i, "priority %d", &priority))
12543         ;
12544       else if (unformat (i, "protocol %d", &protocol))
12545         ;
12546       else if (unformat (i, "lport_start %d", &lport_start))
12547         ;
12548       else if (unformat (i, "lport_stop %d", &lport_stop))
12549         ;
12550       else if (unformat (i, "rport_start %d", &rport_start))
12551         ;
12552       else if (unformat (i, "rport_stop %d", &rport_stop))
12553         ;
12554       else
12555         if (unformat
12556             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12557         {
12558           is_ipv6 = 0;
12559           is_ip_any = 0;
12560         }
12561       else
12562         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12563         {
12564           is_ipv6 = 0;
12565           is_ip_any = 0;
12566         }
12567       else
12568         if (unformat
12569             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12570         {
12571           is_ipv6 = 0;
12572           is_ip_any = 0;
12573         }
12574       else
12575         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12576         {
12577           is_ipv6 = 0;
12578           is_ip_any = 0;
12579         }
12580       else
12581         if (unformat
12582             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12583         {
12584           is_ipv6 = 1;
12585           is_ip_any = 0;
12586         }
12587       else
12588         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12589         {
12590           is_ipv6 = 1;
12591           is_ip_any = 0;
12592         }
12593       else
12594         if (unformat
12595             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12596         {
12597           is_ipv6 = 1;
12598           is_ip_any = 0;
12599         }
12600       else
12601         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12602         {
12603           is_ipv6 = 1;
12604           is_ip_any = 0;
12605         }
12606       else
12607         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12608         {
12609           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12610             {
12611               clib_warning ("unsupported action: 'resolve'");
12612               return -99;
12613             }
12614         }
12615       else
12616         {
12617           clib_warning ("parse error '%U'", format_unformat_error, i);
12618           return -99;
12619         }
12620
12621     }
12622
12623   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12624
12625   mp->spd_id = ntohl (spd_id);
12626   mp->priority = ntohl (priority);
12627   mp->is_outbound = is_outbound;
12628
12629   mp->is_ipv6 = is_ipv6;
12630   if (is_ipv6 || is_ip_any)
12631     {
12632       clib_memcpy (mp->remote_address_start, &raddr6_start,
12633                    sizeof (ip6_address_t));
12634       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12635                    sizeof (ip6_address_t));
12636       clib_memcpy (mp->local_address_start, &laddr6_start,
12637                    sizeof (ip6_address_t));
12638       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12639                    sizeof (ip6_address_t));
12640     }
12641   else
12642     {
12643       clib_memcpy (mp->remote_address_start, &raddr4_start,
12644                    sizeof (ip4_address_t));
12645       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12646                    sizeof (ip4_address_t));
12647       clib_memcpy (mp->local_address_start, &laddr4_start,
12648                    sizeof (ip4_address_t));
12649       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12650                    sizeof (ip4_address_t));
12651     }
12652   mp->protocol = (u8) protocol;
12653   mp->local_port_start = ntohs ((u16) lport_start);
12654   mp->local_port_stop = ntohs ((u16) lport_stop);
12655   mp->remote_port_start = ntohs ((u16) rport_start);
12656   mp->remote_port_stop = ntohs ((u16) rport_stop);
12657   mp->policy = (u8) policy;
12658   mp->sa_id = ntohl (sa_id);
12659   mp->is_add = is_add;
12660   mp->is_ip_any = is_ip_any;
12661   S (mp);
12662   W (ret);
12663   return ret;
12664 }
12665
12666 static int
12667 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12668 {
12669   unformat_input_t *i = vam->input;
12670   vl_api_ipsec_sad_add_del_entry_t *mp;
12671   u32 sad_id = 0, spi = 0;
12672   u8 *ck = 0, *ik = 0;
12673   u8 is_add = 1;
12674
12675   u8 protocol = IPSEC_PROTOCOL_AH;
12676   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12677   u32 crypto_alg = 0, integ_alg = 0;
12678   ip4_address_t tun_src4;
12679   ip4_address_t tun_dst4;
12680   ip6_address_t tun_src6;
12681   ip6_address_t tun_dst6;
12682   int ret;
12683
12684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12685     {
12686       if (unformat (i, "del"))
12687         is_add = 0;
12688       else if (unformat (i, "sad_id %d", &sad_id))
12689         ;
12690       else if (unformat (i, "spi %d", &spi))
12691         ;
12692       else if (unformat (i, "esp"))
12693         protocol = IPSEC_PROTOCOL_ESP;
12694       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12695         {
12696           is_tunnel = 1;
12697           is_tunnel_ipv6 = 0;
12698         }
12699       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12700         {
12701           is_tunnel = 1;
12702           is_tunnel_ipv6 = 0;
12703         }
12704       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12705         {
12706           is_tunnel = 1;
12707           is_tunnel_ipv6 = 1;
12708         }
12709       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12710         {
12711           is_tunnel = 1;
12712           is_tunnel_ipv6 = 1;
12713         }
12714       else
12715         if (unformat
12716             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12717         {
12718           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12719               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12720             {
12721               clib_warning ("unsupported crypto-alg: '%U'",
12722                             format_ipsec_crypto_alg, crypto_alg);
12723               return -99;
12724             }
12725         }
12726       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12727         ;
12728       else
12729         if (unformat
12730             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12731         {
12732           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12733               integ_alg >= IPSEC_INTEG_N_ALG)
12734             {
12735               clib_warning ("unsupported integ-alg: '%U'",
12736                             format_ipsec_integ_alg, integ_alg);
12737               return -99;
12738             }
12739         }
12740       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12741         ;
12742       else
12743         {
12744           clib_warning ("parse error '%U'", format_unformat_error, i);
12745           return -99;
12746         }
12747
12748     }
12749
12750   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12751
12752   mp->sad_id = ntohl (sad_id);
12753   mp->is_add = is_add;
12754   mp->protocol = protocol;
12755   mp->spi = ntohl (spi);
12756   mp->is_tunnel = is_tunnel;
12757   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12758   mp->crypto_algorithm = crypto_alg;
12759   mp->integrity_algorithm = integ_alg;
12760   mp->crypto_key_length = vec_len (ck);
12761   mp->integrity_key_length = vec_len (ik);
12762
12763   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12764     mp->crypto_key_length = sizeof (mp->crypto_key);
12765
12766   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12767     mp->integrity_key_length = sizeof (mp->integrity_key);
12768
12769   if (ck)
12770     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12771   if (ik)
12772     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12773
12774   if (is_tunnel)
12775     {
12776       if (is_tunnel_ipv6)
12777         {
12778           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12779                        sizeof (ip6_address_t));
12780           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12781                        sizeof (ip6_address_t));
12782         }
12783       else
12784         {
12785           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12786                        sizeof (ip4_address_t));
12787           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12788                        sizeof (ip4_address_t));
12789         }
12790     }
12791
12792   S (mp);
12793   W (ret);
12794   return ret;
12795 }
12796
12797 static int
12798 api_ipsec_sa_set_key (vat_main_t * vam)
12799 {
12800   unformat_input_t *i = vam->input;
12801   vl_api_ipsec_sa_set_key_t *mp;
12802   u32 sa_id;
12803   u8 *ck = 0, *ik = 0;
12804   int ret;
12805
12806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12807     {
12808       if (unformat (i, "sa_id %d", &sa_id))
12809         ;
12810       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12811         ;
12812       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12813         ;
12814       else
12815         {
12816           clib_warning ("parse error '%U'", format_unformat_error, i);
12817           return -99;
12818         }
12819     }
12820
12821   M (IPSEC_SA_SET_KEY, mp);
12822
12823   mp->sa_id = ntohl (sa_id);
12824   mp->crypto_key_length = vec_len (ck);
12825   mp->integrity_key_length = vec_len (ik);
12826
12827   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12828     mp->crypto_key_length = sizeof (mp->crypto_key);
12829
12830   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12831     mp->integrity_key_length = sizeof (mp->integrity_key);
12832
12833   if (ck)
12834     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12835   if (ik)
12836     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12837
12838   S (mp);
12839   W (ret);
12840   return ret;
12841 }
12842
12843 static int
12844 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12845 {
12846   unformat_input_t *i = vam->input;
12847   vl_api_ipsec_tunnel_if_add_del_t *mp;
12848   u32 local_spi = 0, remote_spi = 0;
12849   u32 crypto_alg = 0, integ_alg = 0;
12850   u8 *lck = NULL, *rck = NULL;
12851   u8 *lik = NULL, *rik = NULL;
12852   ip4_address_t local_ip = { {0} };
12853   ip4_address_t remote_ip = { {0} };
12854   u8 is_add = 1;
12855   u8 esn = 0;
12856   u8 anti_replay = 0;
12857   int ret;
12858
12859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12860     {
12861       if (unformat (i, "del"))
12862         is_add = 0;
12863       else if (unformat (i, "esn"))
12864         esn = 1;
12865       else if (unformat (i, "anti_replay"))
12866         anti_replay = 1;
12867       else if (unformat (i, "local_spi %d", &local_spi))
12868         ;
12869       else if (unformat (i, "remote_spi %d", &remote_spi))
12870         ;
12871       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12872         ;
12873       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12874         ;
12875       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12876         ;
12877       else
12878         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12879         ;
12880       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12881         ;
12882       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12883         ;
12884       else
12885         if (unformat
12886             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12887         {
12888           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12889               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12890             {
12891               errmsg ("unsupported crypto-alg: '%U'\n",
12892                       format_ipsec_crypto_alg, crypto_alg);
12893               return -99;
12894             }
12895         }
12896       else
12897         if (unformat
12898             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12899         {
12900           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12901               integ_alg >= IPSEC_INTEG_N_ALG)
12902             {
12903               errmsg ("unsupported integ-alg: '%U'\n",
12904                       format_ipsec_integ_alg, integ_alg);
12905               return -99;
12906             }
12907         }
12908       else
12909         {
12910           errmsg ("parse error '%U'\n", format_unformat_error, i);
12911           return -99;
12912         }
12913     }
12914
12915   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12916
12917   mp->is_add = is_add;
12918   mp->esn = esn;
12919   mp->anti_replay = anti_replay;
12920
12921   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12922   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12923
12924   mp->local_spi = htonl (local_spi);
12925   mp->remote_spi = htonl (remote_spi);
12926   mp->crypto_alg = (u8) crypto_alg;
12927
12928   mp->local_crypto_key_len = 0;
12929   if (lck)
12930     {
12931       mp->local_crypto_key_len = vec_len (lck);
12932       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12933         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12934       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12935     }
12936
12937   mp->remote_crypto_key_len = 0;
12938   if (rck)
12939     {
12940       mp->remote_crypto_key_len = vec_len (rck);
12941       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12942         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12943       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12944     }
12945
12946   mp->integ_alg = (u8) integ_alg;
12947
12948   mp->local_integ_key_len = 0;
12949   if (lik)
12950     {
12951       mp->local_integ_key_len = vec_len (lik);
12952       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12953         mp->local_integ_key_len = sizeof (mp->local_integ_key);
12954       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12955     }
12956
12957   mp->remote_integ_key_len = 0;
12958   if (rik)
12959     {
12960       mp->remote_integ_key_len = vec_len (rik);
12961       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12962         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12963       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12964     }
12965
12966   S (mp);
12967   W (ret);
12968   return ret;
12969 }
12970
12971 static int
12972 api_ikev2_profile_add_del (vat_main_t * vam)
12973 {
12974   unformat_input_t *i = vam->input;
12975   vl_api_ikev2_profile_add_del_t *mp;
12976   u8 is_add = 1;
12977   u8 *name = 0;
12978   int ret;
12979
12980   const char *valid_chars = "a-zA-Z0-9_";
12981
12982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12983     {
12984       if (unformat (i, "del"))
12985         is_add = 0;
12986       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12987         vec_add1 (name, 0);
12988       else
12989         {
12990           errmsg ("parse error '%U'", format_unformat_error, i);
12991           return -99;
12992         }
12993     }
12994
12995   if (!vec_len (name))
12996     {
12997       errmsg ("profile name must be specified");
12998       return -99;
12999     }
13000
13001   if (vec_len (name) > 64)
13002     {
13003       errmsg ("profile name too long");
13004       return -99;
13005     }
13006
13007   M (IKEV2_PROFILE_ADD_DEL, mp);
13008
13009   clib_memcpy (mp->name, name, vec_len (name));
13010   mp->is_add = is_add;
13011   vec_free (name);
13012
13013   S (mp);
13014   W (ret);
13015   return ret;
13016 }
13017
13018 static int
13019 api_ikev2_profile_set_auth (vat_main_t * vam)
13020 {
13021   unformat_input_t *i = vam->input;
13022   vl_api_ikev2_profile_set_auth_t *mp;
13023   u8 *name = 0;
13024   u8 *data = 0;
13025   u32 auth_method = 0;
13026   u8 is_hex = 0;
13027   int ret;
13028
13029   const char *valid_chars = "a-zA-Z0-9_";
13030
13031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13032     {
13033       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13034         vec_add1 (name, 0);
13035       else if (unformat (i, "auth_method %U",
13036                          unformat_ikev2_auth_method, &auth_method))
13037         ;
13038       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13039         is_hex = 1;
13040       else if (unformat (i, "auth_data %v", &data))
13041         ;
13042       else
13043         {
13044           errmsg ("parse error '%U'", format_unformat_error, i);
13045           return -99;
13046         }
13047     }
13048
13049   if (!vec_len (name))
13050     {
13051       errmsg ("profile name must be specified");
13052       return -99;
13053     }
13054
13055   if (vec_len (name) > 64)
13056     {
13057       errmsg ("profile name too long");
13058       return -99;
13059     }
13060
13061   if (!vec_len (data))
13062     {
13063       errmsg ("auth_data must be specified");
13064       return -99;
13065     }
13066
13067   if (!auth_method)
13068     {
13069       errmsg ("auth_method must be specified");
13070       return -99;
13071     }
13072
13073   M (IKEV2_PROFILE_SET_AUTH, mp);
13074
13075   mp->is_hex = is_hex;
13076   mp->auth_method = (u8) auth_method;
13077   mp->data_len = vec_len (data);
13078   clib_memcpy (mp->name, name, vec_len (name));
13079   clib_memcpy (mp->data, data, vec_len (data));
13080   vec_free (name);
13081   vec_free (data);
13082
13083   S (mp);
13084   W (ret);
13085   return ret;
13086 }
13087
13088 static int
13089 api_ikev2_profile_set_id (vat_main_t * vam)
13090 {
13091   unformat_input_t *i = vam->input;
13092   vl_api_ikev2_profile_set_id_t *mp;
13093   u8 *name = 0;
13094   u8 *data = 0;
13095   u8 is_local = 0;
13096   u32 id_type = 0;
13097   ip4_address_t ip4;
13098   int ret;
13099
13100   const char *valid_chars = "a-zA-Z0-9_";
13101
13102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13103     {
13104       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13105         vec_add1 (name, 0);
13106       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13107         ;
13108       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13109         {
13110           data = vec_new (u8, 4);
13111           clib_memcpy (data, ip4.as_u8, 4);
13112         }
13113       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13114         ;
13115       else if (unformat (i, "id_data %v", &data))
13116         ;
13117       else if (unformat (i, "local"))
13118         is_local = 1;
13119       else if (unformat (i, "remote"))
13120         is_local = 0;
13121       else
13122         {
13123           errmsg ("parse error '%U'", format_unformat_error, i);
13124           return -99;
13125         }
13126     }
13127
13128   if (!vec_len (name))
13129     {
13130       errmsg ("profile name must be specified");
13131       return -99;
13132     }
13133
13134   if (vec_len (name) > 64)
13135     {
13136       errmsg ("profile name too long");
13137       return -99;
13138     }
13139
13140   if (!vec_len (data))
13141     {
13142       errmsg ("id_data must be specified");
13143       return -99;
13144     }
13145
13146   if (!id_type)
13147     {
13148       errmsg ("id_type must be specified");
13149       return -99;
13150     }
13151
13152   M (IKEV2_PROFILE_SET_ID, mp);
13153
13154   mp->is_local = is_local;
13155   mp->id_type = (u8) id_type;
13156   mp->data_len = vec_len (data);
13157   clib_memcpy (mp->name, name, vec_len (name));
13158   clib_memcpy (mp->data, data, vec_len (data));
13159   vec_free (name);
13160   vec_free (data);
13161
13162   S (mp);
13163   W (ret);
13164   return ret;
13165 }
13166
13167 static int
13168 api_ikev2_profile_set_ts (vat_main_t * vam)
13169 {
13170   unformat_input_t *i = vam->input;
13171   vl_api_ikev2_profile_set_ts_t *mp;
13172   u8 *name = 0;
13173   u8 is_local = 0;
13174   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13175   ip4_address_t start_addr, end_addr;
13176
13177   const char *valid_chars = "a-zA-Z0-9_";
13178   int ret;
13179
13180   start_addr.as_u32 = 0;
13181   end_addr.as_u32 = (u32) ~ 0;
13182
13183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13184     {
13185       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13186         vec_add1 (name, 0);
13187       else if (unformat (i, "protocol %d", &proto))
13188         ;
13189       else if (unformat (i, "start_port %d", &start_port))
13190         ;
13191       else if (unformat (i, "end_port %d", &end_port))
13192         ;
13193       else
13194         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13195         ;
13196       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13197         ;
13198       else if (unformat (i, "local"))
13199         is_local = 1;
13200       else if (unformat (i, "remote"))
13201         is_local = 0;
13202       else
13203         {
13204           errmsg ("parse error '%U'", format_unformat_error, i);
13205           return -99;
13206         }
13207     }
13208
13209   if (!vec_len (name))
13210     {
13211       errmsg ("profile name must be specified");
13212       return -99;
13213     }
13214
13215   if (vec_len (name) > 64)
13216     {
13217       errmsg ("profile name too long");
13218       return -99;
13219     }
13220
13221   M (IKEV2_PROFILE_SET_TS, mp);
13222
13223   mp->is_local = is_local;
13224   mp->proto = (u8) proto;
13225   mp->start_port = (u16) start_port;
13226   mp->end_port = (u16) end_port;
13227   mp->start_addr = start_addr.as_u32;
13228   mp->end_addr = end_addr.as_u32;
13229   clib_memcpy (mp->name, name, vec_len (name));
13230   vec_free (name);
13231
13232   S (mp);
13233   W (ret);
13234   return ret;
13235 }
13236
13237 static int
13238 api_ikev2_set_local_key (vat_main_t * vam)
13239 {
13240   unformat_input_t *i = vam->input;
13241   vl_api_ikev2_set_local_key_t *mp;
13242   u8 *file = 0;
13243   int ret;
13244
13245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13246     {
13247       if (unformat (i, "file %v", &file))
13248         vec_add1 (file, 0);
13249       else
13250         {
13251           errmsg ("parse error '%U'", format_unformat_error, i);
13252           return -99;
13253         }
13254     }
13255
13256   if (!vec_len (file))
13257     {
13258       errmsg ("RSA key file must be specified");
13259       return -99;
13260     }
13261
13262   if (vec_len (file) > 256)
13263     {
13264       errmsg ("file name too long");
13265       return -99;
13266     }
13267
13268   M (IKEV2_SET_LOCAL_KEY, mp);
13269
13270   clib_memcpy (mp->key_file, file, vec_len (file));
13271   vec_free (file);
13272
13273   S (mp);
13274   W (ret);
13275   return ret;
13276 }
13277
13278 static int
13279 api_ikev2_set_responder (vat_main_t * vam)
13280 {
13281   unformat_input_t *i = vam->input;
13282   vl_api_ikev2_set_responder_t *mp;
13283   int ret;
13284   u8 *name = 0;
13285   u32 sw_if_index = ~0;
13286   ip4_address_t address;
13287
13288   const char *valid_chars = "a-zA-Z0-9_";
13289
13290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13291     {
13292       if (unformat
13293           (i, "%U interface %d address %U", unformat_token, valid_chars,
13294            &name, &sw_if_index, unformat_ip4_address, &address))
13295         vec_add1 (name, 0);
13296       else
13297         {
13298           errmsg ("parse error '%U'", format_unformat_error, i);
13299           return -99;
13300         }
13301     }
13302
13303   if (!vec_len (name))
13304     {
13305       errmsg ("profile name must be specified");
13306       return -99;
13307     }
13308
13309   if (vec_len (name) > 64)
13310     {
13311       errmsg ("profile name too long");
13312       return -99;
13313     }
13314
13315   M (IKEV2_SET_RESPONDER, mp);
13316
13317   clib_memcpy (mp->name, name, vec_len (name));
13318   vec_free (name);
13319
13320   mp->sw_if_index = sw_if_index;
13321   clib_memcpy (mp->address, &address, sizeof (address));
13322
13323   S (mp);
13324   W (ret);
13325   return ret;
13326 }
13327
13328 static int
13329 api_ikev2_set_ike_transforms (vat_main_t * vam)
13330 {
13331   unformat_input_t *i = vam->input;
13332   vl_api_ikev2_set_ike_transforms_t *mp;
13333   int ret;
13334   u8 *name = 0;
13335   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13336
13337   const char *valid_chars = "a-zA-Z0-9_";
13338
13339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13340     {
13341       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13342                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13343         vec_add1 (name, 0);
13344       else
13345         {
13346           errmsg ("parse error '%U'", format_unformat_error, i);
13347           return -99;
13348         }
13349     }
13350
13351   if (!vec_len (name))
13352     {
13353       errmsg ("profile name must be specified");
13354       return -99;
13355     }
13356
13357   if (vec_len (name) > 64)
13358     {
13359       errmsg ("profile name too long");
13360       return -99;
13361     }
13362
13363   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13364
13365   clib_memcpy (mp->name, name, vec_len (name));
13366   vec_free (name);
13367   mp->crypto_alg = crypto_alg;
13368   mp->crypto_key_size = crypto_key_size;
13369   mp->integ_alg = integ_alg;
13370   mp->dh_group = dh_group;
13371
13372   S (mp);
13373   W (ret);
13374   return ret;
13375 }
13376
13377
13378 static int
13379 api_ikev2_set_esp_transforms (vat_main_t * vam)
13380 {
13381   unformat_input_t *i = vam->input;
13382   vl_api_ikev2_set_esp_transforms_t *mp;
13383   int ret;
13384   u8 *name = 0;
13385   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13386
13387   const char *valid_chars = "a-zA-Z0-9_";
13388
13389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13390     {
13391       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13392                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13393         vec_add1 (name, 0);
13394       else
13395         {
13396           errmsg ("parse error '%U'", format_unformat_error, i);
13397           return -99;
13398         }
13399     }
13400
13401   if (!vec_len (name))
13402     {
13403       errmsg ("profile name must be specified");
13404       return -99;
13405     }
13406
13407   if (vec_len (name) > 64)
13408     {
13409       errmsg ("profile name too long");
13410       return -99;
13411     }
13412
13413   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13414
13415   clib_memcpy (mp->name, name, vec_len (name));
13416   vec_free (name);
13417   mp->crypto_alg = crypto_alg;
13418   mp->crypto_key_size = crypto_key_size;
13419   mp->integ_alg = integ_alg;
13420   mp->dh_group = dh_group;
13421
13422   S (mp);
13423   W (ret);
13424   return ret;
13425 }
13426
13427 static int
13428 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13429 {
13430   unformat_input_t *i = vam->input;
13431   vl_api_ikev2_set_sa_lifetime_t *mp;
13432   int ret;
13433   u8 *name = 0;
13434   u64 lifetime, lifetime_maxdata;
13435   u32 lifetime_jitter, handover;
13436
13437   const char *valid_chars = "a-zA-Z0-9_";
13438
13439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13440     {
13441       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13442                     &lifetime, &lifetime_jitter, &handover,
13443                     &lifetime_maxdata))
13444         vec_add1 (name, 0);
13445       else
13446         {
13447           errmsg ("parse error '%U'", format_unformat_error, i);
13448           return -99;
13449         }
13450     }
13451
13452   if (!vec_len (name))
13453     {
13454       errmsg ("profile name must be specified");
13455       return -99;
13456     }
13457
13458   if (vec_len (name) > 64)
13459     {
13460       errmsg ("profile name too long");
13461       return -99;
13462     }
13463
13464   M (IKEV2_SET_SA_LIFETIME, mp);
13465
13466   clib_memcpy (mp->name, name, vec_len (name));
13467   vec_free (name);
13468   mp->lifetime = lifetime;
13469   mp->lifetime_jitter = lifetime_jitter;
13470   mp->handover = handover;
13471   mp->lifetime_maxdata = lifetime_maxdata;
13472
13473   S (mp);
13474   W (ret);
13475   return ret;
13476 }
13477
13478 static int
13479 api_ikev2_initiate_sa_init (vat_main_t * vam)
13480 {
13481   unformat_input_t *i = vam->input;
13482   vl_api_ikev2_initiate_sa_init_t *mp;
13483   int ret;
13484   u8 *name = 0;
13485
13486   const char *valid_chars = "a-zA-Z0-9_";
13487
13488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13489     {
13490       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13491         vec_add1 (name, 0);
13492       else
13493         {
13494           errmsg ("parse error '%U'", format_unformat_error, i);
13495           return -99;
13496         }
13497     }
13498
13499   if (!vec_len (name))
13500     {
13501       errmsg ("profile name must be specified");
13502       return -99;
13503     }
13504
13505   if (vec_len (name) > 64)
13506     {
13507       errmsg ("profile name too long");
13508       return -99;
13509     }
13510
13511   M (IKEV2_INITIATE_SA_INIT, mp);
13512
13513   clib_memcpy (mp->name, name, vec_len (name));
13514   vec_free (name);
13515
13516   S (mp);
13517   W (ret);
13518   return ret;
13519 }
13520
13521 static int
13522 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13523 {
13524   unformat_input_t *i = vam->input;
13525   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13526   int ret;
13527   u64 ispi;
13528
13529
13530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13531     {
13532       if (unformat (i, "%lx", &ispi))
13533         ;
13534       else
13535         {
13536           errmsg ("parse error '%U'", format_unformat_error, i);
13537           return -99;
13538         }
13539     }
13540
13541   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13542
13543   mp->ispi = ispi;
13544
13545   S (mp);
13546   W (ret);
13547   return ret;
13548 }
13549
13550 static int
13551 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13552 {
13553   unformat_input_t *i = vam->input;
13554   vl_api_ikev2_initiate_del_child_sa_t *mp;
13555   int ret;
13556   u32 ispi;
13557
13558
13559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13560     {
13561       if (unformat (i, "%x", &ispi))
13562         ;
13563       else
13564         {
13565           errmsg ("parse error '%U'", format_unformat_error, i);
13566           return -99;
13567         }
13568     }
13569
13570   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13571
13572   mp->ispi = ispi;
13573
13574   S (mp);
13575   W (ret);
13576   return ret;
13577 }
13578
13579 static int
13580 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13581 {
13582   unformat_input_t *i = vam->input;
13583   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13584   int ret;
13585   u32 ispi;
13586
13587
13588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13589     {
13590       if (unformat (i, "%x", &ispi))
13591         ;
13592       else
13593         {
13594           errmsg ("parse error '%U'", format_unformat_error, i);
13595           return -99;
13596         }
13597     }
13598
13599   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13600
13601   mp->ispi = ispi;
13602
13603   S (mp);
13604   W (ret);
13605   return ret;
13606 }
13607
13608 /*
13609  * MAP
13610  */
13611 static int
13612 api_map_add_domain (vat_main_t * vam)
13613 {
13614   unformat_input_t *i = vam->input;
13615   vl_api_map_add_domain_t *mp;
13616
13617   ip4_address_t ip4_prefix;
13618   ip6_address_t ip6_prefix;
13619   ip6_address_t ip6_src;
13620   u32 num_m_args = 0;
13621   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13622     0, psid_length = 0;
13623   u8 is_translation = 0;
13624   u32 mtu = 0;
13625   u32 ip6_src_len = 128;
13626   int ret;
13627
13628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13629     {
13630       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13631                     &ip4_prefix, &ip4_prefix_len))
13632         num_m_args++;
13633       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13634                          &ip6_prefix, &ip6_prefix_len))
13635         num_m_args++;
13636       else
13637         if (unformat
13638             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13639              &ip6_src_len))
13640         num_m_args++;
13641       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13642         num_m_args++;
13643       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13644         num_m_args++;
13645       else if (unformat (i, "psid-offset %d", &psid_offset))
13646         num_m_args++;
13647       else if (unformat (i, "psid-len %d", &psid_length))
13648         num_m_args++;
13649       else if (unformat (i, "mtu %d", &mtu))
13650         num_m_args++;
13651       else if (unformat (i, "map-t"))
13652         is_translation = 1;
13653       else
13654         {
13655           clib_warning ("parse error '%U'", format_unformat_error, i);
13656           return -99;
13657         }
13658     }
13659
13660   if (num_m_args < 3)
13661     {
13662       errmsg ("mandatory argument(s) missing");
13663       return -99;
13664     }
13665
13666   /* Construct the API message */
13667   M (MAP_ADD_DOMAIN, mp);
13668
13669   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13670   mp->ip4_prefix_len = ip4_prefix_len;
13671
13672   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13673   mp->ip6_prefix_len = ip6_prefix_len;
13674
13675   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13676   mp->ip6_src_prefix_len = ip6_src_len;
13677
13678   mp->ea_bits_len = ea_bits_len;
13679   mp->psid_offset = psid_offset;
13680   mp->psid_length = psid_length;
13681   mp->is_translation = is_translation;
13682   mp->mtu = htons (mtu);
13683
13684   /* send it... */
13685   S (mp);
13686
13687   /* Wait for a reply, return good/bad news  */
13688   W (ret);
13689   return ret;
13690 }
13691
13692 static int
13693 api_map_del_domain (vat_main_t * vam)
13694 {
13695   unformat_input_t *i = vam->input;
13696   vl_api_map_del_domain_t *mp;
13697
13698   u32 num_m_args = 0;
13699   u32 index;
13700   int ret;
13701
13702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13703     {
13704       if (unformat (i, "index %d", &index))
13705         num_m_args++;
13706       else
13707         {
13708           clib_warning ("parse error '%U'", format_unformat_error, i);
13709           return -99;
13710         }
13711     }
13712
13713   if (num_m_args != 1)
13714     {
13715       errmsg ("mandatory argument(s) missing");
13716       return -99;
13717     }
13718
13719   /* Construct the API message */
13720   M (MAP_DEL_DOMAIN, mp);
13721
13722   mp->index = ntohl (index);
13723
13724   /* send it... */
13725   S (mp);
13726
13727   /* Wait for a reply, return good/bad news  */
13728   W (ret);
13729   return ret;
13730 }
13731
13732 static int
13733 api_map_add_del_rule (vat_main_t * vam)
13734 {
13735   unformat_input_t *i = vam->input;
13736   vl_api_map_add_del_rule_t *mp;
13737   u8 is_add = 1;
13738   ip6_address_t ip6_dst;
13739   u32 num_m_args = 0, index, psid = 0;
13740   int ret;
13741
13742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13743     {
13744       if (unformat (i, "index %d", &index))
13745         num_m_args++;
13746       else if (unformat (i, "psid %d", &psid))
13747         num_m_args++;
13748       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13749         num_m_args++;
13750       else if (unformat (i, "del"))
13751         {
13752           is_add = 0;
13753         }
13754       else
13755         {
13756           clib_warning ("parse error '%U'", format_unformat_error, i);
13757           return -99;
13758         }
13759     }
13760
13761   /* Construct the API message */
13762   M (MAP_ADD_DEL_RULE, mp);
13763
13764   mp->index = ntohl (index);
13765   mp->is_add = is_add;
13766   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13767   mp->psid = ntohs (psid);
13768
13769   /* send it... */
13770   S (mp);
13771
13772   /* Wait for a reply, return good/bad news  */
13773   W (ret);
13774   return ret;
13775 }
13776
13777 static int
13778 api_map_domain_dump (vat_main_t * vam)
13779 {
13780   vl_api_map_domain_dump_t *mp;
13781   vl_api_control_ping_t *mp_ping;
13782   int ret;
13783
13784   /* Construct the API message */
13785   M (MAP_DOMAIN_DUMP, mp);
13786
13787   /* send it... */
13788   S (mp);
13789
13790   /* Use a control ping for synchronization */
13791   M (CONTROL_PING, mp_ping);
13792   S (mp_ping);
13793
13794   W (ret);
13795   return ret;
13796 }
13797
13798 static int
13799 api_map_rule_dump (vat_main_t * vam)
13800 {
13801   unformat_input_t *i = vam->input;
13802   vl_api_map_rule_dump_t *mp;
13803   vl_api_control_ping_t *mp_ping;
13804   u32 domain_index = ~0;
13805   int ret;
13806
13807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13808     {
13809       if (unformat (i, "index %u", &domain_index))
13810         ;
13811       else
13812         break;
13813     }
13814
13815   if (domain_index == ~0)
13816     {
13817       clib_warning ("parse error: domain index expected");
13818       return -99;
13819     }
13820
13821   /* Construct the API message */
13822   M (MAP_RULE_DUMP, mp);
13823
13824   mp->domain_index = htonl (domain_index);
13825
13826   /* send it... */
13827   S (mp);
13828
13829   /* Use a control ping for synchronization */
13830   M (CONTROL_PING, mp_ping);
13831   S (mp_ping);
13832
13833   W (ret);
13834   return ret;
13835 }
13836
13837 static void vl_api_map_add_domain_reply_t_handler
13838   (vl_api_map_add_domain_reply_t * mp)
13839 {
13840   vat_main_t *vam = &vat_main;
13841   i32 retval = ntohl (mp->retval);
13842
13843   if (vam->async_mode)
13844     {
13845       vam->async_errors += (retval < 0);
13846     }
13847   else
13848     {
13849       vam->retval = retval;
13850       vam->result_ready = 1;
13851     }
13852 }
13853
13854 static void vl_api_map_add_domain_reply_t_handler_json
13855   (vl_api_map_add_domain_reply_t * mp)
13856 {
13857   vat_main_t *vam = &vat_main;
13858   vat_json_node_t node;
13859
13860   vat_json_init_object (&node);
13861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13862   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13863
13864   vat_json_print (vam->ofp, &node);
13865   vat_json_free (&node);
13866
13867   vam->retval = ntohl (mp->retval);
13868   vam->result_ready = 1;
13869 }
13870
13871 static int
13872 api_get_first_msg_id (vat_main_t * vam)
13873 {
13874   vl_api_get_first_msg_id_t *mp;
13875   unformat_input_t *i = vam->input;
13876   u8 *name;
13877   u8 name_set = 0;
13878   int ret;
13879
13880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13881     {
13882       if (unformat (i, "client %s", &name))
13883         name_set = 1;
13884       else
13885         break;
13886     }
13887
13888   if (name_set == 0)
13889     {
13890       errmsg ("missing client name");
13891       return -99;
13892     }
13893   vec_add1 (name, 0);
13894
13895   if (vec_len (name) > 63)
13896     {
13897       errmsg ("client name too long");
13898       return -99;
13899     }
13900
13901   M (GET_FIRST_MSG_ID, mp);
13902   clib_memcpy (mp->name, name, vec_len (name));
13903   S (mp);
13904   W (ret);
13905   return ret;
13906 }
13907
13908 static int
13909 api_cop_interface_enable_disable (vat_main_t * vam)
13910 {
13911   unformat_input_t *line_input = vam->input;
13912   vl_api_cop_interface_enable_disable_t *mp;
13913   u32 sw_if_index = ~0;
13914   u8 enable_disable = 1;
13915   int ret;
13916
13917   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13918     {
13919       if (unformat (line_input, "disable"))
13920         enable_disable = 0;
13921       if (unformat (line_input, "enable"))
13922         enable_disable = 1;
13923       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13924                          vam, &sw_if_index))
13925         ;
13926       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13927         ;
13928       else
13929         break;
13930     }
13931
13932   if (sw_if_index == ~0)
13933     {
13934       errmsg ("missing interface name or sw_if_index");
13935       return -99;
13936     }
13937
13938   /* Construct the API message */
13939   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13940   mp->sw_if_index = ntohl (sw_if_index);
13941   mp->enable_disable = enable_disable;
13942
13943   /* send it... */
13944   S (mp);
13945   /* Wait for the reply */
13946   W (ret);
13947   return ret;
13948 }
13949
13950 static int
13951 api_cop_whitelist_enable_disable (vat_main_t * vam)
13952 {
13953   unformat_input_t *line_input = vam->input;
13954   vl_api_cop_whitelist_enable_disable_t *mp;
13955   u32 sw_if_index = ~0;
13956   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13957   u32 fib_id = 0;
13958   int ret;
13959
13960   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13961     {
13962       if (unformat (line_input, "ip4"))
13963         ip4 = 1;
13964       else if (unformat (line_input, "ip6"))
13965         ip6 = 1;
13966       else if (unformat (line_input, "default"))
13967         default_cop = 1;
13968       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13969                          vam, &sw_if_index))
13970         ;
13971       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13972         ;
13973       else if (unformat (line_input, "fib-id %d", &fib_id))
13974         ;
13975       else
13976         break;
13977     }
13978
13979   if (sw_if_index == ~0)
13980     {
13981       errmsg ("missing interface name or sw_if_index");
13982       return -99;
13983     }
13984
13985   /* Construct the API message */
13986   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13987   mp->sw_if_index = ntohl (sw_if_index);
13988   mp->fib_id = ntohl (fib_id);
13989   mp->ip4 = ip4;
13990   mp->ip6 = ip6;
13991   mp->default_cop = default_cop;
13992
13993   /* send it... */
13994   S (mp);
13995   /* Wait for the reply */
13996   W (ret);
13997   return ret;
13998 }
13999
14000 static int
14001 api_get_node_graph (vat_main_t * vam)
14002 {
14003   vl_api_get_node_graph_t *mp;
14004   int ret;
14005
14006   M (GET_NODE_GRAPH, mp);
14007
14008   /* send it... */
14009   S (mp);
14010   /* Wait for the reply */
14011   W (ret);
14012   return ret;
14013 }
14014
14015 /* *INDENT-OFF* */
14016 /** Used for parsing LISP eids */
14017 typedef CLIB_PACKED(struct{
14018   u8 addr[16];   /**< eid address */
14019   u32 len;       /**< prefix length if IP */
14020   u8 type;      /**< type of eid */
14021 }) lisp_eid_vat_t;
14022 /* *INDENT-ON* */
14023
14024 static uword
14025 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14026 {
14027   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14028
14029   memset (a, 0, sizeof (a[0]));
14030
14031   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14032     {
14033       a->type = 0;              /* ipv4 type */
14034     }
14035   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14036     {
14037       a->type = 1;              /* ipv6 type */
14038     }
14039   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14040     {
14041       a->type = 2;              /* mac type */
14042     }
14043   else
14044     {
14045       return 0;
14046     }
14047
14048   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14049     {
14050       return 0;
14051     }
14052
14053   return 1;
14054 }
14055
14056 static int
14057 lisp_eid_size_vat (u8 type)
14058 {
14059   switch (type)
14060     {
14061     case 0:
14062       return 4;
14063     case 1:
14064       return 16;
14065     case 2:
14066       return 6;
14067     }
14068   return 0;
14069 }
14070
14071 static void
14072 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14073 {
14074   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14075 }
14076
14077 static int
14078 api_one_add_del_locator_set (vat_main_t * vam)
14079 {
14080   unformat_input_t *input = vam->input;
14081   vl_api_one_add_del_locator_set_t *mp;
14082   u8 is_add = 1;
14083   u8 *locator_set_name = NULL;
14084   u8 locator_set_name_set = 0;
14085   vl_api_local_locator_t locator, *locators = 0;
14086   u32 sw_if_index, priority, weight;
14087   u32 data_len = 0;
14088
14089   int ret;
14090   /* Parse args required to build the message */
14091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14092     {
14093       if (unformat (input, "del"))
14094         {
14095           is_add = 0;
14096         }
14097       else if (unformat (input, "locator-set %s", &locator_set_name))
14098         {
14099           locator_set_name_set = 1;
14100         }
14101       else if (unformat (input, "sw_if_index %u p %u w %u",
14102                          &sw_if_index, &priority, &weight))
14103         {
14104           locator.sw_if_index = htonl (sw_if_index);
14105           locator.priority = priority;
14106           locator.weight = weight;
14107           vec_add1 (locators, locator);
14108         }
14109       else
14110         if (unformat
14111             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14112              &sw_if_index, &priority, &weight))
14113         {
14114           locator.sw_if_index = htonl (sw_if_index);
14115           locator.priority = priority;
14116           locator.weight = weight;
14117           vec_add1 (locators, locator);
14118         }
14119       else
14120         break;
14121     }
14122
14123   if (locator_set_name_set == 0)
14124     {
14125       errmsg ("missing locator-set name");
14126       vec_free (locators);
14127       return -99;
14128     }
14129
14130   if (vec_len (locator_set_name) > 64)
14131     {
14132       errmsg ("locator-set name too long");
14133       vec_free (locator_set_name);
14134       vec_free (locators);
14135       return -99;
14136     }
14137   vec_add1 (locator_set_name, 0);
14138
14139   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14140
14141   /* Construct the API message */
14142   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14143
14144   mp->is_add = is_add;
14145   clib_memcpy (mp->locator_set_name, locator_set_name,
14146                vec_len (locator_set_name));
14147   vec_free (locator_set_name);
14148
14149   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14150   if (locators)
14151     clib_memcpy (mp->locators, locators, data_len);
14152   vec_free (locators);
14153
14154   /* send it... */
14155   S (mp);
14156
14157   /* Wait for a reply... */
14158   W (ret);
14159   return ret;
14160 }
14161
14162 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14163
14164 static int
14165 api_one_add_del_locator (vat_main_t * vam)
14166 {
14167   unformat_input_t *input = vam->input;
14168   vl_api_one_add_del_locator_t *mp;
14169   u32 tmp_if_index = ~0;
14170   u32 sw_if_index = ~0;
14171   u8 sw_if_index_set = 0;
14172   u8 sw_if_index_if_name_set = 0;
14173   u32 priority = ~0;
14174   u8 priority_set = 0;
14175   u32 weight = ~0;
14176   u8 weight_set = 0;
14177   u8 is_add = 1;
14178   u8 *locator_set_name = NULL;
14179   u8 locator_set_name_set = 0;
14180   int ret;
14181
14182   /* Parse args required to build the message */
14183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14184     {
14185       if (unformat (input, "del"))
14186         {
14187           is_add = 0;
14188         }
14189       else if (unformat (input, "locator-set %s", &locator_set_name))
14190         {
14191           locator_set_name_set = 1;
14192         }
14193       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14194                          &tmp_if_index))
14195         {
14196           sw_if_index_if_name_set = 1;
14197           sw_if_index = tmp_if_index;
14198         }
14199       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14200         {
14201           sw_if_index_set = 1;
14202           sw_if_index = tmp_if_index;
14203         }
14204       else if (unformat (input, "p %d", &priority))
14205         {
14206           priority_set = 1;
14207         }
14208       else if (unformat (input, "w %d", &weight))
14209         {
14210           weight_set = 1;
14211         }
14212       else
14213         break;
14214     }
14215
14216   if (locator_set_name_set == 0)
14217     {
14218       errmsg ("missing locator-set name");
14219       return -99;
14220     }
14221
14222   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14223     {
14224       errmsg ("missing sw_if_index");
14225       vec_free (locator_set_name);
14226       return -99;
14227     }
14228
14229   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14230     {
14231       errmsg ("cannot use both params interface name and sw_if_index");
14232       vec_free (locator_set_name);
14233       return -99;
14234     }
14235
14236   if (priority_set == 0)
14237     {
14238       errmsg ("missing locator-set priority");
14239       vec_free (locator_set_name);
14240       return -99;
14241     }
14242
14243   if (weight_set == 0)
14244     {
14245       errmsg ("missing locator-set weight");
14246       vec_free (locator_set_name);
14247       return -99;
14248     }
14249
14250   if (vec_len (locator_set_name) > 64)
14251     {
14252       errmsg ("locator-set name too long");
14253       vec_free (locator_set_name);
14254       return -99;
14255     }
14256   vec_add1 (locator_set_name, 0);
14257
14258   /* Construct the API message */
14259   M (ONE_ADD_DEL_LOCATOR, mp);
14260
14261   mp->is_add = is_add;
14262   mp->sw_if_index = ntohl (sw_if_index);
14263   mp->priority = priority;
14264   mp->weight = weight;
14265   clib_memcpy (mp->locator_set_name, locator_set_name,
14266                vec_len (locator_set_name));
14267   vec_free (locator_set_name);
14268
14269   /* send it... */
14270   S (mp);
14271
14272   /* Wait for a reply... */
14273   W (ret);
14274   return ret;
14275 }
14276
14277 #define api_lisp_add_del_locator api_one_add_del_locator
14278
14279 uword
14280 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14281 {
14282   u32 *key_id = va_arg (*args, u32 *);
14283   u8 *s = 0;
14284
14285   if (unformat (input, "%s", &s))
14286     {
14287       if (!strcmp ((char *) s, "sha1"))
14288         key_id[0] = HMAC_SHA_1_96;
14289       else if (!strcmp ((char *) s, "sha256"))
14290         key_id[0] = HMAC_SHA_256_128;
14291       else
14292         {
14293           clib_warning ("invalid key_id: '%s'", s);
14294           key_id[0] = HMAC_NO_KEY;
14295         }
14296     }
14297   else
14298     return 0;
14299
14300   vec_free (s);
14301   return 1;
14302 }
14303
14304 static int
14305 api_one_add_del_local_eid (vat_main_t * vam)
14306 {
14307   unformat_input_t *input = vam->input;
14308   vl_api_one_add_del_local_eid_t *mp;
14309   u8 is_add = 1;
14310   u8 eid_set = 0;
14311   lisp_eid_vat_t _eid, *eid = &_eid;
14312   u8 *locator_set_name = 0;
14313   u8 locator_set_name_set = 0;
14314   u32 vni = 0;
14315   u16 key_id = 0;
14316   u8 *key = 0;
14317   int ret;
14318
14319   /* Parse args required to build the message */
14320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14321     {
14322       if (unformat (input, "del"))
14323         {
14324           is_add = 0;
14325         }
14326       else if (unformat (input, "vni %d", &vni))
14327         {
14328           ;
14329         }
14330       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14331         {
14332           eid_set = 1;
14333         }
14334       else if (unformat (input, "locator-set %s", &locator_set_name))
14335         {
14336           locator_set_name_set = 1;
14337         }
14338       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14339         ;
14340       else if (unformat (input, "secret-key %_%v%_", &key))
14341         ;
14342       else
14343         break;
14344     }
14345
14346   if (locator_set_name_set == 0)
14347     {
14348       errmsg ("missing locator-set name");
14349       return -99;
14350     }
14351
14352   if (0 == eid_set)
14353     {
14354       errmsg ("EID address not set!");
14355       vec_free (locator_set_name);
14356       return -99;
14357     }
14358
14359   if (key && (0 == key_id))
14360     {
14361       errmsg ("invalid key_id!");
14362       return -99;
14363     }
14364
14365   if (vec_len (key) > 64)
14366     {
14367       errmsg ("key too long");
14368       vec_free (key);
14369       return -99;
14370     }
14371
14372   if (vec_len (locator_set_name) > 64)
14373     {
14374       errmsg ("locator-set name too long");
14375       vec_free (locator_set_name);
14376       return -99;
14377     }
14378   vec_add1 (locator_set_name, 0);
14379
14380   /* Construct the API message */
14381   M (ONE_ADD_DEL_LOCAL_EID, mp);
14382
14383   mp->is_add = is_add;
14384   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14385   mp->eid_type = eid->type;
14386   mp->prefix_len = eid->len;
14387   mp->vni = clib_host_to_net_u32 (vni);
14388   mp->key_id = clib_host_to_net_u16 (key_id);
14389   clib_memcpy (mp->locator_set_name, locator_set_name,
14390                vec_len (locator_set_name));
14391   clib_memcpy (mp->key, key, vec_len (key));
14392
14393   vec_free (locator_set_name);
14394   vec_free (key);
14395
14396   /* send it... */
14397   S (mp);
14398
14399   /* Wait for a reply... */
14400   W (ret);
14401   return ret;
14402 }
14403
14404 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14405
14406 static int
14407 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14408 {
14409   u32 dp_table = 0, vni = 0;;
14410   unformat_input_t *input = vam->input;
14411   vl_api_gpe_add_del_fwd_entry_t *mp;
14412   u8 is_add = 1;
14413   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14414   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14415   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14416   u32 action = ~0, w;
14417   ip4_address_t rmt_rloc4, lcl_rloc4;
14418   ip6_address_t rmt_rloc6, lcl_rloc6;
14419   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14420   int ret;
14421
14422   memset (&rloc, 0, sizeof (rloc));
14423
14424   /* Parse args required to build the message */
14425   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14426     {
14427       if (unformat (input, "del"))
14428         is_add = 0;
14429       else if (unformat (input, "add"))
14430         is_add = 1;
14431       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14432         {
14433           rmt_eid_set = 1;
14434         }
14435       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14436         {
14437           lcl_eid_set = 1;
14438         }
14439       else if (unformat (input, "vrf %d", &dp_table))
14440         ;
14441       else if (unformat (input, "bd %d", &dp_table))
14442         ;
14443       else if (unformat (input, "vni %d", &vni))
14444         ;
14445       else if (unformat (input, "w %d", &w))
14446         {
14447           if (!curr_rloc)
14448             {
14449               errmsg ("No RLOC configured for setting priority/weight!");
14450               return -99;
14451             }
14452           curr_rloc->weight = w;
14453         }
14454       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14455                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14456         {
14457           rloc.is_ip4 = 1;
14458
14459           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14460           rloc.weight = 0;
14461           vec_add1 (lcl_locs, rloc);
14462
14463           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14464           vec_add1 (rmt_locs, rloc);
14465           /* weight saved in rmt loc */
14466           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14467         }
14468       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14469                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14470         {
14471           rloc.is_ip4 = 0;
14472           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14473           rloc.weight = 0;
14474           vec_add1 (lcl_locs, rloc);
14475
14476           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14477           vec_add1 (rmt_locs, rloc);
14478           /* weight saved in rmt loc */
14479           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14480         }
14481       else if (unformat (input, "action %d", &action))
14482         {
14483           ;
14484         }
14485       else
14486         {
14487           clib_warning ("parse error '%U'", format_unformat_error, input);
14488           return -99;
14489         }
14490     }
14491
14492   if (!rmt_eid_set)
14493     {
14494       errmsg ("remote eid addresses not set");
14495       return -99;
14496     }
14497
14498   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14499     {
14500       errmsg ("eid types don't match");
14501       return -99;
14502     }
14503
14504   if (0 == rmt_locs && (u32) ~ 0 == action)
14505     {
14506       errmsg ("action not set for negative mapping");
14507       return -99;
14508     }
14509
14510   /* Construct the API message */
14511   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14512       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14513
14514   mp->is_add = is_add;
14515   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14516   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14517   mp->eid_type = rmt_eid->type;
14518   mp->dp_table = clib_host_to_net_u32 (dp_table);
14519   mp->vni = clib_host_to_net_u32 (vni);
14520   mp->rmt_len = rmt_eid->len;
14521   mp->lcl_len = lcl_eid->len;
14522   mp->action = action;
14523
14524   if (0 != rmt_locs && 0 != lcl_locs)
14525     {
14526       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14527       clib_memcpy (mp->locs, lcl_locs,
14528                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14529
14530       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14531       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14532                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14533     }
14534   vec_free (lcl_locs);
14535   vec_free (rmt_locs);
14536
14537   /* send it... */
14538   S (mp);
14539
14540   /* Wait for a reply... */
14541   W (ret);
14542   return ret;
14543 }
14544
14545 static int
14546 api_one_add_del_map_server (vat_main_t * vam)
14547 {
14548   unformat_input_t *input = vam->input;
14549   vl_api_one_add_del_map_server_t *mp;
14550   u8 is_add = 1;
14551   u8 ipv4_set = 0;
14552   u8 ipv6_set = 0;
14553   ip4_address_t ipv4;
14554   ip6_address_t ipv6;
14555   int ret;
14556
14557   /* Parse args required to build the message */
14558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14559     {
14560       if (unformat (input, "del"))
14561         {
14562           is_add = 0;
14563         }
14564       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14565         {
14566           ipv4_set = 1;
14567         }
14568       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14569         {
14570           ipv6_set = 1;
14571         }
14572       else
14573         break;
14574     }
14575
14576   if (ipv4_set && ipv6_set)
14577     {
14578       errmsg ("both eid v4 and v6 addresses set");
14579       return -99;
14580     }
14581
14582   if (!ipv4_set && !ipv6_set)
14583     {
14584       errmsg ("eid addresses not set");
14585       return -99;
14586     }
14587
14588   /* Construct the API message */
14589   M (ONE_ADD_DEL_MAP_SERVER, mp);
14590
14591   mp->is_add = is_add;
14592   if (ipv6_set)
14593     {
14594       mp->is_ipv6 = 1;
14595       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14596     }
14597   else
14598     {
14599       mp->is_ipv6 = 0;
14600       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14601     }
14602
14603   /* send it... */
14604   S (mp);
14605
14606   /* Wait for a reply... */
14607   W (ret);
14608   return ret;
14609 }
14610
14611 #define api_lisp_add_del_map_server api_one_add_del_map_server
14612
14613 static int
14614 api_one_add_del_map_resolver (vat_main_t * vam)
14615 {
14616   unformat_input_t *input = vam->input;
14617   vl_api_one_add_del_map_resolver_t *mp;
14618   u8 is_add = 1;
14619   u8 ipv4_set = 0;
14620   u8 ipv6_set = 0;
14621   ip4_address_t ipv4;
14622   ip6_address_t ipv6;
14623   int ret;
14624
14625   /* Parse args required to build the message */
14626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14627     {
14628       if (unformat (input, "del"))
14629         {
14630           is_add = 0;
14631         }
14632       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14633         {
14634           ipv4_set = 1;
14635         }
14636       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14637         {
14638           ipv6_set = 1;
14639         }
14640       else
14641         break;
14642     }
14643
14644   if (ipv4_set && ipv6_set)
14645     {
14646       errmsg ("both eid v4 and v6 addresses set");
14647       return -99;
14648     }
14649
14650   if (!ipv4_set && !ipv6_set)
14651     {
14652       errmsg ("eid addresses not set");
14653       return -99;
14654     }
14655
14656   /* Construct the API message */
14657   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14658
14659   mp->is_add = is_add;
14660   if (ipv6_set)
14661     {
14662       mp->is_ipv6 = 1;
14663       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14664     }
14665   else
14666     {
14667       mp->is_ipv6 = 0;
14668       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14669     }
14670
14671   /* send it... */
14672   S (mp);
14673
14674   /* Wait for a reply... */
14675   W (ret);
14676   return ret;
14677 }
14678
14679 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14680
14681 static int
14682 api_lisp_gpe_enable_disable (vat_main_t * vam)
14683 {
14684   unformat_input_t *input = vam->input;
14685   vl_api_gpe_enable_disable_t *mp;
14686   u8 is_set = 0;
14687   u8 is_en = 1;
14688   int ret;
14689
14690   /* Parse args required to build the message */
14691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14692     {
14693       if (unformat (input, "enable"))
14694         {
14695           is_set = 1;
14696           is_en = 1;
14697         }
14698       else if (unformat (input, "disable"))
14699         {
14700           is_set = 1;
14701           is_en = 0;
14702         }
14703       else
14704         break;
14705     }
14706
14707   if (is_set == 0)
14708     {
14709       errmsg ("Value not set");
14710       return -99;
14711     }
14712
14713   /* Construct the API message */
14714   M (GPE_ENABLE_DISABLE, mp);
14715
14716   mp->is_en = is_en;
14717
14718   /* send it... */
14719   S (mp);
14720
14721   /* Wait for a reply... */
14722   W (ret);
14723   return ret;
14724 }
14725
14726 static int
14727 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14728 {
14729   unformat_input_t *input = vam->input;
14730   vl_api_one_rloc_probe_enable_disable_t *mp;
14731   u8 is_set = 0;
14732   u8 is_en = 0;
14733   int ret;
14734
14735   /* Parse args required to build the message */
14736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14737     {
14738       if (unformat (input, "enable"))
14739         {
14740           is_set = 1;
14741           is_en = 1;
14742         }
14743       else if (unformat (input, "disable"))
14744         is_set = 1;
14745       else
14746         break;
14747     }
14748
14749   if (!is_set)
14750     {
14751       errmsg ("Value not set");
14752       return -99;
14753     }
14754
14755   /* Construct the API message */
14756   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14757
14758   mp->is_enabled = is_en;
14759
14760   /* send it... */
14761   S (mp);
14762
14763   /* Wait for a reply... */
14764   W (ret);
14765   return ret;
14766 }
14767
14768 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14769
14770 static int
14771 api_one_map_register_enable_disable (vat_main_t * vam)
14772 {
14773   unformat_input_t *input = vam->input;
14774   vl_api_one_map_register_enable_disable_t *mp;
14775   u8 is_set = 0;
14776   u8 is_en = 0;
14777   int ret;
14778
14779   /* Parse args required to build the message */
14780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14781     {
14782       if (unformat (input, "enable"))
14783         {
14784           is_set = 1;
14785           is_en = 1;
14786         }
14787       else if (unformat (input, "disable"))
14788         is_set = 1;
14789       else
14790         break;
14791     }
14792
14793   if (!is_set)
14794     {
14795       errmsg ("Value not set");
14796       return -99;
14797     }
14798
14799   /* Construct the API message */
14800   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14801
14802   mp->is_enabled = is_en;
14803
14804   /* send it... */
14805   S (mp);
14806
14807   /* Wait for a reply... */
14808   W (ret);
14809   return ret;
14810 }
14811
14812 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14813
14814 static int
14815 api_one_enable_disable (vat_main_t * vam)
14816 {
14817   unformat_input_t *input = vam->input;
14818   vl_api_one_enable_disable_t *mp;
14819   u8 is_set = 0;
14820   u8 is_en = 0;
14821   int ret;
14822
14823   /* Parse args required to build the message */
14824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14825     {
14826       if (unformat (input, "enable"))
14827         {
14828           is_set = 1;
14829           is_en = 1;
14830         }
14831       else if (unformat (input, "disable"))
14832         {
14833           is_set = 1;
14834         }
14835       else
14836         break;
14837     }
14838
14839   if (!is_set)
14840     {
14841       errmsg ("Value not set");
14842       return -99;
14843     }
14844
14845   /* Construct the API message */
14846   M (ONE_ENABLE_DISABLE, mp);
14847
14848   mp->is_en = is_en;
14849
14850   /* send it... */
14851   S (mp);
14852
14853   /* Wait for a reply... */
14854   W (ret);
14855   return ret;
14856 }
14857
14858 #define api_lisp_enable_disable api_one_enable_disable
14859
14860 static int
14861 api_show_one_map_register_state (vat_main_t * vam)
14862 {
14863   vl_api_show_one_map_register_state_t *mp;
14864   int ret;
14865
14866   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14867
14868   /* send */
14869   S (mp);
14870
14871   /* wait for reply */
14872   W (ret);
14873   return ret;
14874 }
14875
14876 #define api_show_lisp_map_register_state api_show_one_map_register_state
14877
14878 static int
14879 api_show_one_rloc_probe_state (vat_main_t * vam)
14880 {
14881   vl_api_show_one_rloc_probe_state_t *mp;
14882   int ret;
14883
14884   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14885
14886   /* send */
14887   S (mp);
14888
14889   /* wait for reply */
14890   W (ret);
14891   return ret;
14892 }
14893
14894 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14895
14896 static int
14897 api_one_add_del_l2_arp_entry (vat_main_t * vam)
14898 {
14899   vl_api_one_add_del_l2_arp_entry_t *mp;
14900   unformat_input_t *input = vam->input;
14901   u8 is_add = 1;
14902   u8 mac_set = 0;
14903   u8 bd_set = 0;
14904   u8 ip_set = 0;
14905   u8 mac[6] = { 0, };
14906   u32 ip4 = 0, bd = ~0;
14907   int ret;
14908
14909   /* Parse args required to build the message */
14910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14911     {
14912       if (unformat (input, "del"))
14913         is_add = 0;
14914       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
14915         mac_set = 1;
14916       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
14917         ip_set = 1;
14918       else if (unformat (input, "bd %d", &bd))
14919         bd_set = 1;
14920       else
14921         {
14922           errmsg ("parse error '%U'", format_unformat_error, input);
14923           return -99;
14924         }
14925     }
14926
14927   if (!bd_set || !ip_set || (!mac_set && is_add))
14928     {
14929       errmsg ("Missing BD, IP or MAC!");
14930       return -99;
14931     }
14932
14933   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
14934   mp->is_add = is_add;
14935   clib_memcpy (mp->mac, mac, 6);
14936   mp->bd = clib_host_to_net_u32 (bd);
14937   mp->ip4 = ip4;
14938
14939   /* send */
14940   S (mp);
14941
14942   /* wait for reply */
14943   W (ret);
14944   return ret;
14945 }
14946
14947 static int
14948 api_one_l2_arp_bd_get (vat_main_t * vam)
14949 {
14950   vl_api_one_l2_arp_bd_get_t *mp;
14951   int ret;
14952
14953   M (ONE_L2_ARP_BD_GET, mp);
14954
14955   /* send */
14956   S (mp);
14957
14958   /* wait for reply */
14959   W (ret);
14960   return ret;
14961 }
14962
14963 static int
14964 api_one_l2_arp_entries_get (vat_main_t * vam)
14965 {
14966   vl_api_one_l2_arp_entries_get_t *mp;
14967   unformat_input_t *input = vam->input;
14968   u8 bd_set = 0;
14969   u32 bd = ~0;
14970   int ret;
14971
14972   /* Parse args required to build the message */
14973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14974     {
14975       if (unformat (input, "bd %d", &bd))
14976         bd_set = 1;
14977       else
14978         {
14979           errmsg ("parse error '%U'", format_unformat_error, input);
14980           return -99;
14981         }
14982     }
14983
14984   if (!bd_set)
14985     {
14986       errmsg ("Expected bridge domain!");
14987       return -99;
14988     }
14989
14990   M (ONE_L2_ARP_ENTRIES_GET, mp);
14991   mp->bd = clib_host_to_net_u32 (bd);
14992
14993   /* send */
14994   S (mp);
14995
14996   /* wait for reply */
14997   W (ret);
14998   return ret;
14999 }
15000
15001 static int
15002 api_one_stats_enable_disable (vat_main_t * vam)
15003 {
15004   vl_api_one_stats_enable_disable_t *mp;
15005   unformat_input_t *input = vam->input;
15006   u8 is_set = 0;
15007   u8 is_en = 0;
15008   int ret;
15009
15010   /* Parse args required to build the message */
15011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15012     {
15013       if (unformat (input, "enable"))
15014         {
15015           is_set = 1;
15016           is_en = 1;
15017         }
15018       else if (unformat (input, "disable"))
15019         {
15020           is_set = 1;
15021         }
15022       else
15023         break;
15024     }
15025
15026   if (!is_set)
15027     {
15028       errmsg ("Value not set");
15029       return -99;
15030     }
15031
15032   M (ONE_STATS_ENABLE_DISABLE, mp);
15033   mp->is_en = is_en;
15034
15035   /* send */
15036   S (mp);
15037
15038   /* wait for reply */
15039   W (ret);
15040   return ret;
15041 }
15042
15043 static int
15044 api_show_one_stats_enable_disable (vat_main_t * vam)
15045 {
15046   vl_api_show_one_stats_enable_disable_t *mp;
15047   int ret;
15048
15049   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15050
15051   /* send */
15052   S (mp);
15053
15054   /* wait for reply */
15055   W (ret);
15056   return ret;
15057 }
15058
15059 static int
15060 api_show_one_map_request_mode (vat_main_t * vam)
15061 {
15062   vl_api_show_one_map_request_mode_t *mp;
15063   int ret;
15064
15065   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15066
15067   /* send */
15068   S (mp);
15069
15070   /* wait for reply */
15071   W (ret);
15072   return ret;
15073 }
15074
15075 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15076
15077 static int
15078 api_one_map_request_mode (vat_main_t * vam)
15079 {
15080   unformat_input_t *input = vam->input;
15081   vl_api_one_map_request_mode_t *mp;
15082   u8 mode = 0;
15083   int ret;
15084
15085   /* Parse args required to build the message */
15086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15087     {
15088       if (unformat (input, "dst-only"))
15089         mode = 0;
15090       else if (unformat (input, "src-dst"))
15091         mode = 1;
15092       else
15093         {
15094           errmsg ("parse error '%U'", format_unformat_error, input);
15095           return -99;
15096         }
15097     }
15098
15099   M (ONE_MAP_REQUEST_MODE, mp);
15100
15101   mp->mode = mode;
15102
15103   /* send */
15104   S (mp);
15105
15106   /* wait for reply */
15107   W (ret);
15108   return ret;
15109 }
15110
15111 #define api_lisp_map_request_mode api_one_map_request_mode
15112
15113 /**
15114  * Enable/disable ONE proxy ITR.
15115  *
15116  * @param vam vpp API test context
15117  * @return return code
15118  */
15119 static int
15120 api_one_pitr_set_locator_set (vat_main_t * vam)
15121 {
15122   u8 ls_name_set = 0;
15123   unformat_input_t *input = vam->input;
15124   vl_api_one_pitr_set_locator_set_t *mp;
15125   u8 is_add = 1;
15126   u8 *ls_name = 0;
15127   int ret;
15128
15129   /* Parse args required to build the message */
15130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15131     {
15132       if (unformat (input, "del"))
15133         is_add = 0;
15134       else if (unformat (input, "locator-set %s", &ls_name))
15135         ls_name_set = 1;
15136       else
15137         {
15138           errmsg ("parse error '%U'", format_unformat_error, input);
15139           return -99;
15140         }
15141     }
15142
15143   if (!ls_name_set)
15144     {
15145       errmsg ("locator-set name not set!");
15146       return -99;
15147     }
15148
15149   M (ONE_PITR_SET_LOCATOR_SET, mp);
15150
15151   mp->is_add = is_add;
15152   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15153   vec_free (ls_name);
15154
15155   /* send */
15156   S (mp);
15157
15158   /* wait for reply */
15159   W (ret);
15160   return ret;
15161 }
15162
15163 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15164
15165 static int
15166 api_show_one_pitr (vat_main_t * vam)
15167 {
15168   vl_api_show_one_pitr_t *mp;
15169   int ret;
15170
15171   if (!vam->json_output)
15172     {
15173       print (vam->ofp, "%=20s", "lisp status:");
15174     }
15175
15176   M (SHOW_ONE_PITR, mp);
15177   /* send it... */
15178   S (mp);
15179
15180   /* Wait for a reply... */
15181   W (ret);
15182   return ret;
15183 }
15184
15185 #define api_show_lisp_pitr api_show_one_pitr
15186
15187 static int
15188 api_one_use_petr (vat_main_t * vam)
15189 {
15190   unformat_input_t *input = vam->input;
15191   vl_api_one_use_petr_t *mp;
15192   u8 is_add = 0;
15193   ip_address_t ip;
15194   int ret;
15195
15196   memset (&ip, 0, sizeof (ip));
15197
15198   /* Parse args required to build the message */
15199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15200     {
15201       if (unformat (input, "disable"))
15202         is_add = 0;
15203       else
15204         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15205         {
15206           is_add = 1;
15207           ip_addr_version (&ip) = IP4;
15208         }
15209       else
15210         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15211         {
15212           is_add = 1;
15213           ip_addr_version (&ip) = IP6;
15214         }
15215       else
15216         {
15217           errmsg ("parse error '%U'", format_unformat_error, input);
15218           return -99;
15219         }
15220     }
15221
15222   M (ONE_USE_PETR, mp);
15223
15224   mp->is_add = is_add;
15225   if (is_add)
15226     {
15227       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15228       if (mp->is_ip4)
15229         clib_memcpy (mp->address, &ip, 4);
15230       else
15231         clib_memcpy (mp->address, &ip, 16);
15232     }
15233
15234   /* send */
15235   S (mp);
15236
15237   /* wait for reply */
15238   W (ret);
15239   return ret;
15240 }
15241
15242 #define api_lisp_use_petr api_one_use_petr
15243
15244 static int
15245 api_show_one_use_petr (vat_main_t * vam)
15246 {
15247   vl_api_show_one_use_petr_t *mp;
15248   int ret;
15249
15250   if (!vam->json_output)
15251     {
15252       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15253     }
15254
15255   M (SHOW_ONE_USE_PETR, mp);
15256   /* send it... */
15257   S (mp);
15258
15259   /* Wait for a reply... */
15260   W (ret);
15261   return ret;
15262 }
15263
15264 #define api_show_lisp_use_petr api_show_one_use_petr
15265
15266 /**
15267  * Add/delete mapping between vni and vrf
15268  */
15269 static int
15270 api_one_eid_table_add_del_map (vat_main_t * vam)
15271 {
15272   unformat_input_t *input = vam->input;
15273   vl_api_one_eid_table_add_del_map_t *mp;
15274   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15275   u32 vni, vrf, bd_index;
15276   int ret;
15277
15278   /* Parse args required to build the message */
15279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15280     {
15281       if (unformat (input, "del"))
15282         is_add = 0;
15283       else if (unformat (input, "vrf %d", &vrf))
15284         vrf_set = 1;
15285       else if (unformat (input, "bd_index %d", &bd_index))
15286         bd_index_set = 1;
15287       else if (unformat (input, "vni %d", &vni))
15288         vni_set = 1;
15289       else
15290         break;
15291     }
15292
15293   if (!vni_set || (!vrf_set && !bd_index_set))
15294     {
15295       errmsg ("missing arguments!");
15296       return -99;
15297     }
15298
15299   if (vrf_set && bd_index_set)
15300     {
15301       errmsg ("error: both vrf and bd entered!");
15302       return -99;
15303     }
15304
15305   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15306
15307   mp->is_add = is_add;
15308   mp->vni = htonl (vni);
15309   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15310   mp->is_l2 = bd_index_set;
15311
15312   /* send */
15313   S (mp);
15314
15315   /* wait for reply */
15316   W (ret);
15317   return ret;
15318 }
15319
15320 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15321
15322 uword
15323 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15324 {
15325   u32 *action = va_arg (*args, u32 *);
15326   u8 *s = 0;
15327
15328   if (unformat (input, "%s", &s))
15329     {
15330       if (!strcmp ((char *) s, "no-action"))
15331         action[0] = 0;
15332       else if (!strcmp ((char *) s, "natively-forward"))
15333         action[0] = 1;
15334       else if (!strcmp ((char *) s, "send-map-request"))
15335         action[0] = 2;
15336       else if (!strcmp ((char *) s, "drop"))
15337         action[0] = 3;
15338       else
15339         {
15340           clib_warning ("invalid action: '%s'", s);
15341           action[0] = 3;
15342         }
15343     }
15344   else
15345     return 0;
15346
15347   vec_free (s);
15348   return 1;
15349 }
15350
15351 /**
15352  * Add/del remote mapping to/from ONE control plane
15353  *
15354  * @param vam vpp API test context
15355  * @return return code
15356  */
15357 static int
15358 api_one_add_del_remote_mapping (vat_main_t * vam)
15359 {
15360   unformat_input_t *input = vam->input;
15361   vl_api_one_add_del_remote_mapping_t *mp;
15362   u32 vni = 0;
15363   lisp_eid_vat_t _eid, *eid = &_eid;
15364   lisp_eid_vat_t _seid, *seid = &_seid;
15365   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15366   u32 action = ~0, p, w, data_len;
15367   ip4_address_t rloc4;
15368   ip6_address_t rloc6;
15369   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15370   int ret;
15371
15372   memset (&rloc, 0, sizeof (rloc));
15373
15374   /* Parse args required to build the message */
15375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15376     {
15377       if (unformat (input, "del-all"))
15378         {
15379           del_all = 1;
15380         }
15381       else if (unformat (input, "del"))
15382         {
15383           is_add = 0;
15384         }
15385       else if (unformat (input, "add"))
15386         {
15387           is_add = 1;
15388         }
15389       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15390         {
15391           eid_set = 1;
15392         }
15393       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15394         {
15395           seid_set = 1;
15396         }
15397       else if (unformat (input, "vni %d", &vni))
15398         {
15399           ;
15400         }
15401       else if (unformat (input, "p %d w %d", &p, &w))
15402         {
15403           if (!curr_rloc)
15404             {
15405               errmsg ("No RLOC configured for setting priority/weight!");
15406               return -99;
15407             }
15408           curr_rloc->priority = p;
15409           curr_rloc->weight = w;
15410         }
15411       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15412         {
15413           rloc.is_ip4 = 1;
15414           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15415           vec_add1 (rlocs, rloc);
15416           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15417         }
15418       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15419         {
15420           rloc.is_ip4 = 0;
15421           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15422           vec_add1 (rlocs, rloc);
15423           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15424         }
15425       else if (unformat (input, "action %U",
15426                          unformat_negative_mapping_action, &action))
15427         {
15428           ;
15429         }
15430       else
15431         {
15432           clib_warning ("parse error '%U'", format_unformat_error, input);
15433           return -99;
15434         }
15435     }
15436
15437   if (0 == eid_set)
15438     {
15439       errmsg ("missing params!");
15440       return -99;
15441     }
15442
15443   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15444     {
15445       errmsg ("no action set for negative map-reply!");
15446       return -99;
15447     }
15448
15449   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15450
15451   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15452   mp->is_add = is_add;
15453   mp->vni = htonl (vni);
15454   mp->action = (u8) action;
15455   mp->is_src_dst = seid_set;
15456   mp->eid_len = eid->len;
15457   mp->seid_len = seid->len;
15458   mp->del_all = del_all;
15459   mp->eid_type = eid->type;
15460   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15461   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15462
15463   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15464   clib_memcpy (mp->rlocs, rlocs, data_len);
15465   vec_free (rlocs);
15466
15467   /* send it... */
15468   S (mp);
15469
15470   /* Wait for a reply... */
15471   W (ret);
15472   return ret;
15473 }
15474
15475 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15476
15477 /**
15478  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15479  * forwarding entries in data-plane accordingly.
15480  *
15481  * @param vam vpp API test context
15482  * @return return code
15483  */
15484 static int
15485 api_one_add_del_adjacency (vat_main_t * vam)
15486 {
15487   unformat_input_t *input = vam->input;
15488   vl_api_one_add_del_adjacency_t *mp;
15489   u32 vni = 0;
15490   ip4_address_t leid4, reid4;
15491   ip6_address_t leid6, reid6;
15492   u8 reid_mac[6] = { 0 };
15493   u8 leid_mac[6] = { 0 };
15494   u8 reid_type, leid_type;
15495   u32 leid_len = 0, reid_len = 0, len;
15496   u8 is_add = 1;
15497   int ret;
15498
15499   leid_type = reid_type = (u8) ~ 0;
15500
15501   /* Parse args required to build the message */
15502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15503     {
15504       if (unformat (input, "del"))
15505         {
15506           is_add = 0;
15507         }
15508       else if (unformat (input, "add"))
15509         {
15510           is_add = 1;
15511         }
15512       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15513                          &reid4, &len))
15514         {
15515           reid_type = 0;        /* ipv4 */
15516           reid_len = len;
15517         }
15518       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15519                          &reid6, &len))
15520         {
15521           reid_type = 1;        /* ipv6 */
15522           reid_len = len;
15523         }
15524       else if (unformat (input, "reid %U", unformat_ethernet_address,
15525                          reid_mac))
15526         {
15527           reid_type = 2;        /* mac */
15528         }
15529       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15530                          &leid4, &len))
15531         {
15532           leid_type = 0;        /* ipv4 */
15533           leid_len = len;
15534         }
15535       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15536                          &leid6, &len))
15537         {
15538           leid_type = 1;        /* ipv6 */
15539           leid_len = len;
15540         }
15541       else if (unformat (input, "leid %U", unformat_ethernet_address,
15542                          leid_mac))
15543         {
15544           leid_type = 2;        /* mac */
15545         }
15546       else if (unformat (input, "vni %d", &vni))
15547         {
15548           ;
15549         }
15550       else
15551         {
15552           errmsg ("parse error '%U'", format_unformat_error, input);
15553           return -99;
15554         }
15555     }
15556
15557   if ((u8) ~ 0 == reid_type)
15558     {
15559       errmsg ("missing params!");
15560       return -99;
15561     }
15562
15563   if (leid_type != reid_type)
15564     {
15565       errmsg ("remote and local EIDs are of different types!");
15566       return -99;
15567     }
15568
15569   M (ONE_ADD_DEL_ADJACENCY, mp);
15570   mp->is_add = is_add;
15571   mp->vni = htonl (vni);
15572   mp->leid_len = leid_len;
15573   mp->reid_len = reid_len;
15574   mp->eid_type = reid_type;
15575
15576   switch (mp->eid_type)
15577     {
15578     case 0:
15579       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15580       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15581       break;
15582     case 1:
15583       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15584       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15585       break;
15586     case 2:
15587       clib_memcpy (mp->leid, leid_mac, 6);
15588       clib_memcpy (mp->reid, reid_mac, 6);
15589       break;
15590     default:
15591       errmsg ("unknown EID type %d!", mp->eid_type);
15592       return 0;
15593     }
15594
15595   /* send it... */
15596   S (mp);
15597
15598   /* Wait for a reply... */
15599   W (ret);
15600   return ret;
15601 }
15602
15603 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15604
15605 uword
15606 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15607 {
15608   u32 *mode = va_arg (*args, u32 *);
15609
15610   if (unformat (input, "lisp"))
15611     *mode = 0;
15612   else if (unformat (input, "vxlan"))
15613     *mode = 1;
15614   else
15615     return 0;
15616
15617   return 1;
15618 }
15619
15620 static int
15621 api_gpe_get_encap_mode (vat_main_t * vam)
15622 {
15623   vl_api_gpe_get_encap_mode_t *mp;
15624   int ret;
15625
15626   /* Construct the API message */
15627   M (GPE_GET_ENCAP_MODE, mp);
15628
15629   /* send it... */
15630   S (mp);
15631
15632   /* Wait for a reply... */
15633   W (ret);
15634   return ret;
15635 }
15636
15637 static int
15638 api_gpe_set_encap_mode (vat_main_t * vam)
15639 {
15640   unformat_input_t *input = vam->input;
15641   vl_api_gpe_set_encap_mode_t *mp;
15642   int ret;
15643   u32 mode = 0;
15644
15645   /* Parse args required to build the message */
15646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15647     {
15648       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15649         ;
15650       else
15651         break;
15652     }
15653
15654   /* Construct the API message */
15655   M (GPE_SET_ENCAP_MODE, mp);
15656
15657   mp->mode = mode;
15658
15659   /* send it... */
15660   S (mp);
15661
15662   /* Wait for a reply... */
15663   W (ret);
15664   return ret;
15665 }
15666
15667 static int
15668 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15669 {
15670   unformat_input_t *input = vam->input;
15671   vl_api_gpe_add_del_iface_t *mp;
15672   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15673   u32 dp_table = 0, vni = 0;
15674   int ret;
15675
15676   /* Parse args required to build the message */
15677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15678     {
15679       if (unformat (input, "up"))
15680         {
15681           action_set = 1;
15682           is_add = 1;
15683         }
15684       else if (unformat (input, "down"))
15685         {
15686           action_set = 1;
15687           is_add = 0;
15688         }
15689       else if (unformat (input, "table_id %d", &dp_table))
15690         {
15691           dp_table_set = 1;
15692         }
15693       else if (unformat (input, "bd_id %d", &dp_table))
15694         {
15695           dp_table_set = 1;
15696           is_l2 = 1;
15697         }
15698       else if (unformat (input, "vni %d", &vni))
15699         {
15700           vni_set = 1;
15701         }
15702       else
15703         break;
15704     }
15705
15706   if (action_set == 0)
15707     {
15708       errmsg ("Action not set");
15709       return -99;
15710     }
15711   if (dp_table_set == 0 || vni_set == 0)
15712     {
15713       errmsg ("vni and dp_table must be set");
15714       return -99;
15715     }
15716
15717   /* Construct the API message */
15718   M (GPE_ADD_DEL_IFACE, mp);
15719
15720   mp->is_add = is_add;
15721   mp->dp_table = dp_table;
15722   mp->is_l2 = is_l2;
15723   mp->vni = vni;
15724
15725   /* send it... */
15726   S (mp);
15727
15728   /* Wait for a reply... */
15729   W (ret);
15730   return ret;
15731 }
15732
15733 /**
15734  * Add/del map request itr rlocs from ONE control plane and updates
15735  *
15736  * @param vam vpp API test context
15737  * @return return code
15738  */
15739 static int
15740 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15741 {
15742   unformat_input_t *input = vam->input;
15743   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15744   u8 *locator_set_name = 0;
15745   u8 locator_set_name_set = 0;
15746   u8 is_add = 1;
15747   int ret;
15748
15749   /* Parse args required to build the message */
15750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15751     {
15752       if (unformat (input, "del"))
15753         {
15754           is_add = 0;
15755         }
15756       else if (unformat (input, "%_%v%_", &locator_set_name))
15757         {
15758           locator_set_name_set = 1;
15759         }
15760       else
15761         {
15762           clib_warning ("parse error '%U'", format_unformat_error, input);
15763           return -99;
15764         }
15765     }
15766
15767   if (is_add && !locator_set_name_set)
15768     {
15769       errmsg ("itr-rloc is not set!");
15770       return -99;
15771     }
15772
15773   if (is_add && vec_len (locator_set_name) > 64)
15774     {
15775       errmsg ("itr-rloc locator-set name too long");
15776       vec_free (locator_set_name);
15777       return -99;
15778     }
15779
15780   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15781   mp->is_add = is_add;
15782   if (is_add)
15783     {
15784       clib_memcpy (mp->locator_set_name, locator_set_name,
15785                    vec_len (locator_set_name));
15786     }
15787   else
15788     {
15789       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15790     }
15791   vec_free (locator_set_name);
15792
15793   /* send it... */
15794   S (mp);
15795
15796   /* Wait for a reply... */
15797   W (ret);
15798   return ret;
15799 }
15800
15801 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15802
15803 static int
15804 api_one_locator_dump (vat_main_t * vam)
15805 {
15806   unformat_input_t *input = vam->input;
15807   vl_api_one_locator_dump_t *mp;
15808   vl_api_control_ping_t *mp_ping;
15809   u8 is_index_set = 0, is_name_set = 0;
15810   u8 *ls_name = 0;
15811   u32 ls_index = ~0;
15812   int ret;
15813
15814   /* Parse args required to build the message */
15815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15816     {
15817       if (unformat (input, "ls_name %_%v%_", &ls_name))
15818         {
15819           is_name_set = 1;
15820         }
15821       else if (unformat (input, "ls_index %d", &ls_index))
15822         {
15823           is_index_set = 1;
15824         }
15825       else
15826         {
15827           errmsg ("parse error '%U'", format_unformat_error, input);
15828           return -99;
15829         }
15830     }
15831
15832   if (!is_index_set && !is_name_set)
15833     {
15834       errmsg ("error: expected one of index or name!");
15835       return -99;
15836     }
15837
15838   if (is_index_set && is_name_set)
15839     {
15840       errmsg ("error: only one param expected!");
15841       return -99;
15842     }
15843
15844   if (vec_len (ls_name) > 62)
15845     {
15846       errmsg ("error: locator set name too long!");
15847       return -99;
15848     }
15849
15850   if (!vam->json_output)
15851     {
15852       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15853     }
15854
15855   M (ONE_LOCATOR_DUMP, mp);
15856   mp->is_index_set = is_index_set;
15857
15858   if (is_index_set)
15859     mp->ls_index = clib_host_to_net_u32 (ls_index);
15860   else
15861     {
15862       vec_add1 (ls_name, 0);
15863       strncpy ((char *) mp->ls_name, (char *) ls_name,
15864                sizeof (mp->ls_name) - 1);
15865     }
15866
15867   /* send it... */
15868   S (mp);
15869
15870   /* Use a control ping for synchronization */
15871   M (CONTROL_PING, mp_ping);
15872   S (mp_ping);
15873
15874   /* Wait for a reply... */
15875   W (ret);
15876   return ret;
15877 }
15878
15879 #define api_lisp_locator_dump api_one_locator_dump
15880
15881 static int
15882 api_one_locator_set_dump (vat_main_t * vam)
15883 {
15884   vl_api_one_locator_set_dump_t *mp;
15885   vl_api_control_ping_t *mp_ping;
15886   unformat_input_t *input = vam->input;
15887   u8 filter = 0;
15888   int ret;
15889
15890   /* Parse args required to build the message */
15891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15892     {
15893       if (unformat (input, "local"))
15894         {
15895           filter = 1;
15896         }
15897       else if (unformat (input, "remote"))
15898         {
15899           filter = 2;
15900         }
15901       else
15902         {
15903           errmsg ("parse error '%U'", format_unformat_error, input);
15904           return -99;
15905         }
15906     }
15907
15908   if (!vam->json_output)
15909     {
15910       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15911     }
15912
15913   M (ONE_LOCATOR_SET_DUMP, mp);
15914
15915   mp->filter = filter;
15916
15917   /* send it... */
15918   S (mp);
15919
15920   /* Use a control ping for synchronization */
15921   M (CONTROL_PING, mp_ping);
15922   S (mp_ping);
15923
15924   /* Wait for a reply... */
15925   W (ret);
15926   return ret;
15927 }
15928
15929 #define api_lisp_locator_set_dump api_one_locator_set_dump
15930
15931 static int
15932 api_one_eid_table_map_dump (vat_main_t * vam)
15933 {
15934   u8 is_l2 = 0;
15935   u8 mode_set = 0;
15936   unformat_input_t *input = vam->input;
15937   vl_api_one_eid_table_map_dump_t *mp;
15938   vl_api_control_ping_t *mp_ping;
15939   int ret;
15940
15941   /* Parse args required to build the message */
15942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15943     {
15944       if (unformat (input, "l2"))
15945         {
15946           is_l2 = 1;
15947           mode_set = 1;
15948         }
15949       else if (unformat (input, "l3"))
15950         {
15951           is_l2 = 0;
15952           mode_set = 1;
15953         }
15954       else
15955         {
15956           errmsg ("parse error '%U'", format_unformat_error, input);
15957           return -99;
15958         }
15959     }
15960
15961   if (!mode_set)
15962     {
15963       errmsg ("expected one of 'l2' or 'l3' parameter!");
15964       return -99;
15965     }
15966
15967   if (!vam->json_output)
15968     {
15969       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15970     }
15971
15972   M (ONE_EID_TABLE_MAP_DUMP, mp);
15973   mp->is_l2 = is_l2;
15974
15975   /* send it... */
15976   S (mp);
15977
15978   /* Use a control ping for synchronization */
15979   M (CONTROL_PING, mp_ping);
15980   S (mp_ping);
15981
15982   /* Wait for a reply... */
15983   W (ret);
15984   return ret;
15985 }
15986
15987 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15988
15989 static int
15990 api_one_eid_table_vni_dump (vat_main_t * vam)
15991 {
15992   vl_api_one_eid_table_vni_dump_t *mp;
15993   vl_api_control_ping_t *mp_ping;
15994   int ret;
15995
15996   if (!vam->json_output)
15997     {
15998       print (vam->ofp, "VNI");
15999     }
16000
16001   M (ONE_EID_TABLE_VNI_DUMP, mp);
16002
16003   /* send it... */
16004   S (mp);
16005
16006   /* Use a control ping for synchronization */
16007   M (CONTROL_PING, mp_ping);
16008   S (mp_ping);
16009
16010   /* Wait for a reply... */
16011   W (ret);
16012   return ret;
16013 }
16014
16015 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16016
16017 static int
16018 api_one_eid_table_dump (vat_main_t * vam)
16019 {
16020   unformat_input_t *i = vam->input;
16021   vl_api_one_eid_table_dump_t *mp;
16022   vl_api_control_ping_t *mp_ping;
16023   struct in_addr ip4;
16024   struct in6_addr ip6;
16025   u8 mac[6];
16026   u8 eid_type = ~0, eid_set = 0;
16027   u32 prefix_length = ~0, t, vni = 0;
16028   u8 filter = 0;
16029   int ret;
16030
16031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16032     {
16033       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16034         {
16035           eid_set = 1;
16036           eid_type = 0;
16037           prefix_length = t;
16038         }
16039       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16040         {
16041           eid_set = 1;
16042           eid_type = 1;
16043           prefix_length = t;
16044         }
16045       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16046         {
16047           eid_set = 1;
16048           eid_type = 2;
16049         }
16050       else if (unformat (i, "vni %d", &t))
16051         {
16052           vni = t;
16053         }
16054       else if (unformat (i, "local"))
16055         {
16056           filter = 1;
16057         }
16058       else if (unformat (i, "remote"))
16059         {
16060           filter = 2;
16061         }
16062       else
16063         {
16064           errmsg ("parse error '%U'", format_unformat_error, i);
16065           return -99;
16066         }
16067     }
16068
16069   if (!vam->json_output)
16070     {
16071       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16072              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16073     }
16074
16075   M (ONE_EID_TABLE_DUMP, mp);
16076
16077   mp->filter = filter;
16078   if (eid_set)
16079     {
16080       mp->eid_set = 1;
16081       mp->vni = htonl (vni);
16082       mp->eid_type = eid_type;
16083       switch (eid_type)
16084         {
16085         case 0:
16086           mp->prefix_length = prefix_length;
16087           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16088           break;
16089         case 1:
16090           mp->prefix_length = prefix_length;
16091           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16092           break;
16093         case 2:
16094           clib_memcpy (mp->eid, mac, sizeof (mac));
16095           break;
16096         default:
16097           errmsg ("unknown EID type %d!", eid_type);
16098           return -99;
16099         }
16100     }
16101
16102   /* send it... */
16103   S (mp);
16104
16105   /* Use a control ping for synchronization */
16106   M (CONTROL_PING, mp_ping);
16107   S (mp_ping);
16108
16109   /* Wait for a reply... */
16110   W (ret);
16111   return ret;
16112 }
16113
16114 #define api_lisp_eid_table_dump api_one_eid_table_dump
16115
16116 static int
16117 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16118 {
16119   unformat_input_t *i = vam->input;
16120   vl_api_gpe_fwd_entries_get_t *mp;
16121   u8 vni_set = 0;
16122   u32 vni = ~0;
16123   int ret;
16124
16125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16126     {
16127       if (unformat (i, "vni %d", &vni))
16128         {
16129           vni_set = 1;
16130         }
16131       else
16132         {
16133           errmsg ("parse error '%U'", format_unformat_error, i);
16134           return -99;
16135         }
16136     }
16137
16138   if (!vni_set)
16139     {
16140       errmsg ("vni not set!");
16141       return -99;
16142     }
16143
16144   if (!vam->json_output)
16145     {
16146       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16147              "leid", "reid");
16148     }
16149
16150   M (GPE_FWD_ENTRIES_GET, mp);
16151   mp->vni = clib_host_to_net_u32 (vni);
16152
16153   /* send it... */
16154   S (mp);
16155
16156   /* Wait for a reply... */
16157   W (ret);
16158   return ret;
16159 }
16160
16161 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16162 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16163 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16164 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16165 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16166 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16167
16168 static int
16169 api_one_adjacencies_get (vat_main_t * vam)
16170 {
16171   unformat_input_t *i = vam->input;
16172   vl_api_one_adjacencies_get_t *mp;
16173   u8 vni_set = 0;
16174   u32 vni = ~0;
16175   int ret;
16176
16177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16178     {
16179       if (unformat (i, "vni %d", &vni))
16180         {
16181           vni_set = 1;
16182         }
16183       else
16184         {
16185           errmsg ("parse error '%U'", format_unformat_error, i);
16186           return -99;
16187         }
16188     }
16189
16190   if (!vni_set)
16191     {
16192       errmsg ("vni not set!");
16193       return -99;
16194     }
16195
16196   if (!vam->json_output)
16197     {
16198       print (vam->ofp, "%s %40s", "leid", "reid");
16199     }
16200
16201   M (ONE_ADJACENCIES_GET, mp);
16202   mp->vni = clib_host_to_net_u32 (vni);
16203
16204   /* send it... */
16205   S (mp);
16206
16207   /* Wait for a reply... */
16208   W (ret);
16209   return ret;
16210 }
16211
16212 #define api_lisp_adjacencies_get api_one_adjacencies_get
16213
16214 static int
16215 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16216 {
16217   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16218   int ret;
16219
16220   if (!vam->json_output)
16221     {
16222       print (vam->ofp, "VNIs");
16223     }
16224
16225   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16226
16227   /* send it... */
16228   S (mp);
16229
16230   /* Wait for a reply... */
16231   W (ret);
16232   return ret;
16233 }
16234
16235 static int
16236 api_one_map_server_dump (vat_main_t * vam)
16237 {
16238   vl_api_one_map_server_dump_t *mp;
16239   vl_api_control_ping_t *mp_ping;
16240   int ret;
16241
16242   if (!vam->json_output)
16243     {
16244       print (vam->ofp, "%=20s", "Map server");
16245     }
16246
16247   M (ONE_MAP_SERVER_DUMP, mp);
16248   /* send it... */
16249   S (mp);
16250
16251   /* Use a control ping for synchronization */
16252   M (CONTROL_PING, mp_ping);
16253   S (mp_ping);
16254
16255   /* Wait for a reply... */
16256   W (ret);
16257   return ret;
16258 }
16259
16260 #define api_lisp_map_server_dump api_one_map_server_dump
16261
16262 static int
16263 api_one_map_resolver_dump (vat_main_t * vam)
16264 {
16265   vl_api_one_map_resolver_dump_t *mp;
16266   vl_api_control_ping_t *mp_ping;
16267   int ret;
16268
16269   if (!vam->json_output)
16270     {
16271       print (vam->ofp, "%=20s", "Map resolver");
16272     }
16273
16274   M (ONE_MAP_RESOLVER_DUMP, mp);
16275   /* send it... */
16276   S (mp);
16277
16278   /* Use a control ping for synchronization */
16279   M (CONTROL_PING, mp_ping);
16280   S (mp_ping);
16281
16282   /* Wait for a reply... */
16283   W (ret);
16284   return ret;
16285 }
16286
16287 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16288
16289 static int
16290 api_one_stats_flush (vat_main_t * vam)
16291 {
16292   vl_api_one_stats_flush_t *mp;
16293   int ret = 0;
16294
16295   M (ONE_STATS_FLUSH, mp);
16296   S (mp);
16297   W (ret);
16298   return ret;
16299 }
16300
16301 static int
16302 api_one_stats_dump (vat_main_t * vam)
16303 {
16304   vl_api_one_stats_dump_t *mp;
16305   vl_api_control_ping_t *mp_ping;
16306   int ret;
16307
16308   M (ONE_STATS_DUMP, mp);
16309   /* send it... */
16310   S (mp);
16311
16312   /* Use a control ping for synchronization */
16313   M (CONTROL_PING, mp_ping);
16314   S (mp_ping);
16315
16316   /* Wait for a reply... */
16317   W (ret);
16318   return ret;
16319 }
16320
16321 static int
16322 api_show_one_status (vat_main_t * vam)
16323 {
16324   vl_api_show_one_status_t *mp;
16325   int ret;
16326
16327   if (!vam->json_output)
16328     {
16329       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16330     }
16331
16332   M (SHOW_ONE_STATUS, mp);
16333   /* send it... */
16334   S (mp);
16335   /* Wait for a reply... */
16336   W (ret);
16337   return ret;
16338 }
16339
16340 #define api_show_lisp_status api_show_one_status
16341
16342 static int
16343 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16344 {
16345   vl_api_gpe_fwd_entry_path_dump_t *mp;
16346   vl_api_control_ping_t *mp_ping;
16347   unformat_input_t *i = vam->input;
16348   u32 fwd_entry_index = ~0;
16349   int ret;
16350
16351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16352     {
16353       if (unformat (i, "index %d", &fwd_entry_index))
16354         ;
16355       else
16356         break;
16357     }
16358
16359   if (~0 == fwd_entry_index)
16360     {
16361       errmsg ("no index specified!");
16362       return -99;
16363     }
16364
16365   if (!vam->json_output)
16366     {
16367       print (vam->ofp, "first line");
16368     }
16369
16370   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16371
16372   /* send it... */
16373   S (mp);
16374   /* Use a control ping for synchronization */
16375   M (CONTROL_PING, mp_ping);
16376   S (mp_ping);
16377
16378   /* Wait for a reply... */
16379   W (ret);
16380   return ret;
16381 }
16382
16383 static int
16384 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16385 {
16386   vl_api_one_get_map_request_itr_rlocs_t *mp;
16387   int ret;
16388
16389   if (!vam->json_output)
16390     {
16391       print (vam->ofp, "%=20s", "itr-rlocs:");
16392     }
16393
16394   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16395   /* send it... */
16396   S (mp);
16397   /* Wait for a reply... */
16398   W (ret);
16399   return ret;
16400 }
16401
16402 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16403
16404 static int
16405 api_af_packet_create (vat_main_t * vam)
16406 {
16407   unformat_input_t *i = vam->input;
16408   vl_api_af_packet_create_t *mp;
16409   u8 *host_if_name = 0;
16410   u8 hw_addr[6];
16411   u8 random_hw_addr = 1;
16412   int ret;
16413
16414   memset (hw_addr, 0, sizeof (hw_addr));
16415
16416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16417     {
16418       if (unformat (i, "name %s", &host_if_name))
16419         vec_add1 (host_if_name, 0);
16420       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16421         random_hw_addr = 0;
16422       else
16423         break;
16424     }
16425
16426   if (!vec_len (host_if_name))
16427     {
16428       errmsg ("host-interface name must be specified");
16429       return -99;
16430     }
16431
16432   if (vec_len (host_if_name) > 64)
16433     {
16434       errmsg ("host-interface name too long");
16435       return -99;
16436     }
16437
16438   M (AF_PACKET_CREATE, mp);
16439
16440   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16441   clib_memcpy (mp->hw_addr, hw_addr, 6);
16442   mp->use_random_hw_addr = random_hw_addr;
16443   vec_free (host_if_name);
16444
16445   S (mp);
16446
16447   /* *INDENT-OFF* */
16448   W2 (ret,
16449       ({
16450         if (ret == 0)
16451           fprintf (vam->ofp ? vam->ofp : stderr,
16452                    " new sw_if_index = %d\n", vam->sw_if_index);
16453       }));
16454   /* *INDENT-ON* */
16455   return ret;
16456 }
16457
16458 static int
16459 api_af_packet_delete (vat_main_t * vam)
16460 {
16461   unformat_input_t *i = vam->input;
16462   vl_api_af_packet_delete_t *mp;
16463   u8 *host_if_name = 0;
16464   int ret;
16465
16466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16467     {
16468       if (unformat (i, "name %s", &host_if_name))
16469         vec_add1 (host_if_name, 0);
16470       else
16471         break;
16472     }
16473
16474   if (!vec_len (host_if_name))
16475     {
16476       errmsg ("host-interface name must be specified");
16477       return -99;
16478     }
16479
16480   if (vec_len (host_if_name) > 64)
16481     {
16482       errmsg ("host-interface name too long");
16483       return -99;
16484     }
16485
16486   M (AF_PACKET_DELETE, mp);
16487
16488   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16489   vec_free (host_if_name);
16490
16491   S (mp);
16492   W (ret);
16493   return ret;
16494 }
16495
16496 static int
16497 api_policer_add_del (vat_main_t * vam)
16498 {
16499   unformat_input_t *i = vam->input;
16500   vl_api_policer_add_del_t *mp;
16501   u8 is_add = 1;
16502   u8 *name = 0;
16503   u32 cir = 0;
16504   u32 eir = 0;
16505   u64 cb = 0;
16506   u64 eb = 0;
16507   u8 rate_type = 0;
16508   u8 round_type = 0;
16509   u8 type = 0;
16510   u8 color_aware = 0;
16511   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16512   int ret;
16513
16514   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16515   conform_action.dscp = 0;
16516   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16517   exceed_action.dscp = 0;
16518   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16519   violate_action.dscp = 0;
16520
16521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16522     {
16523       if (unformat (i, "del"))
16524         is_add = 0;
16525       else if (unformat (i, "name %s", &name))
16526         vec_add1 (name, 0);
16527       else if (unformat (i, "cir %u", &cir))
16528         ;
16529       else if (unformat (i, "eir %u", &eir))
16530         ;
16531       else if (unformat (i, "cb %u", &cb))
16532         ;
16533       else if (unformat (i, "eb %u", &eb))
16534         ;
16535       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16536                          &rate_type))
16537         ;
16538       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16539                          &round_type))
16540         ;
16541       else if (unformat (i, "type %U", unformat_policer_type, &type))
16542         ;
16543       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16544                          &conform_action))
16545         ;
16546       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16547                          &exceed_action))
16548         ;
16549       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16550                          &violate_action))
16551         ;
16552       else if (unformat (i, "color-aware"))
16553         color_aware = 1;
16554       else
16555         break;
16556     }
16557
16558   if (!vec_len (name))
16559     {
16560       errmsg ("policer name must be specified");
16561       return -99;
16562     }
16563
16564   if (vec_len (name) > 64)
16565     {
16566       errmsg ("policer name too long");
16567       return -99;
16568     }
16569
16570   M (POLICER_ADD_DEL, mp);
16571
16572   clib_memcpy (mp->name, name, vec_len (name));
16573   vec_free (name);
16574   mp->is_add = is_add;
16575   mp->cir = cir;
16576   mp->eir = eir;
16577   mp->cb = cb;
16578   mp->eb = eb;
16579   mp->rate_type = rate_type;
16580   mp->round_type = round_type;
16581   mp->type = type;
16582   mp->conform_action_type = conform_action.action_type;
16583   mp->conform_dscp = conform_action.dscp;
16584   mp->exceed_action_type = exceed_action.action_type;
16585   mp->exceed_dscp = exceed_action.dscp;
16586   mp->violate_action_type = violate_action.action_type;
16587   mp->violate_dscp = violate_action.dscp;
16588   mp->color_aware = color_aware;
16589
16590   S (mp);
16591   W (ret);
16592   return ret;
16593 }
16594
16595 static int
16596 api_policer_dump (vat_main_t * vam)
16597 {
16598   unformat_input_t *i = vam->input;
16599   vl_api_policer_dump_t *mp;
16600   vl_api_control_ping_t *mp_ping;
16601   u8 *match_name = 0;
16602   u8 match_name_valid = 0;
16603   int ret;
16604
16605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16606     {
16607       if (unformat (i, "name %s", &match_name))
16608         {
16609           vec_add1 (match_name, 0);
16610           match_name_valid = 1;
16611         }
16612       else
16613         break;
16614     }
16615
16616   M (POLICER_DUMP, mp);
16617   mp->match_name_valid = match_name_valid;
16618   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16619   vec_free (match_name);
16620   /* send it... */
16621   S (mp);
16622
16623   /* Use a control ping for synchronization */
16624   M (CONTROL_PING, mp_ping);
16625   S (mp_ping);
16626
16627   /* Wait for a reply... */
16628   W (ret);
16629   return ret;
16630 }
16631
16632 static int
16633 api_policer_classify_set_interface (vat_main_t * vam)
16634 {
16635   unformat_input_t *i = vam->input;
16636   vl_api_policer_classify_set_interface_t *mp;
16637   u32 sw_if_index;
16638   int sw_if_index_set;
16639   u32 ip4_table_index = ~0;
16640   u32 ip6_table_index = ~0;
16641   u32 l2_table_index = ~0;
16642   u8 is_add = 1;
16643   int ret;
16644
16645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16646     {
16647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16648         sw_if_index_set = 1;
16649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16650         sw_if_index_set = 1;
16651       else if (unformat (i, "del"))
16652         is_add = 0;
16653       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16654         ;
16655       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16656         ;
16657       else if (unformat (i, "l2-table %d", &l2_table_index))
16658         ;
16659       else
16660         {
16661           clib_warning ("parse error '%U'", format_unformat_error, i);
16662           return -99;
16663         }
16664     }
16665
16666   if (sw_if_index_set == 0)
16667     {
16668       errmsg ("missing interface name or sw_if_index");
16669       return -99;
16670     }
16671
16672   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16673
16674   mp->sw_if_index = ntohl (sw_if_index);
16675   mp->ip4_table_index = ntohl (ip4_table_index);
16676   mp->ip6_table_index = ntohl (ip6_table_index);
16677   mp->l2_table_index = ntohl (l2_table_index);
16678   mp->is_add = is_add;
16679
16680   S (mp);
16681   W (ret);
16682   return ret;
16683 }
16684
16685 static int
16686 api_policer_classify_dump (vat_main_t * vam)
16687 {
16688   unformat_input_t *i = vam->input;
16689   vl_api_policer_classify_dump_t *mp;
16690   vl_api_control_ping_t *mp_ping;
16691   u8 type = POLICER_CLASSIFY_N_TABLES;
16692   int ret;
16693
16694   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16695     ;
16696   else
16697     {
16698       errmsg ("classify table type must be specified");
16699       return -99;
16700     }
16701
16702   if (!vam->json_output)
16703     {
16704       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16705     }
16706
16707   M (POLICER_CLASSIFY_DUMP, mp);
16708   mp->type = type;
16709   /* send it... */
16710   S (mp);
16711
16712   /* Use a control ping for synchronization */
16713   M (CONTROL_PING, mp_ping);
16714   S (mp_ping);
16715
16716   /* Wait for a reply... */
16717   W (ret);
16718   return ret;
16719 }
16720
16721 static int
16722 api_netmap_create (vat_main_t * vam)
16723 {
16724   unformat_input_t *i = vam->input;
16725   vl_api_netmap_create_t *mp;
16726   u8 *if_name = 0;
16727   u8 hw_addr[6];
16728   u8 random_hw_addr = 1;
16729   u8 is_pipe = 0;
16730   u8 is_master = 0;
16731   int ret;
16732
16733   memset (hw_addr, 0, sizeof (hw_addr));
16734
16735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16736     {
16737       if (unformat (i, "name %s", &if_name))
16738         vec_add1 (if_name, 0);
16739       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16740         random_hw_addr = 0;
16741       else if (unformat (i, "pipe"))
16742         is_pipe = 1;
16743       else if (unformat (i, "master"))
16744         is_master = 1;
16745       else if (unformat (i, "slave"))
16746         is_master = 0;
16747       else
16748         break;
16749     }
16750
16751   if (!vec_len (if_name))
16752     {
16753       errmsg ("interface name must be specified");
16754       return -99;
16755     }
16756
16757   if (vec_len (if_name) > 64)
16758     {
16759       errmsg ("interface name too long");
16760       return -99;
16761     }
16762
16763   M (NETMAP_CREATE, mp);
16764
16765   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16766   clib_memcpy (mp->hw_addr, hw_addr, 6);
16767   mp->use_random_hw_addr = random_hw_addr;
16768   mp->is_pipe = is_pipe;
16769   mp->is_master = is_master;
16770   vec_free (if_name);
16771
16772   S (mp);
16773   W (ret);
16774   return ret;
16775 }
16776
16777 static int
16778 api_netmap_delete (vat_main_t * vam)
16779 {
16780   unformat_input_t *i = vam->input;
16781   vl_api_netmap_delete_t *mp;
16782   u8 *if_name = 0;
16783   int ret;
16784
16785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16786     {
16787       if (unformat (i, "name %s", &if_name))
16788         vec_add1 (if_name, 0);
16789       else
16790         break;
16791     }
16792
16793   if (!vec_len (if_name))
16794     {
16795       errmsg ("interface name must be specified");
16796       return -99;
16797     }
16798
16799   if (vec_len (if_name) > 64)
16800     {
16801       errmsg ("interface name too long");
16802       return -99;
16803     }
16804
16805   M (NETMAP_DELETE, mp);
16806
16807   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16808   vec_free (if_name);
16809
16810   S (mp);
16811   W (ret);
16812   return ret;
16813 }
16814
16815 static void
16816 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16817 {
16818   if (fp->afi == IP46_TYPE_IP6)
16819     print (vam->ofp,
16820            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16821            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16822            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16823            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16824            format_ip6_address, fp->next_hop);
16825   else if (fp->afi == IP46_TYPE_IP4)
16826     print (vam->ofp,
16827            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16828            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16829            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16830            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16831            format_ip4_address, fp->next_hop);
16832 }
16833
16834 static void
16835 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16836                                  vl_api_fib_path2_t * fp)
16837 {
16838   struct in_addr ip4;
16839   struct in6_addr ip6;
16840
16841   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16842   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16843   vat_json_object_add_uint (node, "is_local", fp->is_local);
16844   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16845   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16846   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16847   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16848   if (fp->afi == IP46_TYPE_IP4)
16849     {
16850       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16851       vat_json_object_add_ip4 (node, "next_hop", ip4);
16852     }
16853   else if (fp->afi == IP46_TYPE_IP6)
16854     {
16855       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16856       vat_json_object_add_ip6 (node, "next_hop", ip6);
16857     }
16858 }
16859
16860 static void
16861 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16862 {
16863   vat_main_t *vam = &vat_main;
16864   int count = ntohl (mp->mt_count);
16865   vl_api_fib_path2_t *fp;
16866   i32 i;
16867
16868   print (vam->ofp, "[%d]: sw_if_index %d via:",
16869          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16870   fp = mp->mt_paths;
16871   for (i = 0; i < count; i++)
16872     {
16873       vl_api_mpls_fib_path_print (vam, fp);
16874       fp++;
16875     }
16876
16877   print (vam->ofp, "");
16878 }
16879
16880 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16881 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16882
16883 static void
16884 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16885 {
16886   vat_main_t *vam = &vat_main;
16887   vat_json_node_t *node = NULL;
16888   int count = ntohl (mp->mt_count);
16889   vl_api_fib_path2_t *fp;
16890   i32 i;
16891
16892   if (VAT_JSON_ARRAY != vam->json_tree.type)
16893     {
16894       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16895       vat_json_init_array (&vam->json_tree);
16896     }
16897   node = vat_json_array_add (&vam->json_tree);
16898
16899   vat_json_init_object (node);
16900   vat_json_object_add_uint (node, "tunnel_index",
16901                             ntohl (mp->mt_tunnel_index));
16902   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16903
16904   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16905
16906   fp = mp->mt_paths;
16907   for (i = 0; i < count; i++)
16908     {
16909       vl_api_mpls_fib_path_json_print (node, fp);
16910       fp++;
16911     }
16912 }
16913
16914 static int
16915 api_mpls_tunnel_dump (vat_main_t * vam)
16916 {
16917   vl_api_mpls_tunnel_dump_t *mp;
16918   vl_api_control_ping_t *mp_ping;
16919   i32 index = -1;
16920   int ret;
16921
16922   /* Parse args required to build the message */
16923   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16924     {
16925       if (!unformat (vam->input, "tunnel_index %d", &index))
16926         {
16927           index = -1;
16928           break;
16929         }
16930     }
16931
16932   print (vam->ofp, "  tunnel_index %d", index);
16933
16934   M (MPLS_TUNNEL_DUMP, mp);
16935   mp->tunnel_index = htonl (index);
16936   S (mp);
16937
16938   /* Use a control ping for synchronization */
16939   M (CONTROL_PING, mp_ping);
16940   S (mp_ping);
16941
16942   W (ret);
16943   return ret;
16944 }
16945
16946 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16947 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16948
16949
16950 static void
16951 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16952 {
16953   vat_main_t *vam = &vat_main;
16954   int count = ntohl (mp->count);
16955   vl_api_fib_path2_t *fp;
16956   int i;
16957
16958   print (vam->ofp,
16959          "table-id %d, label %u, ess_bit %u",
16960          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16961   fp = mp->path;
16962   for (i = 0; i < count; i++)
16963     {
16964       vl_api_mpls_fib_path_print (vam, fp);
16965       fp++;
16966     }
16967 }
16968
16969 static void vl_api_mpls_fib_details_t_handler_json
16970   (vl_api_mpls_fib_details_t * mp)
16971 {
16972   vat_main_t *vam = &vat_main;
16973   int count = ntohl (mp->count);
16974   vat_json_node_t *node = NULL;
16975   vl_api_fib_path2_t *fp;
16976   int i;
16977
16978   if (VAT_JSON_ARRAY != vam->json_tree.type)
16979     {
16980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16981       vat_json_init_array (&vam->json_tree);
16982     }
16983   node = vat_json_array_add (&vam->json_tree);
16984
16985   vat_json_init_object (node);
16986   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16987   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16988   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16989   vat_json_object_add_uint (node, "path_count", count);
16990   fp = mp->path;
16991   for (i = 0; i < count; i++)
16992     {
16993       vl_api_mpls_fib_path_json_print (node, fp);
16994       fp++;
16995     }
16996 }
16997
16998 static int
16999 api_mpls_fib_dump (vat_main_t * vam)
17000 {
17001   vl_api_mpls_fib_dump_t *mp;
17002   vl_api_control_ping_t *mp_ping;
17003   int ret;
17004
17005   M (MPLS_FIB_DUMP, mp);
17006   S (mp);
17007
17008   /* Use a control ping for synchronization */
17009   M (CONTROL_PING, mp_ping);
17010   S (mp_ping);
17011
17012   W (ret);
17013   return ret;
17014 }
17015
17016 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17017 #define vl_api_ip_fib_details_t_print vl_noop_handler
17018
17019 static void
17020 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17021 {
17022   vat_main_t *vam = &vat_main;
17023   int count = ntohl (mp->count);
17024   vl_api_fib_path_t *fp;
17025   int i;
17026
17027   print (vam->ofp,
17028          "table-id %d, prefix %U/%d",
17029          ntohl (mp->table_id), format_ip4_address, mp->address,
17030          mp->address_length);
17031   fp = mp->path;
17032   for (i = 0; i < count; i++)
17033     {
17034       if (fp->afi == IP46_TYPE_IP6)
17035         print (vam->ofp,
17036                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17037                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17038                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17039                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17040                format_ip6_address, fp->next_hop);
17041       else if (fp->afi == IP46_TYPE_IP4)
17042         print (vam->ofp,
17043                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17044                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17045                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17046                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17047                format_ip4_address, fp->next_hop);
17048       fp++;
17049     }
17050 }
17051
17052 static void vl_api_ip_fib_details_t_handler_json
17053   (vl_api_ip_fib_details_t * mp)
17054 {
17055   vat_main_t *vam = &vat_main;
17056   int count = ntohl (mp->count);
17057   vat_json_node_t *node = NULL;
17058   struct in_addr ip4;
17059   struct in6_addr ip6;
17060   vl_api_fib_path_t *fp;
17061   int i;
17062
17063   if (VAT_JSON_ARRAY != vam->json_tree.type)
17064     {
17065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17066       vat_json_init_array (&vam->json_tree);
17067     }
17068   node = vat_json_array_add (&vam->json_tree);
17069
17070   vat_json_init_object (node);
17071   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17072   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17073   vat_json_object_add_ip4 (node, "prefix", ip4);
17074   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17075   vat_json_object_add_uint (node, "path_count", count);
17076   fp = mp->path;
17077   for (i = 0; i < count; i++)
17078     {
17079       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17080       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17081       vat_json_object_add_uint (node, "is_local", fp->is_local);
17082       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17083       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17084       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17085       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17086       if (fp->afi == IP46_TYPE_IP4)
17087         {
17088           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17089           vat_json_object_add_ip4 (node, "next_hop", ip4);
17090         }
17091       else if (fp->afi == IP46_TYPE_IP6)
17092         {
17093           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17094           vat_json_object_add_ip6 (node, "next_hop", ip6);
17095         }
17096     }
17097 }
17098
17099 static int
17100 api_ip_fib_dump (vat_main_t * vam)
17101 {
17102   vl_api_ip_fib_dump_t *mp;
17103   vl_api_control_ping_t *mp_ping;
17104   int ret;
17105
17106   M (IP_FIB_DUMP, mp);
17107   S (mp);
17108
17109   /* Use a control ping for synchronization */
17110   M (CONTROL_PING, mp_ping);
17111   S (mp_ping);
17112
17113   W (ret);
17114   return ret;
17115 }
17116
17117 static int
17118 api_ip_mfib_dump (vat_main_t * vam)
17119 {
17120   vl_api_ip_mfib_dump_t *mp;
17121   vl_api_control_ping_t *mp_ping;
17122   int ret;
17123
17124   M (IP_MFIB_DUMP, mp);
17125   S (mp);
17126
17127   /* Use a control ping for synchronization */
17128   M (CONTROL_PING, mp_ping);
17129   S (mp_ping);
17130
17131   W (ret);
17132   return ret;
17133 }
17134
17135 static void vl_api_ip_neighbor_details_t_handler
17136   (vl_api_ip_neighbor_details_t * mp)
17137 {
17138   vat_main_t *vam = &vat_main;
17139
17140   print (vam->ofp, "%c %U %U",
17141          (mp->is_static) ? 'S' : 'D',
17142          format_ethernet_address, &mp->mac_address,
17143          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17144          &mp->ip_address);
17145 }
17146
17147 static void vl_api_ip_neighbor_details_t_handler_json
17148   (vl_api_ip_neighbor_details_t * mp)
17149 {
17150
17151   vat_main_t *vam = &vat_main;
17152   vat_json_node_t *node;
17153   struct in_addr ip4;
17154   struct in6_addr ip6;
17155
17156   if (VAT_JSON_ARRAY != vam->json_tree.type)
17157     {
17158       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17159       vat_json_init_array (&vam->json_tree);
17160     }
17161   node = vat_json_array_add (&vam->json_tree);
17162
17163   vat_json_init_object (node);
17164   vat_json_object_add_string_copy (node, "flag",
17165                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17166                                    "dynamic");
17167
17168   vat_json_object_add_string_copy (node, "link_layer",
17169                                    format (0, "%U", format_ethernet_address,
17170                                            &mp->mac_address));
17171
17172   if (mp->is_ipv6)
17173     {
17174       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17175       vat_json_object_add_ip6 (node, "ip_address", ip6);
17176     }
17177   else
17178     {
17179       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17180       vat_json_object_add_ip4 (node, "ip_address", ip4);
17181     }
17182 }
17183
17184 static int
17185 api_ip_neighbor_dump (vat_main_t * vam)
17186 {
17187   unformat_input_t *i = vam->input;
17188   vl_api_ip_neighbor_dump_t *mp;
17189   vl_api_control_ping_t *mp_ping;
17190   u8 is_ipv6 = 0;
17191   u32 sw_if_index = ~0;
17192   int ret;
17193
17194   /* Parse args required to build the message */
17195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17196     {
17197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17198         ;
17199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17200         ;
17201       else if (unformat (i, "ip6"))
17202         is_ipv6 = 1;
17203       else
17204         break;
17205     }
17206
17207   if (sw_if_index == ~0)
17208     {
17209       errmsg ("missing interface name or sw_if_index");
17210       return -99;
17211     }
17212
17213   M (IP_NEIGHBOR_DUMP, mp);
17214   mp->is_ipv6 = (u8) is_ipv6;
17215   mp->sw_if_index = ntohl (sw_if_index);
17216   S (mp);
17217
17218   /* Use a control ping for synchronization */
17219   M (CONTROL_PING, mp_ping);
17220   S (mp_ping);
17221
17222   W (ret);
17223   return ret;
17224 }
17225
17226 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17227 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17228
17229 static void
17230 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17231 {
17232   vat_main_t *vam = &vat_main;
17233   int count = ntohl (mp->count);
17234   vl_api_fib_path_t *fp;
17235   int i;
17236
17237   print (vam->ofp,
17238          "table-id %d, prefix %U/%d",
17239          ntohl (mp->table_id), format_ip6_address, mp->address,
17240          mp->address_length);
17241   fp = mp->path;
17242   for (i = 0; i < count; i++)
17243     {
17244       if (fp->afi == IP46_TYPE_IP6)
17245         print (vam->ofp,
17246                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17247                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17248                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17249                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17250                format_ip6_address, fp->next_hop);
17251       else if (fp->afi == IP46_TYPE_IP4)
17252         print (vam->ofp,
17253                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17254                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17255                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17256                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17257                format_ip4_address, fp->next_hop);
17258       fp++;
17259     }
17260 }
17261
17262 static void vl_api_ip6_fib_details_t_handler_json
17263   (vl_api_ip6_fib_details_t * mp)
17264 {
17265   vat_main_t *vam = &vat_main;
17266   int count = ntohl (mp->count);
17267   vat_json_node_t *node = NULL;
17268   struct in_addr ip4;
17269   struct in6_addr ip6;
17270   vl_api_fib_path_t *fp;
17271   int i;
17272
17273   if (VAT_JSON_ARRAY != vam->json_tree.type)
17274     {
17275       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17276       vat_json_init_array (&vam->json_tree);
17277     }
17278   node = vat_json_array_add (&vam->json_tree);
17279
17280   vat_json_init_object (node);
17281   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17282   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17283   vat_json_object_add_ip6 (node, "prefix", ip6);
17284   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17285   vat_json_object_add_uint (node, "path_count", count);
17286   fp = mp->path;
17287   for (i = 0; i < count; i++)
17288     {
17289       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17290       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17291       vat_json_object_add_uint (node, "is_local", fp->is_local);
17292       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17293       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17294       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17295       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17296       if (fp->afi == IP46_TYPE_IP4)
17297         {
17298           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17299           vat_json_object_add_ip4 (node, "next_hop", ip4);
17300         }
17301       else if (fp->afi == IP46_TYPE_IP6)
17302         {
17303           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17304           vat_json_object_add_ip6 (node, "next_hop", ip6);
17305         }
17306     }
17307 }
17308
17309 static int
17310 api_ip6_fib_dump (vat_main_t * vam)
17311 {
17312   vl_api_ip6_fib_dump_t *mp;
17313   vl_api_control_ping_t *mp_ping;
17314   int ret;
17315
17316   M (IP6_FIB_DUMP, mp);
17317   S (mp);
17318
17319   /* Use a control ping for synchronization */
17320   M (CONTROL_PING, mp_ping);
17321   S (mp_ping);
17322
17323   W (ret);
17324   return ret;
17325 }
17326
17327 static int
17328 api_ip6_mfib_dump (vat_main_t * vam)
17329 {
17330   vl_api_ip6_mfib_dump_t *mp;
17331   vl_api_control_ping_t *mp_ping;
17332   int ret;
17333
17334   M (IP6_MFIB_DUMP, mp);
17335   S (mp);
17336
17337   /* Use a control ping for synchronization */
17338   M (CONTROL_PING, mp_ping);
17339   S (mp_ping);
17340
17341   W (ret);
17342   return ret;
17343 }
17344
17345 int
17346 api_classify_table_ids (vat_main_t * vam)
17347 {
17348   vl_api_classify_table_ids_t *mp;
17349   int ret;
17350
17351   /* Construct the API message */
17352   M (CLASSIFY_TABLE_IDS, mp);
17353   mp->context = 0;
17354
17355   S (mp);
17356   W (ret);
17357   return ret;
17358 }
17359
17360 int
17361 api_classify_table_by_interface (vat_main_t * vam)
17362 {
17363   unformat_input_t *input = vam->input;
17364   vl_api_classify_table_by_interface_t *mp;
17365
17366   u32 sw_if_index = ~0;
17367   int ret;
17368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17369     {
17370       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17371         ;
17372       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17373         ;
17374       else
17375         break;
17376     }
17377   if (sw_if_index == ~0)
17378     {
17379       errmsg ("missing interface name or sw_if_index");
17380       return -99;
17381     }
17382
17383   /* Construct the API message */
17384   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17385   mp->context = 0;
17386   mp->sw_if_index = ntohl (sw_if_index);
17387
17388   S (mp);
17389   W (ret);
17390   return ret;
17391 }
17392
17393 int
17394 api_classify_table_info (vat_main_t * vam)
17395 {
17396   unformat_input_t *input = vam->input;
17397   vl_api_classify_table_info_t *mp;
17398
17399   u32 table_id = ~0;
17400   int ret;
17401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17402     {
17403       if (unformat (input, "table_id %d", &table_id))
17404         ;
17405       else
17406         break;
17407     }
17408   if (table_id == ~0)
17409     {
17410       errmsg ("missing table id");
17411       return -99;
17412     }
17413
17414   /* Construct the API message */
17415   M (CLASSIFY_TABLE_INFO, mp);
17416   mp->context = 0;
17417   mp->table_id = ntohl (table_id);
17418
17419   S (mp);
17420   W (ret);
17421   return ret;
17422 }
17423
17424 int
17425 api_classify_session_dump (vat_main_t * vam)
17426 {
17427   unformat_input_t *input = vam->input;
17428   vl_api_classify_session_dump_t *mp;
17429   vl_api_control_ping_t *mp_ping;
17430
17431   u32 table_id = ~0;
17432   int ret;
17433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17434     {
17435       if (unformat (input, "table_id %d", &table_id))
17436         ;
17437       else
17438         break;
17439     }
17440   if (table_id == ~0)
17441     {
17442       errmsg ("missing table id");
17443       return -99;
17444     }
17445
17446   /* Construct the API message */
17447   M (CLASSIFY_SESSION_DUMP, mp);
17448   mp->context = 0;
17449   mp->table_id = ntohl (table_id);
17450   S (mp);
17451
17452   /* Use a control ping for synchronization */
17453   M (CONTROL_PING, mp_ping);
17454   S (mp_ping);
17455
17456   W (ret);
17457   return ret;
17458 }
17459
17460 static void
17461 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17462 {
17463   vat_main_t *vam = &vat_main;
17464
17465   print (vam->ofp, "collector_address %U, collector_port %d, "
17466          "src_address %U, vrf_id %d, path_mtu %u, "
17467          "template_interval %u, udp_checksum %d",
17468          format_ip4_address, mp->collector_address,
17469          ntohs (mp->collector_port),
17470          format_ip4_address, mp->src_address,
17471          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17472          ntohl (mp->template_interval), mp->udp_checksum);
17473
17474   vam->retval = 0;
17475   vam->result_ready = 1;
17476 }
17477
17478 static void
17479   vl_api_ipfix_exporter_details_t_handler_json
17480   (vl_api_ipfix_exporter_details_t * mp)
17481 {
17482   vat_main_t *vam = &vat_main;
17483   vat_json_node_t node;
17484   struct in_addr collector_address;
17485   struct in_addr src_address;
17486
17487   vat_json_init_object (&node);
17488   clib_memcpy (&collector_address, &mp->collector_address,
17489                sizeof (collector_address));
17490   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17491   vat_json_object_add_uint (&node, "collector_port",
17492                             ntohs (mp->collector_port));
17493   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17494   vat_json_object_add_ip4 (&node, "src_address", src_address);
17495   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17496   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17497   vat_json_object_add_uint (&node, "template_interval",
17498                             ntohl (mp->template_interval));
17499   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17500
17501   vat_json_print (vam->ofp, &node);
17502   vat_json_free (&node);
17503   vam->retval = 0;
17504   vam->result_ready = 1;
17505 }
17506
17507 int
17508 api_ipfix_exporter_dump (vat_main_t * vam)
17509 {
17510   vl_api_ipfix_exporter_dump_t *mp;
17511   int ret;
17512
17513   /* Construct the API message */
17514   M (IPFIX_EXPORTER_DUMP, mp);
17515   mp->context = 0;
17516
17517   S (mp);
17518   W (ret);
17519   return ret;
17520 }
17521
17522 static int
17523 api_ipfix_classify_stream_dump (vat_main_t * vam)
17524 {
17525   vl_api_ipfix_classify_stream_dump_t *mp;
17526   int ret;
17527
17528   /* Construct the API message */
17529   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17530   mp->context = 0;
17531
17532   S (mp);
17533   W (ret);
17534   return ret;
17535   /* NOTREACHED */
17536   return 0;
17537 }
17538
17539 static void
17540   vl_api_ipfix_classify_stream_details_t_handler
17541   (vl_api_ipfix_classify_stream_details_t * mp)
17542 {
17543   vat_main_t *vam = &vat_main;
17544   print (vam->ofp, "domain_id %d, src_port %d",
17545          ntohl (mp->domain_id), ntohs (mp->src_port));
17546   vam->retval = 0;
17547   vam->result_ready = 1;
17548 }
17549
17550 static void
17551   vl_api_ipfix_classify_stream_details_t_handler_json
17552   (vl_api_ipfix_classify_stream_details_t * mp)
17553 {
17554   vat_main_t *vam = &vat_main;
17555   vat_json_node_t node;
17556
17557   vat_json_init_object (&node);
17558   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17559   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17560
17561   vat_json_print (vam->ofp, &node);
17562   vat_json_free (&node);
17563   vam->retval = 0;
17564   vam->result_ready = 1;
17565 }
17566
17567 static int
17568 api_ipfix_classify_table_dump (vat_main_t * vam)
17569 {
17570   vl_api_ipfix_classify_table_dump_t *mp;
17571   vl_api_control_ping_t *mp_ping;
17572   int ret;
17573
17574   if (!vam->json_output)
17575     {
17576       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17577              "transport_protocol");
17578     }
17579
17580   /* Construct the API message */
17581   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17582
17583   /* send it... */
17584   S (mp);
17585
17586   /* Use a control ping for synchronization */
17587   M (CONTROL_PING, mp_ping);
17588   S (mp_ping);
17589
17590   W (ret);
17591   return ret;
17592 }
17593
17594 static void
17595   vl_api_ipfix_classify_table_details_t_handler
17596   (vl_api_ipfix_classify_table_details_t * mp)
17597 {
17598   vat_main_t *vam = &vat_main;
17599   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17600          mp->transport_protocol);
17601 }
17602
17603 static void
17604   vl_api_ipfix_classify_table_details_t_handler_json
17605   (vl_api_ipfix_classify_table_details_t * mp)
17606 {
17607   vat_json_node_t *node = NULL;
17608   vat_main_t *vam = &vat_main;
17609
17610   if (VAT_JSON_ARRAY != vam->json_tree.type)
17611     {
17612       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17613       vat_json_init_array (&vam->json_tree);
17614     }
17615
17616   node = vat_json_array_add (&vam->json_tree);
17617   vat_json_init_object (node);
17618
17619   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17620   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17621   vat_json_object_add_uint (node, "transport_protocol",
17622                             mp->transport_protocol);
17623 }
17624
17625 static int
17626 api_sw_interface_span_enable_disable (vat_main_t * vam)
17627 {
17628   unformat_input_t *i = vam->input;
17629   vl_api_sw_interface_span_enable_disable_t *mp;
17630   u32 src_sw_if_index = ~0;
17631   u32 dst_sw_if_index = ~0;
17632   u8 state = 3;
17633   int ret;
17634
17635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17636     {
17637       if (unformat
17638           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17639         ;
17640       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17641         ;
17642       else
17643         if (unformat
17644             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17645         ;
17646       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17647         ;
17648       else if (unformat (i, "disable"))
17649         state = 0;
17650       else if (unformat (i, "rx"))
17651         state = 1;
17652       else if (unformat (i, "tx"))
17653         state = 2;
17654       else if (unformat (i, "both"))
17655         state = 3;
17656       else
17657         break;
17658     }
17659
17660   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17661
17662   mp->sw_if_index_from = htonl (src_sw_if_index);
17663   mp->sw_if_index_to = htonl (dst_sw_if_index);
17664   mp->state = state;
17665
17666   S (mp);
17667   W (ret);
17668   return ret;
17669 }
17670
17671 static void
17672 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17673                                             * mp)
17674 {
17675   vat_main_t *vam = &vat_main;
17676   u8 *sw_if_from_name = 0;
17677   u8 *sw_if_to_name = 0;
17678   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17679   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17680   char *states[] = { "none", "rx", "tx", "both" };
17681   hash_pair_t *p;
17682
17683   /* *INDENT-OFF* */
17684   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17685   ({
17686     if ((u32) p->value[0] == sw_if_index_from)
17687       {
17688         sw_if_from_name = (u8 *)(p->key);
17689         if (sw_if_to_name)
17690           break;
17691       }
17692     if ((u32) p->value[0] == sw_if_index_to)
17693       {
17694         sw_if_to_name = (u8 *)(p->key);
17695         if (sw_if_from_name)
17696           break;
17697       }
17698   }));
17699   /* *INDENT-ON* */
17700   print (vam->ofp, "%20s => %20s (%s)",
17701          sw_if_from_name, sw_if_to_name, states[mp->state]);
17702 }
17703
17704 static void
17705   vl_api_sw_interface_span_details_t_handler_json
17706   (vl_api_sw_interface_span_details_t * mp)
17707 {
17708   vat_main_t *vam = &vat_main;
17709   vat_json_node_t *node = NULL;
17710   u8 *sw_if_from_name = 0;
17711   u8 *sw_if_to_name = 0;
17712   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17713   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17714   hash_pair_t *p;
17715
17716   /* *INDENT-OFF* */
17717   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17718   ({
17719     if ((u32) p->value[0] == sw_if_index_from)
17720       {
17721         sw_if_from_name = (u8 *)(p->key);
17722         if (sw_if_to_name)
17723           break;
17724       }
17725     if ((u32) p->value[0] == sw_if_index_to)
17726       {
17727         sw_if_to_name = (u8 *)(p->key);
17728         if (sw_if_from_name)
17729           break;
17730       }
17731   }));
17732   /* *INDENT-ON* */
17733
17734   if (VAT_JSON_ARRAY != vam->json_tree.type)
17735     {
17736       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17737       vat_json_init_array (&vam->json_tree);
17738     }
17739   node = vat_json_array_add (&vam->json_tree);
17740
17741   vat_json_init_object (node);
17742   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17743   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17744   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17745   if (0 != sw_if_to_name)
17746     {
17747       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17748     }
17749   vat_json_object_add_uint (node, "state", mp->state);
17750 }
17751
17752 static int
17753 api_sw_interface_span_dump (vat_main_t * vam)
17754 {
17755   vl_api_sw_interface_span_dump_t *mp;
17756   vl_api_control_ping_t *mp_ping;
17757   int ret;
17758
17759   M (SW_INTERFACE_SPAN_DUMP, mp);
17760   S (mp);
17761
17762   /* Use a control ping for synchronization */
17763   M (CONTROL_PING, mp_ping);
17764   S (mp_ping);
17765
17766   W (ret);
17767   return ret;
17768 }
17769
17770 int
17771 api_pg_create_interface (vat_main_t * vam)
17772 {
17773   unformat_input_t *input = vam->input;
17774   vl_api_pg_create_interface_t *mp;
17775
17776   u32 if_id = ~0;
17777   int ret;
17778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17779     {
17780       if (unformat (input, "if_id %d", &if_id))
17781         ;
17782       else
17783         break;
17784     }
17785   if (if_id == ~0)
17786     {
17787       errmsg ("missing pg interface index");
17788       return -99;
17789     }
17790
17791   /* Construct the API message */
17792   M (PG_CREATE_INTERFACE, mp);
17793   mp->context = 0;
17794   mp->interface_id = ntohl (if_id);
17795
17796   S (mp);
17797   W (ret);
17798   return ret;
17799 }
17800
17801 int
17802 api_pg_capture (vat_main_t * vam)
17803 {
17804   unformat_input_t *input = vam->input;
17805   vl_api_pg_capture_t *mp;
17806
17807   u32 if_id = ~0;
17808   u8 enable = 1;
17809   u32 count = 1;
17810   u8 pcap_file_set = 0;
17811   u8 *pcap_file = 0;
17812   int ret;
17813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17814     {
17815       if (unformat (input, "if_id %d", &if_id))
17816         ;
17817       else if (unformat (input, "pcap %s", &pcap_file))
17818         pcap_file_set = 1;
17819       else if (unformat (input, "count %d", &count))
17820         ;
17821       else if (unformat (input, "disable"))
17822         enable = 0;
17823       else
17824         break;
17825     }
17826   if (if_id == ~0)
17827     {
17828       errmsg ("missing pg interface index");
17829       return -99;
17830     }
17831   if (pcap_file_set > 0)
17832     {
17833       if (vec_len (pcap_file) > 255)
17834         {
17835           errmsg ("pcap file name is too long");
17836           return -99;
17837         }
17838     }
17839
17840   u32 name_len = vec_len (pcap_file);
17841   /* Construct the API message */
17842   M (PG_CAPTURE, mp);
17843   mp->context = 0;
17844   mp->interface_id = ntohl (if_id);
17845   mp->is_enabled = enable;
17846   mp->count = ntohl (count);
17847   mp->pcap_name_length = ntohl (name_len);
17848   if (pcap_file_set != 0)
17849     {
17850       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17851     }
17852   vec_free (pcap_file);
17853
17854   S (mp);
17855   W (ret);
17856   return ret;
17857 }
17858
17859 int
17860 api_pg_enable_disable (vat_main_t * vam)
17861 {
17862   unformat_input_t *input = vam->input;
17863   vl_api_pg_enable_disable_t *mp;
17864
17865   u8 enable = 1;
17866   u8 stream_name_set = 0;
17867   u8 *stream_name = 0;
17868   int ret;
17869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17870     {
17871       if (unformat (input, "stream %s", &stream_name))
17872         stream_name_set = 1;
17873       else if (unformat (input, "disable"))
17874         enable = 0;
17875       else
17876         break;
17877     }
17878
17879   if (stream_name_set > 0)
17880     {
17881       if (vec_len (stream_name) > 255)
17882         {
17883           errmsg ("stream name too long");
17884           return -99;
17885         }
17886     }
17887
17888   u32 name_len = vec_len (stream_name);
17889   /* Construct the API message */
17890   M (PG_ENABLE_DISABLE, mp);
17891   mp->context = 0;
17892   mp->is_enabled = enable;
17893   if (stream_name_set != 0)
17894     {
17895       mp->stream_name_length = ntohl (name_len);
17896       clib_memcpy (mp->stream_name, stream_name, name_len);
17897     }
17898   vec_free (stream_name);
17899
17900   S (mp);
17901   W (ret);
17902   return ret;
17903 }
17904
17905 int
17906 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17907 {
17908   unformat_input_t *input = vam->input;
17909   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17910
17911   u16 *low_ports = 0;
17912   u16 *high_ports = 0;
17913   u16 this_low;
17914   u16 this_hi;
17915   ip4_address_t ip4_addr;
17916   ip6_address_t ip6_addr;
17917   u32 length;
17918   u32 tmp, tmp2;
17919   u8 prefix_set = 0;
17920   u32 vrf_id = ~0;
17921   u8 is_add = 1;
17922   u8 is_ipv6 = 0;
17923   int ret;
17924
17925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17926     {
17927       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17928         {
17929           prefix_set = 1;
17930         }
17931       else
17932         if (unformat
17933             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17934         {
17935           prefix_set = 1;
17936           is_ipv6 = 1;
17937         }
17938       else if (unformat (input, "vrf %d", &vrf_id))
17939         ;
17940       else if (unformat (input, "del"))
17941         is_add = 0;
17942       else if (unformat (input, "port %d", &tmp))
17943         {
17944           if (tmp == 0 || tmp > 65535)
17945             {
17946               errmsg ("port %d out of range", tmp);
17947               return -99;
17948             }
17949           this_low = tmp;
17950           this_hi = this_low + 1;
17951           vec_add1 (low_ports, this_low);
17952           vec_add1 (high_ports, this_hi);
17953         }
17954       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17955         {
17956           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17957             {
17958               errmsg ("incorrect range parameters");
17959               return -99;
17960             }
17961           this_low = tmp;
17962           /* Note: in debug CLI +1 is added to high before
17963              passing to real fn that does "the work"
17964              (ip_source_and_port_range_check_add_del).
17965              This fn is a wrapper around the binary API fn a
17966              control plane will call, which expects this increment
17967              to have occurred. Hence letting the binary API control
17968              plane fn do the increment for consistency between VAT
17969              and other control planes.
17970            */
17971           this_hi = tmp2;
17972           vec_add1 (low_ports, this_low);
17973           vec_add1 (high_ports, this_hi);
17974         }
17975       else
17976         break;
17977     }
17978
17979   if (prefix_set == 0)
17980     {
17981       errmsg ("<address>/<mask> not specified");
17982       return -99;
17983     }
17984
17985   if (vrf_id == ~0)
17986     {
17987       errmsg ("VRF ID required, not specified");
17988       return -99;
17989     }
17990
17991   if (vrf_id == 0)
17992     {
17993       errmsg
17994         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17995       return -99;
17996     }
17997
17998   if (vec_len (low_ports) == 0)
17999     {
18000       errmsg ("At least one port or port range required");
18001       return -99;
18002     }
18003
18004   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18005
18006   mp->is_add = is_add;
18007
18008   if (is_ipv6)
18009     {
18010       mp->is_ipv6 = 1;
18011       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18012     }
18013   else
18014     {
18015       mp->is_ipv6 = 0;
18016       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18017     }
18018
18019   mp->mask_length = length;
18020   mp->number_of_ranges = vec_len (low_ports);
18021
18022   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18023   vec_free (low_ports);
18024
18025   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18026   vec_free (high_ports);
18027
18028   mp->vrf_id = ntohl (vrf_id);
18029
18030   S (mp);
18031   W (ret);
18032   return ret;
18033 }
18034
18035 int
18036 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18037 {
18038   unformat_input_t *input = vam->input;
18039   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18040   u32 sw_if_index = ~0;
18041   int vrf_set = 0;
18042   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18043   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18044   u8 is_add = 1;
18045   int ret;
18046
18047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18048     {
18049       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18050         ;
18051       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18052         ;
18053       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18054         vrf_set = 1;
18055       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18056         vrf_set = 1;
18057       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18058         vrf_set = 1;
18059       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18060         vrf_set = 1;
18061       else if (unformat (input, "del"))
18062         is_add = 0;
18063       else
18064         break;
18065     }
18066
18067   if (sw_if_index == ~0)
18068     {
18069       errmsg ("Interface required but not specified");
18070       return -99;
18071     }
18072
18073   if (vrf_set == 0)
18074     {
18075       errmsg ("VRF ID required but not specified");
18076       return -99;
18077     }
18078
18079   if (tcp_out_vrf_id == 0
18080       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18081     {
18082       errmsg
18083         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18084       return -99;
18085     }
18086
18087   /* Construct the API message */
18088   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18089
18090   mp->sw_if_index = ntohl (sw_if_index);
18091   mp->is_add = is_add;
18092   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18093   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18094   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18095   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18096
18097   /* send it... */
18098   S (mp);
18099
18100   /* Wait for a reply... */
18101   W (ret);
18102   return ret;
18103 }
18104
18105 static int
18106 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18107 {
18108   unformat_input_t *i = vam->input;
18109   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18110   u32 local_sa_id = 0;
18111   u32 remote_sa_id = 0;
18112   ip4_address_t src_address;
18113   ip4_address_t dst_address;
18114   u8 is_add = 1;
18115   int ret;
18116
18117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18118     {
18119       if (unformat (i, "local_sa %d", &local_sa_id))
18120         ;
18121       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18122         ;
18123       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18124         ;
18125       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18126         ;
18127       else if (unformat (i, "del"))
18128         is_add = 0;
18129       else
18130         {
18131           clib_warning ("parse error '%U'", format_unformat_error, i);
18132           return -99;
18133         }
18134     }
18135
18136   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18137
18138   mp->local_sa_id = ntohl (local_sa_id);
18139   mp->remote_sa_id = ntohl (remote_sa_id);
18140   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18141   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18142   mp->is_add = is_add;
18143
18144   S (mp);
18145   W (ret);
18146   return ret;
18147 }
18148
18149 static int
18150 api_punt (vat_main_t * vam)
18151 {
18152   unformat_input_t *i = vam->input;
18153   vl_api_punt_t *mp;
18154   u32 ipv = ~0;
18155   u32 protocol = ~0;
18156   u32 port = ~0;
18157   int is_add = 1;
18158   int ret;
18159
18160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18161     {
18162       if (unformat (i, "ip %d", &ipv))
18163         ;
18164       else if (unformat (i, "protocol %d", &protocol))
18165         ;
18166       else if (unformat (i, "port %d", &port))
18167         ;
18168       else if (unformat (i, "del"))
18169         is_add = 0;
18170       else
18171         {
18172           clib_warning ("parse error '%U'", format_unformat_error, i);
18173           return -99;
18174         }
18175     }
18176
18177   M (PUNT, mp);
18178
18179   mp->is_add = (u8) is_add;
18180   mp->ipv = (u8) ipv;
18181   mp->l4_protocol = (u8) protocol;
18182   mp->l4_port = htons ((u16) port);
18183
18184   S (mp);
18185   W (ret);
18186   return ret;
18187 }
18188
18189 static void vl_api_ipsec_gre_tunnel_details_t_handler
18190   (vl_api_ipsec_gre_tunnel_details_t * mp)
18191 {
18192   vat_main_t *vam = &vat_main;
18193
18194   print (vam->ofp, "%11d%15U%15U%14d%14d",
18195          ntohl (mp->sw_if_index),
18196          format_ip4_address, &mp->src_address,
18197          format_ip4_address, &mp->dst_address,
18198          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18199 }
18200
18201 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18202   (vl_api_ipsec_gre_tunnel_details_t * mp)
18203 {
18204   vat_main_t *vam = &vat_main;
18205   vat_json_node_t *node = NULL;
18206   struct in_addr ip4;
18207
18208   if (VAT_JSON_ARRAY != vam->json_tree.type)
18209     {
18210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18211       vat_json_init_array (&vam->json_tree);
18212     }
18213   node = vat_json_array_add (&vam->json_tree);
18214
18215   vat_json_init_object (node);
18216   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18217   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18218   vat_json_object_add_ip4 (node, "src_address", ip4);
18219   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18220   vat_json_object_add_ip4 (node, "dst_address", ip4);
18221   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18222   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18223 }
18224
18225 static int
18226 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18227 {
18228   unformat_input_t *i = vam->input;
18229   vl_api_ipsec_gre_tunnel_dump_t *mp;
18230   vl_api_control_ping_t *mp_ping;
18231   u32 sw_if_index;
18232   u8 sw_if_index_set = 0;
18233   int ret;
18234
18235   /* Parse args required to build the message */
18236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18237     {
18238       if (unformat (i, "sw_if_index %d", &sw_if_index))
18239         sw_if_index_set = 1;
18240       else
18241         break;
18242     }
18243
18244   if (sw_if_index_set == 0)
18245     {
18246       sw_if_index = ~0;
18247     }
18248
18249   if (!vam->json_output)
18250     {
18251       print (vam->ofp, "%11s%15s%15s%14s%14s",
18252              "sw_if_index", "src_address", "dst_address",
18253              "local_sa_id", "remote_sa_id");
18254     }
18255
18256   /* Get list of gre-tunnel interfaces */
18257   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18258
18259   mp->sw_if_index = htonl (sw_if_index);
18260
18261   S (mp);
18262
18263   /* Use a control ping for synchronization */
18264   M (CONTROL_PING, mp_ping);
18265   S (mp_ping);
18266
18267   W (ret);
18268   return ret;
18269 }
18270
18271 static int
18272 api_delete_subif (vat_main_t * vam)
18273 {
18274   unformat_input_t *i = vam->input;
18275   vl_api_delete_subif_t *mp;
18276   u32 sw_if_index = ~0;
18277   int ret;
18278
18279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18280     {
18281       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18282         ;
18283       if (unformat (i, "sw_if_index %d", &sw_if_index))
18284         ;
18285       else
18286         break;
18287     }
18288
18289   if (sw_if_index == ~0)
18290     {
18291       errmsg ("missing sw_if_index");
18292       return -99;
18293     }
18294
18295   /* Construct the API message */
18296   M (DELETE_SUBIF, mp);
18297   mp->sw_if_index = ntohl (sw_if_index);
18298
18299   S (mp);
18300   W (ret);
18301   return ret;
18302 }
18303
18304 #define foreach_pbb_vtr_op      \
18305 _("disable",  L2_VTR_DISABLED)  \
18306 _("pop",  L2_VTR_POP_2)         \
18307 _("push",  L2_VTR_PUSH_2)
18308
18309 static int
18310 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18311 {
18312   unformat_input_t *i = vam->input;
18313   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18314   u32 sw_if_index = ~0, vtr_op = ~0;
18315   u16 outer_tag = ~0;
18316   u8 dmac[6], smac[6];
18317   u8 dmac_set = 0, smac_set = 0;
18318   u16 vlanid = 0;
18319   u32 sid = ~0;
18320   u32 tmp;
18321   int ret;
18322
18323   /* Shut up coverity */
18324   memset (dmac, 0, sizeof (dmac));
18325   memset (smac, 0, sizeof (smac));
18326
18327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18328     {
18329       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18330         ;
18331       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18332         ;
18333       else if (unformat (i, "vtr_op %d", &vtr_op))
18334         ;
18335 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18336       foreach_pbb_vtr_op
18337 #undef _
18338         else if (unformat (i, "translate_pbb_stag"))
18339         {
18340           if (unformat (i, "%d", &tmp))
18341             {
18342               vtr_op = L2_VTR_TRANSLATE_2_1;
18343               outer_tag = tmp;
18344             }
18345           else
18346             {
18347               errmsg
18348                 ("translate_pbb_stag operation requires outer tag definition");
18349               return -99;
18350             }
18351         }
18352       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18353         dmac_set++;
18354       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18355         smac_set++;
18356       else if (unformat (i, "sid %d", &sid))
18357         ;
18358       else if (unformat (i, "vlanid %d", &tmp))
18359         vlanid = tmp;
18360       else
18361         {
18362           clib_warning ("parse error '%U'", format_unformat_error, i);
18363           return -99;
18364         }
18365     }
18366
18367   if ((sw_if_index == ~0) || (vtr_op == ~0))
18368     {
18369       errmsg ("missing sw_if_index or vtr operation");
18370       return -99;
18371     }
18372   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18373       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18374     {
18375       errmsg
18376         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18377       return -99;
18378     }
18379
18380   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18381   mp->sw_if_index = ntohl (sw_if_index);
18382   mp->vtr_op = ntohl (vtr_op);
18383   mp->outer_tag = ntohs (outer_tag);
18384   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18385   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18386   mp->b_vlanid = ntohs (vlanid);
18387   mp->i_sid = ntohl (sid);
18388
18389   S (mp);
18390   W (ret);
18391   return ret;
18392 }
18393
18394 static int
18395 api_flow_classify_set_interface (vat_main_t * vam)
18396 {
18397   unformat_input_t *i = vam->input;
18398   vl_api_flow_classify_set_interface_t *mp;
18399   u32 sw_if_index;
18400   int sw_if_index_set;
18401   u32 ip4_table_index = ~0;
18402   u32 ip6_table_index = ~0;
18403   u8 is_add = 1;
18404   int ret;
18405
18406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18407     {
18408       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18409         sw_if_index_set = 1;
18410       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18411         sw_if_index_set = 1;
18412       else if (unformat (i, "del"))
18413         is_add = 0;
18414       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18415         ;
18416       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18417         ;
18418       else
18419         {
18420           clib_warning ("parse error '%U'", format_unformat_error, i);
18421           return -99;
18422         }
18423     }
18424
18425   if (sw_if_index_set == 0)
18426     {
18427       errmsg ("missing interface name or sw_if_index");
18428       return -99;
18429     }
18430
18431   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18432
18433   mp->sw_if_index = ntohl (sw_if_index);
18434   mp->ip4_table_index = ntohl (ip4_table_index);
18435   mp->ip6_table_index = ntohl (ip6_table_index);
18436   mp->is_add = is_add;
18437
18438   S (mp);
18439   W (ret);
18440   return ret;
18441 }
18442
18443 static int
18444 api_flow_classify_dump (vat_main_t * vam)
18445 {
18446   unformat_input_t *i = vam->input;
18447   vl_api_flow_classify_dump_t *mp;
18448   vl_api_control_ping_t *mp_ping;
18449   u8 type = FLOW_CLASSIFY_N_TABLES;
18450   int ret;
18451
18452   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18453     ;
18454   else
18455     {
18456       errmsg ("classify table type must be specified");
18457       return -99;
18458     }
18459
18460   if (!vam->json_output)
18461     {
18462       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18463     }
18464
18465   M (FLOW_CLASSIFY_DUMP, mp);
18466   mp->type = type;
18467   /* send it... */
18468   S (mp);
18469
18470   /* Use a control ping for synchronization */
18471   M (CONTROL_PING, mp_ping);
18472   S (mp_ping);
18473
18474   /* Wait for a reply... */
18475   W (ret);
18476   return ret;
18477 }
18478
18479 static int
18480 api_feature_enable_disable (vat_main_t * vam)
18481 {
18482   unformat_input_t *i = vam->input;
18483   vl_api_feature_enable_disable_t *mp;
18484   u8 *arc_name = 0;
18485   u8 *feature_name = 0;
18486   u32 sw_if_index = ~0;
18487   u8 enable = 1;
18488   int ret;
18489
18490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18491     {
18492       if (unformat (i, "arc_name %s", &arc_name))
18493         ;
18494       else if (unformat (i, "feature_name %s", &feature_name))
18495         ;
18496       else
18497         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18498         ;
18499       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18500         ;
18501       else if (unformat (i, "disable"))
18502         enable = 0;
18503       else
18504         break;
18505     }
18506
18507   if (arc_name == 0)
18508     {
18509       errmsg ("missing arc name");
18510       return -99;
18511     }
18512   if (vec_len (arc_name) > 63)
18513     {
18514       errmsg ("arc name too long");
18515     }
18516
18517   if (feature_name == 0)
18518     {
18519       errmsg ("missing feature name");
18520       return -99;
18521     }
18522   if (vec_len (feature_name) > 63)
18523     {
18524       errmsg ("feature name too long");
18525     }
18526
18527   if (sw_if_index == ~0)
18528     {
18529       errmsg ("missing interface name or sw_if_index");
18530       return -99;
18531     }
18532
18533   /* Construct the API message */
18534   M (FEATURE_ENABLE_DISABLE, mp);
18535   mp->sw_if_index = ntohl (sw_if_index);
18536   mp->enable = enable;
18537   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18538   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18539   vec_free (arc_name);
18540   vec_free (feature_name);
18541
18542   S (mp);
18543   W (ret);
18544   return ret;
18545 }
18546
18547 static int
18548 api_sw_interface_tag_add_del (vat_main_t * vam)
18549 {
18550   unformat_input_t *i = vam->input;
18551   vl_api_sw_interface_tag_add_del_t *mp;
18552   u32 sw_if_index = ~0;
18553   u8 *tag = 0;
18554   u8 enable = 1;
18555   int ret;
18556
18557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18558     {
18559       if (unformat (i, "tag %s", &tag))
18560         ;
18561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18562         ;
18563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18564         ;
18565       else if (unformat (i, "del"))
18566         enable = 0;
18567       else
18568         break;
18569     }
18570
18571   if (sw_if_index == ~0)
18572     {
18573       errmsg ("missing interface name or sw_if_index");
18574       return -99;
18575     }
18576
18577   if (enable && (tag == 0))
18578     {
18579       errmsg ("no tag specified");
18580       return -99;
18581     }
18582
18583   /* Construct the API message */
18584   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18585   mp->sw_if_index = ntohl (sw_if_index);
18586   mp->is_add = enable;
18587   if (enable)
18588     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18589   vec_free (tag);
18590
18591   S (mp);
18592   W (ret);
18593   return ret;
18594 }
18595
18596 static void vl_api_l2_xconnect_details_t_handler
18597   (vl_api_l2_xconnect_details_t * mp)
18598 {
18599   vat_main_t *vam = &vat_main;
18600
18601   print (vam->ofp, "%15d%15d",
18602          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18603 }
18604
18605 static void vl_api_l2_xconnect_details_t_handler_json
18606   (vl_api_l2_xconnect_details_t * mp)
18607 {
18608   vat_main_t *vam = &vat_main;
18609   vat_json_node_t *node = NULL;
18610
18611   if (VAT_JSON_ARRAY != vam->json_tree.type)
18612     {
18613       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18614       vat_json_init_array (&vam->json_tree);
18615     }
18616   node = vat_json_array_add (&vam->json_tree);
18617
18618   vat_json_init_object (node);
18619   vat_json_object_add_uint (node, "rx_sw_if_index",
18620                             ntohl (mp->rx_sw_if_index));
18621   vat_json_object_add_uint (node, "tx_sw_if_index",
18622                             ntohl (mp->tx_sw_if_index));
18623 }
18624
18625 static int
18626 api_l2_xconnect_dump (vat_main_t * vam)
18627 {
18628   vl_api_l2_xconnect_dump_t *mp;
18629   vl_api_control_ping_t *mp_ping;
18630   int ret;
18631
18632   if (!vam->json_output)
18633     {
18634       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18635     }
18636
18637   M (L2_XCONNECT_DUMP, mp);
18638
18639   S (mp);
18640
18641   /* Use a control ping for synchronization */
18642   M (CONTROL_PING, mp_ping);
18643   S (mp_ping);
18644
18645   W (ret);
18646   return ret;
18647 }
18648
18649 static int
18650 api_sw_interface_set_mtu (vat_main_t * vam)
18651 {
18652   unformat_input_t *i = vam->input;
18653   vl_api_sw_interface_set_mtu_t *mp;
18654   u32 sw_if_index = ~0;
18655   u32 mtu = 0;
18656   int ret;
18657
18658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18659     {
18660       if (unformat (i, "mtu %d", &mtu))
18661         ;
18662       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18663         ;
18664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18665         ;
18666       else
18667         break;
18668     }
18669
18670   if (sw_if_index == ~0)
18671     {
18672       errmsg ("missing interface name or sw_if_index");
18673       return -99;
18674     }
18675
18676   if (mtu == 0)
18677     {
18678       errmsg ("no mtu specified");
18679       return -99;
18680     }
18681
18682   /* Construct the API message */
18683   M (SW_INTERFACE_SET_MTU, mp);
18684   mp->sw_if_index = ntohl (sw_if_index);
18685   mp->mtu = ntohs ((u16) mtu);
18686
18687   S (mp);
18688   W (ret);
18689   return ret;
18690 }
18691
18692
18693 static int
18694 q_or_quit (vat_main_t * vam)
18695 {
18696 #if VPP_API_TEST_BUILTIN == 0
18697   longjmp (vam->jump_buf, 1);
18698 #endif
18699   return 0;                     /* not so much */
18700 }
18701
18702 static int
18703 q (vat_main_t * vam)
18704 {
18705   return q_or_quit (vam);
18706 }
18707
18708 static int
18709 quit (vat_main_t * vam)
18710 {
18711   return q_or_quit (vam);
18712 }
18713
18714 static int
18715 comment (vat_main_t * vam)
18716 {
18717   return 0;
18718 }
18719
18720 static int
18721 cmd_cmp (void *a1, void *a2)
18722 {
18723   u8 **c1 = a1;
18724   u8 **c2 = a2;
18725
18726   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18727 }
18728
18729 static int
18730 help (vat_main_t * vam)
18731 {
18732   u8 **cmds = 0;
18733   u8 *name = 0;
18734   hash_pair_t *p;
18735   unformat_input_t *i = vam->input;
18736   int j;
18737
18738   if (unformat (i, "%s", &name))
18739     {
18740       uword *hs;
18741
18742       vec_add1 (name, 0);
18743
18744       hs = hash_get_mem (vam->help_by_name, name);
18745       if (hs)
18746         print (vam->ofp, "usage: %s %s", name, hs[0]);
18747       else
18748         print (vam->ofp, "No such msg / command '%s'", name);
18749       vec_free (name);
18750       return 0;
18751     }
18752
18753   print (vam->ofp, "Help is available for the following:");
18754
18755     /* *INDENT-OFF* */
18756     hash_foreach_pair (p, vam->function_by_name,
18757     ({
18758       vec_add1 (cmds, (u8 *)(p->key));
18759     }));
18760     /* *INDENT-ON* */
18761
18762   vec_sort_with_function (cmds, cmd_cmp);
18763
18764   for (j = 0; j < vec_len (cmds); j++)
18765     print (vam->ofp, "%s", cmds[j]);
18766
18767   vec_free (cmds);
18768   return 0;
18769 }
18770
18771 static int
18772 set (vat_main_t * vam)
18773 {
18774   u8 *name = 0, *value = 0;
18775   unformat_input_t *i = vam->input;
18776
18777   if (unformat (i, "%s", &name))
18778     {
18779       /* The input buffer is a vector, not a string. */
18780       value = vec_dup (i->buffer);
18781       vec_delete (value, i->index, 0);
18782       /* Almost certainly has a trailing newline */
18783       if (value[vec_len (value) - 1] == '\n')
18784         value[vec_len (value) - 1] = 0;
18785       /* Make sure it's a proper string, one way or the other */
18786       vec_add1 (value, 0);
18787       (void) clib_macro_set_value (&vam->macro_main,
18788                                    (char *) name, (char *) value);
18789     }
18790   else
18791     errmsg ("usage: set <name> <value>");
18792
18793   vec_free (name);
18794   vec_free (value);
18795   return 0;
18796 }
18797
18798 static int
18799 unset (vat_main_t * vam)
18800 {
18801   u8 *name = 0;
18802
18803   if (unformat (vam->input, "%s", &name))
18804     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18805       errmsg ("unset: %s wasn't set", name);
18806   vec_free (name);
18807   return 0;
18808 }
18809
18810 typedef struct
18811 {
18812   u8 *name;
18813   u8 *value;
18814 } macro_sort_t;
18815
18816
18817 static int
18818 macro_sort_cmp (void *a1, void *a2)
18819 {
18820   macro_sort_t *s1 = a1;
18821   macro_sort_t *s2 = a2;
18822
18823   return strcmp ((char *) (s1->name), (char *) (s2->name));
18824 }
18825
18826 static int
18827 dump_macro_table (vat_main_t * vam)
18828 {
18829   macro_sort_t *sort_me = 0, *sm;
18830   int i;
18831   hash_pair_t *p;
18832
18833     /* *INDENT-OFF* */
18834     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18835     ({
18836       vec_add2 (sort_me, sm, 1);
18837       sm->name = (u8 *)(p->key);
18838       sm->value = (u8 *) (p->value[0]);
18839     }));
18840     /* *INDENT-ON* */
18841
18842   vec_sort_with_function (sort_me, macro_sort_cmp);
18843
18844   if (vec_len (sort_me))
18845     print (vam->ofp, "%-15s%s", "Name", "Value");
18846   else
18847     print (vam->ofp, "The macro table is empty...");
18848
18849   for (i = 0; i < vec_len (sort_me); i++)
18850     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18851   return 0;
18852 }
18853
18854 static int
18855 dump_node_table (vat_main_t * vam)
18856 {
18857   int i, j;
18858   vlib_node_t *node, *next_node;
18859
18860   if (vec_len (vam->graph_nodes) == 0)
18861     {
18862       print (vam->ofp, "Node table empty, issue get_node_graph...");
18863       return 0;
18864     }
18865
18866   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18867     {
18868       node = vam->graph_nodes[i];
18869       print (vam->ofp, "[%d] %s", i, node->name);
18870       for (j = 0; j < vec_len (node->next_nodes); j++)
18871         {
18872           if (node->next_nodes[j] != ~0)
18873             {
18874               next_node = vam->graph_nodes[node->next_nodes[j]];
18875               print (vam->ofp, "  [%d] %s", j, next_node->name);
18876             }
18877         }
18878     }
18879   return 0;
18880 }
18881
18882 static int
18883 value_sort_cmp (void *a1, void *a2)
18884 {
18885   name_sort_t *n1 = a1;
18886   name_sort_t *n2 = a2;
18887
18888   if (n1->value < n2->value)
18889     return -1;
18890   if (n1->value > n2->value)
18891     return 1;
18892   return 0;
18893 }
18894
18895
18896 static int
18897 dump_msg_api_table (vat_main_t * vam)
18898 {
18899   api_main_t *am = &api_main;
18900   name_sort_t *nses = 0, *ns;
18901   hash_pair_t *hp;
18902   int i;
18903
18904   /* *INDENT-OFF* */
18905   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18906   ({
18907     vec_add2 (nses, ns, 1);
18908     ns->name = (u8 *)(hp->key);
18909     ns->value = (u32) hp->value[0];
18910   }));
18911   /* *INDENT-ON* */
18912
18913   vec_sort_with_function (nses, value_sort_cmp);
18914
18915   for (i = 0; i < vec_len (nses); i++)
18916     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18917   vec_free (nses);
18918   return 0;
18919 }
18920
18921 static int
18922 get_msg_id (vat_main_t * vam)
18923 {
18924   u8 *name_and_crc;
18925   u32 message_index;
18926
18927   if (unformat (vam->input, "%s", &name_and_crc))
18928     {
18929       message_index = vl_api_get_msg_index (name_and_crc);
18930       if (message_index == ~0)
18931         {
18932           print (vam->ofp, " '%s' not found", name_and_crc);
18933           return 0;
18934         }
18935       print (vam->ofp, " '%s' has message index %d",
18936              name_and_crc, message_index);
18937       return 0;
18938     }
18939   errmsg ("name_and_crc required...");
18940   return 0;
18941 }
18942
18943 static int
18944 search_node_table (vat_main_t * vam)
18945 {
18946   unformat_input_t *line_input = vam->input;
18947   u8 *node_to_find;
18948   int j;
18949   vlib_node_t *node, *next_node;
18950   uword *p;
18951
18952   if (vam->graph_node_index_by_name == 0)
18953     {
18954       print (vam->ofp, "Node table empty, issue get_node_graph...");
18955       return 0;
18956     }
18957
18958   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18959     {
18960       if (unformat (line_input, "%s", &node_to_find))
18961         {
18962           vec_add1 (node_to_find, 0);
18963           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18964           if (p == 0)
18965             {
18966               print (vam->ofp, "%s not found...", node_to_find);
18967               goto out;
18968             }
18969           node = vam->graph_nodes[p[0]];
18970           print (vam->ofp, "[%d] %s", p[0], node->name);
18971           for (j = 0; j < vec_len (node->next_nodes); j++)
18972             {
18973               if (node->next_nodes[j] != ~0)
18974                 {
18975                   next_node = vam->graph_nodes[node->next_nodes[j]];
18976                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18977                 }
18978             }
18979         }
18980
18981       else
18982         {
18983           clib_warning ("parse error '%U'", format_unformat_error,
18984                         line_input);
18985           return -99;
18986         }
18987
18988     out:
18989       vec_free (node_to_find);
18990
18991     }
18992
18993   return 0;
18994 }
18995
18996
18997 static int
18998 script (vat_main_t * vam)
18999 {
19000 #if (VPP_API_TEST_BUILTIN==0)
19001   u8 *s = 0;
19002   char *save_current_file;
19003   unformat_input_t save_input;
19004   jmp_buf save_jump_buf;
19005   u32 save_line_number;
19006
19007   FILE *new_fp, *save_ifp;
19008
19009   if (unformat (vam->input, "%s", &s))
19010     {
19011       new_fp = fopen ((char *) s, "r");
19012       if (new_fp == 0)
19013         {
19014           errmsg ("Couldn't open script file %s", s);
19015           vec_free (s);
19016           return -99;
19017         }
19018     }
19019   else
19020     {
19021       errmsg ("Missing script name");
19022       return -99;
19023     }
19024
19025   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19026   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19027   save_ifp = vam->ifp;
19028   save_line_number = vam->input_line_number;
19029   save_current_file = (char *) vam->current_file;
19030
19031   vam->input_line_number = 0;
19032   vam->ifp = new_fp;
19033   vam->current_file = s;
19034   do_one_file (vam);
19035
19036   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19037   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19038   vam->ifp = save_ifp;
19039   vam->input_line_number = save_line_number;
19040   vam->current_file = (u8 *) save_current_file;
19041   vec_free (s);
19042
19043   return 0;
19044 #else
19045   clib_warning ("use the exec command...");
19046   return -99;
19047 #endif
19048 }
19049
19050 static int
19051 echo (vat_main_t * vam)
19052 {
19053   print (vam->ofp, "%v", vam->input->buffer);
19054   return 0;
19055 }
19056
19057 /* List of API message constructors, CLI names map to api_xxx */
19058 #define foreach_vpe_api_msg                                             \
19059 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19060 _(sw_interface_dump,"")                                                 \
19061 _(sw_interface_set_flags,                                               \
19062   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19063 _(sw_interface_add_del_address,                                         \
19064   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19065 _(sw_interface_set_table,                                               \
19066   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19067 _(sw_interface_set_mpls_enable,                                         \
19068   "<intfc> | sw_if_index [disable | dis]")                              \
19069 _(sw_interface_set_vpath,                                               \
19070   "<intfc> | sw_if_index <id> enable | disable")                        \
19071 _(sw_interface_set_vxlan_bypass,                                        \
19072   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19073 _(sw_interface_set_l2_xconnect,                                         \
19074   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19075   "enable | disable")                                                   \
19076 _(sw_interface_set_l2_bridge,                                           \
19077   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19078   "[shg <split-horizon-group>] [bvi]\n"                                 \
19079   "enable | disable")                                                   \
19080 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19081 _(bridge_domain_add_del,                                                \
19082   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [del]\n") \
19083 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19084 _(l2fib_add_del,                                                        \
19085   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19086 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19087 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19088 _(l2_flags,                                                             \
19089   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
19090 _(bridge_flags,                                                         \
19091   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19092 _(tap_connect,                                                          \
19093   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19094 _(tap_modify,                                                           \
19095   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19096 _(tap_delete,                                                           \
19097   "<vpp-if-name> | sw_if_index <id>")                                   \
19098 _(sw_interface_tap_dump, "")                                            \
19099 _(ip_add_del_route,                                                     \
19100   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19101   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19102   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19103   "[multipath] [count <n>]")                                            \
19104 _(ip_mroute_add_del,                                                    \
19105   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19106   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19107 _(mpls_route_add_del,                                                   \
19108   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19109   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19110   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19111   "[multipath] [count <n>]")                                            \
19112 _(mpls_ip_bind_unbind,                                                  \
19113   "<label> <addr/len>")                                                 \
19114 _(mpls_tunnel_add_del,                                                  \
19115   " via <addr> [table-id <n>]\n"                                        \
19116   "sw_if_index <id>] [l2]  [del]")                                      \
19117 _(proxy_arp_add_del,                                                    \
19118   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19119 _(proxy_arp_intfc_enable_disable,                                       \
19120   "<intfc> | sw_if_index <id> enable | disable")                        \
19121 _(sw_interface_set_unnumbered,                                          \
19122   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19123 _(ip_neighbor_add_del,                                                  \
19124   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19125   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19126 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19127 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19128 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19129   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19130   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19131   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19132 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19133 _(reset_fib, "vrf <n> [ipv6]")                                          \
19134 _(dhcp_proxy_config,                                                    \
19135   "svr <v46-address> src <v46-address>\n"                               \
19136    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19137 _(dhcp_proxy_set_vss,                                                   \
19138   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19139 _(dhcp_proxy_dump, "ip6")                                               \
19140 _(dhcp_client_config,                                                   \
19141   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19142 _(set_ip_flow_hash,                                                     \
19143   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19144 _(sw_interface_ip6_enable_disable,                                      \
19145   "<intfc> | sw_if_index <id> enable | disable")                        \
19146 _(sw_interface_ip6_set_link_local_address,                              \
19147   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19148 _(ip6nd_proxy_add_del,                                                  \
19149   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19150 _(ip6nd_proxy_dump, "")                                                 \
19151 _(sw_interface_ip6nd_ra_prefix,                                         \
19152   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19153   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19154   "[nolink] [isno]")                                                    \
19155 _(sw_interface_ip6nd_ra_config,                                         \
19156   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19157   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19158   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19159 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19160 _(l2_patch_add_del,                                                     \
19161   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19162   "enable | disable")                                                   \
19163 _(sr_localsid_add_del,                                                  \
19164   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19165   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19166 _(classify_add_del_table,                                               \
19167   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19168   " [del] [del-chain] mask <mask-value>\n"                              \
19169   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19170   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19171 _(classify_add_del_session,                                             \
19172   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19173   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19174   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19175   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19176 _(classify_set_interface_ip_table,                                      \
19177   "<intfc> | sw_if_index <nn> table <nn>")                              \
19178 _(classify_set_interface_l2_tables,                                     \
19179   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19180   "  [other-table <nn>]")                                               \
19181 _(get_node_index, "node <node-name")                                    \
19182 _(add_node_next, "node <node-name> next <next-node-name>")              \
19183 _(l2tpv3_create_tunnel,                                                 \
19184   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
19185   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
19186   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
19187 _(l2tpv3_set_tunnel_cookies,                                            \
19188   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
19189   "[new_remote_cookie <nn>]\n")                                         \
19190 _(l2tpv3_interface_enable_disable,                                      \
19191   "<intfc> | sw_if_index <nn> enable | disable")                        \
19192 _(l2tpv3_set_lookup_key,                                                \
19193   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
19194 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
19195 _(vxlan_add_del_tunnel,                                                 \
19196   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
19197   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19198   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
19199 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
19200 _(gre_add_del_tunnel,                                                   \
19201   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
19202 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
19203 _(l2_fib_clear_table, "")                                               \
19204 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
19205 _(l2_interface_vlan_tag_rewrite,                                        \
19206   "<intfc> | sw_if_index <nn> \n"                                       \
19207   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19208   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19209 _(create_vhost_user_if,                                                 \
19210         "socket <filename> [server] [renumber <dev_instance>] "         \
19211         "[mac <mac_address>]")                                          \
19212 _(modify_vhost_user_if,                                                 \
19213         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19214         "[server] [renumber <dev_instance>]")                           \
19215 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19216 _(sw_interface_vhost_user_dump, "")                                     \
19217 _(show_version, "")                                                     \
19218 _(vxlan_gpe_add_del_tunnel,                                             \
19219   "local <addr> remote <addr> vni <nn>\n"                               \
19220     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
19221   "[next-ethernet] [next-nsh]\n")                                       \
19222 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19223 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19224 _(interface_name_renumber,                                              \
19225   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19226 _(input_acl_set_interface,                                              \
19227   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19228   "  [l2-table <nn>] [del]")                                            \
19229 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19230 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19231 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19232 _(ip_dump, "ipv4 | ipv6")                                               \
19233 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19234 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19235   "  spid_id <n> ")                                                     \
19236 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19237   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19238   "  integ_alg <alg> integ_key <hex>")                                  \
19239 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19240   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19241   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19242   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19243 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19244 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19245   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19246   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19247   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19248 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19249 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19250   "(auth_data 0x<data> | auth_data <data>)")                            \
19251 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19252   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19253 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
19254   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19255   "(local|remote)")                                                     \
19256 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
19257 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19258 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19259 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19260 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19261 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19262 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19263 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19264 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19265 _(delete_loopback,"sw_if_index <nn>")                                   \
19266 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19267 _(map_add_domain,                                                       \
19268   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19269   "ip6-src <ip6addr> "                                                  \
19270   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19271 _(map_del_domain, "index <n>")                                          \
19272 _(map_add_del_rule,                                                     \
19273   "index <n> psid <n> dst <ip6addr> [del]")                             \
19274 _(map_domain_dump, "")                                                  \
19275 _(map_rule_dump, "index <map-domain>")                                  \
19276 _(want_interface_events,  "enable|disable")                             \
19277 _(want_stats,"enable|disable")                                          \
19278 _(get_first_msg_id, "client <name>")                                    \
19279 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19280 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19281   "fib-id <nn> [ip4][ip6][default]")                                    \
19282 _(get_node_graph, " ")                                                  \
19283 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19284 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19285 _(ioam_disable, "")                                                     \
19286 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19287                             " sw_if_index <sw_if_index> p <priority> "  \
19288                             "w <weight>] [del]")                        \
19289 _(one_add_del_locator, "locator-set <locator_name> "                    \
19290                         "iface <intf> | sw_if_index <sw_if_index> "     \
19291                         "p <priority> w <weight> [del]")                \
19292 _(one_add_del_local_eid,"vni <vni> eid "                                \
19293                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19294                          "locator-set <locator_name> [del]"             \
19295                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19296 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19297 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19298 _(one_enable_disable, "enable|disable")                                 \
19299 _(one_map_register_enable_disable, "enable|disable")                    \
19300 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19301 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19302                                "[seid <seid>] "                         \
19303                                "rloc <locator> p <prio> "               \
19304                                "w <weight> [rloc <loc> ... ] "          \
19305                                "action <action> [del-all]")             \
19306 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19307                           "<local-eid>")                                \
19308 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19309 _(one_use_petr, "ip-address> | disable")                                \
19310 _(one_map_request_mode, "src-dst|dst-only")                             \
19311 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19312 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19313 _(one_locator_set_dump, "[local | remote]")                             \
19314 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19315 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19316                        "[local] | [remote]")                            \
19317 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
19318 _(one_l2_arp_bd_get, "")                                                \
19319 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
19320 _(one_stats_enable_disable, "enable|disalbe")                           \
19321 _(show_one_stats_enable_disable, "")                                    \
19322 _(one_eid_table_vni_dump, "")                                           \
19323 _(one_eid_table_map_dump, "l2|l3")                                      \
19324 _(one_map_resolver_dump, "")                                            \
19325 _(one_map_server_dump, "")                                              \
19326 _(one_adjacencies_get, "vni <vni>")                                     \
19327 _(show_one_rloc_probe_state, "")                                        \
19328 _(show_one_map_register_state, "")                                      \
19329 _(show_one_status, "")                                                  \
19330 _(one_stats_dump, "")                                                   \
19331 _(one_stats_flush, "")                                                  \
19332 _(one_get_map_request_itr_rlocs, "")                                    \
19333 _(show_one_pitr, "")                                                    \
19334 _(show_one_use_petr, "")                                                \
19335 _(show_one_map_request_mode, "")                                        \
19336 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19337                             " sw_if_index <sw_if_index> p <priority> "  \
19338                             "w <weight>] [del]")                        \
19339 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19340                         "iface <intf> | sw_if_index <sw_if_index> "     \
19341                         "p <priority> w <weight> [del]")                \
19342 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19343                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19344                          "locator-set <locator_name> [del]"             \
19345                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19346 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19347 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19348 _(lisp_enable_disable, "enable|disable")                                \
19349 _(lisp_map_register_enable_disable, "enable|disable")                   \
19350 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19351 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19352                                "[seid <seid>] "                         \
19353                                "rloc <locator> p <prio> "               \
19354                                "w <weight> [rloc <loc> ... ] "          \
19355                                "action <action> [del-all]")             \
19356 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19357                           "<local-eid>")                                \
19358 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19359 _(lisp_use_petr, "<ip-address> | disable")                              \
19360 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19361 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19362 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19363 _(lisp_locator_set_dump, "[local | remote]")                            \
19364 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19365 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19366                        "[local] | [remote]")                            \
19367 _(lisp_eid_table_vni_dump, "")                                          \
19368 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19369 _(lisp_map_resolver_dump, "")                                           \
19370 _(lisp_map_server_dump, "")                                             \
19371 _(lisp_adjacencies_get, "vni <vni>")                                    \
19372 _(gpe_fwd_entry_vnis_get, "")                                           \
19373 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19374 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19375 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19376 _(gpe_get_encap_mode, "")                                               \
19377 _(lisp_gpe_add_del_iface, "up|down")                                    \
19378 _(lisp_gpe_enable_disable, "enable|disable")                            \
19379 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19380   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19381 _(show_lisp_rloc_probe_state, "")                                       \
19382 _(show_lisp_map_register_state, "")                                     \
19383 _(show_lisp_status, "")                                                 \
19384 _(lisp_get_map_request_itr_rlocs, "")                                   \
19385 _(show_lisp_pitr, "")                                                   \
19386 _(show_lisp_use_petr, "")                                               \
19387 _(show_lisp_map_request_mode, "")                                       \
19388 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19389 _(af_packet_delete, "name <host interface name>")                       \
19390 _(policer_add_del, "name <policer name> <params> [del]")                \
19391 _(policer_dump, "[name <policer name>]")                                \
19392 _(policer_classify_set_interface,                                       \
19393   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19394   "  [l2-table <nn>] [del]")                                            \
19395 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19396 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19397     "[master|slave]")                                                   \
19398 _(netmap_delete, "name <interface name>")                               \
19399 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19400 _(mpls_fib_dump, "")                                                    \
19401 _(classify_table_ids, "")                                               \
19402 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19403 _(classify_table_info, "table_id <nn>")                                 \
19404 _(classify_session_dump, "table_id <nn>")                               \
19405 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19406     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19407     "[template_interval <nn>] [udp_checksum]")                          \
19408 _(ipfix_exporter_dump, "")                                              \
19409 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19410 _(ipfix_classify_stream_dump, "")                                       \
19411 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19412 _(ipfix_classify_table_dump, "")                                        \
19413 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19414 _(sw_interface_span_dump, "")                                           \
19415 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19416 _(pg_create_interface, "if_id <nn>")                                    \
19417 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19418 _(pg_enable_disable, "[stream <id>] disable")                           \
19419 _(ip_source_and_port_range_check_add_del,                               \
19420   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19421 _(ip_source_and_port_range_check_interface_add_del,                     \
19422   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19423   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19424 _(ipsec_gre_add_del_tunnel,                                             \
19425   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19426 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19427 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19428 _(l2_interface_pbb_tag_rewrite,                                         \
19429   "<intfc> | sw_if_index <nn> \n"                                       \
19430   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19431   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19432 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19433 _(flow_classify_set_interface,                                          \
19434   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19435 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19436 _(ip_fib_dump, "")                                                      \
19437 _(ip_mfib_dump, "")                                                     \
19438 _(ip6_fib_dump, "")                                                     \
19439 _(ip6_mfib_dump, "")                                                    \
19440 _(feature_enable_disable, "arc_name <arc_name> "                        \
19441   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19442 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19443 "[disable]")                                                            \
19444 _(l2_xconnect_dump, "")                                                 \
19445 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19446 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19447 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19448
19449 /* List of command functions, CLI names map directly to functions */
19450 #define foreach_cli_function                                    \
19451 _(comment, "usage: comment <ignore-rest-of-line>")              \
19452 _(dump_interface_table, "usage: dump_interface_table")          \
19453 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19454 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19455 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19456 _(dump_stats_table, "usage: dump_stats_table")                  \
19457 _(dump_macro_table, "usage: dump_macro_table ")                 \
19458 _(dump_node_table, "usage: dump_node_table")                    \
19459 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19460 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19461 _(echo, "usage: echo <message>")                                \
19462 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19463 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19464 _(help, "usage: help")                                          \
19465 _(q, "usage: quit")                                             \
19466 _(quit, "usage: quit")                                          \
19467 _(search_node_table, "usage: search_node_table <name>...")      \
19468 _(set, "usage: set <variable-name> <value>")                    \
19469 _(script, "usage: script <file-name>")                          \
19470 _(unset, "usage: unset <variable-name>")
19471
19472 #define _(N,n)                                  \
19473     static void vl_api_##n##_t_handler_uni      \
19474     (vl_api_##n##_t * mp)                       \
19475     {                                           \
19476         vat_main_t * vam = &vat_main;           \
19477         if (vam->json_output) {                 \
19478             vl_api_##n##_t_handler_json(mp);    \
19479         } else {                                \
19480             vl_api_##n##_t_handler(mp);         \
19481         }                                       \
19482     }
19483 foreach_vpe_api_reply_msg;
19484 #if VPP_API_TEST_BUILTIN == 0
19485 foreach_standalone_reply_msg;
19486 #endif
19487 #undef _
19488
19489 void
19490 vat_api_hookup (vat_main_t * vam)
19491 {
19492 #define _(N,n)                                                  \
19493     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19494                            vl_api_##n##_t_handler_uni,          \
19495                            vl_noop_handler,                     \
19496                            vl_api_##n##_t_endian,               \
19497                            vl_api_##n##_t_print,                \
19498                            sizeof(vl_api_##n##_t), 1);
19499   foreach_vpe_api_reply_msg;
19500 #if VPP_API_TEST_BUILTIN == 0
19501   foreach_standalone_reply_msg;
19502 #endif
19503 #undef _
19504
19505 #if (VPP_API_TEST_BUILTIN==0)
19506   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19507
19508   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19509
19510   vam->function_by_name = hash_create_string (0, sizeof (uword));
19511
19512   vam->help_by_name = hash_create_string (0, sizeof (uword));
19513 #endif
19514
19515   /* API messages we can send */
19516 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19517   foreach_vpe_api_msg;
19518 #undef _
19519
19520   /* Help strings */
19521 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19522   foreach_vpe_api_msg;
19523 #undef _
19524
19525   /* CLI functions */
19526 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19527   foreach_cli_function;
19528 #undef _
19529
19530   /* Help strings */
19531 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19532   foreach_cli_function;
19533 #undef _
19534 }
19535
19536 #if VPP_API_TEST_BUILTIN
19537 static clib_error_t *
19538 vat_api_hookup_shim (vlib_main_t * vm)
19539 {
19540   vat_api_hookup (&vat_main);
19541   return 0;
19542 }
19543
19544 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19545 #endif
19546
19547 /*
19548  * fd.io coding-style-patch-verification: ON
19549  *
19550  * Local Variables:
19551  * eval: (c-set-style "gnu")
19552  * End:
19553  */