P2P Ethernet - API
[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 _(p2p_ethernet_add_reply)                               \
4450 _(p2p_ethernet_del_reply)
4451
4452 #define _(n)                                    \
4453     static void vl_api_##n##_t_handler          \
4454     (vl_api_##n##_t * mp)                       \
4455     {                                           \
4456         vat_main_t * vam = &vat_main;           \
4457         i32 retval = ntohl(mp->retval);         \
4458         if (vam->async_mode) {                  \
4459             vam->async_errors += (retval < 0);  \
4460         } else {                                \
4461             vam->retval = retval;               \
4462             vam->result_ready = 1;              \
4463         }                                       \
4464     }
4465 foreach_standard_reply_retval_handler;
4466 #undef _
4467
4468 #define _(n)                                    \
4469     static void vl_api_##n##_t_handler_json     \
4470     (vl_api_##n##_t * mp)                       \
4471     {                                           \
4472         vat_main_t * vam = &vat_main;           \
4473         vat_json_node_t node;                   \
4474         vat_json_init_object(&node);            \
4475         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4476         vat_json_print(vam->ofp, &node);        \
4477         vam->retval = ntohl(mp->retval);        \
4478         vam->result_ready = 1;                  \
4479     }
4480 foreach_standard_reply_retval_handler;
4481 #undef _
4482
4483 /*
4484  * Table of message reply handlers, must include boilerplate handlers
4485  * we just generated
4486  */
4487
4488 #define foreach_vpe_api_reply_msg                                       \
4489 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4490 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4491 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4492 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4493 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4494 _(CLI_REPLY, cli_reply)                                                 \
4495 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4496 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4497   sw_interface_add_del_address_reply)                                   \
4498 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4499 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4500 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4501 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4502 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4503   sw_interface_set_l2_xconnect_reply)                                   \
4504 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4505   sw_interface_set_l2_bridge_reply)                                     \
4506 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4507 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4508 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4509 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4510 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4511 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4512 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4513 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4514 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4515 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4516 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4517 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4518 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4519 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4520 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4521 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4522 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4523 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4524   proxy_arp_intfc_enable_disable_reply)                                 \
4525 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4526 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4527   sw_interface_set_unnumbered_reply)                                    \
4528 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4529 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4530 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4531 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4532 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4533 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4534 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4535 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4536 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4537 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4538 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4539 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4540   sw_interface_ip6_enable_disable_reply)                                \
4541 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4542   sw_interface_ip6_set_link_local_address_reply)                        \
4543 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4544 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4545 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4546   sw_interface_ip6nd_ra_prefix_reply)                                   \
4547 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4548   sw_interface_ip6nd_ra_config_reply)                                   \
4549 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4550 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4551 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4552 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4553 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4554 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4555 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4556 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4557 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4558 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4559 classify_set_interface_ip_table_reply)                                  \
4560 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4561   classify_set_interface_l2_tables_reply)                               \
4562 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4563 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4564 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4565 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4566 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4567   l2tpv3_interface_enable_disable_reply)                                \
4568 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4569 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4570 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4571 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4572 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4573 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4574 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4575 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4576 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4577 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4578 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4579 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4580 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4581 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4582 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4583 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4584 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4585 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4586 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4587 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4588 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4589 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4590 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4591 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4592 _(IP_DETAILS, ip_details)                                               \
4593 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4594 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4595 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4596 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4597 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4598 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4599 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4600 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4601 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4602 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4603 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4604 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4605 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4606 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4607 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4608 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4609 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4610 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4611 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4612 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4613 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4614 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4615 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4616 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4617 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4618 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4619 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4620 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4621 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4622 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4623 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4624 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4625 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4626 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4627 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4628 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4629 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4630 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4631 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4632 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4633 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4634 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4635 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4636 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4637 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4638   one_map_register_enable_disable_reply)                                \
4639 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4640   one_rloc_probe_enable_disable_reply)                                  \
4641 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4642 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4643 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4644 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4645 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4646 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4647 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4648 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4649 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4650 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4651 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4652 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4653 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4654 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4655 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4656 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4657   show_one_stats_enable_disable_reply)                                  \
4658 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4659 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4660 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4661 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4662 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4663 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4664 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4665 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4666 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4667 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4668 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4669   gpe_fwd_entry_path_details)                                           \
4670 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4671 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4672   one_add_del_map_request_itr_rlocs_reply)                              \
4673 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4674   one_get_map_request_itr_rlocs_reply)                                  \
4675 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4676 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4677 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4678 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4679 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4680   show_one_map_register_state_reply)                                    \
4681 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4682 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4683 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4684 _(POLICER_DETAILS, policer_details)                                     \
4685 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4686 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4687 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4688 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4689 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4690 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4691 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4692 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4693 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4694 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4695 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4696 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4697 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4698 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4699 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4700 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4701 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4702 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4703 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4704 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4705 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4706 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4707 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4708 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4709 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4710  ip_source_and_port_range_check_add_del_reply)                          \
4711 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4712  ip_source_and_port_range_check_interface_add_del_reply)                \
4713 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4714 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4715 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4716 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4717 _(PUNT_REPLY, punt_reply)                                               \
4718 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4719 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4720 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4721 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4722 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4723 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4724 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4725 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
4726 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
4727 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)
4728
4729 #define foreach_standalone_reply_msg                                    \
4730 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4731 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4732 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4733 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4734 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4735 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4736 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4737
4738 typedef struct
4739 {
4740   u8 *name;
4741   u32 value;
4742 } name_sort_t;
4743
4744
4745 #define STR_VTR_OP_CASE(op)     \
4746     case L2_VTR_ ## op:         \
4747         return "" # op;
4748
4749 static const char *
4750 str_vtr_op (u32 vtr_op)
4751 {
4752   switch (vtr_op)
4753     {
4754       STR_VTR_OP_CASE (DISABLED);
4755       STR_VTR_OP_CASE (PUSH_1);
4756       STR_VTR_OP_CASE (PUSH_2);
4757       STR_VTR_OP_CASE (POP_1);
4758       STR_VTR_OP_CASE (POP_2);
4759       STR_VTR_OP_CASE (TRANSLATE_1_1);
4760       STR_VTR_OP_CASE (TRANSLATE_1_2);
4761       STR_VTR_OP_CASE (TRANSLATE_2_1);
4762       STR_VTR_OP_CASE (TRANSLATE_2_2);
4763     }
4764
4765   return "UNKNOWN";
4766 }
4767
4768 static int
4769 dump_sub_interface_table (vat_main_t * vam)
4770 {
4771   const sw_interface_subif_t *sub = NULL;
4772
4773   if (vam->json_output)
4774     {
4775       clib_warning
4776         ("JSON output supported only for VPE API calls and dump_stats_table");
4777       return -99;
4778     }
4779
4780   print (vam->ofp,
4781          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4782          "Interface", "sw_if_index",
4783          "sub id", "dot1ad", "tags", "outer id",
4784          "inner id", "exact", "default", "outer any", "inner any");
4785
4786   vec_foreach (sub, vam->sw_if_subif_table)
4787   {
4788     print (vam->ofp,
4789            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4790            sub->interface_name,
4791            sub->sw_if_index,
4792            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4793            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4794            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4795            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4796     if (sub->vtr_op != L2_VTR_DISABLED)
4797       {
4798         print (vam->ofp,
4799                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4800                "tag1: %d tag2: %d ]",
4801                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4802                sub->vtr_tag1, sub->vtr_tag2);
4803       }
4804   }
4805
4806   return 0;
4807 }
4808
4809 static int
4810 name_sort_cmp (void *a1, void *a2)
4811 {
4812   name_sort_t *n1 = a1;
4813   name_sort_t *n2 = a2;
4814
4815   return strcmp ((char *) n1->name, (char *) n2->name);
4816 }
4817
4818 static int
4819 dump_interface_table (vat_main_t * vam)
4820 {
4821   hash_pair_t *p;
4822   name_sort_t *nses = 0, *ns;
4823
4824   if (vam->json_output)
4825     {
4826       clib_warning
4827         ("JSON output supported only for VPE API calls and dump_stats_table");
4828       return -99;
4829     }
4830
4831   /* *INDENT-OFF* */
4832   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4833   ({
4834     vec_add2 (nses, ns, 1);
4835     ns->name = (u8 *)(p->key);
4836     ns->value = (u32) p->value[0];
4837   }));
4838   /* *INDENT-ON* */
4839
4840   vec_sort_with_function (nses, name_sort_cmp);
4841
4842   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4843   vec_foreach (ns, nses)
4844   {
4845     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4846   }
4847   vec_free (nses);
4848   return 0;
4849 }
4850
4851 static int
4852 dump_ip_table (vat_main_t * vam, int is_ipv6)
4853 {
4854   const ip_details_t *det = NULL;
4855   const ip_address_details_t *address = NULL;
4856   u32 i = ~0;
4857
4858   print (vam->ofp, "%-12s", "sw_if_index");
4859
4860   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4861   {
4862     i++;
4863     if (!det->present)
4864       {
4865         continue;
4866       }
4867     print (vam->ofp, "%-12d", i);
4868     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4869     if (!det->addr)
4870       {
4871         continue;
4872       }
4873     vec_foreach (address, det->addr)
4874     {
4875       print (vam->ofp,
4876              "            %-30U%-13d",
4877              is_ipv6 ? format_ip6_address : format_ip4_address,
4878              address->ip, address->prefix_length);
4879     }
4880   }
4881
4882   return 0;
4883 }
4884
4885 static int
4886 dump_ipv4_table (vat_main_t * vam)
4887 {
4888   if (vam->json_output)
4889     {
4890       clib_warning
4891         ("JSON output supported only for VPE API calls and dump_stats_table");
4892       return -99;
4893     }
4894
4895   return dump_ip_table (vam, 0);
4896 }
4897
4898 static int
4899 dump_ipv6_table (vat_main_t * vam)
4900 {
4901   if (vam->json_output)
4902     {
4903       clib_warning
4904         ("JSON output supported only for VPE API calls and dump_stats_table");
4905       return -99;
4906     }
4907
4908   return dump_ip_table (vam, 1);
4909 }
4910
4911 static char *
4912 counter_type_to_str (u8 counter_type, u8 is_combined)
4913 {
4914   if (!is_combined)
4915     {
4916       switch (counter_type)
4917         {
4918         case VNET_INTERFACE_COUNTER_DROP:
4919           return "drop";
4920         case VNET_INTERFACE_COUNTER_PUNT:
4921           return "punt";
4922         case VNET_INTERFACE_COUNTER_IP4:
4923           return "ip4";
4924         case VNET_INTERFACE_COUNTER_IP6:
4925           return "ip6";
4926         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4927           return "rx-no-buf";
4928         case VNET_INTERFACE_COUNTER_RX_MISS:
4929           return "rx-miss";
4930         case VNET_INTERFACE_COUNTER_RX_ERROR:
4931           return "rx-error";
4932         case VNET_INTERFACE_COUNTER_TX_ERROR:
4933           return "tx-error";
4934         default:
4935           return "INVALID-COUNTER-TYPE";
4936         }
4937     }
4938   else
4939     {
4940       switch (counter_type)
4941         {
4942         case VNET_INTERFACE_COUNTER_RX:
4943           return "rx";
4944         case VNET_INTERFACE_COUNTER_TX:
4945           return "tx";
4946         default:
4947           return "INVALID-COUNTER-TYPE";
4948         }
4949     }
4950 }
4951
4952 static int
4953 dump_stats_table (vat_main_t * vam)
4954 {
4955   vat_json_node_t node;
4956   vat_json_node_t *msg_array;
4957   vat_json_node_t *msg;
4958   vat_json_node_t *counter_array;
4959   vat_json_node_t *counter;
4960   interface_counter_t c;
4961   u64 packets;
4962   ip4_fib_counter_t *c4;
4963   ip6_fib_counter_t *c6;
4964   ip4_nbr_counter_t *n4;
4965   ip6_nbr_counter_t *n6;
4966   int i, j;
4967
4968   if (!vam->json_output)
4969     {
4970       clib_warning ("dump_stats_table supported only in JSON format");
4971       return -99;
4972     }
4973
4974   vat_json_init_object (&node);
4975
4976   /* interface counters */
4977   msg_array = vat_json_object_add (&node, "interface_counters");
4978   vat_json_init_array (msg_array);
4979   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4980     {
4981       msg = vat_json_array_add (msg_array);
4982       vat_json_init_object (msg);
4983       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4984                                        (u8 *) counter_type_to_str (i, 0));
4985       vat_json_object_add_int (msg, "is_combined", 0);
4986       counter_array = vat_json_object_add (msg, "data");
4987       vat_json_init_array (counter_array);
4988       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4989         {
4990           packets = vam->simple_interface_counters[i][j];
4991           vat_json_array_add_uint (counter_array, packets);
4992         }
4993     }
4994   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4995     {
4996       msg = vat_json_array_add (msg_array);
4997       vat_json_init_object (msg);
4998       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4999                                        (u8 *) counter_type_to_str (i, 1));
5000       vat_json_object_add_int (msg, "is_combined", 1);
5001       counter_array = vat_json_object_add (msg, "data");
5002       vat_json_init_array (counter_array);
5003       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5004         {
5005           c = vam->combined_interface_counters[i][j];
5006           counter = vat_json_array_add (counter_array);
5007           vat_json_init_object (counter);
5008           vat_json_object_add_uint (counter, "packets", c.packets);
5009           vat_json_object_add_uint (counter, "bytes", c.bytes);
5010         }
5011     }
5012
5013   /* ip4 fib counters */
5014   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5015   vat_json_init_array (msg_array);
5016   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5017     {
5018       msg = vat_json_array_add (msg_array);
5019       vat_json_init_object (msg);
5020       vat_json_object_add_uint (msg, "vrf_id",
5021                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5022       counter_array = vat_json_object_add (msg, "c");
5023       vat_json_init_array (counter_array);
5024       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5025         {
5026           counter = vat_json_array_add (counter_array);
5027           vat_json_init_object (counter);
5028           c4 = &vam->ip4_fib_counters[i][j];
5029           vat_json_object_add_ip4 (counter, "address", c4->address);
5030           vat_json_object_add_uint (counter, "address_length",
5031                                     c4->address_length);
5032           vat_json_object_add_uint (counter, "packets", c4->packets);
5033           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5034         }
5035     }
5036
5037   /* ip6 fib counters */
5038   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5039   vat_json_init_array (msg_array);
5040   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5041     {
5042       msg = vat_json_array_add (msg_array);
5043       vat_json_init_object (msg);
5044       vat_json_object_add_uint (msg, "vrf_id",
5045                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5046       counter_array = vat_json_object_add (msg, "c");
5047       vat_json_init_array (counter_array);
5048       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5049         {
5050           counter = vat_json_array_add (counter_array);
5051           vat_json_init_object (counter);
5052           c6 = &vam->ip6_fib_counters[i][j];
5053           vat_json_object_add_ip6 (counter, "address", c6->address);
5054           vat_json_object_add_uint (counter, "address_length",
5055                                     c6->address_length);
5056           vat_json_object_add_uint (counter, "packets", c6->packets);
5057           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5058         }
5059     }
5060
5061   /* ip4 nbr counters */
5062   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5063   vat_json_init_array (msg_array);
5064   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5065     {
5066       msg = vat_json_array_add (msg_array);
5067       vat_json_init_object (msg);
5068       vat_json_object_add_uint (msg, "sw_if_index", i);
5069       counter_array = vat_json_object_add (msg, "c");
5070       vat_json_init_array (counter_array);
5071       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5072         {
5073           counter = vat_json_array_add (counter_array);
5074           vat_json_init_object (counter);
5075           n4 = &vam->ip4_nbr_counters[i][j];
5076           vat_json_object_add_ip4 (counter, "address", n4->address);
5077           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5078           vat_json_object_add_uint (counter, "packets", n4->packets);
5079           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5080         }
5081     }
5082
5083   /* ip6 nbr counters */
5084   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5085   vat_json_init_array (msg_array);
5086   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5087     {
5088       msg = vat_json_array_add (msg_array);
5089       vat_json_init_object (msg);
5090       vat_json_object_add_uint (msg, "sw_if_index", i);
5091       counter_array = vat_json_object_add (msg, "c");
5092       vat_json_init_array (counter_array);
5093       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5094         {
5095           counter = vat_json_array_add (counter_array);
5096           vat_json_init_object (counter);
5097           n6 = &vam->ip6_nbr_counters[i][j];
5098           vat_json_object_add_ip6 (counter, "address", n6->address);
5099           vat_json_object_add_uint (counter, "packets", n6->packets);
5100           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5101         }
5102     }
5103
5104   vat_json_print (vam->ofp, &node);
5105   vat_json_free (&node);
5106
5107   return 0;
5108 }
5109
5110 int
5111 exec (vat_main_t * vam)
5112 {
5113   api_main_t *am = &api_main;
5114   vl_api_cli_t *mp;
5115   f64 timeout;
5116   void *oldheap;
5117   u8 *cmd = 0;
5118   unformat_input_t *i = vam->input;
5119
5120   if (vec_len (i->buffer) == 0)
5121     return -1;
5122
5123   if (vam->exec_mode == 0 && unformat (i, "mode"))
5124     {
5125       vam->exec_mode = 1;
5126       return 0;
5127     }
5128   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5129     {
5130       vam->exec_mode = 0;
5131       return 0;
5132     }
5133
5134
5135   M (CLI, mp);
5136
5137   /*
5138    * Copy cmd into shared memory.
5139    * In order for the CLI command to work, it
5140    * must be a vector ending in \n, not a C-string ending
5141    * in \n\0.
5142    */
5143   pthread_mutex_lock (&am->vlib_rp->mutex);
5144   oldheap = svm_push_data_heap (am->vlib_rp);
5145
5146   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5147   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5148
5149   svm_pop_heap (oldheap);
5150   pthread_mutex_unlock (&am->vlib_rp->mutex);
5151
5152   mp->cmd_in_shmem = pointer_to_uword (cmd);
5153   S (mp);
5154   timeout = vat_time_now (vam) + 10.0;
5155
5156   while (vat_time_now (vam) < timeout)
5157     {
5158       if (vam->result_ready == 1)
5159         {
5160           u8 *free_me;
5161           if (vam->shmem_result != NULL)
5162             print (vam->ofp, "%s", vam->shmem_result);
5163           pthread_mutex_lock (&am->vlib_rp->mutex);
5164           oldheap = svm_push_data_heap (am->vlib_rp);
5165
5166           free_me = (u8 *) vam->shmem_result;
5167           vec_free (free_me);
5168
5169           svm_pop_heap (oldheap);
5170           pthread_mutex_unlock (&am->vlib_rp->mutex);
5171           return 0;
5172         }
5173     }
5174   return -99;
5175 }
5176
5177 /*
5178  * Future replacement of exec() that passes CLI buffers directly in
5179  * the API messages instead of an additional shared memory area.
5180  */
5181 static int
5182 exec_inband (vat_main_t * vam)
5183 {
5184   vl_api_cli_inband_t *mp;
5185   unformat_input_t *i = vam->input;
5186   int ret;
5187
5188   if (vec_len (i->buffer) == 0)
5189     return -1;
5190
5191   if (vam->exec_mode == 0 && unformat (i, "mode"))
5192     {
5193       vam->exec_mode = 1;
5194       return 0;
5195     }
5196   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5197     {
5198       vam->exec_mode = 0;
5199       return 0;
5200     }
5201
5202   /*
5203    * In order for the CLI command to work, it
5204    * must be a vector ending in \n, not a C-string ending
5205    * in \n\0.
5206    */
5207   u32 len = vec_len (vam->input->buffer);
5208   M2 (CLI_INBAND, mp, len);
5209   clib_memcpy (mp->cmd, vam->input->buffer, len);
5210   mp->length = htonl (len);
5211
5212   S (mp);
5213   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5214   return ret;
5215 }
5216
5217 static int
5218 api_create_loopback (vat_main_t * vam)
5219 {
5220   unformat_input_t *i = vam->input;
5221   vl_api_create_loopback_t *mp;
5222   vl_api_create_loopback_instance_t *mp_lbi;
5223   u8 mac_address[6];
5224   u8 mac_set = 0;
5225   u8 is_specified = 0;
5226   u32 user_instance = 0;
5227   int ret;
5228
5229   memset (mac_address, 0, sizeof (mac_address));
5230
5231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5232     {
5233       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5234         mac_set = 1;
5235       if (unformat (i, "instance %d", &user_instance))
5236         is_specified = 1;
5237       else
5238         break;
5239     }
5240
5241   if (is_specified)
5242     {
5243       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5244       mp_lbi->is_specified = is_specified;
5245       if (is_specified)
5246         mp_lbi->user_instance = htonl (user_instance);
5247       if (mac_set)
5248         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5249       S (mp_lbi);
5250     }
5251   else
5252     {
5253       /* Construct the API message */
5254       M (CREATE_LOOPBACK, mp);
5255       if (mac_set)
5256         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5257       S (mp);
5258     }
5259
5260   W (ret);
5261   return ret;
5262 }
5263
5264 static int
5265 api_delete_loopback (vat_main_t * vam)
5266 {
5267   unformat_input_t *i = vam->input;
5268   vl_api_delete_loopback_t *mp;
5269   u32 sw_if_index = ~0;
5270   int ret;
5271
5272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5273     {
5274       if (unformat (i, "sw_if_index %d", &sw_if_index))
5275         ;
5276       else
5277         break;
5278     }
5279
5280   if (sw_if_index == ~0)
5281     {
5282       errmsg ("missing sw_if_index");
5283       return -99;
5284     }
5285
5286   /* Construct the API message */
5287   M (DELETE_LOOPBACK, mp);
5288   mp->sw_if_index = ntohl (sw_if_index);
5289
5290   S (mp);
5291   W (ret);
5292   return ret;
5293 }
5294
5295 static int
5296 api_want_stats (vat_main_t * vam)
5297 {
5298   unformat_input_t *i = vam->input;
5299   vl_api_want_stats_t *mp;
5300   int enable = -1;
5301   int ret;
5302
5303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5304     {
5305       if (unformat (i, "enable"))
5306         enable = 1;
5307       else if (unformat (i, "disable"))
5308         enable = 0;
5309       else
5310         break;
5311     }
5312
5313   if (enable == -1)
5314     {
5315       errmsg ("missing enable|disable");
5316       return -99;
5317     }
5318
5319   M (WANT_STATS, mp);
5320   mp->enable_disable = enable;
5321
5322   S (mp);
5323   W (ret);
5324   return ret;
5325 }
5326
5327 static int
5328 api_want_interface_events (vat_main_t * vam)
5329 {
5330   unformat_input_t *i = vam->input;
5331   vl_api_want_interface_events_t *mp;
5332   int enable = -1;
5333   int ret;
5334
5335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5336     {
5337       if (unformat (i, "enable"))
5338         enable = 1;
5339       else if (unformat (i, "disable"))
5340         enable = 0;
5341       else
5342         break;
5343     }
5344
5345   if (enable == -1)
5346     {
5347       errmsg ("missing enable|disable");
5348       return -99;
5349     }
5350
5351   M (WANT_INTERFACE_EVENTS, mp);
5352   mp->enable_disable = enable;
5353
5354   vam->interface_event_display = enable;
5355
5356   S (mp);
5357   W (ret);
5358   return ret;
5359 }
5360
5361
5362 /* Note: non-static, called once to set up the initial intfc table */
5363 int
5364 api_sw_interface_dump (vat_main_t * vam)
5365 {
5366   vl_api_sw_interface_dump_t *mp;
5367   vl_api_control_ping_t *mp_ping;
5368   hash_pair_t *p;
5369   name_sort_t *nses = 0, *ns;
5370   sw_interface_subif_t *sub = NULL;
5371   int ret;
5372
5373   /* Toss the old name table */
5374   /* *INDENT-OFF* */
5375   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5376   ({
5377     vec_add2 (nses, ns, 1);
5378     ns->name = (u8 *)(p->key);
5379     ns->value = (u32) p->value[0];
5380   }));
5381   /* *INDENT-ON* */
5382
5383   hash_free (vam->sw_if_index_by_interface_name);
5384
5385   vec_foreach (ns, nses) vec_free (ns->name);
5386
5387   vec_free (nses);
5388
5389   vec_foreach (sub, vam->sw_if_subif_table)
5390   {
5391     vec_free (sub->interface_name);
5392   }
5393   vec_free (vam->sw_if_subif_table);
5394
5395   /* recreate the interface name hash table */
5396   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5397
5398   /* Get list of ethernets */
5399   M (SW_INTERFACE_DUMP, mp);
5400   mp->name_filter_valid = 1;
5401   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5402   S (mp);
5403
5404   /* and local / loopback interfaces */
5405   M (SW_INTERFACE_DUMP, mp);
5406   mp->name_filter_valid = 1;
5407   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5408   S (mp);
5409
5410   /* and packet-generator interfaces */
5411   M (SW_INTERFACE_DUMP, mp);
5412   mp->name_filter_valid = 1;
5413   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5414   S (mp);
5415
5416   /* and vxlan-gpe tunnel interfaces */
5417   M (SW_INTERFACE_DUMP, mp);
5418   mp->name_filter_valid = 1;
5419   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5420            sizeof (mp->name_filter) - 1);
5421   S (mp);
5422
5423   /* and vxlan tunnel interfaces */
5424   M (SW_INTERFACE_DUMP, mp);
5425   mp->name_filter_valid = 1;
5426   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5427   S (mp);
5428
5429   /* and host (af_packet) interfaces */
5430   M (SW_INTERFACE_DUMP, mp);
5431   mp->name_filter_valid = 1;
5432   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5433   S (mp);
5434
5435   /* and l2tpv3 tunnel interfaces */
5436   M (SW_INTERFACE_DUMP, mp);
5437   mp->name_filter_valid = 1;
5438   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5439            sizeof (mp->name_filter) - 1);
5440   S (mp);
5441
5442   /* and GRE tunnel interfaces */
5443   M (SW_INTERFACE_DUMP, mp);
5444   mp->name_filter_valid = 1;
5445   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5446   S (mp);
5447
5448   /* and LISP-GPE interfaces */
5449   M (SW_INTERFACE_DUMP, mp);
5450   mp->name_filter_valid = 1;
5451   strncpy ((char *) mp->name_filter, "lisp_gpe",
5452            sizeof (mp->name_filter) - 1);
5453   S (mp);
5454
5455   /* and IPSEC tunnel interfaces */
5456   M (SW_INTERFACE_DUMP, mp);
5457   mp->name_filter_valid = 1;
5458   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5459   S (mp);
5460
5461   /* Use a control ping for synchronization */
5462   M (CONTROL_PING, mp_ping);
5463   S (mp_ping);
5464
5465   W (ret);
5466   return ret;
5467 }
5468
5469 static int
5470 api_sw_interface_set_flags (vat_main_t * vam)
5471 {
5472   unformat_input_t *i = vam->input;
5473   vl_api_sw_interface_set_flags_t *mp;
5474   u32 sw_if_index;
5475   u8 sw_if_index_set = 0;
5476   u8 admin_up = 0, link_up = 0;
5477   int ret;
5478
5479   /* Parse args required to build the message */
5480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5481     {
5482       if (unformat (i, "admin-up"))
5483         admin_up = 1;
5484       else if (unformat (i, "admin-down"))
5485         admin_up = 0;
5486       else if (unformat (i, "link-up"))
5487         link_up = 1;
5488       else if (unformat (i, "link-down"))
5489         link_up = 0;
5490       else
5491         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5492         sw_if_index_set = 1;
5493       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5494         sw_if_index_set = 1;
5495       else
5496         break;
5497     }
5498
5499   if (sw_if_index_set == 0)
5500     {
5501       errmsg ("missing interface name or sw_if_index");
5502       return -99;
5503     }
5504
5505   /* Construct the API message */
5506   M (SW_INTERFACE_SET_FLAGS, mp);
5507   mp->sw_if_index = ntohl (sw_if_index);
5508   mp->admin_up_down = admin_up;
5509   mp->link_up_down = link_up;
5510
5511   /* send it... */
5512   S (mp);
5513
5514   /* Wait for a reply, return the good/bad news... */
5515   W (ret);
5516   return ret;
5517 }
5518
5519 static int
5520 api_sw_interface_clear_stats (vat_main_t * vam)
5521 {
5522   unformat_input_t *i = vam->input;
5523   vl_api_sw_interface_clear_stats_t *mp;
5524   u32 sw_if_index;
5525   u8 sw_if_index_set = 0;
5526   int ret;
5527
5528   /* Parse args required to build the message */
5529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5530     {
5531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5532         sw_if_index_set = 1;
5533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5534         sw_if_index_set = 1;
5535       else
5536         break;
5537     }
5538
5539   /* Construct the API message */
5540   M (SW_INTERFACE_CLEAR_STATS, mp);
5541
5542   if (sw_if_index_set == 1)
5543     mp->sw_if_index = ntohl (sw_if_index);
5544   else
5545     mp->sw_if_index = ~0;
5546
5547   /* send it... */
5548   S (mp);
5549
5550   /* Wait for a reply, return the good/bad news... */
5551   W (ret);
5552   return ret;
5553 }
5554
5555 static int
5556 api_sw_interface_add_del_address (vat_main_t * vam)
5557 {
5558   unformat_input_t *i = vam->input;
5559   vl_api_sw_interface_add_del_address_t *mp;
5560   u32 sw_if_index;
5561   u8 sw_if_index_set = 0;
5562   u8 is_add = 1, del_all = 0;
5563   u32 address_length = 0;
5564   u8 v4_address_set = 0;
5565   u8 v6_address_set = 0;
5566   ip4_address_t v4address;
5567   ip6_address_t v6address;
5568   int ret;
5569
5570   /* Parse args required to build the message */
5571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5572     {
5573       if (unformat (i, "del-all"))
5574         del_all = 1;
5575       else if (unformat (i, "del"))
5576         is_add = 0;
5577       else
5578         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5579         sw_if_index_set = 1;
5580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5581         sw_if_index_set = 1;
5582       else if (unformat (i, "%U/%d",
5583                          unformat_ip4_address, &v4address, &address_length))
5584         v4_address_set = 1;
5585       else if (unformat (i, "%U/%d",
5586                          unformat_ip6_address, &v6address, &address_length))
5587         v6_address_set = 1;
5588       else
5589         break;
5590     }
5591
5592   if (sw_if_index_set == 0)
5593     {
5594       errmsg ("missing interface name or sw_if_index");
5595       return -99;
5596     }
5597   if (v4_address_set && v6_address_set)
5598     {
5599       errmsg ("both v4 and v6 addresses set");
5600       return -99;
5601     }
5602   if (!v4_address_set && !v6_address_set && !del_all)
5603     {
5604       errmsg ("no addresses set");
5605       return -99;
5606     }
5607
5608   /* Construct the API message */
5609   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5610
5611   mp->sw_if_index = ntohl (sw_if_index);
5612   mp->is_add = is_add;
5613   mp->del_all = del_all;
5614   if (v6_address_set)
5615     {
5616       mp->is_ipv6 = 1;
5617       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5618     }
5619   else
5620     {
5621       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5622     }
5623   mp->address_length = address_length;
5624
5625   /* send it... */
5626   S (mp);
5627
5628   /* Wait for a reply, return good/bad news  */
5629   W (ret);
5630   return ret;
5631 }
5632
5633 static int
5634 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5635 {
5636   unformat_input_t *i = vam->input;
5637   vl_api_sw_interface_set_mpls_enable_t *mp;
5638   u32 sw_if_index;
5639   u8 sw_if_index_set = 0;
5640   u8 enable = 1;
5641   int ret;
5642
5643   /* Parse args required to build the message */
5644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5645     {
5646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5647         sw_if_index_set = 1;
5648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5649         sw_if_index_set = 1;
5650       else if (unformat (i, "disable"))
5651         enable = 0;
5652       else if (unformat (i, "dis"))
5653         enable = 0;
5654       else
5655         break;
5656     }
5657
5658   if (sw_if_index_set == 0)
5659     {
5660       errmsg ("missing interface name or sw_if_index");
5661       return -99;
5662     }
5663
5664   /* Construct the API message */
5665   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5666
5667   mp->sw_if_index = ntohl (sw_if_index);
5668   mp->enable = enable;
5669
5670   /* send it... */
5671   S (mp);
5672
5673   /* Wait for a reply... */
5674   W (ret);
5675   return ret;
5676 }
5677
5678 static int
5679 api_sw_interface_set_table (vat_main_t * vam)
5680 {
5681   unformat_input_t *i = vam->input;
5682   vl_api_sw_interface_set_table_t *mp;
5683   u32 sw_if_index, vrf_id = 0;
5684   u8 sw_if_index_set = 0;
5685   u8 is_ipv6 = 0;
5686   int ret;
5687
5688   /* Parse args required to build the message */
5689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5690     {
5691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5692         sw_if_index_set = 1;
5693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5694         sw_if_index_set = 1;
5695       else if (unformat (i, "vrf %d", &vrf_id))
5696         ;
5697       else if (unformat (i, "ipv6"))
5698         is_ipv6 = 1;
5699       else
5700         break;
5701     }
5702
5703   if (sw_if_index_set == 0)
5704     {
5705       errmsg ("missing interface name or sw_if_index");
5706       return -99;
5707     }
5708
5709   /* Construct the API message */
5710   M (SW_INTERFACE_SET_TABLE, mp);
5711
5712   mp->sw_if_index = ntohl (sw_if_index);
5713   mp->is_ipv6 = is_ipv6;
5714   mp->vrf_id = ntohl (vrf_id);
5715
5716   /* send it... */
5717   S (mp);
5718
5719   /* Wait for a reply... */
5720   W (ret);
5721   return ret;
5722 }
5723
5724 static void vl_api_sw_interface_get_table_reply_t_handler
5725   (vl_api_sw_interface_get_table_reply_t * mp)
5726 {
5727   vat_main_t *vam = &vat_main;
5728
5729   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5730
5731   vam->retval = ntohl (mp->retval);
5732   vam->result_ready = 1;
5733
5734 }
5735
5736 static void vl_api_sw_interface_get_table_reply_t_handler_json
5737   (vl_api_sw_interface_get_table_reply_t * mp)
5738 {
5739   vat_main_t *vam = &vat_main;
5740   vat_json_node_t node;
5741
5742   vat_json_init_object (&node);
5743   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5744   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5745
5746   vat_json_print (vam->ofp, &node);
5747   vat_json_free (&node);
5748
5749   vam->retval = ntohl (mp->retval);
5750   vam->result_ready = 1;
5751 }
5752
5753 static int
5754 api_sw_interface_get_table (vat_main_t * vam)
5755 {
5756   unformat_input_t *i = vam->input;
5757   vl_api_sw_interface_get_table_t *mp;
5758   u32 sw_if_index;
5759   u8 sw_if_index_set = 0;
5760   u8 is_ipv6 = 0;
5761   int ret;
5762
5763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5764     {
5765       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5766         sw_if_index_set = 1;
5767       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5768         sw_if_index_set = 1;
5769       else if (unformat (i, "ipv6"))
5770         is_ipv6 = 1;
5771       else
5772         break;
5773     }
5774
5775   if (sw_if_index_set == 0)
5776     {
5777       errmsg ("missing interface name or sw_if_index");
5778       return -99;
5779     }
5780
5781   M (SW_INTERFACE_GET_TABLE, mp);
5782   mp->sw_if_index = htonl (sw_if_index);
5783   mp->is_ipv6 = is_ipv6;
5784
5785   S (mp);
5786   W (ret);
5787   return ret;
5788 }
5789
5790 static int
5791 api_sw_interface_set_vpath (vat_main_t * vam)
5792 {
5793   unformat_input_t *i = vam->input;
5794   vl_api_sw_interface_set_vpath_t *mp;
5795   u32 sw_if_index = 0;
5796   u8 sw_if_index_set = 0;
5797   u8 is_enable = 0;
5798   int ret;
5799
5800   /* Parse args required to build the message */
5801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5802     {
5803       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5804         sw_if_index_set = 1;
5805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5806         sw_if_index_set = 1;
5807       else if (unformat (i, "enable"))
5808         is_enable = 1;
5809       else if (unformat (i, "disable"))
5810         is_enable = 0;
5811       else
5812         break;
5813     }
5814
5815   if (sw_if_index_set == 0)
5816     {
5817       errmsg ("missing interface name or sw_if_index");
5818       return -99;
5819     }
5820
5821   /* Construct the API message */
5822   M (SW_INTERFACE_SET_VPATH, mp);
5823
5824   mp->sw_if_index = ntohl (sw_if_index);
5825   mp->enable = is_enable;
5826
5827   /* send it... */
5828   S (mp);
5829
5830   /* Wait for a reply... */
5831   W (ret);
5832   return ret;
5833 }
5834
5835 static int
5836 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5837 {
5838   unformat_input_t *i = vam->input;
5839   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5840   u32 sw_if_index = 0;
5841   u8 sw_if_index_set = 0;
5842   u8 is_enable = 1;
5843   u8 is_ipv6 = 0;
5844   int ret;
5845
5846   /* Parse args required to build the message */
5847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5848     {
5849       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5850         sw_if_index_set = 1;
5851       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5852         sw_if_index_set = 1;
5853       else if (unformat (i, "enable"))
5854         is_enable = 1;
5855       else if (unformat (i, "disable"))
5856         is_enable = 0;
5857       else if (unformat (i, "ip4"))
5858         is_ipv6 = 0;
5859       else if (unformat (i, "ip6"))
5860         is_ipv6 = 1;
5861       else
5862         break;
5863     }
5864
5865   if (sw_if_index_set == 0)
5866     {
5867       errmsg ("missing interface name or sw_if_index");
5868       return -99;
5869     }
5870
5871   /* Construct the API message */
5872   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5873
5874   mp->sw_if_index = ntohl (sw_if_index);
5875   mp->enable = is_enable;
5876   mp->is_ipv6 = is_ipv6;
5877
5878   /* send it... */
5879   S (mp);
5880
5881   /* Wait for a reply... */
5882   W (ret);
5883   return ret;
5884 }
5885
5886 static int
5887 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5888 {
5889   unformat_input_t *i = vam->input;
5890   vl_api_sw_interface_set_l2_xconnect_t *mp;
5891   u32 rx_sw_if_index;
5892   u8 rx_sw_if_index_set = 0;
5893   u32 tx_sw_if_index;
5894   u8 tx_sw_if_index_set = 0;
5895   u8 enable = 1;
5896   int ret;
5897
5898   /* Parse args required to build the message */
5899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5900     {
5901       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5902         rx_sw_if_index_set = 1;
5903       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5904         tx_sw_if_index_set = 1;
5905       else if (unformat (i, "rx"))
5906         {
5907           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5908             {
5909               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5910                             &rx_sw_if_index))
5911                 rx_sw_if_index_set = 1;
5912             }
5913           else
5914             break;
5915         }
5916       else if (unformat (i, "tx"))
5917         {
5918           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5919             {
5920               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5921                             &tx_sw_if_index))
5922                 tx_sw_if_index_set = 1;
5923             }
5924           else
5925             break;
5926         }
5927       else if (unformat (i, "enable"))
5928         enable = 1;
5929       else if (unformat (i, "disable"))
5930         enable = 0;
5931       else
5932         break;
5933     }
5934
5935   if (rx_sw_if_index_set == 0)
5936     {
5937       errmsg ("missing rx interface name or rx_sw_if_index");
5938       return -99;
5939     }
5940
5941   if (enable && (tx_sw_if_index_set == 0))
5942     {
5943       errmsg ("missing tx interface name or tx_sw_if_index");
5944       return -99;
5945     }
5946
5947   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5948
5949   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5950   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5951   mp->enable = enable;
5952
5953   S (mp);
5954   W (ret);
5955   return ret;
5956 }
5957
5958 static int
5959 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5960 {
5961   unformat_input_t *i = vam->input;
5962   vl_api_sw_interface_set_l2_bridge_t *mp;
5963   u32 rx_sw_if_index;
5964   u8 rx_sw_if_index_set = 0;
5965   u32 bd_id;
5966   u8 bd_id_set = 0;
5967   u8 bvi = 0;
5968   u32 shg = 0;
5969   u8 enable = 1;
5970   int ret;
5971
5972   /* Parse args required to build the message */
5973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5974     {
5975       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5976         rx_sw_if_index_set = 1;
5977       else if (unformat (i, "bd_id %d", &bd_id))
5978         bd_id_set = 1;
5979       else
5980         if (unformat
5981             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5982         rx_sw_if_index_set = 1;
5983       else if (unformat (i, "shg %d", &shg))
5984         ;
5985       else if (unformat (i, "bvi"))
5986         bvi = 1;
5987       else if (unformat (i, "enable"))
5988         enable = 1;
5989       else if (unformat (i, "disable"))
5990         enable = 0;
5991       else
5992         break;
5993     }
5994
5995   if (rx_sw_if_index_set == 0)
5996     {
5997       errmsg ("missing rx interface name or sw_if_index");
5998       return -99;
5999     }
6000
6001   if (enable && (bd_id_set == 0))
6002     {
6003       errmsg ("missing bridge domain");
6004       return -99;
6005     }
6006
6007   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6008
6009   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6010   mp->bd_id = ntohl (bd_id);
6011   mp->shg = (u8) shg;
6012   mp->bvi = bvi;
6013   mp->enable = enable;
6014
6015   S (mp);
6016   W (ret);
6017   return ret;
6018 }
6019
6020 static int
6021 api_bridge_domain_dump (vat_main_t * vam)
6022 {
6023   unformat_input_t *i = vam->input;
6024   vl_api_bridge_domain_dump_t *mp;
6025   vl_api_control_ping_t *mp_ping;
6026   u32 bd_id = ~0;
6027   int ret;
6028
6029   /* Parse args required to build the message */
6030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6031     {
6032       if (unformat (i, "bd_id %d", &bd_id))
6033         ;
6034       else
6035         break;
6036     }
6037
6038   M (BRIDGE_DOMAIN_DUMP, mp);
6039   mp->bd_id = ntohl (bd_id);
6040   S (mp);
6041
6042   /* Use a control ping for synchronization */
6043   M (CONTROL_PING, mp_ping);
6044   S (mp_ping);
6045
6046   W (ret);
6047   return ret;
6048 }
6049
6050 static int
6051 api_bridge_domain_add_del (vat_main_t * vam)
6052 {
6053   unformat_input_t *i = vam->input;
6054   vl_api_bridge_domain_add_del_t *mp;
6055   u32 bd_id = ~0;
6056   u8 is_add = 1;
6057   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6058   u32 mac_age = 0;
6059   int ret;
6060
6061   /* Parse args required to build the message */
6062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6063     {
6064       if (unformat (i, "bd_id %d", &bd_id))
6065         ;
6066       else if (unformat (i, "flood %d", &flood))
6067         ;
6068       else if (unformat (i, "uu-flood %d", &uu_flood))
6069         ;
6070       else if (unformat (i, "forward %d", &forward))
6071         ;
6072       else if (unformat (i, "learn %d", &learn))
6073         ;
6074       else if (unformat (i, "arp-term %d", &arp_term))
6075         ;
6076       else if (unformat (i, "mac-age %d", &mac_age))
6077         ;
6078       else if (unformat (i, "del"))
6079         {
6080           is_add = 0;
6081           flood = uu_flood = forward = learn = 0;
6082         }
6083       else
6084         break;
6085     }
6086
6087   if (bd_id == ~0)
6088     {
6089       errmsg ("missing bridge domain");
6090       return -99;
6091     }
6092
6093   if (mac_age > 255)
6094     {
6095       errmsg ("mac age must be less than 256 ");
6096       return -99;
6097     }
6098
6099   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6100
6101   mp->bd_id = ntohl (bd_id);
6102   mp->flood = flood;
6103   mp->uu_flood = uu_flood;
6104   mp->forward = forward;
6105   mp->learn = learn;
6106   mp->arp_term = arp_term;
6107   mp->is_add = is_add;
6108   mp->mac_age = (u8) mac_age;
6109
6110   S (mp);
6111   W (ret);
6112   return ret;
6113 }
6114
6115 static int
6116 api_l2fib_flush_bd (vat_main_t * vam)
6117 {
6118   unformat_input_t *i = vam->input;
6119   vl_api_l2fib_flush_bd_t *mp;
6120   u32 bd_id = ~0;
6121   int ret;
6122
6123   /* Parse args required to build the message */
6124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6125     {
6126       if (unformat (i, "bd_id %d", &bd_id));
6127       else
6128         break;
6129     }
6130
6131   if (bd_id == ~0)
6132     {
6133       errmsg ("missing bridge domain");
6134       return -99;
6135     }
6136
6137   M (L2FIB_FLUSH_BD, mp);
6138
6139   mp->bd_id = htonl (bd_id);
6140
6141   S (mp);
6142   W (ret);
6143   return ret;
6144 }
6145
6146 static int
6147 api_l2fib_flush_int (vat_main_t * vam)
6148 {
6149   unformat_input_t *i = vam->input;
6150   vl_api_l2fib_flush_int_t *mp;
6151   u32 sw_if_index = ~0;
6152   int ret;
6153
6154   /* Parse args required to build the message */
6155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6156     {
6157       if (unformat (i, "sw_if_index %d", &sw_if_index));
6158       else
6159         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6160       else
6161         break;
6162     }
6163
6164   if (sw_if_index == ~0)
6165     {
6166       errmsg ("missing interface name or sw_if_index");
6167       return -99;
6168     }
6169
6170   M (L2FIB_FLUSH_INT, mp);
6171
6172   mp->sw_if_index = ntohl (sw_if_index);
6173
6174   S (mp);
6175   W (ret);
6176   return ret;
6177 }
6178
6179 static int
6180 api_l2fib_add_del (vat_main_t * vam)
6181 {
6182   unformat_input_t *i = vam->input;
6183   vl_api_l2fib_add_del_t *mp;
6184   f64 timeout;
6185   u64 mac = 0;
6186   u8 mac_set = 0;
6187   u32 bd_id;
6188   u8 bd_id_set = 0;
6189   u32 sw_if_index = ~0;
6190   u8 sw_if_index_set = 0;
6191   u8 is_add = 1;
6192   u8 static_mac = 0;
6193   u8 filter_mac = 0;
6194   u8 bvi_mac = 0;
6195   int count = 1;
6196   f64 before = 0;
6197   int j;
6198
6199   /* Parse args required to build the message */
6200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6201     {
6202       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6203         mac_set = 1;
6204       else if (unformat (i, "bd_id %d", &bd_id))
6205         bd_id_set = 1;
6206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6207         sw_if_index_set = 1;
6208       else if (unformat (i, "sw_if"))
6209         {
6210           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6211             {
6212               if (unformat
6213                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6214                 sw_if_index_set = 1;
6215             }
6216           else
6217             break;
6218         }
6219       else if (unformat (i, "static"))
6220         static_mac = 1;
6221       else if (unformat (i, "filter"))
6222         {
6223           filter_mac = 1;
6224           static_mac = 1;
6225         }
6226       else if (unformat (i, "bvi"))
6227         {
6228           bvi_mac = 1;
6229           static_mac = 1;
6230         }
6231       else if (unformat (i, "del"))
6232         is_add = 0;
6233       else if (unformat (i, "count %d", &count))
6234         ;
6235       else
6236         break;
6237     }
6238
6239   if (mac_set == 0)
6240     {
6241       errmsg ("missing mac address");
6242       return -99;
6243     }
6244
6245   if (bd_id_set == 0)
6246     {
6247       errmsg ("missing bridge domain");
6248       return -99;
6249     }
6250
6251   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6252     {
6253       errmsg ("missing interface name or sw_if_index");
6254       return -99;
6255     }
6256
6257   if (count > 1)
6258     {
6259       /* Turn on async mode */
6260       vam->async_mode = 1;
6261       vam->async_errors = 0;
6262       before = vat_time_now (vam);
6263     }
6264
6265   for (j = 0; j < count; j++)
6266     {
6267       M (L2FIB_ADD_DEL, mp);
6268
6269       mp->mac = mac;
6270       mp->bd_id = ntohl (bd_id);
6271       mp->is_add = is_add;
6272
6273       if (is_add)
6274         {
6275           mp->sw_if_index = ntohl (sw_if_index);
6276           mp->static_mac = static_mac;
6277           mp->filter_mac = filter_mac;
6278           mp->bvi_mac = bvi_mac;
6279         }
6280       increment_mac_address (&mac);
6281       /* send it... */
6282       S (mp);
6283     }
6284
6285   if (count > 1)
6286     {
6287       vl_api_control_ping_t *mp_ping;
6288       f64 after;
6289
6290       /* Shut off async mode */
6291       vam->async_mode = 0;
6292
6293       M (CONTROL_PING, mp_ping);
6294       S (mp_ping);
6295
6296       timeout = vat_time_now (vam) + 1.0;
6297       while (vat_time_now (vam) < timeout)
6298         if (vam->result_ready == 1)
6299           goto out;
6300       vam->retval = -99;
6301
6302     out:
6303       if (vam->retval == -99)
6304         errmsg ("timeout");
6305
6306       if (vam->async_errors > 0)
6307         {
6308           errmsg ("%d asynchronous errors", vam->async_errors);
6309           vam->retval = -98;
6310         }
6311       vam->async_errors = 0;
6312       after = vat_time_now (vam);
6313
6314       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6315              count, after - before, count / (after - before));
6316     }
6317   else
6318     {
6319       int ret;
6320
6321       /* Wait for a reply... */
6322       W (ret);
6323       return ret;
6324     }
6325   /* Return the good/bad news */
6326   return (vam->retval);
6327 }
6328
6329 static int
6330 api_bridge_domain_set_mac_age (vat_main_t * vam)
6331 {
6332   unformat_input_t *i = vam->input;
6333   vl_api_bridge_domain_set_mac_age_t *mp;
6334   u32 bd_id = ~0;
6335   u32 mac_age = 0;
6336   int ret;
6337
6338   /* Parse args required to build the message */
6339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6340     {
6341       if (unformat (i, "bd_id %d", &bd_id));
6342       else if (unformat (i, "mac-age %d", &mac_age));
6343       else
6344         break;
6345     }
6346
6347   if (bd_id == ~0)
6348     {
6349       errmsg ("missing bridge domain");
6350       return -99;
6351     }
6352
6353   if (mac_age > 255)
6354     {
6355       errmsg ("mac age must be less than 256 ");
6356       return -99;
6357     }
6358
6359   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6360
6361   mp->bd_id = htonl (bd_id);
6362   mp->mac_age = (u8) mac_age;
6363
6364   S (mp);
6365   W (ret);
6366   return ret;
6367 }
6368
6369 static int
6370 api_l2_flags (vat_main_t * vam)
6371 {
6372   unformat_input_t *i = vam->input;
6373   vl_api_l2_flags_t *mp;
6374   u32 sw_if_index;
6375   u32 feature_bitmap = 0;
6376   u8 sw_if_index_set = 0;
6377   int ret;
6378
6379   /* Parse args required to build the message */
6380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6381     {
6382       if (unformat (i, "sw_if_index %d", &sw_if_index))
6383         sw_if_index_set = 1;
6384       else if (unformat (i, "sw_if"))
6385         {
6386           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6387             {
6388               if (unformat
6389                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6390                 sw_if_index_set = 1;
6391             }
6392           else
6393             break;
6394         }
6395       else if (unformat (i, "learn"))
6396         feature_bitmap |= L2INPUT_FEAT_LEARN;
6397       else if (unformat (i, "forward"))
6398         feature_bitmap |= L2INPUT_FEAT_FWD;
6399       else if (unformat (i, "flood"))
6400         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6401       else if (unformat (i, "uu-flood"))
6402         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6403       else
6404         break;
6405     }
6406
6407   if (sw_if_index_set == 0)
6408     {
6409       errmsg ("missing interface name or sw_if_index");
6410       return -99;
6411     }
6412
6413   M (L2_FLAGS, mp);
6414
6415   mp->sw_if_index = ntohl (sw_if_index);
6416   mp->feature_bitmap = ntohl (feature_bitmap);
6417
6418   S (mp);
6419   W (ret);
6420   return ret;
6421 }
6422
6423 static int
6424 api_bridge_flags (vat_main_t * vam)
6425 {
6426   unformat_input_t *i = vam->input;
6427   vl_api_bridge_flags_t *mp;
6428   u32 bd_id;
6429   u8 bd_id_set = 0;
6430   u8 is_set = 1;
6431   u32 flags = 0;
6432   int ret;
6433
6434   /* Parse args required to build the message */
6435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6436     {
6437       if (unformat (i, "bd_id %d", &bd_id))
6438         bd_id_set = 1;
6439       else if (unformat (i, "learn"))
6440         flags |= L2_LEARN;
6441       else if (unformat (i, "forward"))
6442         flags |= L2_FWD;
6443       else if (unformat (i, "flood"))
6444         flags |= L2_FLOOD;
6445       else if (unformat (i, "uu-flood"))
6446         flags |= L2_UU_FLOOD;
6447       else if (unformat (i, "arp-term"))
6448         flags |= L2_ARP_TERM;
6449       else if (unformat (i, "off"))
6450         is_set = 0;
6451       else if (unformat (i, "disable"))
6452         is_set = 0;
6453       else
6454         break;
6455     }
6456
6457   if (bd_id_set == 0)
6458     {
6459       errmsg ("missing bridge domain");
6460       return -99;
6461     }
6462
6463   M (BRIDGE_FLAGS, mp);
6464
6465   mp->bd_id = ntohl (bd_id);
6466   mp->feature_bitmap = ntohl (flags);
6467   mp->is_set = is_set;
6468
6469   S (mp);
6470   W (ret);
6471   return ret;
6472 }
6473
6474 static int
6475 api_bd_ip_mac_add_del (vat_main_t * vam)
6476 {
6477   unformat_input_t *i = vam->input;
6478   vl_api_bd_ip_mac_add_del_t *mp;
6479   u32 bd_id;
6480   u8 is_ipv6 = 0;
6481   u8 is_add = 1;
6482   u8 bd_id_set = 0;
6483   u8 ip_set = 0;
6484   u8 mac_set = 0;
6485   ip4_address_t v4addr;
6486   ip6_address_t v6addr;
6487   u8 macaddr[6];
6488   int ret;
6489
6490
6491   /* Parse args required to build the message */
6492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6493     {
6494       if (unformat (i, "bd_id %d", &bd_id))
6495         {
6496           bd_id_set++;
6497         }
6498       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6499         {
6500           ip_set++;
6501         }
6502       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6503         {
6504           ip_set++;
6505           is_ipv6++;
6506         }
6507       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6508         {
6509           mac_set++;
6510         }
6511       else if (unformat (i, "del"))
6512         is_add = 0;
6513       else
6514         break;
6515     }
6516
6517   if (bd_id_set == 0)
6518     {
6519       errmsg ("missing bridge domain");
6520       return -99;
6521     }
6522   else if (ip_set == 0)
6523     {
6524       errmsg ("missing IP address");
6525       return -99;
6526     }
6527   else if (mac_set == 0)
6528     {
6529       errmsg ("missing MAC address");
6530       return -99;
6531     }
6532
6533   M (BD_IP_MAC_ADD_DEL, mp);
6534
6535   mp->bd_id = ntohl (bd_id);
6536   mp->is_ipv6 = is_ipv6;
6537   mp->is_add = is_add;
6538   if (is_ipv6)
6539     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6540   else
6541     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6542   clib_memcpy (mp->mac_address, macaddr, 6);
6543   S (mp);
6544   W (ret);
6545   return ret;
6546 }
6547
6548 static int
6549 api_tap_connect (vat_main_t * vam)
6550 {
6551   unformat_input_t *i = vam->input;
6552   vl_api_tap_connect_t *mp;
6553   u8 mac_address[6];
6554   u8 random_mac = 1;
6555   u8 name_set = 0;
6556   u8 *tap_name;
6557   u8 *tag = 0;
6558   ip4_address_t ip4_address;
6559   u32 ip4_mask_width;
6560   int ip4_address_set = 0;
6561   ip6_address_t ip6_address;
6562   u32 ip6_mask_width;
6563   int ip6_address_set = 0;
6564   int ret;
6565
6566   memset (mac_address, 0, sizeof (mac_address));
6567
6568   /* Parse args required to build the message */
6569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6570     {
6571       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6572         {
6573           random_mac = 0;
6574         }
6575       else if (unformat (i, "random-mac"))
6576         random_mac = 1;
6577       else if (unformat (i, "tapname %s", &tap_name))
6578         name_set = 1;
6579       else if (unformat (i, "tag %s", &tag))
6580         ;
6581       else if (unformat (i, "address %U/%d",
6582                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6583         ip4_address_set = 1;
6584       else if (unformat (i, "address %U/%d",
6585                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6586         ip6_address_set = 1;
6587       else
6588         break;
6589     }
6590
6591   if (name_set == 0)
6592     {
6593       errmsg ("missing tap name");
6594       return -99;
6595     }
6596   if (vec_len (tap_name) > 63)
6597     {
6598       errmsg ("tap name too long");
6599       return -99;
6600     }
6601   vec_add1 (tap_name, 0);
6602
6603   if (vec_len (tag) > 63)
6604     {
6605       errmsg ("tag too long");
6606       return -99;
6607     }
6608
6609   /* Construct the API message */
6610   M (TAP_CONNECT, mp);
6611
6612   mp->use_random_mac = random_mac;
6613   clib_memcpy (mp->mac_address, mac_address, 6);
6614   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6615   if (tag)
6616     clib_memcpy (mp->tag, tag, vec_len (tag));
6617
6618   if (ip4_address_set)
6619     {
6620       mp->ip4_address_set = 1;
6621       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6622       mp->ip4_mask_width = ip4_mask_width;
6623     }
6624   if (ip6_address_set)
6625     {
6626       mp->ip6_address_set = 1;
6627       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6628       mp->ip6_mask_width = ip6_mask_width;
6629     }
6630
6631   vec_free (tap_name);
6632   vec_free (tag);
6633
6634   /* send it... */
6635   S (mp);
6636
6637   /* Wait for a reply... */
6638   W (ret);
6639   return ret;
6640 }
6641
6642 static int
6643 api_tap_modify (vat_main_t * vam)
6644 {
6645   unformat_input_t *i = vam->input;
6646   vl_api_tap_modify_t *mp;
6647   u8 mac_address[6];
6648   u8 random_mac = 1;
6649   u8 name_set = 0;
6650   u8 *tap_name;
6651   u32 sw_if_index = ~0;
6652   u8 sw_if_index_set = 0;
6653   int ret;
6654
6655   memset (mac_address, 0, sizeof (mac_address));
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6661         sw_if_index_set = 1;
6662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6663         sw_if_index_set = 1;
6664       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6665         {
6666           random_mac = 0;
6667         }
6668       else if (unformat (i, "random-mac"))
6669         random_mac = 1;
6670       else if (unformat (i, "tapname %s", &tap_name))
6671         name_set = 1;
6672       else
6673         break;
6674     }
6675
6676   if (sw_if_index_set == 0)
6677     {
6678       errmsg ("missing vpp interface name");
6679       return -99;
6680     }
6681   if (name_set == 0)
6682     {
6683       errmsg ("missing tap name");
6684       return -99;
6685     }
6686   if (vec_len (tap_name) > 63)
6687     {
6688       errmsg ("tap name too long");
6689     }
6690   vec_add1 (tap_name, 0);
6691
6692   /* Construct the API message */
6693   M (TAP_MODIFY, mp);
6694
6695   mp->use_random_mac = random_mac;
6696   mp->sw_if_index = ntohl (sw_if_index);
6697   clib_memcpy (mp->mac_address, mac_address, 6);
6698   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6699   vec_free (tap_name);
6700
6701   /* send it... */
6702   S (mp);
6703
6704   /* Wait for a reply... */
6705   W (ret);
6706   return ret;
6707 }
6708
6709 static int
6710 api_tap_delete (vat_main_t * vam)
6711 {
6712   unformat_input_t *i = vam->input;
6713   vl_api_tap_delete_t *mp;
6714   u32 sw_if_index = ~0;
6715   u8 sw_if_index_set = 0;
6716   int ret;
6717
6718   /* Parse args required to build the message */
6719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6720     {
6721       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6722         sw_if_index_set = 1;
6723       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6724         sw_if_index_set = 1;
6725       else
6726         break;
6727     }
6728
6729   if (sw_if_index_set == 0)
6730     {
6731       errmsg ("missing vpp interface name");
6732       return -99;
6733     }
6734
6735   /* Construct the API message */
6736   M (TAP_DELETE, mp);
6737
6738   mp->sw_if_index = ntohl (sw_if_index);
6739
6740   /* send it... */
6741   S (mp);
6742
6743   /* Wait for a reply... */
6744   W (ret);
6745   return ret;
6746 }
6747
6748 static int
6749 api_ip_add_del_route (vat_main_t * vam)
6750 {
6751   unformat_input_t *i = vam->input;
6752   vl_api_ip_add_del_route_t *mp;
6753   u32 sw_if_index = ~0, vrf_id = 0;
6754   u8 is_ipv6 = 0;
6755   u8 is_local = 0, is_drop = 0;
6756   u8 is_unreach = 0, is_prohibit = 0;
6757   u8 create_vrf_if_needed = 0;
6758   u8 is_add = 1;
6759   u32 next_hop_weight = 1;
6760   u8 not_last = 0;
6761   u8 is_multipath = 0;
6762   u8 address_set = 0;
6763   u8 address_length_set = 0;
6764   u32 next_hop_table_id = 0;
6765   u32 resolve_attempts = 0;
6766   u32 dst_address_length = 0;
6767   u8 next_hop_set = 0;
6768   ip4_address_t v4_dst_address, v4_next_hop_address;
6769   ip6_address_t v6_dst_address, v6_next_hop_address;
6770   int count = 1;
6771   int j;
6772   f64 before = 0;
6773   u32 random_add_del = 0;
6774   u32 *random_vector = 0;
6775   uword *random_hash;
6776   u32 random_seed = 0xdeaddabe;
6777   u32 classify_table_index = ~0;
6778   u8 is_classify = 0;
6779   u8 resolve_host = 0, resolve_attached = 0;
6780   mpls_label_t *next_hop_out_label_stack = NULL;
6781   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6782   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6783
6784   /* Parse args required to build the message */
6785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6786     {
6787       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6788         ;
6789       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6790         ;
6791       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6792         {
6793           address_set = 1;
6794           is_ipv6 = 0;
6795         }
6796       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6797         {
6798           address_set = 1;
6799           is_ipv6 = 1;
6800         }
6801       else if (unformat (i, "/%d", &dst_address_length))
6802         {
6803           address_length_set = 1;
6804         }
6805
6806       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6807                                          &v4_next_hop_address))
6808         {
6809           next_hop_set = 1;
6810         }
6811       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6812                                          &v6_next_hop_address))
6813         {
6814           next_hop_set = 1;
6815         }
6816       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6817         ;
6818       else if (unformat (i, "weight %d", &next_hop_weight))
6819         ;
6820       else if (unformat (i, "drop"))
6821         {
6822           is_drop = 1;
6823         }
6824       else if (unformat (i, "null-send-unreach"))
6825         {
6826           is_unreach = 1;
6827         }
6828       else if (unformat (i, "null-send-prohibit"))
6829         {
6830           is_prohibit = 1;
6831         }
6832       else if (unformat (i, "local"))
6833         {
6834           is_local = 1;
6835         }
6836       else if (unformat (i, "classify %d", &classify_table_index))
6837         {
6838           is_classify = 1;
6839         }
6840       else if (unformat (i, "del"))
6841         is_add = 0;
6842       else if (unformat (i, "add"))
6843         is_add = 1;
6844       else if (unformat (i, "not-last"))
6845         not_last = 1;
6846       else if (unformat (i, "resolve-via-host"))
6847         resolve_host = 1;
6848       else if (unformat (i, "resolve-via-attached"))
6849         resolve_attached = 1;
6850       else if (unformat (i, "multipath"))
6851         is_multipath = 1;
6852       else if (unformat (i, "vrf %d", &vrf_id))
6853         ;
6854       else if (unformat (i, "create-vrf"))
6855         create_vrf_if_needed = 1;
6856       else if (unformat (i, "count %d", &count))
6857         ;
6858       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6859         ;
6860       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6861         ;
6862       else if (unformat (i, "out-label %d", &next_hop_out_label))
6863         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6864       else if (unformat (i, "via-label %d", &next_hop_via_label))
6865         ;
6866       else if (unformat (i, "random"))
6867         random_add_del = 1;
6868       else if (unformat (i, "seed %d", &random_seed))
6869         ;
6870       else
6871         {
6872           clib_warning ("parse error '%U'", format_unformat_error, i);
6873           return -99;
6874         }
6875     }
6876
6877   if (!next_hop_set && !is_drop && !is_local &&
6878       !is_classify && !is_unreach && !is_prohibit &&
6879       MPLS_LABEL_INVALID == next_hop_via_label)
6880     {
6881       errmsg
6882         ("next hop / local / drop / unreach / prohibit / classify not set");
6883       return -99;
6884     }
6885
6886   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6887     {
6888       errmsg ("next hop and next-hop via label set");
6889       return -99;
6890     }
6891   if (address_set == 0)
6892     {
6893       errmsg ("missing addresses");
6894       return -99;
6895     }
6896
6897   if (address_length_set == 0)
6898     {
6899       errmsg ("missing address length");
6900       return -99;
6901     }
6902
6903   /* Generate a pile of unique, random routes */
6904   if (random_add_del)
6905     {
6906       u32 this_random_address;
6907       random_hash = hash_create (count, sizeof (uword));
6908
6909       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6910       for (j = 0; j <= count; j++)
6911         {
6912           do
6913             {
6914               this_random_address = random_u32 (&random_seed);
6915               this_random_address =
6916                 clib_host_to_net_u32 (this_random_address);
6917             }
6918           while (hash_get (random_hash, this_random_address));
6919           vec_add1 (random_vector, this_random_address);
6920           hash_set (random_hash, this_random_address, 1);
6921         }
6922       hash_free (random_hash);
6923       v4_dst_address.as_u32 = random_vector[0];
6924     }
6925
6926   if (count > 1)
6927     {
6928       /* Turn on async mode */
6929       vam->async_mode = 1;
6930       vam->async_errors = 0;
6931       before = vat_time_now (vam);
6932     }
6933
6934   for (j = 0; j < count; j++)
6935     {
6936       /* Construct the API message */
6937       M2 (IP_ADD_DEL_ROUTE, mp,
6938           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6939
6940       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6941       mp->table_id = ntohl (vrf_id);
6942       mp->create_vrf_if_needed = create_vrf_if_needed;
6943
6944       mp->is_add = is_add;
6945       mp->is_drop = is_drop;
6946       mp->is_unreach = is_unreach;
6947       mp->is_prohibit = is_prohibit;
6948       mp->is_ipv6 = is_ipv6;
6949       mp->is_local = is_local;
6950       mp->is_classify = is_classify;
6951       mp->is_multipath = is_multipath;
6952       mp->is_resolve_host = resolve_host;
6953       mp->is_resolve_attached = resolve_attached;
6954       mp->not_last = not_last;
6955       mp->next_hop_weight = next_hop_weight;
6956       mp->dst_address_length = dst_address_length;
6957       mp->next_hop_table_id = ntohl (next_hop_table_id);
6958       mp->classify_table_index = ntohl (classify_table_index);
6959       mp->next_hop_via_label = ntohl (next_hop_via_label);
6960       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6961       if (0 != mp->next_hop_n_out_labels)
6962         {
6963           memcpy (mp->next_hop_out_label_stack,
6964                   next_hop_out_label_stack,
6965                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6966           vec_free (next_hop_out_label_stack);
6967         }
6968
6969       if (is_ipv6)
6970         {
6971           clib_memcpy (mp->dst_address, &v6_dst_address,
6972                        sizeof (v6_dst_address));
6973           if (next_hop_set)
6974             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6975                          sizeof (v6_next_hop_address));
6976           increment_v6_address (&v6_dst_address);
6977         }
6978       else
6979         {
6980           clib_memcpy (mp->dst_address, &v4_dst_address,
6981                        sizeof (v4_dst_address));
6982           if (next_hop_set)
6983             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6984                          sizeof (v4_next_hop_address));
6985           if (random_add_del)
6986             v4_dst_address.as_u32 = random_vector[j + 1];
6987           else
6988             increment_v4_address (&v4_dst_address);
6989         }
6990       /* send it... */
6991       S (mp);
6992       /* If we receive SIGTERM, stop now... */
6993       if (vam->do_exit)
6994         break;
6995     }
6996
6997   /* When testing multiple add/del ops, use a control-ping to sync */
6998   if (count > 1)
6999     {
7000       vl_api_control_ping_t *mp_ping;
7001       f64 after;
7002       f64 timeout;
7003
7004       /* Shut off async mode */
7005       vam->async_mode = 0;
7006
7007       M (CONTROL_PING, mp_ping);
7008       S (mp_ping);
7009
7010       timeout = vat_time_now (vam) + 1.0;
7011       while (vat_time_now (vam) < timeout)
7012         if (vam->result_ready == 1)
7013           goto out;
7014       vam->retval = -99;
7015
7016     out:
7017       if (vam->retval == -99)
7018         errmsg ("timeout");
7019
7020       if (vam->async_errors > 0)
7021         {
7022           errmsg ("%d asynchronous errors", vam->async_errors);
7023           vam->retval = -98;
7024         }
7025       vam->async_errors = 0;
7026       after = vat_time_now (vam);
7027
7028       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7029       if (j > 0)
7030         count = j;
7031
7032       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7033              count, after - before, count / (after - before));
7034     }
7035   else
7036     {
7037       int ret;
7038
7039       /* Wait for a reply... */
7040       W (ret);
7041       return ret;
7042     }
7043
7044   /* Return the good/bad news */
7045   return (vam->retval);
7046 }
7047
7048 static int
7049 api_ip_mroute_add_del (vat_main_t * vam)
7050 {
7051   unformat_input_t *i = vam->input;
7052   vl_api_ip_mroute_add_del_t *mp;
7053   u32 sw_if_index = ~0, vrf_id = 0;
7054   u8 is_ipv6 = 0;
7055   u8 is_local = 0;
7056   u8 create_vrf_if_needed = 0;
7057   u8 is_add = 1;
7058   u8 address_set = 0;
7059   u32 grp_address_length = 0;
7060   ip4_address_t v4_grp_address, v4_src_address;
7061   ip6_address_t v6_grp_address, v6_src_address;
7062   mfib_itf_flags_t iflags = 0;
7063   mfib_entry_flags_t eflags = 0;
7064   int ret;
7065
7066   /* Parse args required to build the message */
7067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7068     {
7069       if (unformat (i, "sw_if_index %d", &sw_if_index))
7070         ;
7071       else if (unformat (i, "%U %U",
7072                          unformat_ip4_address, &v4_src_address,
7073                          unformat_ip4_address, &v4_grp_address))
7074         {
7075           grp_address_length = 64;
7076           address_set = 1;
7077           is_ipv6 = 0;
7078         }
7079       else if (unformat (i, "%U %U",
7080                          unformat_ip6_address, &v6_src_address,
7081                          unformat_ip6_address, &v6_grp_address))
7082         {
7083           grp_address_length = 256;
7084           address_set = 1;
7085           is_ipv6 = 1;
7086         }
7087       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7088         {
7089           memset (&v4_src_address, 0, sizeof (v4_src_address));
7090           grp_address_length = 32;
7091           address_set = 1;
7092           is_ipv6 = 0;
7093         }
7094       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7095         {
7096           memset (&v6_src_address, 0, sizeof (v6_src_address));
7097           grp_address_length = 128;
7098           address_set = 1;
7099           is_ipv6 = 1;
7100         }
7101       else if (unformat (i, "/%d", &grp_address_length))
7102         ;
7103       else if (unformat (i, "local"))
7104         {
7105           is_local = 1;
7106         }
7107       else if (unformat (i, "del"))
7108         is_add = 0;
7109       else if (unformat (i, "add"))
7110         is_add = 1;
7111       else if (unformat (i, "vrf %d", &vrf_id))
7112         ;
7113       else if (unformat (i, "create-vrf"))
7114         create_vrf_if_needed = 1;
7115       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7116         ;
7117       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7118         ;
7119       else
7120         {
7121           clib_warning ("parse error '%U'", format_unformat_error, i);
7122           return -99;
7123         }
7124     }
7125
7126   if (address_set == 0)
7127     {
7128       errmsg ("missing addresses\n");
7129       return -99;
7130     }
7131
7132   /* Construct the API message */
7133   M (IP_MROUTE_ADD_DEL, mp);
7134
7135   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7136   mp->table_id = ntohl (vrf_id);
7137   mp->create_vrf_if_needed = create_vrf_if_needed;
7138
7139   mp->is_add = is_add;
7140   mp->is_ipv6 = is_ipv6;
7141   mp->is_local = is_local;
7142   mp->itf_flags = ntohl (iflags);
7143   mp->entry_flags = ntohl (eflags);
7144   mp->grp_address_length = grp_address_length;
7145   mp->grp_address_length = ntohs (mp->grp_address_length);
7146
7147   if (is_ipv6)
7148     {
7149       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7150       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7151     }
7152   else
7153     {
7154       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7155       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7156
7157     }
7158
7159   /* send it... */
7160   S (mp);
7161   /* Wait for a reply... */
7162   W (ret);
7163   return ret;
7164 }
7165
7166 static int
7167 api_mpls_route_add_del (vat_main_t * vam)
7168 {
7169   unformat_input_t *i = vam->input;
7170   vl_api_mpls_route_add_del_t *mp;
7171   u32 sw_if_index = ~0, table_id = 0;
7172   u8 create_table_if_needed = 0;
7173   u8 is_add = 1;
7174   u32 next_hop_weight = 1;
7175   u8 is_multipath = 0;
7176   u32 next_hop_table_id = 0;
7177   u8 next_hop_set = 0;
7178   ip4_address_t v4_next_hop_address = {
7179     .as_u32 = 0,
7180   };
7181   ip6_address_t v6_next_hop_address = { {0} };
7182   int count = 1;
7183   int j;
7184   f64 before = 0;
7185   u32 classify_table_index = ~0;
7186   u8 is_classify = 0;
7187   u8 resolve_host = 0, resolve_attached = 0;
7188   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7189   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7190   mpls_label_t *next_hop_out_label_stack = NULL;
7191   mpls_label_t local_label = MPLS_LABEL_INVALID;
7192   u8 is_eos = 0;
7193   u8 next_hop_proto_is_ip4 = 1;
7194
7195   /* Parse args required to build the message */
7196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7197     {
7198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7199         ;
7200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7201         ;
7202       else if (unformat (i, "%d", &local_label))
7203         ;
7204       else if (unformat (i, "eos"))
7205         is_eos = 1;
7206       else if (unformat (i, "non-eos"))
7207         is_eos = 0;
7208       else if (unformat (i, "via %U", unformat_ip4_address,
7209                          &v4_next_hop_address))
7210         {
7211           next_hop_set = 1;
7212           next_hop_proto_is_ip4 = 1;
7213         }
7214       else if (unformat (i, "via %U", unformat_ip6_address,
7215                          &v6_next_hop_address))
7216         {
7217           next_hop_set = 1;
7218           next_hop_proto_is_ip4 = 0;
7219         }
7220       else if (unformat (i, "weight %d", &next_hop_weight))
7221         ;
7222       else if (unformat (i, "create-table"))
7223         create_table_if_needed = 1;
7224       else if (unformat (i, "classify %d", &classify_table_index))
7225         {
7226           is_classify = 1;
7227         }
7228       else if (unformat (i, "del"))
7229         is_add = 0;
7230       else if (unformat (i, "add"))
7231         is_add = 1;
7232       else if (unformat (i, "resolve-via-host"))
7233         resolve_host = 1;
7234       else if (unformat (i, "resolve-via-attached"))
7235         resolve_attached = 1;
7236       else if (unformat (i, "multipath"))
7237         is_multipath = 1;
7238       else if (unformat (i, "count %d", &count))
7239         ;
7240       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7241         {
7242           next_hop_set = 1;
7243           next_hop_proto_is_ip4 = 1;
7244         }
7245       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7246         {
7247           next_hop_set = 1;
7248           next_hop_proto_is_ip4 = 0;
7249         }
7250       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7251         ;
7252       else if (unformat (i, "via-label %d", &next_hop_via_label))
7253         ;
7254       else if (unformat (i, "out-label %d", &next_hop_out_label))
7255         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7256       else
7257         {
7258           clib_warning ("parse error '%U'", format_unformat_error, i);
7259           return -99;
7260         }
7261     }
7262
7263   if (!next_hop_set && !is_classify)
7264     {
7265       errmsg ("next hop / classify not set");
7266       return -99;
7267     }
7268
7269   if (MPLS_LABEL_INVALID == local_label)
7270     {
7271       errmsg ("missing label");
7272       return -99;
7273     }
7274
7275   if (count > 1)
7276     {
7277       /* Turn on async mode */
7278       vam->async_mode = 1;
7279       vam->async_errors = 0;
7280       before = vat_time_now (vam);
7281     }
7282
7283   for (j = 0; j < count; j++)
7284     {
7285       /* Construct the API message */
7286       M2 (MPLS_ROUTE_ADD_DEL, mp,
7287           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7288
7289       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7290       mp->mr_table_id = ntohl (table_id);
7291       mp->mr_create_table_if_needed = create_table_if_needed;
7292
7293       mp->mr_is_add = is_add;
7294       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7295       mp->mr_is_classify = is_classify;
7296       mp->mr_is_multipath = is_multipath;
7297       mp->mr_is_resolve_host = resolve_host;
7298       mp->mr_is_resolve_attached = resolve_attached;
7299       mp->mr_next_hop_weight = next_hop_weight;
7300       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7301       mp->mr_classify_table_index = ntohl (classify_table_index);
7302       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7303       mp->mr_label = ntohl (local_label);
7304       mp->mr_eos = is_eos;
7305
7306       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7307       if (0 != mp->mr_next_hop_n_out_labels)
7308         {
7309           memcpy (mp->mr_next_hop_out_label_stack,
7310                   next_hop_out_label_stack,
7311                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7312           vec_free (next_hop_out_label_stack);
7313         }
7314
7315       if (next_hop_set)
7316         {
7317           if (next_hop_proto_is_ip4)
7318             {
7319               clib_memcpy (mp->mr_next_hop,
7320                            &v4_next_hop_address,
7321                            sizeof (v4_next_hop_address));
7322             }
7323           else
7324             {
7325               clib_memcpy (mp->mr_next_hop,
7326                            &v6_next_hop_address,
7327                            sizeof (v6_next_hop_address));
7328             }
7329         }
7330       local_label++;
7331
7332       /* send it... */
7333       S (mp);
7334       /* If we receive SIGTERM, stop now... */
7335       if (vam->do_exit)
7336         break;
7337     }
7338
7339   /* When testing multiple add/del ops, use a control-ping to sync */
7340   if (count > 1)
7341     {
7342       vl_api_control_ping_t *mp_ping;
7343       f64 after;
7344       f64 timeout;
7345
7346       /* Shut off async mode */
7347       vam->async_mode = 0;
7348
7349       M (CONTROL_PING, mp_ping);
7350       S (mp_ping);
7351
7352       timeout = vat_time_now (vam) + 1.0;
7353       while (vat_time_now (vam) < timeout)
7354         if (vam->result_ready == 1)
7355           goto out;
7356       vam->retval = -99;
7357
7358     out:
7359       if (vam->retval == -99)
7360         errmsg ("timeout");
7361
7362       if (vam->async_errors > 0)
7363         {
7364           errmsg ("%d asynchronous errors", vam->async_errors);
7365           vam->retval = -98;
7366         }
7367       vam->async_errors = 0;
7368       after = vat_time_now (vam);
7369
7370       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7371       if (j > 0)
7372         count = j;
7373
7374       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7375              count, after - before, count / (after - before));
7376     }
7377   else
7378     {
7379       int ret;
7380
7381       /* Wait for a reply... */
7382       W (ret);
7383       return ret;
7384     }
7385
7386   /* Return the good/bad news */
7387   return (vam->retval);
7388 }
7389
7390 static int
7391 api_mpls_ip_bind_unbind (vat_main_t * vam)
7392 {
7393   unformat_input_t *i = vam->input;
7394   vl_api_mpls_ip_bind_unbind_t *mp;
7395   u32 ip_table_id = 0;
7396   u8 create_table_if_needed = 0;
7397   u8 is_bind = 1;
7398   u8 is_ip4 = 1;
7399   ip4_address_t v4_address;
7400   ip6_address_t v6_address;
7401   u32 address_length;
7402   u8 address_set = 0;
7403   mpls_label_t local_label = MPLS_LABEL_INVALID;
7404   int ret;
7405
7406   /* Parse args required to build the message */
7407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7408     {
7409       if (unformat (i, "%U/%d", unformat_ip4_address,
7410                     &v4_address, &address_length))
7411         {
7412           is_ip4 = 1;
7413           address_set = 1;
7414         }
7415       else if (unformat (i, "%U/%d", unformat_ip6_address,
7416                          &v6_address, &address_length))
7417         {
7418           is_ip4 = 0;
7419           address_set = 1;
7420         }
7421       else if (unformat (i, "%d", &local_label))
7422         ;
7423       else if (unformat (i, "create-table"))
7424         create_table_if_needed = 1;
7425       else if (unformat (i, "table-id %d", &ip_table_id))
7426         ;
7427       else if (unformat (i, "unbind"))
7428         is_bind = 0;
7429       else if (unformat (i, "bind"))
7430         is_bind = 1;
7431       else
7432         {
7433           clib_warning ("parse error '%U'", format_unformat_error, i);
7434           return -99;
7435         }
7436     }
7437
7438   if (!address_set)
7439     {
7440       errmsg ("IP addres not set");
7441       return -99;
7442     }
7443
7444   if (MPLS_LABEL_INVALID == local_label)
7445     {
7446       errmsg ("missing label");
7447       return -99;
7448     }
7449
7450   /* Construct the API message */
7451   M (MPLS_IP_BIND_UNBIND, mp);
7452
7453   mp->mb_create_table_if_needed = create_table_if_needed;
7454   mp->mb_is_bind = is_bind;
7455   mp->mb_is_ip4 = is_ip4;
7456   mp->mb_ip_table_id = ntohl (ip_table_id);
7457   mp->mb_mpls_table_id = 0;
7458   mp->mb_label = ntohl (local_label);
7459   mp->mb_address_length = address_length;
7460
7461   if (is_ip4)
7462     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7463   else
7464     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7465
7466   /* send it... */
7467   S (mp);
7468
7469   /* Wait for a reply... */
7470   W (ret);
7471   return ret;
7472 }
7473
7474 static int
7475 api_proxy_arp_add_del (vat_main_t * vam)
7476 {
7477   unformat_input_t *i = vam->input;
7478   vl_api_proxy_arp_add_del_t *mp;
7479   u32 vrf_id = 0;
7480   u8 is_add = 1;
7481   ip4_address_t lo, hi;
7482   u8 range_set = 0;
7483   int ret;
7484
7485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7486     {
7487       if (unformat (i, "vrf %d", &vrf_id))
7488         ;
7489       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7490                          unformat_ip4_address, &hi))
7491         range_set = 1;
7492       else if (unformat (i, "del"))
7493         is_add = 0;
7494       else
7495         {
7496           clib_warning ("parse error '%U'", format_unformat_error, i);
7497           return -99;
7498         }
7499     }
7500
7501   if (range_set == 0)
7502     {
7503       errmsg ("address range not set");
7504       return -99;
7505     }
7506
7507   M (PROXY_ARP_ADD_DEL, mp);
7508
7509   mp->vrf_id = ntohl (vrf_id);
7510   mp->is_add = is_add;
7511   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7512   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7513
7514   S (mp);
7515   W (ret);
7516   return ret;
7517 }
7518
7519 static int
7520 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7521 {
7522   unformat_input_t *i = vam->input;
7523   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7524   u32 sw_if_index;
7525   u8 enable = 1;
7526   u8 sw_if_index_set = 0;
7527   int ret;
7528
7529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7530     {
7531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7532         sw_if_index_set = 1;
7533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7534         sw_if_index_set = 1;
7535       else if (unformat (i, "enable"))
7536         enable = 1;
7537       else if (unformat (i, "disable"))
7538         enable = 0;
7539       else
7540         {
7541           clib_warning ("parse error '%U'", format_unformat_error, i);
7542           return -99;
7543         }
7544     }
7545
7546   if (sw_if_index_set == 0)
7547     {
7548       errmsg ("missing interface name or sw_if_index");
7549       return -99;
7550     }
7551
7552   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7553
7554   mp->sw_if_index = ntohl (sw_if_index);
7555   mp->enable_disable = enable;
7556
7557   S (mp);
7558   W (ret);
7559   return ret;
7560 }
7561
7562 static int
7563 api_mpls_tunnel_add_del (vat_main_t * vam)
7564 {
7565   unformat_input_t *i = vam->input;
7566   vl_api_mpls_tunnel_add_del_t *mp;
7567
7568   u8 is_add = 1;
7569   u8 l2_only = 0;
7570   u32 sw_if_index = ~0;
7571   u32 next_hop_sw_if_index = ~0;
7572   u32 next_hop_proto_is_ip4 = 1;
7573
7574   u32 next_hop_table_id = 0;
7575   ip4_address_t v4_next_hop_address = {
7576     .as_u32 = 0,
7577   };
7578   ip6_address_t v6_next_hop_address = { {0} };
7579   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7580   int ret;
7581
7582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7583     {
7584       if (unformat (i, "add"))
7585         is_add = 1;
7586       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7587         is_add = 0;
7588       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7589         ;
7590       else if (unformat (i, "via %U",
7591                          unformat_ip4_address, &v4_next_hop_address))
7592         {
7593           next_hop_proto_is_ip4 = 1;
7594         }
7595       else if (unformat (i, "via %U",
7596                          unformat_ip6_address, &v6_next_hop_address))
7597         {
7598           next_hop_proto_is_ip4 = 0;
7599         }
7600       else if (unformat (i, "l2-only"))
7601         l2_only = 1;
7602       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7603         ;
7604       else if (unformat (i, "out-label %d", &next_hop_out_label))
7605         vec_add1 (labels, ntohl (next_hop_out_label));
7606       else
7607         {
7608           clib_warning ("parse error '%U'", format_unformat_error, i);
7609           return -99;
7610         }
7611     }
7612
7613   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7614
7615   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7616   mp->mt_sw_if_index = ntohl (sw_if_index);
7617   mp->mt_is_add = is_add;
7618   mp->mt_l2_only = l2_only;
7619   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7620   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7621
7622   mp->mt_next_hop_n_out_labels = vec_len (labels);
7623
7624   if (0 != mp->mt_next_hop_n_out_labels)
7625     {
7626       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7627                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7628       vec_free (labels);
7629     }
7630
7631   if (next_hop_proto_is_ip4)
7632     {
7633       clib_memcpy (mp->mt_next_hop,
7634                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7635     }
7636   else
7637     {
7638       clib_memcpy (mp->mt_next_hop,
7639                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7640     }
7641
7642   S (mp);
7643   W (ret);
7644   return ret;
7645 }
7646
7647 static int
7648 api_sw_interface_set_unnumbered (vat_main_t * vam)
7649 {
7650   unformat_input_t *i = vam->input;
7651   vl_api_sw_interface_set_unnumbered_t *mp;
7652   u32 sw_if_index;
7653   u32 unnum_sw_index = ~0;
7654   u8 is_add = 1;
7655   u8 sw_if_index_set = 0;
7656   int ret;
7657
7658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7659     {
7660       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7661         sw_if_index_set = 1;
7662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7663         sw_if_index_set = 1;
7664       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7665         ;
7666       else if (unformat (i, "del"))
7667         is_add = 0;
7668       else
7669         {
7670           clib_warning ("parse error '%U'", format_unformat_error, i);
7671           return -99;
7672         }
7673     }
7674
7675   if (sw_if_index_set == 0)
7676     {
7677       errmsg ("missing interface name or sw_if_index");
7678       return -99;
7679     }
7680
7681   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7682
7683   mp->sw_if_index = ntohl (sw_if_index);
7684   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7685   mp->is_add = is_add;
7686
7687   S (mp);
7688   W (ret);
7689   return ret;
7690 }
7691
7692 static int
7693 api_ip_neighbor_add_del (vat_main_t * vam)
7694 {
7695   unformat_input_t *i = vam->input;
7696   vl_api_ip_neighbor_add_del_t *mp;
7697   u32 sw_if_index;
7698   u8 sw_if_index_set = 0;
7699   u8 is_add = 1;
7700   u8 is_static = 0;
7701   u8 is_no_fib_entry = 0;
7702   u8 mac_address[6];
7703   u8 mac_set = 0;
7704   u8 v4_address_set = 0;
7705   u8 v6_address_set = 0;
7706   ip4_address_t v4address;
7707   ip6_address_t v6address;
7708   int ret;
7709
7710   memset (mac_address, 0, sizeof (mac_address));
7711
7712   /* Parse args required to build the message */
7713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7714     {
7715       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7716         {
7717           mac_set = 1;
7718         }
7719       else if (unformat (i, "del"))
7720         is_add = 0;
7721       else
7722         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7723         sw_if_index_set = 1;
7724       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7725         sw_if_index_set = 1;
7726       else if (unformat (i, "is_static"))
7727         is_static = 1;
7728       else if (unformat (i, "no-fib-entry"))
7729         is_no_fib_entry = 1;
7730       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7731         v4_address_set = 1;
7732       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7733         v6_address_set = 1;
7734       else
7735         {
7736           clib_warning ("parse error '%U'", format_unformat_error, i);
7737           return -99;
7738         }
7739     }
7740
7741   if (sw_if_index_set == 0)
7742     {
7743       errmsg ("missing interface name or sw_if_index");
7744       return -99;
7745     }
7746   if (v4_address_set && v6_address_set)
7747     {
7748       errmsg ("both v4 and v6 addresses set");
7749       return -99;
7750     }
7751   if (!v4_address_set && !v6_address_set)
7752     {
7753       errmsg ("no address set");
7754       return -99;
7755     }
7756
7757   /* Construct the API message */
7758   M (IP_NEIGHBOR_ADD_DEL, mp);
7759
7760   mp->sw_if_index = ntohl (sw_if_index);
7761   mp->is_add = is_add;
7762   mp->is_static = is_static;
7763   mp->is_no_adj_fib = is_no_fib_entry;
7764   if (mac_set)
7765     clib_memcpy (mp->mac_address, mac_address, 6);
7766   if (v6_address_set)
7767     {
7768       mp->is_ipv6 = 1;
7769       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7770     }
7771   else
7772     {
7773       /* mp->is_ipv6 = 0; via memset in M macro above */
7774       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7775     }
7776
7777   /* send it... */
7778   S (mp);
7779
7780   /* Wait for a reply, return good/bad news  */
7781   W (ret);
7782   return ret;
7783 }
7784
7785 static int
7786 api_reset_vrf (vat_main_t * vam)
7787 {
7788   unformat_input_t *i = vam->input;
7789   vl_api_reset_vrf_t *mp;
7790   u32 vrf_id = 0;
7791   u8 is_ipv6 = 0;
7792   u8 vrf_id_set = 0;
7793   int ret;
7794
7795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7796     {
7797       if (unformat (i, "vrf %d", &vrf_id))
7798         vrf_id_set = 1;
7799       else if (unformat (i, "ipv6"))
7800         is_ipv6 = 1;
7801       else
7802         {
7803           clib_warning ("parse error '%U'", format_unformat_error, i);
7804           return -99;
7805         }
7806     }
7807
7808   if (vrf_id_set == 0)
7809     {
7810       errmsg ("missing vrf id");
7811       return -99;
7812     }
7813
7814   M (RESET_VRF, mp);
7815
7816   mp->vrf_id = ntohl (vrf_id);
7817   mp->is_ipv6 = is_ipv6;
7818
7819   S (mp);
7820   W (ret);
7821   return ret;
7822 }
7823
7824 static int
7825 api_create_vlan_subif (vat_main_t * vam)
7826 {
7827   unformat_input_t *i = vam->input;
7828   vl_api_create_vlan_subif_t *mp;
7829   u32 sw_if_index;
7830   u8 sw_if_index_set = 0;
7831   u32 vlan_id;
7832   u8 vlan_id_set = 0;
7833   int ret;
7834
7835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7836     {
7837       if (unformat (i, "sw_if_index %d", &sw_if_index))
7838         sw_if_index_set = 1;
7839       else
7840         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7841         sw_if_index_set = 1;
7842       else if (unformat (i, "vlan %d", &vlan_id))
7843         vlan_id_set = 1;
7844       else
7845         {
7846           clib_warning ("parse error '%U'", format_unformat_error, i);
7847           return -99;
7848         }
7849     }
7850
7851   if (sw_if_index_set == 0)
7852     {
7853       errmsg ("missing interface name or sw_if_index");
7854       return -99;
7855     }
7856
7857   if (vlan_id_set == 0)
7858     {
7859       errmsg ("missing vlan_id");
7860       return -99;
7861     }
7862   M (CREATE_VLAN_SUBIF, mp);
7863
7864   mp->sw_if_index = ntohl (sw_if_index);
7865   mp->vlan_id = ntohl (vlan_id);
7866
7867   S (mp);
7868   W (ret);
7869   return ret;
7870 }
7871
7872 #define foreach_create_subif_bit                \
7873 _(no_tags)                                      \
7874 _(one_tag)                                      \
7875 _(two_tags)                                     \
7876 _(dot1ad)                                       \
7877 _(exact_match)                                  \
7878 _(default_sub)                                  \
7879 _(outer_vlan_id_any)                            \
7880 _(inner_vlan_id_any)
7881
7882 static int
7883 api_create_subif (vat_main_t * vam)
7884 {
7885   unformat_input_t *i = vam->input;
7886   vl_api_create_subif_t *mp;
7887   u32 sw_if_index;
7888   u8 sw_if_index_set = 0;
7889   u32 sub_id;
7890   u8 sub_id_set = 0;
7891   u32 no_tags = 0;
7892   u32 one_tag = 0;
7893   u32 two_tags = 0;
7894   u32 dot1ad = 0;
7895   u32 exact_match = 0;
7896   u32 default_sub = 0;
7897   u32 outer_vlan_id_any = 0;
7898   u32 inner_vlan_id_any = 0;
7899   u32 tmp;
7900   u16 outer_vlan_id = 0;
7901   u16 inner_vlan_id = 0;
7902   int ret;
7903
7904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7905     {
7906       if (unformat (i, "sw_if_index %d", &sw_if_index))
7907         sw_if_index_set = 1;
7908       else
7909         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7910         sw_if_index_set = 1;
7911       else if (unformat (i, "sub_id %d", &sub_id))
7912         sub_id_set = 1;
7913       else if (unformat (i, "outer_vlan_id %d", &tmp))
7914         outer_vlan_id = tmp;
7915       else if (unformat (i, "inner_vlan_id %d", &tmp))
7916         inner_vlan_id = tmp;
7917
7918 #define _(a) else if (unformat (i, #a)) a = 1 ;
7919       foreach_create_subif_bit
7920 #undef _
7921         else
7922         {
7923           clib_warning ("parse error '%U'", format_unformat_error, i);
7924           return -99;
7925         }
7926     }
7927
7928   if (sw_if_index_set == 0)
7929     {
7930       errmsg ("missing interface name or sw_if_index");
7931       return -99;
7932     }
7933
7934   if (sub_id_set == 0)
7935     {
7936       errmsg ("missing sub_id");
7937       return -99;
7938     }
7939   M (CREATE_SUBIF, mp);
7940
7941   mp->sw_if_index = ntohl (sw_if_index);
7942   mp->sub_id = ntohl (sub_id);
7943
7944 #define _(a) mp->a = a;
7945   foreach_create_subif_bit;
7946 #undef _
7947
7948   mp->outer_vlan_id = ntohs (outer_vlan_id);
7949   mp->inner_vlan_id = ntohs (inner_vlan_id);
7950
7951   S (mp);
7952   W (ret);
7953   return ret;
7954 }
7955
7956 static int
7957 api_oam_add_del (vat_main_t * vam)
7958 {
7959   unformat_input_t *i = vam->input;
7960   vl_api_oam_add_del_t *mp;
7961   u32 vrf_id = 0;
7962   u8 is_add = 1;
7963   ip4_address_t src, dst;
7964   u8 src_set = 0;
7965   u8 dst_set = 0;
7966   int ret;
7967
7968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7969     {
7970       if (unformat (i, "vrf %d", &vrf_id))
7971         ;
7972       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7973         src_set = 1;
7974       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7975         dst_set = 1;
7976       else if (unformat (i, "del"))
7977         is_add = 0;
7978       else
7979         {
7980           clib_warning ("parse error '%U'", format_unformat_error, i);
7981           return -99;
7982         }
7983     }
7984
7985   if (src_set == 0)
7986     {
7987       errmsg ("missing src addr");
7988       return -99;
7989     }
7990
7991   if (dst_set == 0)
7992     {
7993       errmsg ("missing dst addr");
7994       return -99;
7995     }
7996
7997   M (OAM_ADD_DEL, mp);
7998
7999   mp->vrf_id = ntohl (vrf_id);
8000   mp->is_add = is_add;
8001   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8002   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8003
8004   S (mp);
8005   W (ret);
8006   return ret;
8007 }
8008
8009 static int
8010 api_reset_fib (vat_main_t * vam)
8011 {
8012   unformat_input_t *i = vam->input;
8013   vl_api_reset_fib_t *mp;
8014   u32 vrf_id = 0;
8015   u8 is_ipv6 = 0;
8016   u8 vrf_id_set = 0;
8017
8018   int ret;
8019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8020     {
8021       if (unformat (i, "vrf %d", &vrf_id))
8022         vrf_id_set = 1;
8023       else if (unformat (i, "ipv6"))
8024         is_ipv6 = 1;
8025       else
8026         {
8027           clib_warning ("parse error '%U'", format_unformat_error, i);
8028           return -99;
8029         }
8030     }
8031
8032   if (vrf_id_set == 0)
8033     {
8034       errmsg ("missing vrf id");
8035       return -99;
8036     }
8037
8038   M (RESET_FIB, mp);
8039
8040   mp->vrf_id = ntohl (vrf_id);
8041   mp->is_ipv6 = is_ipv6;
8042
8043   S (mp);
8044   W (ret);
8045   return ret;
8046 }
8047
8048 static int
8049 api_dhcp_proxy_config (vat_main_t * vam)
8050 {
8051   unformat_input_t *i = vam->input;
8052   vl_api_dhcp_proxy_config_t *mp;
8053   u32 rx_vrf_id = 0;
8054   u32 server_vrf_id = 0;
8055   u8 is_add = 1;
8056   u8 v4_address_set = 0;
8057   u8 v6_address_set = 0;
8058   ip4_address_t v4address;
8059   ip6_address_t v6address;
8060   u8 v4_src_address_set = 0;
8061   u8 v6_src_address_set = 0;
8062   ip4_address_t v4srcaddress;
8063   ip6_address_t v6srcaddress;
8064   int ret;
8065
8066   /* Parse args required to build the message */
8067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8068     {
8069       if (unformat (i, "del"))
8070         is_add = 0;
8071       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8072         ;
8073       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8074         ;
8075       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8076         v4_address_set = 1;
8077       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8078         v6_address_set = 1;
8079       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8080         v4_src_address_set = 1;
8081       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8082         v6_src_address_set = 1;
8083       else
8084         break;
8085     }
8086
8087   if (v4_address_set && v6_address_set)
8088     {
8089       errmsg ("both v4 and v6 server addresses set");
8090       return -99;
8091     }
8092   if (!v4_address_set && !v6_address_set)
8093     {
8094       errmsg ("no server addresses set");
8095       return -99;
8096     }
8097
8098   if (v4_src_address_set && v6_src_address_set)
8099     {
8100       errmsg ("both v4 and v6  src addresses set");
8101       return -99;
8102     }
8103   if (!v4_src_address_set && !v6_src_address_set)
8104     {
8105       errmsg ("no src addresses set");
8106       return -99;
8107     }
8108
8109   if (!(v4_src_address_set && v4_address_set) &&
8110       !(v6_src_address_set && v6_address_set))
8111     {
8112       errmsg ("no matching server and src addresses set");
8113       return -99;
8114     }
8115
8116   /* Construct the API message */
8117   M (DHCP_PROXY_CONFIG, mp);
8118
8119   mp->is_add = is_add;
8120   mp->rx_vrf_id = ntohl (rx_vrf_id);
8121   mp->server_vrf_id = ntohl (server_vrf_id);
8122   if (v6_address_set)
8123     {
8124       mp->is_ipv6 = 1;
8125       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8126       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8127     }
8128   else
8129     {
8130       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8131       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8132     }
8133
8134   /* send it... */
8135   S (mp);
8136
8137   /* Wait for a reply, return good/bad news  */
8138   W (ret);
8139   return ret;
8140 }
8141
8142 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8143 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8144
8145 static void
8146 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8147 {
8148   vat_main_t *vam = &vat_main;
8149   u32 i, count = mp->count;
8150   vl_api_dhcp_server_t *s;
8151
8152   if (mp->is_ipv6)
8153     print (vam->ofp,
8154            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8155            ntohl (mp->rx_vrf_id),
8156            format_ip6_address, mp->dhcp_src_address,
8157            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8158   else
8159     print (vam->ofp,
8160            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8161            ntohl (mp->rx_vrf_id),
8162            format_ip4_address, mp->dhcp_src_address,
8163            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8164
8165   for (i = 0; i < count; i++)
8166     {
8167       s = &mp->servers[i];
8168
8169       if (mp->is_ipv6)
8170         print (vam->ofp,
8171                " Server Table-ID %d, Server Address %U",
8172                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8173       else
8174         print (vam->ofp,
8175                " Server Table-ID %d, Server Address %U",
8176                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8177     }
8178 }
8179
8180 static void vl_api_dhcp_proxy_details_t_handler_json
8181   (vl_api_dhcp_proxy_details_t * mp)
8182 {
8183   vat_main_t *vam = &vat_main;
8184   vat_json_node_t *node = NULL;
8185   u32 i, count = mp->count;
8186   struct in_addr ip4;
8187   struct in6_addr ip6;
8188   vl_api_dhcp_server_t *s;
8189
8190   if (VAT_JSON_ARRAY != vam->json_tree.type)
8191     {
8192       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8193       vat_json_init_array (&vam->json_tree);
8194     }
8195   node = vat_json_array_add (&vam->json_tree);
8196
8197   vat_json_init_object (node);
8198   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8199   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8200   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8201
8202   if (mp->is_ipv6)
8203     {
8204       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8205       vat_json_object_add_ip6 (node, "src_address", ip6);
8206     }
8207   else
8208     {
8209       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8210       vat_json_object_add_ip4 (node, "src_address", ip4);
8211     }
8212
8213   for (i = 0; i < count; i++)
8214     {
8215       s = &mp->servers[i];
8216
8217       vat_json_object_add_uint (node, "server-table-id",
8218                                 ntohl (s->server_vrf_id));
8219
8220       if (mp->is_ipv6)
8221         {
8222           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8223           vat_json_object_add_ip4 (node, "src_address", ip4);
8224         }
8225       else
8226         {
8227           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8228           vat_json_object_add_ip6 (node, "server_address", ip6);
8229         }
8230     }
8231 }
8232
8233 static int
8234 api_dhcp_proxy_dump (vat_main_t * vam)
8235 {
8236   unformat_input_t *i = vam->input;
8237   vl_api_control_ping_t *mp_ping;
8238   vl_api_dhcp_proxy_dump_t *mp;
8239   u8 is_ipv6 = 0;
8240   int ret;
8241
8242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8243     {
8244       if (unformat (i, "ipv6"))
8245         is_ipv6 = 1;
8246       else
8247         {
8248           clib_warning ("parse error '%U'", format_unformat_error, i);
8249           return -99;
8250         }
8251     }
8252
8253   M (DHCP_PROXY_DUMP, mp);
8254
8255   mp->is_ip6 = is_ipv6;
8256   S (mp);
8257
8258   /* Use a control ping for synchronization */
8259   M (CONTROL_PING, mp_ping);
8260   S (mp_ping);
8261
8262   W (ret);
8263   return ret;
8264 }
8265
8266 static int
8267 api_dhcp_proxy_set_vss (vat_main_t * vam)
8268 {
8269   unformat_input_t *i = vam->input;
8270   vl_api_dhcp_proxy_set_vss_t *mp;
8271   u8 is_ipv6 = 0;
8272   u8 is_add = 1;
8273   u32 tbl_id;
8274   u8 tbl_id_set = 0;
8275   u32 oui;
8276   u8 oui_set = 0;
8277   u32 fib_id;
8278   u8 fib_id_set = 0;
8279   int ret;
8280
8281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8282     {
8283       if (unformat (i, "tbl_id %d", &tbl_id))
8284         tbl_id_set = 1;
8285       if (unformat (i, "fib_id %d", &fib_id))
8286         fib_id_set = 1;
8287       if (unformat (i, "oui %d", &oui))
8288         oui_set = 1;
8289       else if (unformat (i, "ipv6"))
8290         is_ipv6 = 1;
8291       else if (unformat (i, "del"))
8292         is_add = 0;
8293       else
8294         {
8295           clib_warning ("parse error '%U'", format_unformat_error, i);
8296           return -99;
8297         }
8298     }
8299
8300   if (tbl_id_set == 0)
8301     {
8302       errmsg ("missing tbl id");
8303       return -99;
8304     }
8305
8306   if (fib_id_set == 0)
8307     {
8308       errmsg ("missing fib id");
8309       return -99;
8310     }
8311   if (oui_set == 0)
8312     {
8313       errmsg ("missing oui");
8314       return -99;
8315     }
8316
8317   M (DHCP_PROXY_SET_VSS, mp);
8318   mp->tbl_id = ntohl (tbl_id);
8319   mp->fib_id = ntohl (fib_id);
8320   mp->oui = ntohl (oui);
8321   mp->is_ipv6 = is_ipv6;
8322   mp->is_add = is_add;
8323
8324   S (mp);
8325   W (ret);
8326   return ret;
8327 }
8328
8329 static int
8330 api_dhcp_client_config (vat_main_t * vam)
8331 {
8332   unformat_input_t *i = vam->input;
8333   vl_api_dhcp_client_config_t *mp;
8334   u32 sw_if_index;
8335   u8 sw_if_index_set = 0;
8336   u8 is_add = 1;
8337   u8 *hostname = 0;
8338   u8 disable_event = 0;
8339   int ret;
8340
8341   /* Parse args required to build the message */
8342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8343     {
8344       if (unformat (i, "del"))
8345         is_add = 0;
8346       else
8347         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8348         sw_if_index_set = 1;
8349       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8350         sw_if_index_set = 1;
8351       else if (unformat (i, "hostname %s", &hostname))
8352         ;
8353       else if (unformat (i, "disable_event"))
8354         disable_event = 1;
8355       else
8356         break;
8357     }
8358
8359   if (sw_if_index_set == 0)
8360     {
8361       errmsg ("missing interface name or sw_if_index");
8362       return -99;
8363     }
8364
8365   if (vec_len (hostname) > 63)
8366     {
8367       errmsg ("hostname too long");
8368     }
8369   vec_add1 (hostname, 0);
8370
8371   /* Construct the API message */
8372   M (DHCP_CLIENT_CONFIG, mp);
8373
8374   mp->sw_if_index = htonl (sw_if_index);
8375   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8376   vec_free (hostname);
8377   mp->is_add = is_add;
8378   mp->want_dhcp_event = disable_event ? 0 : 1;
8379   mp->pid = htonl (getpid ());
8380
8381   /* send it... */
8382   S (mp);
8383
8384   /* Wait for a reply, return good/bad news  */
8385   W (ret);
8386   return ret;
8387 }
8388
8389 static int
8390 api_set_ip_flow_hash (vat_main_t * vam)
8391 {
8392   unformat_input_t *i = vam->input;
8393   vl_api_set_ip_flow_hash_t *mp;
8394   u32 vrf_id = 0;
8395   u8 is_ipv6 = 0;
8396   u8 vrf_id_set = 0;
8397   u8 src = 0;
8398   u8 dst = 0;
8399   u8 sport = 0;
8400   u8 dport = 0;
8401   u8 proto = 0;
8402   u8 reverse = 0;
8403   int ret;
8404
8405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8406     {
8407       if (unformat (i, "vrf %d", &vrf_id))
8408         vrf_id_set = 1;
8409       else if (unformat (i, "ipv6"))
8410         is_ipv6 = 1;
8411       else if (unformat (i, "src"))
8412         src = 1;
8413       else if (unformat (i, "dst"))
8414         dst = 1;
8415       else if (unformat (i, "sport"))
8416         sport = 1;
8417       else if (unformat (i, "dport"))
8418         dport = 1;
8419       else if (unformat (i, "proto"))
8420         proto = 1;
8421       else if (unformat (i, "reverse"))
8422         reverse = 1;
8423
8424       else
8425         {
8426           clib_warning ("parse error '%U'", format_unformat_error, i);
8427           return -99;
8428         }
8429     }
8430
8431   if (vrf_id_set == 0)
8432     {
8433       errmsg ("missing vrf id");
8434       return -99;
8435     }
8436
8437   M (SET_IP_FLOW_HASH, mp);
8438   mp->src = src;
8439   mp->dst = dst;
8440   mp->sport = sport;
8441   mp->dport = dport;
8442   mp->proto = proto;
8443   mp->reverse = reverse;
8444   mp->vrf_id = ntohl (vrf_id);
8445   mp->is_ipv6 = is_ipv6;
8446
8447   S (mp);
8448   W (ret);
8449   return ret;
8450 }
8451
8452 static int
8453 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8454 {
8455   unformat_input_t *i = vam->input;
8456   vl_api_sw_interface_ip6_enable_disable_t *mp;
8457   u32 sw_if_index;
8458   u8 sw_if_index_set = 0;
8459   u8 enable = 0;
8460   int ret;
8461
8462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8463     {
8464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8465         sw_if_index_set = 1;
8466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8467         sw_if_index_set = 1;
8468       else if (unformat (i, "enable"))
8469         enable = 1;
8470       else if (unformat (i, "disable"))
8471         enable = 0;
8472       else
8473         {
8474           clib_warning ("parse error '%U'", format_unformat_error, i);
8475           return -99;
8476         }
8477     }
8478
8479   if (sw_if_index_set == 0)
8480     {
8481       errmsg ("missing interface name or sw_if_index");
8482       return -99;
8483     }
8484
8485   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8486
8487   mp->sw_if_index = ntohl (sw_if_index);
8488   mp->enable = enable;
8489
8490   S (mp);
8491   W (ret);
8492   return ret;
8493 }
8494
8495 static int
8496 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8497 {
8498   unformat_input_t *i = vam->input;
8499   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8500   u32 sw_if_index;
8501   u8 sw_if_index_set = 0;
8502   u8 v6_address_set = 0;
8503   ip6_address_t v6address;
8504   int ret;
8505
8506   /* Parse args required to build the message */
8507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8508     {
8509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8510         sw_if_index_set = 1;
8511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8512         sw_if_index_set = 1;
8513       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8514         v6_address_set = 1;
8515       else
8516         break;
8517     }
8518
8519   if (sw_if_index_set == 0)
8520     {
8521       errmsg ("missing interface name or sw_if_index");
8522       return -99;
8523     }
8524   if (!v6_address_set)
8525     {
8526       errmsg ("no address set");
8527       return -99;
8528     }
8529
8530   /* Construct the API message */
8531   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8532
8533   mp->sw_if_index = ntohl (sw_if_index);
8534   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8535
8536   /* send it... */
8537   S (mp);
8538
8539   /* Wait for a reply, return good/bad news  */
8540   W (ret);
8541   return ret;
8542 }
8543
8544 static int
8545 api_ip6nd_proxy_add_del (vat_main_t * vam)
8546 {
8547   unformat_input_t *i = vam->input;
8548   vl_api_ip6nd_proxy_add_del_t *mp;
8549   u32 sw_if_index = ~0;
8550   u8 v6_address_set = 0;
8551   ip6_address_t v6address;
8552   u8 is_del = 0;
8553   int ret;
8554
8555   /* Parse args required to build the message */
8556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8557     {
8558       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8559         ;
8560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8561         ;
8562       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8563         v6_address_set = 1;
8564       if (unformat (i, "del"))
8565         is_del = 1;
8566       else
8567         {
8568           clib_warning ("parse error '%U'", format_unformat_error, i);
8569           return -99;
8570         }
8571     }
8572
8573   if (sw_if_index == ~0)
8574     {
8575       errmsg ("missing interface name or sw_if_index");
8576       return -99;
8577     }
8578   if (!v6_address_set)
8579     {
8580       errmsg ("no address set");
8581       return -99;
8582     }
8583
8584   /* Construct the API message */
8585   M (IP6ND_PROXY_ADD_DEL, mp);
8586
8587   mp->is_del = is_del;
8588   mp->sw_if_index = ntohl (sw_if_index);
8589   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8590
8591   /* send it... */
8592   S (mp);
8593
8594   /* Wait for a reply, return good/bad news  */
8595   W (ret);
8596   return ret;
8597 }
8598
8599 static int
8600 api_ip6nd_proxy_dump (vat_main_t * vam)
8601 {
8602   vl_api_ip6nd_proxy_dump_t *mp;
8603   vl_api_control_ping_t *mp_ping;
8604   int ret;
8605
8606   M (IP6ND_PROXY_DUMP, mp);
8607
8608   S (mp);
8609
8610   /* Use a control ping for synchronization */
8611   M (CONTROL_PING, mp_ping);
8612   S (mp_ping);
8613
8614   W (ret);
8615   return ret;
8616 }
8617
8618 static void vl_api_ip6nd_proxy_details_t_handler
8619   (vl_api_ip6nd_proxy_details_t * mp)
8620 {
8621   vat_main_t *vam = &vat_main;
8622
8623   print (vam->ofp, "host %U sw_if_index %d",
8624          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8625 }
8626
8627 static void vl_api_ip6nd_proxy_details_t_handler_json
8628   (vl_api_ip6nd_proxy_details_t * mp)
8629 {
8630   vat_main_t *vam = &vat_main;
8631   struct in6_addr ip6;
8632   vat_json_node_t *node = NULL;
8633
8634   if (VAT_JSON_ARRAY != vam->json_tree.type)
8635     {
8636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8637       vat_json_init_array (&vam->json_tree);
8638     }
8639   node = vat_json_array_add (&vam->json_tree);
8640
8641   vat_json_init_object (node);
8642   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8643
8644   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8645   vat_json_object_add_ip6 (node, "host", ip6);
8646 }
8647
8648 static int
8649 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8650 {
8651   unformat_input_t *i = vam->input;
8652   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8653   u32 sw_if_index;
8654   u8 sw_if_index_set = 0;
8655   u32 address_length = 0;
8656   u8 v6_address_set = 0;
8657   ip6_address_t v6address;
8658   u8 use_default = 0;
8659   u8 no_advertise = 0;
8660   u8 off_link = 0;
8661   u8 no_autoconfig = 0;
8662   u8 no_onlink = 0;
8663   u8 is_no = 0;
8664   u32 val_lifetime = 0;
8665   u32 pref_lifetime = 0;
8666   int ret;
8667
8668   /* Parse args required to build the message */
8669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8670     {
8671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8672         sw_if_index_set = 1;
8673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8674         sw_if_index_set = 1;
8675       else if (unformat (i, "%U/%d",
8676                          unformat_ip6_address, &v6address, &address_length))
8677         v6_address_set = 1;
8678       else if (unformat (i, "val_life %d", &val_lifetime))
8679         ;
8680       else if (unformat (i, "pref_life %d", &pref_lifetime))
8681         ;
8682       else if (unformat (i, "def"))
8683         use_default = 1;
8684       else if (unformat (i, "noadv"))
8685         no_advertise = 1;
8686       else if (unformat (i, "offl"))
8687         off_link = 1;
8688       else if (unformat (i, "noauto"))
8689         no_autoconfig = 1;
8690       else if (unformat (i, "nolink"))
8691         no_onlink = 1;
8692       else if (unformat (i, "isno"))
8693         is_no = 1;
8694       else
8695         {
8696           clib_warning ("parse error '%U'", format_unformat_error, i);
8697           return -99;
8698         }
8699     }
8700
8701   if (sw_if_index_set == 0)
8702     {
8703       errmsg ("missing interface name or sw_if_index");
8704       return -99;
8705     }
8706   if (!v6_address_set)
8707     {
8708       errmsg ("no address set");
8709       return -99;
8710     }
8711
8712   /* Construct the API message */
8713   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8714
8715   mp->sw_if_index = ntohl (sw_if_index);
8716   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8717   mp->address_length = address_length;
8718   mp->use_default = use_default;
8719   mp->no_advertise = no_advertise;
8720   mp->off_link = off_link;
8721   mp->no_autoconfig = no_autoconfig;
8722   mp->no_onlink = no_onlink;
8723   mp->is_no = is_no;
8724   mp->val_lifetime = ntohl (val_lifetime);
8725   mp->pref_lifetime = ntohl (pref_lifetime);
8726
8727   /* send it... */
8728   S (mp);
8729
8730   /* Wait for a reply, return good/bad news  */
8731   W (ret);
8732   return ret;
8733 }
8734
8735 static int
8736 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8737 {
8738   unformat_input_t *i = vam->input;
8739   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8740   u32 sw_if_index;
8741   u8 sw_if_index_set = 0;
8742   u8 suppress = 0;
8743   u8 managed = 0;
8744   u8 other = 0;
8745   u8 ll_option = 0;
8746   u8 send_unicast = 0;
8747   u8 cease = 0;
8748   u8 is_no = 0;
8749   u8 default_router = 0;
8750   u32 max_interval = 0;
8751   u32 min_interval = 0;
8752   u32 lifetime = 0;
8753   u32 initial_count = 0;
8754   u32 initial_interval = 0;
8755   int ret;
8756
8757
8758   /* Parse args required to build the message */
8759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8760     {
8761       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8762         sw_if_index_set = 1;
8763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8764         sw_if_index_set = 1;
8765       else if (unformat (i, "maxint %d", &max_interval))
8766         ;
8767       else if (unformat (i, "minint %d", &min_interval))
8768         ;
8769       else if (unformat (i, "life %d", &lifetime))
8770         ;
8771       else if (unformat (i, "count %d", &initial_count))
8772         ;
8773       else if (unformat (i, "interval %d", &initial_interval))
8774         ;
8775       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8776         suppress = 1;
8777       else if (unformat (i, "managed"))
8778         managed = 1;
8779       else if (unformat (i, "other"))
8780         other = 1;
8781       else if (unformat (i, "ll"))
8782         ll_option = 1;
8783       else if (unformat (i, "send"))
8784         send_unicast = 1;
8785       else if (unformat (i, "cease"))
8786         cease = 1;
8787       else if (unformat (i, "isno"))
8788         is_no = 1;
8789       else if (unformat (i, "def"))
8790         default_router = 1;
8791       else
8792         {
8793           clib_warning ("parse error '%U'", format_unformat_error, i);
8794           return -99;
8795         }
8796     }
8797
8798   if (sw_if_index_set == 0)
8799     {
8800       errmsg ("missing interface name or sw_if_index");
8801       return -99;
8802     }
8803
8804   /* Construct the API message */
8805   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8806
8807   mp->sw_if_index = ntohl (sw_if_index);
8808   mp->max_interval = ntohl (max_interval);
8809   mp->min_interval = ntohl (min_interval);
8810   mp->lifetime = ntohl (lifetime);
8811   mp->initial_count = ntohl (initial_count);
8812   mp->initial_interval = ntohl (initial_interval);
8813   mp->suppress = suppress;
8814   mp->managed = managed;
8815   mp->other = other;
8816   mp->ll_option = ll_option;
8817   mp->send_unicast = send_unicast;
8818   mp->cease = cease;
8819   mp->is_no = is_no;
8820   mp->default_router = default_router;
8821
8822   /* send it... */
8823   S (mp);
8824
8825   /* Wait for a reply, return good/bad news  */
8826   W (ret);
8827   return ret;
8828 }
8829
8830 static int
8831 api_set_arp_neighbor_limit (vat_main_t * vam)
8832 {
8833   unformat_input_t *i = vam->input;
8834   vl_api_set_arp_neighbor_limit_t *mp;
8835   u32 arp_nbr_limit;
8836   u8 limit_set = 0;
8837   u8 is_ipv6 = 0;
8838   int ret;
8839
8840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8841     {
8842       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8843         limit_set = 1;
8844       else if (unformat (i, "ipv6"))
8845         is_ipv6 = 1;
8846       else
8847         {
8848           clib_warning ("parse error '%U'", format_unformat_error, i);
8849           return -99;
8850         }
8851     }
8852
8853   if (limit_set == 0)
8854     {
8855       errmsg ("missing limit value");
8856       return -99;
8857     }
8858
8859   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8860
8861   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8862   mp->is_ipv6 = is_ipv6;
8863
8864   S (mp);
8865   W (ret);
8866   return ret;
8867 }
8868
8869 static int
8870 api_l2_patch_add_del (vat_main_t * vam)
8871 {
8872   unformat_input_t *i = vam->input;
8873   vl_api_l2_patch_add_del_t *mp;
8874   u32 rx_sw_if_index;
8875   u8 rx_sw_if_index_set = 0;
8876   u32 tx_sw_if_index;
8877   u8 tx_sw_if_index_set = 0;
8878   u8 is_add = 1;
8879   int ret;
8880
8881   /* Parse args required to build the message */
8882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8883     {
8884       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8885         rx_sw_if_index_set = 1;
8886       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8887         tx_sw_if_index_set = 1;
8888       else if (unformat (i, "rx"))
8889         {
8890           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8891             {
8892               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8893                             &rx_sw_if_index))
8894                 rx_sw_if_index_set = 1;
8895             }
8896           else
8897             break;
8898         }
8899       else if (unformat (i, "tx"))
8900         {
8901           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8902             {
8903               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8904                             &tx_sw_if_index))
8905                 tx_sw_if_index_set = 1;
8906             }
8907           else
8908             break;
8909         }
8910       else if (unformat (i, "del"))
8911         is_add = 0;
8912       else
8913         break;
8914     }
8915
8916   if (rx_sw_if_index_set == 0)
8917     {
8918       errmsg ("missing rx interface name or rx_sw_if_index");
8919       return -99;
8920     }
8921
8922   if (tx_sw_if_index_set == 0)
8923     {
8924       errmsg ("missing tx interface name or tx_sw_if_index");
8925       return -99;
8926     }
8927
8928   M (L2_PATCH_ADD_DEL, mp);
8929
8930   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8931   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8932   mp->is_add = is_add;
8933
8934   S (mp);
8935   W (ret);
8936   return ret;
8937 }
8938
8939 u8 is_del;
8940 u8 localsid_addr[16];
8941 u8 end_psp;
8942 u8 behavior;
8943 u32 sw_if_index;
8944 u32 vlan_index;
8945 u32 fib_table;
8946 u8 nh_addr[16];
8947
8948 static int
8949 api_sr_localsid_add_del (vat_main_t * vam)
8950 {
8951   unformat_input_t *i = vam->input;
8952   vl_api_sr_localsid_add_del_t *mp;
8953
8954   u8 is_del;
8955   ip6_address_t localsid;
8956   u8 end_psp = 0;
8957   u8 behavior = ~0;
8958   u32 sw_if_index;
8959   u32 fib_table = ~(u32) 0;
8960   ip6_address_t next_hop;
8961
8962   bool nexthop_set = 0;
8963
8964   int ret;
8965
8966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8967     {
8968       if (unformat (i, "del"))
8969         is_del = 1;
8970       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8971       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8972         nexthop_set = 1;
8973       else if (unformat (i, "behavior %u", &behavior));
8974       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8975       else if (unformat (i, "fib-table %u", &fib_table));
8976       else if (unformat (i, "end.psp %u", &behavior));
8977       else
8978         break;
8979     }
8980
8981   M (SR_LOCALSID_ADD_DEL, mp);
8982
8983   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8984   if (nexthop_set)
8985     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8986   mp->behavior = behavior;
8987   mp->sw_if_index = ntohl (sw_if_index);
8988   mp->fib_table = ntohl (fib_table);
8989   mp->end_psp = end_psp;
8990   mp->is_del = is_del;
8991
8992   S (mp);
8993   W (ret);
8994   return ret;
8995 }
8996
8997 static int
8998 api_ioam_enable (vat_main_t * vam)
8999 {
9000   unformat_input_t *input = vam->input;
9001   vl_api_ioam_enable_t *mp;
9002   u32 id = 0;
9003   int has_trace_option = 0;
9004   int has_pot_option = 0;
9005   int has_seqno_option = 0;
9006   int has_analyse_option = 0;
9007   int ret;
9008
9009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9010     {
9011       if (unformat (input, "trace"))
9012         has_trace_option = 1;
9013       else if (unformat (input, "pot"))
9014         has_pot_option = 1;
9015       else if (unformat (input, "seqno"))
9016         has_seqno_option = 1;
9017       else if (unformat (input, "analyse"))
9018         has_analyse_option = 1;
9019       else
9020         break;
9021     }
9022   M (IOAM_ENABLE, mp);
9023   mp->id = htons (id);
9024   mp->seqno = has_seqno_option;
9025   mp->analyse = has_analyse_option;
9026   mp->pot_enable = has_pot_option;
9027   mp->trace_enable = has_trace_option;
9028
9029   S (mp);
9030   W (ret);
9031   return ret;
9032 }
9033
9034
9035 static int
9036 api_ioam_disable (vat_main_t * vam)
9037 {
9038   vl_api_ioam_disable_t *mp;
9039   int ret;
9040
9041   M (IOAM_DISABLE, mp);
9042   S (mp);
9043   W (ret);
9044   return ret;
9045 }
9046
9047 #define foreach_tcp_proto_field                 \
9048 _(src_port)                                     \
9049 _(dst_port)
9050
9051 #define foreach_udp_proto_field                 \
9052 _(src_port)                                     \
9053 _(dst_port)
9054
9055 #define foreach_ip4_proto_field                 \
9056 _(src_address)                                  \
9057 _(dst_address)                                  \
9058 _(tos)                                          \
9059 _(length)                                       \
9060 _(fragment_id)                                  \
9061 _(ttl)                                          \
9062 _(protocol)                                     \
9063 _(checksum)
9064
9065 typedef struct
9066 {
9067   u16 src_port, dst_port;
9068 } tcpudp_header_t;
9069
9070 #if VPP_API_TEST_BUILTIN == 0
9071 uword
9072 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9073 {
9074   u8 **maskp = va_arg (*args, u8 **);
9075   u8 *mask = 0;
9076   u8 found_something = 0;
9077   tcp_header_t *tcp;
9078
9079 #define _(a) u8 a=0;
9080   foreach_tcp_proto_field;
9081 #undef _
9082
9083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9084     {
9085       if (0);
9086 #define _(a) else if (unformat (input, #a)) a=1;
9087       foreach_tcp_proto_field
9088 #undef _
9089         else
9090         break;
9091     }
9092
9093 #define _(a) found_something += a;
9094   foreach_tcp_proto_field;
9095 #undef _
9096
9097   if (found_something == 0)
9098     return 0;
9099
9100   vec_validate (mask, sizeof (*tcp) - 1);
9101
9102   tcp = (tcp_header_t *) mask;
9103
9104 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9105   foreach_tcp_proto_field;
9106 #undef _
9107
9108   *maskp = mask;
9109   return 1;
9110 }
9111
9112 uword
9113 unformat_udp_mask (unformat_input_t * input, va_list * args)
9114 {
9115   u8 **maskp = va_arg (*args, u8 **);
9116   u8 *mask = 0;
9117   u8 found_something = 0;
9118   udp_header_t *udp;
9119
9120 #define _(a) u8 a=0;
9121   foreach_udp_proto_field;
9122 #undef _
9123
9124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9125     {
9126       if (0);
9127 #define _(a) else if (unformat (input, #a)) a=1;
9128       foreach_udp_proto_field
9129 #undef _
9130         else
9131         break;
9132     }
9133
9134 #define _(a) found_something += a;
9135   foreach_udp_proto_field;
9136 #undef _
9137
9138   if (found_something == 0)
9139     return 0;
9140
9141   vec_validate (mask, sizeof (*udp) - 1);
9142
9143   udp = (udp_header_t *) mask;
9144
9145 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9146   foreach_udp_proto_field;
9147 #undef _
9148
9149   *maskp = mask;
9150   return 1;
9151 }
9152
9153 uword
9154 unformat_l4_mask (unformat_input_t * input, va_list * args)
9155 {
9156   u8 **maskp = va_arg (*args, u8 **);
9157   u16 src_port = 0, dst_port = 0;
9158   tcpudp_header_t *tcpudp;
9159
9160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9161     {
9162       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9163         return 1;
9164       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9165         return 1;
9166       else if (unformat (input, "src_port"))
9167         src_port = 0xFFFF;
9168       else if (unformat (input, "dst_port"))
9169         dst_port = 0xFFFF;
9170       else
9171         return 0;
9172     }
9173
9174   if (!src_port && !dst_port)
9175     return 0;
9176
9177   u8 *mask = 0;
9178   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9179
9180   tcpudp = (tcpudp_header_t *) mask;
9181   tcpudp->src_port = src_port;
9182   tcpudp->dst_port = dst_port;
9183
9184   *maskp = mask;
9185
9186   return 1;
9187 }
9188
9189 uword
9190 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9191 {
9192   u8 **maskp = va_arg (*args, u8 **);
9193   u8 *mask = 0;
9194   u8 found_something = 0;
9195   ip4_header_t *ip;
9196
9197 #define _(a) u8 a=0;
9198   foreach_ip4_proto_field;
9199 #undef _
9200   u8 version = 0;
9201   u8 hdr_length = 0;
9202
9203
9204   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9205     {
9206       if (unformat (input, "version"))
9207         version = 1;
9208       else if (unformat (input, "hdr_length"))
9209         hdr_length = 1;
9210       else if (unformat (input, "src"))
9211         src_address = 1;
9212       else if (unformat (input, "dst"))
9213         dst_address = 1;
9214       else if (unformat (input, "proto"))
9215         protocol = 1;
9216
9217 #define _(a) else if (unformat (input, #a)) a=1;
9218       foreach_ip4_proto_field
9219 #undef _
9220         else
9221         break;
9222     }
9223
9224 #define _(a) found_something += a;
9225   foreach_ip4_proto_field;
9226 #undef _
9227
9228   if (found_something == 0)
9229     return 0;
9230
9231   vec_validate (mask, sizeof (*ip) - 1);
9232
9233   ip = (ip4_header_t *) mask;
9234
9235 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9236   foreach_ip4_proto_field;
9237 #undef _
9238
9239   ip->ip_version_and_header_length = 0;
9240
9241   if (version)
9242     ip->ip_version_and_header_length |= 0xF0;
9243
9244   if (hdr_length)
9245     ip->ip_version_and_header_length |= 0x0F;
9246
9247   *maskp = mask;
9248   return 1;
9249 }
9250
9251 #define foreach_ip6_proto_field                 \
9252 _(src_address)                                  \
9253 _(dst_address)                                  \
9254 _(payload_length)                               \
9255 _(hop_limit)                                    \
9256 _(protocol)
9257
9258 uword
9259 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9260 {
9261   u8 **maskp = va_arg (*args, u8 **);
9262   u8 *mask = 0;
9263   u8 found_something = 0;
9264   ip6_header_t *ip;
9265   u32 ip_version_traffic_class_and_flow_label;
9266
9267 #define _(a) u8 a=0;
9268   foreach_ip6_proto_field;
9269 #undef _
9270   u8 version = 0;
9271   u8 traffic_class = 0;
9272   u8 flow_label = 0;
9273
9274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (input, "version"))
9277         version = 1;
9278       else if (unformat (input, "traffic-class"))
9279         traffic_class = 1;
9280       else if (unformat (input, "flow-label"))
9281         flow_label = 1;
9282       else if (unformat (input, "src"))
9283         src_address = 1;
9284       else if (unformat (input, "dst"))
9285         dst_address = 1;
9286       else if (unformat (input, "proto"))
9287         protocol = 1;
9288
9289 #define _(a) else if (unformat (input, #a)) a=1;
9290       foreach_ip6_proto_field
9291 #undef _
9292         else
9293         break;
9294     }
9295
9296 #define _(a) found_something += a;
9297   foreach_ip6_proto_field;
9298 #undef _
9299
9300   if (found_something == 0)
9301     return 0;
9302
9303   vec_validate (mask, sizeof (*ip) - 1);
9304
9305   ip = (ip6_header_t *) mask;
9306
9307 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9308   foreach_ip6_proto_field;
9309 #undef _
9310
9311   ip_version_traffic_class_and_flow_label = 0;
9312
9313   if (version)
9314     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9315
9316   if (traffic_class)
9317     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9318
9319   if (flow_label)
9320     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9321
9322   ip->ip_version_traffic_class_and_flow_label =
9323     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9324
9325   *maskp = mask;
9326   return 1;
9327 }
9328
9329 uword
9330 unformat_l3_mask (unformat_input_t * input, va_list * args)
9331 {
9332   u8 **maskp = va_arg (*args, u8 **);
9333
9334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9335     {
9336       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9337         return 1;
9338       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9339         return 1;
9340       else
9341         break;
9342     }
9343   return 0;
9344 }
9345
9346 uword
9347 unformat_l2_mask (unformat_input_t * input, va_list * args)
9348 {
9349   u8 **maskp = va_arg (*args, u8 **);
9350   u8 *mask = 0;
9351   u8 src = 0;
9352   u8 dst = 0;
9353   u8 proto = 0;
9354   u8 tag1 = 0;
9355   u8 tag2 = 0;
9356   u8 ignore_tag1 = 0;
9357   u8 ignore_tag2 = 0;
9358   u8 cos1 = 0;
9359   u8 cos2 = 0;
9360   u8 dot1q = 0;
9361   u8 dot1ad = 0;
9362   int len = 14;
9363
9364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9365     {
9366       if (unformat (input, "src"))
9367         src = 1;
9368       else if (unformat (input, "dst"))
9369         dst = 1;
9370       else if (unformat (input, "proto"))
9371         proto = 1;
9372       else if (unformat (input, "tag1"))
9373         tag1 = 1;
9374       else if (unformat (input, "tag2"))
9375         tag2 = 1;
9376       else if (unformat (input, "ignore-tag1"))
9377         ignore_tag1 = 1;
9378       else if (unformat (input, "ignore-tag2"))
9379         ignore_tag2 = 1;
9380       else if (unformat (input, "cos1"))
9381         cos1 = 1;
9382       else if (unformat (input, "cos2"))
9383         cos2 = 1;
9384       else if (unformat (input, "dot1q"))
9385         dot1q = 1;
9386       else if (unformat (input, "dot1ad"))
9387         dot1ad = 1;
9388       else
9389         break;
9390     }
9391   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9392        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9393     return 0;
9394
9395   if (tag1 || ignore_tag1 || cos1 || dot1q)
9396     len = 18;
9397   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9398     len = 22;
9399
9400   vec_validate (mask, len - 1);
9401
9402   if (dst)
9403     memset (mask, 0xff, 6);
9404
9405   if (src)
9406     memset (mask + 6, 0xff, 6);
9407
9408   if (tag2 || dot1ad)
9409     {
9410       /* inner vlan tag */
9411       if (tag2)
9412         {
9413           mask[19] = 0xff;
9414           mask[18] = 0x0f;
9415         }
9416       if (cos2)
9417         mask[18] |= 0xe0;
9418       if (proto)
9419         mask[21] = mask[20] = 0xff;
9420       if (tag1)
9421         {
9422           mask[15] = 0xff;
9423           mask[14] = 0x0f;
9424         }
9425       if (cos1)
9426         mask[14] |= 0xe0;
9427       *maskp = mask;
9428       return 1;
9429     }
9430   if (tag1 | dot1q)
9431     {
9432       if (tag1)
9433         {
9434           mask[15] = 0xff;
9435           mask[14] = 0x0f;
9436         }
9437       if (cos1)
9438         mask[14] |= 0xe0;
9439       if (proto)
9440         mask[16] = mask[17] = 0xff;
9441
9442       *maskp = mask;
9443       return 1;
9444     }
9445   if (cos2)
9446     mask[18] |= 0xe0;
9447   if (cos1)
9448     mask[14] |= 0xe0;
9449   if (proto)
9450     mask[12] = mask[13] = 0xff;
9451
9452   *maskp = mask;
9453   return 1;
9454 }
9455
9456 uword
9457 unformat_classify_mask (unformat_input_t * input, va_list * args)
9458 {
9459   u8 **maskp = va_arg (*args, u8 **);
9460   u32 *skipp = va_arg (*args, u32 *);
9461   u32 *matchp = va_arg (*args, u32 *);
9462   u32 match;
9463   u8 *mask = 0;
9464   u8 *l2 = 0;
9465   u8 *l3 = 0;
9466   u8 *l4 = 0;
9467   int i;
9468
9469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9470     {
9471       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9472         ;
9473       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9474         ;
9475       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9476         ;
9477       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9478         ;
9479       else
9480         break;
9481     }
9482
9483   if (l4 && !l3)
9484     {
9485       vec_free (mask);
9486       vec_free (l2);
9487       vec_free (l4);
9488       return 0;
9489     }
9490
9491   if (mask || l2 || l3 || l4)
9492     {
9493       if (l2 || l3 || l4)
9494         {
9495           /* "With a free Ethernet header in every package" */
9496           if (l2 == 0)
9497             vec_validate (l2, 13);
9498           mask = l2;
9499           if (vec_len (l3))
9500             {
9501               vec_append (mask, l3);
9502               vec_free (l3);
9503             }
9504           if (vec_len (l4))
9505             {
9506               vec_append (mask, l4);
9507               vec_free (l4);
9508             }
9509         }
9510
9511       /* Scan forward looking for the first significant mask octet */
9512       for (i = 0; i < vec_len (mask); i++)
9513         if (mask[i])
9514           break;
9515
9516       /* compute (skip, match) params */
9517       *skipp = i / sizeof (u32x4);
9518       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9519
9520       /* Pad mask to an even multiple of the vector size */
9521       while (vec_len (mask) % sizeof (u32x4))
9522         vec_add1 (mask, 0);
9523
9524       match = vec_len (mask) / sizeof (u32x4);
9525
9526       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9527         {
9528           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9529           if (*tmp || *(tmp + 1))
9530             break;
9531           match--;
9532         }
9533       if (match == 0)
9534         clib_warning ("BUG: match 0");
9535
9536       _vec_len (mask) = match * sizeof (u32x4);
9537
9538       *matchp = match;
9539       *maskp = mask;
9540
9541       return 1;
9542     }
9543
9544   return 0;
9545 }
9546 #endif /* VPP_API_TEST_BUILTIN */
9547
9548 #define foreach_l2_next                         \
9549 _(drop, DROP)                                   \
9550 _(ethernet, ETHERNET_INPUT)                     \
9551 _(ip4, IP4_INPUT)                               \
9552 _(ip6, IP6_INPUT)
9553
9554 uword
9555 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9556 {
9557   u32 *miss_next_indexp = va_arg (*args, u32 *);
9558   u32 next_index = 0;
9559   u32 tmp;
9560
9561 #define _(n,N) \
9562   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9563   foreach_l2_next;
9564 #undef _
9565
9566   if (unformat (input, "%d", &tmp))
9567     {
9568       next_index = tmp;
9569       goto out;
9570     }
9571
9572   return 0;
9573
9574 out:
9575   *miss_next_indexp = next_index;
9576   return 1;
9577 }
9578
9579 #define foreach_ip_next                         \
9580 _(drop, DROP)                                   \
9581 _(local, LOCAL)                                 \
9582 _(rewrite, REWRITE)
9583
9584 uword
9585 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9586 {
9587   u32 *miss_next_indexp = va_arg (*args, u32 *);
9588   u32 next_index = 0;
9589   u32 tmp;
9590
9591 #define _(n,N) \
9592   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9593   foreach_ip_next;
9594 #undef _
9595
9596   if (unformat (input, "%d", &tmp))
9597     {
9598       next_index = tmp;
9599       goto out;
9600     }
9601
9602   return 0;
9603
9604 out:
9605   *miss_next_indexp = next_index;
9606   return 1;
9607 }
9608
9609 #define foreach_acl_next                        \
9610 _(deny, DENY)
9611
9612 uword
9613 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9614 {
9615   u32 *miss_next_indexp = va_arg (*args, u32 *);
9616   u32 next_index = 0;
9617   u32 tmp;
9618
9619 #define _(n,N) \
9620   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9621   foreach_acl_next;
9622 #undef _
9623
9624   if (unformat (input, "permit"))
9625     {
9626       next_index = ~0;
9627       goto out;
9628     }
9629   else if (unformat (input, "%d", &tmp))
9630     {
9631       next_index = tmp;
9632       goto out;
9633     }
9634
9635   return 0;
9636
9637 out:
9638   *miss_next_indexp = next_index;
9639   return 1;
9640 }
9641
9642 uword
9643 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9644 {
9645   u32 *r = va_arg (*args, u32 *);
9646
9647   if (unformat (input, "conform-color"))
9648     *r = POLICE_CONFORM;
9649   else if (unformat (input, "exceed-color"))
9650     *r = POLICE_EXCEED;
9651   else
9652     return 0;
9653
9654   return 1;
9655 }
9656
9657 static int
9658 api_classify_add_del_table (vat_main_t * vam)
9659 {
9660   unformat_input_t *i = vam->input;
9661   vl_api_classify_add_del_table_t *mp;
9662
9663   u32 nbuckets = 2;
9664   u32 skip = ~0;
9665   u32 match = ~0;
9666   int is_add = 1;
9667   int del_chain = 0;
9668   u32 table_index = ~0;
9669   u32 next_table_index = ~0;
9670   u32 miss_next_index = ~0;
9671   u32 memory_size = 32 << 20;
9672   u8 *mask = 0;
9673   u32 current_data_flag = 0;
9674   int current_data_offset = 0;
9675   int ret;
9676
9677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9678     {
9679       if (unformat (i, "del"))
9680         is_add = 0;
9681       else if (unformat (i, "del-chain"))
9682         {
9683           is_add = 0;
9684           del_chain = 1;
9685         }
9686       else if (unformat (i, "buckets %d", &nbuckets))
9687         ;
9688       else if (unformat (i, "memory_size %d", &memory_size))
9689         ;
9690       else if (unformat (i, "skip %d", &skip))
9691         ;
9692       else if (unformat (i, "match %d", &match))
9693         ;
9694       else if (unformat (i, "table %d", &table_index))
9695         ;
9696       else if (unformat (i, "mask %U", unformat_classify_mask,
9697                          &mask, &skip, &match))
9698         ;
9699       else if (unformat (i, "next-table %d", &next_table_index))
9700         ;
9701       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9702                          &miss_next_index))
9703         ;
9704       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9705                          &miss_next_index))
9706         ;
9707       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9708                          &miss_next_index))
9709         ;
9710       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9711         ;
9712       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9713         ;
9714       else
9715         break;
9716     }
9717
9718   if (is_add && mask == 0)
9719     {
9720       errmsg ("Mask required");
9721       return -99;
9722     }
9723
9724   if (is_add && skip == ~0)
9725     {
9726       errmsg ("skip count required");
9727       return -99;
9728     }
9729
9730   if (is_add && match == ~0)
9731     {
9732       errmsg ("match count required");
9733       return -99;
9734     }
9735
9736   if (!is_add && table_index == ~0)
9737     {
9738       errmsg ("table index required for delete");
9739       return -99;
9740     }
9741
9742   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9743
9744   mp->is_add = is_add;
9745   mp->del_chain = del_chain;
9746   mp->table_index = ntohl (table_index);
9747   mp->nbuckets = ntohl (nbuckets);
9748   mp->memory_size = ntohl (memory_size);
9749   mp->skip_n_vectors = ntohl (skip);
9750   mp->match_n_vectors = ntohl (match);
9751   mp->next_table_index = ntohl (next_table_index);
9752   mp->miss_next_index = ntohl (miss_next_index);
9753   mp->current_data_flag = ntohl (current_data_flag);
9754   mp->current_data_offset = ntohl (current_data_offset);
9755   clib_memcpy (mp->mask, mask, vec_len (mask));
9756
9757   vec_free (mask);
9758
9759   S (mp);
9760   W (ret);
9761   return ret;
9762 }
9763
9764 #if VPP_API_TEST_BUILTIN == 0
9765 uword
9766 unformat_l4_match (unformat_input_t * input, va_list * args)
9767 {
9768   u8 **matchp = va_arg (*args, u8 **);
9769
9770   u8 *proto_header = 0;
9771   int src_port = 0;
9772   int dst_port = 0;
9773
9774   tcpudp_header_t h;
9775
9776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9777     {
9778       if (unformat (input, "src_port %d", &src_port))
9779         ;
9780       else if (unformat (input, "dst_port %d", &dst_port))
9781         ;
9782       else
9783         return 0;
9784     }
9785
9786   h.src_port = clib_host_to_net_u16 (src_port);
9787   h.dst_port = clib_host_to_net_u16 (dst_port);
9788   vec_validate (proto_header, sizeof (h) - 1);
9789   memcpy (proto_header, &h, sizeof (h));
9790
9791   *matchp = proto_header;
9792
9793   return 1;
9794 }
9795
9796 uword
9797 unformat_ip4_match (unformat_input_t * input, va_list * args)
9798 {
9799   u8 **matchp = va_arg (*args, u8 **);
9800   u8 *match = 0;
9801   ip4_header_t *ip;
9802   int version = 0;
9803   u32 version_val;
9804   int hdr_length = 0;
9805   u32 hdr_length_val;
9806   int src = 0, dst = 0;
9807   ip4_address_t src_val, dst_val;
9808   int proto = 0;
9809   u32 proto_val;
9810   int tos = 0;
9811   u32 tos_val;
9812   int length = 0;
9813   u32 length_val;
9814   int fragment_id = 0;
9815   u32 fragment_id_val;
9816   int ttl = 0;
9817   int ttl_val;
9818   int checksum = 0;
9819   u32 checksum_val;
9820
9821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9822     {
9823       if (unformat (input, "version %d", &version_val))
9824         version = 1;
9825       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9826         hdr_length = 1;
9827       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9828         src = 1;
9829       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9830         dst = 1;
9831       else if (unformat (input, "proto %d", &proto_val))
9832         proto = 1;
9833       else if (unformat (input, "tos %d", &tos_val))
9834         tos = 1;
9835       else if (unformat (input, "length %d", &length_val))
9836         length = 1;
9837       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9838         fragment_id = 1;
9839       else if (unformat (input, "ttl %d", &ttl_val))
9840         ttl = 1;
9841       else if (unformat (input, "checksum %d", &checksum_val))
9842         checksum = 1;
9843       else
9844         break;
9845     }
9846
9847   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9848       + ttl + checksum == 0)
9849     return 0;
9850
9851   /*
9852    * Aligned because we use the real comparison functions
9853    */
9854   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9855
9856   ip = (ip4_header_t *) match;
9857
9858   /* These are realistically matched in practice */
9859   if (src)
9860     ip->src_address.as_u32 = src_val.as_u32;
9861
9862   if (dst)
9863     ip->dst_address.as_u32 = dst_val.as_u32;
9864
9865   if (proto)
9866     ip->protocol = proto_val;
9867
9868
9869   /* These are not, but they're included for completeness */
9870   if (version)
9871     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9872
9873   if (hdr_length)
9874     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9875
9876   if (tos)
9877     ip->tos = tos_val;
9878
9879   if (length)
9880     ip->length = clib_host_to_net_u16 (length_val);
9881
9882   if (ttl)
9883     ip->ttl = ttl_val;
9884
9885   if (checksum)
9886     ip->checksum = clib_host_to_net_u16 (checksum_val);
9887
9888   *matchp = match;
9889   return 1;
9890 }
9891
9892 uword
9893 unformat_ip6_match (unformat_input_t * input, va_list * args)
9894 {
9895   u8 **matchp = va_arg (*args, u8 **);
9896   u8 *match = 0;
9897   ip6_header_t *ip;
9898   int version = 0;
9899   u32 version_val;
9900   u8 traffic_class = 0;
9901   u32 traffic_class_val = 0;
9902   u8 flow_label = 0;
9903   u8 flow_label_val;
9904   int src = 0, dst = 0;
9905   ip6_address_t src_val, dst_val;
9906   int proto = 0;
9907   u32 proto_val;
9908   int payload_length = 0;
9909   u32 payload_length_val;
9910   int hop_limit = 0;
9911   int hop_limit_val;
9912   u32 ip_version_traffic_class_and_flow_label;
9913
9914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9915     {
9916       if (unformat (input, "version %d", &version_val))
9917         version = 1;
9918       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9919         traffic_class = 1;
9920       else if (unformat (input, "flow_label %d", &flow_label_val))
9921         flow_label = 1;
9922       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9923         src = 1;
9924       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9925         dst = 1;
9926       else if (unformat (input, "proto %d", &proto_val))
9927         proto = 1;
9928       else if (unformat (input, "payload_length %d", &payload_length_val))
9929         payload_length = 1;
9930       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9931         hop_limit = 1;
9932       else
9933         break;
9934     }
9935
9936   if (version + traffic_class + flow_label + src + dst + proto +
9937       payload_length + hop_limit == 0)
9938     return 0;
9939
9940   /*
9941    * Aligned because we use the real comparison functions
9942    */
9943   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9944
9945   ip = (ip6_header_t *) match;
9946
9947   if (src)
9948     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9949
9950   if (dst)
9951     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9952
9953   if (proto)
9954     ip->protocol = proto_val;
9955
9956   ip_version_traffic_class_and_flow_label = 0;
9957
9958   if (version)
9959     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9960
9961   if (traffic_class)
9962     ip_version_traffic_class_and_flow_label |=
9963       (traffic_class_val & 0xFF) << 20;
9964
9965   if (flow_label)
9966     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9967
9968   ip->ip_version_traffic_class_and_flow_label =
9969     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9970
9971   if (payload_length)
9972     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9973
9974   if (hop_limit)
9975     ip->hop_limit = hop_limit_val;
9976
9977   *matchp = match;
9978   return 1;
9979 }
9980
9981 uword
9982 unformat_l3_match (unformat_input_t * input, va_list * args)
9983 {
9984   u8 **matchp = va_arg (*args, u8 **);
9985
9986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9987     {
9988       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9989         return 1;
9990       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9991         return 1;
9992       else
9993         break;
9994     }
9995   return 0;
9996 }
9997
9998 uword
9999 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10000 {
10001   u8 *tagp = va_arg (*args, u8 *);
10002   u32 tag;
10003
10004   if (unformat (input, "%d", &tag))
10005     {
10006       tagp[0] = (tag >> 8) & 0x0F;
10007       tagp[1] = tag & 0xFF;
10008       return 1;
10009     }
10010
10011   return 0;
10012 }
10013
10014 uword
10015 unformat_l2_match (unformat_input_t * input, va_list * args)
10016 {
10017   u8 **matchp = va_arg (*args, u8 **);
10018   u8 *match = 0;
10019   u8 src = 0;
10020   u8 src_val[6];
10021   u8 dst = 0;
10022   u8 dst_val[6];
10023   u8 proto = 0;
10024   u16 proto_val;
10025   u8 tag1 = 0;
10026   u8 tag1_val[2];
10027   u8 tag2 = 0;
10028   u8 tag2_val[2];
10029   int len = 14;
10030   u8 ignore_tag1 = 0;
10031   u8 ignore_tag2 = 0;
10032   u8 cos1 = 0;
10033   u8 cos2 = 0;
10034   u32 cos1_val = 0;
10035   u32 cos2_val = 0;
10036
10037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10038     {
10039       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10040         src = 1;
10041       else
10042         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10043         dst = 1;
10044       else if (unformat (input, "proto %U",
10045                          unformat_ethernet_type_host_byte_order, &proto_val))
10046         proto = 1;
10047       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10048         tag1 = 1;
10049       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10050         tag2 = 1;
10051       else if (unformat (input, "ignore-tag1"))
10052         ignore_tag1 = 1;
10053       else if (unformat (input, "ignore-tag2"))
10054         ignore_tag2 = 1;
10055       else if (unformat (input, "cos1 %d", &cos1_val))
10056         cos1 = 1;
10057       else if (unformat (input, "cos2 %d", &cos2_val))
10058         cos2 = 1;
10059       else
10060         break;
10061     }
10062   if ((src + dst + proto + tag1 + tag2 +
10063        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10064     return 0;
10065
10066   if (tag1 || ignore_tag1 || cos1)
10067     len = 18;
10068   if (tag2 || ignore_tag2 || cos2)
10069     len = 22;
10070
10071   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10072
10073   if (dst)
10074     clib_memcpy (match, dst_val, 6);
10075
10076   if (src)
10077     clib_memcpy (match + 6, src_val, 6);
10078
10079   if (tag2)
10080     {
10081       /* inner vlan tag */
10082       match[19] = tag2_val[1];
10083       match[18] = tag2_val[0];
10084       if (cos2)
10085         match[18] |= (cos2_val & 0x7) << 5;
10086       if (proto)
10087         {
10088           match[21] = proto_val & 0xff;
10089           match[20] = proto_val >> 8;
10090         }
10091       if (tag1)
10092         {
10093           match[15] = tag1_val[1];
10094           match[14] = tag1_val[0];
10095         }
10096       if (cos1)
10097         match[14] |= (cos1_val & 0x7) << 5;
10098       *matchp = match;
10099       return 1;
10100     }
10101   if (tag1)
10102     {
10103       match[15] = tag1_val[1];
10104       match[14] = tag1_val[0];
10105       if (proto)
10106         {
10107           match[17] = proto_val & 0xff;
10108           match[16] = proto_val >> 8;
10109         }
10110       if (cos1)
10111         match[14] |= (cos1_val & 0x7) << 5;
10112
10113       *matchp = match;
10114       return 1;
10115     }
10116   if (cos2)
10117     match[18] |= (cos2_val & 0x7) << 5;
10118   if (cos1)
10119     match[14] |= (cos1_val & 0x7) << 5;
10120   if (proto)
10121     {
10122       match[13] = proto_val & 0xff;
10123       match[12] = proto_val >> 8;
10124     }
10125
10126   *matchp = match;
10127   return 1;
10128 }
10129 #endif
10130
10131 uword
10132 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10133 {
10134   u8 **matchp = va_arg (*args, u8 **);
10135   u32 skip_n_vectors = va_arg (*args, u32);
10136   u32 match_n_vectors = va_arg (*args, u32);
10137
10138   u8 *match = 0;
10139   u8 *l2 = 0;
10140   u8 *l3 = 0;
10141   u8 *l4 = 0;
10142
10143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (input, "hex %U", unformat_hex_string, &match))
10146         ;
10147       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10148         ;
10149       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10150         ;
10151       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10152         ;
10153       else
10154         break;
10155     }
10156
10157   if (l4 && !l3)
10158     {
10159       vec_free (match);
10160       vec_free (l2);
10161       vec_free (l4);
10162       return 0;
10163     }
10164
10165   if (match || l2 || l3 || l4)
10166     {
10167       if (l2 || l3 || l4)
10168         {
10169           /* "Win a free Ethernet header in every packet" */
10170           if (l2 == 0)
10171             vec_validate_aligned (l2, 13, sizeof (u32x4));
10172           match = l2;
10173           if (vec_len (l3))
10174             {
10175               vec_append_aligned (match, l3, sizeof (u32x4));
10176               vec_free (l3);
10177             }
10178           if (vec_len (l4))
10179             {
10180               vec_append_aligned (match, l4, sizeof (u32x4));
10181               vec_free (l4);
10182             }
10183         }
10184
10185       /* Make sure the vector is big enough even if key is all 0's */
10186       vec_validate_aligned
10187         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10188          sizeof (u32x4));
10189
10190       /* Set size, include skipped vectors */
10191       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10192
10193       *matchp = match;
10194
10195       return 1;
10196     }
10197
10198   return 0;
10199 }
10200
10201 static int
10202 api_classify_add_del_session (vat_main_t * vam)
10203 {
10204   unformat_input_t *i = vam->input;
10205   vl_api_classify_add_del_session_t *mp;
10206   int is_add = 1;
10207   u32 table_index = ~0;
10208   u32 hit_next_index = ~0;
10209   u32 opaque_index = ~0;
10210   u8 *match = 0;
10211   i32 advance = 0;
10212   u32 skip_n_vectors = 0;
10213   u32 match_n_vectors = 0;
10214   u32 action = 0;
10215   u32 metadata = 0;
10216   int ret;
10217
10218   /*
10219    * Warning: you have to supply skip_n and match_n
10220    * because the API client cant simply look at the classify
10221    * table object.
10222    */
10223
10224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10225     {
10226       if (unformat (i, "del"))
10227         is_add = 0;
10228       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10229                          &hit_next_index))
10230         ;
10231       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10232                          &hit_next_index))
10233         ;
10234       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10235                          &hit_next_index))
10236         ;
10237       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10238         ;
10239       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10240         ;
10241       else if (unformat (i, "opaque-index %d", &opaque_index))
10242         ;
10243       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10244         ;
10245       else if (unformat (i, "match_n %d", &match_n_vectors))
10246         ;
10247       else if (unformat (i, "match %U", api_unformat_classify_match,
10248                          &match, skip_n_vectors, match_n_vectors))
10249         ;
10250       else if (unformat (i, "advance %d", &advance))
10251         ;
10252       else if (unformat (i, "table-index %d", &table_index))
10253         ;
10254       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10255         action = 1;
10256       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10257         action = 2;
10258       else if (unformat (i, "action %d", &action))
10259         ;
10260       else if (unformat (i, "metadata %d", &metadata))
10261         ;
10262       else
10263         break;
10264     }
10265
10266   if (table_index == ~0)
10267     {
10268       errmsg ("Table index required");
10269       return -99;
10270     }
10271
10272   if (is_add && match == 0)
10273     {
10274       errmsg ("Match value required");
10275       return -99;
10276     }
10277
10278   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10279
10280   mp->is_add = is_add;
10281   mp->table_index = ntohl (table_index);
10282   mp->hit_next_index = ntohl (hit_next_index);
10283   mp->opaque_index = ntohl (opaque_index);
10284   mp->advance = ntohl (advance);
10285   mp->action = action;
10286   mp->metadata = ntohl (metadata);
10287   clib_memcpy (mp->match, match, vec_len (match));
10288   vec_free (match);
10289
10290   S (mp);
10291   W (ret);
10292   return ret;
10293 }
10294
10295 static int
10296 api_classify_set_interface_ip_table (vat_main_t * vam)
10297 {
10298   unformat_input_t *i = vam->input;
10299   vl_api_classify_set_interface_ip_table_t *mp;
10300   u32 sw_if_index;
10301   int sw_if_index_set;
10302   u32 table_index = ~0;
10303   u8 is_ipv6 = 0;
10304   int ret;
10305
10306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10307     {
10308       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10309         sw_if_index_set = 1;
10310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10311         sw_if_index_set = 1;
10312       else if (unformat (i, "table %d", &table_index))
10313         ;
10314       else
10315         {
10316           clib_warning ("parse error '%U'", format_unformat_error, i);
10317           return -99;
10318         }
10319     }
10320
10321   if (sw_if_index_set == 0)
10322     {
10323       errmsg ("missing interface name or sw_if_index");
10324       return -99;
10325     }
10326
10327
10328   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10329
10330   mp->sw_if_index = ntohl (sw_if_index);
10331   mp->table_index = ntohl (table_index);
10332   mp->is_ipv6 = is_ipv6;
10333
10334   S (mp);
10335   W (ret);
10336   return ret;
10337 }
10338
10339 static int
10340 api_classify_set_interface_l2_tables (vat_main_t * vam)
10341 {
10342   unformat_input_t *i = vam->input;
10343   vl_api_classify_set_interface_l2_tables_t *mp;
10344   u32 sw_if_index;
10345   int sw_if_index_set;
10346   u32 ip4_table_index = ~0;
10347   u32 ip6_table_index = ~0;
10348   u32 other_table_index = ~0;
10349   u32 is_input = 1;
10350   int ret;
10351
10352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10353     {
10354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10355         sw_if_index_set = 1;
10356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10357         sw_if_index_set = 1;
10358       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10359         ;
10360       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10361         ;
10362       else if (unformat (i, "other-table %d", &other_table_index))
10363         ;
10364       else if (unformat (i, "is-input %d", &is_input))
10365         ;
10366       else
10367         {
10368           clib_warning ("parse error '%U'", format_unformat_error, i);
10369           return -99;
10370         }
10371     }
10372
10373   if (sw_if_index_set == 0)
10374     {
10375       errmsg ("missing interface name or sw_if_index");
10376       return -99;
10377     }
10378
10379
10380   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10381
10382   mp->sw_if_index = ntohl (sw_if_index);
10383   mp->ip4_table_index = ntohl (ip4_table_index);
10384   mp->ip6_table_index = ntohl (ip6_table_index);
10385   mp->other_table_index = ntohl (other_table_index);
10386   mp->is_input = (u8) is_input;
10387
10388   S (mp);
10389   W (ret);
10390   return ret;
10391 }
10392
10393 static int
10394 api_set_ipfix_exporter (vat_main_t * vam)
10395 {
10396   unformat_input_t *i = vam->input;
10397   vl_api_set_ipfix_exporter_t *mp;
10398   ip4_address_t collector_address;
10399   u8 collector_address_set = 0;
10400   u32 collector_port = ~0;
10401   ip4_address_t src_address;
10402   u8 src_address_set = 0;
10403   u32 vrf_id = ~0;
10404   u32 path_mtu = ~0;
10405   u32 template_interval = ~0;
10406   u8 udp_checksum = 0;
10407   int ret;
10408
10409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10410     {
10411       if (unformat (i, "collector_address %U", unformat_ip4_address,
10412                     &collector_address))
10413         collector_address_set = 1;
10414       else if (unformat (i, "collector_port %d", &collector_port))
10415         ;
10416       else if (unformat (i, "src_address %U", unformat_ip4_address,
10417                          &src_address))
10418         src_address_set = 1;
10419       else if (unformat (i, "vrf_id %d", &vrf_id))
10420         ;
10421       else if (unformat (i, "path_mtu %d", &path_mtu))
10422         ;
10423       else if (unformat (i, "template_interval %d", &template_interval))
10424         ;
10425       else if (unformat (i, "udp_checksum"))
10426         udp_checksum = 1;
10427       else
10428         break;
10429     }
10430
10431   if (collector_address_set == 0)
10432     {
10433       errmsg ("collector_address required");
10434       return -99;
10435     }
10436
10437   if (src_address_set == 0)
10438     {
10439       errmsg ("src_address required");
10440       return -99;
10441     }
10442
10443   M (SET_IPFIX_EXPORTER, mp);
10444
10445   memcpy (mp->collector_address, collector_address.data,
10446           sizeof (collector_address.data));
10447   mp->collector_port = htons ((u16) collector_port);
10448   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10449   mp->vrf_id = htonl (vrf_id);
10450   mp->path_mtu = htonl (path_mtu);
10451   mp->template_interval = htonl (template_interval);
10452   mp->udp_checksum = udp_checksum;
10453
10454   S (mp);
10455   W (ret);
10456   return ret;
10457 }
10458
10459 static int
10460 api_set_ipfix_classify_stream (vat_main_t * vam)
10461 {
10462   unformat_input_t *i = vam->input;
10463   vl_api_set_ipfix_classify_stream_t *mp;
10464   u32 domain_id = 0;
10465   u32 src_port = UDP_DST_PORT_ipfix;
10466   int ret;
10467
10468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10469     {
10470       if (unformat (i, "domain %d", &domain_id))
10471         ;
10472       else if (unformat (i, "src_port %d", &src_port))
10473         ;
10474       else
10475         {
10476           errmsg ("unknown input `%U'", format_unformat_error, i);
10477           return -99;
10478         }
10479     }
10480
10481   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10482
10483   mp->domain_id = htonl (domain_id);
10484   mp->src_port = htons ((u16) src_port);
10485
10486   S (mp);
10487   W (ret);
10488   return ret;
10489 }
10490
10491 static int
10492 api_ipfix_classify_table_add_del (vat_main_t * vam)
10493 {
10494   unformat_input_t *i = vam->input;
10495   vl_api_ipfix_classify_table_add_del_t *mp;
10496   int is_add = -1;
10497   u32 classify_table_index = ~0;
10498   u8 ip_version = 0;
10499   u8 transport_protocol = 255;
10500   int ret;
10501
10502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10503     {
10504       if (unformat (i, "add"))
10505         is_add = 1;
10506       else if (unformat (i, "del"))
10507         is_add = 0;
10508       else if (unformat (i, "table %d", &classify_table_index))
10509         ;
10510       else if (unformat (i, "ip4"))
10511         ip_version = 4;
10512       else if (unformat (i, "ip6"))
10513         ip_version = 6;
10514       else if (unformat (i, "tcp"))
10515         transport_protocol = 6;
10516       else if (unformat (i, "udp"))
10517         transport_protocol = 17;
10518       else
10519         {
10520           errmsg ("unknown input `%U'", format_unformat_error, i);
10521           return -99;
10522         }
10523     }
10524
10525   if (is_add == -1)
10526     {
10527       errmsg ("expecting: add|del");
10528       return -99;
10529     }
10530   if (classify_table_index == ~0)
10531     {
10532       errmsg ("classifier table not specified");
10533       return -99;
10534     }
10535   if (ip_version == 0)
10536     {
10537       errmsg ("IP version not specified");
10538       return -99;
10539     }
10540
10541   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10542
10543   mp->is_add = is_add;
10544   mp->table_id = htonl (classify_table_index);
10545   mp->ip_version = ip_version;
10546   mp->transport_protocol = transport_protocol;
10547
10548   S (mp);
10549   W (ret);
10550   return ret;
10551 }
10552
10553 static int
10554 api_get_node_index (vat_main_t * vam)
10555 {
10556   unformat_input_t *i = vam->input;
10557   vl_api_get_node_index_t *mp;
10558   u8 *name = 0;
10559   int ret;
10560
10561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10562     {
10563       if (unformat (i, "node %s", &name))
10564         ;
10565       else
10566         break;
10567     }
10568   if (name == 0)
10569     {
10570       errmsg ("node name required");
10571       return -99;
10572     }
10573   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10574     {
10575       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10576       return -99;
10577     }
10578
10579   M (GET_NODE_INDEX, mp);
10580   clib_memcpy (mp->node_name, name, vec_len (name));
10581   vec_free (name);
10582
10583   S (mp);
10584   W (ret);
10585   return ret;
10586 }
10587
10588 static int
10589 api_get_next_index (vat_main_t * vam)
10590 {
10591   unformat_input_t *i = vam->input;
10592   vl_api_get_next_index_t *mp;
10593   u8 *node_name = 0, *next_node_name = 0;
10594   int ret;
10595
10596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10597     {
10598       if (unformat (i, "node-name %s", &node_name))
10599         ;
10600       else if (unformat (i, "next-node-name %s", &next_node_name))
10601         break;
10602     }
10603
10604   if (node_name == 0)
10605     {
10606       errmsg ("node name required");
10607       return -99;
10608     }
10609   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10610     {
10611       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10612       return -99;
10613     }
10614
10615   if (next_node_name == 0)
10616     {
10617       errmsg ("next node name required");
10618       return -99;
10619     }
10620   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10621     {
10622       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10623       return -99;
10624     }
10625
10626   M (GET_NEXT_INDEX, mp);
10627   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10628   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10629   vec_free (node_name);
10630   vec_free (next_node_name);
10631
10632   S (mp);
10633   W (ret);
10634   return ret;
10635 }
10636
10637 static int
10638 api_add_node_next (vat_main_t * vam)
10639 {
10640   unformat_input_t *i = vam->input;
10641   vl_api_add_node_next_t *mp;
10642   u8 *name = 0;
10643   u8 *next = 0;
10644   int ret;
10645
10646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10647     {
10648       if (unformat (i, "node %s", &name))
10649         ;
10650       else if (unformat (i, "next %s", &next))
10651         ;
10652       else
10653         break;
10654     }
10655   if (name == 0)
10656     {
10657       errmsg ("node name required");
10658       return -99;
10659     }
10660   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10661     {
10662       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10663       return -99;
10664     }
10665   if (next == 0)
10666     {
10667       errmsg ("next node required");
10668       return -99;
10669     }
10670   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10671     {
10672       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10673       return -99;
10674     }
10675
10676   M (ADD_NODE_NEXT, mp);
10677   clib_memcpy (mp->node_name, name, vec_len (name));
10678   clib_memcpy (mp->next_name, next, vec_len (next));
10679   vec_free (name);
10680   vec_free (next);
10681
10682   S (mp);
10683   W (ret);
10684   return ret;
10685 }
10686
10687 static int
10688 api_l2tpv3_create_tunnel (vat_main_t * vam)
10689 {
10690   unformat_input_t *i = vam->input;
10691   ip6_address_t client_address, our_address;
10692   int client_address_set = 0;
10693   int our_address_set = 0;
10694   u32 local_session_id = 0;
10695   u32 remote_session_id = 0;
10696   u64 local_cookie = 0;
10697   u64 remote_cookie = 0;
10698   u8 l2_sublayer_present = 0;
10699   vl_api_l2tpv3_create_tunnel_t *mp;
10700   int ret;
10701
10702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (i, "client_address %U", unformat_ip6_address,
10705                     &client_address))
10706         client_address_set = 1;
10707       else if (unformat (i, "our_address %U", unformat_ip6_address,
10708                          &our_address))
10709         our_address_set = 1;
10710       else if (unformat (i, "local_session_id %d", &local_session_id))
10711         ;
10712       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10713         ;
10714       else if (unformat (i, "local_cookie %lld", &local_cookie))
10715         ;
10716       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10717         ;
10718       else if (unformat (i, "l2-sublayer-present"))
10719         l2_sublayer_present = 1;
10720       else
10721         break;
10722     }
10723
10724   if (client_address_set == 0)
10725     {
10726       errmsg ("client_address required");
10727       return -99;
10728     }
10729
10730   if (our_address_set == 0)
10731     {
10732       errmsg ("our_address required");
10733       return -99;
10734     }
10735
10736   M (L2TPV3_CREATE_TUNNEL, mp);
10737
10738   clib_memcpy (mp->client_address, client_address.as_u8,
10739                sizeof (mp->client_address));
10740
10741   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10742
10743   mp->local_session_id = ntohl (local_session_id);
10744   mp->remote_session_id = ntohl (remote_session_id);
10745   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10746   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10747   mp->l2_sublayer_present = l2_sublayer_present;
10748   mp->is_ipv6 = 1;
10749
10750   S (mp);
10751   W (ret);
10752   return ret;
10753 }
10754
10755 static int
10756 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10757 {
10758   unformat_input_t *i = vam->input;
10759   u32 sw_if_index;
10760   u8 sw_if_index_set = 0;
10761   u64 new_local_cookie = 0;
10762   u64 new_remote_cookie = 0;
10763   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10764   int ret;
10765
10766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10767     {
10768       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10769         sw_if_index_set = 1;
10770       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10771         sw_if_index_set = 1;
10772       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10773         ;
10774       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10775         ;
10776       else
10777         break;
10778     }
10779
10780   if (sw_if_index_set == 0)
10781     {
10782       errmsg ("missing interface name or sw_if_index");
10783       return -99;
10784     }
10785
10786   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10787
10788   mp->sw_if_index = ntohl (sw_if_index);
10789   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10790   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10791
10792   S (mp);
10793   W (ret);
10794   return ret;
10795 }
10796
10797 static int
10798 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10799 {
10800   unformat_input_t *i = vam->input;
10801   vl_api_l2tpv3_interface_enable_disable_t *mp;
10802   u32 sw_if_index;
10803   u8 sw_if_index_set = 0;
10804   u8 enable_disable = 1;
10805   int ret;
10806
10807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10808     {
10809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10810         sw_if_index_set = 1;
10811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10812         sw_if_index_set = 1;
10813       else if (unformat (i, "enable"))
10814         enable_disable = 1;
10815       else if (unformat (i, "disable"))
10816         enable_disable = 0;
10817       else
10818         break;
10819     }
10820
10821   if (sw_if_index_set == 0)
10822     {
10823       errmsg ("missing interface name or sw_if_index");
10824       return -99;
10825     }
10826
10827   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10828
10829   mp->sw_if_index = ntohl (sw_if_index);
10830   mp->enable_disable = enable_disable;
10831
10832   S (mp);
10833   W (ret);
10834   return ret;
10835 }
10836
10837 static int
10838 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10839 {
10840   unformat_input_t *i = vam->input;
10841   vl_api_l2tpv3_set_lookup_key_t *mp;
10842   u8 key = ~0;
10843   int ret;
10844
10845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10846     {
10847       if (unformat (i, "lookup_v6_src"))
10848         key = L2T_LOOKUP_SRC_ADDRESS;
10849       else if (unformat (i, "lookup_v6_dst"))
10850         key = L2T_LOOKUP_DST_ADDRESS;
10851       else if (unformat (i, "lookup_session_id"))
10852         key = L2T_LOOKUP_SESSION_ID;
10853       else
10854         break;
10855     }
10856
10857   if (key == (u8) ~ 0)
10858     {
10859       errmsg ("l2tp session lookup key unset");
10860       return -99;
10861     }
10862
10863   M (L2TPV3_SET_LOOKUP_KEY, mp);
10864
10865   mp->key = key;
10866
10867   S (mp);
10868   W (ret);
10869   return ret;
10870 }
10871
10872 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10873   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10874 {
10875   vat_main_t *vam = &vat_main;
10876
10877   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10878          format_ip6_address, mp->our_address,
10879          format_ip6_address, mp->client_address,
10880          clib_net_to_host_u32 (mp->sw_if_index));
10881
10882   print (vam->ofp,
10883          "   local cookies %016llx %016llx remote cookie %016llx",
10884          clib_net_to_host_u64 (mp->local_cookie[0]),
10885          clib_net_to_host_u64 (mp->local_cookie[1]),
10886          clib_net_to_host_u64 (mp->remote_cookie));
10887
10888   print (vam->ofp, "   local session-id %d remote session-id %d",
10889          clib_net_to_host_u32 (mp->local_session_id),
10890          clib_net_to_host_u32 (mp->remote_session_id));
10891
10892   print (vam->ofp, "   l2 specific sublayer %s\n",
10893          mp->l2_sublayer_present ? "preset" : "absent");
10894
10895 }
10896
10897 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10898   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10899 {
10900   vat_main_t *vam = &vat_main;
10901   vat_json_node_t *node = NULL;
10902   struct in6_addr addr;
10903
10904   if (VAT_JSON_ARRAY != vam->json_tree.type)
10905     {
10906       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10907       vat_json_init_array (&vam->json_tree);
10908     }
10909   node = vat_json_array_add (&vam->json_tree);
10910
10911   vat_json_init_object (node);
10912
10913   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10914   vat_json_object_add_ip6 (node, "our_address", addr);
10915   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10916   vat_json_object_add_ip6 (node, "client_address", addr);
10917
10918   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10919   vat_json_init_array (lc);
10920   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10921   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10922   vat_json_object_add_uint (node, "remote_cookie",
10923                             clib_net_to_host_u64 (mp->remote_cookie));
10924
10925   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10926   vat_json_object_add_uint (node, "local_session_id",
10927                             clib_net_to_host_u32 (mp->local_session_id));
10928   vat_json_object_add_uint (node, "remote_session_id",
10929                             clib_net_to_host_u32 (mp->remote_session_id));
10930   vat_json_object_add_string_copy (node, "l2_sublayer",
10931                                    mp->l2_sublayer_present ? (u8 *) "present"
10932                                    : (u8 *) "absent");
10933 }
10934
10935 static int
10936 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10937 {
10938   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10939   vl_api_control_ping_t *mp_ping;
10940   int ret;
10941
10942   /* Get list of l2tpv3-tunnel interfaces */
10943   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10944   S (mp);
10945
10946   /* Use a control ping for synchronization */
10947   M (CONTROL_PING, mp_ping);
10948   S (mp_ping);
10949
10950   W (ret);
10951   return ret;
10952 }
10953
10954
10955 static void vl_api_sw_interface_tap_details_t_handler
10956   (vl_api_sw_interface_tap_details_t * mp)
10957 {
10958   vat_main_t *vam = &vat_main;
10959
10960   print (vam->ofp, "%-16s %d",
10961          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10962 }
10963
10964 static void vl_api_sw_interface_tap_details_t_handler_json
10965   (vl_api_sw_interface_tap_details_t * mp)
10966 {
10967   vat_main_t *vam = &vat_main;
10968   vat_json_node_t *node = NULL;
10969
10970   if (VAT_JSON_ARRAY != vam->json_tree.type)
10971     {
10972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10973       vat_json_init_array (&vam->json_tree);
10974     }
10975   node = vat_json_array_add (&vam->json_tree);
10976
10977   vat_json_init_object (node);
10978   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10979   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10980 }
10981
10982 static int
10983 api_sw_interface_tap_dump (vat_main_t * vam)
10984 {
10985   vl_api_sw_interface_tap_dump_t *mp;
10986   vl_api_control_ping_t *mp_ping;
10987   int ret;
10988
10989   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10990   /* Get list of tap interfaces */
10991   M (SW_INTERFACE_TAP_DUMP, mp);
10992   S (mp);
10993
10994   /* Use a control ping for synchronization */
10995   M (CONTROL_PING, mp_ping);
10996   S (mp_ping);
10997
10998   W (ret);
10999   return ret;
11000 }
11001
11002 static uword unformat_vxlan_decap_next
11003   (unformat_input_t * input, va_list * args)
11004 {
11005   u32 *result = va_arg (*args, u32 *);
11006   u32 tmp;
11007
11008   if (unformat (input, "l2"))
11009     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11010   else if (unformat (input, "%d", &tmp))
11011     *result = tmp;
11012   else
11013     return 0;
11014   return 1;
11015 }
11016
11017 static int
11018 api_vxlan_add_del_tunnel (vat_main_t * vam)
11019 {
11020   unformat_input_t *line_input = vam->input;
11021   vl_api_vxlan_add_del_tunnel_t *mp;
11022   ip46_address_t src, dst;
11023   u8 is_add = 1;
11024   u8 ipv4_set = 0, ipv6_set = 0;
11025   u8 src_set = 0;
11026   u8 dst_set = 0;
11027   u8 grp_set = 0;
11028   u32 mcast_sw_if_index = ~0;
11029   u32 encap_vrf_id = 0;
11030   u32 decap_next_index = ~0;
11031   u32 vni = 0;
11032   int ret;
11033
11034   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11035   memset (&src, 0, sizeof src);
11036   memset (&dst, 0, sizeof dst);
11037
11038   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11039     {
11040       if (unformat (line_input, "del"))
11041         is_add = 0;
11042       else
11043         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11044         {
11045           ipv4_set = 1;
11046           src_set = 1;
11047         }
11048       else
11049         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11050         {
11051           ipv4_set = 1;
11052           dst_set = 1;
11053         }
11054       else
11055         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11056         {
11057           ipv6_set = 1;
11058           src_set = 1;
11059         }
11060       else
11061         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11062         {
11063           ipv6_set = 1;
11064           dst_set = 1;
11065         }
11066       else if (unformat (line_input, "group %U %U",
11067                          unformat_ip4_address, &dst.ip4,
11068                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11069         {
11070           grp_set = dst_set = 1;
11071           ipv4_set = 1;
11072         }
11073       else if (unformat (line_input, "group %U",
11074                          unformat_ip4_address, &dst.ip4))
11075         {
11076           grp_set = dst_set = 1;
11077           ipv4_set = 1;
11078         }
11079       else if (unformat (line_input, "group %U %U",
11080                          unformat_ip6_address, &dst.ip6,
11081                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11082         {
11083           grp_set = dst_set = 1;
11084           ipv6_set = 1;
11085         }
11086       else if (unformat (line_input, "group %U",
11087                          unformat_ip6_address, &dst.ip6))
11088         {
11089           grp_set = dst_set = 1;
11090           ipv6_set = 1;
11091         }
11092       else
11093         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11094         ;
11095       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11096         ;
11097       else if (unformat (line_input, "decap-next %U",
11098                          unformat_vxlan_decap_next, &decap_next_index))
11099         ;
11100       else if (unformat (line_input, "vni %d", &vni))
11101         ;
11102       else
11103         {
11104           errmsg ("parse error '%U'", format_unformat_error, line_input);
11105           return -99;
11106         }
11107     }
11108
11109   if (src_set == 0)
11110     {
11111       errmsg ("tunnel src address not specified");
11112       return -99;
11113     }
11114   if (dst_set == 0)
11115     {
11116       errmsg ("tunnel dst address not specified");
11117       return -99;
11118     }
11119
11120   if (grp_set && !ip46_address_is_multicast (&dst))
11121     {
11122       errmsg ("tunnel group address not multicast");
11123       return -99;
11124     }
11125   if (grp_set && mcast_sw_if_index == ~0)
11126     {
11127       errmsg ("tunnel nonexistent multicast device");
11128       return -99;
11129     }
11130   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11131     {
11132       errmsg ("tunnel dst address must be unicast");
11133       return -99;
11134     }
11135
11136
11137   if (ipv4_set && ipv6_set)
11138     {
11139       errmsg ("both IPv4 and IPv6 addresses specified");
11140       return -99;
11141     }
11142
11143   if ((vni == 0) || (vni >> 24))
11144     {
11145       errmsg ("vni not specified or out of range");
11146       return -99;
11147     }
11148
11149   M (VXLAN_ADD_DEL_TUNNEL, mp);
11150
11151   if (ipv6_set)
11152     {
11153       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11154       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11155     }
11156   else
11157     {
11158       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11159       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11160     }
11161   mp->encap_vrf_id = ntohl (encap_vrf_id);
11162   mp->decap_next_index = ntohl (decap_next_index);
11163   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11164   mp->vni = ntohl (vni);
11165   mp->is_add = is_add;
11166   mp->is_ipv6 = ipv6_set;
11167
11168   S (mp);
11169   W (ret);
11170   return ret;
11171 }
11172
11173 static void vl_api_vxlan_tunnel_details_t_handler
11174   (vl_api_vxlan_tunnel_details_t * mp)
11175 {
11176   vat_main_t *vam = &vat_main;
11177   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11178   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11179
11180   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11181          ntohl (mp->sw_if_index),
11182          format_ip46_address, &src, IP46_TYPE_ANY,
11183          format_ip46_address, &dst, IP46_TYPE_ANY,
11184          ntohl (mp->encap_vrf_id),
11185          ntohl (mp->decap_next_index), ntohl (mp->vni),
11186          ntohl (mp->mcast_sw_if_index));
11187 }
11188
11189 static void vl_api_vxlan_tunnel_details_t_handler_json
11190   (vl_api_vxlan_tunnel_details_t * mp)
11191 {
11192   vat_main_t *vam = &vat_main;
11193   vat_json_node_t *node = NULL;
11194
11195   if (VAT_JSON_ARRAY != vam->json_tree.type)
11196     {
11197       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11198       vat_json_init_array (&vam->json_tree);
11199     }
11200   node = vat_json_array_add (&vam->json_tree);
11201
11202   vat_json_init_object (node);
11203   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11204   if (mp->is_ipv6)
11205     {
11206       struct in6_addr ip6;
11207
11208       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11209       vat_json_object_add_ip6 (node, "src_address", ip6);
11210       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11211       vat_json_object_add_ip6 (node, "dst_address", ip6);
11212     }
11213   else
11214     {
11215       struct in_addr ip4;
11216
11217       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11218       vat_json_object_add_ip4 (node, "src_address", ip4);
11219       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11220       vat_json_object_add_ip4 (node, "dst_address", ip4);
11221     }
11222   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11223   vat_json_object_add_uint (node, "decap_next_index",
11224                             ntohl (mp->decap_next_index));
11225   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11226   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11227   vat_json_object_add_uint (node, "mcast_sw_if_index",
11228                             ntohl (mp->mcast_sw_if_index));
11229 }
11230
11231 static int
11232 api_vxlan_tunnel_dump (vat_main_t * vam)
11233 {
11234   unformat_input_t *i = vam->input;
11235   vl_api_vxlan_tunnel_dump_t *mp;
11236   vl_api_control_ping_t *mp_ping;
11237   u32 sw_if_index;
11238   u8 sw_if_index_set = 0;
11239   int ret;
11240
11241   /* Parse args required to build the message */
11242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11243     {
11244       if (unformat (i, "sw_if_index %d", &sw_if_index))
11245         sw_if_index_set = 1;
11246       else
11247         break;
11248     }
11249
11250   if (sw_if_index_set == 0)
11251     {
11252       sw_if_index = ~0;
11253     }
11254
11255   if (!vam->json_output)
11256     {
11257       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11258              "sw_if_index", "src_address", "dst_address",
11259              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11260     }
11261
11262   /* Get list of vxlan-tunnel interfaces */
11263   M (VXLAN_TUNNEL_DUMP, mp);
11264
11265   mp->sw_if_index = htonl (sw_if_index);
11266
11267   S (mp);
11268
11269   /* Use a control ping for synchronization */
11270   M (CONTROL_PING, mp_ping);
11271   S (mp_ping);
11272
11273   W (ret);
11274   return ret;
11275 }
11276
11277 static int
11278 api_gre_add_del_tunnel (vat_main_t * vam)
11279 {
11280   unformat_input_t *line_input = vam->input;
11281   vl_api_gre_add_del_tunnel_t *mp;
11282   ip4_address_t src4, dst4;
11283   ip6_address_t src6, dst6;
11284   u8 is_add = 1;
11285   u8 ipv4_set = 0;
11286   u8 ipv6_set = 0;
11287   u8 teb = 0;
11288   u8 src_set = 0;
11289   u8 dst_set = 0;
11290   u32 outer_fib_id = 0;
11291   int ret;
11292
11293   memset (&src4, 0, sizeof src4);
11294   memset (&dst4, 0, sizeof dst4);
11295   memset (&src6, 0, sizeof src6);
11296   memset (&dst6, 0, sizeof dst6);
11297
11298   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11299     {
11300       if (unformat (line_input, "del"))
11301         is_add = 0;
11302       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11303         {
11304           src_set = 1;
11305           ipv4_set = 1;
11306         }
11307       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11308         {
11309           dst_set = 1;
11310           ipv4_set = 1;
11311         }
11312       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11313         {
11314           src_set = 1;
11315           ipv6_set = 1;
11316         }
11317       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11318         {
11319           dst_set = 1;
11320           ipv6_set = 1;
11321         }
11322       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11323         ;
11324       else if (unformat (line_input, "teb"))
11325         teb = 1;
11326       else
11327         {
11328           errmsg ("parse error '%U'", format_unformat_error, line_input);
11329           return -99;
11330         }
11331     }
11332
11333   if (src_set == 0)
11334     {
11335       errmsg ("tunnel src address not specified");
11336       return -99;
11337     }
11338   if (dst_set == 0)
11339     {
11340       errmsg ("tunnel dst address not specified");
11341       return -99;
11342     }
11343   if (ipv4_set && ipv6_set)
11344     {
11345       errmsg ("both IPv4 and IPv6 addresses specified");
11346       return -99;
11347     }
11348
11349
11350   M (GRE_ADD_DEL_TUNNEL, mp);
11351
11352   if (ipv4_set)
11353     {
11354       clib_memcpy (&mp->src_address, &src4, 4);
11355       clib_memcpy (&mp->dst_address, &dst4, 4);
11356     }
11357   else
11358     {
11359       clib_memcpy (&mp->src_address, &src6, 16);
11360       clib_memcpy (&mp->dst_address, &dst6, 16);
11361     }
11362   mp->outer_fib_id = ntohl (outer_fib_id);
11363   mp->is_add = is_add;
11364   mp->teb = teb;
11365   mp->is_ipv6 = ipv6_set;
11366
11367   S (mp);
11368   W (ret);
11369   return ret;
11370 }
11371
11372 static void vl_api_gre_tunnel_details_t_handler
11373   (vl_api_gre_tunnel_details_t * mp)
11374 {
11375   vat_main_t *vam = &vat_main;
11376   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11377   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11378
11379   print (vam->ofp, "%11d%24U%24U%6d%14d",
11380          ntohl (mp->sw_if_index),
11381          format_ip46_address, &src, IP46_TYPE_ANY,
11382          format_ip46_address, &dst, IP46_TYPE_ANY,
11383          mp->teb, ntohl (mp->outer_fib_id));
11384 }
11385
11386 static void vl_api_gre_tunnel_details_t_handler_json
11387   (vl_api_gre_tunnel_details_t * mp)
11388 {
11389   vat_main_t *vam = &vat_main;
11390   vat_json_node_t *node = NULL;
11391   struct in_addr ip4;
11392   struct in6_addr ip6;
11393
11394   if (VAT_JSON_ARRAY != vam->json_tree.type)
11395     {
11396       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11397       vat_json_init_array (&vam->json_tree);
11398     }
11399   node = vat_json_array_add (&vam->json_tree);
11400
11401   vat_json_init_object (node);
11402   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11403   if (!mp->is_ipv6)
11404     {
11405       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11406       vat_json_object_add_ip4 (node, "src_address", ip4);
11407       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11408       vat_json_object_add_ip4 (node, "dst_address", ip4);
11409     }
11410   else
11411     {
11412       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11413       vat_json_object_add_ip6 (node, "src_address", ip6);
11414       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11415       vat_json_object_add_ip6 (node, "dst_address", ip6);
11416     }
11417   vat_json_object_add_uint (node, "teb", mp->teb);
11418   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11419   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11420 }
11421
11422 static int
11423 api_gre_tunnel_dump (vat_main_t * vam)
11424 {
11425   unformat_input_t *i = vam->input;
11426   vl_api_gre_tunnel_dump_t *mp;
11427   vl_api_control_ping_t *mp_ping;
11428   u32 sw_if_index;
11429   u8 sw_if_index_set = 0;
11430   int ret;
11431
11432   /* Parse args required to build the message */
11433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (i, "sw_if_index %d", &sw_if_index))
11436         sw_if_index_set = 1;
11437       else
11438         break;
11439     }
11440
11441   if (sw_if_index_set == 0)
11442     {
11443       sw_if_index = ~0;
11444     }
11445
11446   if (!vam->json_output)
11447     {
11448       print (vam->ofp, "%11s%24s%24s%6s%14s",
11449              "sw_if_index", "src_address", "dst_address", "teb",
11450              "outer_fib_id");
11451     }
11452
11453   /* Get list of gre-tunnel interfaces */
11454   M (GRE_TUNNEL_DUMP, mp);
11455
11456   mp->sw_if_index = htonl (sw_if_index);
11457
11458   S (mp);
11459
11460   /* Use a control ping for synchronization */
11461   M (CONTROL_PING, mp_ping);
11462   S (mp_ping);
11463
11464   W (ret);
11465   return ret;
11466 }
11467
11468 static int
11469 api_l2_fib_clear_table (vat_main_t * vam)
11470 {
11471 //  unformat_input_t * i = vam->input;
11472   vl_api_l2_fib_clear_table_t *mp;
11473   int ret;
11474
11475   M (L2_FIB_CLEAR_TABLE, mp);
11476
11477   S (mp);
11478   W (ret);
11479   return ret;
11480 }
11481
11482 static int
11483 api_l2_interface_efp_filter (vat_main_t * vam)
11484 {
11485   unformat_input_t *i = vam->input;
11486   vl_api_l2_interface_efp_filter_t *mp;
11487   u32 sw_if_index;
11488   u8 enable = 1;
11489   u8 sw_if_index_set = 0;
11490   int ret;
11491
11492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11493     {
11494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11495         sw_if_index_set = 1;
11496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11497         sw_if_index_set = 1;
11498       else if (unformat (i, "enable"))
11499         enable = 1;
11500       else if (unformat (i, "disable"))
11501         enable = 0;
11502       else
11503         {
11504           clib_warning ("parse error '%U'", format_unformat_error, i);
11505           return -99;
11506         }
11507     }
11508
11509   if (sw_if_index_set == 0)
11510     {
11511       errmsg ("missing sw_if_index");
11512       return -99;
11513     }
11514
11515   M (L2_INTERFACE_EFP_FILTER, mp);
11516
11517   mp->sw_if_index = ntohl (sw_if_index);
11518   mp->enable_disable = enable;
11519
11520   S (mp);
11521   W (ret);
11522   return ret;
11523 }
11524
11525 #define foreach_vtr_op                          \
11526 _("disable",  L2_VTR_DISABLED)                  \
11527 _("push-1",  L2_VTR_PUSH_1)                     \
11528 _("push-2",  L2_VTR_PUSH_2)                     \
11529 _("pop-1",  L2_VTR_POP_1)                       \
11530 _("pop-2",  L2_VTR_POP_2)                       \
11531 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11532 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11533 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11534 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11535
11536 static int
11537 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11538 {
11539   unformat_input_t *i = vam->input;
11540   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11541   u32 sw_if_index;
11542   u8 sw_if_index_set = 0;
11543   u8 vtr_op_set = 0;
11544   u32 vtr_op = 0;
11545   u32 push_dot1q = 1;
11546   u32 tag1 = ~0;
11547   u32 tag2 = ~0;
11548   int ret;
11549
11550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11551     {
11552       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11553         sw_if_index_set = 1;
11554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11555         sw_if_index_set = 1;
11556       else if (unformat (i, "vtr_op %d", &vtr_op))
11557         vtr_op_set = 1;
11558 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11559       foreach_vtr_op
11560 #undef _
11561         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11562         ;
11563       else if (unformat (i, "tag1 %d", &tag1))
11564         ;
11565       else if (unformat (i, "tag2 %d", &tag2))
11566         ;
11567       else
11568         {
11569           clib_warning ("parse error '%U'", format_unformat_error, i);
11570           return -99;
11571         }
11572     }
11573
11574   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11575     {
11576       errmsg ("missing vtr operation or sw_if_index");
11577       return -99;
11578     }
11579
11580   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11581   mp->sw_if_index = ntohl (sw_if_index);
11582   mp->vtr_op = ntohl (vtr_op);
11583   mp->push_dot1q = ntohl (push_dot1q);
11584   mp->tag1 = ntohl (tag1);
11585   mp->tag2 = ntohl (tag2);
11586
11587   S (mp);
11588   W (ret);
11589   return ret;
11590 }
11591
11592 static int
11593 api_create_vhost_user_if (vat_main_t * vam)
11594 {
11595   unformat_input_t *i = vam->input;
11596   vl_api_create_vhost_user_if_t *mp;
11597   u8 *file_name;
11598   u8 is_server = 0;
11599   u8 file_name_set = 0;
11600   u32 custom_dev_instance = ~0;
11601   u8 hwaddr[6];
11602   u8 use_custom_mac = 0;
11603   u8 *tag = 0;
11604   int ret;
11605
11606   /* Shut up coverity */
11607   memset (hwaddr, 0, sizeof (hwaddr));
11608
11609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11610     {
11611       if (unformat (i, "socket %s", &file_name))
11612         {
11613           file_name_set = 1;
11614         }
11615       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11616         ;
11617       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11618         use_custom_mac = 1;
11619       else if (unformat (i, "server"))
11620         is_server = 1;
11621       else if (unformat (i, "tag %s", &tag))
11622         ;
11623       else
11624         break;
11625     }
11626
11627   if (file_name_set == 0)
11628     {
11629       errmsg ("missing socket file name");
11630       return -99;
11631     }
11632
11633   if (vec_len (file_name) > 255)
11634     {
11635       errmsg ("socket file name too long");
11636       return -99;
11637     }
11638   vec_add1 (file_name, 0);
11639
11640   M (CREATE_VHOST_USER_IF, mp);
11641
11642   mp->is_server = is_server;
11643   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11644   vec_free (file_name);
11645   if (custom_dev_instance != ~0)
11646     {
11647       mp->renumber = 1;
11648       mp->custom_dev_instance = ntohl (custom_dev_instance);
11649     }
11650   mp->use_custom_mac = use_custom_mac;
11651   clib_memcpy (mp->mac_address, hwaddr, 6);
11652   if (tag)
11653     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11654   vec_free (tag);
11655
11656   S (mp);
11657   W (ret);
11658   return ret;
11659 }
11660
11661 static int
11662 api_modify_vhost_user_if (vat_main_t * vam)
11663 {
11664   unformat_input_t *i = vam->input;
11665   vl_api_modify_vhost_user_if_t *mp;
11666   u8 *file_name;
11667   u8 is_server = 0;
11668   u8 file_name_set = 0;
11669   u32 custom_dev_instance = ~0;
11670   u8 sw_if_index_set = 0;
11671   u32 sw_if_index = (u32) ~ 0;
11672   int ret;
11673
11674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11675     {
11676       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11677         sw_if_index_set = 1;
11678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11679         sw_if_index_set = 1;
11680       else if (unformat (i, "socket %s", &file_name))
11681         {
11682           file_name_set = 1;
11683         }
11684       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11685         ;
11686       else if (unformat (i, "server"))
11687         is_server = 1;
11688       else
11689         break;
11690     }
11691
11692   if (sw_if_index_set == 0)
11693     {
11694       errmsg ("missing sw_if_index or interface name");
11695       return -99;
11696     }
11697
11698   if (file_name_set == 0)
11699     {
11700       errmsg ("missing socket file name");
11701       return -99;
11702     }
11703
11704   if (vec_len (file_name) > 255)
11705     {
11706       errmsg ("socket file name too long");
11707       return -99;
11708     }
11709   vec_add1 (file_name, 0);
11710
11711   M (MODIFY_VHOST_USER_IF, mp);
11712
11713   mp->sw_if_index = ntohl (sw_if_index);
11714   mp->is_server = is_server;
11715   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11716   vec_free (file_name);
11717   if (custom_dev_instance != ~0)
11718     {
11719       mp->renumber = 1;
11720       mp->custom_dev_instance = ntohl (custom_dev_instance);
11721     }
11722
11723   S (mp);
11724   W (ret);
11725   return ret;
11726 }
11727
11728 static int
11729 api_delete_vhost_user_if (vat_main_t * vam)
11730 {
11731   unformat_input_t *i = vam->input;
11732   vl_api_delete_vhost_user_if_t *mp;
11733   u32 sw_if_index = ~0;
11734   u8 sw_if_index_set = 0;
11735   int ret;
11736
11737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11738     {
11739       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11740         sw_if_index_set = 1;
11741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11742         sw_if_index_set = 1;
11743       else
11744         break;
11745     }
11746
11747   if (sw_if_index_set == 0)
11748     {
11749       errmsg ("missing sw_if_index or interface name");
11750       return -99;
11751     }
11752
11753
11754   M (DELETE_VHOST_USER_IF, mp);
11755
11756   mp->sw_if_index = ntohl (sw_if_index);
11757
11758   S (mp);
11759   W (ret);
11760   return ret;
11761 }
11762
11763 static void vl_api_sw_interface_vhost_user_details_t_handler
11764   (vl_api_sw_interface_vhost_user_details_t * mp)
11765 {
11766   vat_main_t *vam = &vat_main;
11767
11768   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11769          (char *) mp->interface_name,
11770          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11771          clib_net_to_host_u64 (mp->features), mp->is_server,
11772          ntohl (mp->num_regions), (char *) mp->sock_filename);
11773   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11774 }
11775
11776 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11777   (vl_api_sw_interface_vhost_user_details_t * mp)
11778 {
11779   vat_main_t *vam = &vat_main;
11780   vat_json_node_t *node = NULL;
11781
11782   if (VAT_JSON_ARRAY != vam->json_tree.type)
11783     {
11784       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11785       vat_json_init_array (&vam->json_tree);
11786     }
11787   node = vat_json_array_add (&vam->json_tree);
11788
11789   vat_json_init_object (node);
11790   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11791   vat_json_object_add_string_copy (node, "interface_name",
11792                                    mp->interface_name);
11793   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11794                             ntohl (mp->virtio_net_hdr_sz));
11795   vat_json_object_add_uint (node, "features",
11796                             clib_net_to_host_u64 (mp->features));
11797   vat_json_object_add_uint (node, "is_server", mp->is_server);
11798   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11799   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11800   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11801 }
11802
11803 static int
11804 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11805 {
11806   vl_api_sw_interface_vhost_user_dump_t *mp;
11807   vl_api_control_ping_t *mp_ping;
11808   int ret;
11809   print (vam->ofp,
11810          "Interface name            idx hdr_sz features server regions filename");
11811
11812   /* Get list of vhost-user interfaces */
11813   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11814   S (mp);
11815
11816   /* Use a control ping for synchronization */
11817   M (CONTROL_PING, mp_ping);
11818   S (mp_ping);
11819
11820   W (ret);
11821   return ret;
11822 }
11823
11824 static int
11825 api_show_version (vat_main_t * vam)
11826 {
11827   vl_api_show_version_t *mp;
11828   int ret;
11829
11830   M (SHOW_VERSION, mp);
11831
11832   S (mp);
11833   W (ret);
11834   return ret;
11835 }
11836
11837
11838 static int
11839 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11840 {
11841   unformat_input_t *line_input = vam->input;
11842   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11843   ip4_address_t local4, remote4;
11844   ip6_address_t local6, remote6;
11845   u8 is_add = 1;
11846   u8 ipv4_set = 0, ipv6_set = 0;
11847   u8 local_set = 0;
11848   u8 remote_set = 0;
11849   u32 encap_vrf_id = 0;
11850   u32 decap_vrf_id = 0;
11851   u8 protocol = ~0;
11852   u32 vni;
11853   u8 vni_set = 0;
11854   int ret;
11855
11856   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11857     {
11858       if (unformat (line_input, "del"))
11859         is_add = 0;
11860       else if (unformat (line_input, "local %U",
11861                          unformat_ip4_address, &local4))
11862         {
11863           local_set = 1;
11864           ipv4_set = 1;
11865         }
11866       else if (unformat (line_input, "remote %U",
11867                          unformat_ip4_address, &remote4))
11868         {
11869           remote_set = 1;
11870           ipv4_set = 1;
11871         }
11872       else if (unformat (line_input, "local %U",
11873                          unformat_ip6_address, &local6))
11874         {
11875           local_set = 1;
11876           ipv6_set = 1;
11877         }
11878       else if (unformat (line_input, "remote %U",
11879                          unformat_ip6_address, &remote6))
11880         {
11881           remote_set = 1;
11882           ipv6_set = 1;
11883         }
11884       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11885         ;
11886       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11887         ;
11888       else if (unformat (line_input, "vni %d", &vni))
11889         vni_set = 1;
11890       else if (unformat (line_input, "next-ip4"))
11891         protocol = 1;
11892       else if (unformat (line_input, "next-ip6"))
11893         protocol = 2;
11894       else if (unformat (line_input, "next-ethernet"))
11895         protocol = 3;
11896       else if (unformat (line_input, "next-nsh"))
11897         protocol = 4;
11898       else
11899         {
11900           errmsg ("parse error '%U'", format_unformat_error, line_input);
11901           return -99;
11902         }
11903     }
11904
11905   if (local_set == 0)
11906     {
11907       errmsg ("tunnel local address not specified");
11908       return -99;
11909     }
11910   if (remote_set == 0)
11911     {
11912       errmsg ("tunnel remote address not specified");
11913       return -99;
11914     }
11915   if (ipv4_set && ipv6_set)
11916     {
11917       errmsg ("both IPv4 and IPv6 addresses specified");
11918       return -99;
11919     }
11920
11921   if (vni_set == 0)
11922     {
11923       errmsg ("vni not specified");
11924       return -99;
11925     }
11926
11927   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11928
11929
11930   if (ipv6_set)
11931     {
11932       clib_memcpy (&mp->local, &local6, sizeof (local6));
11933       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11934     }
11935   else
11936     {
11937       clib_memcpy (&mp->local, &local4, sizeof (local4));
11938       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11939     }
11940
11941   mp->encap_vrf_id = ntohl (encap_vrf_id);
11942   mp->decap_vrf_id = ntohl (decap_vrf_id);
11943   mp->protocol = protocol;
11944   mp->vni = ntohl (vni);
11945   mp->is_add = is_add;
11946   mp->is_ipv6 = ipv6_set;
11947
11948   S (mp);
11949   W (ret);
11950   return ret;
11951 }
11952
11953 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11954   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11955 {
11956   vat_main_t *vam = &vat_main;
11957
11958   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11959          ntohl (mp->sw_if_index),
11960          format_ip46_address, &(mp->local[0]),
11961          format_ip46_address, &(mp->remote[0]),
11962          ntohl (mp->vni),
11963          ntohl (mp->protocol),
11964          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11965 }
11966
11967 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11968   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11969 {
11970   vat_main_t *vam = &vat_main;
11971   vat_json_node_t *node = NULL;
11972   struct in_addr ip4;
11973   struct in6_addr ip6;
11974
11975   if (VAT_JSON_ARRAY != vam->json_tree.type)
11976     {
11977       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11978       vat_json_init_array (&vam->json_tree);
11979     }
11980   node = vat_json_array_add (&vam->json_tree);
11981
11982   vat_json_init_object (node);
11983   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11984   if (mp->is_ipv6)
11985     {
11986       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11987       vat_json_object_add_ip6 (node, "local", ip6);
11988       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11989       vat_json_object_add_ip6 (node, "remote", ip6);
11990     }
11991   else
11992     {
11993       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11994       vat_json_object_add_ip4 (node, "local", ip4);
11995       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11996       vat_json_object_add_ip4 (node, "remote", ip4);
11997     }
11998   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11999   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12000   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12001   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12002   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12003 }
12004
12005 static int
12006 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12007 {
12008   unformat_input_t *i = vam->input;
12009   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12010   vl_api_control_ping_t *mp_ping;
12011   u32 sw_if_index;
12012   u8 sw_if_index_set = 0;
12013   int ret;
12014
12015   /* Parse args required to build the message */
12016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12017     {
12018       if (unformat (i, "sw_if_index %d", &sw_if_index))
12019         sw_if_index_set = 1;
12020       else
12021         break;
12022     }
12023
12024   if (sw_if_index_set == 0)
12025     {
12026       sw_if_index = ~0;
12027     }
12028
12029   if (!vam->json_output)
12030     {
12031       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
12032              "sw_if_index", "local", "remote", "vni",
12033              "protocol", "encap_vrf_id", "decap_vrf_id");
12034     }
12035
12036   /* Get list of vxlan-tunnel interfaces */
12037   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12038
12039   mp->sw_if_index = htonl (sw_if_index);
12040
12041   S (mp);
12042
12043   /* Use a control ping for synchronization */
12044   M (CONTROL_PING, mp_ping);
12045   S (mp_ping);
12046
12047   W (ret);
12048   return ret;
12049 }
12050
12051 u8 *
12052 format_l2_fib_mac_address (u8 * s, va_list * args)
12053 {
12054   u8 *a = va_arg (*args, u8 *);
12055
12056   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12057                  a[2], a[3], a[4], a[5], a[6], a[7]);
12058 }
12059
12060 static void vl_api_l2_fib_table_details_t_handler
12061   (vl_api_l2_fib_table_details_t * mp)
12062 {
12063   vat_main_t *vam = &vat_main;
12064
12065   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12066          "       %d       %d     %d",
12067          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12068          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12069          mp->bvi_mac);
12070 }
12071
12072 static void vl_api_l2_fib_table_details_t_handler_json
12073   (vl_api_l2_fib_table_details_t * mp)
12074 {
12075   vat_main_t *vam = &vat_main;
12076   vat_json_node_t *node = NULL;
12077
12078   if (VAT_JSON_ARRAY != vam->json_tree.type)
12079     {
12080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12081       vat_json_init_array (&vam->json_tree);
12082     }
12083   node = vat_json_array_add (&vam->json_tree);
12084
12085   vat_json_init_object (node);
12086   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12087   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12088   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12089   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12090   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12091   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12092 }
12093
12094 static int
12095 api_l2_fib_table_dump (vat_main_t * vam)
12096 {
12097   unformat_input_t *i = vam->input;
12098   vl_api_l2_fib_table_dump_t *mp;
12099   vl_api_control_ping_t *mp_ping;
12100   u32 bd_id;
12101   u8 bd_id_set = 0;
12102   int ret;
12103
12104   /* Parse args required to build the message */
12105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12106     {
12107       if (unformat (i, "bd_id %d", &bd_id))
12108         bd_id_set = 1;
12109       else
12110         break;
12111     }
12112
12113   if (bd_id_set == 0)
12114     {
12115       errmsg ("missing bridge domain");
12116       return -99;
12117     }
12118
12119   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12120
12121   /* Get list of l2 fib entries */
12122   M (L2_FIB_TABLE_DUMP, mp);
12123
12124   mp->bd_id = ntohl (bd_id);
12125   S (mp);
12126
12127   /* Use a control ping for synchronization */
12128   M (CONTROL_PING, mp_ping);
12129   S (mp_ping);
12130
12131   W (ret);
12132   return ret;
12133 }
12134
12135
12136 static int
12137 api_interface_name_renumber (vat_main_t * vam)
12138 {
12139   unformat_input_t *line_input = vam->input;
12140   vl_api_interface_name_renumber_t *mp;
12141   u32 sw_if_index = ~0;
12142   u32 new_show_dev_instance = ~0;
12143   int ret;
12144
12145   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12146     {
12147       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12148                     &sw_if_index))
12149         ;
12150       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12151         ;
12152       else if (unformat (line_input, "new_show_dev_instance %d",
12153                          &new_show_dev_instance))
12154         ;
12155       else
12156         break;
12157     }
12158
12159   if (sw_if_index == ~0)
12160     {
12161       errmsg ("missing interface name or sw_if_index");
12162       return -99;
12163     }
12164
12165   if (new_show_dev_instance == ~0)
12166     {
12167       errmsg ("missing new_show_dev_instance");
12168       return -99;
12169     }
12170
12171   M (INTERFACE_NAME_RENUMBER, mp);
12172
12173   mp->sw_if_index = ntohl (sw_if_index);
12174   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12175
12176   S (mp);
12177   W (ret);
12178   return ret;
12179 }
12180
12181 static int
12182 api_want_ip4_arp_events (vat_main_t * vam)
12183 {
12184   unformat_input_t *line_input = vam->input;
12185   vl_api_want_ip4_arp_events_t *mp;
12186   ip4_address_t address;
12187   int address_set = 0;
12188   u32 enable_disable = 1;
12189   int ret;
12190
12191   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12192     {
12193       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12194         address_set = 1;
12195       else if (unformat (line_input, "del"))
12196         enable_disable = 0;
12197       else
12198         break;
12199     }
12200
12201   if (address_set == 0)
12202     {
12203       errmsg ("missing addresses");
12204       return -99;
12205     }
12206
12207   M (WANT_IP4_ARP_EVENTS, mp);
12208   mp->enable_disable = enable_disable;
12209   mp->pid = htonl (getpid ());
12210   mp->address = address.as_u32;
12211
12212   S (mp);
12213   W (ret);
12214   return ret;
12215 }
12216
12217 static int
12218 api_want_ip6_nd_events (vat_main_t * vam)
12219 {
12220   unformat_input_t *line_input = vam->input;
12221   vl_api_want_ip6_nd_events_t *mp;
12222   ip6_address_t address;
12223   int address_set = 0;
12224   u32 enable_disable = 1;
12225   int ret;
12226
12227   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12228     {
12229       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12230         address_set = 1;
12231       else if (unformat (line_input, "del"))
12232         enable_disable = 0;
12233       else
12234         break;
12235     }
12236
12237   if (address_set == 0)
12238     {
12239       errmsg ("missing addresses");
12240       return -99;
12241     }
12242
12243   M (WANT_IP6_ND_EVENTS, mp);
12244   mp->enable_disable = enable_disable;
12245   mp->pid = htonl (getpid ());
12246   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12247
12248   S (mp);
12249   W (ret);
12250   return ret;
12251 }
12252
12253 static int
12254 api_input_acl_set_interface (vat_main_t * vam)
12255 {
12256   unformat_input_t *i = vam->input;
12257   vl_api_input_acl_set_interface_t *mp;
12258   u32 sw_if_index;
12259   int sw_if_index_set;
12260   u32 ip4_table_index = ~0;
12261   u32 ip6_table_index = ~0;
12262   u32 l2_table_index = ~0;
12263   u8 is_add = 1;
12264   int ret;
12265
12266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12267     {
12268       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12269         sw_if_index_set = 1;
12270       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12271         sw_if_index_set = 1;
12272       else if (unformat (i, "del"))
12273         is_add = 0;
12274       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12275         ;
12276       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12277         ;
12278       else if (unformat (i, "l2-table %d", &l2_table_index))
12279         ;
12280       else
12281         {
12282           clib_warning ("parse error '%U'", format_unformat_error, i);
12283           return -99;
12284         }
12285     }
12286
12287   if (sw_if_index_set == 0)
12288     {
12289       errmsg ("missing interface name or sw_if_index");
12290       return -99;
12291     }
12292
12293   M (INPUT_ACL_SET_INTERFACE, mp);
12294
12295   mp->sw_if_index = ntohl (sw_if_index);
12296   mp->ip4_table_index = ntohl (ip4_table_index);
12297   mp->ip6_table_index = ntohl (ip6_table_index);
12298   mp->l2_table_index = ntohl (l2_table_index);
12299   mp->is_add = is_add;
12300
12301   S (mp);
12302   W (ret);
12303   return ret;
12304 }
12305
12306 static int
12307 api_ip_address_dump (vat_main_t * vam)
12308 {
12309   unformat_input_t *i = vam->input;
12310   vl_api_ip_address_dump_t *mp;
12311   vl_api_control_ping_t *mp_ping;
12312   u32 sw_if_index = ~0;
12313   u8 sw_if_index_set = 0;
12314   u8 ipv4_set = 0;
12315   u8 ipv6_set = 0;
12316   int ret;
12317
12318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12319     {
12320       if (unformat (i, "sw_if_index %d", &sw_if_index))
12321         sw_if_index_set = 1;
12322       else
12323         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12324         sw_if_index_set = 1;
12325       else if (unformat (i, "ipv4"))
12326         ipv4_set = 1;
12327       else if (unformat (i, "ipv6"))
12328         ipv6_set = 1;
12329       else
12330         break;
12331     }
12332
12333   if (ipv4_set && ipv6_set)
12334     {
12335       errmsg ("ipv4 and ipv6 flags cannot be both set");
12336       return -99;
12337     }
12338
12339   if ((!ipv4_set) && (!ipv6_set))
12340     {
12341       errmsg ("no ipv4 nor ipv6 flag set");
12342       return -99;
12343     }
12344
12345   if (sw_if_index_set == 0)
12346     {
12347       errmsg ("missing interface name or sw_if_index");
12348       return -99;
12349     }
12350
12351   vam->current_sw_if_index = sw_if_index;
12352   vam->is_ipv6 = ipv6_set;
12353
12354   M (IP_ADDRESS_DUMP, mp);
12355   mp->sw_if_index = ntohl (sw_if_index);
12356   mp->is_ipv6 = ipv6_set;
12357   S (mp);
12358
12359   /* Use a control ping for synchronization */
12360   M (CONTROL_PING, mp_ping);
12361   S (mp_ping);
12362
12363   W (ret);
12364   return ret;
12365 }
12366
12367 static int
12368 api_ip_dump (vat_main_t * vam)
12369 {
12370   vl_api_ip_dump_t *mp;
12371   vl_api_control_ping_t *mp_ping;
12372   unformat_input_t *in = vam->input;
12373   int ipv4_set = 0;
12374   int ipv6_set = 0;
12375   int is_ipv6;
12376   int i;
12377   int ret;
12378
12379   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12380     {
12381       if (unformat (in, "ipv4"))
12382         ipv4_set = 1;
12383       else if (unformat (in, "ipv6"))
12384         ipv6_set = 1;
12385       else
12386         break;
12387     }
12388
12389   if (ipv4_set && ipv6_set)
12390     {
12391       errmsg ("ipv4 and ipv6 flags cannot be both set");
12392       return -99;
12393     }
12394
12395   if ((!ipv4_set) && (!ipv6_set))
12396     {
12397       errmsg ("no ipv4 nor ipv6 flag set");
12398       return -99;
12399     }
12400
12401   is_ipv6 = ipv6_set;
12402   vam->is_ipv6 = is_ipv6;
12403
12404   /* free old data */
12405   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12406     {
12407       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12408     }
12409   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12410
12411   M (IP_DUMP, mp);
12412   mp->is_ipv6 = ipv6_set;
12413   S (mp);
12414
12415   /* Use a control ping for synchronization */
12416   M (CONTROL_PING, mp_ping);
12417   S (mp_ping);
12418
12419   W (ret);
12420   return ret;
12421 }
12422
12423 static int
12424 api_ipsec_spd_add_del (vat_main_t * vam)
12425 {
12426   unformat_input_t *i = vam->input;
12427   vl_api_ipsec_spd_add_del_t *mp;
12428   u32 spd_id = ~0;
12429   u8 is_add = 1;
12430   int ret;
12431
12432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12433     {
12434       if (unformat (i, "spd_id %d", &spd_id))
12435         ;
12436       else if (unformat (i, "del"))
12437         is_add = 0;
12438       else
12439         {
12440           clib_warning ("parse error '%U'", format_unformat_error, i);
12441           return -99;
12442         }
12443     }
12444   if (spd_id == ~0)
12445     {
12446       errmsg ("spd_id must be set");
12447       return -99;
12448     }
12449
12450   M (IPSEC_SPD_ADD_DEL, mp);
12451
12452   mp->spd_id = ntohl (spd_id);
12453   mp->is_add = is_add;
12454
12455   S (mp);
12456   W (ret);
12457   return ret;
12458 }
12459
12460 static int
12461 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12462 {
12463   unformat_input_t *i = vam->input;
12464   vl_api_ipsec_interface_add_del_spd_t *mp;
12465   u32 sw_if_index;
12466   u8 sw_if_index_set = 0;
12467   u32 spd_id = (u32) ~ 0;
12468   u8 is_add = 1;
12469   int ret;
12470
12471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12472     {
12473       if (unformat (i, "del"))
12474         is_add = 0;
12475       else if (unformat (i, "spd_id %d", &spd_id))
12476         ;
12477       else
12478         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12479         sw_if_index_set = 1;
12480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12481         sw_if_index_set = 1;
12482       else
12483         {
12484           clib_warning ("parse error '%U'", format_unformat_error, i);
12485           return -99;
12486         }
12487
12488     }
12489
12490   if (spd_id == (u32) ~ 0)
12491     {
12492       errmsg ("spd_id must be set");
12493       return -99;
12494     }
12495
12496   if (sw_if_index_set == 0)
12497     {
12498       errmsg ("missing interface name or sw_if_index");
12499       return -99;
12500     }
12501
12502   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12503
12504   mp->spd_id = ntohl (spd_id);
12505   mp->sw_if_index = ntohl (sw_if_index);
12506   mp->is_add = is_add;
12507
12508   S (mp);
12509   W (ret);
12510   return ret;
12511 }
12512
12513 static int
12514 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12515 {
12516   unformat_input_t *i = vam->input;
12517   vl_api_ipsec_spd_add_del_entry_t *mp;
12518   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12519   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12520   i32 priority = 0;
12521   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12522   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12523   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12524   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12525   int ret;
12526
12527   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12528   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12529   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12530   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12531   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12532   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12533
12534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12535     {
12536       if (unformat (i, "del"))
12537         is_add = 0;
12538       if (unformat (i, "outbound"))
12539         is_outbound = 1;
12540       if (unformat (i, "inbound"))
12541         is_outbound = 0;
12542       else if (unformat (i, "spd_id %d", &spd_id))
12543         ;
12544       else if (unformat (i, "sa_id %d", &sa_id))
12545         ;
12546       else if (unformat (i, "priority %d", &priority))
12547         ;
12548       else if (unformat (i, "protocol %d", &protocol))
12549         ;
12550       else if (unformat (i, "lport_start %d", &lport_start))
12551         ;
12552       else if (unformat (i, "lport_stop %d", &lport_stop))
12553         ;
12554       else if (unformat (i, "rport_start %d", &rport_start))
12555         ;
12556       else if (unformat (i, "rport_stop %d", &rport_stop))
12557         ;
12558       else
12559         if (unformat
12560             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12561         {
12562           is_ipv6 = 0;
12563           is_ip_any = 0;
12564         }
12565       else
12566         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12567         {
12568           is_ipv6 = 0;
12569           is_ip_any = 0;
12570         }
12571       else
12572         if (unformat
12573             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12574         {
12575           is_ipv6 = 0;
12576           is_ip_any = 0;
12577         }
12578       else
12579         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12580         {
12581           is_ipv6 = 0;
12582           is_ip_any = 0;
12583         }
12584       else
12585         if (unformat
12586             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12587         {
12588           is_ipv6 = 1;
12589           is_ip_any = 0;
12590         }
12591       else
12592         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12593         {
12594           is_ipv6 = 1;
12595           is_ip_any = 0;
12596         }
12597       else
12598         if (unformat
12599             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12600         {
12601           is_ipv6 = 1;
12602           is_ip_any = 0;
12603         }
12604       else
12605         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12606         {
12607           is_ipv6 = 1;
12608           is_ip_any = 0;
12609         }
12610       else
12611         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12612         {
12613           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12614             {
12615               clib_warning ("unsupported action: 'resolve'");
12616               return -99;
12617             }
12618         }
12619       else
12620         {
12621           clib_warning ("parse error '%U'", format_unformat_error, i);
12622           return -99;
12623         }
12624
12625     }
12626
12627   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12628
12629   mp->spd_id = ntohl (spd_id);
12630   mp->priority = ntohl (priority);
12631   mp->is_outbound = is_outbound;
12632
12633   mp->is_ipv6 = is_ipv6;
12634   if (is_ipv6 || is_ip_any)
12635     {
12636       clib_memcpy (mp->remote_address_start, &raddr6_start,
12637                    sizeof (ip6_address_t));
12638       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12639                    sizeof (ip6_address_t));
12640       clib_memcpy (mp->local_address_start, &laddr6_start,
12641                    sizeof (ip6_address_t));
12642       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12643                    sizeof (ip6_address_t));
12644     }
12645   else
12646     {
12647       clib_memcpy (mp->remote_address_start, &raddr4_start,
12648                    sizeof (ip4_address_t));
12649       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12650                    sizeof (ip4_address_t));
12651       clib_memcpy (mp->local_address_start, &laddr4_start,
12652                    sizeof (ip4_address_t));
12653       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12654                    sizeof (ip4_address_t));
12655     }
12656   mp->protocol = (u8) protocol;
12657   mp->local_port_start = ntohs ((u16) lport_start);
12658   mp->local_port_stop = ntohs ((u16) lport_stop);
12659   mp->remote_port_start = ntohs ((u16) rport_start);
12660   mp->remote_port_stop = ntohs ((u16) rport_stop);
12661   mp->policy = (u8) policy;
12662   mp->sa_id = ntohl (sa_id);
12663   mp->is_add = is_add;
12664   mp->is_ip_any = is_ip_any;
12665   S (mp);
12666   W (ret);
12667   return ret;
12668 }
12669
12670 static int
12671 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12672 {
12673   unformat_input_t *i = vam->input;
12674   vl_api_ipsec_sad_add_del_entry_t *mp;
12675   u32 sad_id = 0, spi = 0;
12676   u8 *ck = 0, *ik = 0;
12677   u8 is_add = 1;
12678
12679   u8 protocol = IPSEC_PROTOCOL_AH;
12680   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12681   u32 crypto_alg = 0, integ_alg = 0;
12682   ip4_address_t tun_src4;
12683   ip4_address_t tun_dst4;
12684   ip6_address_t tun_src6;
12685   ip6_address_t tun_dst6;
12686   int ret;
12687
12688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (i, "del"))
12691         is_add = 0;
12692       else if (unformat (i, "sad_id %d", &sad_id))
12693         ;
12694       else if (unformat (i, "spi %d", &spi))
12695         ;
12696       else if (unformat (i, "esp"))
12697         protocol = IPSEC_PROTOCOL_ESP;
12698       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12699         {
12700           is_tunnel = 1;
12701           is_tunnel_ipv6 = 0;
12702         }
12703       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12704         {
12705           is_tunnel = 1;
12706           is_tunnel_ipv6 = 0;
12707         }
12708       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12709         {
12710           is_tunnel = 1;
12711           is_tunnel_ipv6 = 1;
12712         }
12713       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12714         {
12715           is_tunnel = 1;
12716           is_tunnel_ipv6 = 1;
12717         }
12718       else
12719         if (unformat
12720             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12721         {
12722           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12723               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12724             {
12725               clib_warning ("unsupported crypto-alg: '%U'",
12726                             format_ipsec_crypto_alg, crypto_alg);
12727               return -99;
12728             }
12729         }
12730       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12731         ;
12732       else
12733         if (unformat
12734             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12735         {
12736           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12737               integ_alg >= IPSEC_INTEG_N_ALG)
12738             {
12739               clib_warning ("unsupported integ-alg: '%U'",
12740                             format_ipsec_integ_alg, integ_alg);
12741               return -99;
12742             }
12743         }
12744       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12745         ;
12746       else
12747         {
12748           clib_warning ("parse error '%U'", format_unformat_error, i);
12749           return -99;
12750         }
12751
12752     }
12753
12754   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12755
12756   mp->sad_id = ntohl (sad_id);
12757   mp->is_add = is_add;
12758   mp->protocol = protocol;
12759   mp->spi = ntohl (spi);
12760   mp->is_tunnel = is_tunnel;
12761   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12762   mp->crypto_algorithm = crypto_alg;
12763   mp->integrity_algorithm = integ_alg;
12764   mp->crypto_key_length = vec_len (ck);
12765   mp->integrity_key_length = vec_len (ik);
12766
12767   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12768     mp->crypto_key_length = sizeof (mp->crypto_key);
12769
12770   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12771     mp->integrity_key_length = sizeof (mp->integrity_key);
12772
12773   if (ck)
12774     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12775   if (ik)
12776     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12777
12778   if (is_tunnel)
12779     {
12780       if (is_tunnel_ipv6)
12781         {
12782           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12783                        sizeof (ip6_address_t));
12784           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12785                        sizeof (ip6_address_t));
12786         }
12787       else
12788         {
12789           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12790                        sizeof (ip4_address_t));
12791           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12792                        sizeof (ip4_address_t));
12793         }
12794     }
12795
12796   S (mp);
12797   W (ret);
12798   return ret;
12799 }
12800
12801 static int
12802 api_ipsec_sa_set_key (vat_main_t * vam)
12803 {
12804   unformat_input_t *i = vam->input;
12805   vl_api_ipsec_sa_set_key_t *mp;
12806   u32 sa_id;
12807   u8 *ck = 0, *ik = 0;
12808   int ret;
12809
12810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12811     {
12812       if (unformat (i, "sa_id %d", &sa_id))
12813         ;
12814       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12815         ;
12816       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12817         ;
12818       else
12819         {
12820           clib_warning ("parse error '%U'", format_unformat_error, i);
12821           return -99;
12822         }
12823     }
12824
12825   M (IPSEC_SA_SET_KEY, mp);
12826
12827   mp->sa_id = ntohl (sa_id);
12828   mp->crypto_key_length = vec_len (ck);
12829   mp->integrity_key_length = vec_len (ik);
12830
12831   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12832     mp->crypto_key_length = sizeof (mp->crypto_key);
12833
12834   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12835     mp->integrity_key_length = sizeof (mp->integrity_key);
12836
12837   if (ck)
12838     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12839   if (ik)
12840     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12841
12842   S (mp);
12843   W (ret);
12844   return ret;
12845 }
12846
12847 static int
12848 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12849 {
12850   unformat_input_t *i = vam->input;
12851   vl_api_ipsec_tunnel_if_add_del_t *mp;
12852   u32 local_spi = 0, remote_spi = 0;
12853   u32 crypto_alg = 0, integ_alg = 0;
12854   u8 *lck = NULL, *rck = NULL;
12855   u8 *lik = NULL, *rik = NULL;
12856   ip4_address_t local_ip = { {0} };
12857   ip4_address_t remote_ip = { {0} };
12858   u8 is_add = 1;
12859   u8 esn = 0;
12860   u8 anti_replay = 0;
12861   int ret;
12862
12863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12864     {
12865       if (unformat (i, "del"))
12866         is_add = 0;
12867       else if (unformat (i, "esn"))
12868         esn = 1;
12869       else if (unformat (i, "anti_replay"))
12870         anti_replay = 1;
12871       else if (unformat (i, "local_spi %d", &local_spi))
12872         ;
12873       else if (unformat (i, "remote_spi %d", &remote_spi))
12874         ;
12875       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12876         ;
12877       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12878         ;
12879       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12880         ;
12881       else
12882         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12883         ;
12884       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12885         ;
12886       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12887         ;
12888       else
12889         if (unformat
12890             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12891         {
12892           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12893               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12894             {
12895               errmsg ("unsupported crypto-alg: '%U'\n",
12896                       format_ipsec_crypto_alg, crypto_alg);
12897               return -99;
12898             }
12899         }
12900       else
12901         if (unformat
12902             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12903         {
12904           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12905               integ_alg >= IPSEC_INTEG_N_ALG)
12906             {
12907               errmsg ("unsupported integ-alg: '%U'\n",
12908                       format_ipsec_integ_alg, integ_alg);
12909               return -99;
12910             }
12911         }
12912       else
12913         {
12914           errmsg ("parse error '%U'\n", format_unformat_error, i);
12915           return -99;
12916         }
12917     }
12918
12919   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12920
12921   mp->is_add = is_add;
12922   mp->esn = esn;
12923   mp->anti_replay = anti_replay;
12924
12925   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12926   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12927
12928   mp->local_spi = htonl (local_spi);
12929   mp->remote_spi = htonl (remote_spi);
12930   mp->crypto_alg = (u8) crypto_alg;
12931
12932   mp->local_crypto_key_len = 0;
12933   if (lck)
12934     {
12935       mp->local_crypto_key_len = vec_len (lck);
12936       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12937         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12938       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12939     }
12940
12941   mp->remote_crypto_key_len = 0;
12942   if (rck)
12943     {
12944       mp->remote_crypto_key_len = vec_len (rck);
12945       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12946         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12947       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12948     }
12949
12950   mp->integ_alg = (u8) integ_alg;
12951
12952   mp->local_integ_key_len = 0;
12953   if (lik)
12954     {
12955       mp->local_integ_key_len = vec_len (lik);
12956       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12957         mp->local_integ_key_len = sizeof (mp->local_integ_key);
12958       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12959     }
12960
12961   mp->remote_integ_key_len = 0;
12962   if (rik)
12963     {
12964       mp->remote_integ_key_len = vec_len (rik);
12965       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12966         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12967       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12968     }
12969
12970   S (mp);
12971   W (ret);
12972   return ret;
12973 }
12974
12975 static int
12976 api_ikev2_profile_add_del (vat_main_t * vam)
12977 {
12978   unformat_input_t *i = vam->input;
12979   vl_api_ikev2_profile_add_del_t *mp;
12980   u8 is_add = 1;
12981   u8 *name = 0;
12982   int ret;
12983
12984   const char *valid_chars = "a-zA-Z0-9_";
12985
12986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12987     {
12988       if (unformat (i, "del"))
12989         is_add = 0;
12990       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12991         vec_add1 (name, 0);
12992       else
12993         {
12994           errmsg ("parse error '%U'", format_unformat_error, i);
12995           return -99;
12996         }
12997     }
12998
12999   if (!vec_len (name))
13000     {
13001       errmsg ("profile name must be specified");
13002       return -99;
13003     }
13004
13005   if (vec_len (name) > 64)
13006     {
13007       errmsg ("profile name too long");
13008       return -99;
13009     }
13010
13011   M (IKEV2_PROFILE_ADD_DEL, mp);
13012
13013   clib_memcpy (mp->name, name, vec_len (name));
13014   mp->is_add = is_add;
13015   vec_free (name);
13016
13017   S (mp);
13018   W (ret);
13019   return ret;
13020 }
13021
13022 static int
13023 api_ikev2_profile_set_auth (vat_main_t * vam)
13024 {
13025   unformat_input_t *i = vam->input;
13026   vl_api_ikev2_profile_set_auth_t *mp;
13027   u8 *name = 0;
13028   u8 *data = 0;
13029   u32 auth_method = 0;
13030   u8 is_hex = 0;
13031   int ret;
13032
13033   const char *valid_chars = "a-zA-Z0-9_";
13034
13035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13036     {
13037       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13038         vec_add1 (name, 0);
13039       else if (unformat (i, "auth_method %U",
13040                          unformat_ikev2_auth_method, &auth_method))
13041         ;
13042       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13043         is_hex = 1;
13044       else if (unformat (i, "auth_data %v", &data))
13045         ;
13046       else
13047         {
13048           errmsg ("parse error '%U'", format_unformat_error, i);
13049           return -99;
13050         }
13051     }
13052
13053   if (!vec_len (name))
13054     {
13055       errmsg ("profile name must be specified");
13056       return -99;
13057     }
13058
13059   if (vec_len (name) > 64)
13060     {
13061       errmsg ("profile name too long");
13062       return -99;
13063     }
13064
13065   if (!vec_len (data))
13066     {
13067       errmsg ("auth_data must be specified");
13068       return -99;
13069     }
13070
13071   if (!auth_method)
13072     {
13073       errmsg ("auth_method must be specified");
13074       return -99;
13075     }
13076
13077   M (IKEV2_PROFILE_SET_AUTH, mp);
13078
13079   mp->is_hex = is_hex;
13080   mp->auth_method = (u8) auth_method;
13081   mp->data_len = vec_len (data);
13082   clib_memcpy (mp->name, name, vec_len (name));
13083   clib_memcpy (mp->data, data, vec_len (data));
13084   vec_free (name);
13085   vec_free (data);
13086
13087   S (mp);
13088   W (ret);
13089   return ret;
13090 }
13091
13092 static int
13093 api_ikev2_profile_set_id (vat_main_t * vam)
13094 {
13095   unformat_input_t *i = vam->input;
13096   vl_api_ikev2_profile_set_id_t *mp;
13097   u8 *name = 0;
13098   u8 *data = 0;
13099   u8 is_local = 0;
13100   u32 id_type = 0;
13101   ip4_address_t ip4;
13102   int ret;
13103
13104   const char *valid_chars = "a-zA-Z0-9_";
13105
13106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13107     {
13108       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13109         vec_add1 (name, 0);
13110       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13111         ;
13112       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13113         {
13114           data = vec_new (u8, 4);
13115           clib_memcpy (data, ip4.as_u8, 4);
13116         }
13117       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13118         ;
13119       else if (unformat (i, "id_data %v", &data))
13120         ;
13121       else if (unformat (i, "local"))
13122         is_local = 1;
13123       else if (unformat (i, "remote"))
13124         is_local = 0;
13125       else
13126         {
13127           errmsg ("parse error '%U'", format_unformat_error, i);
13128           return -99;
13129         }
13130     }
13131
13132   if (!vec_len (name))
13133     {
13134       errmsg ("profile name must be specified");
13135       return -99;
13136     }
13137
13138   if (vec_len (name) > 64)
13139     {
13140       errmsg ("profile name too long");
13141       return -99;
13142     }
13143
13144   if (!vec_len (data))
13145     {
13146       errmsg ("id_data must be specified");
13147       return -99;
13148     }
13149
13150   if (!id_type)
13151     {
13152       errmsg ("id_type must be specified");
13153       return -99;
13154     }
13155
13156   M (IKEV2_PROFILE_SET_ID, mp);
13157
13158   mp->is_local = is_local;
13159   mp->id_type = (u8) id_type;
13160   mp->data_len = vec_len (data);
13161   clib_memcpy (mp->name, name, vec_len (name));
13162   clib_memcpy (mp->data, data, vec_len (data));
13163   vec_free (name);
13164   vec_free (data);
13165
13166   S (mp);
13167   W (ret);
13168   return ret;
13169 }
13170
13171 static int
13172 api_ikev2_profile_set_ts (vat_main_t * vam)
13173 {
13174   unformat_input_t *i = vam->input;
13175   vl_api_ikev2_profile_set_ts_t *mp;
13176   u8 *name = 0;
13177   u8 is_local = 0;
13178   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13179   ip4_address_t start_addr, end_addr;
13180
13181   const char *valid_chars = "a-zA-Z0-9_";
13182   int ret;
13183
13184   start_addr.as_u32 = 0;
13185   end_addr.as_u32 = (u32) ~ 0;
13186
13187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13188     {
13189       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13190         vec_add1 (name, 0);
13191       else if (unformat (i, "protocol %d", &proto))
13192         ;
13193       else if (unformat (i, "start_port %d", &start_port))
13194         ;
13195       else if (unformat (i, "end_port %d", &end_port))
13196         ;
13197       else
13198         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13199         ;
13200       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13201         ;
13202       else if (unformat (i, "local"))
13203         is_local = 1;
13204       else if (unformat (i, "remote"))
13205         is_local = 0;
13206       else
13207         {
13208           errmsg ("parse error '%U'", format_unformat_error, i);
13209           return -99;
13210         }
13211     }
13212
13213   if (!vec_len (name))
13214     {
13215       errmsg ("profile name must be specified");
13216       return -99;
13217     }
13218
13219   if (vec_len (name) > 64)
13220     {
13221       errmsg ("profile name too long");
13222       return -99;
13223     }
13224
13225   M (IKEV2_PROFILE_SET_TS, mp);
13226
13227   mp->is_local = is_local;
13228   mp->proto = (u8) proto;
13229   mp->start_port = (u16) start_port;
13230   mp->end_port = (u16) end_port;
13231   mp->start_addr = start_addr.as_u32;
13232   mp->end_addr = end_addr.as_u32;
13233   clib_memcpy (mp->name, name, vec_len (name));
13234   vec_free (name);
13235
13236   S (mp);
13237   W (ret);
13238   return ret;
13239 }
13240
13241 static int
13242 api_ikev2_set_local_key (vat_main_t * vam)
13243 {
13244   unformat_input_t *i = vam->input;
13245   vl_api_ikev2_set_local_key_t *mp;
13246   u8 *file = 0;
13247   int ret;
13248
13249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13250     {
13251       if (unformat (i, "file %v", &file))
13252         vec_add1 (file, 0);
13253       else
13254         {
13255           errmsg ("parse error '%U'", format_unformat_error, i);
13256           return -99;
13257         }
13258     }
13259
13260   if (!vec_len (file))
13261     {
13262       errmsg ("RSA key file must be specified");
13263       return -99;
13264     }
13265
13266   if (vec_len (file) > 256)
13267     {
13268       errmsg ("file name too long");
13269       return -99;
13270     }
13271
13272   M (IKEV2_SET_LOCAL_KEY, mp);
13273
13274   clib_memcpy (mp->key_file, file, vec_len (file));
13275   vec_free (file);
13276
13277   S (mp);
13278   W (ret);
13279   return ret;
13280 }
13281
13282 static int
13283 api_ikev2_set_responder (vat_main_t * vam)
13284 {
13285   unformat_input_t *i = vam->input;
13286   vl_api_ikev2_set_responder_t *mp;
13287   int ret;
13288   u8 *name = 0;
13289   u32 sw_if_index = ~0;
13290   ip4_address_t address;
13291
13292   const char *valid_chars = "a-zA-Z0-9_";
13293
13294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13295     {
13296       if (unformat
13297           (i, "%U interface %d address %U", unformat_token, valid_chars,
13298            &name, &sw_if_index, unformat_ip4_address, &address))
13299         vec_add1 (name, 0);
13300       else
13301         {
13302           errmsg ("parse error '%U'", format_unformat_error, i);
13303           return -99;
13304         }
13305     }
13306
13307   if (!vec_len (name))
13308     {
13309       errmsg ("profile name must be specified");
13310       return -99;
13311     }
13312
13313   if (vec_len (name) > 64)
13314     {
13315       errmsg ("profile name too long");
13316       return -99;
13317     }
13318
13319   M (IKEV2_SET_RESPONDER, mp);
13320
13321   clib_memcpy (mp->name, name, vec_len (name));
13322   vec_free (name);
13323
13324   mp->sw_if_index = sw_if_index;
13325   clib_memcpy (mp->address, &address, sizeof (address));
13326
13327   S (mp);
13328   W (ret);
13329   return ret;
13330 }
13331
13332 static int
13333 api_ikev2_set_ike_transforms (vat_main_t * vam)
13334 {
13335   unformat_input_t *i = vam->input;
13336   vl_api_ikev2_set_ike_transforms_t *mp;
13337   int ret;
13338   u8 *name = 0;
13339   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13340
13341   const char *valid_chars = "a-zA-Z0-9_";
13342
13343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13344     {
13345       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13346                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13347         vec_add1 (name, 0);
13348       else
13349         {
13350           errmsg ("parse error '%U'", format_unformat_error, i);
13351           return -99;
13352         }
13353     }
13354
13355   if (!vec_len (name))
13356     {
13357       errmsg ("profile name must be specified");
13358       return -99;
13359     }
13360
13361   if (vec_len (name) > 64)
13362     {
13363       errmsg ("profile name too long");
13364       return -99;
13365     }
13366
13367   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13368
13369   clib_memcpy (mp->name, name, vec_len (name));
13370   vec_free (name);
13371   mp->crypto_alg = crypto_alg;
13372   mp->crypto_key_size = crypto_key_size;
13373   mp->integ_alg = integ_alg;
13374   mp->dh_group = dh_group;
13375
13376   S (mp);
13377   W (ret);
13378   return ret;
13379 }
13380
13381
13382 static int
13383 api_ikev2_set_esp_transforms (vat_main_t * vam)
13384 {
13385   unformat_input_t *i = vam->input;
13386   vl_api_ikev2_set_esp_transforms_t *mp;
13387   int ret;
13388   u8 *name = 0;
13389   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13390
13391   const char *valid_chars = "a-zA-Z0-9_";
13392
13393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13394     {
13395       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13396                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13397         vec_add1 (name, 0);
13398       else
13399         {
13400           errmsg ("parse error '%U'", format_unformat_error, i);
13401           return -99;
13402         }
13403     }
13404
13405   if (!vec_len (name))
13406     {
13407       errmsg ("profile name must be specified");
13408       return -99;
13409     }
13410
13411   if (vec_len (name) > 64)
13412     {
13413       errmsg ("profile name too long");
13414       return -99;
13415     }
13416
13417   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13418
13419   clib_memcpy (mp->name, name, vec_len (name));
13420   vec_free (name);
13421   mp->crypto_alg = crypto_alg;
13422   mp->crypto_key_size = crypto_key_size;
13423   mp->integ_alg = integ_alg;
13424   mp->dh_group = dh_group;
13425
13426   S (mp);
13427   W (ret);
13428   return ret;
13429 }
13430
13431 static int
13432 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13433 {
13434   unformat_input_t *i = vam->input;
13435   vl_api_ikev2_set_sa_lifetime_t *mp;
13436   int ret;
13437   u8 *name = 0;
13438   u64 lifetime, lifetime_maxdata;
13439   u32 lifetime_jitter, handover;
13440
13441   const char *valid_chars = "a-zA-Z0-9_";
13442
13443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13444     {
13445       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13446                     &lifetime, &lifetime_jitter, &handover,
13447                     &lifetime_maxdata))
13448         vec_add1 (name, 0);
13449       else
13450         {
13451           errmsg ("parse error '%U'", format_unformat_error, i);
13452           return -99;
13453         }
13454     }
13455
13456   if (!vec_len (name))
13457     {
13458       errmsg ("profile name must be specified");
13459       return -99;
13460     }
13461
13462   if (vec_len (name) > 64)
13463     {
13464       errmsg ("profile name too long");
13465       return -99;
13466     }
13467
13468   M (IKEV2_SET_SA_LIFETIME, mp);
13469
13470   clib_memcpy (mp->name, name, vec_len (name));
13471   vec_free (name);
13472   mp->lifetime = lifetime;
13473   mp->lifetime_jitter = lifetime_jitter;
13474   mp->handover = handover;
13475   mp->lifetime_maxdata = lifetime_maxdata;
13476
13477   S (mp);
13478   W (ret);
13479   return ret;
13480 }
13481
13482 static int
13483 api_ikev2_initiate_sa_init (vat_main_t * vam)
13484 {
13485   unformat_input_t *i = vam->input;
13486   vl_api_ikev2_initiate_sa_init_t *mp;
13487   int ret;
13488   u8 *name = 0;
13489
13490   const char *valid_chars = "a-zA-Z0-9_";
13491
13492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13493     {
13494       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13495         vec_add1 (name, 0);
13496       else
13497         {
13498           errmsg ("parse error '%U'", format_unformat_error, i);
13499           return -99;
13500         }
13501     }
13502
13503   if (!vec_len (name))
13504     {
13505       errmsg ("profile name must be specified");
13506       return -99;
13507     }
13508
13509   if (vec_len (name) > 64)
13510     {
13511       errmsg ("profile name too long");
13512       return -99;
13513     }
13514
13515   M (IKEV2_INITIATE_SA_INIT, mp);
13516
13517   clib_memcpy (mp->name, name, vec_len (name));
13518   vec_free (name);
13519
13520   S (mp);
13521   W (ret);
13522   return ret;
13523 }
13524
13525 static int
13526 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13527 {
13528   unformat_input_t *i = vam->input;
13529   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13530   int ret;
13531   u64 ispi;
13532
13533
13534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13535     {
13536       if (unformat (i, "%lx", &ispi))
13537         ;
13538       else
13539         {
13540           errmsg ("parse error '%U'", format_unformat_error, i);
13541           return -99;
13542         }
13543     }
13544
13545   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13546
13547   mp->ispi = ispi;
13548
13549   S (mp);
13550   W (ret);
13551   return ret;
13552 }
13553
13554 static int
13555 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13556 {
13557   unformat_input_t *i = vam->input;
13558   vl_api_ikev2_initiate_del_child_sa_t *mp;
13559   int ret;
13560   u32 ispi;
13561
13562
13563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13564     {
13565       if (unformat (i, "%x", &ispi))
13566         ;
13567       else
13568         {
13569           errmsg ("parse error '%U'", format_unformat_error, i);
13570           return -99;
13571         }
13572     }
13573
13574   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13575
13576   mp->ispi = ispi;
13577
13578   S (mp);
13579   W (ret);
13580   return ret;
13581 }
13582
13583 static int
13584 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13585 {
13586   unformat_input_t *i = vam->input;
13587   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13588   int ret;
13589   u32 ispi;
13590
13591
13592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13593     {
13594       if (unformat (i, "%x", &ispi))
13595         ;
13596       else
13597         {
13598           errmsg ("parse error '%U'", format_unformat_error, i);
13599           return -99;
13600         }
13601     }
13602
13603   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13604
13605   mp->ispi = ispi;
13606
13607   S (mp);
13608   W (ret);
13609   return ret;
13610 }
13611
13612 /*
13613  * MAP
13614  */
13615 static int
13616 api_map_add_domain (vat_main_t * vam)
13617 {
13618   unformat_input_t *i = vam->input;
13619   vl_api_map_add_domain_t *mp;
13620
13621   ip4_address_t ip4_prefix;
13622   ip6_address_t ip6_prefix;
13623   ip6_address_t ip6_src;
13624   u32 num_m_args = 0;
13625   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13626     0, psid_length = 0;
13627   u8 is_translation = 0;
13628   u32 mtu = 0;
13629   u32 ip6_src_len = 128;
13630   int ret;
13631
13632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13633     {
13634       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13635                     &ip4_prefix, &ip4_prefix_len))
13636         num_m_args++;
13637       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13638                          &ip6_prefix, &ip6_prefix_len))
13639         num_m_args++;
13640       else
13641         if (unformat
13642             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13643              &ip6_src_len))
13644         num_m_args++;
13645       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13646         num_m_args++;
13647       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13648         num_m_args++;
13649       else if (unformat (i, "psid-offset %d", &psid_offset))
13650         num_m_args++;
13651       else if (unformat (i, "psid-len %d", &psid_length))
13652         num_m_args++;
13653       else if (unformat (i, "mtu %d", &mtu))
13654         num_m_args++;
13655       else if (unformat (i, "map-t"))
13656         is_translation = 1;
13657       else
13658         {
13659           clib_warning ("parse error '%U'", format_unformat_error, i);
13660           return -99;
13661         }
13662     }
13663
13664   if (num_m_args < 3)
13665     {
13666       errmsg ("mandatory argument(s) missing");
13667       return -99;
13668     }
13669
13670   /* Construct the API message */
13671   M (MAP_ADD_DOMAIN, mp);
13672
13673   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13674   mp->ip4_prefix_len = ip4_prefix_len;
13675
13676   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13677   mp->ip6_prefix_len = ip6_prefix_len;
13678
13679   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13680   mp->ip6_src_prefix_len = ip6_src_len;
13681
13682   mp->ea_bits_len = ea_bits_len;
13683   mp->psid_offset = psid_offset;
13684   mp->psid_length = psid_length;
13685   mp->is_translation = is_translation;
13686   mp->mtu = htons (mtu);
13687
13688   /* send it... */
13689   S (mp);
13690
13691   /* Wait for a reply, return good/bad news  */
13692   W (ret);
13693   return ret;
13694 }
13695
13696 static int
13697 api_map_del_domain (vat_main_t * vam)
13698 {
13699   unformat_input_t *i = vam->input;
13700   vl_api_map_del_domain_t *mp;
13701
13702   u32 num_m_args = 0;
13703   u32 index;
13704   int ret;
13705
13706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13707     {
13708       if (unformat (i, "index %d", &index))
13709         num_m_args++;
13710       else
13711         {
13712           clib_warning ("parse error '%U'", format_unformat_error, i);
13713           return -99;
13714         }
13715     }
13716
13717   if (num_m_args != 1)
13718     {
13719       errmsg ("mandatory argument(s) missing");
13720       return -99;
13721     }
13722
13723   /* Construct the API message */
13724   M (MAP_DEL_DOMAIN, mp);
13725
13726   mp->index = ntohl (index);
13727
13728   /* send it... */
13729   S (mp);
13730
13731   /* Wait for a reply, return good/bad news  */
13732   W (ret);
13733   return ret;
13734 }
13735
13736 static int
13737 api_map_add_del_rule (vat_main_t * vam)
13738 {
13739   unformat_input_t *i = vam->input;
13740   vl_api_map_add_del_rule_t *mp;
13741   u8 is_add = 1;
13742   ip6_address_t ip6_dst;
13743   u32 num_m_args = 0, index, psid = 0;
13744   int ret;
13745
13746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13747     {
13748       if (unformat (i, "index %d", &index))
13749         num_m_args++;
13750       else if (unformat (i, "psid %d", &psid))
13751         num_m_args++;
13752       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13753         num_m_args++;
13754       else if (unformat (i, "del"))
13755         {
13756           is_add = 0;
13757         }
13758       else
13759         {
13760           clib_warning ("parse error '%U'", format_unformat_error, i);
13761           return -99;
13762         }
13763     }
13764
13765   /* Construct the API message */
13766   M (MAP_ADD_DEL_RULE, mp);
13767
13768   mp->index = ntohl (index);
13769   mp->is_add = is_add;
13770   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13771   mp->psid = ntohs (psid);
13772
13773   /* send it... */
13774   S (mp);
13775
13776   /* Wait for a reply, return good/bad news  */
13777   W (ret);
13778   return ret;
13779 }
13780
13781 static int
13782 api_map_domain_dump (vat_main_t * vam)
13783 {
13784   vl_api_map_domain_dump_t *mp;
13785   vl_api_control_ping_t *mp_ping;
13786   int ret;
13787
13788   /* Construct the API message */
13789   M (MAP_DOMAIN_DUMP, mp);
13790
13791   /* send it... */
13792   S (mp);
13793
13794   /* Use a control ping for synchronization */
13795   M (CONTROL_PING, mp_ping);
13796   S (mp_ping);
13797
13798   W (ret);
13799   return ret;
13800 }
13801
13802 static int
13803 api_map_rule_dump (vat_main_t * vam)
13804 {
13805   unformat_input_t *i = vam->input;
13806   vl_api_map_rule_dump_t *mp;
13807   vl_api_control_ping_t *mp_ping;
13808   u32 domain_index = ~0;
13809   int ret;
13810
13811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13812     {
13813       if (unformat (i, "index %u", &domain_index))
13814         ;
13815       else
13816         break;
13817     }
13818
13819   if (domain_index == ~0)
13820     {
13821       clib_warning ("parse error: domain index expected");
13822       return -99;
13823     }
13824
13825   /* Construct the API message */
13826   M (MAP_RULE_DUMP, mp);
13827
13828   mp->domain_index = htonl (domain_index);
13829
13830   /* send it... */
13831   S (mp);
13832
13833   /* Use a control ping for synchronization */
13834   M (CONTROL_PING, mp_ping);
13835   S (mp_ping);
13836
13837   W (ret);
13838   return ret;
13839 }
13840
13841 static void vl_api_map_add_domain_reply_t_handler
13842   (vl_api_map_add_domain_reply_t * mp)
13843 {
13844   vat_main_t *vam = &vat_main;
13845   i32 retval = ntohl (mp->retval);
13846
13847   if (vam->async_mode)
13848     {
13849       vam->async_errors += (retval < 0);
13850     }
13851   else
13852     {
13853       vam->retval = retval;
13854       vam->result_ready = 1;
13855     }
13856 }
13857
13858 static void vl_api_map_add_domain_reply_t_handler_json
13859   (vl_api_map_add_domain_reply_t * mp)
13860 {
13861   vat_main_t *vam = &vat_main;
13862   vat_json_node_t node;
13863
13864   vat_json_init_object (&node);
13865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13866   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13867
13868   vat_json_print (vam->ofp, &node);
13869   vat_json_free (&node);
13870
13871   vam->retval = ntohl (mp->retval);
13872   vam->result_ready = 1;
13873 }
13874
13875 static int
13876 api_get_first_msg_id (vat_main_t * vam)
13877 {
13878   vl_api_get_first_msg_id_t *mp;
13879   unformat_input_t *i = vam->input;
13880   u8 *name;
13881   u8 name_set = 0;
13882   int ret;
13883
13884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13885     {
13886       if (unformat (i, "client %s", &name))
13887         name_set = 1;
13888       else
13889         break;
13890     }
13891
13892   if (name_set == 0)
13893     {
13894       errmsg ("missing client name");
13895       return -99;
13896     }
13897   vec_add1 (name, 0);
13898
13899   if (vec_len (name) > 63)
13900     {
13901       errmsg ("client name too long");
13902       return -99;
13903     }
13904
13905   M (GET_FIRST_MSG_ID, mp);
13906   clib_memcpy (mp->name, name, vec_len (name));
13907   S (mp);
13908   W (ret);
13909   return ret;
13910 }
13911
13912 static int
13913 api_cop_interface_enable_disable (vat_main_t * vam)
13914 {
13915   unformat_input_t *line_input = vam->input;
13916   vl_api_cop_interface_enable_disable_t *mp;
13917   u32 sw_if_index = ~0;
13918   u8 enable_disable = 1;
13919   int ret;
13920
13921   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13922     {
13923       if (unformat (line_input, "disable"))
13924         enable_disable = 0;
13925       if (unformat (line_input, "enable"))
13926         enable_disable = 1;
13927       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13928                          vam, &sw_if_index))
13929         ;
13930       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13931         ;
13932       else
13933         break;
13934     }
13935
13936   if (sw_if_index == ~0)
13937     {
13938       errmsg ("missing interface name or sw_if_index");
13939       return -99;
13940     }
13941
13942   /* Construct the API message */
13943   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13944   mp->sw_if_index = ntohl (sw_if_index);
13945   mp->enable_disable = enable_disable;
13946
13947   /* send it... */
13948   S (mp);
13949   /* Wait for the reply */
13950   W (ret);
13951   return ret;
13952 }
13953
13954 static int
13955 api_cop_whitelist_enable_disable (vat_main_t * vam)
13956 {
13957   unformat_input_t *line_input = vam->input;
13958   vl_api_cop_whitelist_enable_disable_t *mp;
13959   u32 sw_if_index = ~0;
13960   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13961   u32 fib_id = 0;
13962   int ret;
13963
13964   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13965     {
13966       if (unformat (line_input, "ip4"))
13967         ip4 = 1;
13968       else if (unformat (line_input, "ip6"))
13969         ip6 = 1;
13970       else if (unformat (line_input, "default"))
13971         default_cop = 1;
13972       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13973                          vam, &sw_if_index))
13974         ;
13975       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13976         ;
13977       else if (unformat (line_input, "fib-id %d", &fib_id))
13978         ;
13979       else
13980         break;
13981     }
13982
13983   if (sw_if_index == ~0)
13984     {
13985       errmsg ("missing interface name or sw_if_index");
13986       return -99;
13987     }
13988
13989   /* Construct the API message */
13990   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13991   mp->sw_if_index = ntohl (sw_if_index);
13992   mp->fib_id = ntohl (fib_id);
13993   mp->ip4 = ip4;
13994   mp->ip6 = ip6;
13995   mp->default_cop = default_cop;
13996
13997   /* send it... */
13998   S (mp);
13999   /* Wait for the reply */
14000   W (ret);
14001   return ret;
14002 }
14003
14004 static int
14005 api_get_node_graph (vat_main_t * vam)
14006 {
14007   vl_api_get_node_graph_t *mp;
14008   int ret;
14009
14010   M (GET_NODE_GRAPH, mp);
14011
14012   /* send it... */
14013   S (mp);
14014   /* Wait for the reply */
14015   W (ret);
14016   return ret;
14017 }
14018
14019 /* *INDENT-OFF* */
14020 /** Used for parsing LISP eids */
14021 typedef CLIB_PACKED(struct{
14022   u8 addr[16];   /**< eid address */
14023   u32 len;       /**< prefix length if IP */
14024   u8 type;      /**< type of eid */
14025 }) lisp_eid_vat_t;
14026 /* *INDENT-ON* */
14027
14028 static uword
14029 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14030 {
14031   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14032
14033   memset (a, 0, sizeof (a[0]));
14034
14035   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14036     {
14037       a->type = 0;              /* ipv4 type */
14038     }
14039   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14040     {
14041       a->type = 1;              /* ipv6 type */
14042     }
14043   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14044     {
14045       a->type = 2;              /* mac type */
14046     }
14047   else
14048     {
14049       return 0;
14050     }
14051
14052   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14053     {
14054       return 0;
14055     }
14056
14057   return 1;
14058 }
14059
14060 static int
14061 lisp_eid_size_vat (u8 type)
14062 {
14063   switch (type)
14064     {
14065     case 0:
14066       return 4;
14067     case 1:
14068       return 16;
14069     case 2:
14070       return 6;
14071     }
14072   return 0;
14073 }
14074
14075 static void
14076 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14077 {
14078   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14079 }
14080
14081 static int
14082 api_one_add_del_locator_set (vat_main_t * vam)
14083 {
14084   unformat_input_t *input = vam->input;
14085   vl_api_one_add_del_locator_set_t *mp;
14086   u8 is_add = 1;
14087   u8 *locator_set_name = NULL;
14088   u8 locator_set_name_set = 0;
14089   vl_api_local_locator_t locator, *locators = 0;
14090   u32 sw_if_index, priority, weight;
14091   u32 data_len = 0;
14092
14093   int ret;
14094   /* Parse args required to build the message */
14095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14096     {
14097       if (unformat (input, "del"))
14098         {
14099           is_add = 0;
14100         }
14101       else if (unformat (input, "locator-set %s", &locator_set_name))
14102         {
14103           locator_set_name_set = 1;
14104         }
14105       else if (unformat (input, "sw_if_index %u p %u w %u",
14106                          &sw_if_index, &priority, &weight))
14107         {
14108           locator.sw_if_index = htonl (sw_if_index);
14109           locator.priority = priority;
14110           locator.weight = weight;
14111           vec_add1 (locators, locator);
14112         }
14113       else
14114         if (unformat
14115             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14116              &sw_if_index, &priority, &weight))
14117         {
14118           locator.sw_if_index = htonl (sw_if_index);
14119           locator.priority = priority;
14120           locator.weight = weight;
14121           vec_add1 (locators, locator);
14122         }
14123       else
14124         break;
14125     }
14126
14127   if (locator_set_name_set == 0)
14128     {
14129       errmsg ("missing locator-set name");
14130       vec_free (locators);
14131       return -99;
14132     }
14133
14134   if (vec_len (locator_set_name) > 64)
14135     {
14136       errmsg ("locator-set name too long");
14137       vec_free (locator_set_name);
14138       vec_free (locators);
14139       return -99;
14140     }
14141   vec_add1 (locator_set_name, 0);
14142
14143   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14144
14145   /* Construct the API message */
14146   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14147
14148   mp->is_add = is_add;
14149   clib_memcpy (mp->locator_set_name, locator_set_name,
14150                vec_len (locator_set_name));
14151   vec_free (locator_set_name);
14152
14153   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14154   if (locators)
14155     clib_memcpy (mp->locators, locators, data_len);
14156   vec_free (locators);
14157
14158   /* send it... */
14159   S (mp);
14160
14161   /* Wait for a reply... */
14162   W (ret);
14163   return ret;
14164 }
14165
14166 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14167
14168 static int
14169 api_one_add_del_locator (vat_main_t * vam)
14170 {
14171   unformat_input_t *input = vam->input;
14172   vl_api_one_add_del_locator_t *mp;
14173   u32 tmp_if_index = ~0;
14174   u32 sw_if_index = ~0;
14175   u8 sw_if_index_set = 0;
14176   u8 sw_if_index_if_name_set = 0;
14177   u32 priority = ~0;
14178   u8 priority_set = 0;
14179   u32 weight = ~0;
14180   u8 weight_set = 0;
14181   u8 is_add = 1;
14182   u8 *locator_set_name = NULL;
14183   u8 locator_set_name_set = 0;
14184   int ret;
14185
14186   /* Parse args required to build the message */
14187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14188     {
14189       if (unformat (input, "del"))
14190         {
14191           is_add = 0;
14192         }
14193       else if (unformat (input, "locator-set %s", &locator_set_name))
14194         {
14195           locator_set_name_set = 1;
14196         }
14197       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14198                          &tmp_if_index))
14199         {
14200           sw_if_index_if_name_set = 1;
14201           sw_if_index = tmp_if_index;
14202         }
14203       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14204         {
14205           sw_if_index_set = 1;
14206           sw_if_index = tmp_if_index;
14207         }
14208       else if (unformat (input, "p %d", &priority))
14209         {
14210           priority_set = 1;
14211         }
14212       else if (unformat (input, "w %d", &weight))
14213         {
14214           weight_set = 1;
14215         }
14216       else
14217         break;
14218     }
14219
14220   if (locator_set_name_set == 0)
14221     {
14222       errmsg ("missing locator-set name");
14223       return -99;
14224     }
14225
14226   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14227     {
14228       errmsg ("missing sw_if_index");
14229       vec_free (locator_set_name);
14230       return -99;
14231     }
14232
14233   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14234     {
14235       errmsg ("cannot use both params interface name and sw_if_index");
14236       vec_free (locator_set_name);
14237       return -99;
14238     }
14239
14240   if (priority_set == 0)
14241     {
14242       errmsg ("missing locator-set priority");
14243       vec_free (locator_set_name);
14244       return -99;
14245     }
14246
14247   if (weight_set == 0)
14248     {
14249       errmsg ("missing locator-set weight");
14250       vec_free (locator_set_name);
14251       return -99;
14252     }
14253
14254   if (vec_len (locator_set_name) > 64)
14255     {
14256       errmsg ("locator-set name too long");
14257       vec_free (locator_set_name);
14258       return -99;
14259     }
14260   vec_add1 (locator_set_name, 0);
14261
14262   /* Construct the API message */
14263   M (ONE_ADD_DEL_LOCATOR, mp);
14264
14265   mp->is_add = is_add;
14266   mp->sw_if_index = ntohl (sw_if_index);
14267   mp->priority = priority;
14268   mp->weight = weight;
14269   clib_memcpy (mp->locator_set_name, locator_set_name,
14270                vec_len (locator_set_name));
14271   vec_free (locator_set_name);
14272
14273   /* send it... */
14274   S (mp);
14275
14276   /* Wait for a reply... */
14277   W (ret);
14278   return ret;
14279 }
14280
14281 #define api_lisp_add_del_locator api_one_add_del_locator
14282
14283 uword
14284 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14285 {
14286   u32 *key_id = va_arg (*args, u32 *);
14287   u8 *s = 0;
14288
14289   if (unformat (input, "%s", &s))
14290     {
14291       if (!strcmp ((char *) s, "sha1"))
14292         key_id[0] = HMAC_SHA_1_96;
14293       else if (!strcmp ((char *) s, "sha256"))
14294         key_id[0] = HMAC_SHA_256_128;
14295       else
14296         {
14297           clib_warning ("invalid key_id: '%s'", s);
14298           key_id[0] = HMAC_NO_KEY;
14299         }
14300     }
14301   else
14302     return 0;
14303
14304   vec_free (s);
14305   return 1;
14306 }
14307
14308 static int
14309 api_one_add_del_local_eid (vat_main_t * vam)
14310 {
14311   unformat_input_t *input = vam->input;
14312   vl_api_one_add_del_local_eid_t *mp;
14313   u8 is_add = 1;
14314   u8 eid_set = 0;
14315   lisp_eid_vat_t _eid, *eid = &_eid;
14316   u8 *locator_set_name = 0;
14317   u8 locator_set_name_set = 0;
14318   u32 vni = 0;
14319   u16 key_id = 0;
14320   u8 *key = 0;
14321   int ret;
14322
14323   /* Parse args required to build the message */
14324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14325     {
14326       if (unformat (input, "del"))
14327         {
14328           is_add = 0;
14329         }
14330       else if (unformat (input, "vni %d", &vni))
14331         {
14332           ;
14333         }
14334       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14335         {
14336           eid_set = 1;
14337         }
14338       else if (unformat (input, "locator-set %s", &locator_set_name))
14339         {
14340           locator_set_name_set = 1;
14341         }
14342       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14343         ;
14344       else if (unformat (input, "secret-key %_%v%_", &key))
14345         ;
14346       else
14347         break;
14348     }
14349
14350   if (locator_set_name_set == 0)
14351     {
14352       errmsg ("missing locator-set name");
14353       return -99;
14354     }
14355
14356   if (0 == eid_set)
14357     {
14358       errmsg ("EID address not set!");
14359       vec_free (locator_set_name);
14360       return -99;
14361     }
14362
14363   if (key && (0 == key_id))
14364     {
14365       errmsg ("invalid key_id!");
14366       return -99;
14367     }
14368
14369   if (vec_len (key) > 64)
14370     {
14371       errmsg ("key too long");
14372       vec_free (key);
14373       return -99;
14374     }
14375
14376   if (vec_len (locator_set_name) > 64)
14377     {
14378       errmsg ("locator-set name too long");
14379       vec_free (locator_set_name);
14380       return -99;
14381     }
14382   vec_add1 (locator_set_name, 0);
14383
14384   /* Construct the API message */
14385   M (ONE_ADD_DEL_LOCAL_EID, mp);
14386
14387   mp->is_add = is_add;
14388   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14389   mp->eid_type = eid->type;
14390   mp->prefix_len = eid->len;
14391   mp->vni = clib_host_to_net_u32 (vni);
14392   mp->key_id = clib_host_to_net_u16 (key_id);
14393   clib_memcpy (mp->locator_set_name, locator_set_name,
14394                vec_len (locator_set_name));
14395   clib_memcpy (mp->key, key, vec_len (key));
14396
14397   vec_free (locator_set_name);
14398   vec_free (key);
14399
14400   /* send it... */
14401   S (mp);
14402
14403   /* Wait for a reply... */
14404   W (ret);
14405   return ret;
14406 }
14407
14408 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14409
14410 static int
14411 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14412 {
14413   u32 dp_table = 0, vni = 0;;
14414   unformat_input_t *input = vam->input;
14415   vl_api_gpe_add_del_fwd_entry_t *mp;
14416   u8 is_add = 1;
14417   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14418   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14419   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14420   u32 action = ~0, w;
14421   ip4_address_t rmt_rloc4, lcl_rloc4;
14422   ip6_address_t rmt_rloc6, lcl_rloc6;
14423   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14424   int ret;
14425
14426   memset (&rloc, 0, sizeof (rloc));
14427
14428   /* Parse args required to build the message */
14429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14430     {
14431       if (unformat (input, "del"))
14432         is_add = 0;
14433       else if (unformat (input, "add"))
14434         is_add = 1;
14435       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14436         {
14437           rmt_eid_set = 1;
14438         }
14439       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14440         {
14441           lcl_eid_set = 1;
14442         }
14443       else if (unformat (input, "vrf %d", &dp_table))
14444         ;
14445       else if (unformat (input, "bd %d", &dp_table))
14446         ;
14447       else if (unformat (input, "vni %d", &vni))
14448         ;
14449       else if (unformat (input, "w %d", &w))
14450         {
14451           if (!curr_rloc)
14452             {
14453               errmsg ("No RLOC configured for setting priority/weight!");
14454               return -99;
14455             }
14456           curr_rloc->weight = w;
14457         }
14458       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14459                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14460         {
14461           rloc.is_ip4 = 1;
14462
14463           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14464           rloc.weight = 0;
14465           vec_add1 (lcl_locs, rloc);
14466
14467           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14468           vec_add1 (rmt_locs, rloc);
14469           /* weight saved in rmt loc */
14470           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14471         }
14472       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14473                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14474         {
14475           rloc.is_ip4 = 0;
14476           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14477           rloc.weight = 0;
14478           vec_add1 (lcl_locs, rloc);
14479
14480           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14481           vec_add1 (rmt_locs, rloc);
14482           /* weight saved in rmt loc */
14483           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14484         }
14485       else if (unformat (input, "action %d", &action))
14486         {
14487           ;
14488         }
14489       else
14490         {
14491           clib_warning ("parse error '%U'", format_unformat_error, input);
14492           return -99;
14493         }
14494     }
14495
14496   if (!rmt_eid_set)
14497     {
14498       errmsg ("remote eid addresses not set");
14499       return -99;
14500     }
14501
14502   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14503     {
14504       errmsg ("eid types don't match");
14505       return -99;
14506     }
14507
14508   if (0 == rmt_locs && (u32) ~ 0 == action)
14509     {
14510       errmsg ("action not set for negative mapping");
14511       return -99;
14512     }
14513
14514   /* Construct the API message */
14515   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14516       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14517
14518   mp->is_add = is_add;
14519   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14520   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14521   mp->eid_type = rmt_eid->type;
14522   mp->dp_table = clib_host_to_net_u32 (dp_table);
14523   mp->vni = clib_host_to_net_u32 (vni);
14524   mp->rmt_len = rmt_eid->len;
14525   mp->lcl_len = lcl_eid->len;
14526   mp->action = action;
14527
14528   if (0 != rmt_locs && 0 != lcl_locs)
14529     {
14530       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14531       clib_memcpy (mp->locs, lcl_locs,
14532                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14533
14534       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14535       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14536                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14537     }
14538   vec_free (lcl_locs);
14539   vec_free (rmt_locs);
14540
14541   /* send it... */
14542   S (mp);
14543
14544   /* Wait for a reply... */
14545   W (ret);
14546   return ret;
14547 }
14548
14549 static int
14550 api_one_add_del_map_server (vat_main_t * vam)
14551 {
14552   unformat_input_t *input = vam->input;
14553   vl_api_one_add_del_map_server_t *mp;
14554   u8 is_add = 1;
14555   u8 ipv4_set = 0;
14556   u8 ipv6_set = 0;
14557   ip4_address_t ipv4;
14558   ip6_address_t ipv6;
14559   int ret;
14560
14561   /* Parse args required to build the message */
14562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14563     {
14564       if (unformat (input, "del"))
14565         {
14566           is_add = 0;
14567         }
14568       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14569         {
14570           ipv4_set = 1;
14571         }
14572       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14573         {
14574           ipv6_set = 1;
14575         }
14576       else
14577         break;
14578     }
14579
14580   if (ipv4_set && ipv6_set)
14581     {
14582       errmsg ("both eid v4 and v6 addresses set");
14583       return -99;
14584     }
14585
14586   if (!ipv4_set && !ipv6_set)
14587     {
14588       errmsg ("eid addresses not set");
14589       return -99;
14590     }
14591
14592   /* Construct the API message */
14593   M (ONE_ADD_DEL_MAP_SERVER, mp);
14594
14595   mp->is_add = is_add;
14596   if (ipv6_set)
14597     {
14598       mp->is_ipv6 = 1;
14599       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14600     }
14601   else
14602     {
14603       mp->is_ipv6 = 0;
14604       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14605     }
14606
14607   /* send it... */
14608   S (mp);
14609
14610   /* Wait for a reply... */
14611   W (ret);
14612   return ret;
14613 }
14614
14615 #define api_lisp_add_del_map_server api_one_add_del_map_server
14616
14617 static int
14618 api_one_add_del_map_resolver (vat_main_t * vam)
14619 {
14620   unformat_input_t *input = vam->input;
14621   vl_api_one_add_del_map_resolver_t *mp;
14622   u8 is_add = 1;
14623   u8 ipv4_set = 0;
14624   u8 ipv6_set = 0;
14625   ip4_address_t ipv4;
14626   ip6_address_t ipv6;
14627   int ret;
14628
14629   /* Parse args required to build the message */
14630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14631     {
14632       if (unformat (input, "del"))
14633         {
14634           is_add = 0;
14635         }
14636       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14637         {
14638           ipv4_set = 1;
14639         }
14640       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14641         {
14642           ipv6_set = 1;
14643         }
14644       else
14645         break;
14646     }
14647
14648   if (ipv4_set && ipv6_set)
14649     {
14650       errmsg ("both eid v4 and v6 addresses set");
14651       return -99;
14652     }
14653
14654   if (!ipv4_set && !ipv6_set)
14655     {
14656       errmsg ("eid addresses not set");
14657       return -99;
14658     }
14659
14660   /* Construct the API message */
14661   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14662
14663   mp->is_add = is_add;
14664   if (ipv6_set)
14665     {
14666       mp->is_ipv6 = 1;
14667       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14668     }
14669   else
14670     {
14671       mp->is_ipv6 = 0;
14672       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14673     }
14674
14675   /* send it... */
14676   S (mp);
14677
14678   /* Wait for a reply... */
14679   W (ret);
14680   return ret;
14681 }
14682
14683 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14684
14685 static int
14686 api_lisp_gpe_enable_disable (vat_main_t * vam)
14687 {
14688   unformat_input_t *input = vam->input;
14689   vl_api_gpe_enable_disable_t *mp;
14690   u8 is_set = 0;
14691   u8 is_en = 1;
14692   int ret;
14693
14694   /* Parse args required to build the message */
14695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14696     {
14697       if (unformat (input, "enable"))
14698         {
14699           is_set = 1;
14700           is_en = 1;
14701         }
14702       else if (unformat (input, "disable"))
14703         {
14704           is_set = 1;
14705           is_en = 0;
14706         }
14707       else
14708         break;
14709     }
14710
14711   if (is_set == 0)
14712     {
14713       errmsg ("Value not set");
14714       return -99;
14715     }
14716
14717   /* Construct the API message */
14718   M (GPE_ENABLE_DISABLE, mp);
14719
14720   mp->is_en = is_en;
14721
14722   /* send it... */
14723   S (mp);
14724
14725   /* Wait for a reply... */
14726   W (ret);
14727   return ret;
14728 }
14729
14730 static int
14731 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14732 {
14733   unformat_input_t *input = vam->input;
14734   vl_api_one_rloc_probe_enable_disable_t *mp;
14735   u8 is_set = 0;
14736   u8 is_en = 0;
14737   int ret;
14738
14739   /* Parse args required to build the message */
14740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14741     {
14742       if (unformat (input, "enable"))
14743         {
14744           is_set = 1;
14745           is_en = 1;
14746         }
14747       else if (unformat (input, "disable"))
14748         is_set = 1;
14749       else
14750         break;
14751     }
14752
14753   if (!is_set)
14754     {
14755       errmsg ("Value not set");
14756       return -99;
14757     }
14758
14759   /* Construct the API message */
14760   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14761
14762   mp->is_enabled = is_en;
14763
14764   /* send it... */
14765   S (mp);
14766
14767   /* Wait for a reply... */
14768   W (ret);
14769   return ret;
14770 }
14771
14772 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14773
14774 static int
14775 api_one_map_register_enable_disable (vat_main_t * vam)
14776 {
14777   unformat_input_t *input = vam->input;
14778   vl_api_one_map_register_enable_disable_t *mp;
14779   u8 is_set = 0;
14780   u8 is_en = 0;
14781   int ret;
14782
14783   /* Parse args required to build the message */
14784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14785     {
14786       if (unformat (input, "enable"))
14787         {
14788           is_set = 1;
14789           is_en = 1;
14790         }
14791       else if (unformat (input, "disable"))
14792         is_set = 1;
14793       else
14794         break;
14795     }
14796
14797   if (!is_set)
14798     {
14799       errmsg ("Value not set");
14800       return -99;
14801     }
14802
14803   /* Construct the API message */
14804   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14805
14806   mp->is_enabled = is_en;
14807
14808   /* send it... */
14809   S (mp);
14810
14811   /* Wait for a reply... */
14812   W (ret);
14813   return ret;
14814 }
14815
14816 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14817
14818 static int
14819 api_one_enable_disable (vat_main_t * vam)
14820 {
14821   unformat_input_t *input = vam->input;
14822   vl_api_one_enable_disable_t *mp;
14823   u8 is_set = 0;
14824   u8 is_en = 0;
14825   int ret;
14826
14827   /* Parse args required to build the message */
14828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat (input, "enable"))
14831         {
14832           is_set = 1;
14833           is_en = 1;
14834         }
14835       else if (unformat (input, "disable"))
14836         {
14837           is_set = 1;
14838         }
14839       else
14840         break;
14841     }
14842
14843   if (!is_set)
14844     {
14845       errmsg ("Value not set");
14846       return -99;
14847     }
14848
14849   /* Construct the API message */
14850   M (ONE_ENABLE_DISABLE, mp);
14851
14852   mp->is_en = is_en;
14853
14854   /* send it... */
14855   S (mp);
14856
14857   /* Wait for a reply... */
14858   W (ret);
14859   return ret;
14860 }
14861
14862 #define api_lisp_enable_disable api_one_enable_disable
14863
14864 static int
14865 api_show_one_map_register_state (vat_main_t * vam)
14866 {
14867   vl_api_show_one_map_register_state_t *mp;
14868   int ret;
14869
14870   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14871
14872   /* send */
14873   S (mp);
14874
14875   /* wait for reply */
14876   W (ret);
14877   return ret;
14878 }
14879
14880 #define api_show_lisp_map_register_state api_show_one_map_register_state
14881
14882 static int
14883 api_show_one_rloc_probe_state (vat_main_t * vam)
14884 {
14885   vl_api_show_one_rloc_probe_state_t *mp;
14886   int ret;
14887
14888   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14889
14890   /* send */
14891   S (mp);
14892
14893   /* wait for reply */
14894   W (ret);
14895   return ret;
14896 }
14897
14898 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14899
14900 static int
14901 api_one_add_del_l2_arp_entry (vat_main_t * vam)
14902 {
14903   vl_api_one_add_del_l2_arp_entry_t *mp;
14904   unformat_input_t *input = vam->input;
14905   u8 is_add = 1;
14906   u8 mac_set = 0;
14907   u8 bd_set = 0;
14908   u8 ip_set = 0;
14909   u8 mac[6] = { 0, };
14910   u32 ip4 = 0, bd = ~0;
14911   int ret;
14912
14913   /* Parse args required to build the message */
14914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14915     {
14916       if (unformat (input, "del"))
14917         is_add = 0;
14918       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
14919         mac_set = 1;
14920       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
14921         ip_set = 1;
14922       else if (unformat (input, "bd %d", &bd))
14923         bd_set = 1;
14924       else
14925         {
14926           errmsg ("parse error '%U'", format_unformat_error, input);
14927           return -99;
14928         }
14929     }
14930
14931   if (!bd_set || !ip_set || (!mac_set && is_add))
14932     {
14933       errmsg ("Missing BD, IP or MAC!");
14934       return -99;
14935     }
14936
14937   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
14938   mp->is_add = is_add;
14939   clib_memcpy (mp->mac, mac, 6);
14940   mp->bd = clib_host_to_net_u32 (bd);
14941   mp->ip4 = ip4;
14942
14943   /* send */
14944   S (mp);
14945
14946   /* wait for reply */
14947   W (ret);
14948   return ret;
14949 }
14950
14951 static int
14952 api_one_l2_arp_bd_get (vat_main_t * vam)
14953 {
14954   vl_api_one_l2_arp_bd_get_t *mp;
14955   int ret;
14956
14957   M (ONE_L2_ARP_BD_GET, mp);
14958
14959   /* send */
14960   S (mp);
14961
14962   /* wait for reply */
14963   W (ret);
14964   return ret;
14965 }
14966
14967 static int
14968 api_one_l2_arp_entries_get (vat_main_t * vam)
14969 {
14970   vl_api_one_l2_arp_entries_get_t *mp;
14971   unformat_input_t *input = vam->input;
14972   u8 bd_set = 0;
14973   u32 bd = ~0;
14974   int ret;
14975
14976   /* Parse args required to build the message */
14977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14978     {
14979       if (unformat (input, "bd %d", &bd))
14980         bd_set = 1;
14981       else
14982         {
14983           errmsg ("parse error '%U'", format_unformat_error, input);
14984           return -99;
14985         }
14986     }
14987
14988   if (!bd_set)
14989     {
14990       errmsg ("Expected bridge domain!");
14991       return -99;
14992     }
14993
14994   M (ONE_L2_ARP_ENTRIES_GET, mp);
14995   mp->bd = clib_host_to_net_u32 (bd);
14996
14997   /* send */
14998   S (mp);
14999
15000   /* wait for reply */
15001   W (ret);
15002   return ret;
15003 }
15004
15005 static int
15006 api_one_stats_enable_disable (vat_main_t * vam)
15007 {
15008   vl_api_one_stats_enable_disable_t *mp;
15009   unformat_input_t *input = vam->input;
15010   u8 is_set = 0;
15011   u8 is_en = 0;
15012   int ret;
15013
15014   /* Parse args required to build the message */
15015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15016     {
15017       if (unformat (input, "enable"))
15018         {
15019           is_set = 1;
15020           is_en = 1;
15021         }
15022       else if (unformat (input, "disable"))
15023         {
15024           is_set = 1;
15025         }
15026       else
15027         break;
15028     }
15029
15030   if (!is_set)
15031     {
15032       errmsg ("Value not set");
15033       return -99;
15034     }
15035
15036   M (ONE_STATS_ENABLE_DISABLE, mp);
15037   mp->is_en = is_en;
15038
15039   /* send */
15040   S (mp);
15041
15042   /* wait for reply */
15043   W (ret);
15044   return ret;
15045 }
15046
15047 static int
15048 api_show_one_stats_enable_disable (vat_main_t * vam)
15049 {
15050   vl_api_show_one_stats_enable_disable_t *mp;
15051   int ret;
15052
15053   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15054
15055   /* send */
15056   S (mp);
15057
15058   /* wait for reply */
15059   W (ret);
15060   return ret;
15061 }
15062
15063 static int
15064 api_show_one_map_request_mode (vat_main_t * vam)
15065 {
15066   vl_api_show_one_map_request_mode_t *mp;
15067   int ret;
15068
15069   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15070
15071   /* send */
15072   S (mp);
15073
15074   /* wait for reply */
15075   W (ret);
15076   return ret;
15077 }
15078
15079 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15080
15081 static int
15082 api_one_map_request_mode (vat_main_t * vam)
15083 {
15084   unformat_input_t *input = vam->input;
15085   vl_api_one_map_request_mode_t *mp;
15086   u8 mode = 0;
15087   int ret;
15088
15089   /* Parse args required to build the message */
15090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15091     {
15092       if (unformat (input, "dst-only"))
15093         mode = 0;
15094       else if (unformat (input, "src-dst"))
15095         mode = 1;
15096       else
15097         {
15098           errmsg ("parse error '%U'", format_unformat_error, input);
15099           return -99;
15100         }
15101     }
15102
15103   M (ONE_MAP_REQUEST_MODE, mp);
15104
15105   mp->mode = mode;
15106
15107   /* send */
15108   S (mp);
15109
15110   /* wait for reply */
15111   W (ret);
15112   return ret;
15113 }
15114
15115 #define api_lisp_map_request_mode api_one_map_request_mode
15116
15117 /**
15118  * Enable/disable ONE proxy ITR.
15119  *
15120  * @param vam vpp API test context
15121  * @return return code
15122  */
15123 static int
15124 api_one_pitr_set_locator_set (vat_main_t * vam)
15125 {
15126   u8 ls_name_set = 0;
15127   unformat_input_t *input = vam->input;
15128   vl_api_one_pitr_set_locator_set_t *mp;
15129   u8 is_add = 1;
15130   u8 *ls_name = 0;
15131   int ret;
15132
15133   /* Parse args required to build the message */
15134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15135     {
15136       if (unformat (input, "del"))
15137         is_add = 0;
15138       else if (unformat (input, "locator-set %s", &ls_name))
15139         ls_name_set = 1;
15140       else
15141         {
15142           errmsg ("parse error '%U'", format_unformat_error, input);
15143           return -99;
15144         }
15145     }
15146
15147   if (!ls_name_set)
15148     {
15149       errmsg ("locator-set name not set!");
15150       return -99;
15151     }
15152
15153   M (ONE_PITR_SET_LOCATOR_SET, mp);
15154
15155   mp->is_add = is_add;
15156   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15157   vec_free (ls_name);
15158
15159   /* send */
15160   S (mp);
15161
15162   /* wait for reply */
15163   W (ret);
15164   return ret;
15165 }
15166
15167 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15168
15169 static int
15170 api_show_one_pitr (vat_main_t * vam)
15171 {
15172   vl_api_show_one_pitr_t *mp;
15173   int ret;
15174
15175   if (!vam->json_output)
15176     {
15177       print (vam->ofp, "%=20s", "lisp status:");
15178     }
15179
15180   M (SHOW_ONE_PITR, mp);
15181   /* send it... */
15182   S (mp);
15183
15184   /* Wait for a reply... */
15185   W (ret);
15186   return ret;
15187 }
15188
15189 #define api_show_lisp_pitr api_show_one_pitr
15190
15191 static int
15192 api_one_use_petr (vat_main_t * vam)
15193 {
15194   unformat_input_t *input = vam->input;
15195   vl_api_one_use_petr_t *mp;
15196   u8 is_add = 0;
15197   ip_address_t ip;
15198   int ret;
15199
15200   memset (&ip, 0, sizeof (ip));
15201
15202   /* Parse args required to build the message */
15203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15204     {
15205       if (unformat (input, "disable"))
15206         is_add = 0;
15207       else
15208         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15209         {
15210           is_add = 1;
15211           ip_addr_version (&ip) = IP4;
15212         }
15213       else
15214         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15215         {
15216           is_add = 1;
15217           ip_addr_version (&ip) = IP6;
15218         }
15219       else
15220         {
15221           errmsg ("parse error '%U'", format_unformat_error, input);
15222           return -99;
15223         }
15224     }
15225
15226   M (ONE_USE_PETR, mp);
15227
15228   mp->is_add = is_add;
15229   if (is_add)
15230     {
15231       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15232       if (mp->is_ip4)
15233         clib_memcpy (mp->address, &ip, 4);
15234       else
15235         clib_memcpy (mp->address, &ip, 16);
15236     }
15237
15238   /* send */
15239   S (mp);
15240
15241   /* wait for reply */
15242   W (ret);
15243   return ret;
15244 }
15245
15246 #define api_lisp_use_petr api_one_use_petr
15247
15248 static int
15249 api_show_one_use_petr (vat_main_t * vam)
15250 {
15251   vl_api_show_one_use_petr_t *mp;
15252   int ret;
15253
15254   if (!vam->json_output)
15255     {
15256       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15257     }
15258
15259   M (SHOW_ONE_USE_PETR, mp);
15260   /* send it... */
15261   S (mp);
15262
15263   /* Wait for a reply... */
15264   W (ret);
15265   return ret;
15266 }
15267
15268 #define api_show_lisp_use_petr api_show_one_use_petr
15269
15270 /**
15271  * Add/delete mapping between vni and vrf
15272  */
15273 static int
15274 api_one_eid_table_add_del_map (vat_main_t * vam)
15275 {
15276   unformat_input_t *input = vam->input;
15277   vl_api_one_eid_table_add_del_map_t *mp;
15278   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15279   u32 vni, vrf, bd_index;
15280   int ret;
15281
15282   /* Parse args required to build the message */
15283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15284     {
15285       if (unformat (input, "del"))
15286         is_add = 0;
15287       else if (unformat (input, "vrf %d", &vrf))
15288         vrf_set = 1;
15289       else if (unformat (input, "bd_index %d", &bd_index))
15290         bd_index_set = 1;
15291       else if (unformat (input, "vni %d", &vni))
15292         vni_set = 1;
15293       else
15294         break;
15295     }
15296
15297   if (!vni_set || (!vrf_set && !bd_index_set))
15298     {
15299       errmsg ("missing arguments!");
15300       return -99;
15301     }
15302
15303   if (vrf_set && bd_index_set)
15304     {
15305       errmsg ("error: both vrf and bd entered!");
15306       return -99;
15307     }
15308
15309   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15310
15311   mp->is_add = is_add;
15312   mp->vni = htonl (vni);
15313   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15314   mp->is_l2 = bd_index_set;
15315
15316   /* send */
15317   S (mp);
15318
15319   /* wait for reply */
15320   W (ret);
15321   return ret;
15322 }
15323
15324 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15325
15326 uword
15327 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15328 {
15329   u32 *action = va_arg (*args, u32 *);
15330   u8 *s = 0;
15331
15332   if (unformat (input, "%s", &s))
15333     {
15334       if (!strcmp ((char *) s, "no-action"))
15335         action[0] = 0;
15336       else if (!strcmp ((char *) s, "natively-forward"))
15337         action[0] = 1;
15338       else if (!strcmp ((char *) s, "send-map-request"))
15339         action[0] = 2;
15340       else if (!strcmp ((char *) s, "drop"))
15341         action[0] = 3;
15342       else
15343         {
15344           clib_warning ("invalid action: '%s'", s);
15345           action[0] = 3;
15346         }
15347     }
15348   else
15349     return 0;
15350
15351   vec_free (s);
15352   return 1;
15353 }
15354
15355 /**
15356  * Add/del remote mapping to/from ONE control plane
15357  *
15358  * @param vam vpp API test context
15359  * @return return code
15360  */
15361 static int
15362 api_one_add_del_remote_mapping (vat_main_t * vam)
15363 {
15364   unformat_input_t *input = vam->input;
15365   vl_api_one_add_del_remote_mapping_t *mp;
15366   u32 vni = 0;
15367   lisp_eid_vat_t _eid, *eid = &_eid;
15368   lisp_eid_vat_t _seid, *seid = &_seid;
15369   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15370   u32 action = ~0, p, w, data_len;
15371   ip4_address_t rloc4;
15372   ip6_address_t rloc6;
15373   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15374   int ret;
15375
15376   memset (&rloc, 0, sizeof (rloc));
15377
15378   /* Parse args required to build the message */
15379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15380     {
15381       if (unformat (input, "del-all"))
15382         {
15383           del_all = 1;
15384         }
15385       else if (unformat (input, "del"))
15386         {
15387           is_add = 0;
15388         }
15389       else if (unformat (input, "add"))
15390         {
15391           is_add = 1;
15392         }
15393       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15394         {
15395           eid_set = 1;
15396         }
15397       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15398         {
15399           seid_set = 1;
15400         }
15401       else if (unformat (input, "vni %d", &vni))
15402         {
15403           ;
15404         }
15405       else if (unformat (input, "p %d w %d", &p, &w))
15406         {
15407           if (!curr_rloc)
15408             {
15409               errmsg ("No RLOC configured for setting priority/weight!");
15410               return -99;
15411             }
15412           curr_rloc->priority = p;
15413           curr_rloc->weight = w;
15414         }
15415       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15416         {
15417           rloc.is_ip4 = 1;
15418           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15419           vec_add1 (rlocs, rloc);
15420           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15421         }
15422       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15423         {
15424           rloc.is_ip4 = 0;
15425           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15426           vec_add1 (rlocs, rloc);
15427           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15428         }
15429       else if (unformat (input, "action %U",
15430                          unformat_negative_mapping_action, &action))
15431         {
15432           ;
15433         }
15434       else
15435         {
15436           clib_warning ("parse error '%U'", format_unformat_error, input);
15437           return -99;
15438         }
15439     }
15440
15441   if (0 == eid_set)
15442     {
15443       errmsg ("missing params!");
15444       return -99;
15445     }
15446
15447   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15448     {
15449       errmsg ("no action set for negative map-reply!");
15450       return -99;
15451     }
15452
15453   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15454
15455   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15456   mp->is_add = is_add;
15457   mp->vni = htonl (vni);
15458   mp->action = (u8) action;
15459   mp->is_src_dst = seid_set;
15460   mp->eid_len = eid->len;
15461   mp->seid_len = seid->len;
15462   mp->del_all = del_all;
15463   mp->eid_type = eid->type;
15464   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15465   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15466
15467   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15468   clib_memcpy (mp->rlocs, rlocs, data_len);
15469   vec_free (rlocs);
15470
15471   /* send it... */
15472   S (mp);
15473
15474   /* Wait for a reply... */
15475   W (ret);
15476   return ret;
15477 }
15478
15479 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15480
15481 /**
15482  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15483  * forwarding entries in data-plane accordingly.
15484  *
15485  * @param vam vpp API test context
15486  * @return return code
15487  */
15488 static int
15489 api_one_add_del_adjacency (vat_main_t * vam)
15490 {
15491   unformat_input_t *input = vam->input;
15492   vl_api_one_add_del_adjacency_t *mp;
15493   u32 vni = 0;
15494   ip4_address_t leid4, reid4;
15495   ip6_address_t leid6, reid6;
15496   u8 reid_mac[6] = { 0 };
15497   u8 leid_mac[6] = { 0 };
15498   u8 reid_type, leid_type;
15499   u32 leid_len = 0, reid_len = 0, len;
15500   u8 is_add = 1;
15501   int ret;
15502
15503   leid_type = reid_type = (u8) ~ 0;
15504
15505   /* Parse args required to build the message */
15506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15507     {
15508       if (unformat (input, "del"))
15509         {
15510           is_add = 0;
15511         }
15512       else if (unformat (input, "add"))
15513         {
15514           is_add = 1;
15515         }
15516       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15517                          &reid4, &len))
15518         {
15519           reid_type = 0;        /* ipv4 */
15520           reid_len = len;
15521         }
15522       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15523                          &reid6, &len))
15524         {
15525           reid_type = 1;        /* ipv6 */
15526           reid_len = len;
15527         }
15528       else if (unformat (input, "reid %U", unformat_ethernet_address,
15529                          reid_mac))
15530         {
15531           reid_type = 2;        /* mac */
15532         }
15533       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15534                          &leid4, &len))
15535         {
15536           leid_type = 0;        /* ipv4 */
15537           leid_len = len;
15538         }
15539       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15540                          &leid6, &len))
15541         {
15542           leid_type = 1;        /* ipv6 */
15543           leid_len = len;
15544         }
15545       else if (unformat (input, "leid %U", unformat_ethernet_address,
15546                          leid_mac))
15547         {
15548           leid_type = 2;        /* mac */
15549         }
15550       else if (unformat (input, "vni %d", &vni))
15551         {
15552           ;
15553         }
15554       else
15555         {
15556           errmsg ("parse error '%U'", format_unformat_error, input);
15557           return -99;
15558         }
15559     }
15560
15561   if ((u8) ~ 0 == reid_type)
15562     {
15563       errmsg ("missing params!");
15564       return -99;
15565     }
15566
15567   if (leid_type != reid_type)
15568     {
15569       errmsg ("remote and local EIDs are of different types!");
15570       return -99;
15571     }
15572
15573   M (ONE_ADD_DEL_ADJACENCY, mp);
15574   mp->is_add = is_add;
15575   mp->vni = htonl (vni);
15576   mp->leid_len = leid_len;
15577   mp->reid_len = reid_len;
15578   mp->eid_type = reid_type;
15579
15580   switch (mp->eid_type)
15581     {
15582     case 0:
15583       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15584       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15585       break;
15586     case 1:
15587       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15588       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15589       break;
15590     case 2:
15591       clib_memcpy (mp->leid, leid_mac, 6);
15592       clib_memcpy (mp->reid, reid_mac, 6);
15593       break;
15594     default:
15595       errmsg ("unknown EID type %d!", mp->eid_type);
15596       return 0;
15597     }
15598
15599   /* send it... */
15600   S (mp);
15601
15602   /* Wait for a reply... */
15603   W (ret);
15604   return ret;
15605 }
15606
15607 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15608
15609 uword
15610 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15611 {
15612   u32 *mode = va_arg (*args, u32 *);
15613
15614   if (unformat (input, "lisp"))
15615     *mode = 0;
15616   else if (unformat (input, "vxlan"))
15617     *mode = 1;
15618   else
15619     return 0;
15620
15621   return 1;
15622 }
15623
15624 static int
15625 api_gpe_get_encap_mode (vat_main_t * vam)
15626 {
15627   vl_api_gpe_get_encap_mode_t *mp;
15628   int ret;
15629
15630   /* Construct the API message */
15631   M (GPE_GET_ENCAP_MODE, mp);
15632
15633   /* send it... */
15634   S (mp);
15635
15636   /* Wait for a reply... */
15637   W (ret);
15638   return ret;
15639 }
15640
15641 static int
15642 api_gpe_set_encap_mode (vat_main_t * vam)
15643 {
15644   unformat_input_t *input = vam->input;
15645   vl_api_gpe_set_encap_mode_t *mp;
15646   int ret;
15647   u32 mode = 0;
15648
15649   /* Parse args required to build the message */
15650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15651     {
15652       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15653         ;
15654       else
15655         break;
15656     }
15657
15658   /* Construct the API message */
15659   M (GPE_SET_ENCAP_MODE, mp);
15660
15661   mp->mode = mode;
15662
15663   /* send it... */
15664   S (mp);
15665
15666   /* Wait for a reply... */
15667   W (ret);
15668   return ret;
15669 }
15670
15671 static int
15672 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15673 {
15674   unformat_input_t *input = vam->input;
15675   vl_api_gpe_add_del_iface_t *mp;
15676   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15677   u32 dp_table = 0, vni = 0;
15678   int ret;
15679
15680   /* Parse args required to build the message */
15681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15682     {
15683       if (unformat (input, "up"))
15684         {
15685           action_set = 1;
15686           is_add = 1;
15687         }
15688       else if (unformat (input, "down"))
15689         {
15690           action_set = 1;
15691           is_add = 0;
15692         }
15693       else if (unformat (input, "table_id %d", &dp_table))
15694         {
15695           dp_table_set = 1;
15696         }
15697       else if (unformat (input, "bd_id %d", &dp_table))
15698         {
15699           dp_table_set = 1;
15700           is_l2 = 1;
15701         }
15702       else if (unformat (input, "vni %d", &vni))
15703         {
15704           vni_set = 1;
15705         }
15706       else
15707         break;
15708     }
15709
15710   if (action_set == 0)
15711     {
15712       errmsg ("Action not set");
15713       return -99;
15714     }
15715   if (dp_table_set == 0 || vni_set == 0)
15716     {
15717       errmsg ("vni and dp_table must be set");
15718       return -99;
15719     }
15720
15721   /* Construct the API message */
15722   M (GPE_ADD_DEL_IFACE, mp);
15723
15724   mp->is_add = is_add;
15725   mp->dp_table = dp_table;
15726   mp->is_l2 = is_l2;
15727   mp->vni = vni;
15728
15729   /* send it... */
15730   S (mp);
15731
15732   /* Wait for a reply... */
15733   W (ret);
15734   return ret;
15735 }
15736
15737 /**
15738  * Add/del map request itr rlocs from ONE control plane and updates
15739  *
15740  * @param vam vpp API test context
15741  * @return return code
15742  */
15743 static int
15744 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15745 {
15746   unformat_input_t *input = vam->input;
15747   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15748   u8 *locator_set_name = 0;
15749   u8 locator_set_name_set = 0;
15750   u8 is_add = 1;
15751   int ret;
15752
15753   /* Parse args required to build the message */
15754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15755     {
15756       if (unformat (input, "del"))
15757         {
15758           is_add = 0;
15759         }
15760       else if (unformat (input, "%_%v%_", &locator_set_name))
15761         {
15762           locator_set_name_set = 1;
15763         }
15764       else
15765         {
15766           clib_warning ("parse error '%U'", format_unformat_error, input);
15767           return -99;
15768         }
15769     }
15770
15771   if (is_add && !locator_set_name_set)
15772     {
15773       errmsg ("itr-rloc is not set!");
15774       return -99;
15775     }
15776
15777   if (is_add && vec_len (locator_set_name) > 64)
15778     {
15779       errmsg ("itr-rloc locator-set name too long");
15780       vec_free (locator_set_name);
15781       return -99;
15782     }
15783
15784   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15785   mp->is_add = is_add;
15786   if (is_add)
15787     {
15788       clib_memcpy (mp->locator_set_name, locator_set_name,
15789                    vec_len (locator_set_name));
15790     }
15791   else
15792     {
15793       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15794     }
15795   vec_free (locator_set_name);
15796
15797   /* send it... */
15798   S (mp);
15799
15800   /* Wait for a reply... */
15801   W (ret);
15802   return ret;
15803 }
15804
15805 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15806
15807 static int
15808 api_one_locator_dump (vat_main_t * vam)
15809 {
15810   unformat_input_t *input = vam->input;
15811   vl_api_one_locator_dump_t *mp;
15812   vl_api_control_ping_t *mp_ping;
15813   u8 is_index_set = 0, is_name_set = 0;
15814   u8 *ls_name = 0;
15815   u32 ls_index = ~0;
15816   int ret;
15817
15818   /* Parse args required to build the message */
15819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15820     {
15821       if (unformat (input, "ls_name %_%v%_", &ls_name))
15822         {
15823           is_name_set = 1;
15824         }
15825       else if (unformat (input, "ls_index %d", &ls_index))
15826         {
15827           is_index_set = 1;
15828         }
15829       else
15830         {
15831           errmsg ("parse error '%U'", format_unformat_error, input);
15832           return -99;
15833         }
15834     }
15835
15836   if (!is_index_set && !is_name_set)
15837     {
15838       errmsg ("error: expected one of index or name!");
15839       return -99;
15840     }
15841
15842   if (is_index_set && is_name_set)
15843     {
15844       errmsg ("error: only one param expected!");
15845       return -99;
15846     }
15847
15848   if (vec_len (ls_name) > 62)
15849     {
15850       errmsg ("error: locator set name too long!");
15851       return -99;
15852     }
15853
15854   if (!vam->json_output)
15855     {
15856       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15857     }
15858
15859   M (ONE_LOCATOR_DUMP, mp);
15860   mp->is_index_set = is_index_set;
15861
15862   if (is_index_set)
15863     mp->ls_index = clib_host_to_net_u32 (ls_index);
15864   else
15865     {
15866       vec_add1 (ls_name, 0);
15867       strncpy ((char *) mp->ls_name, (char *) ls_name,
15868                sizeof (mp->ls_name) - 1);
15869     }
15870
15871   /* send it... */
15872   S (mp);
15873
15874   /* Use a control ping for synchronization */
15875   M (CONTROL_PING, mp_ping);
15876   S (mp_ping);
15877
15878   /* Wait for a reply... */
15879   W (ret);
15880   return ret;
15881 }
15882
15883 #define api_lisp_locator_dump api_one_locator_dump
15884
15885 static int
15886 api_one_locator_set_dump (vat_main_t * vam)
15887 {
15888   vl_api_one_locator_set_dump_t *mp;
15889   vl_api_control_ping_t *mp_ping;
15890   unformat_input_t *input = vam->input;
15891   u8 filter = 0;
15892   int ret;
15893
15894   /* Parse args required to build the message */
15895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15896     {
15897       if (unformat (input, "local"))
15898         {
15899           filter = 1;
15900         }
15901       else if (unformat (input, "remote"))
15902         {
15903           filter = 2;
15904         }
15905       else
15906         {
15907           errmsg ("parse error '%U'", format_unformat_error, input);
15908           return -99;
15909         }
15910     }
15911
15912   if (!vam->json_output)
15913     {
15914       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15915     }
15916
15917   M (ONE_LOCATOR_SET_DUMP, mp);
15918
15919   mp->filter = filter;
15920
15921   /* send it... */
15922   S (mp);
15923
15924   /* Use a control ping for synchronization */
15925   M (CONTROL_PING, mp_ping);
15926   S (mp_ping);
15927
15928   /* Wait for a reply... */
15929   W (ret);
15930   return ret;
15931 }
15932
15933 #define api_lisp_locator_set_dump api_one_locator_set_dump
15934
15935 static int
15936 api_one_eid_table_map_dump (vat_main_t * vam)
15937 {
15938   u8 is_l2 = 0;
15939   u8 mode_set = 0;
15940   unformat_input_t *input = vam->input;
15941   vl_api_one_eid_table_map_dump_t *mp;
15942   vl_api_control_ping_t *mp_ping;
15943   int ret;
15944
15945   /* Parse args required to build the message */
15946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15947     {
15948       if (unformat (input, "l2"))
15949         {
15950           is_l2 = 1;
15951           mode_set = 1;
15952         }
15953       else if (unformat (input, "l3"))
15954         {
15955           is_l2 = 0;
15956           mode_set = 1;
15957         }
15958       else
15959         {
15960           errmsg ("parse error '%U'", format_unformat_error, input);
15961           return -99;
15962         }
15963     }
15964
15965   if (!mode_set)
15966     {
15967       errmsg ("expected one of 'l2' or 'l3' parameter!");
15968       return -99;
15969     }
15970
15971   if (!vam->json_output)
15972     {
15973       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15974     }
15975
15976   M (ONE_EID_TABLE_MAP_DUMP, mp);
15977   mp->is_l2 = is_l2;
15978
15979   /* send it... */
15980   S (mp);
15981
15982   /* Use a control ping for synchronization */
15983   M (CONTROL_PING, mp_ping);
15984   S (mp_ping);
15985
15986   /* Wait for a reply... */
15987   W (ret);
15988   return ret;
15989 }
15990
15991 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15992
15993 static int
15994 api_one_eid_table_vni_dump (vat_main_t * vam)
15995 {
15996   vl_api_one_eid_table_vni_dump_t *mp;
15997   vl_api_control_ping_t *mp_ping;
15998   int ret;
15999
16000   if (!vam->json_output)
16001     {
16002       print (vam->ofp, "VNI");
16003     }
16004
16005   M (ONE_EID_TABLE_VNI_DUMP, mp);
16006
16007   /* send it... */
16008   S (mp);
16009
16010   /* Use a control ping for synchronization */
16011   M (CONTROL_PING, mp_ping);
16012   S (mp_ping);
16013
16014   /* Wait for a reply... */
16015   W (ret);
16016   return ret;
16017 }
16018
16019 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16020
16021 static int
16022 api_one_eid_table_dump (vat_main_t * vam)
16023 {
16024   unformat_input_t *i = vam->input;
16025   vl_api_one_eid_table_dump_t *mp;
16026   vl_api_control_ping_t *mp_ping;
16027   struct in_addr ip4;
16028   struct in6_addr ip6;
16029   u8 mac[6];
16030   u8 eid_type = ~0, eid_set = 0;
16031   u32 prefix_length = ~0, t, vni = 0;
16032   u8 filter = 0;
16033   int ret;
16034
16035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16036     {
16037       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16038         {
16039           eid_set = 1;
16040           eid_type = 0;
16041           prefix_length = t;
16042         }
16043       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16044         {
16045           eid_set = 1;
16046           eid_type = 1;
16047           prefix_length = t;
16048         }
16049       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16050         {
16051           eid_set = 1;
16052           eid_type = 2;
16053         }
16054       else if (unformat (i, "vni %d", &t))
16055         {
16056           vni = t;
16057         }
16058       else if (unformat (i, "local"))
16059         {
16060           filter = 1;
16061         }
16062       else if (unformat (i, "remote"))
16063         {
16064           filter = 2;
16065         }
16066       else
16067         {
16068           errmsg ("parse error '%U'", format_unformat_error, i);
16069           return -99;
16070         }
16071     }
16072
16073   if (!vam->json_output)
16074     {
16075       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16076              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16077     }
16078
16079   M (ONE_EID_TABLE_DUMP, mp);
16080
16081   mp->filter = filter;
16082   if (eid_set)
16083     {
16084       mp->eid_set = 1;
16085       mp->vni = htonl (vni);
16086       mp->eid_type = eid_type;
16087       switch (eid_type)
16088         {
16089         case 0:
16090           mp->prefix_length = prefix_length;
16091           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16092           break;
16093         case 1:
16094           mp->prefix_length = prefix_length;
16095           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16096           break;
16097         case 2:
16098           clib_memcpy (mp->eid, mac, sizeof (mac));
16099           break;
16100         default:
16101           errmsg ("unknown EID type %d!", eid_type);
16102           return -99;
16103         }
16104     }
16105
16106   /* send it... */
16107   S (mp);
16108
16109   /* Use a control ping for synchronization */
16110   M (CONTROL_PING, mp_ping);
16111   S (mp_ping);
16112
16113   /* Wait for a reply... */
16114   W (ret);
16115   return ret;
16116 }
16117
16118 #define api_lisp_eid_table_dump api_one_eid_table_dump
16119
16120 static int
16121 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16122 {
16123   unformat_input_t *i = vam->input;
16124   vl_api_gpe_fwd_entries_get_t *mp;
16125   u8 vni_set = 0;
16126   u32 vni = ~0;
16127   int ret;
16128
16129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16130     {
16131       if (unformat (i, "vni %d", &vni))
16132         {
16133           vni_set = 1;
16134         }
16135       else
16136         {
16137           errmsg ("parse error '%U'", format_unformat_error, i);
16138           return -99;
16139         }
16140     }
16141
16142   if (!vni_set)
16143     {
16144       errmsg ("vni not set!");
16145       return -99;
16146     }
16147
16148   if (!vam->json_output)
16149     {
16150       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16151              "leid", "reid");
16152     }
16153
16154   M (GPE_FWD_ENTRIES_GET, mp);
16155   mp->vni = clib_host_to_net_u32 (vni);
16156
16157   /* send it... */
16158   S (mp);
16159
16160   /* Wait for a reply... */
16161   W (ret);
16162   return ret;
16163 }
16164
16165 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16166 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16167 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16168 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16169 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16170 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16171
16172 static int
16173 api_one_adjacencies_get (vat_main_t * vam)
16174 {
16175   unformat_input_t *i = vam->input;
16176   vl_api_one_adjacencies_get_t *mp;
16177   u8 vni_set = 0;
16178   u32 vni = ~0;
16179   int ret;
16180
16181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16182     {
16183       if (unformat (i, "vni %d", &vni))
16184         {
16185           vni_set = 1;
16186         }
16187       else
16188         {
16189           errmsg ("parse error '%U'", format_unformat_error, i);
16190           return -99;
16191         }
16192     }
16193
16194   if (!vni_set)
16195     {
16196       errmsg ("vni not set!");
16197       return -99;
16198     }
16199
16200   if (!vam->json_output)
16201     {
16202       print (vam->ofp, "%s %40s", "leid", "reid");
16203     }
16204
16205   M (ONE_ADJACENCIES_GET, mp);
16206   mp->vni = clib_host_to_net_u32 (vni);
16207
16208   /* send it... */
16209   S (mp);
16210
16211   /* Wait for a reply... */
16212   W (ret);
16213   return ret;
16214 }
16215
16216 #define api_lisp_adjacencies_get api_one_adjacencies_get
16217
16218 static int
16219 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16220 {
16221   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16222   int ret;
16223
16224   if (!vam->json_output)
16225     {
16226       print (vam->ofp, "VNIs");
16227     }
16228
16229   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16230
16231   /* send it... */
16232   S (mp);
16233
16234   /* Wait for a reply... */
16235   W (ret);
16236   return ret;
16237 }
16238
16239 static int
16240 api_one_map_server_dump (vat_main_t * vam)
16241 {
16242   vl_api_one_map_server_dump_t *mp;
16243   vl_api_control_ping_t *mp_ping;
16244   int ret;
16245
16246   if (!vam->json_output)
16247     {
16248       print (vam->ofp, "%=20s", "Map server");
16249     }
16250
16251   M (ONE_MAP_SERVER_DUMP, mp);
16252   /* send it... */
16253   S (mp);
16254
16255   /* Use a control ping for synchronization */
16256   M (CONTROL_PING, mp_ping);
16257   S (mp_ping);
16258
16259   /* Wait for a reply... */
16260   W (ret);
16261   return ret;
16262 }
16263
16264 #define api_lisp_map_server_dump api_one_map_server_dump
16265
16266 static int
16267 api_one_map_resolver_dump (vat_main_t * vam)
16268 {
16269   vl_api_one_map_resolver_dump_t *mp;
16270   vl_api_control_ping_t *mp_ping;
16271   int ret;
16272
16273   if (!vam->json_output)
16274     {
16275       print (vam->ofp, "%=20s", "Map resolver");
16276     }
16277
16278   M (ONE_MAP_RESOLVER_DUMP, mp);
16279   /* send it... */
16280   S (mp);
16281
16282   /* Use a control ping for synchronization */
16283   M (CONTROL_PING, mp_ping);
16284   S (mp_ping);
16285
16286   /* Wait for a reply... */
16287   W (ret);
16288   return ret;
16289 }
16290
16291 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16292
16293 static int
16294 api_one_stats_flush (vat_main_t * vam)
16295 {
16296   vl_api_one_stats_flush_t *mp;
16297   int ret = 0;
16298
16299   M (ONE_STATS_FLUSH, mp);
16300   S (mp);
16301   W (ret);
16302   return ret;
16303 }
16304
16305 static int
16306 api_one_stats_dump (vat_main_t * vam)
16307 {
16308   vl_api_one_stats_dump_t *mp;
16309   vl_api_control_ping_t *mp_ping;
16310   int ret;
16311
16312   M (ONE_STATS_DUMP, mp);
16313   /* send it... */
16314   S (mp);
16315
16316   /* Use a control ping for synchronization */
16317   M (CONTROL_PING, mp_ping);
16318   S (mp_ping);
16319
16320   /* Wait for a reply... */
16321   W (ret);
16322   return ret;
16323 }
16324
16325 static int
16326 api_show_one_status (vat_main_t * vam)
16327 {
16328   vl_api_show_one_status_t *mp;
16329   int ret;
16330
16331   if (!vam->json_output)
16332     {
16333       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16334     }
16335
16336   M (SHOW_ONE_STATUS, mp);
16337   /* send it... */
16338   S (mp);
16339   /* Wait for a reply... */
16340   W (ret);
16341   return ret;
16342 }
16343
16344 #define api_show_lisp_status api_show_one_status
16345
16346 static int
16347 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16348 {
16349   vl_api_gpe_fwd_entry_path_dump_t *mp;
16350   vl_api_control_ping_t *mp_ping;
16351   unformat_input_t *i = vam->input;
16352   u32 fwd_entry_index = ~0;
16353   int ret;
16354
16355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16356     {
16357       if (unformat (i, "index %d", &fwd_entry_index))
16358         ;
16359       else
16360         break;
16361     }
16362
16363   if (~0 == fwd_entry_index)
16364     {
16365       errmsg ("no index specified!");
16366       return -99;
16367     }
16368
16369   if (!vam->json_output)
16370     {
16371       print (vam->ofp, "first line");
16372     }
16373
16374   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16375
16376   /* send it... */
16377   S (mp);
16378   /* Use a control ping for synchronization */
16379   M (CONTROL_PING, mp_ping);
16380   S (mp_ping);
16381
16382   /* Wait for a reply... */
16383   W (ret);
16384   return ret;
16385 }
16386
16387 static int
16388 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16389 {
16390   vl_api_one_get_map_request_itr_rlocs_t *mp;
16391   int ret;
16392
16393   if (!vam->json_output)
16394     {
16395       print (vam->ofp, "%=20s", "itr-rlocs:");
16396     }
16397
16398   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16399   /* send it... */
16400   S (mp);
16401   /* Wait for a reply... */
16402   W (ret);
16403   return ret;
16404 }
16405
16406 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16407
16408 static int
16409 api_af_packet_create (vat_main_t * vam)
16410 {
16411   unformat_input_t *i = vam->input;
16412   vl_api_af_packet_create_t *mp;
16413   u8 *host_if_name = 0;
16414   u8 hw_addr[6];
16415   u8 random_hw_addr = 1;
16416   int ret;
16417
16418   memset (hw_addr, 0, sizeof (hw_addr));
16419
16420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16421     {
16422       if (unformat (i, "name %s", &host_if_name))
16423         vec_add1 (host_if_name, 0);
16424       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16425         random_hw_addr = 0;
16426       else
16427         break;
16428     }
16429
16430   if (!vec_len (host_if_name))
16431     {
16432       errmsg ("host-interface name must be specified");
16433       return -99;
16434     }
16435
16436   if (vec_len (host_if_name) > 64)
16437     {
16438       errmsg ("host-interface name too long");
16439       return -99;
16440     }
16441
16442   M (AF_PACKET_CREATE, mp);
16443
16444   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16445   clib_memcpy (mp->hw_addr, hw_addr, 6);
16446   mp->use_random_hw_addr = random_hw_addr;
16447   vec_free (host_if_name);
16448
16449   S (mp);
16450
16451   /* *INDENT-OFF* */
16452   W2 (ret,
16453       ({
16454         if (ret == 0)
16455           fprintf (vam->ofp ? vam->ofp : stderr,
16456                    " new sw_if_index = %d\n", vam->sw_if_index);
16457       }));
16458   /* *INDENT-ON* */
16459   return ret;
16460 }
16461
16462 static int
16463 api_af_packet_delete (vat_main_t * vam)
16464 {
16465   unformat_input_t *i = vam->input;
16466   vl_api_af_packet_delete_t *mp;
16467   u8 *host_if_name = 0;
16468   int ret;
16469
16470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16471     {
16472       if (unformat (i, "name %s", &host_if_name))
16473         vec_add1 (host_if_name, 0);
16474       else
16475         break;
16476     }
16477
16478   if (!vec_len (host_if_name))
16479     {
16480       errmsg ("host-interface name must be specified");
16481       return -99;
16482     }
16483
16484   if (vec_len (host_if_name) > 64)
16485     {
16486       errmsg ("host-interface name too long");
16487       return -99;
16488     }
16489
16490   M (AF_PACKET_DELETE, mp);
16491
16492   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16493   vec_free (host_if_name);
16494
16495   S (mp);
16496   W (ret);
16497   return ret;
16498 }
16499
16500 static int
16501 api_policer_add_del (vat_main_t * vam)
16502 {
16503   unformat_input_t *i = vam->input;
16504   vl_api_policer_add_del_t *mp;
16505   u8 is_add = 1;
16506   u8 *name = 0;
16507   u32 cir = 0;
16508   u32 eir = 0;
16509   u64 cb = 0;
16510   u64 eb = 0;
16511   u8 rate_type = 0;
16512   u8 round_type = 0;
16513   u8 type = 0;
16514   u8 color_aware = 0;
16515   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16516   int ret;
16517
16518   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16519   conform_action.dscp = 0;
16520   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16521   exceed_action.dscp = 0;
16522   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16523   violate_action.dscp = 0;
16524
16525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16526     {
16527       if (unformat (i, "del"))
16528         is_add = 0;
16529       else if (unformat (i, "name %s", &name))
16530         vec_add1 (name, 0);
16531       else if (unformat (i, "cir %u", &cir))
16532         ;
16533       else if (unformat (i, "eir %u", &eir))
16534         ;
16535       else if (unformat (i, "cb %u", &cb))
16536         ;
16537       else if (unformat (i, "eb %u", &eb))
16538         ;
16539       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16540                          &rate_type))
16541         ;
16542       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16543                          &round_type))
16544         ;
16545       else if (unformat (i, "type %U", unformat_policer_type, &type))
16546         ;
16547       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16548                          &conform_action))
16549         ;
16550       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16551                          &exceed_action))
16552         ;
16553       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16554                          &violate_action))
16555         ;
16556       else if (unformat (i, "color-aware"))
16557         color_aware = 1;
16558       else
16559         break;
16560     }
16561
16562   if (!vec_len (name))
16563     {
16564       errmsg ("policer name must be specified");
16565       return -99;
16566     }
16567
16568   if (vec_len (name) > 64)
16569     {
16570       errmsg ("policer name too long");
16571       return -99;
16572     }
16573
16574   M (POLICER_ADD_DEL, mp);
16575
16576   clib_memcpy (mp->name, name, vec_len (name));
16577   vec_free (name);
16578   mp->is_add = is_add;
16579   mp->cir = cir;
16580   mp->eir = eir;
16581   mp->cb = cb;
16582   mp->eb = eb;
16583   mp->rate_type = rate_type;
16584   mp->round_type = round_type;
16585   mp->type = type;
16586   mp->conform_action_type = conform_action.action_type;
16587   mp->conform_dscp = conform_action.dscp;
16588   mp->exceed_action_type = exceed_action.action_type;
16589   mp->exceed_dscp = exceed_action.dscp;
16590   mp->violate_action_type = violate_action.action_type;
16591   mp->violate_dscp = violate_action.dscp;
16592   mp->color_aware = color_aware;
16593
16594   S (mp);
16595   W (ret);
16596   return ret;
16597 }
16598
16599 static int
16600 api_policer_dump (vat_main_t * vam)
16601 {
16602   unformat_input_t *i = vam->input;
16603   vl_api_policer_dump_t *mp;
16604   vl_api_control_ping_t *mp_ping;
16605   u8 *match_name = 0;
16606   u8 match_name_valid = 0;
16607   int ret;
16608
16609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16610     {
16611       if (unformat (i, "name %s", &match_name))
16612         {
16613           vec_add1 (match_name, 0);
16614           match_name_valid = 1;
16615         }
16616       else
16617         break;
16618     }
16619
16620   M (POLICER_DUMP, mp);
16621   mp->match_name_valid = match_name_valid;
16622   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16623   vec_free (match_name);
16624   /* send it... */
16625   S (mp);
16626
16627   /* Use a control ping for synchronization */
16628   M (CONTROL_PING, mp_ping);
16629   S (mp_ping);
16630
16631   /* Wait for a reply... */
16632   W (ret);
16633   return ret;
16634 }
16635
16636 static int
16637 api_policer_classify_set_interface (vat_main_t * vam)
16638 {
16639   unformat_input_t *i = vam->input;
16640   vl_api_policer_classify_set_interface_t *mp;
16641   u32 sw_if_index;
16642   int sw_if_index_set;
16643   u32 ip4_table_index = ~0;
16644   u32 ip6_table_index = ~0;
16645   u32 l2_table_index = ~0;
16646   u8 is_add = 1;
16647   int ret;
16648
16649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16650     {
16651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16652         sw_if_index_set = 1;
16653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16654         sw_if_index_set = 1;
16655       else if (unformat (i, "del"))
16656         is_add = 0;
16657       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16658         ;
16659       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16660         ;
16661       else if (unformat (i, "l2-table %d", &l2_table_index))
16662         ;
16663       else
16664         {
16665           clib_warning ("parse error '%U'", format_unformat_error, i);
16666           return -99;
16667         }
16668     }
16669
16670   if (sw_if_index_set == 0)
16671     {
16672       errmsg ("missing interface name or sw_if_index");
16673       return -99;
16674     }
16675
16676   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16677
16678   mp->sw_if_index = ntohl (sw_if_index);
16679   mp->ip4_table_index = ntohl (ip4_table_index);
16680   mp->ip6_table_index = ntohl (ip6_table_index);
16681   mp->l2_table_index = ntohl (l2_table_index);
16682   mp->is_add = is_add;
16683
16684   S (mp);
16685   W (ret);
16686   return ret;
16687 }
16688
16689 static int
16690 api_policer_classify_dump (vat_main_t * vam)
16691 {
16692   unformat_input_t *i = vam->input;
16693   vl_api_policer_classify_dump_t *mp;
16694   vl_api_control_ping_t *mp_ping;
16695   u8 type = POLICER_CLASSIFY_N_TABLES;
16696   int ret;
16697
16698   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16699     ;
16700   else
16701     {
16702       errmsg ("classify table type must be specified");
16703       return -99;
16704     }
16705
16706   if (!vam->json_output)
16707     {
16708       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16709     }
16710
16711   M (POLICER_CLASSIFY_DUMP, mp);
16712   mp->type = type;
16713   /* send it... */
16714   S (mp);
16715
16716   /* Use a control ping for synchronization */
16717   M (CONTROL_PING, mp_ping);
16718   S (mp_ping);
16719
16720   /* Wait for a reply... */
16721   W (ret);
16722   return ret;
16723 }
16724
16725 static int
16726 api_netmap_create (vat_main_t * vam)
16727 {
16728   unformat_input_t *i = vam->input;
16729   vl_api_netmap_create_t *mp;
16730   u8 *if_name = 0;
16731   u8 hw_addr[6];
16732   u8 random_hw_addr = 1;
16733   u8 is_pipe = 0;
16734   u8 is_master = 0;
16735   int ret;
16736
16737   memset (hw_addr, 0, sizeof (hw_addr));
16738
16739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16740     {
16741       if (unformat (i, "name %s", &if_name))
16742         vec_add1 (if_name, 0);
16743       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16744         random_hw_addr = 0;
16745       else if (unformat (i, "pipe"))
16746         is_pipe = 1;
16747       else if (unformat (i, "master"))
16748         is_master = 1;
16749       else if (unformat (i, "slave"))
16750         is_master = 0;
16751       else
16752         break;
16753     }
16754
16755   if (!vec_len (if_name))
16756     {
16757       errmsg ("interface name must be specified");
16758       return -99;
16759     }
16760
16761   if (vec_len (if_name) > 64)
16762     {
16763       errmsg ("interface name too long");
16764       return -99;
16765     }
16766
16767   M (NETMAP_CREATE, mp);
16768
16769   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16770   clib_memcpy (mp->hw_addr, hw_addr, 6);
16771   mp->use_random_hw_addr = random_hw_addr;
16772   mp->is_pipe = is_pipe;
16773   mp->is_master = is_master;
16774   vec_free (if_name);
16775
16776   S (mp);
16777   W (ret);
16778   return ret;
16779 }
16780
16781 static int
16782 api_netmap_delete (vat_main_t * vam)
16783 {
16784   unformat_input_t *i = vam->input;
16785   vl_api_netmap_delete_t *mp;
16786   u8 *if_name = 0;
16787   int ret;
16788
16789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16790     {
16791       if (unformat (i, "name %s", &if_name))
16792         vec_add1 (if_name, 0);
16793       else
16794         break;
16795     }
16796
16797   if (!vec_len (if_name))
16798     {
16799       errmsg ("interface name must be specified");
16800       return -99;
16801     }
16802
16803   if (vec_len (if_name) > 64)
16804     {
16805       errmsg ("interface name too long");
16806       return -99;
16807     }
16808
16809   M (NETMAP_DELETE, mp);
16810
16811   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16812   vec_free (if_name);
16813
16814   S (mp);
16815   W (ret);
16816   return ret;
16817 }
16818
16819 static void
16820 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16821 {
16822   if (fp->afi == IP46_TYPE_IP6)
16823     print (vam->ofp,
16824            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16825            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16826            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16827            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16828            format_ip6_address, fp->next_hop);
16829   else if (fp->afi == IP46_TYPE_IP4)
16830     print (vam->ofp,
16831            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16832            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16833            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16834            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16835            format_ip4_address, fp->next_hop);
16836 }
16837
16838 static void
16839 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16840                                  vl_api_fib_path2_t * fp)
16841 {
16842   struct in_addr ip4;
16843   struct in6_addr ip6;
16844
16845   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16846   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16847   vat_json_object_add_uint (node, "is_local", fp->is_local);
16848   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16849   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16850   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16851   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16852   if (fp->afi == IP46_TYPE_IP4)
16853     {
16854       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16855       vat_json_object_add_ip4 (node, "next_hop", ip4);
16856     }
16857   else if (fp->afi == IP46_TYPE_IP6)
16858     {
16859       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16860       vat_json_object_add_ip6 (node, "next_hop", ip6);
16861     }
16862 }
16863
16864 static void
16865 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16866 {
16867   vat_main_t *vam = &vat_main;
16868   int count = ntohl (mp->mt_count);
16869   vl_api_fib_path2_t *fp;
16870   i32 i;
16871
16872   print (vam->ofp, "[%d]: sw_if_index %d via:",
16873          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16874   fp = mp->mt_paths;
16875   for (i = 0; i < count; i++)
16876     {
16877       vl_api_mpls_fib_path_print (vam, fp);
16878       fp++;
16879     }
16880
16881   print (vam->ofp, "");
16882 }
16883
16884 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16885 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16886
16887 static void
16888 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16889 {
16890   vat_main_t *vam = &vat_main;
16891   vat_json_node_t *node = NULL;
16892   int count = ntohl (mp->mt_count);
16893   vl_api_fib_path2_t *fp;
16894   i32 i;
16895
16896   if (VAT_JSON_ARRAY != vam->json_tree.type)
16897     {
16898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16899       vat_json_init_array (&vam->json_tree);
16900     }
16901   node = vat_json_array_add (&vam->json_tree);
16902
16903   vat_json_init_object (node);
16904   vat_json_object_add_uint (node, "tunnel_index",
16905                             ntohl (mp->mt_tunnel_index));
16906   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16907
16908   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16909
16910   fp = mp->mt_paths;
16911   for (i = 0; i < count; i++)
16912     {
16913       vl_api_mpls_fib_path_json_print (node, fp);
16914       fp++;
16915     }
16916 }
16917
16918 static int
16919 api_mpls_tunnel_dump (vat_main_t * vam)
16920 {
16921   vl_api_mpls_tunnel_dump_t *mp;
16922   vl_api_control_ping_t *mp_ping;
16923   i32 index = -1;
16924   int ret;
16925
16926   /* Parse args required to build the message */
16927   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16928     {
16929       if (!unformat (vam->input, "tunnel_index %d", &index))
16930         {
16931           index = -1;
16932           break;
16933         }
16934     }
16935
16936   print (vam->ofp, "  tunnel_index %d", index);
16937
16938   M (MPLS_TUNNEL_DUMP, mp);
16939   mp->tunnel_index = htonl (index);
16940   S (mp);
16941
16942   /* Use a control ping for synchronization */
16943   M (CONTROL_PING, mp_ping);
16944   S (mp_ping);
16945
16946   W (ret);
16947   return ret;
16948 }
16949
16950 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16951 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16952
16953
16954 static void
16955 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16956 {
16957   vat_main_t *vam = &vat_main;
16958   int count = ntohl (mp->count);
16959   vl_api_fib_path2_t *fp;
16960   int i;
16961
16962   print (vam->ofp,
16963          "table-id %d, label %u, ess_bit %u",
16964          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16965   fp = mp->path;
16966   for (i = 0; i < count; i++)
16967     {
16968       vl_api_mpls_fib_path_print (vam, fp);
16969       fp++;
16970     }
16971 }
16972
16973 static void vl_api_mpls_fib_details_t_handler_json
16974   (vl_api_mpls_fib_details_t * mp)
16975 {
16976   vat_main_t *vam = &vat_main;
16977   int count = ntohl (mp->count);
16978   vat_json_node_t *node = NULL;
16979   vl_api_fib_path2_t *fp;
16980   int i;
16981
16982   if (VAT_JSON_ARRAY != vam->json_tree.type)
16983     {
16984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16985       vat_json_init_array (&vam->json_tree);
16986     }
16987   node = vat_json_array_add (&vam->json_tree);
16988
16989   vat_json_init_object (node);
16990   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16991   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16992   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16993   vat_json_object_add_uint (node, "path_count", count);
16994   fp = mp->path;
16995   for (i = 0; i < count; i++)
16996     {
16997       vl_api_mpls_fib_path_json_print (node, fp);
16998       fp++;
16999     }
17000 }
17001
17002 static int
17003 api_mpls_fib_dump (vat_main_t * vam)
17004 {
17005   vl_api_mpls_fib_dump_t *mp;
17006   vl_api_control_ping_t *mp_ping;
17007   int ret;
17008
17009   M (MPLS_FIB_DUMP, mp);
17010   S (mp);
17011
17012   /* Use a control ping for synchronization */
17013   M (CONTROL_PING, mp_ping);
17014   S (mp_ping);
17015
17016   W (ret);
17017   return ret;
17018 }
17019
17020 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17021 #define vl_api_ip_fib_details_t_print vl_noop_handler
17022
17023 static void
17024 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17025 {
17026   vat_main_t *vam = &vat_main;
17027   int count = ntohl (mp->count);
17028   vl_api_fib_path_t *fp;
17029   int i;
17030
17031   print (vam->ofp,
17032          "table-id %d, prefix %U/%d",
17033          ntohl (mp->table_id), format_ip4_address, mp->address,
17034          mp->address_length);
17035   fp = mp->path;
17036   for (i = 0; i < count; i++)
17037     {
17038       if (fp->afi == IP46_TYPE_IP6)
17039         print (vam->ofp,
17040                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17041                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17042                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17043                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17044                format_ip6_address, fp->next_hop);
17045       else if (fp->afi == IP46_TYPE_IP4)
17046         print (vam->ofp,
17047                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17048                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17049                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17050                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17051                format_ip4_address, fp->next_hop);
17052       fp++;
17053     }
17054 }
17055
17056 static void vl_api_ip_fib_details_t_handler_json
17057   (vl_api_ip_fib_details_t * mp)
17058 {
17059   vat_main_t *vam = &vat_main;
17060   int count = ntohl (mp->count);
17061   vat_json_node_t *node = NULL;
17062   struct in_addr ip4;
17063   struct in6_addr ip6;
17064   vl_api_fib_path_t *fp;
17065   int i;
17066
17067   if (VAT_JSON_ARRAY != vam->json_tree.type)
17068     {
17069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17070       vat_json_init_array (&vam->json_tree);
17071     }
17072   node = vat_json_array_add (&vam->json_tree);
17073
17074   vat_json_init_object (node);
17075   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17076   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17077   vat_json_object_add_ip4 (node, "prefix", ip4);
17078   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17079   vat_json_object_add_uint (node, "path_count", count);
17080   fp = mp->path;
17081   for (i = 0; i < count; i++)
17082     {
17083       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17084       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17085       vat_json_object_add_uint (node, "is_local", fp->is_local);
17086       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17087       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17088       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17089       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17090       if (fp->afi == IP46_TYPE_IP4)
17091         {
17092           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17093           vat_json_object_add_ip4 (node, "next_hop", ip4);
17094         }
17095       else if (fp->afi == IP46_TYPE_IP6)
17096         {
17097           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17098           vat_json_object_add_ip6 (node, "next_hop", ip6);
17099         }
17100     }
17101 }
17102
17103 static int
17104 api_ip_fib_dump (vat_main_t * vam)
17105 {
17106   vl_api_ip_fib_dump_t *mp;
17107   vl_api_control_ping_t *mp_ping;
17108   int ret;
17109
17110   M (IP_FIB_DUMP, mp);
17111   S (mp);
17112
17113   /* Use a control ping for synchronization */
17114   M (CONTROL_PING, mp_ping);
17115   S (mp_ping);
17116
17117   W (ret);
17118   return ret;
17119 }
17120
17121 static int
17122 api_ip_mfib_dump (vat_main_t * vam)
17123 {
17124   vl_api_ip_mfib_dump_t *mp;
17125   vl_api_control_ping_t *mp_ping;
17126   int ret;
17127
17128   M (IP_MFIB_DUMP, mp);
17129   S (mp);
17130
17131   /* Use a control ping for synchronization */
17132   M (CONTROL_PING, mp_ping);
17133   S (mp_ping);
17134
17135   W (ret);
17136   return ret;
17137 }
17138
17139 static void vl_api_ip_neighbor_details_t_handler
17140   (vl_api_ip_neighbor_details_t * mp)
17141 {
17142   vat_main_t *vam = &vat_main;
17143
17144   print (vam->ofp, "%c %U %U",
17145          (mp->is_static) ? 'S' : 'D',
17146          format_ethernet_address, &mp->mac_address,
17147          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17148          &mp->ip_address);
17149 }
17150
17151 static void vl_api_ip_neighbor_details_t_handler_json
17152   (vl_api_ip_neighbor_details_t * mp)
17153 {
17154
17155   vat_main_t *vam = &vat_main;
17156   vat_json_node_t *node;
17157   struct in_addr ip4;
17158   struct in6_addr ip6;
17159
17160   if (VAT_JSON_ARRAY != vam->json_tree.type)
17161     {
17162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17163       vat_json_init_array (&vam->json_tree);
17164     }
17165   node = vat_json_array_add (&vam->json_tree);
17166
17167   vat_json_init_object (node);
17168   vat_json_object_add_string_copy (node, "flag",
17169                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17170                                    "dynamic");
17171
17172   vat_json_object_add_string_copy (node, "link_layer",
17173                                    format (0, "%U", format_ethernet_address,
17174                                            &mp->mac_address));
17175
17176   if (mp->is_ipv6)
17177     {
17178       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17179       vat_json_object_add_ip6 (node, "ip_address", ip6);
17180     }
17181   else
17182     {
17183       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17184       vat_json_object_add_ip4 (node, "ip_address", ip4);
17185     }
17186 }
17187
17188 static int
17189 api_ip_neighbor_dump (vat_main_t * vam)
17190 {
17191   unformat_input_t *i = vam->input;
17192   vl_api_ip_neighbor_dump_t *mp;
17193   vl_api_control_ping_t *mp_ping;
17194   u8 is_ipv6 = 0;
17195   u32 sw_if_index = ~0;
17196   int ret;
17197
17198   /* Parse args required to build the message */
17199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17200     {
17201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17202         ;
17203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17204         ;
17205       else if (unformat (i, "ip6"))
17206         is_ipv6 = 1;
17207       else
17208         break;
17209     }
17210
17211   if (sw_if_index == ~0)
17212     {
17213       errmsg ("missing interface name or sw_if_index");
17214       return -99;
17215     }
17216
17217   M (IP_NEIGHBOR_DUMP, mp);
17218   mp->is_ipv6 = (u8) is_ipv6;
17219   mp->sw_if_index = ntohl (sw_if_index);
17220   S (mp);
17221
17222   /* Use a control ping for synchronization */
17223   M (CONTROL_PING, mp_ping);
17224   S (mp_ping);
17225
17226   W (ret);
17227   return ret;
17228 }
17229
17230 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17231 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17232
17233 static void
17234 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17235 {
17236   vat_main_t *vam = &vat_main;
17237   int count = ntohl (mp->count);
17238   vl_api_fib_path_t *fp;
17239   int i;
17240
17241   print (vam->ofp,
17242          "table-id %d, prefix %U/%d",
17243          ntohl (mp->table_id), format_ip6_address, mp->address,
17244          mp->address_length);
17245   fp = mp->path;
17246   for (i = 0; i < count; i++)
17247     {
17248       if (fp->afi == IP46_TYPE_IP6)
17249         print (vam->ofp,
17250                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17251                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17252                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17253                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17254                format_ip6_address, fp->next_hop);
17255       else if (fp->afi == IP46_TYPE_IP4)
17256         print (vam->ofp,
17257                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17258                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17259                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17260                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17261                format_ip4_address, fp->next_hop);
17262       fp++;
17263     }
17264 }
17265
17266 static void vl_api_ip6_fib_details_t_handler_json
17267   (vl_api_ip6_fib_details_t * mp)
17268 {
17269   vat_main_t *vam = &vat_main;
17270   int count = ntohl (mp->count);
17271   vat_json_node_t *node = NULL;
17272   struct in_addr ip4;
17273   struct in6_addr ip6;
17274   vl_api_fib_path_t *fp;
17275   int i;
17276
17277   if (VAT_JSON_ARRAY != vam->json_tree.type)
17278     {
17279       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17280       vat_json_init_array (&vam->json_tree);
17281     }
17282   node = vat_json_array_add (&vam->json_tree);
17283
17284   vat_json_init_object (node);
17285   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17286   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17287   vat_json_object_add_ip6 (node, "prefix", ip6);
17288   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17289   vat_json_object_add_uint (node, "path_count", count);
17290   fp = mp->path;
17291   for (i = 0; i < count; i++)
17292     {
17293       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17294       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17295       vat_json_object_add_uint (node, "is_local", fp->is_local);
17296       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17297       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17298       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17299       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17300       if (fp->afi == IP46_TYPE_IP4)
17301         {
17302           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17303           vat_json_object_add_ip4 (node, "next_hop", ip4);
17304         }
17305       else if (fp->afi == IP46_TYPE_IP6)
17306         {
17307           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17308           vat_json_object_add_ip6 (node, "next_hop", ip6);
17309         }
17310     }
17311 }
17312
17313 static int
17314 api_ip6_fib_dump (vat_main_t * vam)
17315 {
17316   vl_api_ip6_fib_dump_t *mp;
17317   vl_api_control_ping_t *mp_ping;
17318   int ret;
17319
17320   M (IP6_FIB_DUMP, mp);
17321   S (mp);
17322
17323   /* Use a control ping for synchronization */
17324   M (CONTROL_PING, mp_ping);
17325   S (mp_ping);
17326
17327   W (ret);
17328   return ret;
17329 }
17330
17331 static int
17332 api_ip6_mfib_dump (vat_main_t * vam)
17333 {
17334   vl_api_ip6_mfib_dump_t *mp;
17335   vl_api_control_ping_t *mp_ping;
17336   int ret;
17337
17338   M (IP6_MFIB_DUMP, mp);
17339   S (mp);
17340
17341   /* Use a control ping for synchronization */
17342   M (CONTROL_PING, mp_ping);
17343   S (mp_ping);
17344
17345   W (ret);
17346   return ret;
17347 }
17348
17349 int
17350 api_classify_table_ids (vat_main_t * vam)
17351 {
17352   vl_api_classify_table_ids_t *mp;
17353   int ret;
17354
17355   /* Construct the API message */
17356   M (CLASSIFY_TABLE_IDS, mp);
17357   mp->context = 0;
17358
17359   S (mp);
17360   W (ret);
17361   return ret;
17362 }
17363
17364 int
17365 api_classify_table_by_interface (vat_main_t * vam)
17366 {
17367   unformat_input_t *input = vam->input;
17368   vl_api_classify_table_by_interface_t *mp;
17369
17370   u32 sw_if_index = ~0;
17371   int ret;
17372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17373     {
17374       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17375         ;
17376       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17377         ;
17378       else
17379         break;
17380     }
17381   if (sw_if_index == ~0)
17382     {
17383       errmsg ("missing interface name or sw_if_index");
17384       return -99;
17385     }
17386
17387   /* Construct the API message */
17388   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17389   mp->context = 0;
17390   mp->sw_if_index = ntohl (sw_if_index);
17391
17392   S (mp);
17393   W (ret);
17394   return ret;
17395 }
17396
17397 int
17398 api_classify_table_info (vat_main_t * vam)
17399 {
17400   unformat_input_t *input = vam->input;
17401   vl_api_classify_table_info_t *mp;
17402
17403   u32 table_id = ~0;
17404   int ret;
17405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17406     {
17407       if (unformat (input, "table_id %d", &table_id))
17408         ;
17409       else
17410         break;
17411     }
17412   if (table_id == ~0)
17413     {
17414       errmsg ("missing table id");
17415       return -99;
17416     }
17417
17418   /* Construct the API message */
17419   M (CLASSIFY_TABLE_INFO, mp);
17420   mp->context = 0;
17421   mp->table_id = ntohl (table_id);
17422
17423   S (mp);
17424   W (ret);
17425   return ret;
17426 }
17427
17428 int
17429 api_classify_session_dump (vat_main_t * vam)
17430 {
17431   unformat_input_t *input = vam->input;
17432   vl_api_classify_session_dump_t *mp;
17433   vl_api_control_ping_t *mp_ping;
17434
17435   u32 table_id = ~0;
17436   int ret;
17437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17438     {
17439       if (unformat (input, "table_id %d", &table_id))
17440         ;
17441       else
17442         break;
17443     }
17444   if (table_id == ~0)
17445     {
17446       errmsg ("missing table id");
17447       return -99;
17448     }
17449
17450   /* Construct the API message */
17451   M (CLASSIFY_SESSION_DUMP, mp);
17452   mp->context = 0;
17453   mp->table_id = ntohl (table_id);
17454   S (mp);
17455
17456   /* Use a control ping for synchronization */
17457   M (CONTROL_PING, mp_ping);
17458   S (mp_ping);
17459
17460   W (ret);
17461   return ret;
17462 }
17463
17464 static void
17465 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17466 {
17467   vat_main_t *vam = &vat_main;
17468
17469   print (vam->ofp, "collector_address %U, collector_port %d, "
17470          "src_address %U, vrf_id %d, path_mtu %u, "
17471          "template_interval %u, udp_checksum %d",
17472          format_ip4_address, mp->collector_address,
17473          ntohs (mp->collector_port),
17474          format_ip4_address, mp->src_address,
17475          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17476          ntohl (mp->template_interval), mp->udp_checksum);
17477
17478   vam->retval = 0;
17479   vam->result_ready = 1;
17480 }
17481
17482 static void
17483   vl_api_ipfix_exporter_details_t_handler_json
17484   (vl_api_ipfix_exporter_details_t * mp)
17485 {
17486   vat_main_t *vam = &vat_main;
17487   vat_json_node_t node;
17488   struct in_addr collector_address;
17489   struct in_addr src_address;
17490
17491   vat_json_init_object (&node);
17492   clib_memcpy (&collector_address, &mp->collector_address,
17493                sizeof (collector_address));
17494   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17495   vat_json_object_add_uint (&node, "collector_port",
17496                             ntohs (mp->collector_port));
17497   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17498   vat_json_object_add_ip4 (&node, "src_address", src_address);
17499   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17500   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17501   vat_json_object_add_uint (&node, "template_interval",
17502                             ntohl (mp->template_interval));
17503   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17504
17505   vat_json_print (vam->ofp, &node);
17506   vat_json_free (&node);
17507   vam->retval = 0;
17508   vam->result_ready = 1;
17509 }
17510
17511 int
17512 api_ipfix_exporter_dump (vat_main_t * vam)
17513 {
17514   vl_api_ipfix_exporter_dump_t *mp;
17515   int ret;
17516
17517   /* Construct the API message */
17518   M (IPFIX_EXPORTER_DUMP, mp);
17519   mp->context = 0;
17520
17521   S (mp);
17522   W (ret);
17523   return ret;
17524 }
17525
17526 static int
17527 api_ipfix_classify_stream_dump (vat_main_t * vam)
17528 {
17529   vl_api_ipfix_classify_stream_dump_t *mp;
17530   int ret;
17531
17532   /* Construct the API message */
17533   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17534   mp->context = 0;
17535
17536   S (mp);
17537   W (ret);
17538   return ret;
17539   /* NOTREACHED */
17540   return 0;
17541 }
17542
17543 static void
17544   vl_api_ipfix_classify_stream_details_t_handler
17545   (vl_api_ipfix_classify_stream_details_t * mp)
17546 {
17547   vat_main_t *vam = &vat_main;
17548   print (vam->ofp, "domain_id %d, src_port %d",
17549          ntohl (mp->domain_id), ntohs (mp->src_port));
17550   vam->retval = 0;
17551   vam->result_ready = 1;
17552 }
17553
17554 static void
17555   vl_api_ipfix_classify_stream_details_t_handler_json
17556   (vl_api_ipfix_classify_stream_details_t * mp)
17557 {
17558   vat_main_t *vam = &vat_main;
17559   vat_json_node_t node;
17560
17561   vat_json_init_object (&node);
17562   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17563   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17564
17565   vat_json_print (vam->ofp, &node);
17566   vat_json_free (&node);
17567   vam->retval = 0;
17568   vam->result_ready = 1;
17569 }
17570
17571 static int
17572 api_ipfix_classify_table_dump (vat_main_t * vam)
17573 {
17574   vl_api_ipfix_classify_table_dump_t *mp;
17575   vl_api_control_ping_t *mp_ping;
17576   int ret;
17577
17578   if (!vam->json_output)
17579     {
17580       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17581              "transport_protocol");
17582     }
17583
17584   /* Construct the API message */
17585   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17586
17587   /* send it... */
17588   S (mp);
17589
17590   /* Use a control ping for synchronization */
17591   M (CONTROL_PING, mp_ping);
17592   S (mp_ping);
17593
17594   W (ret);
17595   return ret;
17596 }
17597
17598 static void
17599   vl_api_ipfix_classify_table_details_t_handler
17600   (vl_api_ipfix_classify_table_details_t * mp)
17601 {
17602   vat_main_t *vam = &vat_main;
17603   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17604          mp->transport_protocol);
17605 }
17606
17607 static void
17608   vl_api_ipfix_classify_table_details_t_handler_json
17609   (vl_api_ipfix_classify_table_details_t * mp)
17610 {
17611   vat_json_node_t *node = NULL;
17612   vat_main_t *vam = &vat_main;
17613
17614   if (VAT_JSON_ARRAY != vam->json_tree.type)
17615     {
17616       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17617       vat_json_init_array (&vam->json_tree);
17618     }
17619
17620   node = vat_json_array_add (&vam->json_tree);
17621   vat_json_init_object (node);
17622
17623   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17624   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17625   vat_json_object_add_uint (node, "transport_protocol",
17626                             mp->transport_protocol);
17627 }
17628
17629 static int
17630 api_sw_interface_span_enable_disable (vat_main_t * vam)
17631 {
17632   unformat_input_t *i = vam->input;
17633   vl_api_sw_interface_span_enable_disable_t *mp;
17634   u32 src_sw_if_index = ~0;
17635   u32 dst_sw_if_index = ~0;
17636   u8 state = 3;
17637   int ret;
17638
17639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17640     {
17641       if (unformat
17642           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17643         ;
17644       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17645         ;
17646       else
17647         if (unformat
17648             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17649         ;
17650       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17651         ;
17652       else if (unformat (i, "disable"))
17653         state = 0;
17654       else if (unformat (i, "rx"))
17655         state = 1;
17656       else if (unformat (i, "tx"))
17657         state = 2;
17658       else if (unformat (i, "both"))
17659         state = 3;
17660       else
17661         break;
17662     }
17663
17664   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17665
17666   mp->sw_if_index_from = htonl (src_sw_if_index);
17667   mp->sw_if_index_to = htonl (dst_sw_if_index);
17668   mp->state = state;
17669
17670   S (mp);
17671   W (ret);
17672   return ret;
17673 }
17674
17675 static void
17676 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17677                                             * mp)
17678 {
17679   vat_main_t *vam = &vat_main;
17680   u8 *sw_if_from_name = 0;
17681   u8 *sw_if_to_name = 0;
17682   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17683   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17684   char *states[] = { "none", "rx", "tx", "both" };
17685   hash_pair_t *p;
17686
17687   /* *INDENT-OFF* */
17688   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17689   ({
17690     if ((u32) p->value[0] == sw_if_index_from)
17691       {
17692         sw_if_from_name = (u8 *)(p->key);
17693         if (sw_if_to_name)
17694           break;
17695       }
17696     if ((u32) p->value[0] == sw_if_index_to)
17697       {
17698         sw_if_to_name = (u8 *)(p->key);
17699         if (sw_if_from_name)
17700           break;
17701       }
17702   }));
17703   /* *INDENT-ON* */
17704   print (vam->ofp, "%20s => %20s (%s)",
17705          sw_if_from_name, sw_if_to_name, states[mp->state]);
17706 }
17707
17708 static void
17709   vl_api_sw_interface_span_details_t_handler_json
17710   (vl_api_sw_interface_span_details_t * mp)
17711 {
17712   vat_main_t *vam = &vat_main;
17713   vat_json_node_t *node = NULL;
17714   u8 *sw_if_from_name = 0;
17715   u8 *sw_if_to_name = 0;
17716   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17717   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17718   hash_pair_t *p;
17719
17720   /* *INDENT-OFF* */
17721   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17722   ({
17723     if ((u32) p->value[0] == sw_if_index_from)
17724       {
17725         sw_if_from_name = (u8 *)(p->key);
17726         if (sw_if_to_name)
17727           break;
17728       }
17729     if ((u32) p->value[0] == sw_if_index_to)
17730       {
17731         sw_if_to_name = (u8 *)(p->key);
17732         if (sw_if_from_name)
17733           break;
17734       }
17735   }));
17736   /* *INDENT-ON* */
17737
17738   if (VAT_JSON_ARRAY != vam->json_tree.type)
17739     {
17740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17741       vat_json_init_array (&vam->json_tree);
17742     }
17743   node = vat_json_array_add (&vam->json_tree);
17744
17745   vat_json_init_object (node);
17746   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17747   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17748   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17749   if (0 != sw_if_to_name)
17750     {
17751       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17752     }
17753   vat_json_object_add_uint (node, "state", mp->state);
17754 }
17755
17756 static int
17757 api_sw_interface_span_dump (vat_main_t * vam)
17758 {
17759   vl_api_sw_interface_span_dump_t *mp;
17760   vl_api_control_ping_t *mp_ping;
17761   int ret;
17762
17763   M (SW_INTERFACE_SPAN_DUMP, mp);
17764   S (mp);
17765
17766   /* Use a control ping for synchronization */
17767   M (CONTROL_PING, mp_ping);
17768   S (mp_ping);
17769
17770   W (ret);
17771   return ret;
17772 }
17773
17774 int
17775 api_pg_create_interface (vat_main_t * vam)
17776 {
17777   unformat_input_t *input = vam->input;
17778   vl_api_pg_create_interface_t *mp;
17779
17780   u32 if_id = ~0;
17781   int ret;
17782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17783     {
17784       if (unformat (input, "if_id %d", &if_id))
17785         ;
17786       else
17787         break;
17788     }
17789   if (if_id == ~0)
17790     {
17791       errmsg ("missing pg interface index");
17792       return -99;
17793     }
17794
17795   /* Construct the API message */
17796   M (PG_CREATE_INTERFACE, mp);
17797   mp->context = 0;
17798   mp->interface_id = ntohl (if_id);
17799
17800   S (mp);
17801   W (ret);
17802   return ret;
17803 }
17804
17805 int
17806 api_pg_capture (vat_main_t * vam)
17807 {
17808   unformat_input_t *input = vam->input;
17809   vl_api_pg_capture_t *mp;
17810
17811   u32 if_id = ~0;
17812   u8 enable = 1;
17813   u32 count = 1;
17814   u8 pcap_file_set = 0;
17815   u8 *pcap_file = 0;
17816   int ret;
17817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17818     {
17819       if (unformat (input, "if_id %d", &if_id))
17820         ;
17821       else if (unformat (input, "pcap %s", &pcap_file))
17822         pcap_file_set = 1;
17823       else if (unformat (input, "count %d", &count))
17824         ;
17825       else if (unformat (input, "disable"))
17826         enable = 0;
17827       else
17828         break;
17829     }
17830   if (if_id == ~0)
17831     {
17832       errmsg ("missing pg interface index");
17833       return -99;
17834     }
17835   if (pcap_file_set > 0)
17836     {
17837       if (vec_len (pcap_file) > 255)
17838         {
17839           errmsg ("pcap file name is too long");
17840           return -99;
17841         }
17842     }
17843
17844   u32 name_len = vec_len (pcap_file);
17845   /* Construct the API message */
17846   M (PG_CAPTURE, mp);
17847   mp->context = 0;
17848   mp->interface_id = ntohl (if_id);
17849   mp->is_enabled = enable;
17850   mp->count = ntohl (count);
17851   mp->pcap_name_length = ntohl (name_len);
17852   if (pcap_file_set != 0)
17853     {
17854       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17855     }
17856   vec_free (pcap_file);
17857
17858   S (mp);
17859   W (ret);
17860   return ret;
17861 }
17862
17863 int
17864 api_pg_enable_disable (vat_main_t * vam)
17865 {
17866   unformat_input_t *input = vam->input;
17867   vl_api_pg_enable_disable_t *mp;
17868
17869   u8 enable = 1;
17870   u8 stream_name_set = 0;
17871   u8 *stream_name = 0;
17872   int ret;
17873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17874     {
17875       if (unformat (input, "stream %s", &stream_name))
17876         stream_name_set = 1;
17877       else if (unformat (input, "disable"))
17878         enable = 0;
17879       else
17880         break;
17881     }
17882
17883   if (stream_name_set > 0)
17884     {
17885       if (vec_len (stream_name) > 255)
17886         {
17887           errmsg ("stream name too long");
17888           return -99;
17889         }
17890     }
17891
17892   u32 name_len = vec_len (stream_name);
17893   /* Construct the API message */
17894   M (PG_ENABLE_DISABLE, mp);
17895   mp->context = 0;
17896   mp->is_enabled = enable;
17897   if (stream_name_set != 0)
17898     {
17899       mp->stream_name_length = ntohl (name_len);
17900       clib_memcpy (mp->stream_name, stream_name, name_len);
17901     }
17902   vec_free (stream_name);
17903
17904   S (mp);
17905   W (ret);
17906   return ret;
17907 }
17908
17909 int
17910 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17911 {
17912   unformat_input_t *input = vam->input;
17913   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17914
17915   u16 *low_ports = 0;
17916   u16 *high_ports = 0;
17917   u16 this_low;
17918   u16 this_hi;
17919   ip4_address_t ip4_addr;
17920   ip6_address_t ip6_addr;
17921   u32 length;
17922   u32 tmp, tmp2;
17923   u8 prefix_set = 0;
17924   u32 vrf_id = ~0;
17925   u8 is_add = 1;
17926   u8 is_ipv6 = 0;
17927   int ret;
17928
17929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17930     {
17931       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17932         {
17933           prefix_set = 1;
17934         }
17935       else
17936         if (unformat
17937             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17938         {
17939           prefix_set = 1;
17940           is_ipv6 = 1;
17941         }
17942       else if (unformat (input, "vrf %d", &vrf_id))
17943         ;
17944       else if (unformat (input, "del"))
17945         is_add = 0;
17946       else if (unformat (input, "port %d", &tmp))
17947         {
17948           if (tmp == 0 || tmp > 65535)
17949             {
17950               errmsg ("port %d out of range", tmp);
17951               return -99;
17952             }
17953           this_low = tmp;
17954           this_hi = this_low + 1;
17955           vec_add1 (low_ports, this_low);
17956           vec_add1 (high_ports, this_hi);
17957         }
17958       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17959         {
17960           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17961             {
17962               errmsg ("incorrect range parameters");
17963               return -99;
17964             }
17965           this_low = tmp;
17966           /* Note: in debug CLI +1 is added to high before
17967              passing to real fn that does "the work"
17968              (ip_source_and_port_range_check_add_del).
17969              This fn is a wrapper around the binary API fn a
17970              control plane will call, which expects this increment
17971              to have occurred. Hence letting the binary API control
17972              plane fn do the increment for consistency between VAT
17973              and other control planes.
17974            */
17975           this_hi = tmp2;
17976           vec_add1 (low_ports, this_low);
17977           vec_add1 (high_ports, this_hi);
17978         }
17979       else
17980         break;
17981     }
17982
17983   if (prefix_set == 0)
17984     {
17985       errmsg ("<address>/<mask> not specified");
17986       return -99;
17987     }
17988
17989   if (vrf_id == ~0)
17990     {
17991       errmsg ("VRF ID required, not specified");
17992       return -99;
17993     }
17994
17995   if (vrf_id == 0)
17996     {
17997       errmsg
17998         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17999       return -99;
18000     }
18001
18002   if (vec_len (low_ports) == 0)
18003     {
18004       errmsg ("At least one port or port range required");
18005       return -99;
18006     }
18007
18008   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18009
18010   mp->is_add = is_add;
18011
18012   if (is_ipv6)
18013     {
18014       mp->is_ipv6 = 1;
18015       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18016     }
18017   else
18018     {
18019       mp->is_ipv6 = 0;
18020       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18021     }
18022
18023   mp->mask_length = length;
18024   mp->number_of_ranges = vec_len (low_ports);
18025
18026   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18027   vec_free (low_ports);
18028
18029   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18030   vec_free (high_ports);
18031
18032   mp->vrf_id = ntohl (vrf_id);
18033
18034   S (mp);
18035   W (ret);
18036   return ret;
18037 }
18038
18039 int
18040 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18041 {
18042   unformat_input_t *input = vam->input;
18043   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18044   u32 sw_if_index = ~0;
18045   int vrf_set = 0;
18046   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18047   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18048   u8 is_add = 1;
18049   int ret;
18050
18051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18052     {
18053       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18054         ;
18055       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18056         ;
18057       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18058         vrf_set = 1;
18059       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18060         vrf_set = 1;
18061       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18062         vrf_set = 1;
18063       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18064         vrf_set = 1;
18065       else if (unformat (input, "del"))
18066         is_add = 0;
18067       else
18068         break;
18069     }
18070
18071   if (sw_if_index == ~0)
18072     {
18073       errmsg ("Interface required but not specified");
18074       return -99;
18075     }
18076
18077   if (vrf_set == 0)
18078     {
18079       errmsg ("VRF ID required but not specified");
18080       return -99;
18081     }
18082
18083   if (tcp_out_vrf_id == 0
18084       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18085     {
18086       errmsg
18087         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18088       return -99;
18089     }
18090
18091   /* Construct the API message */
18092   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18093
18094   mp->sw_if_index = ntohl (sw_if_index);
18095   mp->is_add = is_add;
18096   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18097   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18098   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18099   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18100
18101   /* send it... */
18102   S (mp);
18103
18104   /* Wait for a reply... */
18105   W (ret);
18106   return ret;
18107 }
18108
18109 static int
18110 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18111 {
18112   unformat_input_t *i = vam->input;
18113   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18114   u32 local_sa_id = 0;
18115   u32 remote_sa_id = 0;
18116   ip4_address_t src_address;
18117   ip4_address_t dst_address;
18118   u8 is_add = 1;
18119   int ret;
18120
18121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18122     {
18123       if (unformat (i, "local_sa %d", &local_sa_id))
18124         ;
18125       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18126         ;
18127       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18128         ;
18129       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18130         ;
18131       else if (unformat (i, "del"))
18132         is_add = 0;
18133       else
18134         {
18135           clib_warning ("parse error '%U'", format_unformat_error, i);
18136           return -99;
18137         }
18138     }
18139
18140   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18141
18142   mp->local_sa_id = ntohl (local_sa_id);
18143   mp->remote_sa_id = ntohl (remote_sa_id);
18144   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18145   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18146   mp->is_add = is_add;
18147
18148   S (mp);
18149   W (ret);
18150   return ret;
18151 }
18152
18153 static int
18154 api_punt (vat_main_t * vam)
18155 {
18156   unformat_input_t *i = vam->input;
18157   vl_api_punt_t *mp;
18158   u32 ipv = ~0;
18159   u32 protocol = ~0;
18160   u32 port = ~0;
18161   int is_add = 1;
18162   int ret;
18163
18164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18165     {
18166       if (unformat (i, "ip %d", &ipv))
18167         ;
18168       else if (unformat (i, "protocol %d", &protocol))
18169         ;
18170       else if (unformat (i, "port %d", &port))
18171         ;
18172       else if (unformat (i, "del"))
18173         is_add = 0;
18174       else
18175         {
18176           clib_warning ("parse error '%U'", format_unformat_error, i);
18177           return -99;
18178         }
18179     }
18180
18181   M (PUNT, mp);
18182
18183   mp->is_add = (u8) is_add;
18184   mp->ipv = (u8) ipv;
18185   mp->l4_protocol = (u8) protocol;
18186   mp->l4_port = htons ((u16) port);
18187
18188   S (mp);
18189   W (ret);
18190   return ret;
18191 }
18192
18193 static void vl_api_ipsec_gre_tunnel_details_t_handler
18194   (vl_api_ipsec_gre_tunnel_details_t * mp)
18195 {
18196   vat_main_t *vam = &vat_main;
18197
18198   print (vam->ofp, "%11d%15U%15U%14d%14d",
18199          ntohl (mp->sw_if_index),
18200          format_ip4_address, &mp->src_address,
18201          format_ip4_address, &mp->dst_address,
18202          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18203 }
18204
18205 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18206   (vl_api_ipsec_gre_tunnel_details_t * mp)
18207 {
18208   vat_main_t *vam = &vat_main;
18209   vat_json_node_t *node = NULL;
18210   struct in_addr ip4;
18211
18212   if (VAT_JSON_ARRAY != vam->json_tree.type)
18213     {
18214       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18215       vat_json_init_array (&vam->json_tree);
18216     }
18217   node = vat_json_array_add (&vam->json_tree);
18218
18219   vat_json_init_object (node);
18220   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18221   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18222   vat_json_object_add_ip4 (node, "src_address", ip4);
18223   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18224   vat_json_object_add_ip4 (node, "dst_address", ip4);
18225   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18226   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18227 }
18228
18229 static int
18230 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18231 {
18232   unformat_input_t *i = vam->input;
18233   vl_api_ipsec_gre_tunnel_dump_t *mp;
18234   vl_api_control_ping_t *mp_ping;
18235   u32 sw_if_index;
18236   u8 sw_if_index_set = 0;
18237   int ret;
18238
18239   /* Parse args required to build the message */
18240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18241     {
18242       if (unformat (i, "sw_if_index %d", &sw_if_index))
18243         sw_if_index_set = 1;
18244       else
18245         break;
18246     }
18247
18248   if (sw_if_index_set == 0)
18249     {
18250       sw_if_index = ~0;
18251     }
18252
18253   if (!vam->json_output)
18254     {
18255       print (vam->ofp, "%11s%15s%15s%14s%14s",
18256              "sw_if_index", "src_address", "dst_address",
18257              "local_sa_id", "remote_sa_id");
18258     }
18259
18260   /* Get list of gre-tunnel interfaces */
18261   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18262
18263   mp->sw_if_index = htonl (sw_if_index);
18264
18265   S (mp);
18266
18267   /* Use a control ping for synchronization */
18268   M (CONTROL_PING, mp_ping);
18269   S (mp_ping);
18270
18271   W (ret);
18272   return ret;
18273 }
18274
18275 static int
18276 api_delete_subif (vat_main_t * vam)
18277 {
18278   unformat_input_t *i = vam->input;
18279   vl_api_delete_subif_t *mp;
18280   u32 sw_if_index = ~0;
18281   int ret;
18282
18283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18284     {
18285       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18286         ;
18287       if (unformat (i, "sw_if_index %d", &sw_if_index))
18288         ;
18289       else
18290         break;
18291     }
18292
18293   if (sw_if_index == ~0)
18294     {
18295       errmsg ("missing sw_if_index");
18296       return -99;
18297     }
18298
18299   /* Construct the API message */
18300   M (DELETE_SUBIF, mp);
18301   mp->sw_if_index = ntohl (sw_if_index);
18302
18303   S (mp);
18304   W (ret);
18305   return ret;
18306 }
18307
18308 #define foreach_pbb_vtr_op      \
18309 _("disable",  L2_VTR_DISABLED)  \
18310 _("pop",  L2_VTR_POP_2)         \
18311 _("push",  L2_VTR_PUSH_2)
18312
18313 static int
18314 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18315 {
18316   unformat_input_t *i = vam->input;
18317   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18318   u32 sw_if_index = ~0, vtr_op = ~0;
18319   u16 outer_tag = ~0;
18320   u8 dmac[6], smac[6];
18321   u8 dmac_set = 0, smac_set = 0;
18322   u16 vlanid = 0;
18323   u32 sid = ~0;
18324   u32 tmp;
18325   int ret;
18326
18327   /* Shut up coverity */
18328   memset (dmac, 0, sizeof (dmac));
18329   memset (smac, 0, sizeof (smac));
18330
18331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18332     {
18333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18334         ;
18335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18336         ;
18337       else if (unformat (i, "vtr_op %d", &vtr_op))
18338         ;
18339 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18340       foreach_pbb_vtr_op
18341 #undef _
18342         else if (unformat (i, "translate_pbb_stag"))
18343         {
18344           if (unformat (i, "%d", &tmp))
18345             {
18346               vtr_op = L2_VTR_TRANSLATE_2_1;
18347               outer_tag = tmp;
18348             }
18349           else
18350             {
18351               errmsg
18352                 ("translate_pbb_stag operation requires outer tag definition");
18353               return -99;
18354             }
18355         }
18356       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18357         dmac_set++;
18358       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18359         smac_set++;
18360       else if (unformat (i, "sid %d", &sid))
18361         ;
18362       else if (unformat (i, "vlanid %d", &tmp))
18363         vlanid = tmp;
18364       else
18365         {
18366           clib_warning ("parse error '%U'", format_unformat_error, i);
18367           return -99;
18368         }
18369     }
18370
18371   if ((sw_if_index == ~0) || (vtr_op == ~0))
18372     {
18373       errmsg ("missing sw_if_index or vtr operation");
18374       return -99;
18375     }
18376   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18377       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18378     {
18379       errmsg
18380         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18381       return -99;
18382     }
18383
18384   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18385   mp->sw_if_index = ntohl (sw_if_index);
18386   mp->vtr_op = ntohl (vtr_op);
18387   mp->outer_tag = ntohs (outer_tag);
18388   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18389   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18390   mp->b_vlanid = ntohs (vlanid);
18391   mp->i_sid = ntohl (sid);
18392
18393   S (mp);
18394   W (ret);
18395   return ret;
18396 }
18397
18398 static int
18399 api_flow_classify_set_interface (vat_main_t * vam)
18400 {
18401   unformat_input_t *i = vam->input;
18402   vl_api_flow_classify_set_interface_t *mp;
18403   u32 sw_if_index;
18404   int sw_if_index_set;
18405   u32 ip4_table_index = ~0;
18406   u32 ip6_table_index = ~0;
18407   u8 is_add = 1;
18408   int ret;
18409
18410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18411     {
18412       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18413         sw_if_index_set = 1;
18414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18415         sw_if_index_set = 1;
18416       else if (unformat (i, "del"))
18417         is_add = 0;
18418       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18419         ;
18420       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18421         ;
18422       else
18423         {
18424           clib_warning ("parse error '%U'", format_unformat_error, i);
18425           return -99;
18426         }
18427     }
18428
18429   if (sw_if_index_set == 0)
18430     {
18431       errmsg ("missing interface name or sw_if_index");
18432       return -99;
18433     }
18434
18435   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18436
18437   mp->sw_if_index = ntohl (sw_if_index);
18438   mp->ip4_table_index = ntohl (ip4_table_index);
18439   mp->ip6_table_index = ntohl (ip6_table_index);
18440   mp->is_add = is_add;
18441
18442   S (mp);
18443   W (ret);
18444   return ret;
18445 }
18446
18447 static int
18448 api_flow_classify_dump (vat_main_t * vam)
18449 {
18450   unformat_input_t *i = vam->input;
18451   vl_api_flow_classify_dump_t *mp;
18452   vl_api_control_ping_t *mp_ping;
18453   u8 type = FLOW_CLASSIFY_N_TABLES;
18454   int ret;
18455
18456   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18457     ;
18458   else
18459     {
18460       errmsg ("classify table type must be specified");
18461       return -99;
18462     }
18463
18464   if (!vam->json_output)
18465     {
18466       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18467     }
18468
18469   M (FLOW_CLASSIFY_DUMP, mp);
18470   mp->type = type;
18471   /* send it... */
18472   S (mp);
18473
18474   /* Use a control ping for synchronization */
18475   M (CONTROL_PING, mp_ping);
18476   S (mp_ping);
18477
18478   /* Wait for a reply... */
18479   W (ret);
18480   return ret;
18481 }
18482
18483 static int
18484 api_feature_enable_disable (vat_main_t * vam)
18485 {
18486   unformat_input_t *i = vam->input;
18487   vl_api_feature_enable_disable_t *mp;
18488   u8 *arc_name = 0;
18489   u8 *feature_name = 0;
18490   u32 sw_if_index = ~0;
18491   u8 enable = 1;
18492   int ret;
18493
18494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18495     {
18496       if (unformat (i, "arc_name %s", &arc_name))
18497         ;
18498       else if (unformat (i, "feature_name %s", &feature_name))
18499         ;
18500       else
18501         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18502         ;
18503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18504         ;
18505       else if (unformat (i, "disable"))
18506         enable = 0;
18507       else
18508         break;
18509     }
18510
18511   if (arc_name == 0)
18512     {
18513       errmsg ("missing arc name");
18514       return -99;
18515     }
18516   if (vec_len (arc_name) > 63)
18517     {
18518       errmsg ("arc name too long");
18519     }
18520
18521   if (feature_name == 0)
18522     {
18523       errmsg ("missing feature name");
18524       return -99;
18525     }
18526   if (vec_len (feature_name) > 63)
18527     {
18528       errmsg ("feature name too long");
18529     }
18530
18531   if (sw_if_index == ~0)
18532     {
18533       errmsg ("missing interface name or sw_if_index");
18534       return -99;
18535     }
18536
18537   /* Construct the API message */
18538   M (FEATURE_ENABLE_DISABLE, mp);
18539   mp->sw_if_index = ntohl (sw_if_index);
18540   mp->enable = enable;
18541   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18542   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18543   vec_free (arc_name);
18544   vec_free (feature_name);
18545
18546   S (mp);
18547   W (ret);
18548   return ret;
18549 }
18550
18551 static int
18552 api_sw_interface_tag_add_del (vat_main_t * vam)
18553 {
18554   unformat_input_t *i = vam->input;
18555   vl_api_sw_interface_tag_add_del_t *mp;
18556   u32 sw_if_index = ~0;
18557   u8 *tag = 0;
18558   u8 enable = 1;
18559   int ret;
18560
18561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18562     {
18563       if (unformat (i, "tag %s", &tag))
18564         ;
18565       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18566         ;
18567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18568         ;
18569       else if (unformat (i, "del"))
18570         enable = 0;
18571       else
18572         break;
18573     }
18574
18575   if (sw_if_index == ~0)
18576     {
18577       errmsg ("missing interface name or sw_if_index");
18578       return -99;
18579     }
18580
18581   if (enable && (tag == 0))
18582     {
18583       errmsg ("no tag specified");
18584       return -99;
18585     }
18586
18587   /* Construct the API message */
18588   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18589   mp->sw_if_index = ntohl (sw_if_index);
18590   mp->is_add = enable;
18591   if (enable)
18592     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18593   vec_free (tag);
18594
18595   S (mp);
18596   W (ret);
18597   return ret;
18598 }
18599
18600 static void vl_api_l2_xconnect_details_t_handler
18601   (vl_api_l2_xconnect_details_t * mp)
18602 {
18603   vat_main_t *vam = &vat_main;
18604
18605   print (vam->ofp, "%15d%15d",
18606          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18607 }
18608
18609 static void vl_api_l2_xconnect_details_t_handler_json
18610   (vl_api_l2_xconnect_details_t * mp)
18611 {
18612   vat_main_t *vam = &vat_main;
18613   vat_json_node_t *node = NULL;
18614
18615   if (VAT_JSON_ARRAY != vam->json_tree.type)
18616     {
18617       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18618       vat_json_init_array (&vam->json_tree);
18619     }
18620   node = vat_json_array_add (&vam->json_tree);
18621
18622   vat_json_init_object (node);
18623   vat_json_object_add_uint (node, "rx_sw_if_index",
18624                             ntohl (mp->rx_sw_if_index));
18625   vat_json_object_add_uint (node, "tx_sw_if_index",
18626                             ntohl (mp->tx_sw_if_index));
18627 }
18628
18629 static int
18630 api_l2_xconnect_dump (vat_main_t * vam)
18631 {
18632   vl_api_l2_xconnect_dump_t *mp;
18633   vl_api_control_ping_t *mp_ping;
18634   int ret;
18635
18636   if (!vam->json_output)
18637     {
18638       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18639     }
18640
18641   M (L2_XCONNECT_DUMP, mp);
18642
18643   S (mp);
18644
18645   /* Use a control ping for synchronization */
18646   M (CONTROL_PING, mp_ping);
18647   S (mp_ping);
18648
18649   W (ret);
18650   return ret;
18651 }
18652
18653 static int
18654 api_sw_interface_set_mtu (vat_main_t * vam)
18655 {
18656   unformat_input_t *i = vam->input;
18657   vl_api_sw_interface_set_mtu_t *mp;
18658   u32 sw_if_index = ~0;
18659   u32 mtu = 0;
18660   int ret;
18661
18662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18663     {
18664       if (unformat (i, "mtu %d", &mtu))
18665         ;
18666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18667         ;
18668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18669         ;
18670       else
18671         break;
18672     }
18673
18674   if (sw_if_index == ~0)
18675     {
18676       errmsg ("missing interface name or sw_if_index");
18677       return -99;
18678     }
18679
18680   if (mtu == 0)
18681     {
18682       errmsg ("no mtu specified");
18683       return -99;
18684     }
18685
18686   /* Construct the API message */
18687   M (SW_INTERFACE_SET_MTU, mp);
18688   mp->sw_if_index = ntohl (sw_if_index);
18689   mp->mtu = ntohs ((u16) mtu);
18690
18691   S (mp);
18692   W (ret);
18693   return ret;
18694 }
18695
18696 static int
18697 api_p2p_ethernet_add (vat_main_t * vam)
18698 {
18699   unformat_input_t *i = vam->input;
18700   vl_api_p2p_ethernet_add_t *mp;
18701   u32 parent_if_index = ~0;
18702   u8 remote_mac[6];
18703   u8 mac_set = 0;
18704   int ret;
18705
18706   memset (remote_mac, 0, sizeof (remote_mac));
18707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18708     {
18709       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
18710         ;
18711       else if (unformat (i, "sw_if_index %d", &parent_if_index))
18712         ;
18713       else
18714         if (unformat
18715             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
18716         mac_set++;
18717       else
18718         {
18719           clib_warning ("parse error '%U'", format_unformat_error, i);
18720           return -99;
18721         }
18722     }
18723
18724   if (parent_if_index == ~0)
18725     {
18726       errmsg ("missing interface name or sw_if_index");
18727       return -99;
18728     }
18729   if (mac_set == 0)
18730     {
18731       errmsg ("missing remote mac address");
18732       return -99;
18733     }
18734
18735   M (P2P_ETHERNET_ADD, mp);
18736   mp->parent_if_index = ntohl (parent_if_index);
18737   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
18738
18739   S (mp);
18740   W (ret);
18741   return ret;
18742 }
18743
18744 static int
18745 api_p2p_ethernet_del (vat_main_t * vam)
18746 {
18747   unformat_input_t *i = vam->input;
18748   vl_api_p2p_ethernet_del_t *mp;
18749   u32 parent_if_index = ~0;
18750   u8 remote_mac[6];
18751   u8 mac_set = 0;
18752   int ret;
18753
18754   memset (remote_mac, 0, sizeof (remote_mac));
18755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18756     {
18757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
18758         ;
18759       else if (unformat (i, "sw_if_index %d", &parent_if_index))
18760         ;
18761       else
18762         if (unformat
18763             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
18764         mac_set++;
18765       else
18766         {
18767           clib_warning ("parse error '%U'", format_unformat_error, i);
18768           return -99;
18769         }
18770     }
18771
18772   if (parent_if_index == ~0)
18773     {
18774       errmsg ("missing interface name or sw_if_index");
18775       return -99;
18776     }
18777   if (mac_set == 0)
18778     {
18779       errmsg ("missing remote mac address");
18780       return -99;
18781     }
18782
18783   M (P2P_ETHERNET_DEL, mp);
18784   mp->parent_if_index = ntohl (parent_if_index);
18785   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
18786
18787   S (mp);
18788   W (ret);
18789   return ret;
18790 }
18791
18792 static int
18793 q_or_quit (vat_main_t * vam)
18794 {
18795 #if VPP_API_TEST_BUILTIN == 0
18796   longjmp (vam->jump_buf, 1);
18797 #endif
18798   return 0;                     /* not so much */
18799 }
18800
18801 static int
18802 q (vat_main_t * vam)
18803 {
18804   return q_or_quit (vam);
18805 }
18806
18807 static int
18808 quit (vat_main_t * vam)
18809 {
18810   return q_or_quit (vam);
18811 }
18812
18813 static int
18814 comment (vat_main_t * vam)
18815 {
18816   return 0;
18817 }
18818
18819 static int
18820 cmd_cmp (void *a1, void *a2)
18821 {
18822   u8 **c1 = a1;
18823   u8 **c2 = a2;
18824
18825   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18826 }
18827
18828 static int
18829 help (vat_main_t * vam)
18830 {
18831   u8 **cmds = 0;
18832   u8 *name = 0;
18833   hash_pair_t *p;
18834   unformat_input_t *i = vam->input;
18835   int j;
18836
18837   if (unformat (i, "%s", &name))
18838     {
18839       uword *hs;
18840
18841       vec_add1 (name, 0);
18842
18843       hs = hash_get_mem (vam->help_by_name, name);
18844       if (hs)
18845         print (vam->ofp, "usage: %s %s", name, hs[0]);
18846       else
18847         print (vam->ofp, "No such msg / command '%s'", name);
18848       vec_free (name);
18849       return 0;
18850     }
18851
18852   print (vam->ofp, "Help is available for the following:");
18853
18854     /* *INDENT-OFF* */
18855     hash_foreach_pair (p, vam->function_by_name,
18856     ({
18857       vec_add1 (cmds, (u8 *)(p->key));
18858     }));
18859     /* *INDENT-ON* */
18860
18861   vec_sort_with_function (cmds, cmd_cmp);
18862
18863   for (j = 0; j < vec_len (cmds); j++)
18864     print (vam->ofp, "%s", cmds[j]);
18865
18866   vec_free (cmds);
18867   return 0;
18868 }
18869
18870 static int
18871 set (vat_main_t * vam)
18872 {
18873   u8 *name = 0, *value = 0;
18874   unformat_input_t *i = vam->input;
18875
18876   if (unformat (i, "%s", &name))
18877     {
18878       /* The input buffer is a vector, not a string. */
18879       value = vec_dup (i->buffer);
18880       vec_delete (value, i->index, 0);
18881       /* Almost certainly has a trailing newline */
18882       if (value[vec_len (value) - 1] == '\n')
18883         value[vec_len (value) - 1] = 0;
18884       /* Make sure it's a proper string, one way or the other */
18885       vec_add1 (value, 0);
18886       (void) clib_macro_set_value (&vam->macro_main,
18887                                    (char *) name, (char *) value);
18888     }
18889   else
18890     errmsg ("usage: set <name> <value>");
18891
18892   vec_free (name);
18893   vec_free (value);
18894   return 0;
18895 }
18896
18897 static int
18898 unset (vat_main_t * vam)
18899 {
18900   u8 *name = 0;
18901
18902   if (unformat (vam->input, "%s", &name))
18903     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18904       errmsg ("unset: %s wasn't set", name);
18905   vec_free (name);
18906   return 0;
18907 }
18908
18909 typedef struct
18910 {
18911   u8 *name;
18912   u8 *value;
18913 } macro_sort_t;
18914
18915
18916 static int
18917 macro_sort_cmp (void *a1, void *a2)
18918 {
18919   macro_sort_t *s1 = a1;
18920   macro_sort_t *s2 = a2;
18921
18922   return strcmp ((char *) (s1->name), (char *) (s2->name));
18923 }
18924
18925 static int
18926 dump_macro_table (vat_main_t * vam)
18927 {
18928   macro_sort_t *sort_me = 0, *sm;
18929   int i;
18930   hash_pair_t *p;
18931
18932     /* *INDENT-OFF* */
18933     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18934     ({
18935       vec_add2 (sort_me, sm, 1);
18936       sm->name = (u8 *)(p->key);
18937       sm->value = (u8 *) (p->value[0]);
18938     }));
18939     /* *INDENT-ON* */
18940
18941   vec_sort_with_function (sort_me, macro_sort_cmp);
18942
18943   if (vec_len (sort_me))
18944     print (vam->ofp, "%-15s%s", "Name", "Value");
18945   else
18946     print (vam->ofp, "The macro table is empty...");
18947
18948   for (i = 0; i < vec_len (sort_me); i++)
18949     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18950   return 0;
18951 }
18952
18953 static int
18954 dump_node_table (vat_main_t * vam)
18955 {
18956   int i, j;
18957   vlib_node_t *node, *next_node;
18958
18959   if (vec_len (vam->graph_nodes) == 0)
18960     {
18961       print (vam->ofp, "Node table empty, issue get_node_graph...");
18962       return 0;
18963     }
18964
18965   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18966     {
18967       node = vam->graph_nodes[i];
18968       print (vam->ofp, "[%d] %s", i, node->name);
18969       for (j = 0; j < vec_len (node->next_nodes); j++)
18970         {
18971           if (node->next_nodes[j] != ~0)
18972             {
18973               next_node = vam->graph_nodes[node->next_nodes[j]];
18974               print (vam->ofp, "  [%d] %s", j, next_node->name);
18975             }
18976         }
18977     }
18978   return 0;
18979 }
18980
18981 static int
18982 value_sort_cmp (void *a1, void *a2)
18983 {
18984   name_sort_t *n1 = a1;
18985   name_sort_t *n2 = a2;
18986
18987   if (n1->value < n2->value)
18988     return -1;
18989   if (n1->value > n2->value)
18990     return 1;
18991   return 0;
18992 }
18993
18994
18995 static int
18996 dump_msg_api_table (vat_main_t * vam)
18997 {
18998   api_main_t *am = &api_main;
18999   name_sort_t *nses = 0, *ns;
19000   hash_pair_t *hp;
19001   int i;
19002
19003   /* *INDENT-OFF* */
19004   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19005   ({
19006     vec_add2 (nses, ns, 1);
19007     ns->name = (u8 *)(hp->key);
19008     ns->value = (u32) hp->value[0];
19009   }));
19010   /* *INDENT-ON* */
19011
19012   vec_sort_with_function (nses, value_sort_cmp);
19013
19014   for (i = 0; i < vec_len (nses); i++)
19015     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19016   vec_free (nses);
19017   return 0;
19018 }
19019
19020 static int
19021 get_msg_id (vat_main_t * vam)
19022 {
19023   u8 *name_and_crc;
19024   u32 message_index;
19025
19026   if (unformat (vam->input, "%s", &name_and_crc))
19027     {
19028       message_index = vl_api_get_msg_index (name_and_crc);
19029       if (message_index == ~0)
19030         {
19031           print (vam->ofp, " '%s' not found", name_and_crc);
19032           return 0;
19033         }
19034       print (vam->ofp, " '%s' has message index %d",
19035              name_and_crc, message_index);
19036       return 0;
19037     }
19038   errmsg ("name_and_crc required...");
19039   return 0;
19040 }
19041
19042 static int
19043 search_node_table (vat_main_t * vam)
19044 {
19045   unformat_input_t *line_input = vam->input;
19046   u8 *node_to_find;
19047   int j;
19048   vlib_node_t *node, *next_node;
19049   uword *p;
19050
19051   if (vam->graph_node_index_by_name == 0)
19052     {
19053       print (vam->ofp, "Node table empty, issue get_node_graph...");
19054       return 0;
19055     }
19056
19057   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19058     {
19059       if (unformat (line_input, "%s", &node_to_find))
19060         {
19061           vec_add1 (node_to_find, 0);
19062           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19063           if (p == 0)
19064             {
19065               print (vam->ofp, "%s not found...", node_to_find);
19066               goto out;
19067             }
19068           node = vam->graph_nodes[p[0]];
19069           print (vam->ofp, "[%d] %s", p[0], node->name);
19070           for (j = 0; j < vec_len (node->next_nodes); j++)
19071             {
19072               if (node->next_nodes[j] != ~0)
19073                 {
19074                   next_node = vam->graph_nodes[node->next_nodes[j]];
19075                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19076                 }
19077             }
19078         }
19079
19080       else
19081         {
19082           clib_warning ("parse error '%U'", format_unformat_error,
19083                         line_input);
19084           return -99;
19085         }
19086
19087     out:
19088       vec_free (node_to_find);
19089
19090     }
19091
19092   return 0;
19093 }
19094
19095
19096 static int
19097 script (vat_main_t * vam)
19098 {
19099 #if (VPP_API_TEST_BUILTIN==0)
19100   u8 *s = 0;
19101   char *save_current_file;
19102   unformat_input_t save_input;
19103   jmp_buf save_jump_buf;
19104   u32 save_line_number;
19105
19106   FILE *new_fp, *save_ifp;
19107
19108   if (unformat (vam->input, "%s", &s))
19109     {
19110       new_fp = fopen ((char *) s, "r");
19111       if (new_fp == 0)
19112         {
19113           errmsg ("Couldn't open script file %s", s);
19114           vec_free (s);
19115           return -99;
19116         }
19117     }
19118   else
19119     {
19120       errmsg ("Missing script name");
19121       return -99;
19122     }
19123
19124   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19125   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19126   save_ifp = vam->ifp;
19127   save_line_number = vam->input_line_number;
19128   save_current_file = (char *) vam->current_file;
19129
19130   vam->input_line_number = 0;
19131   vam->ifp = new_fp;
19132   vam->current_file = s;
19133   do_one_file (vam);
19134
19135   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19136   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19137   vam->ifp = save_ifp;
19138   vam->input_line_number = save_line_number;
19139   vam->current_file = (u8 *) save_current_file;
19140   vec_free (s);
19141
19142   return 0;
19143 #else
19144   clib_warning ("use the exec command...");
19145   return -99;
19146 #endif
19147 }
19148
19149 static int
19150 echo (vat_main_t * vam)
19151 {
19152   print (vam->ofp, "%v", vam->input->buffer);
19153   return 0;
19154 }
19155
19156 /* List of API message constructors, CLI names map to api_xxx */
19157 #define foreach_vpe_api_msg                                             \
19158 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19159 _(sw_interface_dump,"")                                                 \
19160 _(sw_interface_set_flags,                                               \
19161   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19162 _(sw_interface_add_del_address,                                         \
19163   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19164 _(sw_interface_set_table,                                               \
19165   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19166 _(sw_interface_set_mpls_enable,                                         \
19167   "<intfc> | sw_if_index [disable | dis]")                              \
19168 _(sw_interface_set_vpath,                                               \
19169   "<intfc> | sw_if_index <id> enable | disable")                        \
19170 _(sw_interface_set_vxlan_bypass,                                        \
19171   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19172 _(sw_interface_set_l2_xconnect,                                         \
19173   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19174   "enable | disable")                                                   \
19175 _(sw_interface_set_l2_bridge,                                           \
19176   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19177   "[shg <split-horizon-group>] [bvi]\n"                                 \
19178   "enable | disable")                                                   \
19179 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19180 _(bridge_domain_add_del,                                                \
19181   "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") \
19182 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19183 _(l2fib_add_del,                                                        \
19184   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19185 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19186 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19187 _(l2_flags,                                                             \
19188   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
19189 _(bridge_flags,                                                         \
19190   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19191 _(tap_connect,                                                          \
19192   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19193 _(tap_modify,                                                           \
19194   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19195 _(tap_delete,                                                           \
19196   "<vpp-if-name> | sw_if_index <id>")                                   \
19197 _(sw_interface_tap_dump, "")                                            \
19198 _(ip_add_del_route,                                                     \
19199   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19200   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19201   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19202   "[multipath] [count <n>]")                                            \
19203 _(ip_mroute_add_del,                                                    \
19204   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19205   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19206 _(mpls_route_add_del,                                                   \
19207   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19208   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19209   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19210   "[multipath] [count <n>]")                                            \
19211 _(mpls_ip_bind_unbind,                                                  \
19212   "<label> <addr/len>")                                                 \
19213 _(mpls_tunnel_add_del,                                                  \
19214   " via <addr> [table-id <n>]\n"                                        \
19215   "sw_if_index <id>] [l2]  [del]")                                      \
19216 _(proxy_arp_add_del,                                                    \
19217   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19218 _(proxy_arp_intfc_enable_disable,                                       \
19219   "<intfc> | sw_if_index <id> enable | disable")                        \
19220 _(sw_interface_set_unnumbered,                                          \
19221   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19222 _(ip_neighbor_add_del,                                                  \
19223   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19224   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19225 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19226 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19227 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19228   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19229   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19230   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19231 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19232 _(reset_fib, "vrf <n> [ipv6]")                                          \
19233 _(dhcp_proxy_config,                                                    \
19234   "svr <v46-address> src <v46-address>\n"                               \
19235    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19236 _(dhcp_proxy_set_vss,                                                   \
19237   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19238 _(dhcp_proxy_dump, "ip6")                                               \
19239 _(dhcp_client_config,                                                   \
19240   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19241 _(set_ip_flow_hash,                                                     \
19242   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19243 _(sw_interface_ip6_enable_disable,                                      \
19244   "<intfc> | sw_if_index <id> enable | disable")                        \
19245 _(sw_interface_ip6_set_link_local_address,                              \
19246   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19247 _(ip6nd_proxy_add_del,                                                  \
19248   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19249 _(ip6nd_proxy_dump, "")                                                 \
19250 _(sw_interface_ip6nd_ra_prefix,                                         \
19251   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19252   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19253   "[nolink] [isno]")                                                    \
19254 _(sw_interface_ip6nd_ra_config,                                         \
19255   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19256   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19257   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19258 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19259 _(l2_patch_add_del,                                                     \
19260   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19261   "enable | disable")                                                   \
19262 _(sr_localsid_add_del,                                                  \
19263   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19264   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19265 _(classify_add_del_table,                                               \
19266   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19267   " [del] [del-chain] mask <mask-value>\n"                              \
19268   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19269   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19270 _(classify_add_del_session,                                             \
19271   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19272   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19273   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19274   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19275 _(classify_set_interface_ip_table,                                      \
19276   "<intfc> | sw_if_index <nn> table <nn>")                              \
19277 _(classify_set_interface_l2_tables,                                     \
19278   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19279   "  [other-table <nn>]")                                               \
19280 _(get_node_index, "node <node-name")                                    \
19281 _(add_node_next, "node <node-name> next <next-node-name>")              \
19282 _(l2tpv3_create_tunnel,                                                 \
19283   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
19284   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
19285   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
19286 _(l2tpv3_set_tunnel_cookies,                                            \
19287   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
19288   "[new_remote_cookie <nn>]\n")                                         \
19289 _(l2tpv3_interface_enable_disable,                                      \
19290   "<intfc> | sw_if_index <nn> enable | disable")                        \
19291 _(l2tpv3_set_lookup_key,                                                \
19292   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
19293 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
19294 _(vxlan_add_del_tunnel,                                                 \
19295   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
19296   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19297   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
19298 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
19299 _(gre_add_del_tunnel,                                                   \
19300   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
19301 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
19302 _(l2_fib_clear_table, "")                                               \
19303 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
19304 _(l2_interface_vlan_tag_rewrite,                                        \
19305   "<intfc> | sw_if_index <nn> \n"                                       \
19306   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19307   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19308 _(create_vhost_user_if,                                                 \
19309         "socket <filename> [server] [renumber <dev_instance>] "         \
19310         "[mac <mac_address>]")                                          \
19311 _(modify_vhost_user_if,                                                 \
19312         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19313         "[server] [renumber <dev_instance>]")                           \
19314 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19315 _(sw_interface_vhost_user_dump, "")                                     \
19316 _(show_version, "")                                                     \
19317 _(vxlan_gpe_add_del_tunnel,                                             \
19318   "local <addr> remote <addr> vni <nn>\n"                               \
19319     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
19320   "[next-ethernet] [next-nsh]\n")                                       \
19321 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19322 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19323 _(interface_name_renumber,                                              \
19324   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19325 _(input_acl_set_interface,                                              \
19326   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19327   "  [l2-table <nn>] [del]")                                            \
19328 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19329 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19330 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19331 _(ip_dump, "ipv4 | ipv6")                                               \
19332 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19333 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19334   "  spid_id <n> ")                                                     \
19335 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19336   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19337   "  integ_alg <alg> integ_key <hex>")                                  \
19338 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19339   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19340   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19341   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19342 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19343 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19344   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19345   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19346   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19347 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19348 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19349   "(auth_data 0x<data> | auth_data <data>)")                            \
19350 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19351   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19352 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
19353   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19354   "(local|remote)")                                                     \
19355 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
19356 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19357 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19358 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19359 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19360 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19361 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19362 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19363 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19364 _(delete_loopback,"sw_if_index <nn>")                                   \
19365 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19366 _(map_add_domain,                                                       \
19367   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19368   "ip6-src <ip6addr> "                                                  \
19369   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19370 _(map_del_domain, "index <n>")                                          \
19371 _(map_add_del_rule,                                                     \
19372   "index <n> psid <n> dst <ip6addr> [del]")                             \
19373 _(map_domain_dump, "")                                                  \
19374 _(map_rule_dump, "index <map-domain>")                                  \
19375 _(want_interface_events,  "enable|disable")                             \
19376 _(want_stats,"enable|disable")                                          \
19377 _(get_first_msg_id, "client <name>")                                    \
19378 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19379 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19380   "fib-id <nn> [ip4][ip6][default]")                                    \
19381 _(get_node_graph, " ")                                                  \
19382 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19383 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19384 _(ioam_disable, "")                                                     \
19385 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19386                             " sw_if_index <sw_if_index> p <priority> "  \
19387                             "w <weight>] [del]")                        \
19388 _(one_add_del_locator, "locator-set <locator_name> "                    \
19389                         "iface <intf> | sw_if_index <sw_if_index> "     \
19390                         "p <priority> w <weight> [del]")                \
19391 _(one_add_del_local_eid,"vni <vni> eid "                                \
19392                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19393                          "locator-set <locator_name> [del]"             \
19394                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19395 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19396 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19397 _(one_enable_disable, "enable|disable")                                 \
19398 _(one_map_register_enable_disable, "enable|disable")                    \
19399 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19400 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19401                                "[seid <seid>] "                         \
19402                                "rloc <locator> p <prio> "               \
19403                                "w <weight> [rloc <loc> ... ] "          \
19404                                "action <action> [del-all]")             \
19405 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19406                           "<local-eid>")                                \
19407 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19408 _(one_use_petr, "ip-address> | disable")                                \
19409 _(one_map_request_mode, "src-dst|dst-only")                             \
19410 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19411 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19412 _(one_locator_set_dump, "[local | remote]")                             \
19413 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19414 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19415                        "[local] | [remote]")                            \
19416 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
19417 _(one_l2_arp_bd_get, "")                                                \
19418 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
19419 _(one_stats_enable_disable, "enable|disalbe")                           \
19420 _(show_one_stats_enable_disable, "")                                    \
19421 _(one_eid_table_vni_dump, "")                                           \
19422 _(one_eid_table_map_dump, "l2|l3")                                      \
19423 _(one_map_resolver_dump, "")                                            \
19424 _(one_map_server_dump, "")                                              \
19425 _(one_adjacencies_get, "vni <vni>")                                     \
19426 _(show_one_rloc_probe_state, "")                                        \
19427 _(show_one_map_register_state, "")                                      \
19428 _(show_one_status, "")                                                  \
19429 _(one_stats_dump, "")                                                   \
19430 _(one_stats_flush, "")                                                  \
19431 _(one_get_map_request_itr_rlocs, "")                                    \
19432 _(show_one_pitr, "")                                                    \
19433 _(show_one_use_petr, "")                                                \
19434 _(show_one_map_request_mode, "")                                        \
19435 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19436                             " sw_if_index <sw_if_index> p <priority> "  \
19437                             "w <weight>] [del]")                        \
19438 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19439                         "iface <intf> | sw_if_index <sw_if_index> "     \
19440                         "p <priority> w <weight> [del]")                \
19441 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19442                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19443                          "locator-set <locator_name> [del]"             \
19444                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19445 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19446 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19447 _(lisp_enable_disable, "enable|disable")                                \
19448 _(lisp_map_register_enable_disable, "enable|disable")                   \
19449 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19450 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19451                                "[seid <seid>] "                         \
19452                                "rloc <locator> p <prio> "               \
19453                                "w <weight> [rloc <loc> ... ] "          \
19454                                "action <action> [del-all]")             \
19455 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19456                           "<local-eid>")                                \
19457 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19458 _(lisp_use_petr, "<ip-address> | disable")                              \
19459 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19460 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19461 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19462 _(lisp_locator_set_dump, "[local | remote]")                            \
19463 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19464 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19465                        "[local] | [remote]")                            \
19466 _(lisp_eid_table_vni_dump, "")                                          \
19467 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19468 _(lisp_map_resolver_dump, "")                                           \
19469 _(lisp_map_server_dump, "")                                             \
19470 _(lisp_adjacencies_get, "vni <vni>")                                    \
19471 _(gpe_fwd_entry_vnis_get, "")                                           \
19472 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19473 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19474 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19475 _(gpe_get_encap_mode, "")                                               \
19476 _(lisp_gpe_add_del_iface, "up|down")                                    \
19477 _(lisp_gpe_enable_disable, "enable|disable")                            \
19478 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19479   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19480 _(show_lisp_rloc_probe_state, "")                                       \
19481 _(show_lisp_map_register_state, "")                                     \
19482 _(show_lisp_status, "")                                                 \
19483 _(lisp_get_map_request_itr_rlocs, "")                                   \
19484 _(show_lisp_pitr, "")                                                   \
19485 _(show_lisp_use_petr, "")                                               \
19486 _(show_lisp_map_request_mode, "")                                       \
19487 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19488 _(af_packet_delete, "name <host interface name>")                       \
19489 _(policer_add_del, "name <policer name> <params> [del]")                \
19490 _(policer_dump, "[name <policer name>]")                                \
19491 _(policer_classify_set_interface,                                       \
19492   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19493   "  [l2-table <nn>] [del]")                                            \
19494 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19495 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19496     "[master|slave]")                                                   \
19497 _(netmap_delete, "name <interface name>")                               \
19498 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19499 _(mpls_fib_dump, "")                                                    \
19500 _(classify_table_ids, "")                                               \
19501 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19502 _(classify_table_info, "table_id <nn>")                                 \
19503 _(classify_session_dump, "table_id <nn>")                               \
19504 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19505     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19506     "[template_interval <nn>] [udp_checksum]")                          \
19507 _(ipfix_exporter_dump, "")                                              \
19508 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19509 _(ipfix_classify_stream_dump, "")                                       \
19510 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19511 _(ipfix_classify_table_dump, "")                                        \
19512 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19513 _(sw_interface_span_dump, "")                                           \
19514 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19515 _(pg_create_interface, "if_id <nn>")                                    \
19516 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19517 _(pg_enable_disable, "[stream <id>] disable")                           \
19518 _(ip_source_and_port_range_check_add_del,                               \
19519   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19520 _(ip_source_and_port_range_check_interface_add_del,                     \
19521   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19522   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19523 _(ipsec_gre_add_del_tunnel,                                             \
19524   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19525 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19526 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19527 _(l2_interface_pbb_tag_rewrite,                                         \
19528   "<intfc> | sw_if_index <nn> \n"                                       \
19529   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19530   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19531 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19532 _(flow_classify_set_interface,                                          \
19533   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19534 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19535 _(ip_fib_dump, "")                                                      \
19536 _(ip_mfib_dump, "")                                                     \
19537 _(ip6_fib_dump, "")                                                     \
19538 _(ip6_mfib_dump, "")                                                    \
19539 _(feature_enable_disable, "arc_name <arc_name> "                        \
19540   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19541 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19542 "[disable]")                                                            \
19543 _(l2_xconnect_dump, "")                                                 \
19544 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19545 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19546 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
19547 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
19548 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>")
19549
19550 /* List of command functions, CLI names map directly to functions */
19551 #define foreach_cli_function                                    \
19552 _(comment, "usage: comment <ignore-rest-of-line>")              \
19553 _(dump_interface_table, "usage: dump_interface_table")          \
19554 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19555 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19556 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19557 _(dump_stats_table, "usage: dump_stats_table")                  \
19558 _(dump_macro_table, "usage: dump_macro_table ")                 \
19559 _(dump_node_table, "usage: dump_node_table")                    \
19560 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19561 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19562 _(echo, "usage: echo <message>")                                \
19563 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19564 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19565 _(help, "usage: help")                                          \
19566 _(q, "usage: quit")                                             \
19567 _(quit, "usage: quit")                                          \
19568 _(search_node_table, "usage: search_node_table <name>...")      \
19569 _(set, "usage: set <variable-name> <value>")                    \
19570 _(script, "usage: script <file-name>")                          \
19571 _(unset, "usage: unset <variable-name>")
19572
19573 #define _(N,n)                                  \
19574     static void vl_api_##n##_t_handler_uni      \
19575     (vl_api_##n##_t * mp)                       \
19576     {                                           \
19577         vat_main_t * vam = &vat_main;           \
19578         if (vam->json_output) {                 \
19579             vl_api_##n##_t_handler_json(mp);    \
19580         } else {                                \
19581             vl_api_##n##_t_handler(mp);         \
19582         }                                       \
19583     }
19584 foreach_vpe_api_reply_msg;
19585 #if VPP_API_TEST_BUILTIN == 0
19586 foreach_standalone_reply_msg;
19587 #endif
19588 #undef _
19589
19590 void
19591 vat_api_hookup (vat_main_t * vam)
19592 {
19593 #define _(N,n)                                                  \
19594     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19595                            vl_api_##n##_t_handler_uni,          \
19596                            vl_noop_handler,                     \
19597                            vl_api_##n##_t_endian,               \
19598                            vl_api_##n##_t_print,                \
19599                            sizeof(vl_api_##n##_t), 1);
19600   foreach_vpe_api_reply_msg;
19601 #if VPP_API_TEST_BUILTIN == 0
19602   foreach_standalone_reply_msg;
19603 #endif
19604 #undef _
19605
19606 #if (VPP_API_TEST_BUILTIN==0)
19607   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19608
19609   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19610
19611   vam->function_by_name = hash_create_string (0, sizeof (uword));
19612
19613   vam->help_by_name = hash_create_string (0, sizeof (uword));
19614 #endif
19615
19616   /* API messages we can send */
19617 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19618   foreach_vpe_api_msg;
19619 #undef _
19620
19621   /* Help strings */
19622 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19623   foreach_vpe_api_msg;
19624 #undef _
19625
19626   /* CLI functions */
19627 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19628   foreach_cli_function;
19629 #undef _
19630
19631   /* Help strings */
19632 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19633   foreach_cli_function;
19634 #undef _
19635 }
19636
19637 #if VPP_API_TEST_BUILTIN
19638 static clib_error_t *
19639 vat_api_hookup_shim (vlib_main_t * vm)
19640 {
19641   vat_api_hookup (&vat_main);
19642   return 0;
19643 }
19644
19645 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19646 #endif
19647
19648 /*
19649  * fd.io coding-style-patch-verification: ON
19650  *
19651  * Local Variables:
19652  * eval: (c-set-style "gnu")
19653  * End:
19654  */