Dedicated SW Interface Event
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_event_t_handler
976   (vl_api_sw_interface_event_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_event_t_handler_json
988   (vl_api_sw_interface_event_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 static void
1287 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1288 {
1289   u32 n_macs = ntohl (mp->n_macs);
1290   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1291           ntohl (mp->pid), mp->client_index, n_macs);
1292   int i;
1293   for (i = 0; i < n_macs; i++)
1294     {
1295       vl_api_mac_entry_t *mac = &mp->mac[i];
1296       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1297               i + 1, ntohl (mac->sw_if_index),
1298               format_ethernet_address, mac->mac_addr, mac->is_del);
1299       if (i == 1000)
1300         break;
1301     }
1302 }
1303
1304 static void
1305 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1311 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1312
1313 /*
1314  * Special-case: build the bridge domain table, maintain
1315  * the next bd id vbl.
1316  */
1317 static void vl_api_bridge_domain_details_t_handler
1318   (vl_api_bridge_domain_details_t * mp)
1319 {
1320   vat_main_t *vam = &vat_main;
1321   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1322   int i;
1323
1324   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1325          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1326
1327   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1328          ntohl (mp->bd_id), mp->learn, mp->forward,
1329          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1330
1331   if (n_sw_ifs)
1332     {
1333       vl_api_bridge_domain_sw_if_t *sw_ifs;
1334       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1335              "Interface Name");
1336
1337       sw_ifs = mp->sw_if_details;
1338       for (i = 0; i < n_sw_ifs; i++)
1339         {
1340           u8 *sw_if_name = 0;
1341           u32 sw_if_index;
1342           hash_pair_t *p;
1343
1344           sw_if_index = ntohl (sw_ifs->sw_if_index);
1345
1346           /* *INDENT-OFF* */
1347           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1348                              ({
1349                                if ((u32) p->value[0] == sw_if_index)
1350                                  {
1351                                    sw_if_name = (u8 *)(p->key);
1352                                    break;
1353                                  }
1354                              }));
1355           /* *INDENT-ON* */
1356           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1357                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1358                  "sw_if_index not found!");
1359
1360           sw_ifs++;
1361         }
1362     }
1363 }
1364
1365 static void vl_api_bridge_domain_details_t_handler_json
1366   (vl_api_bridge_domain_details_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t *node, *array = NULL;
1370   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1371
1372   if (VAT_JSON_ARRAY != vam->json_tree.type)
1373     {
1374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1375       vat_json_init_array (&vam->json_tree);
1376     }
1377   node = vat_json_array_add (&vam->json_tree);
1378
1379   vat_json_init_object (node);
1380   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1381   vat_json_object_add_uint (node, "flood", mp->flood);
1382   vat_json_object_add_uint (node, "forward", mp->forward);
1383   vat_json_object_add_uint (node, "learn", mp->learn);
1384   vat_json_object_add_uint (node, "bvi_sw_if_index",
1385                             ntohl (mp->bvi_sw_if_index));
1386   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1387   array = vat_json_object_add (node, "sw_if");
1388   vat_json_init_array (array);
1389
1390
1391
1392   if (n_sw_ifs)
1393     {
1394       vl_api_bridge_domain_sw_if_t *sw_ifs;
1395       int i;
1396
1397       sw_ifs = mp->sw_if_details;
1398       for (i = 0; i < n_sw_ifs; i++)
1399         {
1400           node = vat_json_array_add (array);
1401           vat_json_init_object (node);
1402           vat_json_object_add_uint (node, "sw_if_index",
1403                                     ntohl (sw_ifs->sw_if_index));
1404           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1405           sw_ifs++;
1406         }
1407     }
1408 }
1409
1410 static void vl_api_control_ping_reply_t_handler
1411   (vl_api_control_ping_reply_t * mp)
1412 {
1413   vat_main_t *vam = &vat_main;
1414   i32 retval = ntohl (mp->retval);
1415   if (vam->async_mode)
1416     {
1417       vam->async_errors += (retval < 0);
1418     }
1419   else
1420     {
1421       vam->retval = retval;
1422       vam->result_ready = 1;
1423     }
1424 }
1425
1426 static void vl_api_control_ping_reply_t_handler_json
1427   (vl_api_control_ping_reply_t * mp)
1428 {
1429   vat_main_t *vam = &vat_main;
1430   i32 retval = ntohl (mp->retval);
1431
1432   if (VAT_JSON_NONE != vam->json_tree.type)
1433     {
1434       vat_json_print (vam->ofp, &vam->json_tree);
1435       vat_json_free (&vam->json_tree);
1436       vam->json_tree.type = VAT_JSON_NONE;
1437     }
1438   else
1439     {
1440       /* just print [] */
1441       vat_json_init_array (&vam->json_tree);
1442       vat_json_print (vam->ofp, &vam->json_tree);
1443       vam->json_tree.type = VAT_JSON_NONE;
1444     }
1445
1446   vam->retval = retval;
1447   vam->result_ready = 1;
1448 }
1449
1450 static void
1451   vl_api_bridge_domain_set_mac_age_reply_t_handler
1452   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   i32 retval = ntohl (mp->retval);
1456   if (vam->async_mode)
1457     {
1458       vam->async_errors += (retval < 0);
1459     }
1460   else
1461     {
1462       vam->retval = retval;
1463       vam->result_ready = 1;
1464     }
1465 }
1466
1467 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1468   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   vat_json_node_t node;
1472
1473   vat_json_init_object (&node);
1474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1475
1476   vat_json_print (vam->ofp, &node);
1477   vat_json_free (&node);
1478
1479   vam->retval = ntohl (mp->retval);
1480   vam->result_ready = 1;
1481 }
1482
1483 static void
1484 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488   if (vam->async_mode)
1489     {
1490       vam->async_errors += (retval < 0);
1491     }
1492   else
1493     {
1494       vam->retval = retval;
1495       vam->result_ready = 1;
1496     }
1497 }
1498
1499 static void vl_api_l2_flags_reply_t_handler_json
1500   (vl_api_l2_flags_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   vat_json_node_t node;
1504
1505   vat_json_init_object (&node);
1506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1507   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1508                             ntohl (mp->resulting_feature_bitmap));
1509
1510   vat_json_print (vam->ofp, &node);
1511   vat_json_free (&node);
1512
1513   vam->retval = ntohl (mp->retval);
1514   vam->result_ready = 1;
1515 }
1516
1517 static void vl_api_bridge_flags_reply_t_handler
1518   (vl_api_bridge_flags_reply_t * mp)
1519 {
1520   vat_main_t *vam = &vat_main;
1521   i32 retval = ntohl (mp->retval);
1522   if (vam->async_mode)
1523     {
1524       vam->async_errors += (retval < 0);
1525     }
1526   else
1527     {
1528       vam->retval = retval;
1529       vam->result_ready = 1;
1530     }
1531 }
1532
1533 static void vl_api_bridge_flags_reply_t_handler_json
1534   (vl_api_bridge_flags_reply_t * mp)
1535 {
1536   vat_main_t *vam = &vat_main;
1537   vat_json_node_t node;
1538
1539   vat_json_init_object (&node);
1540   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1541   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1542                             ntohl (mp->resulting_feature_bitmap));
1543
1544   vat_json_print (vam->ofp, &node);
1545   vat_json_free (&node);
1546
1547   vam->retval = ntohl (mp->retval);
1548   vam->result_ready = 1;
1549 }
1550
1551 static void vl_api_tap_connect_reply_t_handler
1552   (vl_api_tap_connect_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   i32 retval = ntohl (mp->retval);
1556   if (vam->async_mode)
1557     {
1558       vam->async_errors += (retval < 0);
1559     }
1560   else
1561     {
1562       vam->retval = retval;
1563       vam->sw_if_index = ntohl (mp->sw_if_index);
1564       vam->result_ready = 1;
1565     }
1566
1567 }
1568
1569 static void vl_api_tap_connect_reply_t_handler_json
1570   (vl_api_tap_connect_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1578
1579   vat_json_print (vam->ofp, &node);
1580   vat_json_free (&node);
1581
1582   vam->retval = ntohl (mp->retval);
1583   vam->result_ready = 1;
1584
1585 }
1586
1587 static void
1588 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->sw_if_index = ntohl (mp->sw_if_index);
1600       vam->result_ready = 1;
1601     }
1602 }
1603
1604 static void vl_api_tap_modify_reply_t_handler_json
1605   (vl_api_tap_modify_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   vat_json_node_t node;
1609
1610   vat_json_init_object (&node);
1611   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1612   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void
1622 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->result_ready = 1;
1634     }
1635 }
1636
1637 static void vl_api_tap_delete_reply_t_handler_json
1638   (vl_api_tap_delete_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   vat_json_node_t node;
1642
1643   vat_json_init_object (&node);
1644   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1645
1646   vat_json_print (vam->ofp, &node);
1647   vat_json_free (&node);
1648
1649   vam->retval = ntohl (mp->retval);
1650   vam->result_ready = 1;
1651 }
1652
1653 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1654   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   i32 retval = ntohl (mp->retval);
1658   if (vam->async_mode)
1659     {
1660       vam->async_errors += (retval < 0);
1661     }
1662   else
1663     {
1664       vam->retval = retval;
1665       vam->result_ready = 1;
1666     }
1667 }
1668
1669 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1670   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   vat_json_node_t node;
1674
1675   vat_json_init_object (&node);
1676   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1677   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1678                             ntohl (mp->sw_if_index));
1679
1680   vat_json_print (vam->ofp, &node);
1681   vat_json_free (&node);
1682
1683   vam->retval = ntohl (mp->retval);
1684   vam->result_ready = 1;
1685 }
1686
1687 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1688   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   i32 retval = ntohl (mp->retval);
1692   if (vam->async_mode)
1693     {
1694       vam->async_errors += (retval < 0);
1695     }
1696   else
1697     {
1698       vam->retval = retval;
1699       vam->sw_if_index = ntohl (mp->sw_if_index);
1700       vam->result_ready = 1;
1701     }
1702 }
1703
1704 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1705   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   vat_json_node_t node;
1709
1710   vat_json_init_object (&node);
1711   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1712   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1713
1714   vat_json_print (vam->ofp, &node);
1715   vat_json_free (&node);
1716
1717   vam->retval = ntohl (mp->retval);
1718   vam->result_ready = 1;
1719 }
1720
1721 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1722   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1723 {
1724   vat_main_t *vam = &vat_main;
1725   i32 retval = ntohl (mp->retval);
1726   if (vam->async_mode)
1727     {
1728       vam->async_errors += (retval < 0);
1729     }
1730   else
1731     {
1732       vam->retval = retval;
1733       vam->result_ready = 1;
1734     }
1735 }
1736
1737 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1738   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   vat_json_node_t node;
1742
1743   vat_json_init_object (&node);
1744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1745   vat_json_object_add_uint (&node, "fwd_entry_index",
1746                             clib_net_to_host_u32 (mp->fwd_entry_index));
1747
1748   vat_json_print (vam->ofp, &node);
1749   vat_json_free (&node);
1750
1751   vam->retval = ntohl (mp->retval);
1752   vam->result_ready = 1;
1753 }
1754
1755 static void vl_api_one_add_del_locator_set_reply_t_handler
1756   (vl_api_one_add_del_locator_set_reply_t * mp)
1757 {
1758   vat_main_t *vam = &vat_main;
1759   i32 retval = ntohl (mp->retval);
1760   if (vam->async_mode)
1761     {
1762       vam->async_errors += (retval < 0);
1763     }
1764   else
1765     {
1766       vam->retval = retval;
1767       vam->result_ready = 1;
1768     }
1769 }
1770
1771 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1772   (vl_api_one_add_del_locator_set_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   vat_json_node_t node;
1776
1777   vat_json_init_object (&node);
1778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1779   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1780
1781   vat_json_print (vam->ofp, &node);
1782   vat_json_free (&node);
1783
1784   vam->retval = ntohl (mp->retval);
1785   vam->result_ready = 1;
1786 }
1787
1788 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1789   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1790 {
1791   vat_main_t *vam = &vat_main;
1792   i32 retval = ntohl (mp->retval);
1793   if (vam->async_mode)
1794     {
1795       vam->async_errors += (retval < 0);
1796     }
1797   else
1798     {
1799       vam->retval = retval;
1800       vam->sw_if_index = ntohl (mp->sw_if_index);
1801       vam->result_ready = 1;
1802     }
1803 }
1804
1805 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1806   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   vat_json_node_t node;
1810
1811   vat_json_init_object (&node);
1812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1813   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1814
1815   vat_json_print (vam->ofp, &node);
1816   vat_json_free (&node);
1817
1818   vam->retval = ntohl (mp->retval);
1819   vam->result_ready = 1;
1820 }
1821
1822 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1823   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1824 {
1825   vat_main_t *vam = &vat_main;
1826   i32 retval = ntohl (mp->retval);
1827   if (vam->async_mode)
1828     {
1829       vam->async_errors += (retval < 0);
1830     }
1831   else
1832     {
1833       vam->retval = retval;
1834       vam->sw_if_index = ntohl (mp->sw_if_index);
1835       vam->result_ready = 1;
1836     }
1837 }
1838
1839 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1840   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   vat_json_node_t node;
1844
1845   vat_json_init_object (&node);
1846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1848
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_gre_add_del_tunnel_reply_t_handler
1857   (vl_api_gre_add_del_tunnel_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->sw_if_index = ntohl (mp->sw_if_index);
1869       vam->result_ready = 1;
1870     }
1871 }
1872
1873 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1874   (vl_api_gre_add_del_tunnel_reply_t * mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   vat_json_node_t node;
1878
1879   vat_json_init_object (&node);
1880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1881   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1882
1883   vat_json_print (vam->ofp, &node);
1884   vat_json_free (&node);
1885
1886   vam->retval = ntohl (mp->retval);
1887   vam->result_ready = 1;
1888 }
1889
1890 static void vl_api_create_vhost_user_if_reply_t_handler
1891   (vl_api_create_vhost_user_if_reply_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   i32 retval = ntohl (mp->retval);
1895   if (vam->async_mode)
1896     {
1897       vam->async_errors += (retval < 0);
1898     }
1899   else
1900     {
1901       vam->retval = retval;
1902       vam->sw_if_index = ntohl (mp->sw_if_index);
1903       vam->result_ready = 1;
1904     }
1905 }
1906
1907 static void vl_api_create_vhost_user_if_reply_t_handler_json
1908   (vl_api_create_vhost_user_if_reply_t * mp)
1909 {
1910   vat_main_t *vam = &vat_main;
1911   vat_json_node_t node;
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1916
1917   vat_json_print (vam->ofp, &node);
1918   vat_json_free (&node);
1919
1920   vam->retval = ntohl (mp->retval);
1921   vam->result_ready = 1;
1922 }
1923
1924 static void vl_api_ip_address_details_t_handler
1925   (vl_api_ip_address_details_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928   static ip_address_details_t empty_ip_address_details = { {0} };
1929   ip_address_details_t *address = NULL;
1930   ip_details_t *current_ip_details = NULL;
1931   ip_details_t *details = NULL;
1932
1933   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1934
1935   if (!details || vam->current_sw_if_index >= vec_len (details)
1936       || !details[vam->current_sw_if_index].present)
1937     {
1938       errmsg ("ip address details arrived but not stored");
1939       errmsg ("ip_dump should be called first");
1940       return;
1941     }
1942
1943   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1944
1945 #define addresses (current_ip_details->addr)
1946
1947   vec_validate_init_empty (addresses, vec_len (addresses),
1948                            empty_ip_address_details);
1949
1950   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1951
1952   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1953   address->prefix_length = mp->prefix_length;
1954 #undef addresses
1955 }
1956
1957 static void vl_api_ip_address_details_t_handler_json
1958   (vl_api_ip_address_details_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   vat_json_node_t *node = NULL;
1962   struct in6_addr ip6;
1963   struct in_addr ip4;
1964
1965   if (VAT_JSON_ARRAY != vam->json_tree.type)
1966     {
1967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1968       vat_json_init_array (&vam->json_tree);
1969     }
1970   node = vat_json_array_add (&vam->json_tree);
1971
1972   vat_json_init_object (node);
1973   if (vam->is_ipv6)
1974     {
1975       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1976       vat_json_object_add_ip6 (node, "ip", ip6);
1977     }
1978   else
1979     {
1980       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1981       vat_json_object_add_ip4 (node, "ip", ip4);
1982     }
1983   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1984 }
1985
1986 static void
1987 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   static ip_details_t empty_ip_details = { 0 };
1991   ip_details_t *ip = NULL;
1992   u32 sw_if_index = ~0;
1993
1994   sw_if_index = ntohl (mp->sw_if_index);
1995
1996   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1997                            sw_if_index, empty_ip_details);
1998
1999   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2000                          sw_if_index);
2001
2002   ip->present = 1;
2003 }
2004
2005 static void
2006 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2007 {
2008   vat_main_t *vam = &vat_main;
2009
2010   if (VAT_JSON_ARRAY != vam->json_tree.type)
2011     {
2012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2013       vat_json_init_array (&vam->json_tree);
2014     }
2015   vat_json_array_add_uint (&vam->json_tree,
2016                            clib_net_to_host_u32 (mp->sw_if_index));
2017 }
2018
2019 static void vl_api_map_domain_details_t_handler_json
2020   (vl_api_map_domain_details_t * mp)
2021 {
2022   vat_json_node_t *node = NULL;
2023   vat_main_t *vam = &vat_main;
2024   struct in6_addr ip6;
2025   struct in_addr ip4;
2026
2027   if (VAT_JSON_ARRAY != vam->json_tree.type)
2028     {
2029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2030       vat_json_init_array (&vam->json_tree);
2031     }
2032
2033   node = vat_json_array_add (&vam->json_tree);
2034   vat_json_init_object (node);
2035
2036   vat_json_object_add_uint (node, "domain_index",
2037                             clib_net_to_host_u32 (mp->domain_index));
2038   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2039   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2040   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2041   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2042   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2043   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2044   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2045   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2046   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2047   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2048   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2049   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2050   vat_json_object_add_uint (node, "flags", mp->flags);
2051   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2052   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2053 }
2054
2055 static void vl_api_map_domain_details_t_handler
2056   (vl_api_map_domain_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059
2060   if (mp->is_translation)
2061     {
2062       print (vam->ofp,
2063              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2064              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2065              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2066              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2067              clib_net_to_host_u32 (mp->domain_index));
2068     }
2069   else
2070     {
2071       print (vam->ofp,
2072              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2073              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2074              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2075              format_ip6_address, mp->ip6_src,
2076              clib_net_to_host_u32 (mp->domain_index));
2077     }
2078   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2079          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2080          mp->is_translation ? "map-t" : "");
2081 }
2082
2083 static void vl_api_map_rule_details_t_handler_json
2084   (vl_api_map_rule_details_t * mp)
2085 {
2086   struct in6_addr ip6;
2087   vat_json_node_t *node = NULL;
2088   vat_main_t *vam = &vat_main;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095
2096   node = vat_json_array_add (&vam->json_tree);
2097   vat_json_init_object (node);
2098
2099   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2100   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2101   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2102 }
2103
2104 static void
2105 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2109          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2110 }
2111
2112 static void
2113 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2114 {
2115   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2116           "router_addr %U host_mac %U",
2117           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2118           format_ip4_address, &mp->host_address,
2119           format_ip4_address, &mp->router_address,
2120           format_ethernet_address, mp->host_mac);
2121 }
2122
2123 static void vl_api_dhcp_compl_event_t_handler_json
2124   (vl_api_dhcp_compl_event_t * mp)
2125 {
2126   /* JSON output not supported */
2127 }
2128
2129 static void
2130 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2131                               u32 counter)
2132 {
2133   vat_main_t *vam = &vat_main;
2134   static u64 default_counter = 0;
2135
2136   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2137                            NULL);
2138   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2139                            sw_if_index, default_counter);
2140   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2141 }
2142
2143 static void
2144 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2145                                 interface_counter_t counter)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   static interface_counter_t default_counter = { 0, };
2149
2150   vec_validate_init_empty (vam->combined_interface_counters,
2151                            vnet_counter_type, NULL);
2152   vec_validate_init_empty (vam->combined_interface_counters
2153                            [vnet_counter_type], sw_if_index, default_counter);
2154   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2155 }
2156
2157 static void vl_api_vnet_interface_simple_counters_t_handler
2158   (vl_api_vnet_interface_simple_counters_t * mp)
2159 {
2160   /* not supported */
2161 }
2162
2163 static void vl_api_vnet_interface_combined_counters_t_handler
2164   (vl_api_vnet_interface_combined_counters_t * mp)
2165 {
2166   /* not supported */
2167 }
2168
2169 static void vl_api_vnet_interface_simple_counters_t_handler_json
2170   (vl_api_vnet_interface_simple_counters_t * mp)
2171 {
2172   u64 *v_packets;
2173   u64 packets;
2174   u32 count;
2175   u32 first_sw_if_index;
2176   int i;
2177
2178   count = ntohl (mp->count);
2179   first_sw_if_index = ntohl (mp->first_sw_if_index);
2180
2181   v_packets = (u64 *) & mp->data;
2182   for (i = 0; i < count; i++)
2183     {
2184       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2185       set_simple_interface_counter (mp->vnet_counter_type,
2186                                     first_sw_if_index + i, packets);
2187       v_packets++;
2188     }
2189 }
2190
2191 static void vl_api_vnet_interface_combined_counters_t_handler_json
2192   (vl_api_vnet_interface_combined_counters_t * mp)
2193 {
2194   interface_counter_t counter;
2195   vlib_counter_t *v;
2196   u32 first_sw_if_index;
2197   int i;
2198   u32 count;
2199
2200   count = ntohl (mp->count);
2201   first_sw_if_index = ntohl (mp->first_sw_if_index);
2202
2203   v = (vlib_counter_t *) & mp->data;
2204   for (i = 0; i < count; i++)
2205     {
2206       counter.packets =
2207         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2208       counter.bytes =
2209         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2210       set_combined_interface_counter (mp->vnet_counter_type,
2211                                       first_sw_if_index + i, counter);
2212       v++;
2213     }
2214 }
2215
2216 static u32
2217 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   u32 i;
2221
2222   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2223     {
2224       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2225         {
2226           return i;
2227         }
2228     }
2229   return ~0;
2230 }
2231
2232 static u32
2233 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   u32 i;
2237
2238   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2239     {
2240       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2241         {
2242           return i;
2243         }
2244     }
2245   return ~0;
2246 }
2247
2248 static void vl_api_vnet_ip4_fib_counters_t_handler
2249   (vl_api_vnet_ip4_fib_counters_t * mp)
2250 {
2251   /* not supported */
2252 }
2253
2254 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2255   (vl_api_vnet_ip4_fib_counters_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   vl_api_ip4_fib_counter_t *v;
2259   ip4_fib_counter_t *counter;
2260   struct in_addr ip4;
2261   u32 vrf_id;
2262   u32 vrf_index;
2263   u32 count;
2264   int i;
2265
2266   vrf_id = ntohl (mp->vrf_id);
2267   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2268   if (~0 == vrf_index)
2269     {
2270       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2271       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2272       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2273       vec_validate (vam->ip4_fib_counters, vrf_index);
2274       vam->ip4_fib_counters[vrf_index] = NULL;
2275     }
2276
2277   vec_free (vam->ip4_fib_counters[vrf_index]);
2278   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2279   count = ntohl (mp->count);
2280   for (i = 0; i < count; i++)
2281     {
2282       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2283       counter = &vam->ip4_fib_counters[vrf_index][i];
2284       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2285       counter->address = ip4;
2286       counter->address_length = v->address_length;
2287       counter->packets = clib_net_to_host_u64 (v->packets);
2288       counter->bytes = clib_net_to_host_u64 (v->bytes);
2289       v++;
2290     }
2291 }
2292
2293 static void vl_api_vnet_ip4_nbr_counters_t_handler
2294   (vl_api_vnet_ip4_nbr_counters_t * mp)
2295 {
2296   /* not supported */
2297 }
2298
2299 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2300   (vl_api_vnet_ip4_nbr_counters_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   vl_api_ip4_nbr_counter_t *v;
2304   ip4_nbr_counter_t *counter;
2305   u32 sw_if_index;
2306   u32 count;
2307   int i;
2308
2309   sw_if_index = ntohl (mp->sw_if_index);
2310   count = ntohl (mp->count);
2311   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2312
2313   if (mp->begin)
2314     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2315
2316   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2317   for (i = 0; i < count; i++)
2318     {
2319       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2320       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2321       counter->address.s_addr = v->address;
2322       counter->packets = clib_net_to_host_u64 (v->packets);
2323       counter->bytes = clib_net_to_host_u64 (v->bytes);
2324       counter->linkt = v->link_type;
2325       v++;
2326     }
2327 }
2328
2329 static void vl_api_vnet_ip6_fib_counters_t_handler
2330   (vl_api_vnet_ip6_fib_counters_t * mp)
2331 {
2332   /* not supported */
2333 }
2334
2335 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2336   (vl_api_vnet_ip6_fib_counters_t * mp)
2337 {
2338   vat_main_t *vam = &vat_main;
2339   vl_api_ip6_fib_counter_t *v;
2340   ip6_fib_counter_t *counter;
2341   struct in6_addr ip6;
2342   u32 vrf_id;
2343   u32 vrf_index;
2344   u32 count;
2345   int i;
2346
2347   vrf_id = ntohl (mp->vrf_id);
2348   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2349   if (~0 == vrf_index)
2350     {
2351       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2352       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2353       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2354       vec_validate (vam->ip6_fib_counters, vrf_index);
2355       vam->ip6_fib_counters[vrf_index] = NULL;
2356     }
2357
2358   vec_free (vam->ip6_fib_counters[vrf_index]);
2359   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2360   count = ntohl (mp->count);
2361   for (i = 0; i < count; i++)
2362     {
2363       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2364       counter = &vam->ip6_fib_counters[vrf_index][i];
2365       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2366       counter->address = ip6;
2367       counter->address_length = v->address_length;
2368       counter->packets = clib_net_to_host_u64 (v->packets);
2369       counter->bytes = clib_net_to_host_u64 (v->bytes);
2370       v++;
2371     }
2372 }
2373
2374 static void vl_api_vnet_ip6_nbr_counters_t_handler
2375   (vl_api_vnet_ip6_nbr_counters_t * mp)
2376 {
2377   /* not supported */
2378 }
2379
2380 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2381   (vl_api_vnet_ip6_nbr_counters_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vl_api_ip6_nbr_counter_t *v;
2385   ip6_nbr_counter_t *counter;
2386   struct in6_addr ip6;
2387   u32 sw_if_index;
2388   u32 count;
2389   int i;
2390
2391   sw_if_index = ntohl (mp->sw_if_index);
2392   count = ntohl (mp->count);
2393   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2394
2395   if (mp->begin)
2396     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2397
2398   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2399   for (i = 0; i < count; i++)
2400     {
2401       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2402       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2403       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2404       counter->address = ip6;
2405       counter->packets = clib_net_to_host_u64 (v->packets);
2406       counter->bytes = clib_net_to_host_u64 (v->bytes);
2407       v++;
2408     }
2409 }
2410
2411 static void vl_api_get_first_msg_id_reply_t_handler
2412   (vl_api_get_first_msg_id_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416
2417   if (vam->async_mode)
2418     {
2419       vam->async_errors += (retval < 0);
2420     }
2421   else
2422     {
2423       vam->retval = retval;
2424       vam->result_ready = 1;
2425     }
2426   if (retval >= 0)
2427     {
2428       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2429     }
2430 }
2431
2432 static void vl_api_get_first_msg_id_reply_t_handler_json
2433   (vl_api_get_first_msg_id_reply_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436   vat_json_node_t node;
2437
2438   vat_json_init_object (&node);
2439   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2440   vat_json_object_add_uint (&node, "first_msg_id",
2441                             (uint) ntohs (mp->first_msg_id));
2442
2443   vat_json_print (vam->ofp, &node);
2444   vat_json_free (&node);
2445
2446   vam->retval = ntohl (mp->retval);
2447   vam->result_ready = 1;
2448 }
2449
2450 static void vl_api_get_node_graph_reply_t_handler
2451   (vl_api_get_node_graph_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   api_main_t *am = &api_main;
2455   i32 retval = ntohl (mp->retval);
2456   u8 *pvt_copy, *reply;
2457   void *oldheap;
2458   vlib_node_t *node;
2459   int i;
2460
2461   if (vam->async_mode)
2462     {
2463       vam->async_errors += (retval < 0);
2464     }
2465   else
2466     {
2467       vam->retval = retval;
2468       vam->result_ready = 1;
2469     }
2470
2471   /* "Should never happen..." */
2472   if (retval != 0)
2473     return;
2474
2475   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2476   pvt_copy = vec_dup (reply);
2477
2478   /* Toss the shared-memory original... */
2479   pthread_mutex_lock (&am->vlib_rp->mutex);
2480   oldheap = svm_push_data_heap (am->vlib_rp);
2481
2482   vec_free (reply);
2483
2484   svm_pop_heap (oldheap);
2485   pthread_mutex_unlock (&am->vlib_rp->mutex);
2486
2487   if (vam->graph_nodes)
2488     {
2489       hash_free (vam->graph_node_index_by_name);
2490
2491       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2492         {
2493           node = vam->graph_nodes[i];
2494           vec_free (node->name);
2495           vec_free (node->next_nodes);
2496           vec_free (node);
2497         }
2498       vec_free (vam->graph_nodes);
2499     }
2500
2501   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2502   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2503   vec_free (pvt_copy);
2504
2505   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2506     {
2507       node = vam->graph_nodes[i];
2508       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2509     }
2510 }
2511
2512 static void vl_api_get_node_graph_reply_t_handler_json
2513   (vl_api_get_node_graph_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   api_main_t *am = &api_main;
2517   void *oldheap;
2518   vat_json_node_t node;
2519   u8 *reply;
2520
2521   /* $$$$ make this real? */
2522   vat_json_init_object (&node);
2523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2524   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2525
2526   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2527
2528   /* Toss the shared-memory original... */
2529   pthread_mutex_lock (&am->vlib_rp->mutex);
2530   oldheap = svm_push_data_heap (am->vlib_rp);
2531
2532   vec_free (reply);
2533
2534   svm_pop_heap (oldheap);
2535   pthread_mutex_unlock (&am->vlib_rp->mutex);
2536
2537   vat_json_print (vam->ofp, &node);
2538   vat_json_free (&node);
2539
2540   vam->retval = ntohl (mp->retval);
2541   vam->result_ready = 1;
2542 }
2543
2544 static void
2545 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   u8 *s = 0;
2549
2550   if (mp->local)
2551     {
2552       s = format (s, "%=16d%=16d%=16d",
2553                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2554     }
2555   else
2556     {
2557       s = format (s, "%=16U%=16d%=16d",
2558                   mp->is_ipv6 ? format_ip6_address :
2559                   format_ip4_address,
2560                   mp->ip_address, mp->priority, mp->weight);
2561     }
2562
2563   print (vam->ofp, "%v", s);
2564   vec_free (s);
2565 }
2566
2567 static void
2568 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   vat_json_node_t *node = NULL;
2572   struct in6_addr ip6;
2573   struct in_addr ip4;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581   vat_json_init_object (node);
2582
2583   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2584   vat_json_object_add_uint (node, "priority", mp->priority);
2585   vat_json_object_add_uint (node, "weight", mp->weight);
2586
2587   if (mp->local)
2588     vat_json_object_add_uint (node, "sw_if_index",
2589                               clib_net_to_host_u32 (mp->sw_if_index));
2590   else
2591     {
2592       if (mp->is_ipv6)
2593         {
2594           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2595           vat_json_object_add_ip6 (node, "address", ip6);
2596         }
2597       else
2598         {
2599           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2600           vat_json_object_add_ip4 (node, "address", ip4);
2601         }
2602     }
2603 }
2604
2605 static void
2606 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2607                                           mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u8 *ls_name = 0;
2611
2612   ls_name = format (0, "%s", mp->ls_name);
2613
2614   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2615          ls_name);
2616   vec_free (ls_name);
2617 }
2618
2619 static void
2620   vl_api_one_locator_set_details_t_handler_json
2621   (vl_api_one_locator_set_details_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = 0;
2625   u8 *ls_name = 0;
2626
2627   ls_name = format (0, "%s", mp->ls_name);
2628   vec_add1 (ls_name, 0);
2629
2630   if (VAT_JSON_ARRAY != vam->json_tree.type)
2631     {
2632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2633       vat_json_init_array (&vam->json_tree);
2634     }
2635   node = vat_json_array_add (&vam->json_tree);
2636
2637   vat_json_init_object (node);
2638   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2639   vat_json_object_add_uint (node, "ls_index",
2640                             clib_net_to_host_u32 (mp->ls_index));
2641   vec_free (ls_name);
2642 }
2643
2644 typedef struct
2645 {
2646   u32 spi;
2647   u8 si;
2648 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2649
2650 uword
2651 unformat_nsh_address (unformat_input_t * input, va_list * args)
2652 {
2653   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2654   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2655 }
2656
2657 u8 *
2658 format_nsh_address_vat (u8 * s, va_list * args)
2659 {
2660   nsh_t *a = va_arg (*args, nsh_t *);
2661   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2662 }
2663
2664 static u8 *
2665 format_lisp_flat_eid (u8 * s, va_list * args)
2666 {
2667   u32 type = va_arg (*args, u32);
2668   u8 *eid = va_arg (*args, u8 *);
2669   u32 eid_len = va_arg (*args, u32);
2670
2671   switch (type)
2672     {
2673     case 0:
2674       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2675     case 1:
2676       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2677     case 2:
2678       return format (s, "%U", format_ethernet_address, eid);
2679     case 3:
2680       return format (s, "%U", format_nsh_address_vat, eid);
2681     }
2682   return 0;
2683 }
2684
2685 static u8 *
2686 format_lisp_eid_vat (u8 * s, va_list * args)
2687 {
2688   u32 type = va_arg (*args, u32);
2689   u8 *eid = va_arg (*args, u8 *);
2690   u32 eid_len = va_arg (*args, u32);
2691   u8 *seid = va_arg (*args, u8 *);
2692   u32 seid_len = va_arg (*args, u32);
2693   u32 is_src_dst = va_arg (*args, u32);
2694
2695   if (is_src_dst)
2696     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2697
2698   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2699
2700   return s;
2701 }
2702
2703 static void
2704 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   u8 *s = 0, *eid = 0;
2708
2709   if (~0 == mp->locator_set_index)
2710     s = format (0, "action: %d", mp->action);
2711   else
2712     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2713
2714   eid = format (0, "%U", format_lisp_eid_vat,
2715                 mp->eid_type,
2716                 mp->eid,
2717                 mp->eid_prefix_len,
2718                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2719   vec_add1 (eid, 0);
2720
2721   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2722          clib_net_to_host_u32 (mp->vni),
2723          eid,
2724          mp->is_local ? "local" : "remote",
2725          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2726          clib_net_to_host_u16 (mp->key_id), mp->key);
2727
2728   vec_free (s);
2729   vec_free (eid);
2730 }
2731
2732 static void
2733 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2734                                              * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t *node = 0;
2738   u8 *eid = 0;
2739
2740   if (VAT_JSON_ARRAY != vam->json_tree.type)
2741     {
2742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2743       vat_json_init_array (&vam->json_tree);
2744     }
2745   node = vat_json_array_add (&vam->json_tree);
2746
2747   vat_json_init_object (node);
2748   if (~0 == mp->locator_set_index)
2749     vat_json_object_add_uint (node, "action", mp->action);
2750   else
2751     vat_json_object_add_uint (node, "locator_set_index",
2752                               clib_net_to_host_u32 (mp->locator_set_index));
2753
2754   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2755   if (mp->eid_type == 3)
2756     {
2757       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2758       vat_json_init_object (nsh_json);
2759       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2760       vat_json_object_add_uint (nsh_json, "spi",
2761                                 clib_net_to_host_u32 (nsh->spi));
2762       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2763     }
2764   else
2765     {
2766       eid = format (0, "%U", format_lisp_eid_vat,
2767                     mp->eid_type,
2768                     mp->eid,
2769                     mp->eid_prefix_len,
2770                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2771       vec_add1 (eid, 0);
2772       vat_json_object_add_string_copy (node, "eid", eid);
2773       vec_free (eid);
2774     }
2775   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2776   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2777   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2778
2779   if (mp->key_id)
2780     {
2781       vat_json_object_add_uint (node, "key_id",
2782                                 clib_net_to_host_u16 (mp->key_id));
2783       vat_json_object_add_string_copy (node, "key", mp->key);
2784     }
2785 }
2786
2787 static void
2788 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   u8 *seid = 0, *deid = 0;
2792   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2793
2794   deid = format (0, "%U", format_lisp_eid_vat,
2795                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2796
2797   seid = format (0, "%U", format_lisp_eid_vat,
2798                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2799
2800   vec_add1 (deid, 0);
2801   vec_add1 (seid, 0);
2802
2803   if (mp->is_ip4)
2804     format_ip_address_fcn = format_ip4_address;
2805   else
2806     format_ip_address_fcn = format_ip6_address;
2807
2808
2809   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2810          clib_net_to_host_u32 (mp->vni),
2811          seid, deid,
2812          format_ip_address_fcn, mp->lloc,
2813          format_ip_address_fcn, mp->rloc,
2814          clib_net_to_host_u32 (mp->pkt_count),
2815          clib_net_to_host_u32 (mp->bytes));
2816
2817   vec_free (deid);
2818   vec_free (seid);
2819 }
2820
2821 static void
2822 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2823 {
2824   struct in6_addr ip6;
2825   struct in_addr ip4;
2826   vat_main_t *vam = &vat_main;
2827   vat_json_node_t *node = 0;
2828   u8 *deid = 0, *seid = 0;
2829
2830   if (VAT_JSON_ARRAY != vam->json_tree.type)
2831     {
2832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2833       vat_json_init_array (&vam->json_tree);
2834     }
2835   node = vat_json_array_add (&vam->json_tree);
2836
2837   vat_json_init_object (node);
2838   deid = format (0, "%U", format_lisp_eid_vat,
2839                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2840
2841   seid = format (0, "%U", format_lisp_eid_vat,
2842                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2843
2844   vec_add1 (deid, 0);
2845   vec_add1 (seid, 0);
2846
2847   vat_json_object_add_string_copy (node, "seid", seid);
2848   vat_json_object_add_string_copy (node, "deid", deid);
2849   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2850
2851   if (mp->is_ip4)
2852     {
2853       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2854       vat_json_object_add_ip4 (node, "lloc", ip4);
2855       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2856       vat_json_object_add_ip4 (node, "rloc", ip4);
2857     }
2858   else
2859     {
2860       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2861       vat_json_object_add_ip6 (node, "lloc", ip6);
2862       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2863       vat_json_object_add_ip6 (node, "rloc", ip6);
2864     }
2865   vat_json_object_add_uint (node, "pkt_count",
2866                             clib_net_to_host_u32 (mp->pkt_count));
2867   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2868
2869   vec_free (deid);
2870   vec_free (seid);
2871 }
2872
2873 static void
2874   vl_api_one_eid_table_map_details_t_handler
2875   (vl_api_one_eid_table_map_details_t * mp)
2876 {
2877   vat_main_t *vam = &vat_main;
2878
2879   u8 *line = format (0, "%=10d%=10d",
2880                      clib_net_to_host_u32 (mp->vni),
2881                      clib_net_to_host_u32 (mp->dp_table));
2882   print (vam->ofp, "%v", line);
2883   vec_free (line);
2884 }
2885
2886 static void
2887   vl_api_one_eid_table_map_details_t_handler_json
2888   (vl_api_one_eid_table_map_details_t * mp)
2889 {
2890   vat_main_t *vam = &vat_main;
2891   vat_json_node_t *node = NULL;
2892
2893   if (VAT_JSON_ARRAY != vam->json_tree.type)
2894     {
2895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2896       vat_json_init_array (&vam->json_tree);
2897     }
2898   node = vat_json_array_add (&vam->json_tree);
2899   vat_json_init_object (node);
2900   vat_json_object_add_uint (node, "dp_table",
2901                             clib_net_to_host_u32 (mp->dp_table));
2902   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2903 }
2904
2905 static void
2906   vl_api_one_eid_table_vni_details_t_handler
2907   (vl_api_one_eid_table_vni_details_t * mp)
2908 {
2909   vat_main_t *vam = &vat_main;
2910
2911   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2912   print (vam->ofp, "%v", line);
2913   vec_free (line);
2914 }
2915
2916 static void
2917   vl_api_one_eid_table_vni_details_t_handler_json
2918   (vl_api_one_eid_table_vni_details_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   vat_json_node_t *node = NULL;
2922
2923   if (VAT_JSON_ARRAY != vam->json_tree.type)
2924     {
2925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2926       vat_json_init_array (&vam->json_tree);
2927     }
2928   node = vat_json_array_add (&vam->json_tree);
2929   vat_json_init_object (node);
2930   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2931 }
2932
2933 static void
2934   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
2935   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   int retval = clib_net_to_host_u32 (mp->retval);
2939
2940   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2941   print (vam->ofp, "fallback threshold value: %d", mp->value);
2942
2943   vam->retval = retval;
2944   vam->result_ready = 1;
2945 }
2946
2947 static void
2948   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
2949   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   vat_json_node_t _node, *node = &_node;
2953   int retval = clib_net_to_host_u32 (mp->retval);
2954
2955   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2956   vat_json_init_object (node);
2957   vat_json_object_add_uint (node, "value", mp->value);
2958
2959   vat_json_print (vam->ofp, node);
2960   vat_json_free (node);
2961
2962   vam->retval = retval;
2963   vam->result_ready = 1;
2964 }
2965
2966 static void
2967   vl_api_show_one_map_register_state_reply_t_handler
2968   (vl_api_show_one_map_register_state_reply_t * mp)
2969 {
2970   vat_main_t *vam = &vat_main;
2971   int retval = clib_net_to_host_u32 (mp->retval);
2972
2973   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2974
2975   vam->retval = retval;
2976   vam->result_ready = 1;
2977 }
2978
2979 static void
2980   vl_api_show_one_map_register_state_reply_t_handler_json
2981   (vl_api_show_one_map_register_state_reply_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   vat_json_node_t _node, *node = &_node;
2985   int retval = clib_net_to_host_u32 (mp->retval);
2986
2987   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2988
2989   vat_json_init_object (node);
2990   vat_json_object_add_string_copy (node, "state", s);
2991
2992   vat_json_print (vam->ofp, node);
2993   vat_json_free (node);
2994
2995   vam->retval = retval;
2996   vam->result_ready = 1;
2997   vec_free (s);
2998 }
2999
3000 static void
3001   vl_api_show_one_rloc_probe_state_reply_t_handler
3002   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3003 {
3004   vat_main_t *vam = &vat_main;
3005   int retval = clib_net_to_host_u32 (mp->retval);
3006
3007   if (retval)
3008     goto end;
3009
3010   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3011 end:
3012   vam->retval = retval;
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3018   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   vat_json_node_t _node, *node = &_node;
3022   int retval = clib_net_to_host_u32 (mp->retval);
3023
3024   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3025   vat_json_init_object (node);
3026   vat_json_object_add_string_copy (node, "state", s);
3027
3028   vat_json_print (vam->ofp, node);
3029   vat_json_free (node);
3030
3031   vam->retval = retval;
3032   vam->result_ready = 1;
3033   vec_free (s);
3034 }
3035
3036 static void
3037   vl_api_show_one_stats_enable_disable_reply_t_handler
3038   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3039 {
3040   vat_main_t *vam = &vat_main;
3041   int retval = clib_net_to_host_u32 (mp->retval);
3042
3043   if (retval)
3044     goto end;
3045
3046   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3047 end:
3048   vam->retval = retval;
3049   vam->result_ready = 1;
3050 }
3051
3052 static void
3053   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3054   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3055 {
3056   vat_main_t *vam = &vat_main;
3057   vat_json_node_t _node, *node = &_node;
3058   int retval = clib_net_to_host_u32 (mp->retval);
3059
3060   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3061   vat_json_init_object (node);
3062   vat_json_object_add_string_copy (node, "state", s);
3063
3064   vat_json_print (vam->ofp, node);
3065   vat_json_free (node);
3066
3067   vam->retval = retval;
3068   vam->result_ready = 1;
3069   vec_free (s);
3070 }
3071
3072 static void
3073 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3074 {
3075   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3076   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3077   e->vni = clib_net_to_host_u32 (e->vni);
3078 }
3079
3080 static void
3081   gpe_fwd_entries_get_reply_t_net_to_host
3082   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3083 {
3084   u32 i;
3085
3086   mp->count = clib_net_to_host_u32 (mp->count);
3087   for (i = 0; i < mp->count; i++)
3088     {
3089       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3090     }
3091 }
3092
3093 static u8 *
3094 format_gpe_encap_mode (u8 * s, va_list * args)
3095 {
3096   u32 mode = va_arg (*args, u32);
3097
3098   switch (mode)
3099     {
3100     case 0:
3101       return format (s, "lisp");
3102     case 1:
3103       return format (s, "vxlan");
3104     }
3105   return 0;
3106 }
3107
3108 static void
3109   vl_api_gpe_get_encap_mode_reply_t_handler
3110   (vl_api_gpe_get_encap_mode_reply_t * mp)
3111 {
3112   vat_main_t *vam = &vat_main;
3113
3114   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3115   vam->retval = ntohl (mp->retval);
3116   vam->result_ready = 1;
3117 }
3118
3119 static void
3120   vl_api_gpe_get_encap_mode_reply_t_handler_json
3121   (vl_api_gpe_get_encap_mode_reply_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   vat_json_node_t node;
3125
3126   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3127   vec_add1 (encap_mode, 0);
3128
3129   vat_json_init_object (&node);
3130   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3131
3132   vec_free (encap_mode);
3133   vat_json_print (vam->ofp, &node);
3134   vat_json_free (&node);
3135
3136   vam->retval = ntohl (mp->retval);
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_gpe_fwd_entry_path_details_t_handler
3142   (vl_api_gpe_fwd_entry_path_details_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3146
3147   if (mp->lcl_loc.is_ip4)
3148     format_ip_address_fcn = format_ip4_address;
3149   else
3150     format_ip_address_fcn = format_ip6_address;
3151
3152   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3153          format_ip_address_fcn, &mp->lcl_loc,
3154          format_ip_address_fcn, &mp->rmt_loc);
3155 }
3156
3157 static void
3158 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3159 {
3160   struct in6_addr ip6;
3161   struct in_addr ip4;
3162
3163   if (loc->is_ip4)
3164     {
3165       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3166       vat_json_object_add_ip4 (n, "address", ip4);
3167     }
3168   else
3169     {
3170       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3171       vat_json_object_add_ip6 (n, "address", ip6);
3172     }
3173   vat_json_object_add_uint (n, "weight", loc->weight);
3174 }
3175
3176 static void
3177   vl_api_gpe_fwd_entry_path_details_t_handler_json
3178   (vl_api_gpe_fwd_entry_path_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   vat_json_node_t *node = NULL;
3182   vat_json_node_t *loc_node;
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190   vat_json_init_object (node);
3191
3192   loc_node = vat_json_object_add (node, "local_locator");
3193   vat_json_init_object (loc_node);
3194   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3195
3196   loc_node = vat_json_object_add (node, "remote_locator");
3197   vat_json_init_object (loc_node);
3198   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3199 }
3200
3201 static void
3202   vl_api_gpe_fwd_entries_get_reply_t_handler
3203   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206   u32 i;
3207   int retval = clib_net_to_host_u32 (mp->retval);
3208   vl_api_gpe_fwd_entry_t *e;
3209
3210   if (retval)
3211     goto end;
3212
3213   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3214
3215   for (i = 0; i < mp->count; i++)
3216     {
3217       e = &mp->entries[i];
3218       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3219              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3220              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3221     }
3222
3223 end:
3224   vam->retval = retval;
3225   vam->result_ready = 1;
3226 }
3227
3228 static void
3229   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3230   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3231 {
3232   u8 *s = 0;
3233   vat_main_t *vam = &vat_main;
3234   vat_json_node_t *e = 0, root;
3235   u32 i;
3236   int retval = clib_net_to_host_u32 (mp->retval);
3237   vl_api_gpe_fwd_entry_t *fwd;
3238
3239   if (retval)
3240     goto end;
3241
3242   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3243   vat_json_init_array (&root);
3244
3245   for (i = 0; i < mp->count; i++)
3246     {
3247       e = vat_json_array_add (&root);
3248       fwd = &mp->entries[i];
3249
3250       vat_json_init_object (e);
3251       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3252       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3253       vat_json_object_add_int (e, "vni", fwd->vni);
3254       vat_json_object_add_int (e, "action", fwd->action);
3255
3256       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3257                   fwd->leid_prefix_len);
3258       vec_add1 (s, 0);
3259       vat_json_object_add_string_copy (e, "leid", s);
3260       vec_free (s);
3261
3262       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3263                   fwd->reid_prefix_len);
3264       vec_add1 (s, 0);
3265       vat_json_object_add_string_copy (e, "reid", s);
3266       vec_free (s);
3267     }
3268
3269   vat_json_print (vam->ofp, &root);
3270   vat_json_free (&root);
3271
3272 end:
3273   vam->retval = retval;
3274   vam->result_ready = 1;
3275 }
3276
3277 static void
3278   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3279   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   u32 i, n;
3283   int retval = clib_net_to_host_u32 (mp->retval);
3284   vl_api_gpe_native_fwd_rpath_t *r;
3285
3286   if (retval)
3287     goto end;
3288
3289   n = clib_net_to_host_u32 (mp->count);
3290
3291   for (i = 0; i < n; i++)
3292     {
3293       r = &mp->entries[i];
3294       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3295              clib_net_to_host_u32 (r->fib_index),
3296              clib_net_to_host_u32 (r->nh_sw_if_index),
3297              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3298     }
3299
3300 end:
3301   vam->retval = retval;
3302   vam->result_ready = 1;
3303 }
3304
3305 static void
3306   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3307   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   vat_json_node_t root, *e;
3311   u32 i, n;
3312   int retval = clib_net_to_host_u32 (mp->retval);
3313   vl_api_gpe_native_fwd_rpath_t *r;
3314   u8 *s;
3315
3316   if (retval)
3317     goto end;
3318
3319   n = clib_net_to_host_u32 (mp->count);
3320   vat_json_init_array (&root);
3321
3322   for (i = 0; i < n; i++)
3323     {
3324       e = vat_json_array_add (&root);
3325       vat_json_init_object (e);
3326       r = &mp->entries[i];
3327       s =
3328         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3329                 r->nh_addr);
3330       vec_add1 (s, 0);
3331       vat_json_object_add_string_copy (e, "ip4", s);
3332       vec_free (s);
3333
3334       vat_json_object_add_uint (e, "fib_index",
3335                                 clib_net_to_host_u32 (r->fib_index));
3336       vat_json_object_add_uint (e, "nh_sw_if_index",
3337                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3338     }
3339
3340   vat_json_print (vam->ofp, &root);
3341   vat_json_free (&root);
3342
3343 end:
3344   vam->retval = retval;
3345   vam->result_ready = 1;
3346 }
3347
3348 static void
3349   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3350   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3351 {
3352   vat_main_t *vam = &vat_main;
3353   u32 i, n;
3354   int retval = clib_net_to_host_u32 (mp->retval);
3355
3356   if (retval)
3357     goto end;
3358
3359   n = clib_net_to_host_u32 (mp->count);
3360
3361   for (i = 0; i < n; i++)
3362     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3363
3364 end:
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3371   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t root;
3375   u32 i, n;
3376   int retval = clib_net_to_host_u32 (mp->retval);
3377
3378   if (retval)
3379     goto end;
3380
3381   n = clib_net_to_host_u32 (mp->count);
3382   vat_json_init_array (&root);
3383
3384   for (i = 0; i < n; i++)
3385     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3386
3387   vat_json_print (vam->ofp, &root);
3388   vat_json_free (&root);
3389
3390 end:
3391   vam->retval = retval;
3392   vam->result_ready = 1;
3393 }
3394
3395 static void
3396   vl_api_one_l2_arp_entries_get_reply_t_handler
3397   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   u32 i, n;
3401   int retval = clib_net_to_host_u32 (mp->retval);
3402
3403   if (retval)
3404     goto end;
3405
3406   n = clib_net_to_host_u32 (mp->count);
3407
3408   for (i = 0; i < n; i++)
3409     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3410            format_ethernet_address, mp->entries[i].mac);
3411
3412 end:
3413   vam->retval = retval;
3414   vam->result_ready = 1;
3415 }
3416
3417 static void
3418   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3419   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3420 {
3421   u8 *s = 0;
3422   vat_main_t *vam = &vat_main;
3423   vat_json_node_t *e = 0, root;
3424   u32 i, n;
3425   int retval = clib_net_to_host_u32 (mp->retval);
3426   vl_api_one_l2_arp_entry_t *arp_entry;
3427
3428   if (retval)
3429     goto end;
3430
3431   n = clib_net_to_host_u32 (mp->count);
3432   vat_json_init_array (&root);
3433
3434   for (i = 0; i < n; i++)
3435     {
3436       e = vat_json_array_add (&root);
3437       arp_entry = &mp->entries[i];
3438
3439       vat_json_init_object (e);
3440       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3441       vec_add1 (s, 0);
3442
3443       vat_json_object_add_string_copy (e, "mac", s);
3444       vec_free (s);
3445
3446       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3447       vec_add1 (s, 0);
3448       vat_json_object_add_string_copy (e, "ip4", s);
3449       vec_free (s);
3450     }
3451
3452   vat_json_print (vam->ofp, &root);
3453   vat_json_free (&root);
3454
3455 end:
3456   vam->retval = retval;
3457   vam->result_ready = 1;
3458 }
3459
3460 static void
3461   vl_api_one_l2_arp_bd_get_reply_t_handler
3462   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465   u32 i, n;
3466   int retval = clib_net_to_host_u32 (mp->retval);
3467
3468   if (retval)
3469     goto end;
3470
3471   n = clib_net_to_host_u32 (mp->count);
3472
3473   for (i = 0; i < n; i++)
3474     {
3475       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3476     }
3477
3478 end:
3479   vam->retval = retval;
3480   vam->result_ready = 1;
3481 }
3482
3483 static void
3484   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3485   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3486 {
3487   vat_main_t *vam = &vat_main;
3488   vat_json_node_t root;
3489   u32 i, n;
3490   int retval = clib_net_to_host_u32 (mp->retval);
3491
3492   if (retval)
3493     goto end;
3494
3495   n = clib_net_to_host_u32 (mp->count);
3496   vat_json_init_array (&root);
3497
3498   for (i = 0; i < n; i++)
3499     {
3500       vat_json_array_add_uint (&root,
3501                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3502     }
3503
3504   vat_json_print (vam->ofp, &root);
3505   vat_json_free (&root);
3506
3507 end:
3508   vam->retval = retval;
3509   vam->result_ready = 1;
3510 }
3511
3512 static void
3513   vl_api_one_adjacencies_get_reply_t_handler
3514   (vl_api_one_adjacencies_get_reply_t * mp)
3515 {
3516   vat_main_t *vam = &vat_main;
3517   u32 i, n;
3518   int retval = clib_net_to_host_u32 (mp->retval);
3519   vl_api_one_adjacency_t *a;
3520
3521   if (retval)
3522     goto end;
3523
3524   n = clib_net_to_host_u32 (mp->count);
3525
3526   for (i = 0; i < n; i++)
3527     {
3528       a = &mp->adjacencies[i];
3529       print (vam->ofp, "%U %40U",
3530              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3531              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3532     }
3533
3534 end:
3535   vam->retval = retval;
3536   vam->result_ready = 1;
3537 }
3538
3539 static void
3540   vl_api_one_adjacencies_get_reply_t_handler_json
3541   (vl_api_one_adjacencies_get_reply_t * mp)
3542 {
3543   u8 *s = 0;
3544   vat_main_t *vam = &vat_main;
3545   vat_json_node_t *e = 0, root;
3546   u32 i, n;
3547   int retval = clib_net_to_host_u32 (mp->retval);
3548   vl_api_one_adjacency_t *a;
3549
3550   if (retval)
3551     goto end;
3552
3553   n = clib_net_to_host_u32 (mp->count);
3554   vat_json_init_array (&root);
3555
3556   for (i = 0; i < n; i++)
3557     {
3558       e = vat_json_array_add (&root);
3559       a = &mp->adjacencies[i];
3560
3561       vat_json_init_object (e);
3562       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3563                   a->leid_prefix_len);
3564       vec_add1 (s, 0);
3565       vat_json_object_add_string_copy (e, "leid", s);
3566       vec_free (s);
3567
3568       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3569                   a->reid_prefix_len);
3570       vec_add1 (s, 0);
3571       vat_json_object_add_string_copy (e, "reid", s);
3572       vec_free (s);
3573     }
3574
3575   vat_json_print (vam->ofp, &root);
3576   vat_json_free (&root);
3577
3578 end:
3579   vam->retval = retval;
3580   vam->result_ready = 1;
3581 }
3582
3583 static void
3584 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587
3588   print (vam->ofp, "%=20U",
3589          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3590          mp->ip_address);
3591 }
3592
3593 static void
3594   vl_api_one_map_server_details_t_handler_json
3595   (vl_api_one_map_server_details_t * mp)
3596 {
3597   vat_main_t *vam = &vat_main;
3598   vat_json_node_t *node = NULL;
3599   struct in6_addr ip6;
3600   struct in_addr ip4;
3601
3602   if (VAT_JSON_ARRAY != vam->json_tree.type)
3603     {
3604       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3605       vat_json_init_array (&vam->json_tree);
3606     }
3607   node = vat_json_array_add (&vam->json_tree);
3608
3609   vat_json_init_object (node);
3610   if (mp->is_ipv6)
3611     {
3612       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3613       vat_json_object_add_ip6 (node, "map-server", ip6);
3614     }
3615   else
3616     {
3617       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3618       vat_json_object_add_ip4 (node, "map-server", ip4);
3619     }
3620 }
3621
3622 static void
3623 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3624                                            * mp)
3625 {
3626   vat_main_t *vam = &vat_main;
3627
3628   print (vam->ofp, "%=20U",
3629          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3630          mp->ip_address);
3631 }
3632
3633 static void
3634   vl_api_one_map_resolver_details_t_handler_json
3635   (vl_api_one_map_resolver_details_t * mp)
3636 {
3637   vat_main_t *vam = &vat_main;
3638   vat_json_node_t *node = NULL;
3639   struct in6_addr ip6;
3640   struct in_addr ip4;
3641
3642   if (VAT_JSON_ARRAY != vam->json_tree.type)
3643     {
3644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3645       vat_json_init_array (&vam->json_tree);
3646     }
3647   node = vat_json_array_add (&vam->json_tree);
3648
3649   vat_json_init_object (node);
3650   if (mp->is_ipv6)
3651     {
3652       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3653       vat_json_object_add_ip6 (node, "map resolver", ip6);
3654     }
3655   else
3656     {
3657       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3658       vat_json_object_add_ip4 (node, "map resolver", ip4);
3659     }
3660 }
3661
3662 static void
3663 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3664 {
3665   vat_main_t *vam = &vat_main;
3666   i32 retval = ntohl (mp->retval);
3667
3668   if (0 <= retval)
3669     {
3670       print (vam->ofp, "feature: %s\ngpe: %s",
3671              mp->feature_status ? "enabled" : "disabled",
3672              mp->gpe_status ? "enabled" : "disabled");
3673     }
3674
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_show_one_status_reply_t_handler_json
3681   (vl_api_show_one_status_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   vat_json_node_t node;
3685   u8 *gpe_status = NULL;
3686   u8 *feature_status = NULL;
3687
3688   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3689   feature_status = format (0, "%s",
3690                            mp->feature_status ? "enabled" : "disabled");
3691   vec_add1 (gpe_status, 0);
3692   vec_add1 (feature_status, 0);
3693
3694   vat_json_init_object (&node);
3695   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3696   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3697
3698   vec_free (gpe_status);
3699   vec_free (feature_status);
3700
3701   vat_json_print (vam->ofp, &node);
3702   vat_json_free (&node);
3703
3704   vam->retval = ntohl (mp->retval);
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3710   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   i32 retval = ntohl (mp->retval);
3714
3715   if (retval >= 0)
3716     {
3717       print (vam->ofp, "%=20s", mp->locator_set_name);
3718     }
3719
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3726   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729   vat_json_node_t *node = NULL;
3730
3731   if (VAT_JSON_ARRAY != vam->json_tree.type)
3732     {
3733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3734       vat_json_init_array (&vam->json_tree);
3735     }
3736   node = vat_json_array_add (&vam->json_tree);
3737
3738   vat_json_init_object (node);
3739   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3740
3741   vat_json_print (vam->ofp, node);
3742   vat_json_free (node);
3743
3744   vam->retval = ntohl (mp->retval);
3745   vam->result_ready = 1;
3746 }
3747
3748 static u8 *
3749 format_lisp_map_request_mode (u8 * s, va_list * args)
3750 {
3751   u32 mode = va_arg (*args, u32);
3752
3753   switch (mode)
3754     {
3755     case 0:
3756       return format (0, "dst-only");
3757     case 1:
3758       return format (0, "src-dst");
3759     }
3760   return 0;
3761 }
3762
3763 static void
3764   vl_api_show_one_map_request_mode_reply_t_handler
3765   (vl_api_show_one_map_request_mode_reply_t * mp)
3766 {
3767   vat_main_t *vam = &vat_main;
3768   i32 retval = ntohl (mp->retval);
3769
3770   if (0 <= retval)
3771     {
3772       u32 mode = mp->mode;
3773       print (vam->ofp, "map_request_mode: %U",
3774              format_lisp_map_request_mode, mode);
3775     }
3776
3777   vam->retval = retval;
3778   vam->result_ready = 1;
3779 }
3780
3781 static void
3782   vl_api_show_one_map_request_mode_reply_t_handler_json
3783   (vl_api_show_one_map_request_mode_reply_t * mp)
3784 {
3785   vat_main_t *vam = &vat_main;
3786   vat_json_node_t node;
3787   u8 *s = 0;
3788   u32 mode;
3789
3790   mode = mp->mode;
3791   s = format (0, "%U", format_lisp_map_request_mode, mode);
3792   vec_add1 (s, 0);
3793
3794   vat_json_init_object (&node);
3795   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3796   vat_json_print (vam->ofp, &node);
3797   vat_json_free (&node);
3798
3799   vec_free (s);
3800   vam->retval = ntohl (mp->retval);
3801   vam->result_ready = 1;
3802 }
3803
3804 static void
3805   vl_api_show_one_use_petr_reply_t_handler
3806   (vl_api_show_one_use_petr_reply_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   i32 retval = ntohl (mp->retval);
3810
3811   if (0 <= retval)
3812     {
3813       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3814       if (mp->status)
3815         {
3816           print (vam->ofp, "Proxy-ETR address; %U",
3817                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3818                  mp->address);
3819         }
3820     }
3821
3822   vam->retval = retval;
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_show_one_use_petr_reply_t_handler_json
3828   (vl_api_show_one_use_petr_reply_t * mp)
3829 {
3830   vat_main_t *vam = &vat_main;
3831   vat_json_node_t node;
3832   u8 *status = 0;
3833   struct in_addr ip4;
3834   struct in6_addr ip6;
3835
3836   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3837   vec_add1 (status, 0);
3838
3839   vat_json_init_object (&node);
3840   vat_json_object_add_string_copy (&node, "status", status);
3841   if (mp->status)
3842     {
3843       if (mp->is_ip4)
3844         {
3845           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3846           vat_json_object_add_ip6 (&node, "address", ip6);
3847         }
3848       else
3849         {
3850           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3851           vat_json_object_add_ip4 (&node, "address", ip4);
3852         }
3853     }
3854
3855   vec_free (status);
3856
3857   vat_json_print (vam->ofp, &node);
3858   vat_json_free (&node);
3859
3860   vam->retval = ntohl (mp->retval);
3861   vam->result_ready = 1;
3862 }
3863
3864 static void
3865   vl_api_show_one_nsh_mapping_reply_t_handler
3866   (vl_api_show_one_nsh_mapping_reply_t * mp)
3867 {
3868   vat_main_t *vam = &vat_main;
3869   i32 retval = ntohl (mp->retval);
3870
3871   if (0 <= retval)
3872     {
3873       print (vam->ofp, "%-20s%-16s",
3874              mp->is_set ? "set" : "not-set",
3875              mp->is_set ? (char *) mp->locator_set_name : "");
3876     }
3877
3878   vam->retval = retval;
3879   vam->result_ready = 1;
3880 }
3881
3882 static void
3883   vl_api_show_one_nsh_mapping_reply_t_handler_json
3884   (vl_api_show_one_nsh_mapping_reply_t * mp)
3885 {
3886   vat_main_t *vam = &vat_main;
3887   vat_json_node_t node;
3888   u8 *status = 0;
3889
3890   status = format (0, "%s", mp->is_set ? "yes" : "no");
3891   vec_add1 (status, 0);
3892
3893   vat_json_init_object (&node);
3894   vat_json_object_add_string_copy (&node, "is_set", status);
3895   if (mp->is_set)
3896     {
3897       vat_json_object_add_string_copy (&node, "locator_set",
3898                                        mp->locator_set_name);
3899     }
3900
3901   vec_free (status);
3902
3903   vat_json_print (vam->ofp, &node);
3904   vat_json_free (&node);
3905
3906   vam->retval = ntohl (mp->retval);
3907   vam->result_ready = 1;
3908 }
3909
3910 static void
3911   vl_api_show_one_map_register_ttl_reply_t_handler
3912   (vl_api_show_one_map_register_ttl_reply_t * mp)
3913 {
3914   vat_main_t *vam = &vat_main;
3915   i32 retval = ntohl (mp->retval);
3916
3917   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3918
3919   if (0 <= retval)
3920     {
3921       print (vam->ofp, "ttl: %u", mp->ttl);
3922     }
3923
3924   vam->retval = retval;
3925   vam->result_ready = 1;
3926 }
3927
3928 static void
3929   vl_api_show_one_map_register_ttl_reply_t_handler_json
3930   (vl_api_show_one_map_register_ttl_reply_t * mp)
3931 {
3932   vat_main_t *vam = &vat_main;
3933   vat_json_node_t node;
3934
3935   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3936   vat_json_init_object (&node);
3937   vat_json_object_add_uint (&node, "ttl", mp->ttl);
3938
3939   vat_json_print (vam->ofp, &node);
3940   vat_json_free (&node);
3941
3942   vam->retval = ntohl (mp->retval);
3943   vam->result_ready = 1;
3944 }
3945
3946 static void
3947 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3948 {
3949   vat_main_t *vam = &vat_main;
3950   i32 retval = ntohl (mp->retval);
3951
3952   if (0 <= retval)
3953     {
3954       print (vam->ofp, "%-20s%-16s",
3955              mp->status ? "enabled" : "disabled",
3956              mp->status ? (char *) mp->locator_set_name : "");
3957     }
3958
3959   vam->retval = retval;
3960   vam->result_ready = 1;
3961 }
3962
3963 static void
3964 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3965 {
3966   vat_main_t *vam = &vat_main;
3967   vat_json_node_t node;
3968   u8 *status = 0;
3969
3970   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3971   vec_add1 (status, 0);
3972
3973   vat_json_init_object (&node);
3974   vat_json_object_add_string_copy (&node, "status", status);
3975   if (mp->status)
3976     {
3977       vat_json_object_add_string_copy (&node, "locator_set",
3978                                        mp->locator_set_name);
3979     }
3980
3981   vec_free (status);
3982
3983   vat_json_print (vam->ofp, &node);
3984   vat_json_free (&node);
3985
3986   vam->retval = ntohl (mp->retval);
3987   vam->result_ready = 1;
3988 }
3989
3990 static u8 *
3991 format_policer_type (u8 * s, va_list * va)
3992 {
3993   u32 i = va_arg (*va, u32);
3994
3995   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3996     s = format (s, "1r2c");
3997   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3998     s = format (s, "1r3c");
3999   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4000     s = format (s, "2r3c-2698");
4001   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4002     s = format (s, "2r3c-4115");
4003   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4004     s = format (s, "2r3c-mef5cf1");
4005   else
4006     s = format (s, "ILLEGAL");
4007   return s;
4008 }
4009
4010 static u8 *
4011 format_policer_rate_type (u8 * s, va_list * va)
4012 {
4013   u32 i = va_arg (*va, u32);
4014
4015   if (i == SSE2_QOS_RATE_KBPS)
4016     s = format (s, "kbps");
4017   else if (i == SSE2_QOS_RATE_PPS)
4018     s = format (s, "pps");
4019   else
4020     s = format (s, "ILLEGAL");
4021   return s;
4022 }
4023
4024 static u8 *
4025 format_policer_round_type (u8 * s, va_list * va)
4026 {
4027   u32 i = va_arg (*va, u32);
4028
4029   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4030     s = format (s, "closest");
4031   else if (i == SSE2_QOS_ROUND_TO_UP)
4032     s = format (s, "up");
4033   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4034     s = format (s, "down");
4035   else
4036     s = format (s, "ILLEGAL");
4037   return s;
4038 }
4039
4040 static u8 *
4041 format_policer_action_type (u8 * s, va_list * va)
4042 {
4043   u32 i = va_arg (*va, u32);
4044
4045   if (i == SSE2_QOS_ACTION_DROP)
4046     s = format (s, "drop");
4047   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4048     s = format (s, "transmit");
4049   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4050     s = format (s, "mark-and-transmit");
4051   else
4052     s = format (s, "ILLEGAL");
4053   return s;
4054 }
4055
4056 static u8 *
4057 format_dscp (u8 * s, va_list * va)
4058 {
4059   u32 i = va_arg (*va, u32);
4060   char *t = 0;
4061
4062   switch (i)
4063     {
4064 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4065       foreach_vnet_dscp
4066 #undef _
4067     default:
4068       return format (s, "ILLEGAL");
4069     }
4070   s = format (s, "%s", t);
4071   return s;
4072 }
4073
4074 static void
4075 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4076 {
4077   vat_main_t *vam = &vat_main;
4078   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4079
4080   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4081     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4082   else
4083     conform_dscp_str = format (0, "");
4084
4085   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4086     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4087   else
4088     exceed_dscp_str = format (0, "");
4089
4090   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4091     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4092   else
4093     violate_dscp_str = format (0, "");
4094
4095   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4096          "rate type %U, round type %U, %s rate, %s color-aware, "
4097          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4098          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4099          "conform action %U%s, exceed action %U%s, violate action %U%s",
4100          mp->name,
4101          format_policer_type, mp->type,
4102          ntohl (mp->cir),
4103          ntohl (mp->eir),
4104          clib_net_to_host_u64 (mp->cb),
4105          clib_net_to_host_u64 (mp->eb),
4106          format_policer_rate_type, mp->rate_type,
4107          format_policer_round_type, mp->round_type,
4108          mp->single_rate ? "single" : "dual",
4109          mp->color_aware ? "is" : "not",
4110          ntohl (mp->cir_tokens_per_period),
4111          ntohl (mp->pir_tokens_per_period),
4112          ntohl (mp->scale),
4113          ntohl (mp->current_limit),
4114          ntohl (mp->current_bucket),
4115          ntohl (mp->extended_limit),
4116          ntohl (mp->extended_bucket),
4117          clib_net_to_host_u64 (mp->last_update_time),
4118          format_policer_action_type, mp->conform_action_type,
4119          conform_dscp_str,
4120          format_policer_action_type, mp->exceed_action_type,
4121          exceed_dscp_str,
4122          format_policer_action_type, mp->violate_action_type,
4123          violate_dscp_str);
4124
4125   vec_free (conform_dscp_str);
4126   vec_free (exceed_dscp_str);
4127   vec_free (violate_dscp_str);
4128 }
4129
4130 static void vl_api_policer_details_t_handler_json
4131   (vl_api_policer_details_t * mp)
4132 {
4133   vat_main_t *vam = &vat_main;
4134   vat_json_node_t *node;
4135   u8 *rate_type_str, *round_type_str, *type_str;
4136   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4137
4138   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4139   round_type_str =
4140     format (0, "%U", format_policer_round_type, mp->round_type);
4141   type_str = format (0, "%U", format_policer_type, mp->type);
4142   conform_action_str = format (0, "%U", format_policer_action_type,
4143                                mp->conform_action_type);
4144   exceed_action_str = format (0, "%U", format_policer_action_type,
4145                               mp->exceed_action_type);
4146   violate_action_str = format (0, "%U", format_policer_action_type,
4147                                mp->violate_action_type);
4148
4149   if (VAT_JSON_ARRAY != vam->json_tree.type)
4150     {
4151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4152       vat_json_init_array (&vam->json_tree);
4153     }
4154   node = vat_json_array_add (&vam->json_tree);
4155
4156   vat_json_init_object (node);
4157   vat_json_object_add_string_copy (node, "name", mp->name);
4158   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4159   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4160   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4161   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4162   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4163   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4164   vat_json_object_add_string_copy (node, "type", type_str);
4165   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4166   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4167   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4168   vat_json_object_add_uint (node, "cir_tokens_per_period",
4169                             ntohl (mp->cir_tokens_per_period));
4170   vat_json_object_add_uint (node, "eir_tokens_per_period",
4171                             ntohl (mp->pir_tokens_per_period));
4172   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4173   vat_json_object_add_uint (node, "current_bucket",
4174                             ntohl (mp->current_bucket));
4175   vat_json_object_add_uint (node, "extended_limit",
4176                             ntohl (mp->extended_limit));
4177   vat_json_object_add_uint (node, "extended_bucket",
4178                             ntohl (mp->extended_bucket));
4179   vat_json_object_add_uint (node, "last_update_time",
4180                             ntohl (mp->last_update_time));
4181   vat_json_object_add_string_copy (node, "conform_action",
4182                                    conform_action_str);
4183   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4184     {
4185       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4186       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4187       vec_free (dscp_str);
4188     }
4189   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4190   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4191     {
4192       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4193       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4194       vec_free (dscp_str);
4195     }
4196   vat_json_object_add_string_copy (node, "violate_action",
4197                                    violate_action_str);
4198   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4199     {
4200       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4201       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4202       vec_free (dscp_str);
4203     }
4204
4205   vec_free (rate_type_str);
4206   vec_free (round_type_str);
4207   vec_free (type_str);
4208   vec_free (conform_action_str);
4209   vec_free (exceed_action_str);
4210   vec_free (violate_action_str);
4211 }
4212
4213 static void
4214 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4215                                            mp)
4216 {
4217   vat_main_t *vam = &vat_main;
4218   int i, count = ntohl (mp->count);
4219
4220   if (count > 0)
4221     print (vam->ofp, "classify table ids (%d) : ", count);
4222   for (i = 0; i < count; i++)
4223     {
4224       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4225       print (vam->ofp, (i < count - 1) ? "," : "");
4226     }
4227   vam->retval = ntohl (mp->retval);
4228   vam->result_ready = 1;
4229 }
4230
4231 static void
4232   vl_api_classify_table_ids_reply_t_handler_json
4233   (vl_api_classify_table_ids_reply_t * mp)
4234 {
4235   vat_main_t *vam = &vat_main;
4236   int i, count = ntohl (mp->count);
4237
4238   if (count > 0)
4239     {
4240       vat_json_node_t node;
4241
4242       vat_json_init_object (&node);
4243       for (i = 0; i < count; i++)
4244         {
4245           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4246         }
4247       vat_json_print (vam->ofp, &node);
4248       vat_json_free (&node);
4249     }
4250   vam->retval = ntohl (mp->retval);
4251   vam->result_ready = 1;
4252 }
4253
4254 static void
4255   vl_api_classify_table_by_interface_reply_t_handler
4256   (vl_api_classify_table_by_interface_reply_t * mp)
4257 {
4258   vat_main_t *vam = &vat_main;
4259   u32 table_id;
4260
4261   table_id = ntohl (mp->l2_table_id);
4262   if (table_id != ~0)
4263     print (vam->ofp, "l2 table id : %d", table_id);
4264   else
4265     print (vam->ofp, "l2 table id : No input ACL tables configured");
4266   table_id = ntohl (mp->ip4_table_id);
4267   if (table_id != ~0)
4268     print (vam->ofp, "ip4 table id : %d", table_id);
4269   else
4270     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4271   table_id = ntohl (mp->ip6_table_id);
4272   if (table_id != ~0)
4273     print (vam->ofp, "ip6 table id : %d", table_id);
4274   else
4275     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4276   vam->retval = ntohl (mp->retval);
4277   vam->result_ready = 1;
4278 }
4279
4280 static void
4281   vl_api_classify_table_by_interface_reply_t_handler_json
4282   (vl_api_classify_table_by_interface_reply_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285   vat_json_node_t node;
4286
4287   vat_json_init_object (&node);
4288
4289   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4290   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4291   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4292
4293   vat_json_print (vam->ofp, &node);
4294   vat_json_free (&node);
4295
4296   vam->retval = ntohl (mp->retval);
4297   vam->result_ready = 1;
4298 }
4299
4300 static void vl_api_policer_add_del_reply_t_handler
4301   (vl_api_policer_add_del_reply_t * mp)
4302 {
4303   vat_main_t *vam = &vat_main;
4304   i32 retval = ntohl (mp->retval);
4305   if (vam->async_mode)
4306     {
4307       vam->async_errors += (retval < 0);
4308     }
4309   else
4310     {
4311       vam->retval = retval;
4312       vam->result_ready = 1;
4313       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4314         /*
4315          * Note: this is just barely thread-safe, depends on
4316          * the main thread spinning waiting for an answer...
4317          */
4318         errmsg ("policer index %d", ntohl (mp->policer_index));
4319     }
4320 }
4321
4322 static void vl_api_policer_add_del_reply_t_handler_json
4323   (vl_api_policer_add_del_reply_t * mp)
4324 {
4325   vat_main_t *vam = &vat_main;
4326   vat_json_node_t node;
4327
4328   vat_json_init_object (&node);
4329   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4330   vat_json_object_add_uint (&node, "policer_index",
4331                             ntohl (mp->policer_index));
4332
4333   vat_json_print (vam->ofp, &node);
4334   vat_json_free (&node);
4335
4336   vam->retval = ntohl (mp->retval);
4337   vam->result_ready = 1;
4338 }
4339
4340 /* Format hex dump. */
4341 u8 *
4342 format_hex_bytes (u8 * s, va_list * va)
4343 {
4344   u8 *bytes = va_arg (*va, u8 *);
4345   int n_bytes = va_arg (*va, int);
4346   uword i;
4347
4348   /* Print short or long form depending on byte count. */
4349   uword short_form = n_bytes <= 32;
4350   uword indent = format_get_indent (s);
4351
4352   if (n_bytes == 0)
4353     return s;
4354
4355   for (i = 0; i < n_bytes; i++)
4356     {
4357       if (!short_form && (i % 32) == 0)
4358         s = format (s, "%08x: ", i);
4359       s = format (s, "%02x", bytes[i]);
4360       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4361         s = format (s, "\n%U", format_white_space, indent);
4362     }
4363
4364   return s;
4365 }
4366
4367 static void
4368 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4369                                             * mp)
4370 {
4371   vat_main_t *vam = &vat_main;
4372   i32 retval = ntohl (mp->retval);
4373   if (retval == 0)
4374     {
4375       print (vam->ofp, "classify table info :");
4376       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4377              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4378              ntohl (mp->miss_next_index));
4379       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4380              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4381              ntohl (mp->match_n_vectors));
4382       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4383              ntohl (mp->mask_length));
4384     }
4385   vam->retval = retval;
4386   vam->result_ready = 1;
4387 }
4388
4389 static void
4390   vl_api_classify_table_info_reply_t_handler_json
4391   (vl_api_classify_table_info_reply_t * mp)
4392 {
4393   vat_main_t *vam = &vat_main;
4394   vat_json_node_t node;
4395
4396   i32 retval = ntohl (mp->retval);
4397   if (retval == 0)
4398     {
4399       vat_json_init_object (&node);
4400
4401       vat_json_object_add_int (&node, "sessions",
4402                                ntohl (mp->active_sessions));
4403       vat_json_object_add_int (&node, "nexttbl",
4404                                ntohl (mp->next_table_index));
4405       vat_json_object_add_int (&node, "nextnode",
4406                                ntohl (mp->miss_next_index));
4407       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4408       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4409       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4410       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4411                       ntohl (mp->mask_length), 0);
4412       vat_json_object_add_string_copy (&node, "mask", s);
4413
4414       vat_json_print (vam->ofp, &node);
4415       vat_json_free (&node);
4416     }
4417   vam->retval = ntohl (mp->retval);
4418   vam->result_ready = 1;
4419 }
4420
4421 static void
4422 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4423                                            mp)
4424 {
4425   vat_main_t *vam = &vat_main;
4426
4427   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4428          ntohl (mp->hit_next_index), ntohl (mp->advance),
4429          ntohl (mp->opaque_index));
4430   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4431          ntohl (mp->match_length));
4432 }
4433
4434 static void
4435   vl_api_classify_session_details_t_handler_json
4436   (vl_api_classify_session_details_t * mp)
4437 {
4438   vat_main_t *vam = &vat_main;
4439   vat_json_node_t *node = NULL;
4440
4441   if (VAT_JSON_ARRAY != vam->json_tree.type)
4442     {
4443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4444       vat_json_init_array (&vam->json_tree);
4445     }
4446   node = vat_json_array_add (&vam->json_tree);
4447
4448   vat_json_init_object (node);
4449   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4450   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4451   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4452   u8 *s =
4453     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4454             0);
4455   vat_json_object_add_string_copy (node, "match", s);
4456 }
4457
4458 static void vl_api_pg_create_interface_reply_t_handler
4459   (vl_api_pg_create_interface_reply_t * mp)
4460 {
4461   vat_main_t *vam = &vat_main;
4462
4463   vam->retval = ntohl (mp->retval);
4464   vam->result_ready = 1;
4465 }
4466
4467 static void vl_api_pg_create_interface_reply_t_handler_json
4468   (vl_api_pg_create_interface_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   vat_json_node_t node;
4472
4473   i32 retval = ntohl (mp->retval);
4474   if (retval == 0)
4475     {
4476       vat_json_init_object (&node);
4477
4478       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4479
4480       vat_json_print (vam->ofp, &node);
4481       vat_json_free (&node);
4482     }
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void vl_api_policer_classify_details_t_handler
4488   (vl_api_policer_classify_details_t * mp)
4489 {
4490   vat_main_t *vam = &vat_main;
4491
4492   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4493          ntohl (mp->table_index));
4494 }
4495
4496 static void vl_api_policer_classify_details_t_handler_json
4497   (vl_api_policer_classify_details_t * mp)
4498 {
4499   vat_main_t *vam = &vat_main;
4500   vat_json_node_t *node;
4501
4502   if (VAT_JSON_ARRAY != vam->json_tree.type)
4503     {
4504       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4505       vat_json_init_array (&vam->json_tree);
4506     }
4507   node = vat_json_array_add (&vam->json_tree);
4508
4509   vat_json_init_object (node);
4510   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4511   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4512 }
4513
4514 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4515   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4516 {
4517   vat_main_t *vam = &vat_main;
4518   i32 retval = ntohl (mp->retval);
4519   if (vam->async_mode)
4520     {
4521       vam->async_errors += (retval < 0);
4522     }
4523   else
4524     {
4525       vam->retval = retval;
4526       vam->sw_if_index = ntohl (mp->sw_if_index);
4527       vam->result_ready = 1;
4528     }
4529 }
4530
4531 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4532   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4533 {
4534   vat_main_t *vam = &vat_main;
4535   vat_json_node_t node;
4536
4537   vat_json_init_object (&node);
4538   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4539   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4540
4541   vat_json_print (vam->ofp, &node);
4542   vat_json_free (&node);
4543
4544   vam->retval = ntohl (mp->retval);
4545   vam->result_ready = 1;
4546 }
4547
4548 static void vl_api_flow_classify_details_t_handler
4549   (vl_api_flow_classify_details_t * mp)
4550 {
4551   vat_main_t *vam = &vat_main;
4552
4553   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4554          ntohl (mp->table_index));
4555 }
4556
4557 static void vl_api_flow_classify_details_t_handler_json
4558   (vl_api_flow_classify_details_t * mp)
4559 {
4560   vat_main_t *vam = &vat_main;
4561   vat_json_node_t *node;
4562
4563   if (VAT_JSON_ARRAY != vam->json_tree.type)
4564     {
4565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4566       vat_json_init_array (&vam->json_tree);
4567     }
4568   node = vat_json_array_add (&vam->json_tree);
4569
4570   vat_json_init_object (node);
4571   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4572   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4573 }
4574
4575 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4576 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4577 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4578 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4579 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4580 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4581 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4582 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4583 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4584 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4585 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4586 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4587 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4588 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4589 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4590 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4591 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4592 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4593
4594 /*
4595  * Generate boilerplate reply handlers, which
4596  * dig the return value out of the xxx_reply_t API message,
4597  * stick it into vam->retval, and set vam->result_ready
4598  *
4599  * Could also do this by pointing N message decode slots at
4600  * a single function, but that could break in subtle ways.
4601  */
4602
4603 #define foreach_standard_reply_retval_handler           \
4604 _(sw_interface_set_flags_reply)                         \
4605 _(sw_interface_add_del_address_reply)                   \
4606 _(sw_interface_set_table_reply)                         \
4607 _(sw_interface_set_mpls_enable_reply)                   \
4608 _(sw_interface_set_vpath_reply)                         \
4609 _(sw_interface_set_vxlan_bypass_reply)                  \
4610 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4611 _(sw_interface_set_l2_bridge_reply)                     \
4612 _(bridge_domain_add_del_reply)                          \
4613 _(sw_interface_set_l2_xconnect_reply)                   \
4614 _(l2fib_add_del_reply)                                  \
4615 _(l2fib_flush_int_reply)                                \
4616 _(l2fib_flush_bd_reply)                                 \
4617 _(ip_add_del_route_reply)                               \
4618 _(ip_mroute_add_del_reply)                              \
4619 _(mpls_route_add_del_reply)                             \
4620 _(mpls_ip_bind_unbind_reply)                            \
4621 _(proxy_arp_add_del_reply)                              \
4622 _(proxy_arp_intfc_enable_disable_reply)                 \
4623 _(sw_interface_set_unnumbered_reply)                    \
4624 _(ip_neighbor_add_del_reply)                            \
4625 _(reset_vrf_reply)                                      \
4626 _(oam_add_del_reply)                                    \
4627 _(reset_fib_reply)                                      \
4628 _(dhcp_proxy_config_reply)                              \
4629 _(dhcp_proxy_set_vss_reply)                             \
4630 _(dhcp_client_config_reply)                             \
4631 _(set_ip_flow_hash_reply)                               \
4632 _(sw_interface_ip6_enable_disable_reply)                \
4633 _(sw_interface_ip6_set_link_local_address_reply)        \
4634 _(ip6nd_proxy_add_del_reply)                            \
4635 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4636 _(sw_interface_ip6nd_ra_config_reply)                   \
4637 _(set_arp_neighbor_limit_reply)                         \
4638 _(l2_patch_add_del_reply)                               \
4639 _(sr_policy_add_reply)                                  \
4640 _(sr_policy_mod_reply)                                  \
4641 _(sr_policy_del_reply)                                  \
4642 _(sr_localsid_add_del_reply)                            \
4643 _(sr_steering_add_del_reply)                            \
4644 _(classify_add_del_session_reply)                       \
4645 _(classify_set_interface_ip_table_reply)                \
4646 _(classify_set_interface_l2_tables_reply)               \
4647 _(l2tpv3_set_tunnel_cookies_reply)                      \
4648 _(l2tpv3_interface_enable_disable_reply)                \
4649 _(l2tpv3_set_lookup_key_reply)                          \
4650 _(l2_fib_clear_table_reply)                             \
4651 _(l2_interface_efp_filter_reply)                        \
4652 _(l2_interface_vlan_tag_rewrite_reply)                  \
4653 _(modify_vhost_user_if_reply)                           \
4654 _(delete_vhost_user_if_reply)                           \
4655 _(want_ip4_arp_events_reply)                            \
4656 _(want_ip6_nd_events_reply)                             \
4657 _(want_l2_macs_events_reply)                            \
4658 _(input_acl_set_interface_reply)                        \
4659 _(ipsec_spd_add_del_reply)                              \
4660 _(ipsec_interface_add_del_spd_reply)                    \
4661 _(ipsec_spd_add_del_entry_reply)                        \
4662 _(ipsec_sad_add_del_entry_reply)                        \
4663 _(ipsec_sa_set_key_reply)                               \
4664 _(ipsec_tunnel_if_add_del_reply)                        \
4665 _(ikev2_profile_add_del_reply)                          \
4666 _(ikev2_profile_set_auth_reply)                         \
4667 _(ikev2_profile_set_id_reply)                           \
4668 _(ikev2_profile_set_ts_reply)                           \
4669 _(ikev2_set_local_key_reply)                            \
4670 _(ikev2_set_responder_reply)                            \
4671 _(ikev2_set_ike_transforms_reply)                       \
4672 _(ikev2_set_esp_transforms_reply)                       \
4673 _(ikev2_set_sa_lifetime_reply)                          \
4674 _(ikev2_initiate_sa_init_reply)                         \
4675 _(ikev2_initiate_del_ike_sa_reply)                      \
4676 _(ikev2_initiate_del_child_sa_reply)                    \
4677 _(ikev2_initiate_rekey_child_sa_reply)                  \
4678 _(delete_loopback_reply)                                \
4679 _(bd_ip_mac_add_del_reply)                              \
4680 _(map_del_domain_reply)                                 \
4681 _(map_add_del_rule_reply)                               \
4682 _(want_interface_events_reply)                          \
4683 _(want_stats_reply)                                     \
4684 _(cop_interface_enable_disable_reply)                   \
4685 _(cop_whitelist_enable_disable_reply)                   \
4686 _(sw_interface_clear_stats_reply)                       \
4687 _(ioam_enable_reply)                              \
4688 _(ioam_disable_reply)                              \
4689 _(one_add_del_locator_reply)                            \
4690 _(one_add_del_local_eid_reply)                          \
4691 _(one_add_del_remote_mapping_reply)                     \
4692 _(one_add_del_adjacency_reply)                          \
4693 _(one_add_del_map_resolver_reply)                       \
4694 _(one_add_del_map_server_reply)                         \
4695 _(one_enable_disable_reply)                             \
4696 _(one_rloc_probe_enable_disable_reply)                  \
4697 _(one_map_register_enable_disable_reply)                \
4698 _(one_map_register_set_ttl_reply)                       \
4699 _(one_map_register_fallback_threshold_reply)            \
4700 _(one_pitr_set_locator_set_reply)                       \
4701 _(one_map_request_mode_reply)                           \
4702 _(one_add_del_map_request_itr_rlocs_reply)              \
4703 _(one_eid_table_add_del_map_reply)                      \
4704 _(one_use_petr_reply)                                   \
4705 _(one_stats_enable_disable_reply)                       \
4706 _(one_add_del_l2_arp_entry_reply)                       \
4707 _(one_stats_flush_reply)                                \
4708 _(gpe_enable_disable_reply)                             \
4709 _(gpe_set_encap_mode_reply)                             \
4710 _(gpe_add_del_iface_reply)                              \
4711 _(gpe_add_del_native_fwd_rpath_reply)                   \
4712 _(af_packet_delete_reply)                               \
4713 _(policer_classify_set_interface_reply)                 \
4714 _(netmap_create_reply)                                  \
4715 _(netmap_delete_reply)                                  \
4716 _(set_ipfix_exporter_reply)                             \
4717 _(set_ipfix_classify_stream_reply)                      \
4718 _(ipfix_classify_table_add_del_reply)                   \
4719 _(flow_classify_set_interface_reply)                    \
4720 _(sw_interface_span_enable_disable_reply)               \
4721 _(pg_capture_reply)                                     \
4722 _(pg_enable_disable_reply)                              \
4723 _(ip_source_and_port_range_check_add_del_reply)         \
4724 _(ip_source_and_port_range_check_interface_add_del_reply)\
4725 _(delete_subif_reply)                                   \
4726 _(l2_interface_pbb_tag_rewrite_reply)                   \
4727 _(punt_reply)                                           \
4728 _(feature_enable_disable_reply)                         \
4729 _(sw_interface_tag_add_del_reply)                       \
4730 _(sw_interface_set_mtu_reply)                           \
4731 _(p2p_ethernet_add_reply)                               \
4732 _(p2p_ethernet_del_reply)                               \
4733 _(lldp_config_reply)                                    \
4734 _(sw_interface_set_lldp_reply)
4735
4736 #define _(n)                                    \
4737     static void vl_api_##n##_t_handler          \
4738     (vl_api_##n##_t * mp)                       \
4739     {                                           \
4740         vat_main_t * vam = &vat_main;           \
4741         i32 retval = ntohl(mp->retval);         \
4742         if (vam->async_mode) {                  \
4743             vam->async_errors += (retval < 0);  \
4744         } else {                                \
4745             vam->retval = retval;               \
4746             vam->result_ready = 1;              \
4747         }                                       \
4748     }
4749 foreach_standard_reply_retval_handler;
4750 #undef _
4751
4752 #define _(n)                                    \
4753     static void vl_api_##n##_t_handler_json     \
4754     (vl_api_##n##_t * mp)                       \
4755     {                                           \
4756         vat_main_t * vam = &vat_main;           \
4757         vat_json_node_t node;                   \
4758         vat_json_init_object(&node);            \
4759         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4760         vat_json_print(vam->ofp, &node);        \
4761         vam->retval = ntohl(mp->retval);        \
4762         vam->result_ready = 1;                  \
4763     }
4764 foreach_standard_reply_retval_handler;
4765 #undef _
4766
4767 /*
4768  * Table of message reply handlers, must include boilerplate handlers
4769  * we just generated
4770  */
4771
4772 #define foreach_vpe_api_reply_msg                                       \
4773 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4774 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4775 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4776 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4777 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4778 _(CLI_REPLY, cli_reply)                                                 \
4779 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4780 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4781   sw_interface_add_del_address_reply)                                   \
4782 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4783 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4784 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4785 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4786 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4787 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4788   sw_interface_set_l2_xconnect_reply)                                   \
4789 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4790   sw_interface_set_l2_bridge_reply)                                     \
4791 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4792 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4793 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4794 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4795 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4796 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4797 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4798 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4799 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4800 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4801 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4802 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4803 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4804 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4805 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4806 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4807 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4808 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4809   proxy_arp_intfc_enable_disable_reply)                                 \
4810 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4811 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4812   sw_interface_set_unnumbered_reply)                                    \
4813 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4814 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4815 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4816 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4817 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4818 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4819 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4820 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4821 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4822 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4823 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4824 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4825   sw_interface_ip6_enable_disable_reply)                                \
4826 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4827   sw_interface_ip6_set_link_local_address_reply)                        \
4828 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4829 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4830 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4831   sw_interface_ip6nd_ra_prefix_reply)                                   \
4832 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4833   sw_interface_ip6nd_ra_config_reply)                                   \
4834 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4835 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4836 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4837 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4838 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4839 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4840 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4841 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4842 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4843 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4844 classify_set_interface_ip_table_reply)                                  \
4845 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4846   classify_set_interface_l2_tables_reply)                               \
4847 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4848 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4849 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4850 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4851 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4852   l2tpv3_interface_enable_disable_reply)                                \
4853 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4854 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4855 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4856 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4857 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4858 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4859 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4860 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4861 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4862 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4863 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4864 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4865 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4866 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4867 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4868 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4869 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4870 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4871 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4872 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4873 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4874 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4875 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
4876 _(L2_MACS_EVENT, l2_macs_event)                                         \
4877 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4878 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4879 _(IP_DETAILS, ip_details)                                               \
4880 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4881 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4882 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4883 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4884 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4885 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4886 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4887 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4888 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4889 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4890 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4891 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4892 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4893 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4894 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4895 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4896 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4897 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4898 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4899 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4900 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4901 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4902 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4903 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4904 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4905 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4906 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4907 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4908 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4909 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4910 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4911 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4912 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4913 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4914 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4915 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4916 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4917 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4918 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4919 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4920 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4921 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4922 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4923 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4924 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4925   one_map_register_enable_disable_reply)                                \
4926 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
4927 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
4928   one_map_register_fallback_threshold_reply)                            \
4929 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4930   one_rloc_probe_enable_disable_reply)                                  \
4931 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4932 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4933 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4934 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4935 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4936 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4937 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4938 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4939 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4940 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4941 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4942 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4943 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4944 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4945 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4946 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4947   show_one_stats_enable_disable_reply)                                  \
4948 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4949 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4950 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4951 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4952 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4953 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4954 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4955 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4956 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4957 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4958 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4959 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4960   gpe_add_del_native_fwd_rpath_reply)                                   \
4961 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4962   gpe_fwd_entry_path_details)                                           \
4963 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4964 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4965   one_add_del_map_request_itr_rlocs_reply)                              \
4966 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4967   one_get_map_request_itr_rlocs_reply)                                  \
4968 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4969 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4970 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4971 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4972 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4973 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4974   show_one_map_register_state_reply)                                    \
4975 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
4976 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
4977   show_one_map_register_fallback_threshold_reply)                       \
4978 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4979 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4980 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4981 _(POLICER_DETAILS, policer_details)                                     \
4982 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4983 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4984 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4985 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4986 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4987 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4988 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4989 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4990 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4991 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4992 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4993 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4994 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4995 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4996 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4997 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4998 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4999 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5000 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5001 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5002 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5003 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5004 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5005 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5006 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5007  ip_source_and_port_range_check_add_del_reply)                          \
5008 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5009  ip_source_and_port_range_check_interface_add_del_reply)                \
5010 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5011 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5012 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5013 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5014 _(PUNT_REPLY, punt_reply)                                               \
5015 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5016 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5017 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5018 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5019 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5020 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5021 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5022 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5023 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5024 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5025 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5026 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)
5027
5028 #define foreach_standalone_reply_msg                                    \
5029 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5030 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5031 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5032 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5033 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5034 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5035 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5036
5037 typedef struct
5038 {
5039   u8 *name;
5040   u32 value;
5041 } name_sort_t;
5042
5043
5044 #define STR_VTR_OP_CASE(op)     \
5045     case L2_VTR_ ## op:         \
5046         return "" # op;
5047
5048 static const char *
5049 str_vtr_op (u32 vtr_op)
5050 {
5051   switch (vtr_op)
5052     {
5053       STR_VTR_OP_CASE (DISABLED);
5054       STR_VTR_OP_CASE (PUSH_1);
5055       STR_VTR_OP_CASE (PUSH_2);
5056       STR_VTR_OP_CASE (POP_1);
5057       STR_VTR_OP_CASE (POP_2);
5058       STR_VTR_OP_CASE (TRANSLATE_1_1);
5059       STR_VTR_OP_CASE (TRANSLATE_1_2);
5060       STR_VTR_OP_CASE (TRANSLATE_2_1);
5061       STR_VTR_OP_CASE (TRANSLATE_2_2);
5062     }
5063
5064   return "UNKNOWN";
5065 }
5066
5067 static int
5068 dump_sub_interface_table (vat_main_t * vam)
5069 {
5070   const sw_interface_subif_t *sub = NULL;
5071
5072   if (vam->json_output)
5073     {
5074       clib_warning
5075         ("JSON output supported only for VPE API calls and dump_stats_table");
5076       return -99;
5077     }
5078
5079   print (vam->ofp,
5080          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5081          "Interface", "sw_if_index",
5082          "sub id", "dot1ad", "tags", "outer id",
5083          "inner id", "exact", "default", "outer any", "inner any");
5084
5085   vec_foreach (sub, vam->sw_if_subif_table)
5086   {
5087     print (vam->ofp,
5088            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5089            sub->interface_name,
5090            sub->sw_if_index,
5091            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5092            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5093            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5094            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5095     if (sub->vtr_op != L2_VTR_DISABLED)
5096       {
5097         print (vam->ofp,
5098                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5099                "tag1: %d tag2: %d ]",
5100                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5101                sub->vtr_tag1, sub->vtr_tag2);
5102       }
5103   }
5104
5105   return 0;
5106 }
5107
5108 static int
5109 name_sort_cmp (void *a1, void *a2)
5110 {
5111   name_sort_t *n1 = a1;
5112   name_sort_t *n2 = a2;
5113
5114   return strcmp ((char *) n1->name, (char *) n2->name);
5115 }
5116
5117 static int
5118 dump_interface_table (vat_main_t * vam)
5119 {
5120   hash_pair_t *p;
5121   name_sort_t *nses = 0, *ns;
5122
5123   if (vam->json_output)
5124     {
5125       clib_warning
5126         ("JSON output supported only for VPE API calls and dump_stats_table");
5127       return -99;
5128     }
5129
5130   /* *INDENT-OFF* */
5131   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5132   ({
5133     vec_add2 (nses, ns, 1);
5134     ns->name = (u8 *)(p->key);
5135     ns->value = (u32) p->value[0];
5136   }));
5137   /* *INDENT-ON* */
5138
5139   vec_sort_with_function (nses, name_sort_cmp);
5140
5141   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5142   vec_foreach (ns, nses)
5143   {
5144     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5145   }
5146   vec_free (nses);
5147   return 0;
5148 }
5149
5150 static int
5151 dump_ip_table (vat_main_t * vam, int is_ipv6)
5152 {
5153   const ip_details_t *det = NULL;
5154   const ip_address_details_t *address = NULL;
5155   u32 i = ~0;
5156
5157   print (vam->ofp, "%-12s", "sw_if_index");
5158
5159   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5160   {
5161     i++;
5162     if (!det->present)
5163       {
5164         continue;
5165       }
5166     print (vam->ofp, "%-12d", i);
5167     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5168     if (!det->addr)
5169       {
5170         continue;
5171       }
5172     vec_foreach (address, det->addr)
5173     {
5174       print (vam->ofp,
5175              "            %-30U%-13d",
5176              is_ipv6 ? format_ip6_address : format_ip4_address,
5177              address->ip, address->prefix_length);
5178     }
5179   }
5180
5181   return 0;
5182 }
5183
5184 static int
5185 dump_ipv4_table (vat_main_t * vam)
5186 {
5187   if (vam->json_output)
5188     {
5189       clib_warning
5190         ("JSON output supported only for VPE API calls and dump_stats_table");
5191       return -99;
5192     }
5193
5194   return dump_ip_table (vam, 0);
5195 }
5196
5197 static int
5198 dump_ipv6_table (vat_main_t * vam)
5199 {
5200   if (vam->json_output)
5201     {
5202       clib_warning
5203         ("JSON output supported only for VPE API calls and dump_stats_table");
5204       return -99;
5205     }
5206
5207   return dump_ip_table (vam, 1);
5208 }
5209
5210 static char *
5211 counter_type_to_str (u8 counter_type, u8 is_combined)
5212 {
5213   if (!is_combined)
5214     {
5215       switch (counter_type)
5216         {
5217         case VNET_INTERFACE_COUNTER_DROP:
5218           return "drop";
5219         case VNET_INTERFACE_COUNTER_PUNT:
5220           return "punt";
5221         case VNET_INTERFACE_COUNTER_IP4:
5222           return "ip4";
5223         case VNET_INTERFACE_COUNTER_IP6:
5224           return "ip6";
5225         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5226           return "rx-no-buf";
5227         case VNET_INTERFACE_COUNTER_RX_MISS:
5228           return "rx-miss";
5229         case VNET_INTERFACE_COUNTER_RX_ERROR:
5230           return "rx-error";
5231         case VNET_INTERFACE_COUNTER_TX_ERROR:
5232           return "tx-error";
5233         default:
5234           return "INVALID-COUNTER-TYPE";
5235         }
5236     }
5237   else
5238     {
5239       switch (counter_type)
5240         {
5241         case VNET_INTERFACE_COUNTER_RX:
5242           return "rx";
5243         case VNET_INTERFACE_COUNTER_TX:
5244           return "tx";
5245         default:
5246           return "INVALID-COUNTER-TYPE";
5247         }
5248     }
5249 }
5250
5251 static int
5252 dump_stats_table (vat_main_t * vam)
5253 {
5254   vat_json_node_t node;
5255   vat_json_node_t *msg_array;
5256   vat_json_node_t *msg;
5257   vat_json_node_t *counter_array;
5258   vat_json_node_t *counter;
5259   interface_counter_t c;
5260   u64 packets;
5261   ip4_fib_counter_t *c4;
5262   ip6_fib_counter_t *c6;
5263   ip4_nbr_counter_t *n4;
5264   ip6_nbr_counter_t *n6;
5265   int i, j;
5266
5267   if (!vam->json_output)
5268     {
5269       clib_warning ("dump_stats_table supported only in JSON format");
5270       return -99;
5271     }
5272
5273   vat_json_init_object (&node);
5274
5275   /* interface counters */
5276   msg_array = vat_json_object_add (&node, "interface_counters");
5277   vat_json_init_array (msg_array);
5278   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5279     {
5280       msg = vat_json_array_add (msg_array);
5281       vat_json_init_object (msg);
5282       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5283                                        (u8 *) counter_type_to_str (i, 0));
5284       vat_json_object_add_int (msg, "is_combined", 0);
5285       counter_array = vat_json_object_add (msg, "data");
5286       vat_json_init_array (counter_array);
5287       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5288         {
5289           packets = vam->simple_interface_counters[i][j];
5290           vat_json_array_add_uint (counter_array, packets);
5291         }
5292     }
5293   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5294     {
5295       msg = vat_json_array_add (msg_array);
5296       vat_json_init_object (msg);
5297       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5298                                        (u8 *) counter_type_to_str (i, 1));
5299       vat_json_object_add_int (msg, "is_combined", 1);
5300       counter_array = vat_json_object_add (msg, "data");
5301       vat_json_init_array (counter_array);
5302       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5303         {
5304           c = vam->combined_interface_counters[i][j];
5305           counter = vat_json_array_add (counter_array);
5306           vat_json_init_object (counter);
5307           vat_json_object_add_uint (counter, "packets", c.packets);
5308           vat_json_object_add_uint (counter, "bytes", c.bytes);
5309         }
5310     }
5311
5312   /* ip4 fib counters */
5313   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5314   vat_json_init_array (msg_array);
5315   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5316     {
5317       msg = vat_json_array_add (msg_array);
5318       vat_json_init_object (msg);
5319       vat_json_object_add_uint (msg, "vrf_id",
5320                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5321       counter_array = vat_json_object_add (msg, "c");
5322       vat_json_init_array (counter_array);
5323       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5324         {
5325           counter = vat_json_array_add (counter_array);
5326           vat_json_init_object (counter);
5327           c4 = &vam->ip4_fib_counters[i][j];
5328           vat_json_object_add_ip4 (counter, "address", c4->address);
5329           vat_json_object_add_uint (counter, "address_length",
5330                                     c4->address_length);
5331           vat_json_object_add_uint (counter, "packets", c4->packets);
5332           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5333         }
5334     }
5335
5336   /* ip6 fib counters */
5337   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5338   vat_json_init_array (msg_array);
5339   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5340     {
5341       msg = vat_json_array_add (msg_array);
5342       vat_json_init_object (msg);
5343       vat_json_object_add_uint (msg, "vrf_id",
5344                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5345       counter_array = vat_json_object_add (msg, "c");
5346       vat_json_init_array (counter_array);
5347       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5348         {
5349           counter = vat_json_array_add (counter_array);
5350           vat_json_init_object (counter);
5351           c6 = &vam->ip6_fib_counters[i][j];
5352           vat_json_object_add_ip6 (counter, "address", c6->address);
5353           vat_json_object_add_uint (counter, "address_length",
5354                                     c6->address_length);
5355           vat_json_object_add_uint (counter, "packets", c6->packets);
5356           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5357         }
5358     }
5359
5360   /* ip4 nbr counters */
5361   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5362   vat_json_init_array (msg_array);
5363   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5364     {
5365       msg = vat_json_array_add (msg_array);
5366       vat_json_init_object (msg);
5367       vat_json_object_add_uint (msg, "sw_if_index", i);
5368       counter_array = vat_json_object_add (msg, "c");
5369       vat_json_init_array (counter_array);
5370       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5371         {
5372           counter = vat_json_array_add (counter_array);
5373           vat_json_init_object (counter);
5374           n4 = &vam->ip4_nbr_counters[i][j];
5375           vat_json_object_add_ip4 (counter, "address", n4->address);
5376           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5377           vat_json_object_add_uint (counter, "packets", n4->packets);
5378           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5379         }
5380     }
5381
5382   /* ip6 nbr counters */
5383   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5384   vat_json_init_array (msg_array);
5385   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5386     {
5387       msg = vat_json_array_add (msg_array);
5388       vat_json_init_object (msg);
5389       vat_json_object_add_uint (msg, "sw_if_index", i);
5390       counter_array = vat_json_object_add (msg, "c");
5391       vat_json_init_array (counter_array);
5392       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5393         {
5394           counter = vat_json_array_add (counter_array);
5395           vat_json_init_object (counter);
5396           n6 = &vam->ip6_nbr_counters[i][j];
5397           vat_json_object_add_ip6 (counter, "address", n6->address);
5398           vat_json_object_add_uint (counter, "packets", n6->packets);
5399           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5400         }
5401     }
5402
5403   vat_json_print (vam->ofp, &node);
5404   vat_json_free (&node);
5405
5406   return 0;
5407 }
5408
5409 int
5410 exec (vat_main_t * vam)
5411 {
5412   api_main_t *am = &api_main;
5413   vl_api_cli_t *mp;
5414   f64 timeout;
5415   void *oldheap;
5416   u8 *cmd = 0;
5417   unformat_input_t *i = vam->input;
5418
5419   if (vec_len (i->buffer) == 0)
5420     return -1;
5421
5422   if (vam->exec_mode == 0 && unformat (i, "mode"))
5423     {
5424       vam->exec_mode = 1;
5425       return 0;
5426     }
5427   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5428     {
5429       vam->exec_mode = 0;
5430       return 0;
5431     }
5432
5433
5434   M (CLI, mp);
5435
5436   /*
5437    * Copy cmd into shared memory.
5438    * In order for the CLI command to work, it
5439    * must be a vector ending in \n, not a C-string ending
5440    * in \n\0.
5441    */
5442   pthread_mutex_lock (&am->vlib_rp->mutex);
5443   oldheap = svm_push_data_heap (am->vlib_rp);
5444
5445   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5446   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5447
5448   svm_pop_heap (oldheap);
5449   pthread_mutex_unlock (&am->vlib_rp->mutex);
5450
5451   mp->cmd_in_shmem = pointer_to_uword (cmd);
5452   S (mp);
5453   timeout = vat_time_now (vam) + 10.0;
5454
5455   while (vat_time_now (vam) < timeout)
5456     {
5457       if (vam->result_ready == 1)
5458         {
5459           u8 *free_me;
5460           if (vam->shmem_result != NULL)
5461             print (vam->ofp, "%s", vam->shmem_result);
5462           pthread_mutex_lock (&am->vlib_rp->mutex);
5463           oldheap = svm_push_data_heap (am->vlib_rp);
5464
5465           free_me = (u8 *) vam->shmem_result;
5466           vec_free (free_me);
5467
5468           svm_pop_heap (oldheap);
5469           pthread_mutex_unlock (&am->vlib_rp->mutex);
5470           return 0;
5471         }
5472     }
5473   return -99;
5474 }
5475
5476 /*
5477  * Future replacement of exec() that passes CLI buffers directly in
5478  * the API messages instead of an additional shared memory area.
5479  */
5480 static int
5481 exec_inband (vat_main_t * vam)
5482 {
5483   vl_api_cli_inband_t *mp;
5484   unformat_input_t *i = vam->input;
5485   int ret;
5486
5487   if (vec_len (i->buffer) == 0)
5488     return -1;
5489
5490   if (vam->exec_mode == 0 && unformat (i, "mode"))
5491     {
5492       vam->exec_mode = 1;
5493       return 0;
5494     }
5495   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5496     {
5497       vam->exec_mode = 0;
5498       return 0;
5499     }
5500
5501   /*
5502    * In order for the CLI command to work, it
5503    * must be a vector ending in \n, not a C-string ending
5504    * in \n\0.
5505    */
5506   u32 len = vec_len (vam->input->buffer);
5507   M2 (CLI_INBAND, mp, len);
5508   clib_memcpy (mp->cmd, vam->input->buffer, len);
5509   mp->length = htonl (len);
5510
5511   S (mp);
5512   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5513   return ret;
5514 }
5515
5516 static int
5517 api_create_loopback (vat_main_t * vam)
5518 {
5519   unformat_input_t *i = vam->input;
5520   vl_api_create_loopback_t *mp;
5521   vl_api_create_loopback_instance_t *mp_lbi;
5522   u8 mac_address[6];
5523   u8 mac_set = 0;
5524   u8 is_specified = 0;
5525   u32 user_instance = 0;
5526   int ret;
5527
5528   memset (mac_address, 0, sizeof (mac_address));
5529
5530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5531     {
5532       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5533         mac_set = 1;
5534       if (unformat (i, "instance %d", &user_instance))
5535         is_specified = 1;
5536       else
5537         break;
5538     }
5539
5540   if (is_specified)
5541     {
5542       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5543       mp_lbi->is_specified = is_specified;
5544       if (is_specified)
5545         mp_lbi->user_instance = htonl (user_instance);
5546       if (mac_set)
5547         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5548       S (mp_lbi);
5549     }
5550   else
5551     {
5552       /* Construct the API message */
5553       M (CREATE_LOOPBACK, mp);
5554       if (mac_set)
5555         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5556       S (mp);
5557     }
5558
5559   W (ret);
5560   return ret;
5561 }
5562
5563 static int
5564 api_delete_loopback (vat_main_t * vam)
5565 {
5566   unformat_input_t *i = vam->input;
5567   vl_api_delete_loopback_t *mp;
5568   u32 sw_if_index = ~0;
5569   int ret;
5570
5571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5572     {
5573       if (unformat (i, "sw_if_index %d", &sw_if_index))
5574         ;
5575       else
5576         break;
5577     }
5578
5579   if (sw_if_index == ~0)
5580     {
5581       errmsg ("missing sw_if_index");
5582       return -99;
5583     }
5584
5585   /* Construct the API message */
5586   M (DELETE_LOOPBACK, mp);
5587   mp->sw_if_index = ntohl (sw_if_index);
5588
5589   S (mp);
5590   W (ret);
5591   return ret;
5592 }
5593
5594 static int
5595 api_want_stats (vat_main_t * vam)
5596 {
5597   unformat_input_t *i = vam->input;
5598   vl_api_want_stats_t *mp;
5599   int enable = -1;
5600   int ret;
5601
5602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5603     {
5604       if (unformat (i, "enable"))
5605         enable = 1;
5606       else if (unformat (i, "disable"))
5607         enable = 0;
5608       else
5609         break;
5610     }
5611
5612   if (enable == -1)
5613     {
5614       errmsg ("missing enable|disable");
5615       return -99;
5616     }
5617
5618   M (WANT_STATS, mp);
5619   mp->enable_disable = enable;
5620
5621   S (mp);
5622   W (ret);
5623   return ret;
5624 }
5625
5626 static int
5627 api_want_interface_events (vat_main_t * vam)
5628 {
5629   unformat_input_t *i = vam->input;
5630   vl_api_want_interface_events_t *mp;
5631   int enable = -1;
5632   int ret;
5633
5634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5635     {
5636       if (unformat (i, "enable"))
5637         enable = 1;
5638       else if (unformat (i, "disable"))
5639         enable = 0;
5640       else
5641         break;
5642     }
5643
5644   if (enable == -1)
5645     {
5646       errmsg ("missing enable|disable");
5647       return -99;
5648     }
5649
5650   M (WANT_INTERFACE_EVENTS, mp);
5651   mp->enable_disable = enable;
5652
5653   vam->interface_event_display = enable;
5654
5655   S (mp);
5656   W (ret);
5657   return ret;
5658 }
5659
5660
5661 /* Note: non-static, called once to set up the initial intfc table */
5662 int
5663 api_sw_interface_dump (vat_main_t * vam)
5664 {
5665   vl_api_sw_interface_dump_t *mp;
5666   vl_api_control_ping_t *mp_ping;
5667   hash_pair_t *p;
5668   name_sort_t *nses = 0, *ns;
5669   sw_interface_subif_t *sub = NULL;
5670   int ret;
5671
5672   /* Toss the old name table */
5673   /* *INDENT-OFF* */
5674   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5675   ({
5676     vec_add2 (nses, ns, 1);
5677     ns->name = (u8 *)(p->key);
5678     ns->value = (u32) p->value[0];
5679   }));
5680   /* *INDENT-ON* */
5681
5682   hash_free (vam->sw_if_index_by_interface_name);
5683
5684   vec_foreach (ns, nses) vec_free (ns->name);
5685
5686   vec_free (nses);
5687
5688   vec_foreach (sub, vam->sw_if_subif_table)
5689   {
5690     vec_free (sub->interface_name);
5691   }
5692   vec_free (vam->sw_if_subif_table);
5693
5694   /* recreate the interface name hash table */
5695   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5696
5697   /* Get list of ethernets */
5698   M (SW_INTERFACE_DUMP, mp);
5699   mp->name_filter_valid = 1;
5700   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5701   S (mp);
5702
5703   /* and local / loopback interfaces */
5704   M (SW_INTERFACE_DUMP, mp);
5705   mp->name_filter_valid = 1;
5706   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5707   S (mp);
5708
5709   /* and packet-generator interfaces */
5710   M (SW_INTERFACE_DUMP, mp);
5711   mp->name_filter_valid = 1;
5712   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5713   S (mp);
5714
5715   /* and vxlan-gpe tunnel interfaces */
5716   M (SW_INTERFACE_DUMP, mp);
5717   mp->name_filter_valid = 1;
5718   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5719            sizeof (mp->name_filter) - 1);
5720   S (mp);
5721
5722   /* and vxlan tunnel interfaces */
5723   M (SW_INTERFACE_DUMP, mp);
5724   mp->name_filter_valid = 1;
5725   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5726   S (mp);
5727
5728   /* and host (af_packet) interfaces */
5729   M (SW_INTERFACE_DUMP, mp);
5730   mp->name_filter_valid = 1;
5731   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5732   S (mp);
5733
5734   /* and l2tpv3 tunnel interfaces */
5735   M (SW_INTERFACE_DUMP, mp);
5736   mp->name_filter_valid = 1;
5737   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5738            sizeof (mp->name_filter) - 1);
5739   S (mp);
5740
5741   /* and GRE tunnel interfaces */
5742   M (SW_INTERFACE_DUMP, mp);
5743   mp->name_filter_valid = 1;
5744   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5745   S (mp);
5746
5747   /* and LISP-GPE interfaces */
5748   M (SW_INTERFACE_DUMP, mp);
5749   mp->name_filter_valid = 1;
5750   strncpy ((char *) mp->name_filter, "lisp_gpe",
5751            sizeof (mp->name_filter) - 1);
5752   S (mp);
5753
5754   /* and IPSEC tunnel interfaces */
5755   M (SW_INTERFACE_DUMP, mp);
5756   mp->name_filter_valid = 1;
5757   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5758   S (mp);
5759
5760   /* Use a control ping for synchronization */
5761   M (CONTROL_PING, mp_ping);
5762   S (mp_ping);
5763
5764   W (ret);
5765   return ret;
5766 }
5767
5768 static int
5769 api_sw_interface_set_flags (vat_main_t * vam)
5770 {
5771   unformat_input_t *i = vam->input;
5772   vl_api_sw_interface_set_flags_t *mp;
5773   u32 sw_if_index;
5774   u8 sw_if_index_set = 0;
5775   u8 admin_up = 0;
5776   int ret;
5777
5778   /* Parse args required to build the message */
5779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780     {
5781       if (unformat (i, "admin-up"))
5782         admin_up = 1;
5783       else if (unformat (i, "admin-down"))
5784         admin_up = 0;
5785       else
5786         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5787         sw_if_index_set = 1;
5788       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5789         sw_if_index_set = 1;
5790       else
5791         break;
5792     }
5793
5794   if (sw_if_index_set == 0)
5795     {
5796       errmsg ("missing interface name or sw_if_index");
5797       return -99;
5798     }
5799
5800   /* Construct the API message */
5801   M (SW_INTERFACE_SET_FLAGS, mp);
5802   mp->sw_if_index = ntohl (sw_if_index);
5803   mp->admin_up_down = admin_up;
5804
5805   /* send it... */
5806   S (mp);
5807
5808   /* Wait for a reply, return the good/bad news... */
5809   W (ret);
5810   return ret;
5811 }
5812
5813 static int
5814 api_sw_interface_clear_stats (vat_main_t * vam)
5815 {
5816   unformat_input_t *i = vam->input;
5817   vl_api_sw_interface_clear_stats_t *mp;
5818   u32 sw_if_index;
5819   u8 sw_if_index_set = 0;
5820   int ret;
5821
5822   /* Parse args required to build the message */
5823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5824     {
5825       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5826         sw_if_index_set = 1;
5827       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5828         sw_if_index_set = 1;
5829       else
5830         break;
5831     }
5832
5833   /* Construct the API message */
5834   M (SW_INTERFACE_CLEAR_STATS, mp);
5835
5836   if (sw_if_index_set == 1)
5837     mp->sw_if_index = ntohl (sw_if_index);
5838   else
5839     mp->sw_if_index = ~0;
5840
5841   /* send it... */
5842   S (mp);
5843
5844   /* Wait for a reply, return the good/bad news... */
5845   W (ret);
5846   return ret;
5847 }
5848
5849 static int
5850 api_sw_interface_add_del_address (vat_main_t * vam)
5851 {
5852   unformat_input_t *i = vam->input;
5853   vl_api_sw_interface_add_del_address_t *mp;
5854   u32 sw_if_index;
5855   u8 sw_if_index_set = 0;
5856   u8 is_add = 1, del_all = 0;
5857   u32 address_length = 0;
5858   u8 v4_address_set = 0;
5859   u8 v6_address_set = 0;
5860   ip4_address_t v4address;
5861   ip6_address_t v6address;
5862   int ret;
5863
5864   /* Parse args required to build the message */
5865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5866     {
5867       if (unformat (i, "del-all"))
5868         del_all = 1;
5869       else if (unformat (i, "del"))
5870         is_add = 0;
5871       else
5872         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5873         sw_if_index_set = 1;
5874       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5875         sw_if_index_set = 1;
5876       else if (unformat (i, "%U/%d",
5877                          unformat_ip4_address, &v4address, &address_length))
5878         v4_address_set = 1;
5879       else if (unformat (i, "%U/%d",
5880                          unformat_ip6_address, &v6address, &address_length))
5881         v6_address_set = 1;
5882       else
5883         break;
5884     }
5885
5886   if (sw_if_index_set == 0)
5887     {
5888       errmsg ("missing interface name or sw_if_index");
5889       return -99;
5890     }
5891   if (v4_address_set && v6_address_set)
5892     {
5893       errmsg ("both v4 and v6 addresses set");
5894       return -99;
5895     }
5896   if (!v4_address_set && !v6_address_set && !del_all)
5897     {
5898       errmsg ("no addresses set");
5899       return -99;
5900     }
5901
5902   /* Construct the API message */
5903   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5904
5905   mp->sw_if_index = ntohl (sw_if_index);
5906   mp->is_add = is_add;
5907   mp->del_all = del_all;
5908   if (v6_address_set)
5909     {
5910       mp->is_ipv6 = 1;
5911       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5912     }
5913   else
5914     {
5915       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5916     }
5917   mp->address_length = address_length;
5918
5919   /* send it... */
5920   S (mp);
5921
5922   /* Wait for a reply, return good/bad news  */
5923   W (ret);
5924   return ret;
5925 }
5926
5927 static int
5928 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5929 {
5930   unformat_input_t *i = vam->input;
5931   vl_api_sw_interface_set_mpls_enable_t *mp;
5932   u32 sw_if_index;
5933   u8 sw_if_index_set = 0;
5934   u8 enable = 1;
5935   int ret;
5936
5937   /* Parse args required to build the message */
5938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5939     {
5940       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5941         sw_if_index_set = 1;
5942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5943         sw_if_index_set = 1;
5944       else if (unformat (i, "disable"))
5945         enable = 0;
5946       else if (unformat (i, "dis"))
5947         enable = 0;
5948       else
5949         break;
5950     }
5951
5952   if (sw_if_index_set == 0)
5953     {
5954       errmsg ("missing interface name or sw_if_index");
5955       return -99;
5956     }
5957
5958   /* Construct the API message */
5959   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5960
5961   mp->sw_if_index = ntohl (sw_if_index);
5962   mp->enable = enable;
5963
5964   /* send it... */
5965   S (mp);
5966
5967   /* Wait for a reply... */
5968   W (ret);
5969   return ret;
5970 }
5971
5972 static int
5973 api_sw_interface_set_table (vat_main_t * vam)
5974 {
5975   unformat_input_t *i = vam->input;
5976   vl_api_sw_interface_set_table_t *mp;
5977   u32 sw_if_index, vrf_id = 0;
5978   u8 sw_if_index_set = 0;
5979   u8 is_ipv6 = 0;
5980   int ret;
5981
5982   /* Parse args required to build the message */
5983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5984     {
5985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5986         sw_if_index_set = 1;
5987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5988         sw_if_index_set = 1;
5989       else if (unformat (i, "vrf %d", &vrf_id))
5990         ;
5991       else if (unformat (i, "ipv6"))
5992         is_ipv6 = 1;
5993       else
5994         break;
5995     }
5996
5997   if (sw_if_index_set == 0)
5998     {
5999       errmsg ("missing interface name or sw_if_index");
6000       return -99;
6001     }
6002
6003   /* Construct the API message */
6004   M (SW_INTERFACE_SET_TABLE, mp);
6005
6006   mp->sw_if_index = ntohl (sw_if_index);
6007   mp->is_ipv6 = is_ipv6;
6008   mp->vrf_id = ntohl (vrf_id);
6009
6010   /* send it... */
6011   S (mp);
6012
6013   /* Wait for a reply... */
6014   W (ret);
6015   return ret;
6016 }
6017
6018 static void vl_api_sw_interface_get_table_reply_t_handler
6019   (vl_api_sw_interface_get_table_reply_t * mp)
6020 {
6021   vat_main_t *vam = &vat_main;
6022
6023   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6024
6025   vam->retval = ntohl (mp->retval);
6026   vam->result_ready = 1;
6027
6028 }
6029
6030 static void vl_api_sw_interface_get_table_reply_t_handler_json
6031   (vl_api_sw_interface_get_table_reply_t * mp)
6032 {
6033   vat_main_t *vam = &vat_main;
6034   vat_json_node_t node;
6035
6036   vat_json_init_object (&node);
6037   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6038   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6039
6040   vat_json_print (vam->ofp, &node);
6041   vat_json_free (&node);
6042
6043   vam->retval = ntohl (mp->retval);
6044   vam->result_ready = 1;
6045 }
6046
6047 static int
6048 api_sw_interface_get_table (vat_main_t * vam)
6049 {
6050   unformat_input_t *i = vam->input;
6051   vl_api_sw_interface_get_table_t *mp;
6052   u32 sw_if_index;
6053   u8 sw_if_index_set = 0;
6054   u8 is_ipv6 = 0;
6055   int ret;
6056
6057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6058     {
6059       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6060         sw_if_index_set = 1;
6061       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6062         sw_if_index_set = 1;
6063       else if (unformat (i, "ipv6"))
6064         is_ipv6 = 1;
6065       else
6066         break;
6067     }
6068
6069   if (sw_if_index_set == 0)
6070     {
6071       errmsg ("missing interface name or sw_if_index");
6072       return -99;
6073     }
6074
6075   M (SW_INTERFACE_GET_TABLE, mp);
6076   mp->sw_if_index = htonl (sw_if_index);
6077   mp->is_ipv6 = is_ipv6;
6078
6079   S (mp);
6080   W (ret);
6081   return ret;
6082 }
6083
6084 static int
6085 api_sw_interface_set_vpath (vat_main_t * vam)
6086 {
6087   unformat_input_t *i = vam->input;
6088   vl_api_sw_interface_set_vpath_t *mp;
6089   u32 sw_if_index = 0;
6090   u8 sw_if_index_set = 0;
6091   u8 is_enable = 0;
6092   int ret;
6093
6094   /* Parse args required to build the message */
6095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6096     {
6097       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6098         sw_if_index_set = 1;
6099       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6100         sw_if_index_set = 1;
6101       else if (unformat (i, "enable"))
6102         is_enable = 1;
6103       else if (unformat (i, "disable"))
6104         is_enable = 0;
6105       else
6106         break;
6107     }
6108
6109   if (sw_if_index_set == 0)
6110     {
6111       errmsg ("missing interface name or sw_if_index");
6112       return -99;
6113     }
6114
6115   /* Construct the API message */
6116   M (SW_INTERFACE_SET_VPATH, mp);
6117
6118   mp->sw_if_index = ntohl (sw_if_index);
6119   mp->enable = is_enable;
6120
6121   /* send it... */
6122   S (mp);
6123
6124   /* Wait for a reply... */
6125   W (ret);
6126   return ret;
6127 }
6128
6129 static int
6130 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6131 {
6132   unformat_input_t *i = vam->input;
6133   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6134   u32 sw_if_index = 0;
6135   u8 sw_if_index_set = 0;
6136   u8 is_enable = 1;
6137   u8 is_ipv6 = 0;
6138   int ret;
6139
6140   /* Parse args required to build the message */
6141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6142     {
6143       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6144         sw_if_index_set = 1;
6145       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6146         sw_if_index_set = 1;
6147       else if (unformat (i, "enable"))
6148         is_enable = 1;
6149       else if (unformat (i, "disable"))
6150         is_enable = 0;
6151       else if (unformat (i, "ip4"))
6152         is_ipv6 = 0;
6153       else if (unformat (i, "ip6"))
6154         is_ipv6 = 1;
6155       else
6156         break;
6157     }
6158
6159   if (sw_if_index_set == 0)
6160     {
6161       errmsg ("missing interface name or sw_if_index");
6162       return -99;
6163     }
6164
6165   /* Construct the API message */
6166   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6167
6168   mp->sw_if_index = ntohl (sw_if_index);
6169   mp->enable = is_enable;
6170   mp->is_ipv6 = is_ipv6;
6171
6172   /* send it... */
6173   S (mp);
6174
6175   /* Wait for a reply... */
6176   W (ret);
6177   return ret;
6178 }
6179
6180
6181 static int
6182 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6183 {
6184   unformat_input_t *i = vam->input;
6185   vl_api_sw_interface_set_l2_xconnect_t *mp;
6186   u32 rx_sw_if_index;
6187   u8 rx_sw_if_index_set = 0;
6188   u32 tx_sw_if_index;
6189   u8 tx_sw_if_index_set = 0;
6190   u8 enable = 1;
6191   int ret;
6192
6193   /* Parse args required to build the message */
6194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6195     {
6196       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6197         rx_sw_if_index_set = 1;
6198       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6199         tx_sw_if_index_set = 1;
6200       else if (unformat (i, "rx"))
6201         {
6202           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6203             {
6204               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6205                             &rx_sw_if_index))
6206                 rx_sw_if_index_set = 1;
6207             }
6208           else
6209             break;
6210         }
6211       else if (unformat (i, "tx"))
6212         {
6213           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6214             {
6215               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6216                             &tx_sw_if_index))
6217                 tx_sw_if_index_set = 1;
6218             }
6219           else
6220             break;
6221         }
6222       else if (unformat (i, "enable"))
6223         enable = 1;
6224       else if (unformat (i, "disable"))
6225         enable = 0;
6226       else
6227         break;
6228     }
6229
6230   if (rx_sw_if_index_set == 0)
6231     {
6232       errmsg ("missing rx interface name or rx_sw_if_index");
6233       return -99;
6234     }
6235
6236   if (enable && (tx_sw_if_index_set == 0))
6237     {
6238       errmsg ("missing tx interface name or tx_sw_if_index");
6239       return -99;
6240     }
6241
6242   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6243
6244   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6245   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6246   mp->enable = enable;
6247
6248   S (mp);
6249   W (ret);
6250   return ret;
6251 }
6252
6253 static int
6254 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6255 {
6256   unformat_input_t *i = vam->input;
6257   vl_api_sw_interface_set_l2_bridge_t *mp;
6258   u32 rx_sw_if_index;
6259   u8 rx_sw_if_index_set = 0;
6260   u32 bd_id;
6261   u8 bd_id_set = 0;
6262   u8 bvi = 0;
6263   u32 shg = 0;
6264   u8 enable = 1;
6265   int ret;
6266
6267   /* Parse args required to build the message */
6268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6269     {
6270       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6271         rx_sw_if_index_set = 1;
6272       else if (unformat (i, "bd_id %d", &bd_id))
6273         bd_id_set = 1;
6274       else
6275         if (unformat
6276             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6277         rx_sw_if_index_set = 1;
6278       else if (unformat (i, "shg %d", &shg))
6279         ;
6280       else if (unformat (i, "bvi"))
6281         bvi = 1;
6282       else if (unformat (i, "enable"))
6283         enable = 1;
6284       else if (unformat (i, "disable"))
6285         enable = 0;
6286       else
6287         break;
6288     }
6289
6290   if (rx_sw_if_index_set == 0)
6291     {
6292       errmsg ("missing rx interface name or sw_if_index");
6293       return -99;
6294     }
6295
6296   if (enable && (bd_id_set == 0))
6297     {
6298       errmsg ("missing bridge domain");
6299       return -99;
6300     }
6301
6302   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6303
6304   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6305   mp->bd_id = ntohl (bd_id);
6306   mp->shg = (u8) shg;
6307   mp->bvi = bvi;
6308   mp->enable = enable;
6309
6310   S (mp);
6311   W (ret);
6312   return ret;
6313 }
6314
6315 static int
6316 api_bridge_domain_dump (vat_main_t * vam)
6317 {
6318   unformat_input_t *i = vam->input;
6319   vl_api_bridge_domain_dump_t *mp;
6320   vl_api_control_ping_t *mp_ping;
6321   u32 bd_id = ~0;
6322   int ret;
6323
6324   /* Parse args required to build the message */
6325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6326     {
6327       if (unformat (i, "bd_id %d", &bd_id))
6328         ;
6329       else
6330         break;
6331     }
6332
6333   M (BRIDGE_DOMAIN_DUMP, mp);
6334   mp->bd_id = ntohl (bd_id);
6335   S (mp);
6336
6337   /* Use a control ping for synchronization */
6338   M (CONTROL_PING, mp_ping);
6339   S (mp_ping);
6340
6341   W (ret);
6342   return ret;
6343 }
6344
6345 static int
6346 api_bridge_domain_add_del (vat_main_t * vam)
6347 {
6348   unformat_input_t *i = vam->input;
6349   vl_api_bridge_domain_add_del_t *mp;
6350   u32 bd_id = ~0;
6351   u8 is_add = 1;
6352   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6353   u32 mac_age = 0;
6354   int ret;
6355
6356   /* Parse args required to build the message */
6357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6358     {
6359       if (unformat (i, "bd_id %d", &bd_id))
6360         ;
6361       else if (unformat (i, "flood %d", &flood))
6362         ;
6363       else if (unformat (i, "uu-flood %d", &uu_flood))
6364         ;
6365       else if (unformat (i, "forward %d", &forward))
6366         ;
6367       else if (unformat (i, "learn %d", &learn))
6368         ;
6369       else if (unformat (i, "arp-term %d", &arp_term))
6370         ;
6371       else if (unformat (i, "mac-age %d", &mac_age))
6372         ;
6373       else if (unformat (i, "del"))
6374         {
6375           is_add = 0;
6376           flood = uu_flood = forward = learn = 0;
6377         }
6378       else
6379         break;
6380     }
6381
6382   if (bd_id == ~0)
6383     {
6384       errmsg ("missing bridge domain");
6385       return -99;
6386     }
6387
6388   if (mac_age > 255)
6389     {
6390       errmsg ("mac age must be less than 256 ");
6391       return -99;
6392     }
6393
6394   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6395
6396   mp->bd_id = ntohl (bd_id);
6397   mp->flood = flood;
6398   mp->uu_flood = uu_flood;
6399   mp->forward = forward;
6400   mp->learn = learn;
6401   mp->arp_term = arp_term;
6402   mp->is_add = is_add;
6403   mp->mac_age = (u8) mac_age;
6404
6405   S (mp);
6406   W (ret);
6407   return ret;
6408 }
6409
6410 static int
6411 api_l2fib_flush_bd (vat_main_t * vam)
6412 {
6413   unformat_input_t *i = vam->input;
6414   vl_api_l2fib_flush_bd_t *mp;
6415   u32 bd_id = ~0;
6416   int ret;
6417
6418   /* Parse args required to build the message */
6419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6420     {
6421       if (unformat (i, "bd_id %d", &bd_id));
6422       else
6423         break;
6424     }
6425
6426   if (bd_id == ~0)
6427     {
6428       errmsg ("missing bridge domain");
6429       return -99;
6430     }
6431
6432   M (L2FIB_FLUSH_BD, mp);
6433
6434   mp->bd_id = htonl (bd_id);
6435
6436   S (mp);
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_l2fib_flush_int (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_l2fib_flush_int_t *mp;
6446   u32 sw_if_index = ~0;
6447   int ret;
6448
6449   /* Parse args required to build the message */
6450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6451     {
6452       if (unformat (i, "sw_if_index %d", &sw_if_index));
6453       else
6454         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6455       else
6456         break;
6457     }
6458
6459   if (sw_if_index == ~0)
6460     {
6461       errmsg ("missing interface name or sw_if_index");
6462       return -99;
6463     }
6464
6465   M (L2FIB_FLUSH_INT, mp);
6466
6467   mp->sw_if_index = ntohl (sw_if_index);
6468
6469   S (mp);
6470   W (ret);
6471   return ret;
6472 }
6473
6474 static int
6475 api_l2fib_add_del (vat_main_t * vam)
6476 {
6477   unformat_input_t *i = vam->input;
6478   vl_api_l2fib_add_del_t *mp;
6479   f64 timeout;
6480   u64 mac = 0;
6481   u8 mac_set = 0;
6482   u32 bd_id;
6483   u8 bd_id_set = 0;
6484   u32 sw_if_index = ~0;
6485   u8 sw_if_index_set = 0;
6486   u8 is_add = 1;
6487   u8 static_mac = 0;
6488   u8 filter_mac = 0;
6489   u8 bvi_mac = 0;
6490   int count = 1;
6491   f64 before = 0;
6492   int j;
6493
6494   /* Parse args required to build the message */
6495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6496     {
6497       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6498         mac_set = 1;
6499       else if (unformat (i, "bd_id %d", &bd_id))
6500         bd_id_set = 1;
6501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6502         sw_if_index_set = 1;
6503       else if (unformat (i, "sw_if"))
6504         {
6505           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6506             {
6507               if (unformat
6508                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6509                 sw_if_index_set = 1;
6510             }
6511           else
6512             break;
6513         }
6514       else if (unformat (i, "static"))
6515         static_mac = 1;
6516       else if (unformat (i, "filter"))
6517         {
6518           filter_mac = 1;
6519           static_mac = 1;
6520         }
6521       else if (unformat (i, "bvi"))
6522         {
6523           bvi_mac = 1;
6524           static_mac = 1;
6525         }
6526       else if (unformat (i, "del"))
6527         is_add = 0;
6528       else if (unformat (i, "count %d", &count))
6529         ;
6530       else
6531         break;
6532     }
6533
6534   if (mac_set == 0)
6535     {
6536       errmsg ("missing mac address");
6537       return -99;
6538     }
6539
6540   if (bd_id_set == 0)
6541     {
6542       errmsg ("missing bridge domain");
6543       return -99;
6544     }
6545
6546   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6547     {
6548       errmsg ("missing interface name or sw_if_index");
6549       return -99;
6550     }
6551
6552   if (count > 1)
6553     {
6554       /* Turn on async mode */
6555       vam->async_mode = 1;
6556       vam->async_errors = 0;
6557       before = vat_time_now (vam);
6558     }
6559
6560   for (j = 0; j < count; j++)
6561     {
6562       M (L2FIB_ADD_DEL, mp);
6563
6564       mp->mac = mac;
6565       mp->bd_id = ntohl (bd_id);
6566       mp->is_add = is_add;
6567
6568       if (is_add)
6569         {
6570           mp->sw_if_index = ntohl (sw_if_index);
6571           mp->static_mac = static_mac;
6572           mp->filter_mac = filter_mac;
6573           mp->bvi_mac = bvi_mac;
6574         }
6575       increment_mac_address (&mac);
6576       /* send it... */
6577       S (mp);
6578     }
6579
6580   if (count > 1)
6581     {
6582       vl_api_control_ping_t *mp_ping;
6583       f64 after;
6584
6585       /* Shut off async mode */
6586       vam->async_mode = 0;
6587
6588       M (CONTROL_PING, mp_ping);
6589       S (mp_ping);
6590
6591       timeout = vat_time_now (vam) + 1.0;
6592       while (vat_time_now (vam) < timeout)
6593         if (vam->result_ready == 1)
6594           goto out;
6595       vam->retval = -99;
6596
6597     out:
6598       if (vam->retval == -99)
6599         errmsg ("timeout");
6600
6601       if (vam->async_errors > 0)
6602         {
6603           errmsg ("%d asynchronous errors", vam->async_errors);
6604           vam->retval = -98;
6605         }
6606       vam->async_errors = 0;
6607       after = vat_time_now (vam);
6608
6609       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6610              count, after - before, count / (after - before));
6611     }
6612   else
6613     {
6614       int ret;
6615
6616       /* Wait for a reply... */
6617       W (ret);
6618       return ret;
6619     }
6620   /* Return the good/bad news */
6621   return (vam->retval);
6622 }
6623
6624 static int
6625 api_bridge_domain_set_mac_age (vat_main_t * vam)
6626 {
6627   unformat_input_t *i = vam->input;
6628   vl_api_bridge_domain_set_mac_age_t *mp;
6629   u32 bd_id = ~0;
6630   u32 mac_age = 0;
6631   int ret;
6632
6633   /* Parse args required to build the message */
6634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6635     {
6636       if (unformat (i, "bd_id %d", &bd_id));
6637       else if (unformat (i, "mac-age %d", &mac_age));
6638       else
6639         break;
6640     }
6641
6642   if (bd_id == ~0)
6643     {
6644       errmsg ("missing bridge domain");
6645       return -99;
6646     }
6647
6648   if (mac_age > 255)
6649     {
6650       errmsg ("mac age must be less than 256 ");
6651       return -99;
6652     }
6653
6654   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6655
6656   mp->bd_id = htonl (bd_id);
6657   mp->mac_age = (u8) mac_age;
6658
6659   S (mp);
6660   W (ret);
6661   return ret;
6662 }
6663
6664 static int
6665 api_l2_flags (vat_main_t * vam)
6666 {
6667   unformat_input_t *i = vam->input;
6668   vl_api_l2_flags_t *mp;
6669   u32 sw_if_index;
6670   u32 flags = 0;
6671   u8 sw_if_index_set = 0;
6672   u8 is_set = 0;
6673   int ret;
6674
6675   /* Parse args required to build the message */
6676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6677     {
6678       if (unformat (i, "sw_if_index %d", &sw_if_index))
6679         sw_if_index_set = 1;
6680       else if (unformat (i, "sw_if"))
6681         {
6682           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6683             {
6684               if (unformat
6685                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6686                 sw_if_index_set = 1;
6687             }
6688           else
6689             break;
6690         }
6691       else if (unformat (i, "learn"))
6692         flags |= L2_LEARN;
6693       else if (unformat (i, "forward"))
6694         flags |= L2_FWD;
6695       else if (unformat (i, "flood"))
6696         flags |= L2_FLOOD;
6697       else if (unformat (i, "uu-flood"))
6698         flags |= L2_UU_FLOOD;
6699       else if (unformat (i, "arp-term"))
6700         flags |= L2_ARP_TERM;
6701       else if (unformat (i, "off"))
6702         is_set = 0;
6703       else if (unformat (i, "disable"))
6704         is_set = 0;
6705       else
6706         break;
6707     }
6708
6709   if (sw_if_index_set == 0)
6710     {
6711       errmsg ("missing interface name or sw_if_index");
6712       return -99;
6713     }
6714
6715   M (L2_FLAGS, mp);
6716
6717   mp->sw_if_index = ntohl (sw_if_index);
6718   mp->feature_bitmap = ntohl (flags);
6719   mp->is_set = is_set;
6720
6721   S (mp);
6722   W (ret);
6723   return ret;
6724 }
6725
6726 static int
6727 api_bridge_flags (vat_main_t * vam)
6728 {
6729   unformat_input_t *i = vam->input;
6730   vl_api_bridge_flags_t *mp;
6731   u32 bd_id;
6732   u8 bd_id_set = 0;
6733   u8 is_set = 1;
6734   u32 flags = 0;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "bd_id %d", &bd_id))
6741         bd_id_set = 1;
6742       else if (unformat (i, "learn"))
6743         flags |= L2_LEARN;
6744       else if (unformat (i, "forward"))
6745         flags |= L2_FWD;
6746       else if (unformat (i, "flood"))
6747         flags |= L2_FLOOD;
6748       else if (unformat (i, "uu-flood"))
6749         flags |= L2_UU_FLOOD;
6750       else if (unformat (i, "arp-term"))
6751         flags |= L2_ARP_TERM;
6752       else if (unformat (i, "off"))
6753         is_set = 0;
6754       else if (unformat (i, "disable"))
6755         is_set = 0;
6756       else
6757         break;
6758     }
6759
6760   if (bd_id_set == 0)
6761     {
6762       errmsg ("missing bridge domain");
6763       return -99;
6764     }
6765
6766   M (BRIDGE_FLAGS, mp);
6767
6768   mp->bd_id = ntohl (bd_id);
6769   mp->feature_bitmap = ntohl (flags);
6770   mp->is_set = is_set;
6771
6772   S (mp);
6773   W (ret);
6774   return ret;
6775 }
6776
6777 static int
6778 api_bd_ip_mac_add_del (vat_main_t * vam)
6779 {
6780   unformat_input_t *i = vam->input;
6781   vl_api_bd_ip_mac_add_del_t *mp;
6782   u32 bd_id;
6783   u8 is_ipv6 = 0;
6784   u8 is_add = 1;
6785   u8 bd_id_set = 0;
6786   u8 ip_set = 0;
6787   u8 mac_set = 0;
6788   ip4_address_t v4addr;
6789   ip6_address_t v6addr;
6790   u8 macaddr[6];
6791   int ret;
6792
6793
6794   /* Parse args required to build the message */
6795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6796     {
6797       if (unformat (i, "bd_id %d", &bd_id))
6798         {
6799           bd_id_set++;
6800         }
6801       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6802         {
6803           ip_set++;
6804         }
6805       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6806         {
6807           ip_set++;
6808           is_ipv6++;
6809         }
6810       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6811         {
6812           mac_set++;
6813         }
6814       else if (unformat (i, "del"))
6815         is_add = 0;
6816       else
6817         break;
6818     }
6819
6820   if (bd_id_set == 0)
6821     {
6822       errmsg ("missing bridge domain");
6823       return -99;
6824     }
6825   else if (ip_set == 0)
6826     {
6827       errmsg ("missing IP address");
6828       return -99;
6829     }
6830   else if (mac_set == 0)
6831     {
6832       errmsg ("missing MAC address");
6833       return -99;
6834     }
6835
6836   M (BD_IP_MAC_ADD_DEL, mp);
6837
6838   mp->bd_id = ntohl (bd_id);
6839   mp->is_ipv6 = is_ipv6;
6840   mp->is_add = is_add;
6841   if (is_ipv6)
6842     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6843   else
6844     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6845   clib_memcpy (mp->mac_address, macaddr, 6);
6846   S (mp);
6847   W (ret);
6848   return ret;
6849 }
6850
6851 static int
6852 api_tap_connect (vat_main_t * vam)
6853 {
6854   unformat_input_t *i = vam->input;
6855   vl_api_tap_connect_t *mp;
6856   u8 mac_address[6];
6857   u8 random_mac = 1;
6858   u8 name_set = 0;
6859   u8 *tap_name;
6860   u8 *tag = 0;
6861   ip4_address_t ip4_address;
6862   u32 ip4_mask_width;
6863   int ip4_address_set = 0;
6864   ip6_address_t ip6_address;
6865   u32 ip6_mask_width;
6866   int ip6_address_set = 0;
6867   int ret;
6868
6869   memset (mac_address, 0, sizeof (mac_address));
6870
6871   /* Parse args required to build the message */
6872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6873     {
6874       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6875         {
6876           random_mac = 0;
6877         }
6878       else if (unformat (i, "random-mac"))
6879         random_mac = 1;
6880       else if (unformat (i, "tapname %s", &tap_name))
6881         name_set = 1;
6882       else if (unformat (i, "tag %s", &tag))
6883         ;
6884       else if (unformat (i, "address %U/%d",
6885                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6886         ip4_address_set = 1;
6887       else if (unformat (i, "address %U/%d",
6888                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6889         ip6_address_set = 1;
6890       else
6891         break;
6892     }
6893
6894   if (name_set == 0)
6895     {
6896       errmsg ("missing tap name");
6897       return -99;
6898     }
6899   if (vec_len (tap_name) > 63)
6900     {
6901       errmsg ("tap name too long");
6902       return -99;
6903     }
6904   vec_add1 (tap_name, 0);
6905
6906   if (vec_len (tag) > 63)
6907     {
6908       errmsg ("tag too long");
6909       return -99;
6910     }
6911
6912   /* Construct the API message */
6913   M (TAP_CONNECT, mp);
6914
6915   mp->use_random_mac = random_mac;
6916   clib_memcpy (mp->mac_address, mac_address, 6);
6917   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6918   if (tag)
6919     clib_memcpy (mp->tag, tag, vec_len (tag));
6920
6921   if (ip4_address_set)
6922     {
6923       mp->ip4_address_set = 1;
6924       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6925       mp->ip4_mask_width = ip4_mask_width;
6926     }
6927   if (ip6_address_set)
6928     {
6929       mp->ip6_address_set = 1;
6930       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6931       mp->ip6_mask_width = ip6_mask_width;
6932     }
6933
6934   vec_free (tap_name);
6935   vec_free (tag);
6936
6937   /* send it... */
6938   S (mp);
6939
6940   /* Wait for a reply... */
6941   W (ret);
6942   return ret;
6943 }
6944
6945 static int
6946 api_tap_modify (vat_main_t * vam)
6947 {
6948   unformat_input_t *i = vam->input;
6949   vl_api_tap_modify_t *mp;
6950   u8 mac_address[6];
6951   u8 random_mac = 1;
6952   u8 name_set = 0;
6953   u8 *tap_name;
6954   u32 sw_if_index = ~0;
6955   u8 sw_if_index_set = 0;
6956   int ret;
6957
6958   memset (mac_address, 0, sizeof (mac_address));
6959
6960   /* Parse args required to build the message */
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6964         sw_if_index_set = 1;
6965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6966         sw_if_index_set = 1;
6967       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6968         {
6969           random_mac = 0;
6970         }
6971       else if (unformat (i, "random-mac"))
6972         random_mac = 1;
6973       else if (unformat (i, "tapname %s", &tap_name))
6974         name_set = 1;
6975       else
6976         break;
6977     }
6978
6979   if (sw_if_index_set == 0)
6980     {
6981       errmsg ("missing vpp interface name");
6982       return -99;
6983     }
6984   if (name_set == 0)
6985     {
6986       errmsg ("missing tap name");
6987       return -99;
6988     }
6989   if (vec_len (tap_name) > 63)
6990     {
6991       errmsg ("tap name too long");
6992     }
6993   vec_add1 (tap_name, 0);
6994
6995   /* Construct the API message */
6996   M (TAP_MODIFY, mp);
6997
6998   mp->use_random_mac = random_mac;
6999   mp->sw_if_index = ntohl (sw_if_index);
7000   clib_memcpy (mp->mac_address, mac_address, 6);
7001   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7002   vec_free (tap_name);
7003
7004   /* send it... */
7005   S (mp);
7006
7007   /* Wait for a reply... */
7008   W (ret);
7009   return ret;
7010 }
7011
7012 static int
7013 api_tap_delete (vat_main_t * vam)
7014 {
7015   unformat_input_t *i = vam->input;
7016   vl_api_tap_delete_t *mp;
7017   u32 sw_if_index = ~0;
7018   u8 sw_if_index_set = 0;
7019   int ret;
7020
7021   /* Parse args required to build the message */
7022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023     {
7024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7025         sw_if_index_set = 1;
7026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7027         sw_if_index_set = 1;
7028       else
7029         break;
7030     }
7031
7032   if (sw_if_index_set == 0)
7033     {
7034       errmsg ("missing vpp interface name");
7035       return -99;
7036     }
7037
7038   /* Construct the API message */
7039   M (TAP_DELETE, mp);
7040
7041   mp->sw_if_index = ntohl (sw_if_index);
7042
7043   /* send it... */
7044   S (mp);
7045
7046   /* Wait for a reply... */
7047   W (ret);
7048   return ret;
7049 }
7050
7051 static int
7052 api_ip_add_del_route (vat_main_t * vam)
7053 {
7054   unformat_input_t *i = vam->input;
7055   vl_api_ip_add_del_route_t *mp;
7056   u32 sw_if_index = ~0, vrf_id = 0;
7057   u8 is_ipv6 = 0;
7058   u8 is_local = 0, is_drop = 0;
7059   u8 is_unreach = 0, is_prohibit = 0;
7060   u8 create_vrf_if_needed = 0;
7061   u8 is_add = 1;
7062   u32 next_hop_weight = 1;
7063   u8 not_last = 0;
7064   u8 is_multipath = 0;
7065   u8 address_set = 0;
7066   u8 address_length_set = 0;
7067   u32 next_hop_table_id = 0;
7068   u32 resolve_attempts = 0;
7069   u32 dst_address_length = 0;
7070   u8 next_hop_set = 0;
7071   ip4_address_t v4_dst_address, v4_next_hop_address;
7072   ip6_address_t v6_dst_address, v6_next_hop_address;
7073   int count = 1;
7074   int j;
7075   f64 before = 0;
7076   u32 random_add_del = 0;
7077   u32 *random_vector = 0;
7078   uword *random_hash;
7079   u32 random_seed = 0xdeaddabe;
7080   u32 classify_table_index = ~0;
7081   u8 is_classify = 0;
7082   u8 resolve_host = 0, resolve_attached = 0;
7083   mpls_label_t *next_hop_out_label_stack = NULL;
7084   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7085   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7086
7087   /* Parse args required to build the message */
7088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7089     {
7090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7091         ;
7092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7093         ;
7094       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7095         {
7096           address_set = 1;
7097           is_ipv6 = 0;
7098         }
7099       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7100         {
7101           address_set = 1;
7102           is_ipv6 = 1;
7103         }
7104       else if (unformat (i, "/%d", &dst_address_length))
7105         {
7106           address_length_set = 1;
7107         }
7108
7109       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7110                                          &v4_next_hop_address))
7111         {
7112           next_hop_set = 1;
7113         }
7114       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7115                                          &v6_next_hop_address))
7116         {
7117           next_hop_set = 1;
7118         }
7119       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7120         ;
7121       else if (unformat (i, "weight %d", &next_hop_weight))
7122         ;
7123       else if (unformat (i, "drop"))
7124         {
7125           is_drop = 1;
7126         }
7127       else if (unformat (i, "null-send-unreach"))
7128         {
7129           is_unreach = 1;
7130         }
7131       else if (unformat (i, "null-send-prohibit"))
7132         {
7133           is_prohibit = 1;
7134         }
7135       else if (unformat (i, "local"))
7136         {
7137           is_local = 1;
7138         }
7139       else if (unformat (i, "classify %d", &classify_table_index))
7140         {
7141           is_classify = 1;
7142         }
7143       else if (unformat (i, "del"))
7144         is_add = 0;
7145       else if (unformat (i, "add"))
7146         is_add = 1;
7147       else if (unformat (i, "not-last"))
7148         not_last = 1;
7149       else if (unformat (i, "resolve-via-host"))
7150         resolve_host = 1;
7151       else if (unformat (i, "resolve-via-attached"))
7152         resolve_attached = 1;
7153       else if (unformat (i, "multipath"))
7154         is_multipath = 1;
7155       else if (unformat (i, "vrf %d", &vrf_id))
7156         ;
7157       else if (unformat (i, "create-vrf"))
7158         create_vrf_if_needed = 1;
7159       else if (unformat (i, "count %d", &count))
7160         ;
7161       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7162         ;
7163       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7164         ;
7165       else if (unformat (i, "out-label %d", &next_hop_out_label))
7166         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7167       else if (unformat (i, "via-label %d", &next_hop_via_label))
7168         ;
7169       else if (unformat (i, "random"))
7170         random_add_del = 1;
7171       else if (unformat (i, "seed %d", &random_seed))
7172         ;
7173       else
7174         {
7175           clib_warning ("parse error '%U'", format_unformat_error, i);
7176           return -99;
7177         }
7178     }
7179
7180   if (!next_hop_set && !is_drop && !is_local &&
7181       !is_classify && !is_unreach && !is_prohibit &&
7182       MPLS_LABEL_INVALID == next_hop_via_label)
7183     {
7184       errmsg
7185         ("next hop / local / drop / unreach / prohibit / classify not set");
7186       return -99;
7187     }
7188
7189   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7190     {
7191       errmsg ("next hop and next-hop via label set");
7192       return -99;
7193     }
7194   if (address_set == 0)
7195     {
7196       errmsg ("missing addresses");
7197       return -99;
7198     }
7199
7200   if (address_length_set == 0)
7201     {
7202       errmsg ("missing address length");
7203       return -99;
7204     }
7205
7206   /* Generate a pile of unique, random routes */
7207   if (random_add_del)
7208     {
7209       u32 this_random_address;
7210       random_hash = hash_create (count, sizeof (uword));
7211
7212       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7213       for (j = 0; j <= count; j++)
7214         {
7215           do
7216             {
7217               this_random_address = random_u32 (&random_seed);
7218               this_random_address =
7219                 clib_host_to_net_u32 (this_random_address);
7220             }
7221           while (hash_get (random_hash, this_random_address));
7222           vec_add1 (random_vector, this_random_address);
7223           hash_set (random_hash, this_random_address, 1);
7224         }
7225       hash_free (random_hash);
7226       v4_dst_address.as_u32 = random_vector[0];
7227     }
7228
7229   if (count > 1)
7230     {
7231       /* Turn on async mode */
7232       vam->async_mode = 1;
7233       vam->async_errors = 0;
7234       before = vat_time_now (vam);
7235     }
7236
7237   for (j = 0; j < count; j++)
7238     {
7239       /* Construct the API message */
7240       M2 (IP_ADD_DEL_ROUTE, mp,
7241           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7242
7243       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7244       mp->table_id = ntohl (vrf_id);
7245       mp->create_vrf_if_needed = create_vrf_if_needed;
7246
7247       mp->is_add = is_add;
7248       mp->is_drop = is_drop;
7249       mp->is_unreach = is_unreach;
7250       mp->is_prohibit = is_prohibit;
7251       mp->is_ipv6 = is_ipv6;
7252       mp->is_local = is_local;
7253       mp->is_classify = is_classify;
7254       mp->is_multipath = is_multipath;
7255       mp->is_resolve_host = resolve_host;
7256       mp->is_resolve_attached = resolve_attached;
7257       mp->not_last = not_last;
7258       mp->next_hop_weight = next_hop_weight;
7259       mp->dst_address_length = dst_address_length;
7260       mp->next_hop_table_id = ntohl (next_hop_table_id);
7261       mp->classify_table_index = ntohl (classify_table_index);
7262       mp->next_hop_via_label = ntohl (next_hop_via_label);
7263       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7264       if (0 != mp->next_hop_n_out_labels)
7265         {
7266           memcpy (mp->next_hop_out_label_stack,
7267                   next_hop_out_label_stack,
7268                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7269           vec_free (next_hop_out_label_stack);
7270         }
7271
7272       if (is_ipv6)
7273         {
7274           clib_memcpy (mp->dst_address, &v6_dst_address,
7275                        sizeof (v6_dst_address));
7276           if (next_hop_set)
7277             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7278                          sizeof (v6_next_hop_address));
7279           increment_v6_address (&v6_dst_address);
7280         }
7281       else
7282         {
7283           clib_memcpy (mp->dst_address, &v4_dst_address,
7284                        sizeof (v4_dst_address));
7285           if (next_hop_set)
7286             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7287                          sizeof (v4_next_hop_address));
7288           if (random_add_del)
7289             v4_dst_address.as_u32 = random_vector[j + 1];
7290           else
7291             increment_v4_address (&v4_dst_address);
7292         }
7293       /* send it... */
7294       S (mp);
7295       /* If we receive SIGTERM, stop now... */
7296       if (vam->do_exit)
7297         break;
7298     }
7299
7300   /* When testing multiple add/del ops, use a control-ping to sync */
7301   if (count > 1)
7302     {
7303       vl_api_control_ping_t *mp_ping;
7304       f64 after;
7305       f64 timeout;
7306
7307       /* Shut off async mode */
7308       vam->async_mode = 0;
7309
7310       M (CONTROL_PING, mp_ping);
7311       S (mp_ping);
7312
7313       timeout = vat_time_now (vam) + 1.0;
7314       while (vat_time_now (vam) < timeout)
7315         if (vam->result_ready == 1)
7316           goto out;
7317       vam->retval = -99;
7318
7319     out:
7320       if (vam->retval == -99)
7321         errmsg ("timeout");
7322
7323       if (vam->async_errors > 0)
7324         {
7325           errmsg ("%d asynchronous errors", vam->async_errors);
7326           vam->retval = -98;
7327         }
7328       vam->async_errors = 0;
7329       after = vat_time_now (vam);
7330
7331       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7332       if (j > 0)
7333         count = j;
7334
7335       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7336              count, after - before, count / (after - before));
7337     }
7338   else
7339     {
7340       int ret;
7341
7342       /* Wait for a reply... */
7343       W (ret);
7344       return ret;
7345     }
7346
7347   /* Return the good/bad news */
7348   return (vam->retval);
7349 }
7350
7351 static int
7352 api_ip_mroute_add_del (vat_main_t * vam)
7353 {
7354   unformat_input_t *i = vam->input;
7355   vl_api_ip_mroute_add_del_t *mp;
7356   u32 sw_if_index = ~0, vrf_id = 0;
7357   u8 is_ipv6 = 0;
7358   u8 is_local = 0;
7359   u8 create_vrf_if_needed = 0;
7360   u8 is_add = 1;
7361   u8 address_set = 0;
7362   u32 grp_address_length = 0;
7363   ip4_address_t v4_grp_address, v4_src_address;
7364   ip6_address_t v6_grp_address, v6_src_address;
7365   mfib_itf_flags_t iflags = 0;
7366   mfib_entry_flags_t eflags = 0;
7367   int ret;
7368
7369   /* Parse args required to build the message */
7370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7371     {
7372       if (unformat (i, "sw_if_index %d", &sw_if_index))
7373         ;
7374       else if (unformat (i, "%U %U",
7375                          unformat_ip4_address, &v4_src_address,
7376                          unformat_ip4_address, &v4_grp_address))
7377         {
7378           grp_address_length = 64;
7379           address_set = 1;
7380           is_ipv6 = 0;
7381         }
7382       else if (unformat (i, "%U %U",
7383                          unformat_ip6_address, &v6_src_address,
7384                          unformat_ip6_address, &v6_grp_address))
7385         {
7386           grp_address_length = 256;
7387           address_set = 1;
7388           is_ipv6 = 1;
7389         }
7390       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7391         {
7392           memset (&v4_src_address, 0, sizeof (v4_src_address));
7393           grp_address_length = 32;
7394           address_set = 1;
7395           is_ipv6 = 0;
7396         }
7397       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7398         {
7399           memset (&v6_src_address, 0, sizeof (v6_src_address));
7400           grp_address_length = 128;
7401           address_set = 1;
7402           is_ipv6 = 1;
7403         }
7404       else if (unformat (i, "/%d", &grp_address_length))
7405         ;
7406       else if (unformat (i, "local"))
7407         {
7408           is_local = 1;
7409         }
7410       else if (unformat (i, "del"))
7411         is_add = 0;
7412       else if (unformat (i, "add"))
7413         is_add = 1;
7414       else if (unformat (i, "vrf %d", &vrf_id))
7415         ;
7416       else if (unformat (i, "create-vrf"))
7417         create_vrf_if_needed = 1;
7418       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7419         ;
7420       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7421         ;
7422       else
7423         {
7424           clib_warning ("parse error '%U'", format_unformat_error, i);
7425           return -99;
7426         }
7427     }
7428
7429   if (address_set == 0)
7430     {
7431       errmsg ("missing addresses\n");
7432       return -99;
7433     }
7434
7435   /* Construct the API message */
7436   M (IP_MROUTE_ADD_DEL, mp);
7437
7438   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7439   mp->table_id = ntohl (vrf_id);
7440   mp->create_vrf_if_needed = create_vrf_if_needed;
7441
7442   mp->is_add = is_add;
7443   mp->is_ipv6 = is_ipv6;
7444   mp->is_local = is_local;
7445   mp->itf_flags = ntohl (iflags);
7446   mp->entry_flags = ntohl (eflags);
7447   mp->grp_address_length = grp_address_length;
7448   mp->grp_address_length = ntohs (mp->grp_address_length);
7449
7450   if (is_ipv6)
7451     {
7452       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7453       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7454     }
7455   else
7456     {
7457       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7458       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7459
7460     }
7461
7462   /* send it... */
7463   S (mp);
7464   /* Wait for a reply... */
7465   W (ret);
7466   return ret;
7467 }
7468
7469 static int
7470 api_mpls_route_add_del (vat_main_t * vam)
7471 {
7472   unformat_input_t *i = vam->input;
7473   vl_api_mpls_route_add_del_t *mp;
7474   u32 sw_if_index = ~0, table_id = 0;
7475   u8 create_table_if_needed = 0;
7476   u8 is_add = 1;
7477   u32 next_hop_weight = 1;
7478   u8 is_multipath = 0;
7479   u32 next_hop_table_id = 0;
7480   u8 next_hop_set = 0;
7481   ip4_address_t v4_next_hop_address = {
7482     .as_u32 = 0,
7483   };
7484   ip6_address_t v6_next_hop_address = { {0} };
7485   int count = 1;
7486   int j;
7487   f64 before = 0;
7488   u32 classify_table_index = ~0;
7489   u8 is_classify = 0;
7490   u8 resolve_host = 0, resolve_attached = 0;
7491   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7492   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7493   mpls_label_t *next_hop_out_label_stack = NULL;
7494   mpls_label_t local_label = MPLS_LABEL_INVALID;
7495   u8 is_eos = 0;
7496   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
7497
7498   /* Parse args required to build the message */
7499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7500     {
7501       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7502         ;
7503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7504         ;
7505       else if (unformat (i, "%d", &local_label))
7506         ;
7507       else if (unformat (i, "eos"))
7508         is_eos = 1;
7509       else if (unformat (i, "non-eos"))
7510         is_eos = 0;
7511       else if (unformat (i, "via %U", unformat_ip4_address,
7512                          &v4_next_hop_address))
7513         {
7514           next_hop_set = 1;
7515           next_hop_proto = DPO_PROTO_IP4;
7516         }
7517       else if (unformat (i, "via %U", unformat_ip6_address,
7518                          &v6_next_hop_address))
7519         {
7520           next_hop_set = 1;
7521           next_hop_proto = DPO_PROTO_IP6;
7522         }
7523       else if (unformat (i, "weight %d", &next_hop_weight))
7524         ;
7525       else if (unformat (i, "create-table"))
7526         create_table_if_needed = 1;
7527       else if (unformat (i, "classify %d", &classify_table_index))
7528         {
7529           is_classify = 1;
7530         }
7531       else if (unformat (i, "del"))
7532         is_add = 0;
7533       else if (unformat (i, "add"))
7534         is_add = 1;
7535       else if (unformat (i, "resolve-via-host"))
7536         resolve_host = 1;
7537       else if (unformat (i, "resolve-via-attached"))
7538         resolve_attached = 1;
7539       else if (unformat (i, "multipath"))
7540         is_multipath = 1;
7541       else if (unformat (i, "count %d", &count))
7542         ;
7543       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7544         {
7545           next_hop_set = 1;
7546           next_hop_proto = DPO_PROTO_IP4;
7547         }
7548       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7549         {
7550           next_hop_set = 1;
7551           next_hop_proto = DPO_PROTO_IP6;
7552         }
7553       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7554         ;
7555       else if (unformat (i, "via-label %d", &next_hop_via_label))
7556         ;
7557       else if (unformat (i, "out-label %d", &next_hop_out_label))
7558         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7559       else
7560         {
7561           clib_warning ("parse error '%U'", format_unformat_error, i);
7562           return -99;
7563         }
7564     }
7565
7566   if (!next_hop_set && !is_classify)
7567     {
7568       errmsg ("next hop / classify not set");
7569       return -99;
7570     }
7571
7572   if (MPLS_LABEL_INVALID == local_label)
7573     {
7574       errmsg ("missing label");
7575       return -99;
7576     }
7577
7578   if (count > 1)
7579     {
7580       /* Turn on async mode */
7581       vam->async_mode = 1;
7582       vam->async_errors = 0;
7583       before = vat_time_now (vam);
7584     }
7585
7586   for (j = 0; j < count; j++)
7587     {
7588       /* Construct the API message */
7589       M2 (MPLS_ROUTE_ADD_DEL, mp,
7590           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7591
7592       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7593       mp->mr_table_id = ntohl (table_id);
7594       mp->mr_create_table_if_needed = create_table_if_needed;
7595
7596       mp->mr_is_add = is_add;
7597       mp->mr_next_hop_proto = next_hop_proto;
7598       mp->mr_is_classify = is_classify;
7599       mp->mr_is_multipath = is_multipath;
7600       mp->mr_is_resolve_host = resolve_host;
7601       mp->mr_is_resolve_attached = resolve_attached;
7602       mp->mr_next_hop_weight = next_hop_weight;
7603       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7604       mp->mr_classify_table_index = ntohl (classify_table_index);
7605       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7606       mp->mr_label = ntohl (local_label);
7607       mp->mr_eos = is_eos;
7608
7609       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7610       if (0 != mp->mr_next_hop_n_out_labels)
7611         {
7612           memcpy (mp->mr_next_hop_out_label_stack,
7613                   next_hop_out_label_stack,
7614                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7615           vec_free (next_hop_out_label_stack);
7616         }
7617
7618       if (next_hop_set)
7619         {
7620           if (DPO_PROTO_IP4 == next_hop_proto)
7621             {
7622               clib_memcpy (mp->mr_next_hop,
7623                            &v4_next_hop_address,
7624                            sizeof (v4_next_hop_address));
7625             }
7626           else if (DPO_PROTO_IP6 == next_hop_proto)
7627
7628             {
7629               clib_memcpy (mp->mr_next_hop,
7630                            &v6_next_hop_address,
7631                            sizeof (v6_next_hop_address));
7632             }
7633         }
7634       local_label++;
7635
7636       /* send it... */
7637       S (mp);
7638       /* If we receive SIGTERM, stop now... */
7639       if (vam->do_exit)
7640         break;
7641     }
7642
7643   /* When testing multiple add/del ops, use a control-ping to sync */
7644   if (count > 1)
7645     {
7646       vl_api_control_ping_t *mp_ping;
7647       f64 after;
7648       f64 timeout;
7649
7650       /* Shut off async mode */
7651       vam->async_mode = 0;
7652
7653       M (CONTROL_PING, mp_ping);
7654       S (mp_ping);
7655
7656       timeout = vat_time_now (vam) + 1.0;
7657       while (vat_time_now (vam) < timeout)
7658         if (vam->result_ready == 1)
7659           goto out;
7660       vam->retval = -99;
7661
7662     out:
7663       if (vam->retval == -99)
7664         errmsg ("timeout");
7665
7666       if (vam->async_errors > 0)
7667         {
7668           errmsg ("%d asynchronous errors", vam->async_errors);
7669           vam->retval = -98;
7670         }
7671       vam->async_errors = 0;
7672       after = vat_time_now (vam);
7673
7674       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7675       if (j > 0)
7676         count = j;
7677
7678       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7679              count, after - before, count / (after - before));
7680     }
7681   else
7682     {
7683       int ret;
7684
7685       /* Wait for a reply... */
7686       W (ret);
7687       return ret;
7688     }
7689
7690   /* Return the good/bad news */
7691   return (vam->retval);
7692 }
7693
7694 static int
7695 api_mpls_ip_bind_unbind (vat_main_t * vam)
7696 {
7697   unformat_input_t *i = vam->input;
7698   vl_api_mpls_ip_bind_unbind_t *mp;
7699   u32 ip_table_id = 0;
7700   u8 create_table_if_needed = 0;
7701   u8 is_bind = 1;
7702   u8 is_ip4 = 1;
7703   ip4_address_t v4_address;
7704   ip6_address_t v6_address;
7705   u32 address_length;
7706   u8 address_set = 0;
7707   mpls_label_t local_label = MPLS_LABEL_INVALID;
7708   int ret;
7709
7710   /* Parse args required to build the message */
7711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712     {
7713       if (unformat (i, "%U/%d", unformat_ip4_address,
7714                     &v4_address, &address_length))
7715         {
7716           is_ip4 = 1;
7717           address_set = 1;
7718         }
7719       else if (unformat (i, "%U/%d", unformat_ip6_address,
7720                          &v6_address, &address_length))
7721         {
7722           is_ip4 = 0;
7723           address_set = 1;
7724         }
7725       else if (unformat (i, "%d", &local_label))
7726         ;
7727       else if (unformat (i, "create-table"))
7728         create_table_if_needed = 1;
7729       else if (unformat (i, "table-id %d", &ip_table_id))
7730         ;
7731       else if (unformat (i, "unbind"))
7732         is_bind = 0;
7733       else if (unformat (i, "bind"))
7734         is_bind = 1;
7735       else
7736         {
7737           clib_warning ("parse error '%U'", format_unformat_error, i);
7738           return -99;
7739         }
7740     }
7741
7742   if (!address_set)
7743     {
7744       errmsg ("IP addres not set");
7745       return -99;
7746     }
7747
7748   if (MPLS_LABEL_INVALID == local_label)
7749     {
7750       errmsg ("missing label");
7751       return -99;
7752     }
7753
7754   /* Construct the API message */
7755   M (MPLS_IP_BIND_UNBIND, mp);
7756
7757   mp->mb_create_table_if_needed = create_table_if_needed;
7758   mp->mb_is_bind = is_bind;
7759   mp->mb_is_ip4 = is_ip4;
7760   mp->mb_ip_table_id = ntohl (ip_table_id);
7761   mp->mb_mpls_table_id = 0;
7762   mp->mb_label = ntohl (local_label);
7763   mp->mb_address_length = address_length;
7764
7765   if (is_ip4)
7766     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7767   else
7768     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7769
7770   /* send it... */
7771   S (mp);
7772
7773   /* Wait for a reply... */
7774   W (ret);
7775   return ret;
7776 }
7777
7778 static int
7779 api_proxy_arp_add_del (vat_main_t * vam)
7780 {
7781   unformat_input_t *i = vam->input;
7782   vl_api_proxy_arp_add_del_t *mp;
7783   u32 vrf_id = 0;
7784   u8 is_add = 1;
7785   ip4_address_t lo, hi;
7786   u8 range_set = 0;
7787   int ret;
7788
7789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7790     {
7791       if (unformat (i, "vrf %d", &vrf_id))
7792         ;
7793       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7794                          unformat_ip4_address, &hi))
7795         range_set = 1;
7796       else if (unformat (i, "del"))
7797         is_add = 0;
7798       else
7799         {
7800           clib_warning ("parse error '%U'", format_unformat_error, i);
7801           return -99;
7802         }
7803     }
7804
7805   if (range_set == 0)
7806     {
7807       errmsg ("address range not set");
7808       return -99;
7809     }
7810
7811   M (PROXY_ARP_ADD_DEL, mp);
7812
7813   mp->vrf_id = ntohl (vrf_id);
7814   mp->is_add = is_add;
7815   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7816   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7817
7818   S (mp);
7819   W (ret);
7820   return ret;
7821 }
7822
7823 static int
7824 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7825 {
7826   unformat_input_t *i = vam->input;
7827   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7828   u32 sw_if_index;
7829   u8 enable = 1;
7830   u8 sw_if_index_set = 0;
7831   int ret;
7832
7833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7834     {
7835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7836         sw_if_index_set = 1;
7837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7838         sw_if_index_set = 1;
7839       else if (unformat (i, "enable"))
7840         enable = 1;
7841       else if (unformat (i, "disable"))
7842         enable = 0;
7843       else
7844         {
7845           clib_warning ("parse error '%U'", format_unformat_error, i);
7846           return -99;
7847         }
7848     }
7849
7850   if (sw_if_index_set == 0)
7851     {
7852       errmsg ("missing interface name or sw_if_index");
7853       return -99;
7854     }
7855
7856   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7857
7858   mp->sw_if_index = ntohl (sw_if_index);
7859   mp->enable_disable = enable;
7860
7861   S (mp);
7862   W (ret);
7863   return ret;
7864 }
7865
7866 static int
7867 api_mpls_tunnel_add_del (vat_main_t * vam)
7868 {
7869   unformat_input_t *i = vam->input;
7870   vl_api_mpls_tunnel_add_del_t *mp;
7871
7872   u8 is_add = 1;
7873   u8 l2_only = 0;
7874   u32 sw_if_index = ~0;
7875   u32 next_hop_sw_if_index = ~0;
7876   u32 next_hop_proto_is_ip4 = 1;
7877
7878   u32 next_hop_table_id = 0;
7879   ip4_address_t v4_next_hop_address = {
7880     .as_u32 = 0,
7881   };
7882   ip6_address_t v6_next_hop_address = { {0} };
7883   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7884   int ret;
7885
7886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7887     {
7888       if (unformat (i, "add"))
7889         is_add = 1;
7890       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7891         is_add = 0;
7892       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7893         ;
7894       else if (unformat (i, "via %U",
7895                          unformat_ip4_address, &v4_next_hop_address))
7896         {
7897           next_hop_proto_is_ip4 = 1;
7898         }
7899       else if (unformat (i, "via %U",
7900                          unformat_ip6_address, &v6_next_hop_address))
7901         {
7902           next_hop_proto_is_ip4 = 0;
7903         }
7904       else if (unformat (i, "l2-only"))
7905         l2_only = 1;
7906       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7907         ;
7908       else if (unformat (i, "out-label %d", &next_hop_out_label))
7909         vec_add1 (labels, ntohl (next_hop_out_label));
7910       else
7911         {
7912           clib_warning ("parse error '%U'", format_unformat_error, i);
7913           return -99;
7914         }
7915     }
7916
7917   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7918
7919   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7920   mp->mt_sw_if_index = ntohl (sw_if_index);
7921   mp->mt_is_add = is_add;
7922   mp->mt_l2_only = l2_only;
7923   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7924   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7925
7926   mp->mt_next_hop_n_out_labels = vec_len (labels);
7927
7928   if (0 != mp->mt_next_hop_n_out_labels)
7929     {
7930       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7931                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7932       vec_free (labels);
7933     }
7934
7935   if (next_hop_proto_is_ip4)
7936     {
7937       clib_memcpy (mp->mt_next_hop,
7938                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7939     }
7940   else
7941     {
7942       clib_memcpy (mp->mt_next_hop,
7943                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7944     }
7945
7946   S (mp);
7947   W (ret);
7948   return ret;
7949 }
7950
7951 static int
7952 api_sw_interface_set_unnumbered (vat_main_t * vam)
7953 {
7954   unformat_input_t *i = vam->input;
7955   vl_api_sw_interface_set_unnumbered_t *mp;
7956   u32 sw_if_index;
7957   u32 unnum_sw_index = ~0;
7958   u8 is_add = 1;
7959   u8 sw_if_index_set = 0;
7960   int ret;
7961
7962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7963     {
7964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7965         sw_if_index_set = 1;
7966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7967         sw_if_index_set = 1;
7968       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7969         ;
7970       else if (unformat (i, "del"))
7971         is_add = 0;
7972       else
7973         {
7974           clib_warning ("parse error '%U'", format_unformat_error, i);
7975           return -99;
7976         }
7977     }
7978
7979   if (sw_if_index_set == 0)
7980     {
7981       errmsg ("missing interface name or sw_if_index");
7982       return -99;
7983     }
7984
7985   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7986
7987   mp->sw_if_index = ntohl (sw_if_index);
7988   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7989   mp->is_add = is_add;
7990
7991   S (mp);
7992   W (ret);
7993   return ret;
7994 }
7995
7996 static int
7997 api_ip_neighbor_add_del (vat_main_t * vam)
7998 {
7999   unformat_input_t *i = vam->input;
8000   vl_api_ip_neighbor_add_del_t *mp;
8001   u32 sw_if_index;
8002   u8 sw_if_index_set = 0;
8003   u8 is_add = 1;
8004   u8 is_static = 0;
8005   u8 is_no_fib_entry = 0;
8006   u8 mac_address[6];
8007   u8 mac_set = 0;
8008   u8 v4_address_set = 0;
8009   u8 v6_address_set = 0;
8010   ip4_address_t v4address;
8011   ip6_address_t v6address;
8012   int ret;
8013
8014   memset (mac_address, 0, sizeof (mac_address));
8015
8016   /* Parse args required to build the message */
8017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8018     {
8019       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8020         {
8021           mac_set = 1;
8022         }
8023       else if (unformat (i, "del"))
8024         is_add = 0;
8025       else
8026         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8027         sw_if_index_set = 1;
8028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8029         sw_if_index_set = 1;
8030       else if (unformat (i, "is_static"))
8031         is_static = 1;
8032       else if (unformat (i, "no-fib-entry"))
8033         is_no_fib_entry = 1;
8034       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8035         v4_address_set = 1;
8036       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8037         v6_address_set = 1;
8038       else
8039         {
8040           clib_warning ("parse error '%U'", format_unformat_error, i);
8041           return -99;
8042         }
8043     }
8044
8045   if (sw_if_index_set == 0)
8046     {
8047       errmsg ("missing interface name or sw_if_index");
8048       return -99;
8049     }
8050   if (v4_address_set && v6_address_set)
8051     {
8052       errmsg ("both v4 and v6 addresses set");
8053       return -99;
8054     }
8055   if (!v4_address_set && !v6_address_set)
8056     {
8057       errmsg ("no address set");
8058       return -99;
8059     }
8060
8061   /* Construct the API message */
8062   M (IP_NEIGHBOR_ADD_DEL, mp);
8063
8064   mp->sw_if_index = ntohl (sw_if_index);
8065   mp->is_add = is_add;
8066   mp->is_static = is_static;
8067   mp->is_no_adj_fib = is_no_fib_entry;
8068   if (mac_set)
8069     clib_memcpy (mp->mac_address, mac_address, 6);
8070   if (v6_address_set)
8071     {
8072       mp->is_ipv6 = 1;
8073       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8074     }
8075   else
8076     {
8077       /* mp->is_ipv6 = 0; via memset in M macro above */
8078       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8079     }
8080
8081   /* send it... */
8082   S (mp);
8083
8084   /* Wait for a reply, return good/bad news  */
8085   W (ret);
8086   return ret;
8087 }
8088
8089 static int
8090 api_reset_vrf (vat_main_t * vam)
8091 {
8092   unformat_input_t *i = vam->input;
8093   vl_api_reset_vrf_t *mp;
8094   u32 vrf_id = 0;
8095   u8 is_ipv6 = 0;
8096   u8 vrf_id_set = 0;
8097   int ret;
8098
8099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8100     {
8101       if (unformat (i, "vrf %d", &vrf_id))
8102         vrf_id_set = 1;
8103       else if (unformat (i, "ipv6"))
8104         is_ipv6 = 1;
8105       else
8106         {
8107           clib_warning ("parse error '%U'", format_unformat_error, i);
8108           return -99;
8109         }
8110     }
8111
8112   if (vrf_id_set == 0)
8113     {
8114       errmsg ("missing vrf id");
8115       return -99;
8116     }
8117
8118   M (RESET_VRF, mp);
8119
8120   mp->vrf_id = ntohl (vrf_id);
8121   mp->is_ipv6 = is_ipv6;
8122
8123   S (mp);
8124   W (ret);
8125   return ret;
8126 }
8127
8128 static int
8129 api_create_vlan_subif (vat_main_t * vam)
8130 {
8131   unformat_input_t *i = vam->input;
8132   vl_api_create_vlan_subif_t *mp;
8133   u32 sw_if_index;
8134   u8 sw_if_index_set = 0;
8135   u32 vlan_id;
8136   u8 vlan_id_set = 0;
8137   int ret;
8138
8139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8140     {
8141       if (unformat (i, "sw_if_index %d", &sw_if_index))
8142         sw_if_index_set = 1;
8143       else
8144         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8145         sw_if_index_set = 1;
8146       else if (unformat (i, "vlan %d", &vlan_id))
8147         vlan_id_set = 1;
8148       else
8149         {
8150           clib_warning ("parse error '%U'", format_unformat_error, i);
8151           return -99;
8152         }
8153     }
8154
8155   if (sw_if_index_set == 0)
8156     {
8157       errmsg ("missing interface name or sw_if_index");
8158       return -99;
8159     }
8160
8161   if (vlan_id_set == 0)
8162     {
8163       errmsg ("missing vlan_id");
8164       return -99;
8165     }
8166   M (CREATE_VLAN_SUBIF, mp);
8167
8168   mp->sw_if_index = ntohl (sw_if_index);
8169   mp->vlan_id = ntohl (vlan_id);
8170
8171   S (mp);
8172   W (ret);
8173   return ret;
8174 }
8175
8176 #define foreach_create_subif_bit                \
8177 _(no_tags)                                      \
8178 _(one_tag)                                      \
8179 _(two_tags)                                     \
8180 _(dot1ad)                                       \
8181 _(exact_match)                                  \
8182 _(default_sub)                                  \
8183 _(outer_vlan_id_any)                            \
8184 _(inner_vlan_id_any)
8185
8186 static int
8187 api_create_subif (vat_main_t * vam)
8188 {
8189   unformat_input_t *i = vam->input;
8190   vl_api_create_subif_t *mp;
8191   u32 sw_if_index;
8192   u8 sw_if_index_set = 0;
8193   u32 sub_id;
8194   u8 sub_id_set = 0;
8195   u32 no_tags = 0;
8196   u32 one_tag = 0;
8197   u32 two_tags = 0;
8198   u32 dot1ad = 0;
8199   u32 exact_match = 0;
8200   u32 default_sub = 0;
8201   u32 outer_vlan_id_any = 0;
8202   u32 inner_vlan_id_any = 0;
8203   u32 tmp;
8204   u16 outer_vlan_id = 0;
8205   u16 inner_vlan_id = 0;
8206   int ret;
8207
8208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8209     {
8210       if (unformat (i, "sw_if_index %d", &sw_if_index))
8211         sw_if_index_set = 1;
8212       else
8213         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8214         sw_if_index_set = 1;
8215       else if (unformat (i, "sub_id %d", &sub_id))
8216         sub_id_set = 1;
8217       else if (unformat (i, "outer_vlan_id %d", &tmp))
8218         outer_vlan_id = tmp;
8219       else if (unformat (i, "inner_vlan_id %d", &tmp))
8220         inner_vlan_id = tmp;
8221
8222 #define _(a) else if (unformat (i, #a)) a = 1 ;
8223       foreach_create_subif_bit
8224 #undef _
8225         else
8226         {
8227           clib_warning ("parse error '%U'", format_unformat_error, i);
8228           return -99;
8229         }
8230     }
8231
8232   if (sw_if_index_set == 0)
8233     {
8234       errmsg ("missing interface name or sw_if_index");
8235       return -99;
8236     }
8237
8238   if (sub_id_set == 0)
8239     {
8240       errmsg ("missing sub_id");
8241       return -99;
8242     }
8243   M (CREATE_SUBIF, mp);
8244
8245   mp->sw_if_index = ntohl (sw_if_index);
8246   mp->sub_id = ntohl (sub_id);
8247
8248 #define _(a) mp->a = a;
8249   foreach_create_subif_bit;
8250 #undef _
8251
8252   mp->outer_vlan_id = ntohs (outer_vlan_id);
8253   mp->inner_vlan_id = ntohs (inner_vlan_id);
8254
8255   S (mp);
8256   W (ret);
8257   return ret;
8258 }
8259
8260 static int
8261 api_oam_add_del (vat_main_t * vam)
8262 {
8263   unformat_input_t *i = vam->input;
8264   vl_api_oam_add_del_t *mp;
8265   u32 vrf_id = 0;
8266   u8 is_add = 1;
8267   ip4_address_t src, dst;
8268   u8 src_set = 0;
8269   u8 dst_set = 0;
8270   int ret;
8271
8272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8273     {
8274       if (unformat (i, "vrf %d", &vrf_id))
8275         ;
8276       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8277         src_set = 1;
8278       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8279         dst_set = 1;
8280       else if (unformat (i, "del"))
8281         is_add = 0;
8282       else
8283         {
8284           clib_warning ("parse error '%U'", format_unformat_error, i);
8285           return -99;
8286         }
8287     }
8288
8289   if (src_set == 0)
8290     {
8291       errmsg ("missing src addr");
8292       return -99;
8293     }
8294
8295   if (dst_set == 0)
8296     {
8297       errmsg ("missing dst addr");
8298       return -99;
8299     }
8300
8301   M (OAM_ADD_DEL, mp);
8302
8303   mp->vrf_id = ntohl (vrf_id);
8304   mp->is_add = is_add;
8305   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8306   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8307
8308   S (mp);
8309   W (ret);
8310   return ret;
8311 }
8312
8313 static int
8314 api_reset_fib (vat_main_t * vam)
8315 {
8316   unformat_input_t *i = vam->input;
8317   vl_api_reset_fib_t *mp;
8318   u32 vrf_id = 0;
8319   u8 is_ipv6 = 0;
8320   u8 vrf_id_set = 0;
8321
8322   int ret;
8323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8324     {
8325       if (unformat (i, "vrf %d", &vrf_id))
8326         vrf_id_set = 1;
8327       else if (unformat (i, "ipv6"))
8328         is_ipv6 = 1;
8329       else
8330         {
8331           clib_warning ("parse error '%U'", format_unformat_error, i);
8332           return -99;
8333         }
8334     }
8335
8336   if (vrf_id_set == 0)
8337     {
8338       errmsg ("missing vrf id");
8339       return -99;
8340     }
8341
8342   M (RESET_FIB, mp);
8343
8344   mp->vrf_id = ntohl (vrf_id);
8345   mp->is_ipv6 = is_ipv6;
8346
8347   S (mp);
8348   W (ret);
8349   return ret;
8350 }
8351
8352 static int
8353 api_dhcp_proxy_config (vat_main_t * vam)
8354 {
8355   unformat_input_t *i = vam->input;
8356   vl_api_dhcp_proxy_config_t *mp;
8357   u32 rx_vrf_id = 0;
8358   u32 server_vrf_id = 0;
8359   u8 is_add = 1;
8360   u8 v4_address_set = 0;
8361   u8 v6_address_set = 0;
8362   ip4_address_t v4address;
8363   ip6_address_t v6address;
8364   u8 v4_src_address_set = 0;
8365   u8 v6_src_address_set = 0;
8366   ip4_address_t v4srcaddress;
8367   ip6_address_t v6srcaddress;
8368   int ret;
8369
8370   /* Parse args required to build the message */
8371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8372     {
8373       if (unformat (i, "del"))
8374         is_add = 0;
8375       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8376         ;
8377       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8378         ;
8379       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8380         v4_address_set = 1;
8381       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8382         v6_address_set = 1;
8383       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8384         v4_src_address_set = 1;
8385       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8386         v6_src_address_set = 1;
8387       else
8388         break;
8389     }
8390
8391   if (v4_address_set && v6_address_set)
8392     {
8393       errmsg ("both v4 and v6 server addresses set");
8394       return -99;
8395     }
8396   if (!v4_address_set && !v6_address_set)
8397     {
8398       errmsg ("no server addresses set");
8399       return -99;
8400     }
8401
8402   if (v4_src_address_set && v6_src_address_set)
8403     {
8404       errmsg ("both v4 and v6  src addresses set");
8405       return -99;
8406     }
8407   if (!v4_src_address_set && !v6_src_address_set)
8408     {
8409       errmsg ("no src addresses set");
8410       return -99;
8411     }
8412
8413   if (!(v4_src_address_set && v4_address_set) &&
8414       !(v6_src_address_set && v6_address_set))
8415     {
8416       errmsg ("no matching server and src addresses set");
8417       return -99;
8418     }
8419
8420   /* Construct the API message */
8421   M (DHCP_PROXY_CONFIG, mp);
8422
8423   mp->is_add = is_add;
8424   mp->rx_vrf_id = ntohl (rx_vrf_id);
8425   mp->server_vrf_id = ntohl (server_vrf_id);
8426   if (v6_address_set)
8427     {
8428       mp->is_ipv6 = 1;
8429       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8430       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8431     }
8432   else
8433     {
8434       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8435       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8436     }
8437
8438   /* send it... */
8439   S (mp);
8440
8441   /* Wait for a reply, return good/bad news  */
8442   W (ret);
8443   return ret;
8444 }
8445
8446 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8447 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8448
8449 static void
8450 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8451 {
8452   vat_main_t *vam = &vat_main;
8453   u32 i, count = mp->count;
8454   vl_api_dhcp_server_t *s;
8455
8456   if (mp->is_ipv6)
8457     print (vam->ofp,
8458            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8459            ntohl (mp->rx_vrf_id),
8460            format_ip6_address, mp->dhcp_src_address,
8461            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8462   else
8463     print (vam->ofp,
8464            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8465            ntohl (mp->rx_vrf_id),
8466            format_ip4_address, mp->dhcp_src_address,
8467            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8468
8469   for (i = 0; i < count; i++)
8470     {
8471       s = &mp->servers[i];
8472
8473       if (mp->is_ipv6)
8474         print (vam->ofp,
8475                " Server Table-ID %d, Server Address %U",
8476                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8477       else
8478         print (vam->ofp,
8479                " Server Table-ID %d, Server Address %U",
8480                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8481     }
8482 }
8483
8484 static void vl_api_dhcp_proxy_details_t_handler_json
8485   (vl_api_dhcp_proxy_details_t * mp)
8486 {
8487   vat_main_t *vam = &vat_main;
8488   vat_json_node_t *node = NULL;
8489   u32 i, count = mp->count;
8490   struct in_addr ip4;
8491   struct in6_addr ip6;
8492   vl_api_dhcp_server_t *s;
8493
8494   if (VAT_JSON_ARRAY != vam->json_tree.type)
8495     {
8496       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8497       vat_json_init_array (&vam->json_tree);
8498     }
8499   node = vat_json_array_add (&vam->json_tree);
8500
8501   vat_json_init_object (node);
8502   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8503   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8504   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8505
8506   if (mp->is_ipv6)
8507     {
8508       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8509       vat_json_object_add_ip6 (node, "src_address", ip6);
8510     }
8511   else
8512     {
8513       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8514       vat_json_object_add_ip4 (node, "src_address", ip4);
8515     }
8516
8517   for (i = 0; i < count; i++)
8518     {
8519       s = &mp->servers[i];
8520
8521       vat_json_object_add_uint (node, "server-table-id",
8522                                 ntohl (s->server_vrf_id));
8523
8524       if (mp->is_ipv6)
8525         {
8526           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8527           vat_json_object_add_ip4 (node, "src_address", ip4);
8528         }
8529       else
8530         {
8531           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8532           vat_json_object_add_ip6 (node, "server_address", ip6);
8533         }
8534     }
8535 }
8536
8537 static int
8538 api_dhcp_proxy_dump (vat_main_t * vam)
8539 {
8540   unformat_input_t *i = vam->input;
8541   vl_api_control_ping_t *mp_ping;
8542   vl_api_dhcp_proxy_dump_t *mp;
8543   u8 is_ipv6 = 0;
8544   int ret;
8545
8546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8547     {
8548       if (unformat (i, "ipv6"))
8549         is_ipv6 = 1;
8550       else
8551         {
8552           clib_warning ("parse error '%U'", format_unformat_error, i);
8553           return -99;
8554         }
8555     }
8556
8557   M (DHCP_PROXY_DUMP, mp);
8558
8559   mp->is_ip6 = is_ipv6;
8560   S (mp);
8561
8562   /* Use a control ping for synchronization */
8563   M (CONTROL_PING, mp_ping);
8564   S (mp_ping);
8565
8566   W (ret);
8567   return ret;
8568 }
8569
8570 static int
8571 api_dhcp_proxy_set_vss (vat_main_t * vam)
8572 {
8573   unformat_input_t *i = vam->input;
8574   vl_api_dhcp_proxy_set_vss_t *mp;
8575   u8 is_ipv6 = 0;
8576   u8 is_add = 1;
8577   u32 tbl_id;
8578   u8 tbl_id_set = 0;
8579   u32 oui;
8580   u8 oui_set = 0;
8581   u32 fib_id;
8582   u8 fib_id_set = 0;
8583   int ret;
8584
8585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8586     {
8587       if (unformat (i, "tbl_id %d", &tbl_id))
8588         tbl_id_set = 1;
8589       if (unformat (i, "fib_id %d", &fib_id))
8590         fib_id_set = 1;
8591       if (unformat (i, "oui %d", &oui))
8592         oui_set = 1;
8593       else if (unformat (i, "ipv6"))
8594         is_ipv6 = 1;
8595       else if (unformat (i, "del"))
8596         is_add = 0;
8597       else
8598         {
8599           clib_warning ("parse error '%U'", format_unformat_error, i);
8600           return -99;
8601         }
8602     }
8603
8604   if (tbl_id_set == 0)
8605     {
8606       errmsg ("missing tbl id");
8607       return -99;
8608     }
8609
8610   if (fib_id_set == 0)
8611     {
8612       errmsg ("missing fib id");
8613       return -99;
8614     }
8615   if (oui_set == 0)
8616     {
8617       errmsg ("missing oui");
8618       return -99;
8619     }
8620
8621   M (DHCP_PROXY_SET_VSS, mp);
8622   mp->tbl_id = ntohl (tbl_id);
8623   mp->fib_id = ntohl (fib_id);
8624   mp->oui = ntohl (oui);
8625   mp->is_ipv6 = is_ipv6;
8626   mp->is_add = is_add;
8627
8628   S (mp);
8629   W (ret);
8630   return ret;
8631 }
8632
8633 static int
8634 api_dhcp_client_config (vat_main_t * vam)
8635 {
8636   unformat_input_t *i = vam->input;
8637   vl_api_dhcp_client_config_t *mp;
8638   u32 sw_if_index;
8639   u8 sw_if_index_set = 0;
8640   u8 is_add = 1;
8641   u8 *hostname = 0;
8642   u8 disable_event = 0;
8643   int ret;
8644
8645   /* Parse args required to build the message */
8646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8647     {
8648       if (unformat (i, "del"))
8649         is_add = 0;
8650       else
8651         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8652         sw_if_index_set = 1;
8653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8654         sw_if_index_set = 1;
8655       else if (unformat (i, "hostname %s", &hostname))
8656         ;
8657       else if (unformat (i, "disable_event"))
8658         disable_event = 1;
8659       else
8660         break;
8661     }
8662
8663   if (sw_if_index_set == 0)
8664     {
8665       errmsg ("missing interface name or sw_if_index");
8666       return -99;
8667     }
8668
8669   if (vec_len (hostname) > 63)
8670     {
8671       errmsg ("hostname too long");
8672     }
8673   vec_add1 (hostname, 0);
8674
8675   /* Construct the API message */
8676   M (DHCP_CLIENT_CONFIG, mp);
8677
8678   mp->sw_if_index = htonl (sw_if_index);
8679   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8680   vec_free (hostname);
8681   mp->is_add = is_add;
8682   mp->want_dhcp_event = disable_event ? 0 : 1;
8683   mp->pid = htonl (getpid ());
8684
8685   /* send it... */
8686   S (mp);
8687
8688   /* Wait for a reply, return good/bad news  */
8689   W (ret);
8690   return ret;
8691 }
8692
8693 static int
8694 api_set_ip_flow_hash (vat_main_t * vam)
8695 {
8696   unformat_input_t *i = vam->input;
8697   vl_api_set_ip_flow_hash_t *mp;
8698   u32 vrf_id = 0;
8699   u8 is_ipv6 = 0;
8700   u8 vrf_id_set = 0;
8701   u8 src = 0;
8702   u8 dst = 0;
8703   u8 sport = 0;
8704   u8 dport = 0;
8705   u8 proto = 0;
8706   u8 reverse = 0;
8707   int ret;
8708
8709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8710     {
8711       if (unformat (i, "vrf %d", &vrf_id))
8712         vrf_id_set = 1;
8713       else if (unformat (i, "ipv6"))
8714         is_ipv6 = 1;
8715       else if (unformat (i, "src"))
8716         src = 1;
8717       else if (unformat (i, "dst"))
8718         dst = 1;
8719       else if (unformat (i, "sport"))
8720         sport = 1;
8721       else if (unformat (i, "dport"))
8722         dport = 1;
8723       else if (unformat (i, "proto"))
8724         proto = 1;
8725       else if (unformat (i, "reverse"))
8726         reverse = 1;
8727
8728       else
8729         {
8730           clib_warning ("parse error '%U'", format_unformat_error, i);
8731           return -99;
8732         }
8733     }
8734
8735   if (vrf_id_set == 0)
8736     {
8737       errmsg ("missing vrf id");
8738       return -99;
8739     }
8740
8741   M (SET_IP_FLOW_HASH, mp);
8742   mp->src = src;
8743   mp->dst = dst;
8744   mp->sport = sport;
8745   mp->dport = dport;
8746   mp->proto = proto;
8747   mp->reverse = reverse;
8748   mp->vrf_id = ntohl (vrf_id);
8749   mp->is_ipv6 = is_ipv6;
8750
8751   S (mp);
8752   W (ret);
8753   return ret;
8754 }
8755
8756 static int
8757 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8758 {
8759   unformat_input_t *i = vam->input;
8760   vl_api_sw_interface_ip6_enable_disable_t *mp;
8761   u32 sw_if_index;
8762   u8 sw_if_index_set = 0;
8763   u8 enable = 0;
8764   int ret;
8765
8766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8767     {
8768       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8769         sw_if_index_set = 1;
8770       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8771         sw_if_index_set = 1;
8772       else if (unformat (i, "enable"))
8773         enable = 1;
8774       else if (unformat (i, "disable"))
8775         enable = 0;
8776       else
8777         {
8778           clib_warning ("parse error '%U'", format_unformat_error, i);
8779           return -99;
8780         }
8781     }
8782
8783   if (sw_if_index_set == 0)
8784     {
8785       errmsg ("missing interface name or sw_if_index");
8786       return -99;
8787     }
8788
8789   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8790
8791   mp->sw_if_index = ntohl (sw_if_index);
8792   mp->enable = enable;
8793
8794   S (mp);
8795   W (ret);
8796   return ret;
8797 }
8798
8799 static int
8800 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8801 {
8802   unformat_input_t *i = vam->input;
8803   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8804   u32 sw_if_index;
8805   u8 sw_if_index_set = 0;
8806   u8 v6_address_set = 0;
8807   ip6_address_t v6address;
8808   int ret;
8809
8810   /* Parse args required to build the message */
8811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8812     {
8813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8814         sw_if_index_set = 1;
8815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8816         sw_if_index_set = 1;
8817       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8818         v6_address_set = 1;
8819       else
8820         break;
8821     }
8822
8823   if (sw_if_index_set == 0)
8824     {
8825       errmsg ("missing interface name or sw_if_index");
8826       return -99;
8827     }
8828   if (!v6_address_set)
8829     {
8830       errmsg ("no address set");
8831       return -99;
8832     }
8833
8834   /* Construct the API message */
8835   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8836
8837   mp->sw_if_index = ntohl (sw_if_index);
8838   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8839
8840   /* send it... */
8841   S (mp);
8842
8843   /* Wait for a reply, return good/bad news  */
8844   W (ret);
8845   return ret;
8846 }
8847
8848 static int
8849 api_ip6nd_proxy_add_del (vat_main_t * vam)
8850 {
8851   unformat_input_t *i = vam->input;
8852   vl_api_ip6nd_proxy_add_del_t *mp;
8853   u32 sw_if_index = ~0;
8854   u8 v6_address_set = 0;
8855   ip6_address_t v6address;
8856   u8 is_del = 0;
8857   int ret;
8858
8859   /* Parse args required to build the message */
8860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8863         ;
8864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8865         ;
8866       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8867         v6_address_set = 1;
8868       if (unformat (i, "del"))
8869         is_del = 1;
8870       else
8871         {
8872           clib_warning ("parse error '%U'", format_unformat_error, i);
8873           return -99;
8874         }
8875     }
8876
8877   if (sw_if_index == ~0)
8878     {
8879       errmsg ("missing interface name or sw_if_index");
8880       return -99;
8881     }
8882   if (!v6_address_set)
8883     {
8884       errmsg ("no address set");
8885       return -99;
8886     }
8887
8888   /* Construct the API message */
8889   M (IP6ND_PROXY_ADD_DEL, mp);
8890
8891   mp->is_del = is_del;
8892   mp->sw_if_index = ntohl (sw_if_index);
8893   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8894
8895   /* send it... */
8896   S (mp);
8897
8898   /* Wait for a reply, return good/bad news  */
8899   W (ret);
8900   return ret;
8901 }
8902
8903 static int
8904 api_ip6nd_proxy_dump (vat_main_t * vam)
8905 {
8906   vl_api_ip6nd_proxy_dump_t *mp;
8907   vl_api_control_ping_t *mp_ping;
8908   int ret;
8909
8910   M (IP6ND_PROXY_DUMP, mp);
8911
8912   S (mp);
8913
8914   /* Use a control ping for synchronization */
8915   M (CONTROL_PING, mp_ping);
8916   S (mp_ping);
8917
8918   W (ret);
8919   return ret;
8920 }
8921
8922 static void vl_api_ip6nd_proxy_details_t_handler
8923   (vl_api_ip6nd_proxy_details_t * mp)
8924 {
8925   vat_main_t *vam = &vat_main;
8926
8927   print (vam->ofp, "host %U sw_if_index %d",
8928          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8929 }
8930
8931 static void vl_api_ip6nd_proxy_details_t_handler_json
8932   (vl_api_ip6nd_proxy_details_t * mp)
8933 {
8934   vat_main_t *vam = &vat_main;
8935   struct in6_addr ip6;
8936   vat_json_node_t *node = NULL;
8937
8938   if (VAT_JSON_ARRAY != vam->json_tree.type)
8939     {
8940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8941       vat_json_init_array (&vam->json_tree);
8942     }
8943   node = vat_json_array_add (&vam->json_tree);
8944
8945   vat_json_init_object (node);
8946   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8947
8948   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8949   vat_json_object_add_ip6 (node, "host", ip6);
8950 }
8951
8952 static int
8953 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8954 {
8955   unformat_input_t *i = vam->input;
8956   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8957   u32 sw_if_index;
8958   u8 sw_if_index_set = 0;
8959   u32 address_length = 0;
8960   u8 v6_address_set = 0;
8961   ip6_address_t v6address;
8962   u8 use_default = 0;
8963   u8 no_advertise = 0;
8964   u8 off_link = 0;
8965   u8 no_autoconfig = 0;
8966   u8 no_onlink = 0;
8967   u8 is_no = 0;
8968   u32 val_lifetime = 0;
8969   u32 pref_lifetime = 0;
8970   int ret;
8971
8972   /* Parse args required to build the message */
8973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8974     {
8975       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8976         sw_if_index_set = 1;
8977       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8978         sw_if_index_set = 1;
8979       else if (unformat (i, "%U/%d",
8980                          unformat_ip6_address, &v6address, &address_length))
8981         v6_address_set = 1;
8982       else if (unformat (i, "val_life %d", &val_lifetime))
8983         ;
8984       else if (unformat (i, "pref_life %d", &pref_lifetime))
8985         ;
8986       else if (unformat (i, "def"))
8987         use_default = 1;
8988       else if (unformat (i, "noadv"))
8989         no_advertise = 1;
8990       else if (unformat (i, "offl"))
8991         off_link = 1;
8992       else if (unformat (i, "noauto"))
8993         no_autoconfig = 1;
8994       else if (unformat (i, "nolink"))
8995         no_onlink = 1;
8996       else if (unformat (i, "isno"))
8997         is_no = 1;
8998       else
8999         {
9000           clib_warning ("parse error '%U'", format_unformat_error, i);
9001           return -99;
9002         }
9003     }
9004
9005   if (sw_if_index_set == 0)
9006     {
9007       errmsg ("missing interface name or sw_if_index");
9008       return -99;
9009     }
9010   if (!v6_address_set)
9011     {
9012       errmsg ("no address set");
9013       return -99;
9014     }
9015
9016   /* Construct the API message */
9017   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9018
9019   mp->sw_if_index = ntohl (sw_if_index);
9020   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9021   mp->address_length = address_length;
9022   mp->use_default = use_default;
9023   mp->no_advertise = no_advertise;
9024   mp->off_link = off_link;
9025   mp->no_autoconfig = no_autoconfig;
9026   mp->no_onlink = no_onlink;
9027   mp->is_no = is_no;
9028   mp->val_lifetime = ntohl (val_lifetime);
9029   mp->pref_lifetime = ntohl (pref_lifetime);
9030
9031   /* send it... */
9032   S (mp);
9033
9034   /* Wait for a reply, return good/bad news  */
9035   W (ret);
9036   return ret;
9037 }
9038
9039 static int
9040 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9041 {
9042   unformat_input_t *i = vam->input;
9043   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9044   u32 sw_if_index;
9045   u8 sw_if_index_set = 0;
9046   u8 suppress = 0;
9047   u8 managed = 0;
9048   u8 other = 0;
9049   u8 ll_option = 0;
9050   u8 send_unicast = 0;
9051   u8 cease = 0;
9052   u8 is_no = 0;
9053   u8 default_router = 0;
9054   u32 max_interval = 0;
9055   u32 min_interval = 0;
9056   u32 lifetime = 0;
9057   u32 initial_count = 0;
9058   u32 initial_interval = 0;
9059   int ret;
9060
9061
9062   /* Parse args required to build the message */
9063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9064     {
9065       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9066         sw_if_index_set = 1;
9067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9068         sw_if_index_set = 1;
9069       else if (unformat (i, "maxint %d", &max_interval))
9070         ;
9071       else if (unformat (i, "minint %d", &min_interval))
9072         ;
9073       else if (unformat (i, "life %d", &lifetime))
9074         ;
9075       else if (unformat (i, "count %d", &initial_count))
9076         ;
9077       else if (unformat (i, "interval %d", &initial_interval))
9078         ;
9079       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9080         suppress = 1;
9081       else if (unformat (i, "managed"))
9082         managed = 1;
9083       else if (unformat (i, "other"))
9084         other = 1;
9085       else if (unformat (i, "ll"))
9086         ll_option = 1;
9087       else if (unformat (i, "send"))
9088         send_unicast = 1;
9089       else if (unformat (i, "cease"))
9090         cease = 1;
9091       else if (unformat (i, "isno"))
9092         is_no = 1;
9093       else if (unformat (i, "def"))
9094         default_router = 1;
9095       else
9096         {
9097           clib_warning ("parse error '%U'", format_unformat_error, i);
9098           return -99;
9099         }
9100     }
9101
9102   if (sw_if_index_set == 0)
9103     {
9104       errmsg ("missing interface name or sw_if_index");
9105       return -99;
9106     }
9107
9108   /* Construct the API message */
9109   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9110
9111   mp->sw_if_index = ntohl (sw_if_index);
9112   mp->max_interval = ntohl (max_interval);
9113   mp->min_interval = ntohl (min_interval);
9114   mp->lifetime = ntohl (lifetime);
9115   mp->initial_count = ntohl (initial_count);
9116   mp->initial_interval = ntohl (initial_interval);
9117   mp->suppress = suppress;
9118   mp->managed = managed;
9119   mp->other = other;
9120   mp->ll_option = ll_option;
9121   mp->send_unicast = send_unicast;
9122   mp->cease = cease;
9123   mp->is_no = is_no;
9124   mp->default_router = default_router;
9125
9126   /* send it... */
9127   S (mp);
9128
9129   /* Wait for a reply, return good/bad news  */
9130   W (ret);
9131   return ret;
9132 }
9133
9134 static int
9135 api_set_arp_neighbor_limit (vat_main_t * vam)
9136 {
9137   unformat_input_t *i = vam->input;
9138   vl_api_set_arp_neighbor_limit_t *mp;
9139   u32 arp_nbr_limit;
9140   u8 limit_set = 0;
9141   u8 is_ipv6 = 0;
9142   int ret;
9143
9144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9145     {
9146       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9147         limit_set = 1;
9148       else if (unformat (i, "ipv6"))
9149         is_ipv6 = 1;
9150       else
9151         {
9152           clib_warning ("parse error '%U'", format_unformat_error, i);
9153           return -99;
9154         }
9155     }
9156
9157   if (limit_set == 0)
9158     {
9159       errmsg ("missing limit value");
9160       return -99;
9161     }
9162
9163   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9164
9165   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9166   mp->is_ipv6 = is_ipv6;
9167
9168   S (mp);
9169   W (ret);
9170   return ret;
9171 }
9172
9173 static int
9174 api_l2_patch_add_del (vat_main_t * vam)
9175 {
9176   unformat_input_t *i = vam->input;
9177   vl_api_l2_patch_add_del_t *mp;
9178   u32 rx_sw_if_index;
9179   u8 rx_sw_if_index_set = 0;
9180   u32 tx_sw_if_index;
9181   u8 tx_sw_if_index_set = 0;
9182   u8 is_add = 1;
9183   int ret;
9184
9185   /* Parse args required to build the message */
9186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9187     {
9188       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9189         rx_sw_if_index_set = 1;
9190       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9191         tx_sw_if_index_set = 1;
9192       else if (unformat (i, "rx"))
9193         {
9194           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9195             {
9196               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9197                             &rx_sw_if_index))
9198                 rx_sw_if_index_set = 1;
9199             }
9200           else
9201             break;
9202         }
9203       else if (unformat (i, "tx"))
9204         {
9205           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9206             {
9207               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9208                             &tx_sw_if_index))
9209                 tx_sw_if_index_set = 1;
9210             }
9211           else
9212             break;
9213         }
9214       else if (unformat (i, "del"))
9215         is_add = 0;
9216       else
9217         break;
9218     }
9219
9220   if (rx_sw_if_index_set == 0)
9221     {
9222       errmsg ("missing rx interface name or rx_sw_if_index");
9223       return -99;
9224     }
9225
9226   if (tx_sw_if_index_set == 0)
9227     {
9228       errmsg ("missing tx interface name or tx_sw_if_index");
9229       return -99;
9230     }
9231
9232   M (L2_PATCH_ADD_DEL, mp);
9233
9234   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9235   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9236   mp->is_add = is_add;
9237
9238   S (mp);
9239   W (ret);
9240   return ret;
9241 }
9242
9243 u8 is_del;
9244 u8 localsid_addr[16];
9245 u8 end_psp;
9246 u8 behavior;
9247 u32 sw_if_index;
9248 u32 vlan_index;
9249 u32 fib_table;
9250 u8 nh_addr[16];
9251
9252 static int
9253 api_sr_localsid_add_del (vat_main_t * vam)
9254 {
9255   unformat_input_t *i = vam->input;
9256   vl_api_sr_localsid_add_del_t *mp;
9257
9258   u8 is_del;
9259   ip6_address_t localsid;
9260   u8 end_psp = 0;
9261   u8 behavior = ~0;
9262   u32 sw_if_index;
9263   u32 fib_table = ~(u32) 0;
9264   ip6_address_t next_hop;
9265
9266   bool nexthop_set = 0;
9267
9268   int ret;
9269
9270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9271     {
9272       if (unformat (i, "del"))
9273         is_del = 1;
9274       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9275       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9276         nexthop_set = 1;
9277       else if (unformat (i, "behavior %u", &behavior));
9278       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9279       else if (unformat (i, "fib-table %u", &fib_table));
9280       else if (unformat (i, "end.psp %u", &behavior));
9281       else
9282         break;
9283     }
9284
9285   M (SR_LOCALSID_ADD_DEL, mp);
9286
9287   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9288   if (nexthop_set)
9289     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9290   mp->behavior = behavior;
9291   mp->sw_if_index = ntohl (sw_if_index);
9292   mp->fib_table = ntohl (fib_table);
9293   mp->end_psp = end_psp;
9294   mp->is_del = is_del;
9295
9296   S (mp);
9297   W (ret);
9298   return ret;
9299 }
9300
9301 static int
9302 api_ioam_enable (vat_main_t * vam)
9303 {
9304   unformat_input_t *input = vam->input;
9305   vl_api_ioam_enable_t *mp;
9306   u32 id = 0;
9307   int has_trace_option = 0;
9308   int has_pot_option = 0;
9309   int has_seqno_option = 0;
9310   int has_analyse_option = 0;
9311   int ret;
9312
9313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9314     {
9315       if (unformat (input, "trace"))
9316         has_trace_option = 1;
9317       else if (unformat (input, "pot"))
9318         has_pot_option = 1;
9319       else if (unformat (input, "seqno"))
9320         has_seqno_option = 1;
9321       else if (unformat (input, "analyse"))
9322         has_analyse_option = 1;
9323       else
9324         break;
9325     }
9326   M (IOAM_ENABLE, mp);
9327   mp->id = htons (id);
9328   mp->seqno = has_seqno_option;
9329   mp->analyse = has_analyse_option;
9330   mp->pot_enable = has_pot_option;
9331   mp->trace_enable = has_trace_option;
9332
9333   S (mp);
9334   W (ret);
9335   return ret;
9336 }
9337
9338
9339 static int
9340 api_ioam_disable (vat_main_t * vam)
9341 {
9342   vl_api_ioam_disable_t *mp;
9343   int ret;
9344
9345   M (IOAM_DISABLE, mp);
9346   S (mp);
9347   W (ret);
9348   return ret;
9349 }
9350
9351 #define foreach_tcp_proto_field                 \
9352 _(src_port)                                     \
9353 _(dst_port)
9354
9355 #define foreach_udp_proto_field                 \
9356 _(src_port)                                     \
9357 _(dst_port)
9358
9359 #define foreach_ip4_proto_field                 \
9360 _(src_address)                                  \
9361 _(dst_address)                                  \
9362 _(tos)                                          \
9363 _(length)                                       \
9364 _(fragment_id)                                  \
9365 _(ttl)                                          \
9366 _(protocol)                                     \
9367 _(checksum)
9368
9369 typedef struct
9370 {
9371   u16 src_port, dst_port;
9372 } tcpudp_header_t;
9373
9374 #if VPP_API_TEST_BUILTIN == 0
9375 uword
9376 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9377 {
9378   u8 **maskp = va_arg (*args, u8 **);
9379   u8 *mask = 0;
9380   u8 found_something = 0;
9381   tcp_header_t *tcp;
9382
9383 #define _(a) u8 a=0;
9384   foreach_tcp_proto_field;
9385 #undef _
9386
9387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9388     {
9389       if (0);
9390 #define _(a) else if (unformat (input, #a)) a=1;
9391       foreach_tcp_proto_field
9392 #undef _
9393         else
9394         break;
9395     }
9396
9397 #define _(a) found_something += a;
9398   foreach_tcp_proto_field;
9399 #undef _
9400
9401   if (found_something == 0)
9402     return 0;
9403
9404   vec_validate (mask, sizeof (*tcp) - 1);
9405
9406   tcp = (tcp_header_t *) mask;
9407
9408 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9409   foreach_tcp_proto_field;
9410 #undef _
9411
9412   *maskp = mask;
9413   return 1;
9414 }
9415
9416 uword
9417 unformat_udp_mask (unformat_input_t * input, va_list * args)
9418 {
9419   u8 **maskp = va_arg (*args, u8 **);
9420   u8 *mask = 0;
9421   u8 found_something = 0;
9422   udp_header_t *udp;
9423
9424 #define _(a) u8 a=0;
9425   foreach_udp_proto_field;
9426 #undef _
9427
9428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9429     {
9430       if (0);
9431 #define _(a) else if (unformat (input, #a)) a=1;
9432       foreach_udp_proto_field
9433 #undef _
9434         else
9435         break;
9436     }
9437
9438 #define _(a) found_something += a;
9439   foreach_udp_proto_field;
9440 #undef _
9441
9442   if (found_something == 0)
9443     return 0;
9444
9445   vec_validate (mask, sizeof (*udp) - 1);
9446
9447   udp = (udp_header_t *) mask;
9448
9449 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9450   foreach_udp_proto_field;
9451 #undef _
9452
9453   *maskp = mask;
9454   return 1;
9455 }
9456
9457 uword
9458 unformat_l4_mask (unformat_input_t * input, va_list * args)
9459 {
9460   u8 **maskp = va_arg (*args, u8 **);
9461   u16 src_port = 0, dst_port = 0;
9462   tcpudp_header_t *tcpudp;
9463
9464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9465     {
9466       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9467         return 1;
9468       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9469         return 1;
9470       else if (unformat (input, "src_port"))
9471         src_port = 0xFFFF;
9472       else if (unformat (input, "dst_port"))
9473         dst_port = 0xFFFF;
9474       else
9475         return 0;
9476     }
9477
9478   if (!src_port && !dst_port)
9479     return 0;
9480
9481   u8 *mask = 0;
9482   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9483
9484   tcpudp = (tcpudp_header_t *) mask;
9485   tcpudp->src_port = src_port;
9486   tcpudp->dst_port = dst_port;
9487
9488   *maskp = mask;
9489
9490   return 1;
9491 }
9492
9493 uword
9494 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9495 {
9496   u8 **maskp = va_arg (*args, u8 **);
9497   u8 *mask = 0;
9498   u8 found_something = 0;
9499   ip4_header_t *ip;
9500
9501 #define _(a) u8 a=0;
9502   foreach_ip4_proto_field;
9503 #undef _
9504   u8 version = 0;
9505   u8 hdr_length = 0;
9506
9507
9508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9509     {
9510       if (unformat (input, "version"))
9511         version = 1;
9512       else if (unformat (input, "hdr_length"))
9513         hdr_length = 1;
9514       else if (unformat (input, "src"))
9515         src_address = 1;
9516       else if (unformat (input, "dst"))
9517         dst_address = 1;
9518       else if (unformat (input, "proto"))
9519         protocol = 1;
9520
9521 #define _(a) else if (unformat (input, #a)) a=1;
9522       foreach_ip4_proto_field
9523 #undef _
9524         else
9525         break;
9526     }
9527
9528 #define _(a) found_something += a;
9529   foreach_ip4_proto_field;
9530 #undef _
9531
9532   if (found_something == 0)
9533     return 0;
9534
9535   vec_validate (mask, sizeof (*ip) - 1);
9536
9537   ip = (ip4_header_t *) mask;
9538
9539 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9540   foreach_ip4_proto_field;
9541 #undef _
9542
9543   ip->ip_version_and_header_length = 0;
9544
9545   if (version)
9546     ip->ip_version_and_header_length |= 0xF0;
9547
9548   if (hdr_length)
9549     ip->ip_version_and_header_length |= 0x0F;
9550
9551   *maskp = mask;
9552   return 1;
9553 }
9554
9555 #define foreach_ip6_proto_field                 \
9556 _(src_address)                                  \
9557 _(dst_address)                                  \
9558 _(payload_length)                               \
9559 _(hop_limit)                                    \
9560 _(protocol)
9561
9562 uword
9563 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9564 {
9565   u8 **maskp = va_arg (*args, u8 **);
9566   u8 *mask = 0;
9567   u8 found_something = 0;
9568   ip6_header_t *ip;
9569   u32 ip_version_traffic_class_and_flow_label;
9570
9571 #define _(a) u8 a=0;
9572   foreach_ip6_proto_field;
9573 #undef _
9574   u8 version = 0;
9575   u8 traffic_class = 0;
9576   u8 flow_label = 0;
9577
9578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9579     {
9580       if (unformat (input, "version"))
9581         version = 1;
9582       else if (unformat (input, "traffic-class"))
9583         traffic_class = 1;
9584       else if (unformat (input, "flow-label"))
9585         flow_label = 1;
9586       else if (unformat (input, "src"))
9587         src_address = 1;
9588       else if (unformat (input, "dst"))
9589         dst_address = 1;
9590       else if (unformat (input, "proto"))
9591         protocol = 1;
9592
9593 #define _(a) else if (unformat (input, #a)) a=1;
9594       foreach_ip6_proto_field
9595 #undef _
9596         else
9597         break;
9598     }
9599
9600 #define _(a) found_something += a;
9601   foreach_ip6_proto_field;
9602 #undef _
9603
9604   if (found_something == 0)
9605     return 0;
9606
9607   vec_validate (mask, sizeof (*ip) - 1);
9608
9609   ip = (ip6_header_t *) mask;
9610
9611 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9612   foreach_ip6_proto_field;
9613 #undef _
9614
9615   ip_version_traffic_class_and_flow_label = 0;
9616
9617   if (version)
9618     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9619
9620   if (traffic_class)
9621     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9622
9623   if (flow_label)
9624     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9625
9626   ip->ip_version_traffic_class_and_flow_label =
9627     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9628
9629   *maskp = mask;
9630   return 1;
9631 }
9632
9633 uword
9634 unformat_l3_mask (unformat_input_t * input, va_list * args)
9635 {
9636   u8 **maskp = va_arg (*args, u8 **);
9637
9638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9639     {
9640       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9641         return 1;
9642       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9643         return 1;
9644       else
9645         break;
9646     }
9647   return 0;
9648 }
9649
9650 uword
9651 unformat_l2_mask (unformat_input_t * input, va_list * args)
9652 {
9653   u8 **maskp = va_arg (*args, u8 **);
9654   u8 *mask = 0;
9655   u8 src = 0;
9656   u8 dst = 0;
9657   u8 proto = 0;
9658   u8 tag1 = 0;
9659   u8 tag2 = 0;
9660   u8 ignore_tag1 = 0;
9661   u8 ignore_tag2 = 0;
9662   u8 cos1 = 0;
9663   u8 cos2 = 0;
9664   u8 dot1q = 0;
9665   u8 dot1ad = 0;
9666   int len = 14;
9667
9668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9669     {
9670       if (unformat (input, "src"))
9671         src = 1;
9672       else if (unformat (input, "dst"))
9673         dst = 1;
9674       else if (unformat (input, "proto"))
9675         proto = 1;
9676       else if (unformat (input, "tag1"))
9677         tag1 = 1;
9678       else if (unformat (input, "tag2"))
9679         tag2 = 1;
9680       else if (unformat (input, "ignore-tag1"))
9681         ignore_tag1 = 1;
9682       else if (unformat (input, "ignore-tag2"))
9683         ignore_tag2 = 1;
9684       else if (unformat (input, "cos1"))
9685         cos1 = 1;
9686       else if (unformat (input, "cos2"))
9687         cos2 = 1;
9688       else if (unformat (input, "dot1q"))
9689         dot1q = 1;
9690       else if (unformat (input, "dot1ad"))
9691         dot1ad = 1;
9692       else
9693         break;
9694     }
9695   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9696        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9697     return 0;
9698
9699   if (tag1 || ignore_tag1 || cos1 || dot1q)
9700     len = 18;
9701   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9702     len = 22;
9703
9704   vec_validate (mask, len - 1);
9705
9706   if (dst)
9707     memset (mask, 0xff, 6);
9708
9709   if (src)
9710     memset (mask + 6, 0xff, 6);
9711
9712   if (tag2 || dot1ad)
9713     {
9714       /* inner vlan tag */
9715       if (tag2)
9716         {
9717           mask[19] = 0xff;
9718           mask[18] = 0x0f;
9719         }
9720       if (cos2)
9721         mask[18] |= 0xe0;
9722       if (proto)
9723         mask[21] = mask[20] = 0xff;
9724       if (tag1)
9725         {
9726           mask[15] = 0xff;
9727           mask[14] = 0x0f;
9728         }
9729       if (cos1)
9730         mask[14] |= 0xe0;
9731       *maskp = mask;
9732       return 1;
9733     }
9734   if (tag1 | dot1q)
9735     {
9736       if (tag1)
9737         {
9738           mask[15] = 0xff;
9739           mask[14] = 0x0f;
9740         }
9741       if (cos1)
9742         mask[14] |= 0xe0;
9743       if (proto)
9744         mask[16] = mask[17] = 0xff;
9745
9746       *maskp = mask;
9747       return 1;
9748     }
9749   if (cos2)
9750     mask[18] |= 0xe0;
9751   if (cos1)
9752     mask[14] |= 0xe0;
9753   if (proto)
9754     mask[12] = mask[13] = 0xff;
9755
9756   *maskp = mask;
9757   return 1;
9758 }
9759
9760 uword
9761 unformat_classify_mask (unformat_input_t * input, va_list * args)
9762 {
9763   u8 **maskp = va_arg (*args, u8 **);
9764   u32 *skipp = va_arg (*args, u32 *);
9765   u32 *matchp = va_arg (*args, u32 *);
9766   u32 match;
9767   u8 *mask = 0;
9768   u8 *l2 = 0;
9769   u8 *l3 = 0;
9770   u8 *l4 = 0;
9771   int i;
9772
9773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9774     {
9775       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9776         ;
9777       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9778         ;
9779       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9780         ;
9781       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9782         ;
9783       else
9784         break;
9785     }
9786
9787   if (l4 && !l3)
9788     {
9789       vec_free (mask);
9790       vec_free (l2);
9791       vec_free (l4);
9792       return 0;
9793     }
9794
9795   if (mask || l2 || l3 || l4)
9796     {
9797       if (l2 || l3 || l4)
9798         {
9799           /* "With a free Ethernet header in every package" */
9800           if (l2 == 0)
9801             vec_validate (l2, 13);
9802           mask = l2;
9803           if (vec_len (l3))
9804             {
9805               vec_append (mask, l3);
9806               vec_free (l3);
9807             }
9808           if (vec_len (l4))
9809             {
9810               vec_append (mask, l4);
9811               vec_free (l4);
9812             }
9813         }
9814
9815       /* Scan forward looking for the first significant mask octet */
9816       for (i = 0; i < vec_len (mask); i++)
9817         if (mask[i])
9818           break;
9819
9820       /* compute (skip, match) params */
9821       *skipp = i / sizeof (u32x4);
9822       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9823
9824       /* Pad mask to an even multiple of the vector size */
9825       while (vec_len (mask) % sizeof (u32x4))
9826         vec_add1 (mask, 0);
9827
9828       match = vec_len (mask) / sizeof (u32x4);
9829
9830       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9831         {
9832           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9833           if (*tmp || *(tmp + 1))
9834             break;
9835           match--;
9836         }
9837       if (match == 0)
9838         clib_warning ("BUG: match 0");
9839
9840       _vec_len (mask) = match * sizeof (u32x4);
9841
9842       *matchp = match;
9843       *maskp = mask;
9844
9845       return 1;
9846     }
9847
9848   return 0;
9849 }
9850 #endif /* VPP_API_TEST_BUILTIN */
9851
9852 #define foreach_l2_next                         \
9853 _(drop, DROP)                                   \
9854 _(ethernet, ETHERNET_INPUT)                     \
9855 _(ip4, IP4_INPUT)                               \
9856 _(ip6, IP6_INPUT)
9857
9858 uword
9859 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9860 {
9861   u32 *miss_next_indexp = va_arg (*args, u32 *);
9862   u32 next_index = 0;
9863   u32 tmp;
9864
9865 #define _(n,N) \
9866   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9867   foreach_l2_next;
9868 #undef _
9869
9870   if (unformat (input, "%d", &tmp))
9871     {
9872       next_index = tmp;
9873       goto out;
9874     }
9875
9876   return 0;
9877
9878 out:
9879   *miss_next_indexp = next_index;
9880   return 1;
9881 }
9882
9883 #define foreach_ip_next                         \
9884 _(drop, DROP)                                   \
9885 _(local, LOCAL)                                 \
9886 _(rewrite, REWRITE)
9887
9888 uword
9889 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9890 {
9891   u32 *miss_next_indexp = va_arg (*args, u32 *);
9892   u32 next_index = 0;
9893   u32 tmp;
9894
9895 #define _(n,N) \
9896   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9897   foreach_ip_next;
9898 #undef _
9899
9900   if (unformat (input, "%d", &tmp))
9901     {
9902       next_index = tmp;
9903       goto out;
9904     }
9905
9906   return 0;
9907
9908 out:
9909   *miss_next_indexp = next_index;
9910   return 1;
9911 }
9912
9913 #define foreach_acl_next                        \
9914 _(deny, DENY)
9915
9916 uword
9917 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9918 {
9919   u32 *miss_next_indexp = va_arg (*args, u32 *);
9920   u32 next_index = 0;
9921   u32 tmp;
9922
9923 #define _(n,N) \
9924   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9925   foreach_acl_next;
9926 #undef _
9927
9928   if (unformat (input, "permit"))
9929     {
9930       next_index = ~0;
9931       goto out;
9932     }
9933   else if (unformat (input, "%d", &tmp))
9934     {
9935       next_index = tmp;
9936       goto out;
9937     }
9938
9939   return 0;
9940
9941 out:
9942   *miss_next_indexp = next_index;
9943   return 1;
9944 }
9945
9946 uword
9947 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9948 {
9949   u32 *r = va_arg (*args, u32 *);
9950
9951   if (unformat (input, "conform-color"))
9952     *r = POLICE_CONFORM;
9953   else if (unformat (input, "exceed-color"))
9954     *r = POLICE_EXCEED;
9955   else
9956     return 0;
9957
9958   return 1;
9959 }
9960
9961 static int
9962 api_classify_add_del_table (vat_main_t * vam)
9963 {
9964   unformat_input_t *i = vam->input;
9965   vl_api_classify_add_del_table_t *mp;
9966
9967   u32 nbuckets = 2;
9968   u32 skip = ~0;
9969   u32 match = ~0;
9970   int is_add = 1;
9971   int del_chain = 0;
9972   u32 table_index = ~0;
9973   u32 next_table_index = ~0;
9974   u32 miss_next_index = ~0;
9975   u32 memory_size = 32 << 20;
9976   u8 *mask = 0;
9977   u32 current_data_flag = 0;
9978   int current_data_offset = 0;
9979   int ret;
9980
9981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9982     {
9983       if (unformat (i, "del"))
9984         is_add = 0;
9985       else if (unformat (i, "del-chain"))
9986         {
9987           is_add = 0;
9988           del_chain = 1;
9989         }
9990       else if (unformat (i, "buckets %d", &nbuckets))
9991         ;
9992       else if (unformat (i, "memory_size %d", &memory_size))
9993         ;
9994       else if (unformat (i, "skip %d", &skip))
9995         ;
9996       else if (unformat (i, "match %d", &match))
9997         ;
9998       else if (unformat (i, "table %d", &table_index))
9999         ;
10000       else if (unformat (i, "mask %U", unformat_classify_mask,
10001                          &mask, &skip, &match))
10002         ;
10003       else if (unformat (i, "next-table %d", &next_table_index))
10004         ;
10005       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10006                          &miss_next_index))
10007         ;
10008       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10009                          &miss_next_index))
10010         ;
10011       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10012                          &miss_next_index))
10013         ;
10014       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10015         ;
10016       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10017         ;
10018       else
10019         break;
10020     }
10021
10022   if (is_add && mask == 0)
10023     {
10024       errmsg ("Mask required");
10025       return -99;
10026     }
10027
10028   if (is_add && skip == ~0)
10029     {
10030       errmsg ("skip count required");
10031       return -99;
10032     }
10033
10034   if (is_add && match == ~0)
10035     {
10036       errmsg ("match count required");
10037       return -99;
10038     }
10039
10040   if (!is_add && table_index == ~0)
10041     {
10042       errmsg ("table index required for delete");
10043       return -99;
10044     }
10045
10046   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10047
10048   mp->is_add = is_add;
10049   mp->del_chain = del_chain;
10050   mp->table_index = ntohl (table_index);
10051   mp->nbuckets = ntohl (nbuckets);
10052   mp->memory_size = ntohl (memory_size);
10053   mp->skip_n_vectors = ntohl (skip);
10054   mp->match_n_vectors = ntohl (match);
10055   mp->next_table_index = ntohl (next_table_index);
10056   mp->miss_next_index = ntohl (miss_next_index);
10057   mp->current_data_flag = ntohl (current_data_flag);
10058   mp->current_data_offset = ntohl (current_data_offset);
10059   clib_memcpy (mp->mask, mask, vec_len (mask));
10060
10061   vec_free (mask);
10062
10063   S (mp);
10064   W (ret);
10065   return ret;
10066 }
10067
10068 #if VPP_API_TEST_BUILTIN == 0
10069 uword
10070 unformat_l4_match (unformat_input_t * input, va_list * args)
10071 {
10072   u8 **matchp = va_arg (*args, u8 **);
10073
10074   u8 *proto_header = 0;
10075   int src_port = 0;
10076   int dst_port = 0;
10077
10078   tcpudp_header_t h;
10079
10080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10081     {
10082       if (unformat (input, "src_port %d", &src_port))
10083         ;
10084       else if (unformat (input, "dst_port %d", &dst_port))
10085         ;
10086       else
10087         return 0;
10088     }
10089
10090   h.src_port = clib_host_to_net_u16 (src_port);
10091   h.dst_port = clib_host_to_net_u16 (dst_port);
10092   vec_validate (proto_header, sizeof (h) - 1);
10093   memcpy (proto_header, &h, sizeof (h));
10094
10095   *matchp = proto_header;
10096
10097   return 1;
10098 }
10099
10100 uword
10101 unformat_ip4_match (unformat_input_t * input, va_list * args)
10102 {
10103   u8 **matchp = va_arg (*args, u8 **);
10104   u8 *match = 0;
10105   ip4_header_t *ip;
10106   int version = 0;
10107   u32 version_val;
10108   int hdr_length = 0;
10109   u32 hdr_length_val;
10110   int src = 0, dst = 0;
10111   ip4_address_t src_val, dst_val;
10112   int proto = 0;
10113   u32 proto_val;
10114   int tos = 0;
10115   u32 tos_val;
10116   int length = 0;
10117   u32 length_val;
10118   int fragment_id = 0;
10119   u32 fragment_id_val;
10120   int ttl = 0;
10121   int ttl_val;
10122   int checksum = 0;
10123   u32 checksum_val;
10124
10125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10126     {
10127       if (unformat (input, "version %d", &version_val))
10128         version = 1;
10129       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10130         hdr_length = 1;
10131       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10132         src = 1;
10133       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10134         dst = 1;
10135       else if (unformat (input, "proto %d", &proto_val))
10136         proto = 1;
10137       else if (unformat (input, "tos %d", &tos_val))
10138         tos = 1;
10139       else if (unformat (input, "length %d", &length_val))
10140         length = 1;
10141       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10142         fragment_id = 1;
10143       else if (unformat (input, "ttl %d", &ttl_val))
10144         ttl = 1;
10145       else if (unformat (input, "checksum %d", &checksum_val))
10146         checksum = 1;
10147       else
10148         break;
10149     }
10150
10151   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10152       + ttl + checksum == 0)
10153     return 0;
10154
10155   /*
10156    * Aligned because we use the real comparison functions
10157    */
10158   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10159
10160   ip = (ip4_header_t *) match;
10161
10162   /* These are realistically matched in practice */
10163   if (src)
10164     ip->src_address.as_u32 = src_val.as_u32;
10165
10166   if (dst)
10167     ip->dst_address.as_u32 = dst_val.as_u32;
10168
10169   if (proto)
10170     ip->protocol = proto_val;
10171
10172
10173   /* These are not, but they're included for completeness */
10174   if (version)
10175     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10176
10177   if (hdr_length)
10178     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10179
10180   if (tos)
10181     ip->tos = tos_val;
10182
10183   if (length)
10184     ip->length = clib_host_to_net_u16 (length_val);
10185
10186   if (ttl)
10187     ip->ttl = ttl_val;
10188
10189   if (checksum)
10190     ip->checksum = clib_host_to_net_u16 (checksum_val);
10191
10192   *matchp = match;
10193   return 1;
10194 }
10195
10196 uword
10197 unformat_ip6_match (unformat_input_t * input, va_list * args)
10198 {
10199   u8 **matchp = va_arg (*args, u8 **);
10200   u8 *match = 0;
10201   ip6_header_t *ip;
10202   int version = 0;
10203   u32 version_val;
10204   u8 traffic_class = 0;
10205   u32 traffic_class_val = 0;
10206   u8 flow_label = 0;
10207   u8 flow_label_val;
10208   int src = 0, dst = 0;
10209   ip6_address_t src_val, dst_val;
10210   int proto = 0;
10211   u32 proto_val;
10212   int payload_length = 0;
10213   u32 payload_length_val;
10214   int hop_limit = 0;
10215   int hop_limit_val;
10216   u32 ip_version_traffic_class_and_flow_label;
10217
10218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10219     {
10220       if (unformat (input, "version %d", &version_val))
10221         version = 1;
10222       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10223         traffic_class = 1;
10224       else if (unformat (input, "flow_label %d", &flow_label_val))
10225         flow_label = 1;
10226       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10227         src = 1;
10228       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10229         dst = 1;
10230       else if (unformat (input, "proto %d", &proto_val))
10231         proto = 1;
10232       else if (unformat (input, "payload_length %d", &payload_length_val))
10233         payload_length = 1;
10234       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10235         hop_limit = 1;
10236       else
10237         break;
10238     }
10239
10240   if (version + traffic_class + flow_label + src + dst + proto +
10241       payload_length + hop_limit == 0)
10242     return 0;
10243
10244   /*
10245    * Aligned because we use the real comparison functions
10246    */
10247   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10248
10249   ip = (ip6_header_t *) match;
10250
10251   if (src)
10252     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10253
10254   if (dst)
10255     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10256
10257   if (proto)
10258     ip->protocol = proto_val;
10259
10260   ip_version_traffic_class_and_flow_label = 0;
10261
10262   if (version)
10263     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10264
10265   if (traffic_class)
10266     ip_version_traffic_class_and_flow_label |=
10267       (traffic_class_val & 0xFF) << 20;
10268
10269   if (flow_label)
10270     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10271
10272   ip->ip_version_traffic_class_and_flow_label =
10273     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10274
10275   if (payload_length)
10276     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10277
10278   if (hop_limit)
10279     ip->hop_limit = hop_limit_val;
10280
10281   *matchp = match;
10282   return 1;
10283 }
10284
10285 uword
10286 unformat_l3_match (unformat_input_t * input, va_list * args)
10287 {
10288   u8 **matchp = va_arg (*args, u8 **);
10289
10290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10291     {
10292       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10293         return 1;
10294       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10295         return 1;
10296       else
10297         break;
10298     }
10299   return 0;
10300 }
10301
10302 uword
10303 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10304 {
10305   u8 *tagp = va_arg (*args, u8 *);
10306   u32 tag;
10307
10308   if (unformat (input, "%d", &tag))
10309     {
10310       tagp[0] = (tag >> 8) & 0x0F;
10311       tagp[1] = tag & 0xFF;
10312       return 1;
10313     }
10314
10315   return 0;
10316 }
10317
10318 uword
10319 unformat_l2_match (unformat_input_t * input, va_list * args)
10320 {
10321   u8 **matchp = va_arg (*args, u8 **);
10322   u8 *match = 0;
10323   u8 src = 0;
10324   u8 src_val[6];
10325   u8 dst = 0;
10326   u8 dst_val[6];
10327   u8 proto = 0;
10328   u16 proto_val;
10329   u8 tag1 = 0;
10330   u8 tag1_val[2];
10331   u8 tag2 = 0;
10332   u8 tag2_val[2];
10333   int len = 14;
10334   u8 ignore_tag1 = 0;
10335   u8 ignore_tag2 = 0;
10336   u8 cos1 = 0;
10337   u8 cos2 = 0;
10338   u32 cos1_val = 0;
10339   u32 cos2_val = 0;
10340
10341   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10342     {
10343       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10344         src = 1;
10345       else
10346         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10347         dst = 1;
10348       else if (unformat (input, "proto %U",
10349                          unformat_ethernet_type_host_byte_order, &proto_val))
10350         proto = 1;
10351       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10352         tag1 = 1;
10353       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10354         tag2 = 1;
10355       else if (unformat (input, "ignore-tag1"))
10356         ignore_tag1 = 1;
10357       else if (unformat (input, "ignore-tag2"))
10358         ignore_tag2 = 1;
10359       else if (unformat (input, "cos1 %d", &cos1_val))
10360         cos1 = 1;
10361       else if (unformat (input, "cos2 %d", &cos2_val))
10362         cos2 = 1;
10363       else
10364         break;
10365     }
10366   if ((src + dst + proto + tag1 + tag2 +
10367        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10368     return 0;
10369
10370   if (tag1 || ignore_tag1 || cos1)
10371     len = 18;
10372   if (tag2 || ignore_tag2 || cos2)
10373     len = 22;
10374
10375   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10376
10377   if (dst)
10378     clib_memcpy (match, dst_val, 6);
10379
10380   if (src)
10381     clib_memcpy (match + 6, src_val, 6);
10382
10383   if (tag2)
10384     {
10385       /* inner vlan tag */
10386       match[19] = tag2_val[1];
10387       match[18] = tag2_val[0];
10388       if (cos2)
10389         match[18] |= (cos2_val & 0x7) << 5;
10390       if (proto)
10391         {
10392           match[21] = proto_val & 0xff;
10393           match[20] = proto_val >> 8;
10394         }
10395       if (tag1)
10396         {
10397           match[15] = tag1_val[1];
10398           match[14] = tag1_val[0];
10399         }
10400       if (cos1)
10401         match[14] |= (cos1_val & 0x7) << 5;
10402       *matchp = match;
10403       return 1;
10404     }
10405   if (tag1)
10406     {
10407       match[15] = tag1_val[1];
10408       match[14] = tag1_val[0];
10409       if (proto)
10410         {
10411           match[17] = proto_val & 0xff;
10412           match[16] = proto_val >> 8;
10413         }
10414       if (cos1)
10415         match[14] |= (cos1_val & 0x7) << 5;
10416
10417       *matchp = match;
10418       return 1;
10419     }
10420   if (cos2)
10421     match[18] |= (cos2_val & 0x7) << 5;
10422   if (cos1)
10423     match[14] |= (cos1_val & 0x7) << 5;
10424   if (proto)
10425     {
10426       match[13] = proto_val & 0xff;
10427       match[12] = proto_val >> 8;
10428     }
10429
10430   *matchp = match;
10431   return 1;
10432 }
10433 #endif
10434
10435 uword
10436 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10437 {
10438   u8 **matchp = va_arg (*args, u8 **);
10439   u32 skip_n_vectors = va_arg (*args, u32);
10440   u32 match_n_vectors = va_arg (*args, u32);
10441
10442   u8 *match = 0;
10443   u8 *l2 = 0;
10444   u8 *l3 = 0;
10445   u8 *l4 = 0;
10446
10447   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10448     {
10449       if (unformat (input, "hex %U", unformat_hex_string, &match))
10450         ;
10451       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10452         ;
10453       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10454         ;
10455       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10456         ;
10457       else
10458         break;
10459     }
10460
10461   if (l4 && !l3)
10462     {
10463       vec_free (match);
10464       vec_free (l2);
10465       vec_free (l4);
10466       return 0;
10467     }
10468
10469   if (match || l2 || l3 || l4)
10470     {
10471       if (l2 || l3 || l4)
10472         {
10473           /* "Win a free Ethernet header in every packet" */
10474           if (l2 == 0)
10475             vec_validate_aligned (l2, 13, sizeof (u32x4));
10476           match = l2;
10477           if (vec_len (l3))
10478             {
10479               vec_append_aligned (match, l3, sizeof (u32x4));
10480               vec_free (l3);
10481             }
10482           if (vec_len (l4))
10483             {
10484               vec_append_aligned (match, l4, sizeof (u32x4));
10485               vec_free (l4);
10486             }
10487         }
10488
10489       /* Make sure the vector is big enough even if key is all 0's */
10490       vec_validate_aligned
10491         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10492          sizeof (u32x4));
10493
10494       /* Set size, include skipped vectors */
10495       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10496
10497       *matchp = match;
10498
10499       return 1;
10500     }
10501
10502   return 0;
10503 }
10504
10505 static int
10506 api_classify_add_del_session (vat_main_t * vam)
10507 {
10508   unformat_input_t *i = vam->input;
10509   vl_api_classify_add_del_session_t *mp;
10510   int is_add = 1;
10511   u32 table_index = ~0;
10512   u32 hit_next_index = ~0;
10513   u32 opaque_index = ~0;
10514   u8 *match = 0;
10515   i32 advance = 0;
10516   u32 skip_n_vectors = 0;
10517   u32 match_n_vectors = 0;
10518   u32 action = 0;
10519   u32 metadata = 0;
10520   int ret;
10521
10522   /*
10523    * Warning: you have to supply skip_n and match_n
10524    * because the API client cant simply look at the classify
10525    * table object.
10526    */
10527
10528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10529     {
10530       if (unformat (i, "del"))
10531         is_add = 0;
10532       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10533                          &hit_next_index))
10534         ;
10535       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10536                          &hit_next_index))
10537         ;
10538       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10539                          &hit_next_index))
10540         ;
10541       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10542         ;
10543       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10544         ;
10545       else if (unformat (i, "opaque-index %d", &opaque_index))
10546         ;
10547       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10548         ;
10549       else if (unformat (i, "match_n %d", &match_n_vectors))
10550         ;
10551       else if (unformat (i, "match %U", api_unformat_classify_match,
10552                          &match, skip_n_vectors, match_n_vectors))
10553         ;
10554       else if (unformat (i, "advance %d", &advance))
10555         ;
10556       else if (unformat (i, "table-index %d", &table_index))
10557         ;
10558       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10559         action = 1;
10560       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10561         action = 2;
10562       else if (unformat (i, "action %d", &action))
10563         ;
10564       else if (unformat (i, "metadata %d", &metadata))
10565         ;
10566       else
10567         break;
10568     }
10569
10570   if (table_index == ~0)
10571     {
10572       errmsg ("Table index required");
10573       return -99;
10574     }
10575
10576   if (is_add && match == 0)
10577     {
10578       errmsg ("Match value required");
10579       return -99;
10580     }
10581
10582   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10583
10584   mp->is_add = is_add;
10585   mp->table_index = ntohl (table_index);
10586   mp->hit_next_index = ntohl (hit_next_index);
10587   mp->opaque_index = ntohl (opaque_index);
10588   mp->advance = ntohl (advance);
10589   mp->action = action;
10590   mp->metadata = ntohl (metadata);
10591   clib_memcpy (mp->match, match, vec_len (match));
10592   vec_free (match);
10593
10594   S (mp);
10595   W (ret);
10596   return ret;
10597 }
10598
10599 static int
10600 api_classify_set_interface_ip_table (vat_main_t * vam)
10601 {
10602   unformat_input_t *i = vam->input;
10603   vl_api_classify_set_interface_ip_table_t *mp;
10604   u32 sw_if_index;
10605   int sw_if_index_set;
10606   u32 table_index = ~0;
10607   u8 is_ipv6 = 0;
10608   int ret;
10609
10610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10611     {
10612       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10613         sw_if_index_set = 1;
10614       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10615         sw_if_index_set = 1;
10616       else if (unformat (i, "table %d", &table_index))
10617         ;
10618       else
10619         {
10620           clib_warning ("parse error '%U'", format_unformat_error, i);
10621           return -99;
10622         }
10623     }
10624
10625   if (sw_if_index_set == 0)
10626     {
10627       errmsg ("missing interface name or sw_if_index");
10628       return -99;
10629     }
10630
10631
10632   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10633
10634   mp->sw_if_index = ntohl (sw_if_index);
10635   mp->table_index = ntohl (table_index);
10636   mp->is_ipv6 = is_ipv6;
10637
10638   S (mp);
10639   W (ret);
10640   return ret;
10641 }
10642
10643 static int
10644 api_classify_set_interface_l2_tables (vat_main_t * vam)
10645 {
10646   unformat_input_t *i = vam->input;
10647   vl_api_classify_set_interface_l2_tables_t *mp;
10648   u32 sw_if_index;
10649   int sw_if_index_set;
10650   u32 ip4_table_index = ~0;
10651   u32 ip6_table_index = ~0;
10652   u32 other_table_index = ~0;
10653   u32 is_input = 1;
10654   int ret;
10655
10656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10657     {
10658       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10659         sw_if_index_set = 1;
10660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10661         sw_if_index_set = 1;
10662       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10663         ;
10664       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10665         ;
10666       else if (unformat (i, "other-table %d", &other_table_index))
10667         ;
10668       else if (unformat (i, "is-input %d", &is_input))
10669         ;
10670       else
10671         {
10672           clib_warning ("parse error '%U'", format_unformat_error, i);
10673           return -99;
10674         }
10675     }
10676
10677   if (sw_if_index_set == 0)
10678     {
10679       errmsg ("missing interface name or sw_if_index");
10680       return -99;
10681     }
10682
10683
10684   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10685
10686   mp->sw_if_index = ntohl (sw_if_index);
10687   mp->ip4_table_index = ntohl (ip4_table_index);
10688   mp->ip6_table_index = ntohl (ip6_table_index);
10689   mp->other_table_index = ntohl (other_table_index);
10690   mp->is_input = (u8) is_input;
10691
10692   S (mp);
10693   W (ret);
10694   return ret;
10695 }
10696
10697 static int
10698 api_set_ipfix_exporter (vat_main_t * vam)
10699 {
10700   unformat_input_t *i = vam->input;
10701   vl_api_set_ipfix_exporter_t *mp;
10702   ip4_address_t collector_address;
10703   u8 collector_address_set = 0;
10704   u32 collector_port = ~0;
10705   ip4_address_t src_address;
10706   u8 src_address_set = 0;
10707   u32 vrf_id = ~0;
10708   u32 path_mtu = ~0;
10709   u32 template_interval = ~0;
10710   u8 udp_checksum = 0;
10711   int ret;
10712
10713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10714     {
10715       if (unformat (i, "collector_address %U", unformat_ip4_address,
10716                     &collector_address))
10717         collector_address_set = 1;
10718       else if (unformat (i, "collector_port %d", &collector_port))
10719         ;
10720       else if (unformat (i, "src_address %U", unformat_ip4_address,
10721                          &src_address))
10722         src_address_set = 1;
10723       else if (unformat (i, "vrf_id %d", &vrf_id))
10724         ;
10725       else if (unformat (i, "path_mtu %d", &path_mtu))
10726         ;
10727       else if (unformat (i, "template_interval %d", &template_interval))
10728         ;
10729       else if (unformat (i, "udp_checksum"))
10730         udp_checksum = 1;
10731       else
10732         break;
10733     }
10734
10735   if (collector_address_set == 0)
10736     {
10737       errmsg ("collector_address required");
10738       return -99;
10739     }
10740
10741   if (src_address_set == 0)
10742     {
10743       errmsg ("src_address required");
10744       return -99;
10745     }
10746
10747   M (SET_IPFIX_EXPORTER, mp);
10748
10749   memcpy (mp->collector_address, collector_address.data,
10750           sizeof (collector_address.data));
10751   mp->collector_port = htons ((u16) collector_port);
10752   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10753   mp->vrf_id = htonl (vrf_id);
10754   mp->path_mtu = htonl (path_mtu);
10755   mp->template_interval = htonl (template_interval);
10756   mp->udp_checksum = udp_checksum;
10757
10758   S (mp);
10759   W (ret);
10760   return ret;
10761 }
10762
10763 static int
10764 api_set_ipfix_classify_stream (vat_main_t * vam)
10765 {
10766   unformat_input_t *i = vam->input;
10767   vl_api_set_ipfix_classify_stream_t *mp;
10768   u32 domain_id = 0;
10769   u32 src_port = UDP_DST_PORT_ipfix;
10770   int ret;
10771
10772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10773     {
10774       if (unformat (i, "domain %d", &domain_id))
10775         ;
10776       else if (unformat (i, "src_port %d", &src_port))
10777         ;
10778       else
10779         {
10780           errmsg ("unknown input `%U'", format_unformat_error, i);
10781           return -99;
10782         }
10783     }
10784
10785   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10786
10787   mp->domain_id = htonl (domain_id);
10788   mp->src_port = htons ((u16) src_port);
10789
10790   S (mp);
10791   W (ret);
10792   return ret;
10793 }
10794
10795 static int
10796 api_ipfix_classify_table_add_del (vat_main_t * vam)
10797 {
10798   unformat_input_t *i = vam->input;
10799   vl_api_ipfix_classify_table_add_del_t *mp;
10800   int is_add = -1;
10801   u32 classify_table_index = ~0;
10802   u8 ip_version = 0;
10803   u8 transport_protocol = 255;
10804   int ret;
10805
10806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10807     {
10808       if (unformat (i, "add"))
10809         is_add = 1;
10810       else if (unformat (i, "del"))
10811         is_add = 0;
10812       else if (unformat (i, "table %d", &classify_table_index))
10813         ;
10814       else if (unformat (i, "ip4"))
10815         ip_version = 4;
10816       else if (unformat (i, "ip6"))
10817         ip_version = 6;
10818       else if (unformat (i, "tcp"))
10819         transport_protocol = 6;
10820       else if (unformat (i, "udp"))
10821         transport_protocol = 17;
10822       else
10823         {
10824           errmsg ("unknown input `%U'", format_unformat_error, i);
10825           return -99;
10826         }
10827     }
10828
10829   if (is_add == -1)
10830     {
10831       errmsg ("expecting: add|del");
10832       return -99;
10833     }
10834   if (classify_table_index == ~0)
10835     {
10836       errmsg ("classifier table not specified");
10837       return -99;
10838     }
10839   if (ip_version == 0)
10840     {
10841       errmsg ("IP version not specified");
10842       return -99;
10843     }
10844
10845   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10846
10847   mp->is_add = is_add;
10848   mp->table_id = htonl (classify_table_index);
10849   mp->ip_version = ip_version;
10850   mp->transport_protocol = transport_protocol;
10851
10852   S (mp);
10853   W (ret);
10854   return ret;
10855 }
10856
10857 static int
10858 api_get_node_index (vat_main_t * vam)
10859 {
10860   unformat_input_t *i = vam->input;
10861   vl_api_get_node_index_t *mp;
10862   u8 *name = 0;
10863   int ret;
10864
10865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10866     {
10867       if (unformat (i, "node %s", &name))
10868         ;
10869       else
10870         break;
10871     }
10872   if (name == 0)
10873     {
10874       errmsg ("node name required");
10875       return -99;
10876     }
10877   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10878     {
10879       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10880       return -99;
10881     }
10882
10883   M (GET_NODE_INDEX, mp);
10884   clib_memcpy (mp->node_name, name, vec_len (name));
10885   vec_free (name);
10886
10887   S (mp);
10888   W (ret);
10889   return ret;
10890 }
10891
10892 static int
10893 api_get_next_index (vat_main_t * vam)
10894 {
10895   unformat_input_t *i = vam->input;
10896   vl_api_get_next_index_t *mp;
10897   u8 *node_name = 0, *next_node_name = 0;
10898   int ret;
10899
10900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10901     {
10902       if (unformat (i, "node-name %s", &node_name))
10903         ;
10904       else if (unformat (i, "next-node-name %s", &next_node_name))
10905         break;
10906     }
10907
10908   if (node_name == 0)
10909     {
10910       errmsg ("node name required");
10911       return -99;
10912     }
10913   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10914     {
10915       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10916       return -99;
10917     }
10918
10919   if (next_node_name == 0)
10920     {
10921       errmsg ("next node name required");
10922       return -99;
10923     }
10924   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10925     {
10926       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10927       return -99;
10928     }
10929
10930   M (GET_NEXT_INDEX, mp);
10931   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10932   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10933   vec_free (node_name);
10934   vec_free (next_node_name);
10935
10936   S (mp);
10937   W (ret);
10938   return ret;
10939 }
10940
10941 static int
10942 api_add_node_next (vat_main_t * vam)
10943 {
10944   unformat_input_t *i = vam->input;
10945   vl_api_add_node_next_t *mp;
10946   u8 *name = 0;
10947   u8 *next = 0;
10948   int ret;
10949
10950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10951     {
10952       if (unformat (i, "node %s", &name))
10953         ;
10954       else if (unformat (i, "next %s", &next))
10955         ;
10956       else
10957         break;
10958     }
10959   if (name == 0)
10960     {
10961       errmsg ("node name required");
10962       return -99;
10963     }
10964   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10965     {
10966       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10967       return -99;
10968     }
10969   if (next == 0)
10970     {
10971       errmsg ("next node required");
10972       return -99;
10973     }
10974   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10975     {
10976       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10977       return -99;
10978     }
10979
10980   M (ADD_NODE_NEXT, mp);
10981   clib_memcpy (mp->node_name, name, vec_len (name));
10982   clib_memcpy (mp->next_name, next, vec_len (next));
10983   vec_free (name);
10984   vec_free (next);
10985
10986   S (mp);
10987   W (ret);
10988   return ret;
10989 }
10990
10991 static int
10992 api_l2tpv3_create_tunnel (vat_main_t * vam)
10993 {
10994   unformat_input_t *i = vam->input;
10995   ip6_address_t client_address, our_address;
10996   int client_address_set = 0;
10997   int our_address_set = 0;
10998   u32 local_session_id = 0;
10999   u32 remote_session_id = 0;
11000   u64 local_cookie = 0;
11001   u64 remote_cookie = 0;
11002   u8 l2_sublayer_present = 0;
11003   vl_api_l2tpv3_create_tunnel_t *mp;
11004   int ret;
11005
11006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11007     {
11008       if (unformat (i, "client_address %U", unformat_ip6_address,
11009                     &client_address))
11010         client_address_set = 1;
11011       else if (unformat (i, "our_address %U", unformat_ip6_address,
11012                          &our_address))
11013         our_address_set = 1;
11014       else if (unformat (i, "local_session_id %d", &local_session_id))
11015         ;
11016       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11017         ;
11018       else if (unformat (i, "local_cookie %lld", &local_cookie))
11019         ;
11020       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11021         ;
11022       else if (unformat (i, "l2-sublayer-present"))
11023         l2_sublayer_present = 1;
11024       else
11025         break;
11026     }
11027
11028   if (client_address_set == 0)
11029     {
11030       errmsg ("client_address required");
11031       return -99;
11032     }
11033
11034   if (our_address_set == 0)
11035     {
11036       errmsg ("our_address required");
11037       return -99;
11038     }
11039
11040   M (L2TPV3_CREATE_TUNNEL, mp);
11041
11042   clib_memcpy (mp->client_address, client_address.as_u8,
11043                sizeof (mp->client_address));
11044
11045   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11046
11047   mp->local_session_id = ntohl (local_session_id);
11048   mp->remote_session_id = ntohl (remote_session_id);
11049   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11050   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11051   mp->l2_sublayer_present = l2_sublayer_present;
11052   mp->is_ipv6 = 1;
11053
11054   S (mp);
11055   W (ret);
11056   return ret;
11057 }
11058
11059 static int
11060 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11061 {
11062   unformat_input_t *i = vam->input;
11063   u32 sw_if_index;
11064   u8 sw_if_index_set = 0;
11065   u64 new_local_cookie = 0;
11066   u64 new_remote_cookie = 0;
11067   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11068   int ret;
11069
11070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11071     {
11072       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11073         sw_if_index_set = 1;
11074       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11075         sw_if_index_set = 1;
11076       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11077         ;
11078       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11079         ;
11080       else
11081         break;
11082     }
11083
11084   if (sw_if_index_set == 0)
11085     {
11086       errmsg ("missing interface name or sw_if_index");
11087       return -99;
11088     }
11089
11090   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11091
11092   mp->sw_if_index = ntohl (sw_if_index);
11093   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11094   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11095
11096   S (mp);
11097   W (ret);
11098   return ret;
11099 }
11100
11101 static int
11102 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11103 {
11104   unformat_input_t *i = vam->input;
11105   vl_api_l2tpv3_interface_enable_disable_t *mp;
11106   u32 sw_if_index;
11107   u8 sw_if_index_set = 0;
11108   u8 enable_disable = 1;
11109   int ret;
11110
11111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11112     {
11113       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11114         sw_if_index_set = 1;
11115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11116         sw_if_index_set = 1;
11117       else if (unformat (i, "enable"))
11118         enable_disable = 1;
11119       else if (unformat (i, "disable"))
11120         enable_disable = 0;
11121       else
11122         break;
11123     }
11124
11125   if (sw_if_index_set == 0)
11126     {
11127       errmsg ("missing interface name or sw_if_index");
11128       return -99;
11129     }
11130
11131   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11132
11133   mp->sw_if_index = ntohl (sw_if_index);
11134   mp->enable_disable = enable_disable;
11135
11136   S (mp);
11137   W (ret);
11138   return ret;
11139 }
11140
11141 static int
11142 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11143 {
11144   unformat_input_t *i = vam->input;
11145   vl_api_l2tpv3_set_lookup_key_t *mp;
11146   u8 key = ~0;
11147   int ret;
11148
11149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11150     {
11151       if (unformat (i, "lookup_v6_src"))
11152         key = L2T_LOOKUP_SRC_ADDRESS;
11153       else if (unformat (i, "lookup_v6_dst"))
11154         key = L2T_LOOKUP_DST_ADDRESS;
11155       else if (unformat (i, "lookup_session_id"))
11156         key = L2T_LOOKUP_SESSION_ID;
11157       else
11158         break;
11159     }
11160
11161   if (key == (u8) ~ 0)
11162     {
11163       errmsg ("l2tp session lookup key unset");
11164       return -99;
11165     }
11166
11167   M (L2TPV3_SET_LOOKUP_KEY, mp);
11168
11169   mp->key = key;
11170
11171   S (mp);
11172   W (ret);
11173   return ret;
11174 }
11175
11176 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11177   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11178 {
11179   vat_main_t *vam = &vat_main;
11180
11181   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11182          format_ip6_address, mp->our_address,
11183          format_ip6_address, mp->client_address,
11184          clib_net_to_host_u32 (mp->sw_if_index));
11185
11186   print (vam->ofp,
11187          "   local cookies %016llx %016llx remote cookie %016llx",
11188          clib_net_to_host_u64 (mp->local_cookie[0]),
11189          clib_net_to_host_u64 (mp->local_cookie[1]),
11190          clib_net_to_host_u64 (mp->remote_cookie));
11191
11192   print (vam->ofp, "   local session-id %d remote session-id %d",
11193          clib_net_to_host_u32 (mp->local_session_id),
11194          clib_net_to_host_u32 (mp->remote_session_id));
11195
11196   print (vam->ofp, "   l2 specific sublayer %s\n",
11197          mp->l2_sublayer_present ? "preset" : "absent");
11198
11199 }
11200
11201 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11202   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11203 {
11204   vat_main_t *vam = &vat_main;
11205   vat_json_node_t *node = NULL;
11206   struct in6_addr addr;
11207
11208   if (VAT_JSON_ARRAY != vam->json_tree.type)
11209     {
11210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11211       vat_json_init_array (&vam->json_tree);
11212     }
11213   node = vat_json_array_add (&vam->json_tree);
11214
11215   vat_json_init_object (node);
11216
11217   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11218   vat_json_object_add_ip6 (node, "our_address", addr);
11219   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11220   vat_json_object_add_ip6 (node, "client_address", addr);
11221
11222   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11223   vat_json_init_array (lc);
11224   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11225   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11226   vat_json_object_add_uint (node, "remote_cookie",
11227                             clib_net_to_host_u64 (mp->remote_cookie));
11228
11229   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11230   vat_json_object_add_uint (node, "local_session_id",
11231                             clib_net_to_host_u32 (mp->local_session_id));
11232   vat_json_object_add_uint (node, "remote_session_id",
11233                             clib_net_to_host_u32 (mp->remote_session_id));
11234   vat_json_object_add_string_copy (node, "l2_sublayer",
11235                                    mp->l2_sublayer_present ? (u8 *) "present"
11236                                    : (u8 *) "absent");
11237 }
11238
11239 static int
11240 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11241 {
11242   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11243   vl_api_control_ping_t *mp_ping;
11244   int ret;
11245
11246   /* Get list of l2tpv3-tunnel interfaces */
11247   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11248   S (mp);
11249
11250   /* Use a control ping for synchronization */
11251   M (CONTROL_PING, mp_ping);
11252   S (mp_ping);
11253
11254   W (ret);
11255   return ret;
11256 }
11257
11258
11259 static void vl_api_sw_interface_tap_details_t_handler
11260   (vl_api_sw_interface_tap_details_t * mp)
11261 {
11262   vat_main_t *vam = &vat_main;
11263
11264   print (vam->ofp, "%-16s %d",
11265          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11266 }
11267
11268 static void vl_api_sw_interface_tap_details_t_handler_json
11269   (vl_api_sw_interface_tap_details_t * mp)
11270 {
11271   vat_main_t *vam = &vat_main;
11272   vat_json_node_t *node = NULL;
11273
11274   if (VAT_JSON_ARRAY != vam->json_tree.type)
11275     {
11276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11277       vat_json_init_array (&vam->json_tree);
11278     }
11279   node = vat_json_array_add (&vam->json_tree);
11280
11281   vat_json_init_object (node);
11282   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11283   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11284 }
11285
11286 static int
11287 api_sw_interface_tap_dump (vat_main_t * vam)
11288 {
11289   vl_api_sw_interface_tap_dump_t *mp;
11290   vl_api_control_ping_t *mp_ping;
11291   int ret;
11292
11293   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11294   /* Get list of tap interfaces */
11295   M (SW_INTERFACE_TAP_DUMP, mp);
11296   S (mp);
11297
11298   /* Use a control ping for synchronization */
11299   M (CONTROL_PING, mp_ping);
11300   S (mp_ping);
11301
11302   W (ret);
11303   return ret;
11304 }
11305
11306 static uword unformat_vxlan_decap_next
11307   (unformat_input_t * input, va_list * args)
11308 {
11309   u32 *result = va_arg (*args, u32 *);
11310   u32 tmp;
11311
11312   if (unformat (input, "l2"))
11313     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11314   else if (unformat (input, "%d", &tmp))
11315     *result = tmp;
11316   else
11317     return 0;
11318   return 1;
11319 }
11320
11321 static int
11322 api_vxlan_add_del_tunnel (vat_main_t * vam)
11323 {
11324   unformat_input_t *line_input = vam->input;
11325   vl_api_vxlan_add_del_tunnel_t *mp;
11326   ip46_address_t src, dst;
11327   u8 is_add = 1;
11328   u8 ipv4_set = 0, ipv6_set = 0;
11329   u8 src_set = 0;
11330   u8 dst_set = 0;
11331   u8 grp_set = 0;
11332   u32 mcast_sw_if_index = ~0;
11333   u32 encap_vrf_id = 0;
11334   u32 decap_next_index = ~0;
11335   u32 vni = 0;
11336   int ret;
11337
11338   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11339   memset (&src, 0, sizeof src);
11340   memset (&dst, 0, sizeof dst);
11341
11342   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11343     {
11344       if (unformat (line_input, "del"))
11345         is_add = 0;
11346       else
11347         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11348         {
11349           ipv4_set = 1;
11350           src_set = 1;
11351         }
11352       else
11353         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11354         {
11355           ipv4_set = 1;
11356           dst_set = 1;
11357         }
11358       else
11359         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11360         {
11361           ipv6_set = 1;
11362           src_set = 1;
11363         }
11364       else
11365         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11366         {
11367           ipv6_set = 1;
11368           dst_set = 1;
11369         }
11370       else if (unformat (line_input, "group %U %U",
11371                          unformat_ip4_address, &dst.ip4,
11372                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11373         {
11374           grp_set = dst_set = 1;
11375           ipv4_set = 1;
11376         }
11377       else if (unformat (line_input, "group %U",
11378                          unformat_ip4_address, &dst.ip4))
11379         {
11380           grp_set = dst_set = 1;
11381           ipv4_set = 1;
11382         }
11383       else if (unformat (line_input, "group %U %U",
11384                          unformat_ip6_address, &dst.ip6,
11385                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11386         {
11387           grp_set = dst_set = 1;
11388           ipv6_set = 1;
11389         }
11390       else if (unformat (line_input, "group %U",
11391                          unformat_ip6_address, &dst.ip6))
11392         {
11393           grp_set = dst_set = 1;
11394           ipv6_set = 1;
11395         }
11396       else
11397         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11398         ;
11399       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11400         ;
11401       else if (unformat (line_input, "decap-next %U",
11402                          unformat_vxlan_decap_next, &decap_next_index))
11403         ;
11404       else if (unformat (line_input, "vni %d", &vni))
11405         ;
11406       else
11407         {
11408           errmsg ("parse error '%U'", format_unformat_error, line_input);
11409           return -99;
11410         }
11411     }
11412
11413   if (src_set == 0)
11414     {
11415       errmsg ("tunnel src address not specified");
11416       return -99;
11417     }
11418   if (dst_set == 0)
11419     {
11420       errmsg ("tunnel dst address not specified");
11421       return -99;
11422     }
11423
11424   if (grp_set && !ip46_address_is_multicast (&dst))
11425     {
11426       errmsg ("tunnel group address not multicast");
11427       return -99;
11428     }
11429   if (grp_set && mcast_sw_if_index == ~0)
11430     {
11431       errmsg ("tunnel nonexistent multicast device");
11432       return -99;
11433     }
11434   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11435     {
11436       errmsg ("tunnel dst address must be unicast");
11437       return -99;
11438     }
11439
11440
11441   if (ipv4_set && ipv6_set)
11442     {
11443       errmsg ("both IPv4 and IPv6 addresses specified");
11444       return -99;
11445     }
11446
11447   if ((vni == 0) || (vni >> 24))
11448     {
11449       errmsg ("vni not specified or out of range");
11450       return -99;
11451     }
11452
11453   M (VXLAN_ADD_DEL_TUNNEL, mp);
11454
11455   if (ipv6_set)
11456     {
11457       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11458       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11459     }
11460   else
11461     {
11462       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11463       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11464     }
11465   mp->encap_vrf_id = ntohl (encap_vrf_id);
11466   mp->decap_next_index = ntohl (decap_next_index);
11467   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11468   mp->vni = ntohl (vni);
11469   mp->is_add = is_add;
11470   mp->is_ipv6 = ipv6_set;
11471
11472   S (mp);
11473   W (ret);
11474   return ret;
11475 }
11476
11477 static void vl_api_vxlan_tunnel_details_t_handler
11478   (vl_api_vxlan_tunnel_details_t * mp)
11479 {
11480   vat_main_t *vam = &vat_main;
11481   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11482   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11483
11484   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11485          ntohl (mp->sw_if_index),
11486          format_ip46_address, &src, IP46_TYPE_ANY,
11487          format_ip46_address, &dst, IP46_TYPE_ANY,
11488          ntohl (mp->encap_vrf_id),
11489          ntohl (mp->decap_next_index), ntohl (mp->vni),
11490          ntohl (mp->mcast_sw_if_index));
11491 }
11492
11493 static void vl_api_vxlan_tunnel_details_t_handler_json
11494   (vl_api_vxlan_tunnel_details_t * mp)
11495 {
11496   vat_main_t *vam = &vat_main;
11497   vat_json_node_t *node = NULL;
11498
11499   if (VAT_JSON_ARRAY != vam->json_tree.type)
11500     {
11501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11502       vat_json_init_array (&vam->json_tree);
11503     }
11504   node = vat_json_array_add (&vam->json_tree);
11505
11506   vat_json_init_object (node);
11507   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11508   if (mp->is_ipv6)
11509     {
11510       struct in6_addr ip6;
11511
11512       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11513       vat_json_object_add_ip6 (node, "src_address", ip6);
11514       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11515       vat_json_object_add_ip6 (node, "dst_address", ip6);
11516     }
11517   else
11518     {
11519       struct in_addr ip4;
11520
11521       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11522       vat_json_object_add_ip4 (node, "src_address", ip4);
11523       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11524       vat_json_object_add_ip4 (node, "dst_address", ip4);
11525     }
11526   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11527   vat_json_object_add_uint (node, "decap_next_index",
11528                             ntohl (mp->decap_next_index));
11529   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11530   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11531   vat_json_object_add_uint (node, "mcast_sw_if_index",
11532                             ntohl (mp->mcast_sw_if_index));
11533 }
11534
11535 static int
11536 api_vxlan_tunnel_dump (vat_main_t * vam)
11537 {
11538   unformat_input_t *i = vam->input;
11539   vl_api_vxlan_tunnel_dump_t *mp;
11540   vl_api_control_ping_t *mp_ping;
11541   u32 sw_if_index;
11542   u8 sw_if_index_set = 0;
11543   int ret;
11544
11545   /* Parse args required to build the message */
11546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11547     {
11548       if (unformat (i, "sw_if_index %d", &sw_if_index))
11549         sw_if_index_set = 1;
11550       else
11551         break;
11552     }
11553
11554   if (sw_if_index_set == 0)
11555     {
11556       sw_if_index = ~0;
11557     }
11558
11559   if (!vam->json_output)
11560     {
11561       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11562              "sw_if_index", "src_address", "dst_address",
11563              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11564     }
11565
11566   /* Get list of vxlan-tunnel interfaces */
11567   M (VXLAN_TUNNEL_DUMP, mp);
11568
11569   mp->sw_if_index = htonl (sw_if_index);
11570
11571   S (mp);
11572
11573   /* Use a control ping for synchronization */
11574   M (CONTROL_PING, mp_ping);
11575   S (mp_ping);
11576
11577   W (ret);
11578   return ret;
11579 }
11580
11581 static int
11582 api_gre_add_del_tunnel (vat_main_t * vam)
11583 {
11584   unformat_input_t *line_input = vam->input;
11585   vl_api_gre_add_del_tunnel_t *mp;
11586   ip4_address_t src4, dst4;
11587   ip6_address_t src6, dst6;
11588   u8 is_add = 1;
11589   u8 ipv4_set = 0;
11590   u8 ipv6_set = 0;
11591   u8 teb = 0;
11592   u8 src_set = 0;
11593   u8 dst_set = 0;
11594   u32 outer_fib_id = 0;
11595   int ret;
11596
11597   memset (&src4, 0, sizeof src4);
11598   memset (&dst4, 0, sizeof dst4);
11599   memset (&src6, 0, sizeof src6);
11600   memset (&dst6, 0, sizeof dst6);
11601
11602   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11603     {
11604       if (unformat (line_input, "del"))
11605         is_add = 0;
11606       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11607         {
11608           src_set = 1;
11609           ipv4_set = 1;
11610         }
11611       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11612         {
11613           dst_set = 1;
11614           ipv4_set = 1;
11615         }
11616       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11617         {
11618           src_set = 1;
11619           ipv6_set = 1;
11620         }
11621       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11622         {
11623           dst_set = 1;
11624           ipv6_set = 1;
11625         }
11626       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11627         ;
11628       else if (unformat (line_input, "teb"))
11629         teb = 1;
11630       else
11631         {
11632           errmsg ("parse error '%U'", format_unformat_error, line_input);
11633           return -99;
11634         }
11635     }
11636
11637   if (src_set == 0)
11638     {
11639       errmsg ("tunnel src address not specified");
11640       return -99;
11641     }
11642   if (dst_set == 0)
11643     {
11644       errmsg ("tunnel dst address not specified");
11645       return -99;
11646     }
11647   if (ipv4_set && ipv6_set)
11648     {
11649       errmsg ("both IPv4 and IPv6 addresses specified");
11650       return -99;
11651     }
11652
11653
11654   M (GRE_ADD_DEL_TUNNEL, mp);
11655
11656   if (ipv4_set)
11657     {
11658       clib_memcpy (&mp->src_address, &src4, 4);
11659       clib_memcpy (&mp->dst_address, &dst4, 4);
11660     }
11661   else
11662     {
11663       clib_memcpy (&mp->src_address, &src6, 16);
11664       clib_memcpy (&mp->dst_address, &dst6, 16);
11665     }
11666   mp->outer_fib_id = ntohl (outer_fib_id);
11667   mp->is_add = is_add;
11668   mp->teb = teb;
11669   mp->is_ipv6 = ipv6_set;
11670
11671   S (mp);
11672   W (ret);
11673   return ret;
11674 }
11675
11676 static void vl_api_gre_tunnel_details_t_handler
11677   (vl_api_gre_tunnel_details_t * mp)
11678 {
11679   vat_main_t *vam = &vat_main;
11680   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11681   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11682
11683   print (vam->ofp, "%11d%24U%24U%6d%14d",
11684          ntohl (mp->sw_if_index),
11685          format_ip46_address, &src, IP46_TYPE_ANY,
11686          format_ip46_address, &dst, IP46_TYPE_ANY,
11687          mp->teb, ntohl (mp->outer_fib_id));
11688 }
11689
11690 static void vl_api_gre_tunnel_details_t_handler_json
11691   (vl_api_gre_tunnel_details_t * mp)
11692 {
11693   vat_main_t *vam = &vat_main;
11694   vat_json_node_t *node = NULL;
11695   struct in_addr ip4;
11696   struct in6_addr ip6;
11697
11698   if (VAT_JSON_ARRAY != vam->json_tree.type)
11699     {
11700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11701       vat_json_init_array (&vam->json_tree);
11702     }
11703   node = vat_json_array_add (&vam->json_tree);
11704
11705   vat_json_init_object (node);
11706   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11707   if (!mp->is_ipv6)
11708     {
11709       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11710       vat_json_object_add_ip4 (node, "src_address", ip4);
11711       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11712       vat_json_object_add_ip4 (node, "dst_address", ip4);
11713     }
11714   else
11715     {
11716       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11717       vat_json_object_add_ip6 (node, "src_address", ip6);
11718       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11719       vat_json_object_add_ip6 (node, "dst_address", ip6);
11720     }
11721   vat_json_object_add_uint (node, "teb", mp->teb);
11722   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11723   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11724 }
11725
11726 static int
11727 api_gre_tunnel_dump (vat_main_t * vam)
11728 {
11729   unformat_input_t *i = vam->input;
11730   vl_api_gre_tunnel_dump_t *mp;
11731   vl_api_control_ping_t *mp_ping;
11732   u32 sw_if_index;
11733   u8 sw_if_index_set = 0;
11734   int ret;
11735
11736   /* Parse args required to build the message */
11737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11738     {
11739       if (unformat (i, "sw_if_index %d", &sw_if_index))
11740         sw_if_index_set = 1;
11741       else
11742         break;
11743     }
11744
11745   if (sw_if_index_set == 0)
11746     {
11747       sw_if_index = ~0;
11748     }
11749
11750   if (!vam->json_output)
11751     {
11752       print (vam->ofp, "%11s%24s%24s%6s%14s",
11753              "sw_if_index", "src_address", "dst_address", "teb",
11754              "outer_fib_id");
11755     }
11756
11757   /* Get list of gre-tunnel interfaces */
11758   M (GRE_TUNNEL_DUMP, mp);
11759
11760   mp->sw_if_index = htonl (sw_if_index);
11761
11762   S (mp);
11763
11764   /* Use a control ping for synchronization */
11765   M (CONTROL_PING, mp_ping);
11766   S (mp_ping);
11767
11768   W (ret);
11769   return ret;
11770 }
11771
11772 static int
11773 api_l2_fib_clear_table (vat_main_t * vam)
11774 {
11775 //  unformat_input_t * i = vam->input;
11776   vl_api_l2_fib_clear_table_t *mp;
11777   int ret;
11778
11779   M (L2_FIB_CLEAR_TABLE, mp);
11780
11781   S (mp);
11782   W (ret);
11783   return ret;
11784 }
11785
11786 static int
11787 api_l2_interface_efp_filter (vat_main_t * vam)
11788 {
11789   unformat_input_t *i = vam->input;
11790   vl_api_l2_interface_efp_filter_t *mp;
11791   u32 sw_if_index;
11792   u8 enable = 1;
11793   u8 sw_if_index_set = 0;
11794   int ret;
11795
11796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11797     {
11798       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11799         sw_if_index_set = 1;
11800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11801         sw_if_index_set = 1;
11802       else if (unformat (i, "enable"))
11803         enable = 1;
11804       else if (unformat (i, "disable"))
11805         enable = 0;
11806       else
11807         {
11808           clib_warning ("parse error '%U'", format_unformat_error, i);
11809           return -99;
11810         }
11811     }
11812
11813   if (sw_if_index_set == 0)
11814     {
11815       errmsg ("missing sw_if_index");
11816       return -99;
11817     }
11818
11819   M (L2_INTERFACE_EFP_FILTER, mp);
11820
11821   mp->sw_if_index = ntohl (sw_if_index);
11822   mp->enable_disable = enable;
11823
11824   S (mp);
11825   W (ret);
11826   return ret;
11827 }
11828
11829 #define foreach_vtr_op                          \
11830 _("disable",  L2_VTR_DISABLED)                  \
11831 _("push-1",  L2_VTR_PUSH_1)                     \
11832 _("push-2",  L2_VTR_PUSH_2)                     \
11833 _("pop-1",  L2_VTR_POP_1)                       \
11834 _("pop-2",  L2_VTR_POP_2)                       \
11835 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11836 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11837 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11838 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11839
11840 static int
11841 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11842 {
11843   unformat_input_t *i = vam->input;
11844   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11845   u32 sw_if_index;
11846   u8 sw_if_index_set = 0;
11847   u8 vtr_op_set = 0;
11848   u32 vtr_op = 0;
11849   u32 push_dot1q = 1;
11850   u32 tag1 = ~0;
11851   u32 tag2 = ~0;
11852   int ret;
11853
11854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11855     {
11856       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11857         sw_if_index_set = 1;
11858       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11859         sw_if_index_set = 1;
11860       else if (unformat (i, "vtr_op %d", &vtr_op))
11861         vtr_op_set = 1;
11862 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11863       foreach_vtr_op
11864 #undef _
11865         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11866         ;
11867       else if (unformat (i, "tag1 %d", &tag1))
11868         ;
11869       else if (unformat (i, "tag2 %d", &tag2))
11870         ;
11871       else
11872         {
11873           clib_warning ("parse error '%U'", format_unformat_error, i);
11874           return -99;
11875         }
11876     }
11877
11878   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11879     {
11880       errmsg ("missing vtr operation or sw_if_index");
11881       return -99;
11882     }
11883
11884   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11885   mp->sw_if_index = ntohl (sw_if_index);
11886   mp->vtr_op = ntohl (vtr_op);
11887   mp->push_dot1q = ntohl (push_dot1q);
11888   mp->tag1 = ntohl (tag1);
11889   mp->tag2 = ntohl (tag2);
11890
11891   S (mp);
11892   W (ret);
11893   return ret;
11894 }
11895
11896 static int
11897 api_create_vhost_user_if (vat_main_t * vam)
11898 {
11899   unformat_input_t *i = vam->input;
11900   vl_api_create_vhost_user_if_t *mp;
11901   u8 *file_name;
11902   u8 is_server = 0;
11903   u8 file_name_set = 0;
11904   u32 custom_dev_instance = ~0;
11905   u8 hwaddr[6];
11906   u8 use_custom_mac = 0;
11907   u8 *tag = 0;
11908   int ret;
11909
11910   /* Shut up coverity */
11911   memset (hwaddr, 0, sizeof (hwaddr));
11912
11913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11914     {
11915       if (unformat (i, "socket %s", &file_name))
11916         {
11917           file_name_set = 1;
11918         }
11919       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11920         ;
11921       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11922         use_custom_mac = 1;
11923       else if (unformat (i, "server"))
11924         is_server = 1;
11925       else if (unformat (i, "tag %s", &tag))
11926         ;
11927       else
11928         break;
11929     }
11930
11931   if (file_name_set == 0)
11932     {
11933       errmsg ("missing socket file name");
11934       return -99;
11935     }
11936
11937   if (vec_len (file_name) > 255)
11938     {
11939       errmsg ("socket file name too long");
11940       return -99;
11941     }
11942   vec_add1 (file_name, 0);
11943
11944   M (CREATE_VHOST_USER_IF, mp);
11945
11946   mp->is_server = is_server;
11947   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11948   vec_free (file_name);
11949   if (custom_dev_instance != ~0)
11950     {
11951       mp->renumber = 1;
11952       mp->custom_dev_instance = ntohl (custom_dev_instance);
11953     }
11954   mp->use_custom_mac = use_custom_mac;
11955   clib_memcpy (mp->mac_address, hwaddr, 6);
11956   if (tag)
11957     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11958   vec_free (tag);
11959
11960   S (mp);
11961   W (ret);
11962   return ret;
11963 }
11964
11965 static int
11966 api_modify_vhost_user_if (vat_main_t * vam)
11967 {
11968   unformat_input_t *i = vam->input;
11969   vl_api_modify_vhost_user_if_t *mp;
11970   u8 *file_name;
11971   u8 is_server = 0;
11972   u8 file_name_set = 0;
11973   u32 custom_dev_instance = ~0;
11974   u8 sw_if_index_set = 0;
11975   u32 sw_if_index = (u32) ~ 0;
11976   int ret;
11977
11978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11979     {
11980       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11981         sw_if_index_set = 1;
11982       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11983         sw_if_index_set = 1;
11984       else if (unformat (i, "socket %s", &file_name))
11985         {
11986           file_name_set = 1;
11987         }
11988       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11989         ;
11990       else if (unformat (i, "server"))
11991         is_server = 1;
11992       else
11993         break;
11994     }
11995
11996   if (sw_if_index_set == 0)
11997     {
11998       errmsg ("missing sw_if_index or interface name");
11999       return -99;
12000     }
12001
12002   if (file_name_set == 0)
12003     {
12004       errmsg ("missing socket file name");
12005       return -99;
12006     }
12007
12008   if (vec_len (file_name) > 255)
12009     {
12010       errmsg ("socket file name too long");
12011       return -99;
12012     }
12013   vec_add1 (file_name, 0);
12014
12015   M (MODIFY_VHOST_USER_IF, mp);
12016
12017   mp->sw_if_index = ntohl (sw_if_index);
12018   mp->is_server = is_server;
12019   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12020   vec_free (file_name);
12021   if (custom_dev_instance != ~0)
12022     {
12023       mp->renumber = 1;
12024       mp->custom_dev_instance = ntohl (custom_dev_instance);
12025     }
12026
12027   S (mp);
12028   W (ret);
12029   return ret;
12030 }
12031
12032 static int
12033 api_delete_vhost_user_if (vat_main_t * vam)
12034 {
12035   unformat_input_t *i = vam->input;
12036   vl_api_delete_vhost_user_if_t *mp;
12037   u32 sw_if_index = ~0;
12038   u8 sw_if_index_set = 0;
12039   int ret;
12040
12041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12042     {
12043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12044         sw_if_index_set = 1;
12045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12046         sw_if_index_set = 1;
12047       else
12048         break;
12049     }
12050
12051   if (sw_if_index_set == 0)
12052     {
12053       errmsg ("missing sw_if_index or interface name");
12054       return -99;
12055     }
12056
12057
12058   M (DELETE_VHOST_USER_IF, mp);
12059
12060   mp->sw_if_index = ntohl (sw_if_index);
12061
12062   S (mp);
12063   W (ret);
12064   return ret;
12065 }
12066
12067 static void vl_api_sw_interface_vhost_user_details_t_handler
12068   (vl_api_sw_interface_vhost_user_details_t * mp)
12069 {
12070   vat_main_t *vam = &vat_main;
12071
12072   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12073          (char *) mp->interface_name,
12074          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12075          clib_net_to_host_u64 (mp->features), mp->is_server,
12076          ntohl (mp->num_regions), (char *) mp->sock_filename);
12077   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12078 }
12079
12080 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12081   (vl_api_sw_interface_vhost_user_details_t * mp)
12082 {
12083   vat_main_t *vam = &vat_main;
12084   vat_json_node_t *node = NULL;
12085
12086   if (VAT_JSON_ARRAY != vam->json_tree.type)
12087     {
12088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12089       vat_json_init_array (&vam->json_tree);
12090     }
12091   node = vat_json_array_add (&vam->json_tree);
12092
12093   vat_json_init_object (node);
12094   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12095   vat_json_object_add_string_copy (node, "interface_name",
12096                                    mp->interface_name);
12097   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12098                             ntohl (mp->virtio_net_hdr_sz));
12099   vat_json_object_add_uint (node, "features",
12100                             clib_net_to_host_u64 (mp->features));
12101   vat_json_object_add_uint (node, "is_server", mp->is_server);
12102   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12103   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12104   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12105 }
12106
12107 static int
12108 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12109 {
12110   vl_api_sw_interface_vhost_user_dump_t *mp;
12111   vl_api_control_ping_t *mp_ping;
12112   int ret;
12113   print (vam->ofp,
12114          "Interface name            idx hdr_sz features server regions filename");
12115
12116   /* Get list of vhost-user interfaces */
12117   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12118   S (mp);
12119
12120   /* Use a control ping for synchronization */
12121   M (CONTROL_PING, mp_ping);
12122   S (mp_ping);
12123
12124   W (ret);
12125   return ret;
12126 }
12127
12128 static int
12129 api_show_version (vat_main_t * vam)
12130 {
12131   vl_api_show_version_t *mp;
12132   int ret;
12133
12134   M (SHOW_VERSION, mp);
12135
12136   S (mp);
12137   W (ret);
12138   return ret;
12139 }
12140
12141
12142 static int
12143 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12144 {
12145   unformat_input_t *line_input = vam->input;
12146   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12147   ip4_address_t local4, remote4;
12148   ip6_address_t local6, remote6;
12149   u8 is_add = 1;
12150   u8 ipv4_set = 0, ipv6_set = 0;
12151   u8 local_set = 0;
12152   u8 remote_set = 0;
12153   u8 grp_set = 0;
12154   u32 mcast_sw_if_index = ~0;
12155   u32 encap_vrf_id = 0;
12156   u32 decap_vrf_id = 0;
12157   u8 protocol = ~0;
12158   u32 vni;
12159   u8 vni_set = 0;
12160   int ret;
12161
12162   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12163   memset (&local4, 0, sizeof local4);
12164   memset (&remote4, 0, sizeof remote4);
12165   memset (&local6, 0, sizeof local6);
12166   memset (&remote6, 0, sizeof remote6);
12167
12168   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12169     {
12170       if (unformat (line_input, "del"))
12171         is_add = 0;
12172       else if (unformat (line_input, "local %U",
12173                          unformat_ip4_address, &local4))
12174         {
12175           local_set = 1;
12176           ipv4_set = 1;
12177         }
12178       else if (unformat (line_input, "remote %U",
12179                          unformat_ip4_address, &remote4))
12180         {
12181           remote_set = 1;
12182           ipv4_set = 1;
12183         }
12184       else if (unformat (line_input, "local %U",
12185                          unformat_ip6_address, &local6))
12186         {
12187           local_set = 1;
12188           ipv6_set = 1;
12189         }
12190       else if (unformat (line_input, "remote %U",
12191                          unformat_ip6_address, &remote6))
12192         {
12193           remote_set = 1;
12194           ipv6_set = 1;
12195         }
12196       else if (unformat (line_input, "group %U %U",
12197                          unformat_ip4_address, &remote4,
12198                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12199         {
12200           grp_set = remote_set = 1;
12201           ipv4_set = 1;
12202         }
12203       else if (unformat (line_input, "group %U",
12204                          unformat_ip4_address, &remote4))
12205         {
12206           grp_set = remote_set = 1;
12207           ipv4_set = 1;
12208         }
12209       else if (unformat (line_input, "group %U %U",
12210                          unformat_ip6_address, &remote6,
12211                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12212         {
12213           grp_set = remote_set = 1;
12214           ipv6_set = 1;
12215         }
12216       else if (unformat (line_input, "group %U",
12217                          unformat_ip6_address, &remote6))
12218         {
12219           grp_set = remote_set = 1;
12220           ipv6_set = 1;
12221         }
12222       else
12223         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12224         ;
12225       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12226         ;
12227       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12228         ;
12229       else if (unformat (line_input, "vni %d", &vni))
12230         vni_set = 1;
12231       else if (unformat (line_input, "next-ip4"))
12232         protocol = 1;
12233       else if (unformat (line_input, "next-ip6"))
12234         protocol = 2;
12235       else if (unformat (line_input, "next-ethernet"))
12236         protocol = 3;
12237       else if (unformat (line_input, "next-nsh"))
12238         protocol = 4;
12239       else
12240         {
12241           errmsg ("parse error '%U'", format_unformat_error, line_input);
12242           return -99;
12243         }
12244     }
12245
12246   if (local_set == 0)
12247     {
12248       errmsg ("tunnel local address not specified");
12249       return -99;
12250     }
12251   if (remote_set == 0)
12252     {
12253       errmsg ("tunnel remote address not specified");
12254       return -99;
12255     }
12256   if (grp_set && mcast_sw_if_index == ~0)
12257     {
12258       errmsg ("tunnel nonexistent multicast device");
12259       return -99;
12260     }
12261   if (ipv4_set && ipv6_set)
12262     {
12263       errmsg ("both IPv4 and IPv6 addresses specified");
12264       return -99;
12265     }
12266
12267   if (vni_set == 0)
12268     {
12269       errmsg ("vni not specified");
12270       return -99;
12271     }
12272
12273   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12274
12275
12276   if (ipv6_set)
12277     {
12278       clib_memcpy (&mp->local, &local6, sizeof (local6));
12279       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12280     }
12281   else
12282     {
12283       clib_memcpy (&mp->local, &local4, sizeof (local4));
12284       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12285     }
12286
12287   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12288   mp->encap_vrf_id = ntohl (encap_vrf_id);
12289   mp->decap_vrf_id = ntohl (decap_vrf_id);
12290   mp->protocol = protocol;
12291   mp->vni = ntohl (vni);
12292   mp->is_add = is_add;
12293   mp->is_ipv6 = ipv6_set;
12294
12295   S (mp);
12296   W (ret);
12297   return ret;
12298 }
12299
12300 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12301   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12302 {
12303   vat_main_t *vam = &vat_main;
12304   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12305   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12306
12307   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12308          ntohl (mp->sw_if_index),
12309          format_ip46_address, &local, IP46_TYPE_ANY,
12310          format_ip46_address, &remote, IP46_TYPE_ANY,
12311          ntohl (mp->vni), mp->protocol,
12312          ntohl (mp->mcast_sw_if_index),
12313          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12314 }
12315
12316
12317 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12318   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12319 {
12320   vat_main_t *vam = &vat_main;
12321   vat_json_node_t *node = NULL;
12322   struct in_addr ip4;
12323   struct in6_addr ip6;
12324
12325   if (VAT_JSON_ARRAY != vam->json_tree.type)
12326     {
12327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12328       vat_json_init_array (&vam->json_tree);
12329     }
12330   node = vat_json_array_add (&vam->json_tree);
12331
12332   vat_json_init_object (node);
12333   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12334   if (mp->is_ipv6)
12335     {
12336       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12337       vat_json_object_add_ip6 (node, "local", ip6);
12338       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12339       vat_json_object_add_ip6 (node, "remote", ip6);
12340     }
12341   else
12342     {
12343       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12344       vat_json_object_add_ip4 (node, "local", ip4);
12345       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12346       vat_json_object_add_ip4 (node, "remote", ip4);
12347     }
12348   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12349   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12350   vat_json_object_add_uint (node, "mcast_sw_if_index",
12351                             ntohl (mp->mcast_sw_if_index));
12352   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12353   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12354   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12355 }
12356
12357 static int
12358 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12359 {
12360   unformat_input_t *i = vam->input;
12361   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12362   vl_api_control_ping_t *mp_ping;
12363   u32 sw_if_index;
12364   u8 sw_if_index_set = 0;
12365   int ret;
12366
12367   /* Parse args required to build the message */
12368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12369     {
12370       if (unformat (i, "sw_if_index %d", &sw_if_index))
12371         sw_if_index_set = 1;
12372       else
12373         break;
12374     }
12375
12376   if (sw_if_index_set == 0)
12377     {
12378       sw_if_index = ~0;
12379     }
12380
12381   if (!vam->json_output)
12382     {
12383       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12384              "sw_if_index", "local", "remote", "vni",
12385              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12386     }
12387
12388   /* Get list of vxlan-tunnel interfaces */
12389   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12390
12391   mp->sw_if_index = htonl (sw_if_index);
12392
12393   S (mp);
12394
12395   /* Use a control ping for synchronization */
12396   M (CONTROL_PING, mp_ping);
12397   S (mp_ping);
12398
12399   W (ret);
12400   return ret;
12401 }
12402
12403
12404 u8 *
12405 format_l2_fib_mac_address (u8 * s, va_list * args)
12406 {
12407   u8 *a = va_arg (*args, u8 *);
12408
12409   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12410                  a[2], a[3], a[4], a[5], a[6], a[7]);
12411 }
12412
12413 static void vl_api_l2_fib_table_details_t_handler
12414   (vl_api_l2_fib_table_details_t * mp)
12415 {
12416   vat_main_t *vam = &vat_main;
12417
12418   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12419          "       %d       %d     %d",
12420          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12421          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12422          mp->bvi_mac);
12423 }
12424
12425 static void vl_api_l2_fib_table_details_t_handler_json
12426   (vl_api_l2_fib_table_details_t * mp)
12427 {
12428   vat_main_t *vam = &vat_main;
12429   vat_json_node_t *node = NULL;
12430
12431   if (VAT_JSON_ARRAY != vam->json_tree.type)
12432     {
12433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12434       vat_json_init_array (&vam->json_tree);
12435     }
12436   node = vat_json_array_add (&vam->json_tree);
12437
12438   vat_json_init_object (node);
12439   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12440   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12441   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12442   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12443   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12444   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12445 }
12446
12447 static int
12448 api_l2_fib_table_dump (vat_main_t * vam)
12449 {
12450   unformat_input_t *i = vam->input;
12451   vl_api_l2_fib_table_dump_t *mp;
12452   vl_api_control_ping_t *mp_ping;
12453   u32 bd_id;
12454   u8 bd_id_set = 0;
12455   int ret;
12456
12457   /* Parse args required to build the message */
12458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12459     {
12460       if (unformat (i, "bd_id %d", &bd_id))
12461         bd_id_set = 1;
12462       else
12463         break;
12464     }
12465
12466   if (bd_id_set == 0)
12467     {
12468       errmsg ("missing bridge domain");
12469       return -99;
12470     }
12471
12472   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12473
12474   /* Get list of l2 fib entries */
12475   M (L2_FIB_TABLE_DUMP, mp);
12476
12477   mp->bd_id = ntohl (bd_id);
12478   S (mp);
12479
12480   /* Use a control ping for synchronization */
12481   M (CONTROL_PING, mp_ping);
12482   S (mp_ping);
12483
12484   W (ret);
12485   return ret;
12486 }
12487
12488
12489 static int
12490 api_interface_name_renumber (vat_main_t * vam)
12491 {
12492   unformat_input_t *line_input = vam->input;
12493   vl_api_interface_name_renumber_t *mp;
12494   u32 sw_if_index = ~0;
12495   u32 new_show_dev_instance = ~0;
12496   int ret;
12497
12498   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12499     {
12500       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12501                     &sw_if_index))
12502         ;
12503       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12504         ;
12505       else if (unformat (line_input, "new_show_dev_instance %d",
12506                          &new_show_dev_instance))
12507         ;
12508       else
12509         break;
12510     }
12511
12512   if (sw_if_index == ~0)
12513     {
12514       errmsg ("missing interface name or sw_if_index");
12515       return -99;
12516     }
12517
12518   if (new_show_dev_instance == ~0)
12519     {
12520       errmsg ("missing new_show_dev_instance");
12521       return -99;
12522     }
12523
12524   M (INTERFACE_NAME_RENUMBER, mp);
12525
12526   mp->sw_if_index = ntohl (sw_if_index);
12527   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12528
12529   S (mp);
12530   W (ret);
12531   return ret;
12532 }
12533
12534 static int
12535 api_want_ip4_arp_events (vat_main_t * vam)
12536 {
12537   unformat_input_t *line_input = vam->input;
12538   vl_api_want_ip4_arp_events_t *mp;
12539   ip4_address_t address;
12540   int address_set = 0;
12541   u32 enable_disable = 1;
12542   int ret;
12543
12544   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12545     {
12546       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12547         address_set = 1;
12548       else if (unformat (line_input, "del"))
12549         enable_disable = 0;
12550       else
12551         break;
12552     }
12553
12554   if (address_set == 0)
12555     {
12556       errmsg ("missing addresses");
12557       return -99;
12558     }
12559
12560   M (WANT_IP4_ARP_EVENTS, mp);
12561   mp->enable_disable = enable_disable;
12562   mp->pid = htonl (getpid ());
12563   mp->address = address.as_u32;
12564
12565   S (mp);
12566   W (ret);
12567   return ret;
12568 }
12569
12570 static int
12571 api_want_ip6_nd_events (vat_main_t * vam)
12572 {
12573   unformat_input_t *line_input = vam->input;
12574   vl_api_want_ip6_nd_events_t *mp;
12575   ip6_address_t address;
12576   int address_set = 0;
12577   u32 enable_disable = 1;
12578   int ret;
12579
12580   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12581     {
12582       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12583         address_set = 1;
12584       else if (unformat (line_input, "del"))
12585         enable_disable = 0;
12586       else
12587         break;
12588     }
12589
12590   if (address_set == 0)
12591     {
12592       errmsg ("missing addresses");
12593       return -99;
12594     }
12595
12596   M (WANT_IP6_ND_EVENTS, mp);
12597   mp->enable_disable = enable_disable;
12598   mp->pid = htonl (getpid ());
12599   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12600
12601   S (mp);
12602   W (ret);
12603   return ret;
12604 }
12605
12606 static int
12607 api_want_l2_macs_events (vat_main_t * vam)
12608 {
12609   unformat_input_t *line_input = vam->input;
12610   vl_api_want_l2_macs_events_t *mp;
12611   u8 enable_disable = 1;
12612   u32 scan_delay = 0;
12613   u32 max_macs_in_event = 0;
12614   u32 learn_limit = 0;
12615   int ret;
12616
12617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12618     {
12619       if (unformat (line_input, "learn-limit %d", &learn_limit))
12620         ;
12621       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12622         ;
12623       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12624         ;
12625       else if (unformat (line_input, "disable"))
12626         enable_disable = 0;
12627       else
12628         break;
12629     }
12630
12631   M (WANT_L2_MACS_EVENTS, mp);
12632   mp->enable_disable = enable_disable;
12633   mp->pid = htonl (getpid ());
12634   mp->learn_limit = htonl (learn_limit);
12635   mp->scan_delay = (u8) scan_delay;
12636   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12637   S (mp);
12638   W (ret);
12639   return ret;
12640 }
12641
12642 static int
12643 api_input_acl_set_interface (vat_main_t * vam)
12644 {
12645   unformat_input_t *i = vam->input;
12646   vl_api_input_acl_set_interface_t *mp;
12647   u32 sw_if_index;
12648   int sw_if_index_set;
12649   u32 ip4_table_index = ~0;
12650   u32 ip6_table_index = ~0;
12651   u32 l2_table_index = ~0;
12652   u8 is_add = 1;
12653   int ret;
12654
12655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12656     {
12657       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12658         sw_if_index_set = 1;
12659       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12660         sw_if_index_set = 1;
12661       else if (unformat (i, "del"))
12662         is_add = 0;
12663       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12664         ;
12665       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12666         ;
12667       else if (unformat (i, "l2-table %d", &l2_table_index))
12668         ;
12669       else
12670         {
12671           clib_warning ("parse error '%U'", format_unformat_error, i);
12672           return -99;
12673         }
12674     }
12675
12676   if (sw_if_index_set == 0)
12677     {
12678       errmsg ("missing interface name or sw_if_index");
12679       return -99;
12680     }
12681
12682   M (INPUT_ACL_SET_INTERFACE, mp);
12683
12684   mp->sw_if_index = ntohl (sw_if_index);
12685   mp->ip4_table_index = ntohl (ip4_table_index);
12686   mp->ip6_table_index = ntohl (ip6_table_index);
12687   mp->l2_table_index = ntohl (l2_table_index);
12688   mp->is_add = is_add;
12689
12690   S (mp);
12691   W (ret);
12692   return ret;
12693 }
12694
12695 static int
12696 api_ip_address_dump (vat_main_t * vam)
12697 {
12698   unformat_input_t *i = vam->input;
12699   vl_api_ip_address_dump_t *mp;
12700   vl_api_control_ping_t *mp_ping;
12701   u32 sw_if_index = ~0;
12702   u8 sw_if_index_set = 0;
12703   u8 ipv4_set = 0;
12704   u8 ipv6_set = 0;
12705   int ret;
12706
12707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12708     {
12709       if (unformat (i, "sw_if_index %d", &sw_if_index))
12710         sw_if_index_set = 1;
12711       else
12712         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12713         sw_if_index_set = 1;
12714       else if (unformat (i, "ipv4"))
12715         ipv4_set = 1;
12716       else if (unformat (i, "ipv6"))
12717         ipv6_set = 1;
12718       else
12719         break;
12720     }
12721
12722   if (ipv4_set && ipv6_set)
12723     {
12724       errmsg ("ipv4 and ipv6 flags cannot be both set");
12725       return -99;
12726     }
12727
12728   if ((!ipv4_set) && (!ipv6_set))
12729     {
12730       errmsg ("no ipv4 nor ipv6 flag set");
12731       return -99;
12732     }
12733
12734   if (sw_if_index_set == 0)
12735     {
12736       errmsg ("missing interface name or sw_if_index");
12737       return -99;
12738     }
12739
12740   vam->current_sw_if_index = sw_if_index;
12741   vam->is_ipv6 = ipv6_set;
12742
12743   M (IP_ADDRESS_DUMP, mp);
12744   mp->sw_if_index = ntohl (sw_if_index);
12745   mp->is_ipv6 = ipv6_set;
12746   S (mp);
12747
12748   /* Use a control ping for synchronization */
12749   M (CONTROL_PING, mp_ping);
12750   S (mp_ping);
12751
12752   W (ret);
12753   return ret;
12754 }
12755
12756 static int
12757 api_ip_dump (vat_main_t * vam)
12758 {
12759   vl_api_ip_dump_t *mp;
12760   vl_api_control_ping_t *mp_ping;
12761   unformat_input_t *in = vam->input;
12762   int ipv4_set = 0;
12763   int ipv6_set = 0;
12764   int is_ipv6;
12765   int i;
12766   int ret;
12767
12768   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12769     {
12770       if (unformat (in, "ipv4"))
12771         ipv4_set = 1;
12772       else if (unformat (in, "ipv6"))
12773         ipv6_set = 1;
12774       else
12775         break;
12776     }
12777
12778   if (ipv4_set && ipv6_set)
12779     {
12780       errmsg ("ipv4 and ipv6 flags cannot be both set");
12781       return -99;
12782     }
12783
12784   if ((!ipv4_set) && (!ipv6_set))
12785     {
12786       errmsg ("no ipv4 nor ipv6 flag set");
12787       return -99;
12788     }
12789
12790   is_ipv6 = ipv6_set;
12791   vam->is_ipv6 = is_ipv6;
12792
12793   /* free old data */
12794   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12795     {
12796       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12797     }
12798   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12799
12800   M (IP_DUMP, mp);
12801   mp->is_ipv6 = ipv6_set;
12802   S (mp);
12803
12804   /* Use a control ping for synchronization */
12805   M (CONTROL_PING, mp_ping);
12806   S (mp_ping);
12807
12808   W (ret);
12809   return ret;
12810 }
12811
12812 static int
12813 api_ipsec_spd_add_del (vat_main_t * vam)
12814 {
12815   unformat_input_t *i = vam->input;
12816   vl_api_ipsec_spd_add_del_t *mp;
12817   u32 spd_id = ~0;
12818   u8 is_add = 1;
12819   int ret;
12820
12821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12822     {
12823       if (unformat (i, "spd_id %d", &spd_id))
12824         ;
12825       else if (unformat (i, "del"))
12826         is_add = 0;
12827       else
12828         {
12829           clib_warning ("parse error '%U'", format_unformat_error, i);
12830           return -99;
12831         }
12832     }
12833   if (spd_id == ~0)
12834     {
12835       errmsg ("spd_id must be set");
12836       return -99;
12837     }
12838
12839   M (IPSEC_SPD_ADD_DEL, mp);
12840
12841   mp->spd_id = ntohl (spd_id);
12842   mp->is_add = is_add;
12843
12844   S (mp);
12845   W (ret);
12846   return ret;
12847 }
12848
12849 static int
12850 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12851 {
12852   unformat_input_t *i = vam->input;
12853   vl_api_ipsec_interface_add_del_spd_t *mp;
12854   u32 sw_if_index;
12855   u8 sw_if_index_set = 0;
12856   u32 spd_id = (u32) ~ 0;
12857   u8 is_add = 1;
12858   int ret;
12859
12860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12861     {
12862       if (unformat (i, "del"))
12863         is_add = 0;
12864       else if (unformat (i, "spd_id %d", &spd_id))
12865         ;
12866       else
12867         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12868         sw_if_index_set = 1;
12869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12870         sw_if_index_set = 1;
12871       else
12872         {
12873           clib_warning ("parse error '%U'", format_unformat_error, i);
12874           return -99;
12875         }
12876
12877     }
12878
12879   if (spd_id == (u32) ~ 0)
12880     {
12881       errmsg ("spd_id must be set");
12882       return -99;
12883     }
12884
12885   if (sw_if_index_set == 0)
12886     {
12887       errmsg ("missing interface name or sw_if_index");
12888       return -99;
12889     }
12890
12891   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12892
12893   mp->spd_id = ntohl (spd_id);
12894   mp->sw_if_index = ntohl (sw_if_index);
12895   mp->is_add = is_add;
12896
12897   S (mp);
12898   W (ret);
12899   return ret;
12900 }
12901
12902 static int
12903 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12904 {
12905   unformat_input_t *i = vam->input;
12906   vl_api_ipsec_spd_add_del_entry_t *mp;
12907   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12908   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12909   i32 priority = 0;
12910   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12911   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12912   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12913   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12914   int ret;
12915
12916   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12917   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12918   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12919   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12920   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12921   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12922
12923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12924     {
12925       if (unformat (i, "del"))
12926         is_add = 0;
12927       if (unformat (i, "outbound"))
12928         is_outbound = 1;
12929       if (unformat (i, "inbound"))
12930         is_outbound = 0;
12931       else if (unformat (i, "spd_id %d", &spd_id))
12932         ;
12933       else if (unformat (i, "sa_id %d", &sa_id))
12934         ;
12935       else if (unformat (i, "priority %d", &priority))
12936         ;
12937       else if (unformat (i, "protocol %d", &protocol))
12938         ;
12939       else if (unformat (i, "lport_start %d", &lport_start))
12940         ;
12941       else if (unformat (i, "lport_stop %d", &lport_stop))
12942         ;
12943       else if (unformat (i, "rport_start %d", &rport_start))
12944         ;
12945       else if (unformat (i, "rport_stop %d", &rport_stop))
12946         ;
12947       else
12948         if (unformat
12949             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12950         {
12951           is_ipv6 = 0;
12952           is_ip_any = 0;
12953         }
12954       else
12955         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12956         {
12957           is_ipv6 = 0;
12958           is_ip_any = 0;
12959         }
12960       else
12961         if (unformat
12962             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12963         {
12964           is_ipv6 = 0;
12965           is_ip_any = 0;
12966         }
12967       else
12968         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12969         {
12970           is_ipv6 = 0;
12971           is_ip_any = 0;
12972         }
12973       else
12974         if (unformat
12975             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12976         {
12977           is_ipv6 = 1;
12978           is_ip_any = 0;
12979         }
12980       else
12981         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12982         {
12983           is_ipv6 = 1;
12984           is_ip_any = 0;
12985         }
12986       else
12987         if (unformat
12988             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12989         {
12990           is_ipv6 = 1;
12991           is_ip_any = 0;
12992         }
12993       else
12994         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12995         {
12996           is_ipv6 = 1;
12997           is_ip_any = 0;
12998         }
12999       else
13000         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13001         {
13002           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13003             {
13004               clib_warning ("unsupported action: 'resolve'");
13005               return -99;
13006             }
13007         }
13008       else
13009         {
13010           clib_warning ("parse error '%U'", format_unformat_error, i);
13011           return -99;
13012         }
13013
13014     }
13015
13016   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13017
13018   mp->spd_id = ntohl (spd_id);
13019   mp->priority = ntohl (priority);
13020   mp->is_outbound = is_outbound;
13021
13022   mp->is_ipv6 = is_ipv6;
13023   if (is_ipv6 || is_ip_any)
13024     {
13025       clib_memcpy (mp->remote_address_start, &raddr6_start,
13026                    sizeof (ip6_address_t));
13027       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13028                    sizeof (ip6_address_t));
13029       clib_memcpy (mp->local_address_start, &laddr6_start,
13030                    sizeof (ip6_address_t));
13031       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13032                    sizeof (ip6_address_t));
13033     }
13034   else
13035     {
13036       clib_memcpy (mp->remote_address_start, &raddr4_start,
13037                    sizeof (ip4_address_t));
13038       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13039                    sizeof (ip4_address_t));
13040       clib_memcpy (mp->local_address_start, &laddr4_start,
13041                    sizeof (ip4_address_t));
13042       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13043                    sizeof (ip4_address_t));
13044     }
13045   mp->protocol = (u8) protocol;
13046   mp->local_port_start = ntohs ((u16) lport_start);
13047   mp->local_port_stop = ntohs ((u16) lport_stop);
13048   mp->remote_port_start = ntohs ((u16) rport_start);
13049   mp->remote_port_stop = ntohs ((u16) rport_stop);
13050   mp->policy = (u8) policy;
13051   mp->sa_id = ntohl (sa_id);
13052   mp->is_add = is_add;
13053   mp->is_ip_any = is_ip_any;
13054   S (mp);
13055   W (ret);
13056   return ret;
13057 }
13058
13059 static int
13060 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13061 {
13062   unformat_input_t *i = vam->input;
13063   vl_api_ipsec_sad_add_del_entry_t *mp;
13064   u32 sad_id = 0, spi = 0;
13065   u8 *ck = 0, *ik = 0;
13066   u8 is_add = 1;
13067
13068   u8 protocol = IPSEC_PROTOCOL_AH;
13069   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13070   u32 crypto_alg = 0, integ_alg = 0;
13071   ip4_address_t tun_src4;
13072   ip4_address_t tun_dst4;
13073   ip6_address_t tun_src6;
13074   ip6_address_t tun_dst6;
13075   int ret;
13076
13077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13078     {
13079       if (unformat (i, "del"))
13080         is_add = 0;
13081       else if (unformat (i, "sad_id %d", &sad_id))
13082         ;
13083       else if (unformat (i, "spi %d", &spi))
13084         ;
13085       else if (unformat (i, "esp"))
13086         protocol = IPSEC_PROTOCOL_ESP;
13087       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13088         {
13089           is_tunnel = 1;
13090           is_tunnel_ipv6 = 0;
13091         }
13092       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13093         {
13094           is_tunnel = 1;
13095           is_tunnel_ipv6 = 0;
13096         }
13097       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13098         {
13099           is_tunnel = 1;
13100           is_tunnel_ipv6 = 1;
13101         }
13102       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13103         {
13104           is_tunnel = 1;
13105           is_tunnel_ipv6 = 1;
13106         }
13107       else
13108         if (unformat
13109             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13110         {
13111           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13112               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13113             {
13114               clib_warning ("unsupported crypto-alg: '%U'",
13115                             format_ipsec_crypto_alg, crypto_alg);
13116               return -99;
13117             }
13118         }
13119       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13120         ;
13121       else
13122         if (unformat
13123             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13124         {
13125           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13126               integ_alg >= IPSEC_INTEG_N_ALG)
13127             {
13128               clib_warning ("unsupported integ-alg: '%U'",
13129                             format_ipsec_integ_alg, integ_alg);
13130               return -99;
13131             }
13132         }
13133       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13134         ;
13135       else
13136         {
13137           clib_warning ("parse error '%U'", format_unformat_error, i);
13138           return -99;
13139         }
13140
13141     }
13142
13143   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13144
13145   mp->sad_id = ntohl (sad_id);
13146   mp->is_add = is_add;
13147   mp->protocol = protocol;
13148   mp->spi = ntohl (spi);
13149   mp->is_tunnel = is_tunnel;
13150   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13151   mp->crypto_algorithm = crypto_alg;
13152   mp->integrity_algorithm = integ_alg;
13153   mp->crypto_key_length = vec_len (ck);
13154   mp->integrity_key_length = vec_len (ik);
13155
13156   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13157     mp->crypto_key_length = sizeof (mp->crypto_key);
13158
13159   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13160     mp->integrity_key_length = sizeof (mp->integrity_key);
13161
13162   if (ck)
13163     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13164   if (ik)
13165     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13166
13167   if (is_tunnel)
13168     {
13169       if (is_tunnel_ipv6)
13170         {
13171           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13172                        sizeof (ip6_address_t));
13173           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13174                        sizeof (ip6_address_t));
13175         }
13176       else
13177         {
13178           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13179                        sizeof (ip4_address_t));
13180           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13181                        sizeof (ip4_address_t));
13182         }
13183     }
13184
13185   S (mp);
13186   W (ret);
13187   return ret;
13188 }
13189
13190 static int
13191 api_ipsec_sa_set_key (vat_main_t * vam)
13192 {
13193   unformat_input_t *i = vam->input;
13194   vl_api_ipsec_sa_set_key_t *mp;
13195   u32 sa_id;
13196   u8 *ck = 0, *ik = 0;
13197   int ret;
13198
13199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13200     {
13201       if (unformat (i, "sa_id %d", &sa_id))
13202         ;
13203       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13204         ;
13205       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13206         ;
13207       else
13208         {
13209           clib_warning ("parse error '%U'", format_unformat_error, i);
13210           return -99;
13211         }
13212     }
13213
13214   M (IPSEC_SA_SET_KEY, mp);
13215
13216   mp->sa_id = ntohl (sa_id);
13217   mp->crypto_key_length = vec_len (ck);
13218   mp->integrity_key_length = vec_len (ik);
13219
13220   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13221     mp->crypto_key_length = sizeof (mp->crypto_key);
13222
13223   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13224     mp->integrity_key_length = sizeof (mp->integrity_key);
13225
13226   if (ck)
13227     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13228   if (ik)
13229     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13230
13231   S (mp);
13232   W (ret);
13233   return ret;
13234 }
13235
13236 static int
13237 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13238 {
13239   unformat_input_t *i = vam->input;
13240   vl_api_ipsec_tunnel_if_add_del_t *mp;
13241   u32 local_spi = 0, remote_spi = 0;
13242   u32 crypto_alg = 0, integ_alg = 0;
13243   u8 *lck = NULL, *rck = NULL;
13244   u8 *lik = NULL, *rik = NULL;
13245   ip4_address_t local_ip = { {0} };
13246   ip4_address_t remote_ip = { {0} };
13247   u8 is_add = 1;
13248   u8 esn = 0;
13249   u8 anti_replay = 0;
13250   int ret;
13251
13252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13253     {
13254       if (unformat (i, "del"))
13255         is_add = 0;
13256       else if (unformat (i, "esn"))
13257         esn = 1;
13258       else if (unformat (i, "anti_replay"))
13259         anti_replay = 1;
13260       else if (unformat (i, "local_spi %d", &local_spi))
13261         ;
13262       else if (unformat (i, "remote_spi %d", &remote_spi))
13263         ;
13264       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13265         ;
13266       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13267         ;
13268       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13269         ;
13270       else
13271         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13272         ;
13273       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13274         ;
13275       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13276         ;
13277       else
13278         if (unformat
13279             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13280         {
13281           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13282               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13283             {
13284               errmsg ("unsupported crypto-alg: '%U'\n",
13285                       format_ipsec_crypto_alg, crypto_alg);
13286               return -99;
13287             }
13288         }
13289       else
13290         if (unformat
13291             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13292         {
13293           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13294               integ_alg >= IPSEC_INTEG_N_ALG)
13295             {
13296               errmsg ("unsupported integ-alg: '%U'\n",
13297                       format_ipsec_integ_alg, integ_alg);
13298               return -99;
13299             }
13300         }
13301       else
13302         {
13303           errmsg ("parse error '%U'\n", format_unformat_error, i);
13304           return -99;
13305         }
13306     }
13307
13308   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13309
13310   mp->is_add = is_add;
13311   mp->esn = esn;
13312   mp->anti_replay = anti_replay;
13313
13314   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13315   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13316
13317   mp->local_spi = htonl (local_spi);
13318   mp->remote_spi = htonl (remote_spi);
13319   mp->crypto_alg = (u8) crypto_alg;
13320
13321   mp->local_crypto_key_len = 0;
13322   if (lck)
13323     {
13324       mp->local_crypto_key_len = vec_len (lck);
13325       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13326         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13327       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13328     }
13329
13330   mp->remote_crypto_key_len = 0;
13331   if (rck)
13332     {
13333       mp->remote_crypto_key_len = vec_len (rck);
13334       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13335         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13336       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13337     }
13338
13339   mp->integ_alg = (u8) integ_alg;
13340
13341   mp->local_integ_key_len = 0;
13342   if (lik)
13343     {
13344       mp->local_integ_key_len = vec_len (lik);
13345       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13346         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13347       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13348     }
13349
13350   mp->remote_integ_key_len = 0;
13351   if (rik)
13352     {
13353       mp->remote_integ_key_len = vec_len (rik);
13354       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13355         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13356       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13357     }
13358
13359   S (mp);
13360   W (ret);
13361   return ret;
13362 }
13363
13364 static int
13365 api_ikev2_profile_add_del (vat_main_t * vam)
13366 {
13367   unformat_input_t *i = vam->input;
13368   vl_api_ikev2_profile_add_del_t *mp;
13369   u8 is_add = 1;
13370   u8 *name = 0;
13371   int ret;
13372
13373   const char *valid_chars = "a-zA-Z0-9_";
13374
13375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13376     {
13377       if (unformat (i, "del"))
13378         is_add = 0;
13379       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13380         vec_add1 (name, 0);
13381       else
13382         {
13383           errmsg ("parse error '%U'", format_unformat_error, i);
13384           return -99;
13385         }
13386     }
13387
13388   if (!vec_len (name))
13389     {
13390       errmsg ("profile name must be specified");
13391       return -99;
13392     }
13393
13394   if (vec_len (name) > 64)
13395     {
13396       errmsg ("profile name too long");
13397       return -99;
13398     }
13399
13400   M (IKEV2_PROFILE_ADD_DEL, mp);
13401
13402   clib_memcpy (mp->name, name, vec_len (name));
13403   mp->is_add = is_add;
13404   vec_free (name);
13405
13406   S (mp);
13407   W (ret);
13408   return ret;
13409 }
13410
13411 static int
13412 api_ikev2_profile_set_auth (vat_main_t * vam)
13413 {
13414   unformat_input_t *i = vam->input;
13415   vl_api_ikev2_profile_set_auth_t *mp;
13416   u8 *name = 0;
13417   u8 *data = 0;
13418   u32 auth_method = 0;
13419   u8 is_hex = 0;
13420   int ret;
13421
13422   const char *valid_chars = "a-zA-Z0-9_";
13423
13424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13425     {
13426       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13427         vec_add1 (name, 0);
13428       else if (unformat (i, "auth_method %U",
13429                          unformat_ikev2_auth_method, &auth_method))
13430         ;
13431       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13432         is_hex = 1;
13433       else if (unformat (i, "auth_data %v", &data))
13434         ;
13435       else
13436         {
13437           errmsg ("parse error '%U'", format_unformat_error, i);
13438           return -99;
13439         }
13440     }
13441
13442   if (!vec_len (name))
13443     {
13444       errmsg ("profile name must be specified");
13445       return -99;
13446     }
13447
13448   if (vec_len (name) > 64)
13449     {
13450       errmsg ("profile name too long");
13451       return -99;
13452     }
13453
13454   if (!vec_len (data))
13455     {
13456       errmsg ("auth_data must be specified");
13457       return -99;
13458     }
13459
13460   if (!auth_method)
13461     {
13462       errmsg ("auth_method must be specified");
13463       return -99;
13464     }
13465
13466   M (IKEV2_PROFILE_SET_AUTH, mp);
13467
13468   mp->is_hex = is_hex;
13469   mp->auth_method = (u8) auth_method;
13470   mp->data_len = vec_len (data);
13471   clib_memcpy (mp->name, name, vec_len (name));
13472   clib_memcpy (mp->data, data, vec_len (data));
13473   vec_free (name);
13474   vec_free (data);
13475
13476   S (mp);
13477   W (ret);
13478   return ret;
13479 }
13480
13481 static int
13482 api_ikev2_profile_set_id (vat_main_t * vam)
13483 {
13484   unformat_input_t *i = vam->input;
13485   vl_api_ikev2_profile_set_id_t *mp;
13486   u8 *name = 0;
13487   u8 *data = 0;
13488   u8 is_local = 0;
13489   u32 id_type = 0;
13490   ip4_address_t ip4;
13491   int ret;
13492
13493   const char *valid_chars = "a-zA-Z0-9_";
13494
13495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13496     {
13497       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13498         vec_add1 (name, 0);
13499       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13500         ;
13501       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13502         {
13503           data = vec_new (u8, 4);
13504           clib_memcpy (data, ip4.as_u8, 4);
13505         }
13506       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13507         ;
13508       else if (unformat (i, "id_data %v", &data))
13509         ;
13510       else if (unformat (i, "local"))
13511         is_local = 1;
13512       else if (unformat (i, "remote"))
13513         is_local = 0;
13514       else
13515         {
13516           errmsg ("parse error '%U'", format_unformat_error, i);
13517           return -99;
13518         }
13519     }
13520
13521   if (!vec_len (name))
13522     {
13523       errmsg ("profile name must be specified");
13524       return -99;
13525     }
13526
13527   if (vec_len (name) > 64)
13528     {
13529       errmsg ("profile name too long");
13530       return -99;
13531     }
13532
13533   if (!vec_len (data))
13534     {
13535       errmsg ("id_data must be specified");
13536       return -99;
13537     }
13538
13539   if (!id_type)
13540     {
13541       errmsg ("id_type must be specified");
13542       return -99;
13543     }
13544
13545   M (IKEV2_PROFILE_SET_ID, mp);
13546
13547   mp->is_local = is_local;
13548   mp->id_type = (u8) id_type;
13549   mp->data_len = vec_len (data);
13550   clib_memcpy (mp->name, name, vec_len (name));
13551   clib_memcpy (mp->data, data, vec_len (data));
13552   vec_free (name);
13553   vec_free (data);
13554
13555   S (mp);
13556   W (ret);
13557   return ret;
13558 }
13559
13560 static int
13561 api_ikev2_profile_set_ts (vat_main_t * vam)
13562 {
13563   unformat_input_t *i = vam->input;
13564   vl_api_ikev2_profile_set_ts_t *mp;
13565   u8 *name = 0;
13566   u8 is_local = 0;
13567   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13568   ip4_address_t start_addr, end_addr;
13569
13570   const char *valid_chars = "a-zA-Z0-9_";
13571   int ret;
13572
13573   start_addr.as_u32 = 0;
13574   end_addr.as_u32 = (u32) ~ 0;
13575
13576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13577     {
13578       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13579         vec_add1 (name, 0);
13580       else if (unformat (i, "protocol %d", &proto))
13581         ;
13582       else if (unformat (i, "start_port %d", &start_port))
13583         ;
13584       else if (unformat (i, "end_port %d", &end_port))
13585         ;
13586       else
13587         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13588         ;
13589       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13590         ;
13591       else if (unformat (i, "local"))
13592         is_local = 1;
13593       else if (unformat (i, "remote"))
13594         is_local = 0;
13595       else
13596         {
13597           errmsg ("parse error '%U'", format_unformat_error, i);
13598           return -99;
13599         }
13600     }
13601
13602   if (!vec_len (name))
13603     {
13604       errmsg ("profile name must be specified");
13605       return -99;
13606     }
13607
13608   if (vec_len (name) > 64)
13609     {
13610       errmsg ("profile name too long");
13611       return -99;
13612     }
13613
13614   M (IKEV2_PROFILE_SET_TS, mp);
13615
13616   mp->is_local = is_local;
13617   mp->proto = (u8) proto;
13618   mp->start_port = (u16) start_port;
13619   mp->end_port = (u16) end_port;
13620   mp->start_addr = start_addr.as_u32;
13621   mp->end_addr = end_addr.as_u32;
13622   clib_memcpy (mp->name, name, vec_len (name));
13623   vec_free (name);
13624
13625   S (mp);
13626   W (ret);
13627   return ret;
13628 }
13629
13630 static int
13631 api_ikev2_set_local_key (vat_main_t * vam)
13632 {
13633   unformat_input_t *i = vam->input;
13634   vl_api_ikev2_set_local_key_t *mp;
13635   u8 *file = 0;
13636   int ret;
13637
13638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13639     {
13640       if (unformat (i, "file %v", &file))
13641         vec_add1 (file, 0);
13642       else
13643         {
13644           errmsg ("parse error '%U'", format_unformat_error, i);
13645           return -99;
13646         }
13647     }
13648
13649   if (!vec_len (file))
13650     {
13651       errmsg ("RSA key file must be specified");
13652       return -99;
13653     }
13654
13655   if (vec_len (file) > 256)
13656     {
13657       errmsg ("file name too long");
13658       return -99;
13659     }
13660
13661   M (IKEV2_SET_LOCAL_KEY, mp);
13662
13663   clib_memcpy (mp->key_file, file, vec_len (file));
13664   vec_free (file);
13665
13666   S (mp);
13667   W (ret);
13668   return ret;
13669 }
13670
13671 static int
13672 api_ikev2_set_responder (vat_main_t * vam)
13673 {
13674   unformat_input_t *i = vam->input;
13675   vl_api_ikev2_set_responder_t *mp;
13676   int ret;
13677   u8 *name = 0;
13678   u32 sw_if_index = ~0;
13679   ip4_address_t address;
13680
13681   const char *valid_chars = "a-zA-Z0-9_";
13682
13683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13684     {
13685       if (unformat
13686           (i, "%U interface %d address %U", unformat_token, valid_chars,
13687            &name, &sw_if_index, unformat_ip4_address, &address))
13688         vec_add1 (name, 0);
13689       else
13690         {
13691           errmsg ("parse error '%U'", format_unformat_error, i);
13692           return -99;
13693         }
13694     }
13695
13696   if (!vec_len (name))
13697     {
13698       errmsg ("profile name must be specified");
13699       return -99;
13700     }
13701
13702   if (vec_len (name) > 64)
13703     {
13704       errmsg ("profile name too long");
13705       return -99;
13706     }
13707
13708   M (IKEV2_SET_RESPONDER, mp);
13709
13710   clib_memcpy (mp->name, name, vec_len (name));
13711   vec_free (name);
13712
13713   mp->sw_if_index = sw_if_index;
13714   clib_memcpy (mp->address, &address, sizeof (address));
13715
13716   S (mp);
13717   W (ret);
13718   return ret;
13719 }
13720
13721 static int
13722 api_ikev2_set_ike_transforms (vat_main_t * vam)
13723 {
13724   unformat_input_t *i = vam->input;
13725   vl_api_ikev2_set_ike_transforms_t *mp;
13726   int ret;
13727   u8 *name = 0;
13728   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13729
13730   const char *valid_chars = "a-zA-Z0-9_";
13731
13732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13733     {
13734       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13735                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13736         vec_add1 (name, 0);
13737       else
13738         {
13739           errmsg ("parse error '%U'", format_unformat_error, i);
13740           return -99;
13741         }
13742     }
13743
13744   if (!vec_len (name))
13745     {
13746       errmsg ("profile name must be specified");
13747       return -99;
13748     }
13749
13750   if (vec_len (name) > 64)
13751     {
13752       errmsg ("profile name too long");
13753       return -99;
13754     }
13755
13756   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13757
13758   clib_memcpy (mp->name, name, vec_len (name));
13759   vec_free (name);
13760   mp->crypto_alg = crypto_alg;
13761   mp->crypto_key_size = crypto_key_size;
13762   mp->integ_alg = integ_alg;
13763   mp->dh_group = dh_group;
13764
13765   S (mp);
13766   W (ret);
13767   return ret;
13768 }
13769
13770
13771 static int
13772 api_ikev2_set_esp_transforms (vat_main_t * vam)
13773 {
13774   unformat_input_t *i = vam->input;
13775   vl_api_ikev2_set_esp_transforms_t *mp;
13776   int ret;
13777   u8 *name = 0;
13778   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13779
13780   const char *valid_chars = "a-zA-Z0-9_";
13781
13782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13783     {
13784       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13785                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13786         vec_add1 (name, 0);
13787       else
13788         {
13789           errmsg ("parse error '%U'", format_unformat_error, i);
13790           return -99;
13791         }
13792     }
13793
13794   if (!vec_len (name))
13795     {
13796       errmsg ("profile name must be specified");
13797       return -99;
13798     }
13799
13800   if (vec_len (name) > 64)
13801     {
13802       errmsg ("profile name too long");
13803       return -99;
13804     }
13805
13806   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13807
13808   clib_memcpy (mp->name, name, vec_len (name));
13809   vec_free (name);
13810   mp->crypto_alg = crypto_alg;
13811   mp->crypto_key_size = crypto_key_size;
13812   mp->integ_alg = integ_alg;
13813   mp->dh_group = dh_group;
13814
13815   S (mp);
13816   W (ret);
13817   return ret;
13818 }
13819
13820 static int
13821 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13822 {
13823   unformat_input_t *i = vam->input;
13824   vl_api_ikev2_set_sa_lifetime_t *mp;
13825   int ret;
13826   u8 *name = 0;
13827   u64 lifetime, lifetime_maxdata;
13828   u32 lifetime_jitter, handover;
13829
13830   const char *valid_chars = "a-zA-Z0-9_";
13831
13832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13833     {
13834       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13835                     &lifetime, &lifetime_jitter, &handover,
13836                     &lifetime_maxdata))
13837         vec_add1 (name, 0);
13838       else
13839         {
13840           errmsg ("parse error '%U'", format_unformat_error, i);
13841           return -99;
13842         }
13843     }
13844
13845   if (!vec_len (name))
13846     {
13847       errmsg ("profile name must be specified");
13848       return -99;
13849     }
13850
13851   if (vec_len (name) > 64)
13852     {
13853       errmsg ("profile name too long");
13854       return -99;
13855     }
13856
13857   M (IKEV2_SET_SA_LIFETIME, mp);
13858
13859   clib_memcpy (mp->name, name, vec_len (name));
13860   vec_free (name);
13861   mp->lifetime = lifetime;
13862   mp->lifetime_jitter = lifetime_jitter;
13863   mp->handover = handover;
13864   mp->lifetime_maxdata = lifetime_maxdata;
13865
13866   S (mp);
13867   W (ret);
13868   return ret;
13869 }
13870
13871 static int
13872 api_ikev2_initiate_sa_init (vat_main_t * vam)
13873 {
13874   unformat_input_t *i = vam->input;
13875   vl_api_ikev2_initiate_sa_init_t *mp;
13876   int ret;
13877   u8 *name = 0;
13878
13879   const char *valid_chars = "a-zA-Z0-9_";
13880
13881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13882     {
13883       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13884         vec_add1 (name, 0);
13885       else
13886         {
13887           errmsg ("parse error '%U'", format_unformat_error, i);
13888           return -99;
13889         }
13890     }
13891
13892   if (!vec_len (name))
13893     {
13894       errmsg ("profile name must be specified");
13895       return -99;
13896     }
13897
13898   if (vec_len (name) > 64)
13899     {
13900       errmsg ("profile name too long");
13901       return -99;
13902     }
13903
13904   M (IKEV2_INITIATE_SA_INIT, mp);
13905
13906   clib_memcpy (mp->name, name, vec_len (name));
13907   vec_free (name);
13908
13909   S (mp);
13910   W (ret);
13911   return ret;
13912 }
13913
13914 static int
13915 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13916 {
13917   unformat_input_t *i = vam->input;
13918   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13919   int ret;
13920   u64 ispi;
13921
13922
13923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13924     {
13925       if (unformat (i, "%lx", &ispi))
13926         ;
13927       else
13928         {
13929           errmsg ("parse error '%U'", format_unformat_error, i);
13930           return -99;
13931         }
13932     }
13933
13934   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13935
13936   mp->ispi = ispi;
13937
13938   S (mp);
13939   W (ret);
13940   return ret;
13941 }
13942
13943 static int
13944 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13945 {
13946   unformat_input_t *i = vam->input;
13947   vl_api_ikev2_initiate_del_child_sa_t *mp;
13948   int ret;
13949   u32 ispi;
13950
13951
13952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13953     {
13954       if (unformat (i, "%x", &ispi))
13955         ;
13956       else
13957         {
13958           errmsg ("parse error '%U'", format_unformat_error, i);
13959           return -99;
13960         }
13961     }
13962
13963   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13964
13965   mp->ispi = ispi;
13966
13967   S (mp);
13968   W (ret);
13969   return ret;
13970 }
13971
13972 static int
13973 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13974 {
13975   unformat_input_t *i = vam->input;
13976   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13977   int ret;
13978   u32 ispi;
13979
13980
13981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13982     {
13983       if (unformat (i, "%x", &ispi))
13984         ;
13985       else
13986         {
13987           errmsg ("parse error '%U'", format_unformat_error, i);
13988           return -99;
13989         }
13990     }
13991
13992   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13993
13994   mp->ispi = ispi;
13995
13996   S (mp);
13997   W (ret);
13998   return ret;
13999 }
14000
14001 /*
14002  * MAP
14003  */
14004 static int
14005 api_map_add_domain (vat_main_t * vam)
14006 {
14007   unformat_input_t *i = vam->input;
14008   vl_api_map_add_domain_t *mp;
14009
14010   ip4_address_t ip4_prefix;
14011   ip6_address_t ip6_prefix;
14012   ip6_address_t ip6_src;
14013   u32 num_m_args = 0;
14014   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14015     0, psid_length = 0;
14016   u8 is_translation = 0;
14017   u32 mtu = 0;
14018   u32 ip6_src_len = 128;
14019   int ret;
14020
14021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14022     {
14023       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14024                     &ip4_prefix, &ip4_prefix_len))
14025         num_m_args++;
14026       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14027                          &ip6_prefix, &ip6_prefix_len))
14028         num_m_args++;
14029       else
14030         if (unformat
14031             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14032              &ip6_src_len))
14033         num_m_args++;
14034       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14035         num_m_args++;
14036       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14037         num_m_args++;
14038       else if (unformat (i, "psid-offset %d", &psid_offset))
14039         num_m_args++;
14040       else if (unformat (i, "psid-len %d", &psid_length))
14041         num_m_args++;
14042       else if (unformat (i, "mtu %d", &mtu))
14043         num_m_args++;
14044       else if (unformat (i, "map-t"))
14045         is_translation = 1;
14046       else
14047         {
14048           clib_warning ("parse error '%U'", format_unformat_error, i);
14049           return -99;
14050         }
14051     }
14052
14053   if (num_m_args < 3)
14054     {
14055       errmsg ("mandatory argument(s) missing");
14056       return -99;
14057     }
14058
14059   /* Construct the API message */
14060   M (MAP_ADD_DOMAIN, mp);
14061
14062   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14063   mp->ip4_prefix_len = ip4_prefix_len;
14064
14065   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14066   mp->ip6_prefix_len = ip6_prefix_len;
14067
14068   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14069   mp->ip6_src_prefix_len = ip6_src_len;
14070
14071   mp->ea_bits_len = ea_bits_len;
14072   mp->psid_offset = psid_offset;
14073   mp->psid_length = psid_length;
14074   mp->is_translation = is_translation;
14075   mp->mtu = htons (mtu);
14076
14077   /* send it... */
14078   S (mp);
14079
14080   /* Wait for a reply, return good/bad news  */
14081   W (ret);
14082   return ret;
14083 }
14084
14085 static int
14086 api_map_del_domain (vat_main_t * vam)
14087 {
14088   unformat_input_t *i = vam->input;
14089   vl_api_map_del_domain_t *mp;
14090
14091   u32 num_m_args = 0;
14092   u32 index;
14093   int ret;
14094
14095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14096     {
14097       if (unformat (i, "index %d", &index))
14098         num_m_args++;
14099       else
14100         {
14101           clib_warning ("parse error '%U'", format_unformat_error, i);
14102           return -99;
14103         }
14104     }
14105
14106   if (num_m_args != 1)
14107     {
14108       errmsg ("mandatory argument(s) missing");
14109       return -99;
14110     }
14111
14112   /* Construct the API message */
14113   M (MAP_DEL_DOMAIN, mp);
14114
14115   mp->index = ntohl (index);
14116
14117   /* send it... */
14118   S (mp);
14119
14120   /* Wait for a reply, return good/bad news  */
14121   W (ret);
14122   return ret;
14123 }
14124
14125 static int
14126 api_map_add_del_rule (vat_main_t * vam)
14127 {
14128   unformat_input_t *i = vam->input;
14129   vl_api_map_add_del_rule_t *mp;
14130   u8 is_add = 1;
14131   ip6_address_t ip6_dst;
14132   u32 num_m_args = 0, index, psid = 0;
14133   int ret;
14134
14135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14136     {
14137       if (unformat (i, "index %d", &index))
14138         num_m_args++;
14139       else if (unformat (i, "psid %d", &psid))
14140         num_m_args++;
14141       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14142         num_m_args++;
14143       else if (unformat (i, "del"))
14144         {
14145           is_add = 0;
14146         }
14147       else
14148         {
14149           clib_warning ("parse error '%U'", format_unformat_error, i);
14150           return -99;
14151         }
14152     }
14153
14154   /* Construct the API message */
14155   M (MAP_ADD_DEL_RULE, mp);
14156
14157   mp->index = ntohl (index);
14158   mp->is_add = is_add;
14159   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14160   mp->psid = ntohs (psid);
14161
14162   /* send it... */
14163   S (mp);
14164
14165   /* Wait for a reply, return good/bad news  */
14166   W (ret);
14167   return ret;
14168 }
14169
14170 static int
14171 api_map_domain_dump (vat_main_t * vam)
14172 {
14173   vl_api_map_domain_dump_t *mp;
14174   vl_api_control_ping_t *mp_ping;
14175   int ret;
14176
14177   /* Construct the API message */
14178   M (MAP_DOMAIN_DUMP, mp);
14179
14180   /* send it... */
14181   S (mp);
14182
14183   /* Use a control ping for synchronization */
14184   M (CONTROL_PING, mp_ping);
14185   S (mp_ping);
14186
14187   W (ret);
14188   return ret;
14189 }
14190
14191 static int
14192 api_map_rule_dump (vat_main_t * vam)
14193 {
14194   unformat_input_t *i = vam->input;
14195   vl_api_map_rule_dump_t *mp;
14196   vl_api_control_ping_t *mp_ping;
14197   u32 domain_index = ~0;
14198   int ret;
14199
14200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14201     {
14202       if (unformat (i, "index %u", &domain_index))
14203         ;
14204       else
14205         break;
14206     }
14207
14208   if (domain_index == ~0)
14209     {
14210       clib_warning ("parse error: domain index expected");
14211       return -99;
14212     }
14213
14214   /* Construct the API message */
14215   M (MAP_RULE_DUMP, mp);
14216
14217   mp->domain_index = htonl (domain_index);
14218
14219   /* send it... */
14220   S (mp);
14221
14222   /* Use a control ping for synchronization */
14223   M (CONTROL_PING, mp_ping);
14224   S (mp_ping);
14225
14226   W (ret);
14227   return ret;
14228 }
14229
14230 static void vl_api_map_add_domain_reply_t_handler
14231   (vl_api_map_add_domain_reply_t * mp)
14232 {
14233   vat_main_t *vam = &vat_main;
14234   i32 retval = ntohl (mp->retval);
14235
14236   if (vam->async_mode)
14237     {
14238       vam->async_errors += (retval < 0);
14239     }
14240   else
14241     {
14242       vam->retval = retval;
14243       vam->result_ready = 1;
14244     }
14245 }
14246
14247 static void vl_api_map_add_domain_reply_t_handler_json
14248   (vl_api_map_add_domain_reply_t * mp)
14249 {
14250   vat_main_t *vam = &vat_main;
14251   vat_json_node_t node;
14252
14253   vat_json_init_object (&node);
14254   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14255   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14256
14257   vat_json_print (vam->ofp, &node);
14258   vat_json_free (&node);
14259
14260   vam->retval = ntohl (mp->retval);
14261   vam->result_ready = 1;
14262 }
14263
14264 static int
14265 api_get_first_msg_id (vat_main_t * vam)
14266 {
14267   vl_api_get_first_msg_id_t *mp;
14268   unformat_input_t *i = vam->input;
14269   u8 *name;
14270   u8 name_set = 0;
14271   int ret;
14272
14273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14274     {
14275       if (unformat (i, "client %s", &name))
14276         name_set = 1;
14277       else
14278         break;
14279     }
14280
14281   if (name_set == 0)
14282     {
14283       errmsg ("missing client name");
14284       return -99;
14285     }
14286   vec_add1 (name, 0);
14287
14288   if (vec_len (name) > 63)
14289     {
14290       errmsg ("client name too long");
14291       return -99;
14292     }
14293
14294   M (GET_FIRST_MSG_ID, mp);
14295   clib_memcpy (mp->name, name, vec_len (name));
14296   S (mp);
14297   W (ret);
14298   return ret;
14299 }
14300
14301 static int
14302 api_cop_interface_enable_disable (vat_main_t * vam)
14303 {
14304   unformat_input_t *line_input = vam->input;
14305   vl_api_cop_interface_enable_disable_t *mp;
14306   u32 sw_if_index = ~0;
14307   u8 enable_disable = 1;
14308   int ret;
14309
14310   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14311     {
14312       if (unformat (line_input, "disable"))
14313         enable_disable = 0;
14314       if (unformat (line_input, "enable"))
14315         enable_disable = 1;
14316       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14317                          vam, &sw_if_index))
14318         ;
14319       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14320         ;
14321       else
14322         break;
14323     }
14324
14325   if (sw_if_index == ~0)
14326     {
14327       errmsg ("missing interface name or sw_if_index");
14328       return -99;
14329     }
14330
14331   /* Construct the API message */
14332   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14333   mp->sw_if_index = ntohl (sw_if_index);
14334   mp->enable_disable = enable_disable;
14335
14336   /* send it... */
14337   S (mp);
14338   /* Wait for the reply */
14339   W (ret);
14340   return ret;
14341 }
14342
14343 static int
14344 api_cop_whitelist_enable_disable (vat_main_t * vam)
14345 {
14346   unformat_input_t *line_input = vam->input;
14347   vl_api_cop_whitelist_enable_disable_t *mp;
14348   u32 sw_if_index = ~0;
14349   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14350   u32 fib_id = 0;
14351   int ret;
14352
14353   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14354     {
14355       if (unformat (line_input, "ip4"))
14356         ip4 = 1;
14357       else if (unformat (line_input, "ip6"))
14358         ip6 = 1;
14359       else if (unformat (line_input, "default"))
14360         default_cop = 1;
14361       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14362                          vam, &sw_if_index))
14363         ;
14364       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14365         ;
14366       else if (unformat (line_input, "fib-id %d", &fib_id))
14367         ;
14368       else
14369         break;
14370     }
14371
14372   if (sw_if_index == ~0)
14373     {
14374       errmsg ("missing interface name or sw_if_index");
14375       return -99;
14376     }
14377
14378   /* Construct the API message */
14379   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14380   mp->sw_if_index = ntohl (sw_if_index);
14381   mp->fib_id = ntohl (fib_id);
14382   mp->ip4 = ip4;
14383   mp->ip6 = ip6;
14384   mp->default_cop = default_cop;
14385
14386   /* send it... */
14387   S (mp);
14388   /* Wait for the reply */
14389   W (ret);
14390   return ret;
14391 }
14392
14393 static int
14394 api_get_node_graph (vat_main_t * vam)
14395 {
14396   vl_api_get_node_graph_t *mp;
14397   int ret;
14398
14399   M (GET_NODE_GRAPH, mp);
14400
14401   /* send it... */
14402   S (mp);
14403   /* Wait for the reply */
14404   W (ret);
14405   return ret;
14406 }
14407
14408 /* *INDENT-OFF* */
14409 /** Used for parsing LISP eids */
14410 typedef CLIB_PACKED(struct{
14411   u8 addr[16];   /**< eid address */
14412   u32 len;       /**< prefix length if IP */
14413   u8 type;      /**< type of eid */
14414 }) lisp_eid_vat_t;
14415 /* *INDENT-ON* */
14416
14417 static uword
14418 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14419 {
14420   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14421
14422   memset (a, 0, sizeof (a[0]));
14423
14424   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14425     {
14426       a->type = 0;              /* ipv4 type */
14427     }
14428   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14429     {
14430       a->type = 1;              /* ipv6 type */
14431     }
14432   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14433     {
14434       a->type = 2;              /* mac type */
14435     }
14436   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14437     {
14438       a->type = 3;              /* NSH type */
14439       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14440       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14441     }
14442   else
14443     {
14444       return 0;
14445     }
14446
14447   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14448     {
14449       return 0;
14450     }
14451
14452   return 1;
14453 }
14454
14455 static int
14456 lisp_eid_size_vat (u8 type)
14457 {
14458   switch (type)
14459     {
14460     case 0:
14461       return 4;
14462     case 1:
14463       return 16;
14464     case 2:
14465       return 6;
14466     case 3:
14467       return 5;
14468     }
14469   return 0;
14470 }
14471
14472 static void
14473 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14474 {
14475   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14476 }
14477
14478 static int
14479 api_one_add_del_locator_set (vat_main_t * vam)
14480 {
14481   unformat_input_t *input = vam->input;
14482   vl_api_one_add_del_locator_set_t *mp;
14483   u8 is_add = 1;
14484   u8 *locator_set_name = NULL;
14485   u8 locator_set_name_set = 0;
14486   vl_api_local_locator_t locator, *locators = 0;
14487   u32 sw_if_index, priority, weight;
14488   u32 data_len = 0;
14489
14490   int ret;
14491   /* Parse args required to build the message */
14492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14493     {
14494       if (unformat (input, "del"))
14495         {
14496           is_add = 0;
14497         }
14498       else if (unformat (input, "locator-set %s", &locator_set_name))
14499         {
14500           locator_set_name_set = 1;
14501         }
14502       else if (unformat (input, "sw_if_index %u p %u w %u",
14503                          &sw_if_index, &priority, &weight))
14504         {
14505           locator.sw_if_index = htonl (sw_if_index);
14506           locator.priority = priority;
14507           locator.weight = weight;
14508           vec_add1 (locators, locator);
14509         }
14510       else
14511         if (unformat
14512             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14513              &sw_if_index, &priority, &weight))
14514         {
14515           locator.sw_if_index = htonl (sw_if_index);
14516           locator.priority = priority;
14517           locator.weight = weight;
14518           vec_add1 (locators, locator);
14519         }
14520       else
14521         break;
14522     }
14523
14524   if (locator_set_name_set == 0)
14525     {
14526       errmsg ("missing locator-set name");
14527       vec_free (locators);
14528       return -99;
14529     }
14530
14531   if (vec_len (locator_set_name) > 64)
14532     {
14533       errmsg ("locator-set name too long");
14534       vec_free (locator_set_name);
14535       vec_free (locators);
14536       return -99;
14537     }
14538   vec_add1 (locator_set_name, 0);
14539
14540   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14541
14542   /* Construct the API message */
14543   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14544
14545   mp->is_add = is_add;
14546   clib_memcpy (mp->locator_set_name, locator_set_name,
14547                vec_len (locator_set_name));
14548   vec_free (locator_set_name);
14549
14550   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14551   if (locators)
14552     clib_memcpy (mp->locators, locators, data_len);
14553   vec_free (locators);
14554
14555   /* send it... */
14556   S (mp);
14557
14558   /* Wait for a reply... */
14559   W (ret);
14560   return ret;
14561 }
14562
14563 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14564
14565 static int
14566 api_one_add_del_locator (vat_main_t * vam)
14567 {
14568   unformat_input_t *input = vam->input;
14569   vl_api_one_add_del_locator_t *mp;
14570   u32 tmp_if_index = ~0;
14571   u32 sw_if_index = ~0;
14572   u8 sw_if_index_set = 0;
14573   u8 sw_if_index_if_name_set = 0;
14574   u32 priority = ~0;
14575   u8 priority_set = 0;
14576   u32 weight = ~0;
14577   u8 weight_set = 0;
14578   u8 is_add = 1;
14579   u8 *locator_set_name = NULL;
14580   u8 locator_set_name_set = 0;
14581   int ret;
14582
14583   /* Parse args required to build the message */
14584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14585     {
14586       if (unformat (input, "del"))
14587         {
14588           is_add = 0;
14589         }
14590       else if (unformat (input, "locator-set %s", &locator_set_name))
14591         {
14592           locator_set_name_set = 1;
14593         }
14594       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14595                          &tmp_if_index))
14596         {
14597           sw_if_index_if_name_set = 1;
14598           sw_if_index = tmp_if_index;
14599         }
14600       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14601         {
14602           sw_if_index_set = 1;
14603           sw_if_index = tmp_if_index;
14604         }
14605       else if (unformat (input, "p %d", &priority))
14606         {
14607           priority_set = 1;
14608         }
14609       else if (unformat (input, "w %d", &weight))
14610         {
14611           weight_set = 1;
14612         }
14613       else
14614         break;
14615     }
14616
14617   if (locator_set_name_set == 0)
14618     {
14619       errmsg ("missing locator-set name");
14620       return -99;
14621     }
14622
14623   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14624     {
14625       errmsg ("missing sw_if_index");
14626       vec_free (locator_set_name);
14627       return -99;
14628     }
14629
14630   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14631     {
14632       errmsg ("cannot use both params interface name and sw_if_index");
14633       vec_free (locator_set_name);
14634       return -99;
14635     }
14636
14637   if (priority_set == 0)
14638     {
14639       errmsg ("missing locator-set priority");
14640       vec_free (locator_set_name);
14641       return -99;
14642     }
14643
14644   if (weight_set == 0)
14645     {
14646       errmsg ("missing locator-set weight");
14647       vec_free (locator_set_name);
14648       return -99;
14649     }
14650
14651   if (vec_len (locator_set_name) > 64)
14652     {
14653       errmsg ("locator-set name too long");
14654       vec_free (locator_set_name);
14655       return -99;
14656     }
14657   vec_add1 (locator_set_name, 0);
14658
14659   /* Construct the API message */
14660   M (ONE_ADD_DEL_LOCATOR, mp);
14661
14662   mp->is_add = is_add;
14663   mp->sw_if_index = ntohl (sw_if_index);
14664   mp->priority = priority;
14665   mp->weight = weight;
14666   clib_memcpy (mp->locator_set_name, locator_set_name,
14667                vec_len (locator_set_name));
14668   vec_free (locator_set_name);
14669
14670   /* send it... */
14671   S (mp);
14672
14673   /* Wait for a reply... */
14674   W (ret);
14675   return ret;
14676 }
14677
14678 #define api_lisp_add_del_locator api_one_add_del_locator
14679
14680 uword
14681 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14682 {
14683   u32 *key_id = va_arg (*args, u32 *);
14684   u8 *s = 0;
14685
14686   if (unformat (input, "%s", &s))
14687     {
14688       if (!strcmp ((char *) s, "sha1"))
14689         key_id[0] = HMAC_SHA_1_96;
14690       else if (!strcmp ((char *) s, "sha256"))
14691         key_id[0] = HMAC_SHA_256_128;
14692       else
14693         {
14694           clib_warning ("invalid key_id: '%s'", s);
14695           key_id[0] = HMAC_NO_KEY;
14696         }
14697     }
14698   else
14699     return 0;
14700
14701   vec_free (s);
14702   return 1;
14703 }
14704
14705 static int
14706 api_one_add_del_local_eid (vat_main_t * vam)
14707 {
14708   unformat_input_t *input = vam->input;
14709   vl_api_one_add_del_local_eid_t *mp;
14710   u8 is_add = 1;
14711   u8 eid_set = 0;
14712   lisp_eid_vat_t _eid, *eid = &_eid;
14713   u8 *locator_set_name = 0;
14714   u8 locator_set_name_set = 0;
14715   u32 vni = 0;
14716   u16 key_id = 0;
14717   u8 *key = 0;
14718   int ret;
14719
14720   /* Parse args required to build the message */
14721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14722     {
14723       if (unformat (input, "del"))
14724         {
14725           is_add = 0;
14726         }
14727       else if (unformat (input, "vni %d", &vni))
14728         {
14729           ;
14730         }
14731       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14732         {
14733           eid_set = 1;
14734         }
14735       else if (unformat (input, "locator-set %s", &locator_set_name))
14736         {
14737           locator_set_name_set = 1;
14738         }
14739       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14740         ;
14741       else if (unformat (input, "secret-key %_%v%_", &key))
14742         ;
14743       else
14744         break;
14745     }
14746
14747   if (locator_set_name_set == 0)
14748     {
14749       errmsg ("missing locator-set name");
14750       return -99;
14751     }
14752
14753   if (0 == eid_set)
14754     {
14755       errmsg ("EID address not set!");
14756       vec_free (locator_set_name);
14757       return -99;
14758     }
14759
14760   if (key && (0 == key_id))
14761     {
14762       errmsg ("invalid key_id!");
14763       return -99;
14764     }
14765
14766   if (vec_len (key) > 64)
14767     {
14768       errmsg ("key too long");
14769       vec_free (key);
14770       return -99;
14771     }
14772
14773   if (vec_len (locator_set_name) > 64)
14774     {
14775       errmsg ("locator-set name too long");
14776       vec_free (locator_set_name);
14777       return -99;
14778     }
14779   vec_add1 (locator_set_name, 0);
14780
14781   /* Construct the API message */
14782   M (ONE_ADD_DEL_LOCAL_EID, mp);
14783
14784   mp->is_add = is_add;
14785   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14786   mp->eid_type = eid->type;
14787   mp->prefix_len = eid->len;
14788   mp->vni = clib_host_to_net_u32 (vni);
14789   mp->key_id = clib_host_to_net_u16 (key_id);
14790   clib_memcpy (mp->locator_set_name, locator_set_name,
14791                vec_len (locator_set_name));
14792   clib_memcpy (mp->key, key, vec_len (key));
14793
14794   vec_free (locator_set_name);
14795   vec_free (key);
14796
14797   /* send it... */
14798   S (mp);
14799
14800   /* Wait for a reply... */
14801   W (ret);
14802   return ret;
14803 }
14804
14805 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14806
14807 static int
14808 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14809 {
14810   u32 dp_table = 0, vni = 0;;
14811   unformat_input_t *input = vam->input;
14812   vl_api_gpe_add_del_fwd_entry_t *mp;
14813   u8 is_add = 1;
14814   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14815   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14816   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14817   u32 action = ~0, w;
14818   ip4_address_t rmt_rloc4, lcl_rloc4;
14819   ip6_address_t rmt_rloc6, lcl_rloc6;
14820   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14821   int ret;
14822
14823   memset (&rloc, 0, sizeof (rloc));
14824
14825   /* Parse args required to build the message */
14826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14827     {
14828       if (unformat (input, "del"))
14829         is_add = 0;
14830       else if (unformat (input, "add"))
14831         is_add = 1;
14832       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14833         {
14834           rmt_eid_set = 1;
14835         }
14836       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14837         {
14838           lcl_eid_set = 1;
14839         }
14840       else if (unformat (input, "vrf %d", &dp_table))
14841         ;
14842       else if (unformat (input, "bd %d", &dp_table))
14843         ;
14844       else if (unformat (input, "vni %d", &vni))
14845         ;
14846       else if (unformat (input, "w %d", &w))
14847         {
14848           if (!curr_rloc)
14849             {
14850               errmsg ("No RLOC configured for setting priority/weight!");
14851               return -99;
14852             }
14853           curr_rloc->weight = w;
14854         }
14855       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14856                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14857         {
14858           rloc.is_ip4 = 1;
14859
14860           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14861           rloc.weight = 0;
14862           vec_add1 (lcl_locs, rloc);
14863
14864           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14865           vec_add1 (rmt_locs, rloc);
14866           /* weight saved in rmt loc */
14867           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14868         }
14869       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14870                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14871         {
14872           rloc.is_ip4 = 0;
14873           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14874           rloc.weight = 0;
14875           vec_add1 (lcl_locs, rloc);
14876
14877           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14878           vec_add1 (rmt_locs, rloc);
14879           /* weight saved in rmt loc */
14880           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14881         }
14882       else if (unformat (input, "action %d", &action))
14883         {
14884           ;
14885         }
14886       else
14887         {
14888           clib_warning ("parse error '%U'", format_unformat_error, input);
14889           return -99;
14890         }
14891     }
14892
14893   if (!rmt_eid_set)
14894     {
14895       errmsg ("remote eid addresses not set");
14896       return -99;
14897     }
14898
14899   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14900     {
14901       errmsg ("eid types don't match");
14902       return -99;
14903     }
14904
14905   if (0 == rmt_locs && (u32) ~ 0 == action)
14906     {
14907       errmsg ("action not set for negative mapping");
14908       return -99;
14909     }
14910
14911   /* Construct the API message */
14912   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14913       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14914
14915   mp->is_add = is_add;
14916   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14917   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14918   mp->eid_type = rmt_eid->type;
14919   mp->dp_table = clib_host_to_net_u32 (dp_table);
14920   mp->vni = clib_host_to_net_u32 (vni);
14921   mp->rmt_len = rmt_eid->len;
14922   mp->lcl_len = lcl_eid->len;
14923   mp->action = action;
14924
14925   if (0 != rmt_locs && 0 != lcl_locs)
14926     {
14927       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14928       clib_memcpy (mp->locs, lcl_locs,
14929                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14930
14931       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14932       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14933                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14934     }
14935   vec_free (lcl_locs);
14936   vec_free (rmt_locs);
14937
14938   /* send it... */
14939   S (mp);
14940
14941   /* Wait for a reply... */
14942   W (ret);
14943   return ret;
14944 }
14945
14946 static int
14947 api_one_add_del_map_server (vat_main_t * vam)
14948 {
14949   unformat_input_t *input = vam->input;
14950   vl_api_one_add_del_map_server_t *mp;
14951   u8 is_add = 1;
14952   u8 ipv4_set = 0;
14953   u8 ipv6_set = 0;
14954   ip4_address_t ipv4;
14955   ip6_address_t ipv6;
14956   int ret;
14957
14958   /* Parse args required to build the message */
14959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14960     {
14961       if (unformat (input, "del"))
14962         {
14963           is_add = 0;
14964         }
14965       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14966         {
14967           ipv4_set = 1;
14968         }
14969       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14970         {
14971           ipv6_set = 1;
14972         }
14973       else
14974         break;
14975     }
14976
14977   if (ipv4_set && ipv6_set)
14978     {
14979       errmsg ("both eid v4 and v6 addresses set");
14980       return -99;
14981     }
14982
14983   if (!ipv4_set && !ipv6_set)
14984     {
14985       errmsg ("eid addresses not set");
14986       return -99;
14987     }
14988
14989   /* Construct the API message */
14990   M (ONE_ADD_DEL_MAP_SERVER, mp);
14991
14992   mp->is_add = is_add;
14993   if (ipv6_set)
14994     {
14995       mp->is_ipv6 = 1;
14996       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14997     }
14998   else
14999     {
15000       mp->is_ipv6 = 0;
15001       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15002     }
15003
15004   /* send it... */
15005   S (mp);
15006
15007   /* Wait for a reply... */
15008   W (ret);
15009   return ret;
15010 }
15011
15012 #define api_lisp_add_del_map_server api_one_add_del_map_server
15013
15014 static int
15015 api_one_add_del_map_resolver (vat_main_t * vam)
15016 {
15017   unformat_input_t *input = vam->input;
15018   vl_api_one_add_del_map_resolver_t *mp;
15019   u8 is_add = 1;
15020   u8 ipv4_set = 0;
15021   u8 ipv6_set = 0;
15022   ip4_address_t ipv4;
15023   ip6_address_t ipv6;
15024   int ret;
15025
15026   /* Parse args required to build the message */
15027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15028     {
15029       if (unformat (input, "del"))
15030         {
15031           is_add = 0;
15032         }
15033       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15034         {
15035           ipv4_set = 1;
15036         }
15037       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15038         {
15039           ipv6_set = 1;
15040         }
15041       else
15042         break;
15043     }
15044
15045   if (ipv4_set && ipv6_set)
15046     {
15047       errmsg ("both eid v4 and v6 addresses set");
15048       return -99;
15049     }
15050
15051   if (!ipv4_set && !ipv6_set)
15052     {
15053       errmsg ("eid addresses not set");
15054       return -99;
15055     }
15056
15057   /* Construct the API message */
15058   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15059
15060   mp->is_add = is_add;
15061   if (ipv6_set)
15062     {
15063       mp->is_ipv6 = 1;
15064       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15065     }
15066   else
15067     {
15068       mp->is_ipv6 = 0;
15069       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15070     }
15071
15072   /* send it... */
15073   S (mp);
15074
15075   /* Wait for a reply... */
15076   W (ret);
15077   return ret;
15078 }
15079
15080 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15081
15082 static int
15083 api_lisp_gpe_enable_disable (vat_main_t * vam)
15084 {
15085   unformat_input_t *input = vam->input;
15086   vl_api_gpe_enable_disable_t *mp;
15087   u8 is_set = 0;
15088   u8 is_en = 1;
15089   int ret;
15090
15091   /* Parse args required to build the message */
15092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15093     {
15094       if (unformat (input, "enable"))
15095         {
15096           is_set = 1;
15097           is_en = 1;
15098         }
15099       else if (unformat (input, "disable"))
15100         {
15101           is_set = 1;
15102           is_en = 0;
15103         }
15104       else
15105         break;
15106     }
15107
15108   if (is_set == 0)
15109     {
15110       errmsg ("Value not set");
15111       return -99;
15112     }
15113
15114   /* Construct the API message */
15115   M (GPE_ENABLE_DISABLE, mp);
15116
15117   mp->is_en = is_en;
15118
15119   /* send it... */
15120   S (mp);
15121
15122   /* Wait for a reply... */
15123   W (ret);
15124   return ret;
15125 }
15126
15127 static int
15128 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15129 {
15130   unformat_input_t *input = vam->input;
15131   vl_api_one_rloc_probe_enable_disable_t *mp;
15132   u8 is_set = 0;
15133   u8 is_en = 0;
15134   int ret;
15135
15136   /* Parse args required to build the message */
15137   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15138     {
15139       if (unformat (input, "enable"))
15140         {
15141           is_set = 1;
15142           is_en = 1;
15143         }
15144       else if (unformat (input, "disable"))
15145         is_set = 1;
15146       else
15147         break;
15148     }
15149
15150   if (!is_set)
15151     {
15152       errmsg ("Value not set");
15153       return -99;
15154     }
15155
15156   /* Construct the API message */
15157   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15158
15159   mp->is_enabled = is_en;
15160
15161   /* send it... */
15162   S (mp);
15163
15164   /* Wait for a reply... */
15165   W (ret);
15166   return ret;
15167 }
15168
15169 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15170
15171 static int
15172 api_one_map_register_enable_disable (vat_main_t * vam)
15173 {
15174   unformat_input_t *input = vam->input;
15175   vl_api_one_map_register_enable_disable_t *mp;
15176   u8 is_set = 0;
15177   u8 is_en = 0;
15178   int ret;
15179
15180   /* Parse args required to build the message */
15181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15182     {
15183       if (unformat (input, "enable"))
15184         {
15185           is_set = 1;
15186           is_en = 1;
15187         }
15188       else if (unformat (input, "disable"))
15189         is_set = 1;
15190       else
15191         break;
15192     }
15193
15194   if (!is_set)
15195     {
15196       errmsg ("Value not set");
15197       return -99;
15198     }
15199
15200   /* Construct the API message */
15201   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15202
15203   mp->is_enabled = is_en;
15204
15205   /* send it... */
15206   S (mp);
15207
15208   /* Wait for a reply... */
15209   W (ret);
15210   return ret;
15211 }
15212
15213 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15214
15215 static int
15216 api_one_enable_disable (vat_main_t * vam)
15217 {
15218   unformat_input_t *input = vam->input;
15219   vl_api_one_enable_disable_t *mp;
15220   u8 is_set = 0;
15221   u8 is_en = 0;
15222   int ret;
15223
15224   /* Parse args required to build the message */
15225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15226     {
15227       if (unformat (input, "enable"))
15228         {
15229           is_set = 1;
15230           is_en = 1;
15231         }
15232       else if (unformat (input, "disable"))
15233         {
15234           is_set = 1;
15235         }
15236       else
15237         break;
15238     }
15239
15240   if (!is_set)
15241     {
15242       errmsg ("Value not set");
15243       return -99;
15244     }
15245
15246   /* Construct the API message */
15247   M (ONE_ENABLE_DISABLE, mp);
15248
15249   mp->is_en = is_en;
15250
15251   /* send it... */
15252   S (mp);
15253
15254   /* Wait for a reply... */
15255   W (ret);
15256   return ret;
15257 }
15258
15259 #define api_lisp_enable_disable api_one_enable_disable
15260
15261 static int
15262 api_show_one_map_register_state (vat_main_t * vam)
15263 {
15264   vl_api_show_one_map_register_state_t *mp;
15265   int ret;
15266
15267   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15268
15269   /* send */
15270   S (mp);
15271
15272   /* wait for reply */
15273   W (ret);
15274   return ret;
15275 }
15276
15277 #define api_show_lisp_map_register_state api_show_one_map_register_state
15278
15279 static int
15280 api_show_one_rloc_probe_state (vat_main_t * vam)
15281 {
15282   vl_api_show_one_rloc_probe_state_t *mp;
15283   int ret;
15284
15285   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15286
15287   /* send */
15288   S (mp);
15289
15290   /* wait for reply */
15291   W (ret);
15292   return ret;
15293 }
15294
15295 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15296
15297 static int
15298 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15299 {
15300   vl_api_one_add_del_l2_arp_entry_t *mp;
15301   unformat_input_t *input = vam->input;
15302   u8 is_add = 1;
15303   u8 mac_set = 0;
15304   u8 bd_set = 0;
15305   u8 ip_set = 0;
15306   u8 mac[6] = { 0, };
15307   u32 ip4 = 0, bd = ~0;
15308   int ret;
15309
15310   /* Parse args required to build the message */
15311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15312     {
15313       if (unformat (input, "del"))
15314         is_add = 0;
15315       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15316         mac_set = 1;
15317       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15318         ip_set = 1;
15319       else if (unformat (input, "bd %d", &bd))
15320         bd_set = 1;
15321       else
15322         {
15323           errmsg ("parse error '%U'", format_unformat_error, input);
15324           return -99;
15325         }
15326     }
15327
15328   if (!bd_set || !ip_set || (!mac_set && is_add))
15329     {
15330       errmsg ("Missing BD, IP or MAC!");
15331       return -99;
15332     }
15333
15334   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15335   mp->is_add = is_add;
15336   clib_memcpy (mp->mac, mac, 6);
15337   mp->bd = clib_host_to_net_u32 (bd);
15338   mp->ip4 = ip4;
15339
15340   /* send */
15341   S (mp);
15342
15343   /* wait for reply */
15344   W (ret);
15345   return ret;
15346 }
15347
15348 static int
15349 api_one_l2_arp_bd_get (vat_main_t * vam)
15350 {
15351   vl_api_one_l2_arp_bd_get_t *mp;
15352   int ret;
15353
15354   M (ONE_L2_ARP_BD_GET, mp);
15355
15356   /* send */
15357   S (mp);
15358
15359   /* wait for reply */
15360   W (ret);
15361   return ret;
15362 }
15363
15364 static int
15365 api_one_l2_arp_entries_get (vat_main_t * vam)
15366 {
15367   vl_api_one_l2_arp_entries_get_t *mp;
15368   unformat_input_t *input = vam->input;
15369   u8 bd_set = 0;
15370   u32 bd = ~0;
15371   int ret;
15372
15373   /* Parse args required to build the message */
15374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15375     {
15376       if (unformat (input, "bd %d", &bd))
15377         bd_set = 1;
15378       else
15379         {
15380           errmsg ("parse error '%U'", format_unformat_error, input);
15381           return -99;
15382         }
15383     }
15384
15385   if (!bd_set)
15386     {
15387       errmsg ("Expected bridge domain!");
15388       return -99;
15389     }
15390
15391   M (ONE_L2_ARP_ENTRIES_GET, mp);
15392   mp->bd = clib_host_to_net_u32 (bd);
15393
15394   /* send */
15395   S (mp);
15396
15397   /* wait for reply */
15398   W (ret);
15399   return ret;
15400 }
15401
15402 static int
15403 api_one_stats_enable_disable (vat_main_t * vam)
15404 {
15405   vl_api_one_stats_enable_disable_t *mp;
15406   unformat_input_t *input = vam->input;
15407   u8 is_set = 0;
15408   u8 is_en = 0;
15409   int ret;
15410
15411   /* Parse args required to build the message */
15412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15413     {
15414       if (unformat (input, "enable"))
15415         {
15416           is_set = 1;
15417           is_en = 1;
15418         }
15419       else if (unformat (input, "disable"))
15420         {
15421           is_set = 1;
15422         }
15423       else
15424         break;
15425     }
15426
15427   if (!is_set)
15428     {
15429       errmsg ("Value not set");
15430       return -99;
15431     }
15432
15433   M (ONE_STATS_ENABLE_DISABLE, mp);
15434   mp->is_en = is_en;
15435
15436   /* send */
15437   S (mp);
15438
15439   /* wait for reply */
15440   W (ret);
15441   return ret;
15442 }
15443
15444 static int
15445 api_show_one_stats_enable_disable (vat_main_t * vam)
15446 {
15447   vl_api_show_one_stats_enable_disable_t *mp;
15448   int ret;
15449
15450   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15451
15452   /* send */
15453   S (mp);
15454
15455   /* wait for reply */
15456   W (ret);
15457   return ret;
15458 }
15459
15460 static int
15461 api_show_one_map_request_mode (vat_main_t * vam)
15462 {
15463   vl_api_show_one_map_request_mode_t *mp;
15464   int ret;
15465
15466   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15467
15468   /* send */
15469   S (mp);
15470
15471   /* wait for reply */
15472   W (ret);
15473   return ret;
15474 }
15475
15476 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15477
15478 static int
15479 api_one_map_request_mode (vat_main_t * vam)
15480 {
15481   unformat_input_t *input = vam->input;
15482   vl_api_one_map_request_mode_t *mp;
15483   u8 mode = 0;
15484   int ret;
15485
15486   /* Parse args required to build the message */
15487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15488     {
15489       if (unformat (input, "dst-only"))
15490         mode = 0;
15491       else if (unformat (input, "src-dst"))
15492         mode = 1;
15493       else
15494         {
15495           errmsg ("parse error '%U'", format_unformat_error, input);
15496           return -99;
15497         }
15498     }
15499
15500   M (ONE_MAP_REQUEST_MODE, mp);
15501
15502   mp->mode = mode;
15503
15504   /* send */
15505   S (mp);
15506
15507   /* wait for reply */
15508   W (ret);
15509   return ret;
15510 }
15511
15512 #define api_lisp_map_request_mode api_one_map_request_mode
15513
15514 /**
15515  * Enable/disable ONE proxy ITR.
15516  *
15517  * @param vam vpp API test context
15518  * @return return code
15519  */
15520 static int
15521 api_one_pitr_set_locator_set (vat_main_t * vam)
15522 {
15523   u8 ls_name_set = 0;
15524   unformat_input_t *input = vam->input;
15525   vl_api_one_pitr_set_locator_set_t *mp;
15526   u8 is_add = 1;
15527   u8 *ls_name = 0;
15528   int ret;
15529
15530   /* Parse args required to build the message */
15531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15532     {
15533       if (unformat (input, "del"))
15534         is_add = 0;
15535       else if (unformat (input, "locator-set %s", &ls_name))
15536         ls_name_set = 1;
15537       else
15538         {
15539           errmsg ("parse error '%U'", format_unformat_error, input);
15540           return -99;
15541         }
15542     }
15543
15544   if (!ls_name_set)
15545     {
15546       errmsg ("locator-set name not set!");
15547       return -99;
15548     }
15549
15550   M (ONE_PITR_SET_LOCATOR_SET, mp);
15551
15552   mp->is_add = is_add;
15553   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15554   vec_free (ls_name);
15555
15556   /* send */
15557   S (mp);
15558
15559   /* wait for reply */
15560   W (ret);
15561   return ret;
15562 }
15563
15564 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15565
15566 static int
15567 api_one_nsh_set_locator_set (vat_main_t * vam)
15568 {
15569   u8 ls_name_set = 0;
15570   unformat_input_t *input = vam->input;
15571   vl_api_one_nsh_set_locator_set_t *mp;
15572   u8 is_add = 1;
15573   u8 *ls_name = 0;
15574   int ret;
15575
15576   /* Parse args required to build the message */
15577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15578     {
15579       if (unformat (input, "del"))
15580         is_add = 0;
15581       else if (unformat (input, "ls %s", &ls_name))
15582         ls_name_set = 1;
15583       else
15584         {
15585           errmsg ("parse error '%U'", format_unformat_error, input);
15586           return -99;
15587         }
15588     }
15589
15590   if (!ls_name_set && is_add)
15591     {
15592       errmsg ("locator-set name not set!");
15593       return -99;
15594     }
15595
15596   M (ONE_NSH_SET_LOCATOR_SET, mp);
15597
15598   mp->is_add = is_add;
15599   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15600   vec_free (ls_name);
15601
15602   /* send */
15603   S (mp);
15604
15605   /* wait for reply */
15606   W (ret);
15607   return ret;
15608 }
15609
15610 static int
15611 api_show_one_pitr (vat_main_t * vam)
15612 {
15613   vl_api_show_one_pitr_t *mp;
15614   int ret;
15615
15616   if (!vam->json_output)
15617     {
15618       print (vam->ofp, "%=20s", "lisp status:");
15619     }
15620
15621   M (SHOW_ONE_PITR, mp);
15622   /* send it... */
15623   S (mp);
15624
15625   /* Wait for a reply... */
15626   W (ret);
15627   return ret;
15628 }
15629
15630 #define api_show_lisp_pitr api_show_one_pitr
15631
15632 static int
15633 api_one_use_petr (vat_main_t * vam)
15634 {
15635   unformat_input_t *input = vam->input;
15636   vl_api_one_use_petr_t *mp;
15637   u8 is_add = 0;
15638   ip_address_t ip;
15639   int ret;
15640
15641   memset (&ip, 0, sizeof (ip));
15642
15643   /* Parse args required to build the message */
15644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15645     {
15646       if (unformat (input, "disable"))
15647         is_add = 0;
15648       else
15649         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15650         {
15651           is_add = 1;
15652           ip_addr_version (&ip) = IP4;
15653         }
15654       else
15655         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15656         {
15657           is_add = 1;
15658           ip_addr_version (&ip) = IP6;
15659         }
15660       else
15661         {
15662           errmsg ("parse error '%U'", format_unformat_error, input);
15663           return -99;
15664         }
15665     }
15666
15667   M (ONE_USE_PETR, mp);
15668
15669   mp->is_add = is_add;
15670   if (is_add)
15671     {
15672       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15673       if (mp->is_ip4)
15674         clib_memcpy (mp->address, &ip, 4);
15675       else
15676         clib_memcpy (mp->address, &ip, 16);
15677     }
15678
15679   /* send */
15680   S (mp);
15681
15682   /* wait for reply */
15683   W (ret);
15684   return ret;
15685 }
15686
15687 #define api_lisp_use_petr api_one_use_petr
15688
15689 static int
15690 api_show_one_nsh_mapping (vat_main_t * vam)
15691 {
15692   vl_api_show_one_use_petr_t *mp;
15693   int ret;
15694
15695   if (!vam->json_output)
15696     {
15697       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15698     }
15699
15700   M (SHOW_ONE_NSH_MAPPING, mp);
15701   /* send it... */
15702   S (mp);
15703
15704   /* Wait for a reply... */
15705   W (ret);
15706   return ret;
15707 }
15708
15709 static int
15710 api_show_one_use_petr (vat_main_t * vam)
15711 {
15712   vl_api_show_one_use_petr_t *mp;
15713   int ret;
15714
15715   if (!vam->json_output)
15716     {
15717       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15718     }
15719
15720   M (SHOW_ONE_USE_PETR, mp);
15721   /* send it... */
15722   S (mp);
15723
15724   /* Wait for a reply... */
15725   W (ret);
15726   return ret;
15727 }
15728
15729 #define api_show_lisp_use_petr api_show_one_use_petr
15730
15731 /**
15732  * Add/delete mapping between vni and vrf
15733  */
15734 static int
15735 api_one_eid_table_add_del_map (vat_main_t * vam)
15736 {
15737   unformat_input_t *input = vam->input;
15738   vl_api_one_eid_table_add_del_map_t *mp;
15739   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15740   u32 vni, vrf, bd_index;
15741   int ret;
15742
15743   /* Parse args required to build the message */
15744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15745     {
15746       if (unformat (input, "del"))
15747         is_add = 0;
15748       else if (unformat (input, "vrf %d", &vrf))
15749         vrf_set = 1;
15750       else if (unformat (input, "bd_index %d", &bd_index))
15751         bd_index_set = 1;
15752       else if (unformat (input, "vni %d", &vni))
15753         vni_set = 1;
15754       else
15755         break;
15756     }
15757
15758   if (!vni_set || (!vrf_set && !bd_index_set))
15759     {
15760       errmsg ("missing arguments!");
15761       return -99;
15762     }
15763
15764   if (vrf_set && bd_index_set)
15765     {
15766       errmsg ("error: both vrf and bd entered!");
15767       return -99;
15768     }
15769
15770   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15771
15772   mp->is_add = is_add;
15773   mp->vni = htonl (vni);
15774   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15775   mp->is_l2 = bd_index_set;
15776
15777   /* send */
15778   S (mp);
15779
15780   /* wait for reply */
15781   W (ret);
15782   return ret;
15783 }
15784
15785 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15786
15787 uword
15788 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15789 {
15790   u32 *action = va_arg (*args, u32 *);
15791   u8 *s = 0;
15792
15793   if (unformat (input, "%s", &s))
15794     {
15795       if (!strcmp ((char *) s, "no-action"))
15796         action[0] = 0;
15797       else if (!strcmp ((char *) s, "natively-forward"))
15798         action[0] = 1;
15799       else if (!strcmp ((char *) s, "send-map-request"))
15800         action[0] = 2;
15801       else if (!strcmp ((char *) s, "drop"))
15802         action[0] = 3;
15803       else
15804         {
15805           clib_warning ("invalid action: '%s'", s);
15806           action[0] = 3;
15807         }
15808     }
15809   else
15810     return 0;
15811
15812   vec_free (s);
15813   return 1;
15814 }
15815
15816 /**
15817  * Add/del remote mapping to/from ONE control plane
15818  *
15819  * @param vam vpp API test context
15820  * @return return code
15821  */
15822 static int
15823 api_one_add_del_remote_mapping (vat_main_t * vam)
15824 {
15825   unformat_input_t *input = vam->input;
15826   vl_api_one_add_del_remote_mapping_t *mp;
15827   u32 vni = 0;
15828   lisp_eid_vat_t _eid, *eid = &_eid;
15829   lisp_eid_vat_t _seid, *seid = &_seid;
15830   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15831   u32 action = ~0, p, w, data_len;
15832   ip4_address_t rloc4;
15833   ip6_address_t rloc6;
15834   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15835   int ret;
15836
15837   memset (&rloc, 0, sizeof (rloc));
15838
15839   /* Parse args required to build the message */
15840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15841     {
15842       if (unformat (input, "del-all"))
15843         {
15844           del_all = 1;
15845         }
15846       else if (unformat (input, "del"))
15847         {
15848           is_add = 0;
15849         }
15850       else if (unformat (input, "add"))
15851         {
15852           is_add = 1;
15853         }
15854       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15855         {
15856           eid_set = 1;
15857         }
15858       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15859         {
15860           seid_set = 1;
15861         }
15862       else if (unformat (input, "vni %d", &vni))
15863         {
15864           ;
15865         }
15866       else if (unformat (input, "p %d w %d", &p, &w))
15867         {
15868           if (!curr_rloc)
15869             {
15870               errmsg ("No RLOC configured for setting priority/weight!");
15871               return -99;
15872             }
15873           curr_rloc->priority = p;
15874           curr_rloc->weight = w;
15875         }
15876       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15877         {
15878           rloc.is_ip4 = 1;
15879           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15880           vec_add1 (rlocs, rloc);
15881           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15882         }
15883       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15884         {
15885           rloc.is_ip4 = 0;
15886           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15887           vec_add1 (rlocs, rloc);
15888           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15889         }
15890       else if (unformat (input, "action %U",
15891                          unformat_negative_mapping_action, &action))
15892         {
15893           ;
15894         }
15895       else
15896         {
15897           clib_warning ("parse error '%U'", format_unformat_error, input);
15898           return -99;
15899         }
15900     }
15901
15902   if (0 == eid_set)
15903     {
15904       errmsg ("missing params!");
15905       return -99;
15906     }
15907
15908   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15909     {
15910       errmsg ("no action set for negative map-reply!");
15911       return -99;
15912     }
15913
15914   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15915
15916   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15917   mp->is_add = is_add;
15918   mp->vni = htonl (vni);
15919   mp->action = (u8) action;
15920   mp->is_src_dst = seid_set;
15921   mp->eid_len = eid->len;
15922   mp->seid_len = seid->len;
15923   mp->del_all = del_all;
15924   mp->eid_type = eid->type;
15925   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15926   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15927
15928   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15929   clib_memcpy (mp->rlocs, rlocs, data_len);
15930   vec_free (rlocs);
15931
15932   /* send it... */
15933   S (mp);
15934
15935   /* Wait for a reply... */
15936   W (ret);
15937   return ret;
15938 }
15939
15940 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15941
15942 /**
15943  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15944  * forwarding entries in data-plane accordingly.
15945  *
15946  * @param vam vpp API test context
15947  * @return return code
15948  */
15949 static int
15950 api_one_add_del_adjacency (vat_main_t * vam)
15951 {
15952   unformat_input_t *input = vam->input;
15953   vl_api_one_add_del_adjacency_t *mp;
15954   u32 vni = 0;
15955   ip4_address_t leid4, reid4;
15956   ip6_address_t leid6, reid6;
15957   u8 reid_mac[6] = { 0 };
15958   u8 leid_mac[6] = { 0 };
15959   u8 reid_type, leid_type;
15960   u32 leid_len = 0, reid_len = 0, len;
15961   u8 is_add = 1;
15962   int ret;
15963
15964   leid_type = reid_type = (u8) ~ 0;
15965
15966   /* Parse args required to build the message */
15967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15968     {
15969       if (unformat (input, "del"))
15970         {
15971           is_add = 0;
15972         }
15973       else if (unformat (input, "add"))
15974         {
15975           is_add = 1;
15976         }
15977       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15978                          &reid4, &len))
15979         {
15980           reid_type = 0;        /* ipv4 */
15981           reid_len = len;
15982         }
15983       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15984                          &reid6, &len))
15985         {
15986           reid_type = 1;        /* ipv6 */
15987           reid_len = len;
15988         }
15989       else if (unformat (input, "reid %U", unformat_ethernet_address,
15990                          reid_mac))
15991         {
15992           reid_type = 2;        /* mac */
15993         }
15994       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15995                          &leid4, &len))
15996         {
15997           leid_type = 0;        /* ipv4 */
15998           leid_len = len;
15999         }
16000       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16001                          &leid6, &len))
16002         {
16003           leid_type = 1;        /* ipv6 */
16004           leid_len = len;
16005         }
16006       else if (unformat (input, "leid %U", unformat_ethernet_address,
16007                          leid_mac))
16008         {
16009           leid_type = 2;        /* mac */
16010         }
16011       else if (unformat (input, "vni %d", &vni))
16012         {
16013           ;
16014         }
16015       else
16016         {
16017           errmsg ("parse error '%U'", format_unformat_error, input);
16018           return -99;
16019         }
16020     }
16021
16022   if ((u8) ~ 0 == reid_type)
16023     {
16024       errmsg ("missing params!");
16025       return -99;
16026     }
16027
16028   if (leid_type != reid_type)
16029     {
16030       errmsg ("remote and local EIDs are of different types!");
16031       return -99;
16032     }
16033
16034   M (ONE_ADD_DEL_ADJACENCY, mp);
16035   mp->is_add = is_add;
16036   mp->vni = htonl (vni);
16037   mp->leid_len = leid_len;
16038   mp->reid_len = reid_len;
16039   mp->eid_type = reid_type;
16040
16041   switch (mp->eid_type)
16042     {
16043     case 0:
16044       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16045       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16046       break;
16047     case 1:
16048       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16049       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16050       break;
16051     case 2:
16052       clib_memcpy (mp->leid, leid_mac, 6);
16053       clib_memcpy (mp->reid, reid_mac, 6);
16054       break;
16055     default:
16056       errmsg ("unknown EID type %d!", mp->eid_type);
16057       return 0;
16058     }
16059
16060   /* send it... */
16061   S (mp);
16062
16063   /* Wait for a reply... */
16064   W (ret);
16065   return ret;
16066 }
16067
16068 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16069
16070 uword
16071 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16072 {
16073   u32 *mode = va_arg (*args, u32 *);
16074
16075   if (unformat (input, "lisp"))
16076     *mode = 0;
16077   else if (unformat (input, "vxlan"))
16078     *mode = 1;
16079   else
16080     return 0;
16081
16082   return 1;
16083 }
16084
16085 static int
16086 api_gpe_get_encap_mode (vat_main_t * vam)
16087 {
16088   vl_api_gpe_get_encap_mode_t *mp;
16089   int ret;
16090
16091   /* Construct the API message */
16092   M (GPE_GET_ENCAP_MODE, mp);
16093
16094   /* send it... */
16095   S (mp);
16096
16097   /* Wait for a reply... */
16098   W (ret);
16099   return ret;
16100 }
16101
16102 static int
16103 api_gpe_set_encap_mode (vat_main_t * vam)
16104 {
16105   unformat_input_t *input = vam->input;
16106   vl_api_gpe_set_encap_mode_t *mp;
16107   int ret;
16108   u32 mode = 0;
16109
16110   /* Parse args required to build the message */
16111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16112     {
16113       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16114         ;
16115       else
16116         break;
16117     }
16118
16119   /* Construct the API message */
16120   M (GPE_SET_ENCAP_MODE, mp);
16121
16122   mp->mode = mode;
16123
16124   /* send it... */
16125   S (mp);
16126
16127   /* Wait for a reply... */
16128   W (ret);
16129   return ret;
16130 }
16131
16132 static int
16133 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16134 {
16135   unformat_input_t *input = vam->input;
16136   vl_api_gpe_add_del_iface_t *mp;
16137   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16138   u32 dp_table = 0, vni = 0;
16139   int ret;
16140
16141   /* Parse args required to build the message */
16142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16143     {
16144       if (unformat (input, "up"))
16145         {
16146           action_set = 1;
16147           is_add = 1;
16148         }
16149       else if (unformat (input, "down"))
16150         {
16151           action_set = 1;
16152           is_add = 0;
16153         }
16154       else if (unformat (input, "table_id %d", &dp_table))
16155         {
16156           dp_table_set = 1;
16157         }
16158       else if (unformat (input, "bd_id %d", &dp_table))
16159         {
16160           dp_table_set = 1;
16161           is_l2 = 1;
16162         }
16163       else if (unformat (input, "vni %d", &vni))
16164         {
16165           vni_set = 1;
16166         }
16167       else
16168         break;
16169     }
16170
16171   if (action_set == 0)
16172     {
16173       errmsg ("Action not set");
16174       return -99;
16175     }
16176   if (dp_table_set == 0 || vni_set == 0)
16177     {
16178       errmsg ("vni and dp_table must be set");
16179       return -99;
16180     }
16181
16182   /* Construct the API message */
16183   M (GPE_ADD_DEL_IFACE, mp);
16184
16185   mp->is_add = is_add;
16186   mp->dp_table = clib_host_to_net_u32 (dp_table);
16187   mp->is_l2 = is_l2;
16188   mp->vni = clib_host_to_net_u32 (vni);
16189
16190   /* send it... */
16191   S (mp);
16192
16193   /* Wait for a reply... */
16194   W (ret);
16195   return ret;
16196 }
16197
16198 static int
16199 api_one_map_register_fallback_threshold (vat_main_t * vam)
16200 {
16201   unformat_input_t *input = vam->input;
16202   vl_api_one_map_register_fallback_threshold_t *mp;
16203   u32 value = 0;
16204   u8 is_set = 0;
16205   int ret;
16206
16207   /* Parse args required to build the message */
16208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16209     {
16210       if (unformat (input, "%u", &value))
16211         is_set = 1;
16212       else
16213         {
16214           clib_warning ("parse error '%U'", format_unformat_error, input);
16215           return -99;
16216         }
16217     }
16218
16219   if (!is_set)
16220     {
16221       errmsg ("fallback threshold value is missing!");
16222       return -99;
16223     }
16224
16225   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16226   mp->value = clib_host_to_net_u32 (value);
16227
16228   /* send it... */
16229   S (mp);
16230
16231   /* Wait for a reply... */
16232   W (ret);
16233   return ret;
16234 }
16235
16236 static int
16237 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16238 {
16239   vl_api_show_one_map_register_fallback_threshold_t *mp;
16240   int ret;
16241
16242   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16243
16244   /* send it... */
16245   S (mp);
16246
16247   /* Wait for a reply... */
16248   W (ret);
16249   return ret;
16250 }
16251
16252 static int
16253 api_one_map_register_set_ttl (vat_main_t * vam)
16254 {
16255   unformat_input_t *input = vam->input;
16256   vl_api_one_map_register_set_ttl_t *mp;
16257   u32 ttl = 0;
16258   u8 is_set = 0;
16259   int ret;
16260
16261   /* Parse args required to build the message */
16262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16263     {
16264       if (unformat (input, "%u", &ttl))
16265         is_set = 1;
16266       else
16267         {
16268           clib_warning ("parse error '%U'", format_unformat_error, input);
16269           return -99;
16270         }
16271     }
16272
16273   if (!is_set)
16274     {
16275       errmsg ("TTL value missing!");
16276       return -99;
16277     }
16278
16279   M (ONE_MAP_REGISTER_SET_TTL, mp);
16280   mp->ttl = clib_host_to_net_u32 (ttl);
16281
16282   /* send it... */
16283   S (mp);
16284
16285   /* Wait for a reply... */
16286   W (ret);
16287   return ret;
16288 }
16289
16290 static int
16291 api_show_one_map_register_ttl (vat_main_t * vam)
16292 {
16293   vl_api_show_one_map_register_ttl_t *mp;
16294   int ret;
16295
16296   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16297
16298   /* send it... */
16299   S (mp);
16300
16301   /* Wait for a reply... */
16302   W (ret);
16303   return ret;
16304 }
16305
16306 /**
16307  * Add/del map request itr rlocs from ONE control plane and updates
16308  *
16309  * @param vam vpp API test context
16310  * @return return code
16311  */
16312 static int
16313 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16314 {
16315   unformat_input_t *input = vam->input;
16316   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16317   u8 *locator_set_name = 0;
16318   u8 locator_set_name_set = 0;
16319   u8 is_add = 1;
16320   int ret;
16321
16322   /* Parse args required to build the message */
16323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16324     {
16325       if (unformat (input, "del"))
16326         {
16327           is_add = 0;
16328         }
16329       else if (unformat (input, "%_%v%_", &locator_set_name))
16330         {
16331           locator_set_name_set = 1;
16332         }
16333       else
16334         {
16335           clib_warning ("parse error '%U'", format_unformat_error, input);
16336           return -99;
16337         }
16338     }
16339
16340   if (is_add && !locator_set_name_set)
16341     {
16342       errmsg ("itr-rloc is not set!");
16343       return -99;
16344     }
16345
16346   if (is_add && vec_len (locator_set_name) > 64)
16347     {
16348       errmsg ("itr-rloc locator-set name too long");
16349       vec_free (locator_set_name);
16350       return -99;
16351     }
16352
16353   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16354   mp->is_add = is_add;
16355   if (is_add)
16356     {
16357       clib_memcpy (mp->locator_set_name, locator_set_name,
16358                    vec_len (locator_set_name));
16359     }
16360   else
16361     {
16362       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16363     }
16364   vec_free (locator_set_name);
16365
16366   /* send it... */
16367   S (mp);
16368
16369   /* Wait for a reply... */
16370   W (ret);
16371   return ret;
16372 }
16373
16374 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16375
16376 static int
16377 api_one_locator_dump (vat_main_t * vam)
16378 {
16379   unformat_input_t *input = vam->input;
16380   vl_api_one_locator_dump_t *mp;
16381   vl_api_control_ping_t *mp_ping;
16382   u8 is_index_set = 0, is_name_set = 0;
16383   u8 *ls_name = 0;
16384   u32 ls_index = ~0;
16385   int ret;
16386
16387   /* Parse args required to build the message */
16388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16389     {
16390       if (unformat (input, "ls_name %_%v%_", &ls_name))
16391         {
16392           is_name_set = 1;
16393         }
16394       else if (unformat (input, "ls_index %d", &ls_index))
16395         {
16396           is_index_set = 1;
16397         }
16398       else
16399         {
16400           errmsg ("parse error '%U'", format_unformat_error, input);
16401           return -99;
16402         }
16403     }
16404
16405   if (!is_index_set && !is_name_set)
16406     {
16407       errmsg ("error: expected one of index or name!");
16408       return -99;
16409     }
16410
16411   if (is_index_set && is_name_set)
16412     {
16413       errmsg ("error: only one param expected!");
16414       return -99;
16415     }
16416
16417   if (vec_len (ls_name) > 62)
16418     {
16419       errmsg ("error: locator set name too long!");
16420       return -99;
16421     }
16422
16423   if (!vam->json_output)
16424     {
16425       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16426     }
16427
16428   M (ONE_LOCATOR_DUMP, mp);
16429   mp->is_index_set = is_index_set;
16430
16431   if (is_index_set)
16432     mp->ls_index = clib_host_to_net_u32 (ls_index);
16433   else
16434     {
16435       vec_add1 (ls_name, 0);
16436       strncpy ((char *) mp->ls_name, (char *) ls_name,
16437                sizeof (mp->ls_name) - 1);
16438     }
16439
16440   /* send it... */
16441   S (mp);
16442
16443   /* Use a control ping for synchronization */
16444   M (CONTROL_PING, mp_ping);
16445   S (mp_ping);
16446
16447   /* Wait for a reply... */
16448   W (ret);
16449   return ret;
16450 }
16451
16452 #define api_lisp_locator_dump api_one_locator_dump
16453
16454 static int
16455 api_one_locator_set_dump (vat_main_t * vam)
16456 {
16457   vl_api_one_locator_set_dump_t *mp;
16458   vl_api_control_ping_t *mp_ping;
16459   unformat_input_t *input = vam->input;
16460   u8 filter = 0;
16461   int ret;
16462
16463   /* Parse args required to build the message */
16464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16465     {
16466       if (unformat (input, "local"))
16467         {
16468           filter = 1;
16469         }
16470       else if (unformat (input, "remote"))
16471         {
16472           filter = 2;
16473         }
16474       else
16475         {
16476           errmsg ("parse error '%U'", format_unformat_error, input);
16477           return -99;
16478         }
16479     }
16480
16481   if (!vam->json_output)
16482     {
16483       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16484     }
16485
16486   M (ONE_LOCATOR_SET_DUMP, mp);
16487
16488   mp->filter = filter;
16489
16490   /* send it... */
16491   S (mp);
16492
16493   /* Use a control ping for synchronization */
16494   M (CONTROL_PING, mp_ping);
16495   S (mp_ping);
16496
16497   /* Wait for a reply... */
16498   W (ret);
16499   return ret;
16500 }
16501
16502 #define api_lisp_locator_set_dump api_one_locator_set_dump
16503
16504 static int
16505 api_one_eid_table_map_dump (vat_main_t * vam)
16506 {
16507   u8 is_l2 = 0;
16508   u8 mode_set = 0;
16509   unformat_input_t *input = vam->input;
16510   vl_api_one_eid_table_map_dump_t *mp;
16511   vl_api_control_ping_t *mp_ping;
16512   int ret;
16513
16514   /* Parse args required to build the message */
16515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16516     {
16517       if (unformat (input, "l2"))
16518         {
16519           is_l2 = 1;
16520           mode_set = 1;
16521         }
16522       else if (unformat (input, "l3"))
16523         {
16524           is_l2 = 0;
16525           mode_set = 1;
16526         }
16527       else
16528         {
16529           errmsg ("parse error '%U'", format_unformat_error, input);
16530           return -99;
16531         }
16532     }
16533
16534   if (!mode_set)
16535     {
16536       errmsg ("expected one of 'l2' or 'l3' parameter!");
16537       return -99;
16538     }
16539
16540   if (!vam->json_output)
16541     {
16542       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16543     }
16544
16545   M (ONE_EID_TABLE_MAP_DUMP, mp);
16546   mp->is_l2 = is_l2;
16547
16548   /* send it... */
16549   S (mp);
16550
16551   /* Use a control ping for synchronization */
16552   M (CONTROL_PING, mp_ping);
16553   S (mp_ping);
16554
16555   /* Wait for a reply... */
16556   W (ret);
16557   return ret;
16558 }
16559
16560 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16561
16562 static int
16563 api_one_eid_table_vni_dump (vat_main_t * vam)
16564 {
16565   vl_api_one_eid_table_vni_dump_t *mp;
16566   vl_api_control_ping_t *mp_ping;
16567   int ret;
16568
16569   if (!vam->json_output)
16570     {
16571       print (vam->ofp, "VNI");
16572     }
16573
16574   M (ONE_EID_TABLE_VNI_DUMP, mp);
16575
16576   /* send it... */
16577   S (mp);
16578
16579   /* Use a control ping for synchronization */
16580   M (CONTROL_PING, mp_ping);
16581   S (mp_ping);
16582
16583   /* Wait for a reply... */
16584   W (ret);
16585   return ret;
16586 }
16587
16588 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16589
16590 static int
16591 api_one_eid_table_dump (vat_main_t * vam)
16592 {
16593   unformat_input_t *i = vam->input;
16594   vl_api_one_eid_table_dump_t *mp;
16595   vl_api_control_ping_t *mp_ping;
16596   struct in_addr ip4;
16597   struct in6_addr ip6;
16598   u8 mac[6];
16599   u8 eid_type = ~0, eid_set = 0;
16600   u32 prefix_length = ~0, t, vni = 0;
16601   u8 filter = 0;
16602   int ret;
16603   lisp_nsh_api_t nsh;
16604
16605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16606     {
16607       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16608         {
16609           eid_set = 1;
16610           eid_type = 0;
16611           prefix_length = t;
16612         }
16613       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16614         {
16615           eid_set = 1;
16616           eid_type = 1;
16617           prefix_length = t;
16618         }
16619       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16620         {
16621           eid_set = 1;
16622           eid_type = 2;
16623         }
16624       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16625         {
16626           eid_set = 1;
16627           eid_type = 3;
16628         }
16629       else if (unformat (i, "vni %d", &t))
16630         {
16631           vni = t;
16632         }
16633       else if (unformat (i, "local"))
16634         {
16635           filter = 1;
16636         }
16637       else if (unformat (i, "remote"))
16638         {
16639           filter = 2;
16640         }
16641       else
16642         {
16643           errmsg ("parse error '%U'", format_unformat_error, i);
16644           return -99;
16645         }
16646     }
16647
16648   if (!vam->json_output)
16649     {
16650       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16651              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16652     }
16653
16654   M (ONE_EID_TABLE_DUMP, mp);
16655
16656   mp->filter = filter;
16657   if (eid_set)
16658     {
16659       mp->eid_set = 1;
16660       mp->vni = htonl (vni);
16661       mp->eid_type = eid_type;
16662       switch (eid_type)
16663         {
16664         case 0:
16665           mp->prefix_length = prefix_length;
16666           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16667           break;
16668         case 1:
16669           mp->prefix_length = prefix_length;
16670           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16671           break;
16672         case 2:
16673           clib_memcpy (mp->eid, mac, sizeof (mac));
16674           break;
16675         case 3:
16676           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16677           break;
16678         default:
16679           errmsg ("unknown EID type %d!", eid_type);
16680           return -99;
16681         }
16682     }
16683
16684   /* send it... */
16685   S (mp);
16686
16687   /* Use a control ping for synchronization */
16688   M (CONTROL_PING, mp_ping);
16689   S (mp_ping);
16690
16691   /* Wait for a reply... */
16692   W (ret);
16693   return ret;
16694 }
16695
16696 #define api_lisp_eid_table_dump api_one_eid_table_dump
16697
16698 static int
16699 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16700 {
16701   unformat_input_t *i = vam->input;
16702   vl_api_gpe_fwd_entries_get_t *mp;
16703   u8 vni_set = 0;
16704   u32 vni = ~0;
16705   int ret;
16706
16707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16708     {
16709       if (unformat (i, "vni %d", &vni))
16710         {
16711           vni_set = 1;
16712         }
16713       else
16714         {
16715           errmsg ("parse error '%U'", format_unformat_error, i);
16716           return -99;
16717         }
16718     }
16719
16720   if (!vni_set)
16721     {
16722       errmsg ("vni not set!");
16723       return -99;
16724     }
16725
16726   if (!vam->json_output)
16727     {
16728       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16729              "leid", "reid");
16730     }
16731
16732   M (GPE_FWD_ENTRIES_GET, mp);
16733   mp->vni = clib_host_to_net_u32 (vni);
16734
16735   /* send it... */
16736   S (mp);
16737
16738   /* Wait for a reply... */
16739   W (ret);
16740   return ret;
16741 }
16742
16743 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16744 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16745 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16746 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16747 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16748 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16749 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16750 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16751
16752 static int
16753 api_one_adjacencies_get (vat_main_t * vam)
16754 {
16755   unformat_input_t *i = vam->input;
16756   vl_api_one_adjacencies_get_t *mp;
16757   u8 vni_set = 0;
16758   u32 vni = ~0;
16759   int ret;
16760
16761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16762     {
16763       if (unformat (i, "vni %d", &vni))
16764         {
16765           vni_set = 1;
16766         }
16767       else
16768         {
16769           errmsg ("parse error '%U'", format_unformat_error, i);
16770           return -99;
16771         }
16772     }
16773
16774   if (!vni_set)
16775     {
16776       errmsg ("vni not set!");
16777       return -99;
16778     }
16779
16780   if (!vam->json_output)
16781     {
16782       print (vam->ofp, "%s %40s", "leid", "reid");
16783     }
16784
16785   M (ONE_ADJACENCIES_GET, mp);
16786   mp->vni = clib_host_to_net_u32 (vni);
16787
16788   /* send it... */
16789   S (mp);
16790
16791   /* Wait for a reply... */
16792   W (ret);
16793   return ret;
16794 }
16795
16796 #define api_lisp_adjacencies_get api_one_adjacencies_get
16797
16798 static int
16799 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16800 {
16801   unformat_input_t *i = vam->input;
16802   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16803   int ret;
16804   u8 ip_family_set = 0, is_ip4 = 1;
16805
16806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16807     {
16808       if (unformat (i, "ip4"))
16809         {
16810           ip_family_set = 1;
16811           is_ip4 = 1;
16812         }
16813       else if (unformat (i, "ip6"))
16814         {
16815           ip_family_set = 1;
16816           is_ip4 = 0;
16817         }
16818       else
16819         {
16820           errmsg ("parse error '%U'", format_unformat_error, i);
16821           return -99;
16822         }
16823     }
16824
16825   if (!ip_family_set)
16826     {
16827       errmsg ("ip family not set!");
16828       return -99;
16829     }
16830
16831   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16832   mp->is_ip4 = is_ip4;
16833
16834   /* send it... */
16835   S (mp);
16836
16837   /* Wait for a reply... */
16838   W (ret);
16839   return ret;
16840 }
16841
16842 static int
16843 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16844 {
16845   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16846   int ret;
16847
16848   if (!vam->json_output)
16849     {
16850       print (vam->ofp, "VNIs");
16851     }
16852
16853   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16854
16855   /* send it... */
16856   S (mp);
16857
16858   /* Wait for a reply... */
16859   W (ret);
16860   return ret;
16861 }
16862
16863 static int
16864 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16865 {
16866   unformat_input_t *i = vam->input;
16867   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16868   int ret = 0;
16869   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16870   struct in_addr ip4;
16871   struct in6_addr ip6;
16872   u32 table_id = 0, nh_sw_if_index = ~0;
16873
16874   memset (&ip4, 0, sizeof (ip4));
16875   memset (&ip6, 0, sizeof (ip6));
16876
16877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16878     {
16879       if (unformat (i, "del"))
16880         is_add = 0;
16881       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16882                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16883         {
16884           ip_set = 1;
16885           is_ip4 = 1;
16886         }
16887       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16888                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16889         {
16890           ip_set = 1;
16891           is_ip4 = 0;
16892         }
16893       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16894         {
16895           ip_set = 1;
16896           is_ip4 = 1;
16897           nh_sw_if_index = ~0;
16898         }
16899       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16900         {
16901           ip_set = 1;
16902           is_ip4 = 0;
16903           nh_sw_if_index = ~0;
16904         }
16905       else if (unformat (i, "table %d", &table_id))
16906         ;
16907       else
16908         {
16909           errmsg ("parse error '%U'", format_unformat_error, i);
16910           return -99;
16911         }
16912     }
16913
16914   if (!ip_set)
16915     {
16916       errmsg ("nh addr not set!");
16917       return -99;
16918     }
16919
16920   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16921   mp->is_add = is_add;
16922   mp->table_id = clib_host_to_net_u32 (table_id);
16923   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16924   mp->is_ip4 = is_ip4;
16925   if (is_ip4)
16926     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16927   else
16928     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16929
16930   /* send it... */
16931   S (mp);
16932
16933   /* Wait for a reply... */
16934   W (ret);
16935   return ret;
16936 }
16937
16938 static int
16939 api_one_map_server_dump (vat_main_t * vam)
16940 {
16941   vl_api_one_map_server_dump_t *mp;
16942   vl_api_control_ping_t *mp_ping;
16943   int ret;
16944
16945   if (!vam->json_output)
16946     {
16947       print (vam->ofp, "%=20s", "Map server");
16948     }
16949
16950   M (ONE_MAP_SERVER_DUMP, mp);
16951   /* send it... */
16952   S (mp);
16953
16954   /* Use a control ping for synchronization */
16955   M (CONTROL_PING, mp_ping);
16956   S (mp_ping);
16957
16958   /* Wait for a reply... */
16959   W (ret);
16960   return ret;
16961 }
16962
16963 #define api_lisp_map_server_dump api_one_map_server_dump
16964
16965 static int
16966 api_one_map_resolver_dump (vat_main_t * vam)
16967 {
16968   vl_api_one_map_resolver_dump_t *mp;
16969   vl_api_control_ping_t *mp_ping;
16970   int ret;
16971
16972   if (!vam->json_output)
16973     {
16974       print (vam->ofp, "%=20s", "Map resolver");
16975     }
16976
16977   M (ONE_MAP_RESOLVER_DUMP, mp);
16978   /* send it... */
16979   S (mp);
16980
16981   /* Use a control ping for synchronization */
16982   M (CONTROL_PING, mp_ping);
16983   S (mp_ping);
16984
16985   /* Wait for a reply... */
16986   W (ret);
16987   return ret;
16988 }
16989
16990 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16991
16992 static int
16993 api_one_stats_flush (vat_main_t * vam)
16994 {
16995   vl_api_one_stats_flush_t *mp;
16996   int ret = 0;
16997
16998   M (ONE_STATS_FLUSH, mp);
16999   S (mp);
17000   W (ret);
17001   return ret;
17002 }
17003
17004 static int
17005 api_one_stats_dump (vat_main_t * vam)
17006 {
17007   vl_api_one_stats_dump_t *mp;
17008   vl_api_control_ping_t *mp_ping;
17009   int ret;
17010
17011   M (ONE_STATS_DUMP, mp);
17012   /* send it... */
17013   S (mp);
17014
17015   /* Use a control ping for synchronization */
17016   M (CONTROL_PING, mp_ping);
17017   S (mp_ping);
17018
17019   /* Wait for a reply... */
17020   W (ret);
17021   return ret;
17022 }
17023
17024 static int
17025 api_show_one_status (vat_main_t * vam)
17026 {
17027   vl_api_show_one_status_t *mp;
17028   int ret;
17029
17030   if (!vam->json_output)
17031     {
17032       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17033     }
17034
17035   M (SHOW_ONE_STATUS, mp);
17036   /* send it... */
17037   S (mp);
17038   /* Wait for a reply... */
17039   W (ret);
17040   return ret;
17041 }
17042
17043 #define api_show_lisp_status api_show_one_status
17044
17045 static int
17046 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17047 {
17048   vl_api_gpe_fwd_entry_path_dump_t *mp;
17049   vl_api_control_ping_t *mp_ping;
17050   unformat_input_t *i = vam->input;
17051   u32 fwd_entry_index = ~0;
17052   int ret;
17053
17054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17055     {
17056       if (unformat (i, "index %d", &fwd_entry_index))
17057         ;
17058       else
17059         break;
17060     }
17061
17062   if (~0 == fwd_entry_index)
17063     {
17064       errmsg ("no index specified!");
17065       return -99;
17066     }
17067
17068   if (!vam->json_output)
17069     {
17070       print (vam->ofp, "first line");
17071     }
17072
17073   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17074
17075   /* send it... */
17076   S (mp);
17077   /* Use a control ping for synchronization */
17078   M (CONTROL_PING, mp_ping);
17079   S (mp_ping);
17080
17081   /* Wait for a reply... */
17082   W (ret);
17083   return ret;
17084 }
17085
17086 static int
17087 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17088 {
17089   vl_api_one_get_map_request_itr_rlocs_t *mp;
17090   int ret;
17091
17092   if (!vam->json_output)
17093     {
17094       print (vam->ofp, "%=20s", "itr-rlocs:");
17095     }
17096
17097   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17098   /* send it... */
17099   S (mp);
17100   /* Wait for a reply... */
17101   W (ret);
17102   return ret;
17103 }
17104
17105 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17106
17107 static int
17108 api_af_packet_create (vat_main_t * vam)
17109 {
17110   unformat_input_t *i = vam->input;
17111   vl_api_af_packet_create_t *mp;
17112   u8 *host_if_name = 0;
17113   u8 hw_addr[6];
17114   u8 random_hw_addr = 1;
17115   int ret;
17116
17117   memset (hw_addr, 0, sizeof (hw_addr));
17118
17119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17120     {
17121       if (unformat (i, "name %s", &host_if_name))
17122         vec_add1 (host_if_name, 0);
17123       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17124         random_hw_addr = 0;
17125       else
17126         break;
17127     }
17128
17129   if (!vec_len (host_if_name))
17130     {
17131       errmsg ("host-interface name must be specified");
17132       return -99;
17133     }
17134
17135   if (vec_len (host_if_name) > 64)
17136     {
17137       errmsg ("host-interface name too long");
17138       return -99;
17139     }
17140
17141   M (AF_PACKET_CREATE, mp);
17142
17143   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17144   clib_memcpy (mp->hw_addr, hw_addr, 6);
17145   mp->use_random_hw_addr = random_hw_addr;
17146   vec_free (host_if_name);
17147
17148   S (mp);
17149
17150   /* *INDENT-OFF* */
17151   W2 (ret,
17152       ({
17153         if (ret == 0)
17154           fprintf (vam->ofp ? vam->ofp : stderr,
17155                    " new sw_if_index = %d\n", vam->sw_if_index);
17156       }));
17157   /* *INDENT-ON* */
17158   return ret;
17159 }
17160
17161 static int
17162 api_af_packet_delete (vat_main_t * vam)
17163 {
17164   unformat_input_t *i = vam->input;
17165   vl_api_af_packet_delete_t *mp;
17166   u8 *host_if_name = 0;
17167   int ret;
17168
17169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17170     {
17171       if (unformat (i, "name %s", &host_if_name))
17172         vec_add1 (host_if_name, 0);
17173       else
17174         break;
17175     }
17176
17177   if (!vec_len (host_if_name))
17178     {
17179       errmsg ("host-interface name must be specified");
17180       return -99;
17181     }
17182
17183   if (vec_len (host_if_name) > 64)
17184     {
17185       errmsg ("host-interface name too long");
17186       return -99;
17187     }
17188
17189   M (AF_PACKET_DELETE, mp);
17190
17191   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17192   vec_free (host_if_name);
17193
17194   S (mp);
17195   W (ret);
17196   return ret;
17197 }
17198
17199 static int
17200 api_policer_add_del (vat_main_t * vam)
17201 {
17202   unformat_input_t *i = vam->input;
17203   vl_api_policer_add_del_t *mp;
17204   u8 is_add = 1;
17205   u8 *name = 0;
17206   u32 cir = 0;
17207   u32 eir = 0;
17208   u64 cb = 0;
17209   u64 eb = 0;
17210   u8 rate_type = 0;
17211   u8 round_type = 0;
17212   u8 type = 0;
17213   u8 color_aware = 0;
17214   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17215   int ret;
17216
17217   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17218   conform_action.dscp = 0;
17219   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17220   exceed_action.dscp = 0;
17221   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17222   violate_action.dscp = 0;
17223
17224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17225     {
17226       if (unformat (i, "del"))
17227         is_add = 0;
17228       else if (unformat (i, "name %s", &name))
17229         vec_add1 (name, 0);
17230       else if (unformat (i, "cir %u", &cir))
17231         ;
17232       else if (unformat (i, "eir %u", &eir))
17233         ;
17234       else if (unformat (i, "cb %u", &cb))
17235         ;
17236       else if (unformat (i, "eb %u", &eb))
17237         ;
17238       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17239                          &rate_type))
17240         ;
17241       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17242                          &round_type))
17243         ;
17244       else if (unformat (i, "type %U", unformat_policer_type, &type))
17245         ;
17246       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17247                          &conform_action))
17248         ;
17249       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17250                          &exceed_action))
17251         ;
17252       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17253                          &violate_action))
17254         ;
17255       else if (unformat (i, "color-aware"))
17256         color_aware = 1;
17257       else
17258         break;
17259     }
17260
17261   if (!vec_len (name))
17262     {
17263       errmsg ("policer name must be specified");
17264       return -99;
17265     }
17266
17267   if (vec_len (name) > 64)
17268     {
17269       errmsg ("policer name too long");
17270       return -99;
17271     }
17272
17273   M (POLICER_ADD_DEL, mp);
17274
17275   clib_memcpy (mp->name, name, vec_len (name));
17276   vec_free (name);
17277   mp->is_add = is_add;
17278   mp->cir = cir;
17279   mp->eir = eir;
17280   mp->cb = cb;
17281   mp->eb = eb;
17282   mp->rate_type = rate_type;
17283   mp->round_type = round_type;
17284   mp->type = type;
17285   mp->conform_action_type = conform_action.action_type;
17286   mp->conform_dscp = conform_action.dscp;
17287   mp->exceed_action_type = exceed_action.action_type;
17288   mp->exceed_dscp = exceed_action.dscp;
17289   mp->violate_action_type = violate_action.action_type;
17290   mp->violate_dscp = violate_action.dscp;
17291   mp->color_aware = color_aware;
17292
17293   S (mp);
17294   W (ret);
17295   return ret;
17296 }
17297
17298 static int
17299 api_policer_dump (vat_main_t * vam)
17300 {
17301   unformat_input_t *i = vam->input;
17302   vl_api_policer_dump_t *mp;
17303   vl_api_control_ping_t *mp_ping;
17304   u8 *match_name = 0;
17305   u8 match_name_valid = 0;
17306   int ret;
17307
17308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17309     {
17310       if (unformat (i, "name %s", &match_name))
17311         {
17312           vec_add1 (match_name, 0);
17313           match_name_valid = 1;
17314         }
17315       else
17316         break;
17317     }
17318
17319   M (POLICER_DUMP, mp);
17320   mp->match_name_valid = match_name_valid;
17321   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17322   vec_free (match_name);
17323   /* send it... */
17324   S (mp);
17325
17326   /* Use a control ping for synchronization */
17327   M (CONTROL_PING, mp_ping);
17328   S (mp_ping);
17329
17330   /* Wait for a reply... */
17331   W (ret);
17332   return ret;
17333 }
17334
17335 static int
17336 api_policer_classify_set_interface (vat_main_t * vam)
17337 {
17338   unformat_input_t *i = vam->input;
17339   vl_api_policer_classify_set_interface_t *mp;
17340   u32 sw_if_index;
17341   int sw_if_index_set;
17342   u32 ip4_table_index = ~0;
17343   u32 ip6_table_index = ~0;
17344   u32 l2_table_index = ~0;
17345   u8 is_add = 1;
17346   int ret;
17347
17348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17349     {
17350       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17351         sw_if_index_set = 1;
17352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17353         sw_if_index_set = 1;
17354       else if (unformat (i, "del"))
17355         is_add = 0;
17356       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17357         ;
17358       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17359         ;
17360       else if (unformat (i, "l2-table %d", &l2_table_index))
17361         ;
17362       else
17363         {
17364           clib_warning ("parse error '%U'", format_unformat_error, i);
17365           return -99;
17366         }
17367     }
17368
17369   if (sw_if_index_set == 0)
17370     {
17371       errmsg ("missing interface name or sw_if_index");
17372       return -99;
17373     }
17374
17375   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17376
17377   mp->sw_if_index = ntohl (sw_if_index);
17378   mp->ip4_table_index = ntohl (ip4_table_index);
17379   mp->ip6_table_index = ntohl (ip6_table_index);
17380   mp->l2_table_index = ntohl (l2_table_index);
17381   mp->is_add = is_add;
17382
17383   S (mp);
17384   W (ret);
17385   return ret;
17386 }
17387
17388 static int
17389 api_policer_classify_dump (vat_main_t * vam)
17390 {
17391   unformat_input_t *i = vam->input;
17392   vl_api_policer_classify_dump_t *mp;
17393   vl_api_control_ping_t *mp_ping;
17394   u8 type = POLICER_CLASSIFY_N_TABLES;
17395   int ret;
17396
17397   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17398     ;
17399   else
17400     {
17401       errmsg ("classify table type must be specified");
17402       return -99;
17403     }
17404
17405   if (!vam->json_output)
17406     {
17407       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17408     }
17409
17410   M (POLICER_CLASSIFY_DUMP, mp);
17411   mp->type = type;
17412   /* send it... */
17413   S (mp);
17414
17415   /* Use a control ping for synchronization */
17416   M (CONTROL_PING, mp_ping);
17417   S (mp_ping);
17418
17419   /* Wait for a reply... */
17420   W (ret);
17421   return ret;
17422 }
17423
17424 static int
17425 api_netmap_create (vat_main_t * vam)
17426 {
17427   unformat_input_t *i = vam->input;
17428   vl_api_netmap_create_t *mp;
17429   u8 *if_name = 0;
17430   u8 hw_addr[6];
17431   u8 random_hw_addr = 1;
17432   u8 is_pipe = 0;
17433   u8 is_master = 0;
17434   int ret;
17435
17436   memset (hw_addr, 0, sizeof (hw_addr));
17437
17438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17439     {
17440       if (unformat (i, "name %s", &if_name))
17441         vec_add1 (if_name, 0);
17442       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17443         random_hw_addr = 0;
17444       else if (unformat (i, "pipe"))
17445         is_pipe = 1;
17446       else if (unformat (i, "master"))
17447         is_master = 1;
17448       else if (unformat (i, "slave"))
17449         is_master = 0;
17450       else
17451         break;
17452     }
17453
17454   if (!vec_len (if_name))
17455     {
17456       errmsg ("interface name must be specified");
17457       return -99;
17458     }
17459
17460   if (vec_len (if_name) > 64)
17461     {
17462       errmsg ("interface name too long");
17463       return -99;
17464     }
17465
17466   M (NETMAP_CREATE, mp);
17467
17468   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17469   clib_memcpy (mp->hw_addr, hw_addr, 6);
17470   mp->use_random_hw_addr = random_hw_addr;
17471   mp->is_pipe = is_pipe;
17472   mp->is_master = is_master;
17473   vec_free (if_name);
17474
17475   S (mp);
17476   W (ret);
17477   return ret;
17478 }
17479
17480 static int
17481 api_netmap_delete (vat_main_t * vam)
17482 {
17483   unformat_input_t *i = vam->input;
17484   vl_api_netmap_delete_t *mp;
17485   u8 *if_name = 0;
17486   int ret;
17487
17488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17489     {
17490       if (unformat (i, "name %s", &if_name))
17491         vec_add1 (if_name, 0);
17492       else
17493         break;
17494     }
17495
17496   if (!vec_len (if_name))
17497     {
17498       errmsg ("interface name must be specified");
17499       return -99;
17500     }
17501
17502   if (vec_len (if_name) > 64)
17503     {
17504       errmsg ("interface name too long");
17505       return -99;
17506     }
17507
17508   M (NETMAP_DELETE, mp);
17509
17510   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17511   vec_free (if_name);
17512
17513   S (mp);
17514   W (ret);
17515   return ret;
17516 }
17517
17518 static void
17519 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17520 {
17521   if (fp->afi == IP46_TYPE_IP6)
17522     print (vam->ofp,
17523            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17524            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17525            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17526            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17527            format_ip6_address, fp->next_hop);
17528   else if (fp->afi == IP46_TYPE_IP4)
17529     print (vam->ofp,
17530            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17531            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17532            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17533            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17534            format_ip4_address, fp->next_hop);
17535 }
17536
17537 static void
17538 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17539                                  vl_api_fib_path2_t * fp)
17540 {
17541   struct in_addr ip4;
17542   struct in6_addr ip6;
17543
17544   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17545   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17546   vat_json_object_add_uint (node, "is_local", fp->is_local);
17547   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17548   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17549   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17550   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17551   if (fp->afi == IP46_TYPE_IP4)
17552     {
17553       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17554       vat_json_object_add_ip4 (node, "next_hop", ip4);
17555     }
17556   else if (fp->afi == IP46_TYPE_IP6)
17557     {
17558       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17559       vat_json_object_add_ip6 (node, "next_hop", ip6);
17560     }
17561 }
17562
17563 static void
17564 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17565 {
17566   vat_main_t *vam = &vat_main;
17567   int count = ntohl (mp->mt_count);
17568   vl_api_fib_path2_t *fp;
17569   i32 i;
17570
17571   print (vam->ofp, "[%d]: sw_if_index %d via:",
17572          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17573   fp = mp->mt_paths;
17574   for (i = 0; i < count; i++)
17575     {
17576       vl_api_mpls_fib_path_print (vam, fp);
17577       fp++;
17578     }
17579
17580   print (vam->ofp, "");
17581 }
17582
17583 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17584 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17585
17586 static void
17587 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17588 {
17589   vat_main_t *vam = &vat_main;
17590   vat_json_node_t *node = NULL;
17591   int count = ntohl (mp->mt_count);
17592   vl_api_fib_path2_t *fp;
17593   i32 i;
17594
17595   if (VAT_JSON_ARRAY != vam->json_tree.type)
17596     {
17597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17598       vat_json_init_array (&vam->json_tree);
17599     }
17600   node = vat_json_array_add (&vam->json_tree);
17601
17602   vat_json_init_object (node);
17603   vat_json_object_add_uint (node, "tunnel_index",
17604                             ntohl (mp->mt_tunnel_index));
17605   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17606
17607   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17608
17609   fp = mp->mt_paths;
17610   for (i = 0; i < count; i++)
17611     {
17612       vl_api_mpls_fib_path_json_print (node, fp);
17613       fp++;
17614     }
17615 }
17616
17617 static int
17618 api_mpls_tunnel_dump (vat_main_t * vam)
17619 {
17620   vl_api_mpls_tunnel_dump_t *mp;
17621   vl_api_control_ping_t *mp_ping;
17622   i32 index = -1;
17623   int ret;
17624
17625   /* Parse args required to build the message */
17626   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17627     {
17628       if (!unformat (vam->input, "tunnel_index %d", &index))
17629         {
17630           index = -1;
17631           break;
17632         }
17633     }
17634
17635   print (vam->ofp, "  tunnel_index %d", index);
17636
17637   M (MPLS_TUNNEL_DUMP, mp);
17638   mp->tunnel_index = htonl (index);
17639   S (mp);
17640
17641   /* Use a control ping for synchronization */
17642   M (CONTROL_PING, mp_ping);
17643   S (mp_ping);
17644
17645   W (ret);
17646   return ret;
17647 }
17648
17649 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17650 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17651
17652
17653 static void
17654 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17655 {
17656   vat_main_t *vam = &vat_main;
17657   int count = ntohl (mp->count);
17658   vl_api_fib_path2_t *fp;
17659   int i;
17660
17661   print (vam->ofp,
17662          "table-id %d, label %u, ess_bit %u",
17663          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17664   fp = mp->path;
17665   for (i = 0; i < count; i++)
17666     {
17667       vl_api_mpls_fib_path_print (vam, fp);
17668       fp++;
17669     }
17670 }
17671
17672 static void vl_api_mpls_fib_details_t_handler_json
17673   (vl_api_mpls_fib_details_t * mp)
17674 {
17675   vat_main_t *vam = &vat_main;
17676   int count = ntohl (mp->count);
17677   vat_json_node_t *node = NULL;
17678   vl_api_fib_path2_t *fp;
17679   int i;
17680
17681   if (VAT_JSON_ARRAY != vam->json_tree.type)
17682     {
17683       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17684       vat_json_init_array (&vam->json_tree);
17685     }
17686   node = vat_json_array_add (&vam->json_tree);
17687
17688   vat_json_init_object (node);
17689   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17690   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17691   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17692   vat_json_object_add_uint (node, "path_count", count);
17693   fp = mp->path;
17694   for (i = 0; i < count; i++)
17695     {
17696       vl_api_mpls_fib_path_json_print (node, fp);
17697       fp++;
17698     }
17699 }
17700
17701 static int
17702 api_mpls_fib_dump (vat_main_t * vam)
17703 {
17704   vl_api_mpls_fib_dump_t *mp;
17705   vl_api_control_ping_t *mp_ping;
17706   int ret;
17707
17708   M (MPLS_FIB_DUMP, mp);
17709   S (mp);
17710
17711   /* Use a control ping for synchronization */
17712   M (CONTROL_PING, mp_ping);
17713   S (mp_ping);
17714
17715   W (ret);
17716   return ret;
17717 }
17718
17719 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17720 #define vl_api_ip_fib_details_t_print vl_noop_handler
17721
17722 static void
17723 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17724 {
17725   vat_main_t *vam = &vat_main;
17726   int count = ntohl (mp->count);
17727   vl_api_fib_path_t *fp;
17728   int i;
17729
17730   print (vam->ofp,
17731          "table-id %d, prefix %U/%d",
17732          ntohl (mp->table_id), format_ip4_address, mp->address,
17733          mp->address_length);
17734   fp = mp->path;
17735   for (i = 0; i < count; i++)
17736     {
17737       if (fp->afi == IP46_TYPE_IP6)
17738         print (vam->ofp,
17739                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17740                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17741                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17742                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17743                format_ip6_address, fp->next_hop);
17744       else if (fp->afi == IP46_TYPE_IP4)
17745         print (vam->ofp,
17746                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17747                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17748                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17749                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17750                format_ip4_address, fp->next_hop);
17751       fp++;
17752     }
17753 }
17754
17755 static void vl_api_ip_fib_details_t_handler_json
17756   (vl_api_ip_fib_details_t * mp)
17757 {
17758   vat_main_t *vam = &vat_main;
17759   int count = ntohl (mp->count);
17760   vat_json_node_t *node = NULL;
17761   struct in_addr ip4;
17762   struct in6_addr ip6;
17763   vl_api_fib_path_t *fp;
17764   int i;
17765
17766   if (VAT_JSON_ARRAY != vam->json_tree.type)
17767     {
17768       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17769       vat_json_init_array (&vam->json_tree);
17770     }
17771   node = vat_json_array_add (&vam->json_tree);
17772
17773   vat_json_init_object (node);
17774   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17775   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17776   vat_json_object_add_ip4 (node, "prefix", ip4);
17777   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17778   vat_json_object_add_uint (node, "path_count", count);
17779   fp = mp->path;
17780   for (i = 0; i < count; i++)
17781     {
17782       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17783       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17784       vat_json_object_add_uint (node, "is_local", fp->is_local);
17785       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17786       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17787       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17788       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17789       if (fp->afi == IP46_TYPE_IP4)
17790         {
17791           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17792           vat_json_object_add_ip4 (node, "next_hop", ip4);
17793         }
17794       else if (fp->afi == IP46_TYPE_IP6)
17795         {
17796           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17797           vat_json_object_add_ip6 (node, "next_hop", ip6);
17798         }
17799     }
17800 }
17801
17802 static int
17803 api_ip_fib_dump (vat_main_t * vam)
17804 {
17805   vl_api_ip_fib_dump_t *mp;
17806   vl_api_control_ping_t *mp_ping;
17807   int ret;
17808
17809   M (IP_FIB_DUMP, mp);
17810   S (mp);
17811
17812   /* Use a control ping for synchronization */
17813   M (CONTROL_PING, mp_ping);
17814   S (mp_ping);
17815
17816   W (ret);
17817   return ret;
17818 }
17819
17820 static int
17821 api_ip_mfib_dump (vat_main_t * vam)
17822 {
17823   vl_api_ip_mfib_dump_t *mp;
17824   vl_api_control_ping_t *mp_ping;
17825   int ret;
17826
17827   M (IP_MFIB_DUMP, mp);
17828   S (mp);
17829
17830   /* Use a control ping for synchronization */
17831   M (CONTROL_PING, mp_ping);
17832   S (mp_ping);
17833
17834   W (ret);
17835   return ret;
17836 }
17837
17838 static void vl_api_ip_neighbor_details_t_handler
17839   (vl_api_ip_neighbor_details_t * mp)
17840 {
17841   vat_main_t *vam = &vat_main;
17842
17843   print (vam->ofp, "%c %U %U",
17844          (mp->is_static) ? 'S' : 'D',
17845          format_ethernet_address, &mp->mac_address,
17846          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17847          &mp->ip_address);
17848 }
17849
17850 static void vl_api_ip_neighbor_details_t_handler_json
17851   (vl_api_ip_neighbor_details_t * mp)
17852 {
17853
17854   vat_main_t *vam = &vat_main;
17855   vat_json_node_t *node;
17856   struct in_addr ip4;
17857   struct in6_addr ip6;
17858
17859   if (VAT_JSON_ARRAY != vam->json_tree.type)
17860     {
17861       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17862       vat_json_init_array (&vam->json_tree);
17863     }
17864   node = vat_json_array_add (&vam->json_tree);
17865
17866   vat_json_init_object (node);
17867   vat_json_object_add_string_copy (node, "flag",
17868                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17869                                    "dynamic");
17870
17871   vat_json_object_add_string_copy (node, "link_layer",
17872                                    format (0, "%U", format_ethernet_address,
17873                                            &mp->mac_address));
17874
17875   if (mp->is_ipv6)
17876     {
17877       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17878       vat_json_object_add_ip6 (node, "ip_address", ip6);
17879     }
17880   else
17881     {
17882       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17883       vat_json_object_add_ip4 (node, "ip_address", ip4);
17884     }
17885 }
17886
17887 static int
17888 api_ip_neighbor_dump (vat_main_t * vam)
17889 {
17890   unformat_input_t *i = vam->input;
17891   vl_api_ip_neighbor_dump_t *mp;
17892   vl_api_control_ping_t *mp_ping;
17893   u8 is_ipv6 = 0;
17894   u32 sw_if_index = ~0;
17895   int ret;
17896
17897   /* Parse args required to build the message */
17898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17899     {
17900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17901         ;
17902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17903         ;
17904       else if (unformat (i, "ip6"))
17905         is_ipv6 = 1;
17906       else
17907         break;
17908     }
17909
17910   if (sw_if_index == ~0)
17911     {
17912       errmsg ("missing interface name or sw_if_index");
17913       return -99;
17914     }
17915
17916   M (IP_NEIGHBOR_DUMP, mp);
17917   mp->is_ipv6 = (u8) is_ipv6;
17918   mp->sw_if_index = ntohl (sw_if_index);
17919   S (mp);
17920
17921   /* Use a control ping for synchronization */
17922   M (CONTROL_PING, mp_ping);
17923   S (mp_ping);
17924
17925   W (ret);
17926   return ret;
17927 }
17928
17929 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17930 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17931
17932 static void
17933 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17934 {
17935   vat_main_t *vam = &vat_main;
17936   int count = ntohl (mp->count);
17937   vl_api_fib_path_t *fp;
17938   int i;
17939
17940   print (vam->ofp,
17941          "table-id %d, prefix %U/%d",
17942          ntohl (mp->table_id), format_ip6_address, mp->address,
17943          mp->address_length);
17944   fp = mp->path;
17945   for (i = 0; i < count; i++)
17946     {
17947       if (fp->afi == IP46_TYPE_IP6)
17948         print (vam->ofp,
17949                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17950                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17951                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17952                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17953                format_ip6_address, fp->next_hop);
17954       else if (fp->afi == IP46_TYPE_IP4)
17955         print (vam->ofp,
17956                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17957                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17958                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17959                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17960                format_ip4_address, fp->next_hop);
17961       fp++;
17962     }
17963 }
17964
17965 static void vl_api_ip6_fib_details_t_handler_json
17966   (vl_api_ip6_fib_details_t * mp)
17967 {
17968   vat_main_t *vam = &vat_main;
17969   int count = ntohl (mp->count);
17970   vat_json_node_t *node = NULL;
17971   struct in_addr ip4;
17972   struct in6_addr ip6;
17973   vl_api_fib_path_t *fp;
17974   int i;
17975
17976   if (VAT_JSON_ARRAY != vam->json_tree.type)
17977     {
17978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17979       vat_json_init_array (&vam->json_tree);
17980     }
17981   node = vat_json_array_add (&vam->json_tree);
17982
17983   vat_json_init_object (node);
17984   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17985   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17986   vat_json_object_add_ip6 (node, "prefix", ip6);
17987   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17988   vat_json_object_add_uint (node, "path_count", count);
17989   fp = mp->path;
17990   for (i = 0; i < count; i++)
17991     {
17992       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17993       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17994       vat_json_object_add_uint (node, "is_local", fp->is_local);
17995       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17996       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17997       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17998       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17999       if (fp->afi == IP46_TYPE_IP4)
18000         {
18001           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18002           vat_json_object_add_ip4 (node, "next_hop", ip4);
18003         }
18004       else if (fp->afi == IP46_TYPE_IP6)
18005         {
18006           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18007           vat_json_object_add_ip6 (node, "next_hop", ip6);
18008         }
18009     }
18010 }
18011
18012 static int
18013 api_ip6_fib_dump (vat_main_t * vam)
18014 {
18015   vl_api_ip6_fib_dump_t *mp;
18016   vl_api_control_ping_t *mp_ping;
18017   int ret;
18018
18019   M (IP6_FIB_DUMP, mp);
18020   S (mp);
18021
18022   /* Use a control ping for synchronization */
18023   M (CONTROL_PING, mp_ping);
18024   S (mp_ping);
18025
18026   W (ret);
18027   return ret;
18028 }
18029
18030 static int
18031 api_ip6_mfib_dump (vat_main_t * vam)
18032 {
18033   vl_api_ip6_mfib_dump_t *mp;
18034   vl_api_control_ping_t *mp_ping;
18035   int ret;
18036
18037   M (IP6_MFIB_DUMP, mp);
18038   S (mp);
18039
18040   /* Use a control ping for synchronization */
18041   M (CONTROL_PING, mp_ping);
18042   S (mp_ping);
18043
18044   W (ret);
18045   return ret;
18046 }
18047
18048 int
18049 api_classify_table_ids (vat_main_t * vam)
18050 {
18051   vl_api_classify_table_ids_t *mp;
18052   int ret;
18053
18054   /* Construct the API message */
18055   M (CLASSIFY_TABLE_IDS, mp);
18056   mp->context = 0;
18057
18058   S (mp);
18059   W (ret);
18060   return ret;
18061 }
18062
18063 int
18064 api_classify_table_by_interface (vat_main_t * vam)
18065 {
18066   unformat_input_t *input = vam->input;
18067   vl_api_classify_table_by_interface_t *mp;
18068
18069   u32 sw_if_index = ~0;
18070   int ret;
18071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18072     {
18073       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18074         ;
18075       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18076         ;
18077       else
18078         break;
18079     }
18080   if (sw_if_index == ~0)
18081     {
18082       errmsg ("missing interface name or sw_if_index");
18083       return -99;
18084     }
18085
18086   /* Construct the API message */
18087   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18088   mp->context = 0;
18089   mp->sw_if_index = ntohl (sw_if_index);
18090
18091   S (mp);
18092   W (ret);
18093   return ret;
18094 }
18095
18096 int
18097 api_classify_table_info (vat_main_t * vam)
18098 {
18099   unformat_input_t *input = vam->input;
18100   vl_api_classify_table_info_t *mp;
18101
18102   u32 table_id = ~0;
18103   int ret;
18104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18105     {
18106       if (unformat (input, "table_id %d", &table_id))
18107         ;
18108       else
18109         break;
18110     }
18111   if (table_id == ~0)
18112     {
18113       errmsg ("missing table id");
18114       return -99;
18115     }
18116
18117   /* Construct the API message */
18118   M (CLASSIFY_TABLE_INFO, mp);
18119   mp->context = 0;
18120   mp->table_id = ntohl (table_id);
18121
18122   S (mp);
18123   W (ret);
18124   return ret;
18125 }
18126
18127 int
18128 api_classify_session_dump (vat_main_t * vam)
18129 {
18130   unformat_input_t *input = vam->input;
18131   vl_api_classify_session_dump_t *mp;
18132   vl_api_control_ping_t *mp_ping;
18133
18134   u32 table_id = ~0;
18135   int ret;
18136   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18137     {
18138       if (unformat (input, "table_id %d", &table_id))
18139         ;
18140       else
18141         break;
18142     }
18143   if (table_id == ~0)
18144     {
18145       errmsg ("missing table id");
18146       return -99;
18147     }
18148
18149   /* Construct the API message */
18150   M (CLASSIFY_SESSION_DUMP, mp);
18151   mp->context = 0;
18152   mp->table_id = ntohl (table_id);
18153   S (mp);
18154
18155   /* Use a control ping for synchronization */
18156   M (CONTROL_PING, mp_ping);
18157   S (mp_ping);
18158
18159   W (ret);
18160   return ret;
18161 }
18162
18163 static void
18164 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18165 {
18166   vat_main_t *vam = &vat_main;
18167
18168   print (vam->ofp, "collector_address %U, collector_port %d, "
18169          "src_address %U, vrf_id %d, path_mtu %u, "
18170          "template_interval %u, udp_checksum %d",
18171          format_ip4_address, mp->collector_address,
18172          ntohs (mp->collector_port),
18173          format_ip4_address, mp->src_address,
18174          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18175          ntohl (mp->template_interval), mp->udp_checksum);
18176
18177   vam->retval = 0;
18178   vam->result_ready = 1;
18179 }
18180
18181 static void
18182   vl_api_ipfix_exporter_details_t_handler_json
18183   (vl_api_ipfix_exporter_details_t * mp)
18184 {
18185   vat_main_t *vam = &vat_main;
18186   vat_json_node_t node;
18187   struct in_addr collector_address;
18188   struct in_addr src_address;
18189
18190   vat_json_init_object (&node);
18191   clib_memcpy (&collector_address, &mp->collector_address,
18192                sizeof (collector_address));
18193   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18194   vat_json_object_add_uint (&node, "collector_port",
18195                             ntohs (mp->collector_port));
18196   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18197   vat_json_object_add_ip4 (&node, "src_address", src_address);
18198   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18199   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18200   vat_json_object_add_uint (&node, "template_interval",
18201                             ntohl (mp->template_interval));
18202   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18203
18204   vat_json_print (vam->ofp, &node);
18205   vat_json_free (&node);
18206   vam->retval = 0;
18207   vam->result_ready = 1;
18208 }
18209
18210 int
18211 api_ipfix_exporter_dump (vat_main_t * vam)
18212 {
18213   vl_api_ipfix_exporter_dump_t *mp;
18214   int ret;
18215
18216   /* Construct the API message */
18217   M (IPFIX_EXPORTER_DUMP, mp);
18218   mp->context = 0;
18219
18220   S (mp);
18221   W (ret);
18222   return ret;
18223 }
18224
18225 static int
18226 api_ipfix_classify_stream_dump (vat_main_t * vam)
18227 {
18228   vl_api_ipfix_classify_stream_dump_t *mp;
18229   int ret;
18230
18231   /* Construct the API message */
18232   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18233   mp->context = 0;
18234
18235   S (mp);
18236   W (ret);
18237   return ret;
18238   /* NOTREACHED */
18239   return 0;
18240 }
18241
18242 static void
18243   vl_api_ipfix_classify_stream_details_t_handler
18244   (vl_api_ipfix_classify_stream_details_t * mp)
18245 {
18246   vat_main_t *vam = &vat_main;
18247   print (vam->ofp, "domain_id %d, src_port %d",
18248          ntohl (mp->domain_id), ntohs (mp->src_port));
18249   vam->retval = 0;
18250   vam->result_ready = 1;
18251 }
18252
18253 static void
18254   vl_api_ipfix_classify_stream_details_t_handler_json
18255   (vl_api_ipfix_classify_stream_details_t * mp)
18256 {
18257   vat_main_t *vam = &vat_main;
18258   vat_json_node_t node;
18259
18260   vat_json_init_object (&node);
18261   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18262   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18263
18264   vat_json_print (vam->ofp, &node);
18265   vat_json_free (&node);
18266   vam->retval = 0;
18267   vam->result_ready = 1;
18268 }
18269
18270 static int
18271 api_ipfix_classify_table_dump (vat_main_t * vam)
18272 {
18273   vl_api_ipfix_classify_table_dump_t *mp;
18274   vl_api_control_ping_t *mp_ping;
18275   int ret;
18276
18277   if (!vam->json_output)
18278     {
18279       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18280              "transport_protocol");
18281     }
18282
18283   /* Construct the API message */
18284   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18285
18286   /* send it... */
18287   S (mp);
18288
18289   /* Use a control ping for synchronization */
18290   M (CONTROL_PING, mp_ping);
18291   S (mp_ping);
18292
18293   W (ret);
18294   return ret;
18295 }
18296
18297 static void
18298   vl_api_ipfix_classify_table_details_t_handler
18299   (vl_api_ipfix_classify_table_details_t * mp)
18300 {
18301   vat_main_t *vam = &vat_main;
18302   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18303          mp->transport_protocol);
18304 }
18305
18306 static void
18307   vl_api_ipfix_classify_table_details_t_handler_json
18308   (vl_api_ipfix_classify_table_details_t * mp)
18309 {
18310   vat_json_node_t *node = NULL;
18311   vat_main_t *vam = &vat_main;
18312
18313   if (VAT_JSON_ARRAY != vam->json_tree.type)
18314     {
18315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18316       vat_json_init_array (&vam->json_tree);
18317     }
18318
18319   node = vat_json_array_add (&vam->json_tree);
18320   vat_json_init_object (node);
18321
18322   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18323   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18324   vat_json_object_add_uint (node, "transport_protocol",
18325                             mp->transport_protocol);
18326 }
18327
18328 static int
18329 api_sw_interface_span_enable_disable (vat_main_t * vam)
18330 {
18331   unformat_input_t *i = vam->input;
18332   vl_api_sw_interface_span_enable_disable_t *mp;
18333   u32 src_sw_if_index = ~0;
18334   u32 dst_sw_if_index = ~0;
18335   u8 state = 3;
18336   int ret;
18337   u8 is_l2 = 0;
18338
18339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18340     {
18341       if (unformat
18342           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18343         ;
18344       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18345         ;
18346       else
18347         if (unformat
18348             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18349         ;
18350       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18351         ;
18352       else if (unformat (i, "disable"))
18353         state = 0;
18354       else if (unformat (i, "rx"))
18355         state = 1;
18356       else if (unformat (i, "tx"))
18357         state = 2;
18358       else if (unformat (i, "both"))
18359         state = 3;
18360       else if (unformat (i, "l2"))
18361         is_l2 = 1;
18362       else
18363         break;
18364     }
18365
18366   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18367
18368   mp->sw_if_index_from = htonl (src_sw_if_index);
18369   mp->sw_if_index_to = htonl (dst_sw_if_index);
18370   mp->state = state;
18371   mp->is_l2 = is_l2;
18372
18373   S (mp);
18374   W (ret);
18375   return ret;
18376 }
18377
18378 static void
18379 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18380                                             * mp)
18381 {
18382   vat_main_t *vam = &vat_main;
18383   u8 *sw_if_from_name = 0;
18384   u8 *sw_if_to_name = 0;
18385   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18386   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18387   char *states[] = { "none", "rx", "tx", "both" };
18388   hash_pair_t *p;
18389
18390   /* *INDENT-OFF* */
18391   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18392   ({
18393     if ((u32) p->value[0] == sw_if_index_from)
18394       {
18395         sw_if_from_name = (u8 *)(p->key);
18396         if (sw_if_to_name)
18397           break;
18398       }
18399     if ((u32) p->value[0] == sw_if_index_to)
18400       {
18401         sw_if_to_name = (u8 *)(p->key);
18402         if (sw_if_from_name)
18403           break;
18404       }
18405   }));
18406   /* *INDENT-ON* */
18407   print (vam->ofp, "%20s => %20s (%s)",
18408          sw_if_from_name, sw_if_to_name, states[mp->state]);
18409 }
18410
18411 static void
18412   vl_api_sw_interface_span_details_t_handler_json
18413   (vl_api_sw_interface_span_details_t * mp)
18414 {
18415   vat_main_t *vam = &vat_main;
18416   vat_json_node_t *node = NULL;
18417   u8 *sw_if_from_name = 0;
18418   u8 *sw_if_to_name = 0;
18419   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18420   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18421   hash_pair_t *p;
18422
18423   /* *INDENT-OFF* */
18424   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18425   ({
18426     if ((u32) p->value[0] == sw_if_index_from)
18427       {
18428         sw_if_from_name = (u8 *)(p->key);
18429         if (sw_if_to_name)
18430           break;
18431       }
18432     if ((u32) p->value[0] == sw_if_index_to)
18433       {
18434         sw_if_to_name = (u8 *)(p->key);
18435         if (sw_if_from_name)
18436           break;
18437       }
18438   }));
18439   /* *INDENT-ON* */
18440
18441   if (VAT_JSON_ARRAY != vam->json_tree.type)
18442     {
18443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18444       vat_json_init_array (&vam->json_tree);
18445     }
18446   node = vat_json_array_add (&vam->json_tree);
18447
18448   vat_json_init_object (node);
18449   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18450   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18451   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18452   if (0 != sw_if_to_name)
18453     {
18454       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18455     }
18456   vat_json_object_add_uint (node, "state", mp->state);
18457 }
18458
18459 static int
18460 api_sw_interface_span_dump (vat_main_t * vam)
18461 {
18462   unformat_input_t *input = vam->input;
18463   vl_api_sw_interface_span_dump_t *mp;
18464   vl_api_control_ping_t *mp_ping;
18465   u8 is_l2 = 0;
18466   int ret;
18467
18468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18469     {
18470       if (unformat (input, "l2"))
18471         is_l2 = 1;
18472       else
18473         break;
18474     }
18475
18476   M (SW_INTERFACE_SPAN_DUMP, mp);
18477   mp->is_l2 = is_l2;
18478   S (mp);
18479
18480   /* Use a control ping for synchronization */
18481   M (CONTROL_PING, mp_ping);
18482   S (mp_ping);
18483
18484   W (ret);
18485   return ret;
18486 }
18487
18488 int
18489 api_pg_create_interface (vat_main_t * vam)
18490 {
18491   unformat_input_t *input = vam->input;
18492   vl_api_pg_create_interface_t *mp;
18493
18494   u32 if_id = ~0;
18495   int ret;
18496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18497     {
18498       if (unformat (input, "if_id %d", &if_id))
18499         ;
18500       else
18501         break;
18502     }
18503   if (if_id == ~0)
18504     {
18505       errmsg ("missing pg interface index");
18506       return -99;
18507     }
18508
18509   /* Construct the API message */
18510   M (PG_CREATE_INTERFACE, mp);
18511   mp->context = 0;
18512   mp->interface_id = ntohl (if_id);
18513
18514   S (mp);
18515   W (ret);
18516   return ret;
18517 }
18518
18519 int
18520 api_pg_capture (vat_main_t * vam)
18521 {
18522   unformat_input_t *input = vam->input;
18523   vl_api_pg_capture_t *mp;
18524
18525   u32 if_id = ~0;
18526   u8 enable = 1;
18527   u32 count = 1;
18528   u8 pcap_file_set = 0;
18529   u8 *pcap_file = 0;
18530   int ret;
18531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18532     {
18533       if (unformat (input, "if_id %d", &if_id))
18534         ;
18535       else if (unformat (input, "pcap %s", &pcap_file))
18536         pcap_file_set = 1;
18537       else if (unformat (input, "count %d", &count))
18538         ;
18539       else if (unformat (input, "disable"))
18540         enable = 0;
18541       else
18542         break;
18543     }
18544   if (if_id == ~0)
18545     {
18546       errmsg ("missing pg interface index");
18547       return -99;
18548     }
18549   if (pcap_file_set > 0)
18550     {
18551       if (vec_len (pcap_file) > 255)
18552         {
18553           errmsg ("pcap file name is too long");
18554           return -99;
18555         }
18556     }
18557
18558   u32 name_len = vec_len (pcap_file);
18559   /* Construct the API message */
18560   M (PG_CAPTURE, mp);
18561   mp->context = 0;
18562   mp->interface_id = ntohl (if_id);
18563   mp->is_enabled = enable;
18564   mp->count = ntohl (count);
18565   mp->pcap_name_length = ntohl (name_len);
18566   if (pcap_file_set != 0)
18567     {
18568       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18569     }
18570   vec_free (pcap_file);
18571
18572   S (mp);
18573   W (ret);
18574   return ret;
18575 }
18576
18577 int
18578 api_pg_enable_disable (vat_main_t * vam)
18579 {
18580   unformat_input_t *input = vam->input;
18581   vl_api_pg_enable_disable_t *mp;
18582
18583   u8 enable = 1;
18584   u8 stream_name_set = 0;
18585   u8 *stream_name = 0;
18586   int ret;
18587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18588     {
18589       if (unformat (input, "stream %s", &stream_name))
18590         stream_name_set = 1;
18591       else if (unformat (input, "disable"))
18592         enable = 0;
18593       else
18594         break;
18595     }
18596
18597   if (stream_name_set > 0)
18598     {
18599       if (vec_len (stream_name) > 255)
18600         {
18601           errmsg ("stream name too long");
18602           return -99;
18603         }
18604     }
18605
18606   u32 name_len = vec_len (stream_name);
18607   /* Construct the API message */
18608   M (PG_ENABLE_DISABLE, mp);
18609   mp->context = 0;
18610   mp->is_enabled = enable;
18611   if (stream_name_set != 0)
18612     {
18613       mp->stream_name_length = ntohl (name_len);
18614       clib_memcpy (mp->stream_name, stream_name, name_len);
18615     }
18616   vec_free (stream_name);
18617
18618   S (mp);
18619   W (ret);
18620   return ret;
18621 }
18622
18623 int
18624 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18625 {
18626   unformat_input_t *input = vam->input;
18627   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18628
18629   u16 *low_ports = 0;
18630   u16 *high_ports = 0;
18631   u16 this_low;
18632   u16 this_hi;
18633   ip4_address_t ip4_addr;
18634   ip6_address_t ip6_addr;
18635   u32 length;
18636   u32 tmp, tmp2;
18637   u8 prefix_set = 0;
18638   u32 vrf_id = ~0;
18639   u8 is_add = 1;
18640   u8 is_ipv6 = 0;
18641   int ret;
18642
18643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18644     {
18645       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18646         {
18647           prefix_set = 1;
18648         }
18649       else
18650         if (unformat
18651             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18652         {
18653           prefix_set = 1;
18654           is_ipv6 = 1;
18655         }
18656       else if (unformat (input, "vrf %d", &vrf_id))
18657         ;
18658       else if (unformat (input, "del"))
18659         is_add = 0;
18660       else if (unformat (input, "port %d", &tmp))
18661         {
18662           if (tmp == 0 || tmp > 65535)
18663             {
18664               errmsg ("port %d out of range", tmp);
18665               return -99;
18666             }
18667           this_low = tmp;
18668           this_hi = this_low + 1;
18669           vec_add1 (low_ports, this_low);
18670           vec_add1 (high_ports, this_hi);
18671         }
18672       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18673         {
18674           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18675             {
18676               errmsg ("incorrect range parameters");
18677               return -99;
18678             }
18679           this_low = tmp;
18680           /* Note: in debug CLI +1 is added to high before
18681              passing to real fn that does "the work"
18682              (ip_source_and_port_range_check_add_del).
18683              This fn is a wrapper around the binary API fn a
18684              control plane will call, which expects this increment
18685              to have occurred. Hence letting the binary API control
18686              plane fn do the increment for consistency between VAT
18687              and other control planes.
18688            */
18689           this_hi = tmp2;
18690           vec_add1 (low_ports, this_low);
18691           vec_add1 (high_ports, this_hi);
18692         }
18693       else
18694         break;
18695     }
18696
18697   if (prefix_set == 0)
18698     {
18699       errmsg ("<address>/<mask> not specified");
18700       return -99;
18701     }
18702
18703   if (vrf_id == ~0)
18704     {
18705       errmsg ("VRF ID required, not specified");
18706       return -99;
18707     }
18708
18709   if (vrf_id == 0)
18710     {
18711       errmsg
18712         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18713       return -99;
18714     }
18715
18716   if (vec_len (low_ports) == 0)
18717     {
18718       errmsg ("At least one port or port range required");
18719       return -99;
18720     }
18721
18722   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18723
18724   mp->is_add = is_add;
18725
18726   if (is_ipv6)
18727     {
18728       mp->is_ipv6 = 1;
18729       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18730     }
18731   else
18732     {
18733       mp->is_ipv6 = 0;
18734       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18735     }
18736
18737   mp->mask_length = length;
18738   mp->number_of_ranges = vec_len (low_ports);
18739
18740   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18741   vec_free (low_ports);
18742
18743   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18744   vec_free (high_ports);
18745
18746   mp->vrf_id = ntohl (vrf_id);
18747
18748   S (mp);
18749   W (ret);
18750   return ret;
18751 }
18752
18753 int
18754 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18755 {
18756   unformat_input_t *input = vam->input;
18757   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18758   u32 sw_if_index = ~0;
18759   int vrf_set = 0;
18760   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18761   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18762   u8 is_add = 1;
18763   int ret;
18764
18765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18766     {
18767       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18768         ;
18769       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18770         ;
18771       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18772         vrf_set = 1;
18773       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18774         vrf_set = 1;
18775       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18776         vrf_set = 1;
18777       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18778         vrf_set = 1;
18779       else if (unformat (input, "del"))
18780         is_add = 0;
18781       else
18782         break;
18783     }
18784
18785   if (sw_if_index == ~0)
18786     {
18787       errmsg ("Interface required but not specified");
18788       return -99;
18789     }
18790
18791   if (vrf_set == 0)
18792     {
18793       errmsg ("VRF ID required but not specified");
18794       return -99;
18795     }
18796
18797   if (tcp_out_vrf_id == 0
18798       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18799     {
18800       errmsg
18801         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18802       return -99;
18803     }
18804
18805   /* Construct the API message */
18806   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18807
18808   mp->sw_if_index = ntohl (sw_if_index);
18809   mp->is_add = is_add;
18810   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18811   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18812   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18813   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18814
18815   /* send it... */
18816   S (mp);
18817
18818   /* Wait for a reply... */
18819   W (ret);
18820   return ret;
18821 }
18822
18823 static int
18824 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18825 {
18826   unformat_input_t *i = vam->input;
18827   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18828   u32 local_sa_id = 0;
18829   u32 remote_sa_id = 0;
18830   ip4_address_t src_address;
18831   ip4_address_t dst_address;
18832   u8 is_add = 1;
18833   int ret;
18834
18835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18836     {
18837       if (unformat (i, "local_sa %d", &local_sa_id))
18838         ;
18839       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18840         ;
18841       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18842         ;
18843       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18844         ;
18845       else if (unformat (i, "del"))
18846         is_add = 0;
18847       else
18848         {
18849           clib_warning ("parse error '%U'", format_unformat_error, i);
18850           return -99;
18851         }
18852     }
18853
18854   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18855
18856   mp->local_sa_id = ntohl (local_sa_id);
18857   mp->remote_sa_id = ntohl (remote_sa_id);
18858   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18859   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18860   mp->is_add = is_add;
18861
18862   S (mp);
18863   W (ret);
18864   return ret;
18865 }
18866
18867 static int
18868 api_punt (vat_main_t * vam)
18869 {
18870   unformat_input_t *i = vam->input;
18871   vl_api_punt_t *mp;
18872   u32 ipv = ~0;
18873   u32 protocol = ~0;
18874   u32 port = ~0;
18875   int is_add = 1;
18876   int ret;
18877
18878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18879     {
18880       if (unformat (i, "ip %d", &ipv))
18881         ;
18882       else if (unformat (i, "protocol %d", &protocol))
18883         ;
18884       else if (unformat (i, "port %d", &port))
18885         ;
18886       else if (unformat (i, "del"))
18887         is_add = 0;
18888       else
18889         {
18890           clib_warning ("parse error '%U'", format_unformat_error, i);
18891           return -99;
18892         }
18893     }
18894
18895   M (PUNT, mp);
18896
18897   mp->is_add = (u8) is_add;
18898   mp->ipv = (u8) ipv;
18899   mp->l4_protocol = (u8) protocol;
18900   mp->l4_port = htons ((u16) port);
18901
18902   S (mp);
18903   W (ret);
18904   return ret;
18905 }
18906
18907 static void vl_api_ipsec_gre_tunnel_details_t_handler
18908   (vl_api_ipsec_gre_tunnel_details_t * mp)
18909 {
18910   vat_main_t *vam = &vat_main;
18911
18912   print (vam->ofp, "%11d%15U%15U%14d%14d",
18913          ntohl (mp->sw_if_index),
18914          format_ip4_address, &mp->src_address,
18915          format_ip4_address, &mp->dst_address,
18916          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18917 }
18918
18919 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18920   (vl_api_ipsec_gre_tunnel_details_t * mp)
18921 {
18922   vat_main_t *vam = &vat_main;
18923   vat_json_node_t *node = NULL;
18924   struct in_addr ip4;
18925
18926   if (VAT_JSON_ARRAY != vam->json_tree.type)
18927     {
18928       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18929       vat_json_init_array (&vam->json_tree);
18930     }
18931   node = vat_json_array_add (&vam->json_tree);
18932
18933   vat_json_init_object (node);
18934   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18935   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18936   vat_json_object_add_ip4 (node, "src_address", ip4);
18937   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18938   vat_json_object_add_ip4 (node, "dst_address", ip4);
18939   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18940   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18941 }
18942
18943 static int
18944 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18945 {
18946   unformat_input_t *i = vam->input;
18947   vl_api_ipsec_gre_tunnel_dump_t *mp;
18948   vl_api_control_ping_t *mp_ping;
18949   u32 sw_if_index;
18950   u8 sw_if_index_set = 0;
18951   int ret;
18952
18953   /* Parse args required to build the message */
18954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18955     {
18956       if (unformat (i, "sw_if_index %d", &sw_if_index))
18957         sw_if_index_set = 1;
18958       else
18959         break;
18960     }
18961
18962   if (sw_if_index_set == 0)
18963     {
18964       sw_if_index = ~0;
18965     }
18966
18967   if (!vam->json_output)
18968     {
18969       print (vam->ofp, "%11s%15s%15s%14s%14s",
18970              "sw_if_index", "src_address", "dst_address",
18971              "local_sa_id", "remote_sa_id");
18972     }
18973
18974   /* Get list of gre-tunnel interfaces */
18975   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18976
18977   mp->sw_if_index = htonl (sw_if_index);
18978
18979   S (mp);
18980
18981   /* Use a control ping for synchronization */
18982   M (CONTROL_PING, mp_ping);
18983   S (mp_ping);
18984
18985   W (ret);
18986   return ret;
18987 }
18988
18989 static int
18990 api_delete_subif (vat_main_t * vam)
18991 {
18992   unformat_input_t *i = vam->input;
18993   vl_api_delete_subif_t *mp;
18994   u32 sw_if_index = ~0;
18995   int ret;
18996
18997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18998     {
18999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19000         ;
19001       if (unformat (i, "sw_if_index %d", &sw_if_index))
19002         ;
19003       else
19004         break;
19005     }
19006
19007   if (sw_if_index == ~0)
19008     {
19009       errmsg ("missing sw_if_index");
19010       return -99;
19011     }
19012
19013   /* Construct the API message */
19014   M (DELETE_SUBIF, mp);
19015   mp->sw_if_index = ntohl (sw_if_index);
19016
19017   S (mp);
19018   W (ret);
19019   return ret;
19020 }
19021
19022 #define foreach_pbb_vtr_op      \
19023 _("disable",  L2_VTR_DISABLED)  \
19024 _("pop",  L2_VTR_POP_2)         \
19025 _("push",  L2_VTR_PUSH_2)
19026
19027 static int
19028 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19029 {
19030   unformat_input_t *i = vam->input;
19031   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19032   u32 sw_if_index = ~0, vtr_op = ~0;
19033   u16 outer_tag = ~0;
19034   u8 dmac[6], smac[6];
19035   u8 dmac_set = 0, smac_set = 0;
19036   u16 vlanid = 0;
19037   u32 sid = ~0;
19038   u32 tmp;
19039   int ret;
19040
19041   /* Shut up coverity */
19042   memset (dmac, 0, sizeof (dmac));
19043   memset (smac, 0, sizeof (smac));
19044
19045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19046     {
19047       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19048         ;
19049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19050         ;
19051       else if (unformat (i, "vtr_op %d", &vtr_op))
19052         ;
19053 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19054       foreach_pbb_vtr_op
19055 #undef _
19056         else if (unformat (i, "translate_pbb_stag"))
19057         {
19058           if (unformat (i, "%d", &tmp))
19059             {
19060               vtr_op = L2_VTR_TRANSLATE_2_1;
19061               outer_tag = tmp;
19062             }
19063           else
19064             {
19065               errmsg
19066                 ("translate_pbb_stag operation requires outer tag definition");
19067               return -99;
19068             }
19069         }
19070       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19071         dmac_set++;
19072       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19073         smac_set++;
19074       else if (unformat (i, "sid %d", &sid))
19075         ;
19076       else if (unformat (i, "vlanid %d", &tmp))
19077         vlanid = tmp;
19078       else
19079         {
19080           clib_warning ("parse error '%U'", format_unformat_error, i);
19081           return -99;
19082         }
19083     }
19084
19085   if ((sw_if_index == ~0) || (vtr_op == ~0))
19086     {
19087       errmsg ("missing sw_if_index or vtr operation");
19088       return -99;
19089     }
19090   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19091       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19092     {
19093       errmsg
19094         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19095       return -99;
19096     }
19097
19098   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19099   mp->sw_if_index = ntohl (sw_if_index);
19100   mp->vtr_op = ntohl (vtr_op);
19101   mp->outer_tag = ntohs (outer_tag);
19102   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19103   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19104   mp->b_vlanid = ntohs (vlanid);
19105   mp->i_sid = ntohl (sid);
19106
19107   S (mp);
19108   W (ret);
19109   return ret;
19110 }
19111
19112 static int
19113 api_flow_classify_set_interface (vat_main_t * vam)
19114 {
19115   unformat_input_t *i = vam->input;
19116   vl_api_flow_classify_set_interface_t *mp;
19117   u32 sw_if_index;
19118   int sw_if_index_set;
19119   u32 ip4_table_index = ~0;
19120   u32 ip6_table_index = ~0;
19121   u8 is_add = 1;
19122   int ret;
19123
19124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19125     {
19126       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19127         sw_if_index_set = 1;
19128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19129         sw_if_index_set = 1;
19130       else if (unformat (i, "del"))
19131         is_add = 0;
19132       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19133         ;
19134       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19135         ;
19136       else
19137         {
19138           clib_warning ("parse error '%U'", format_unformat_error, i);
19139           return -99;
19140         }
19141     }
19142
19143   if (sw_if_index_set == 0)
19144     {
19145       errmsg ("missing interface name or sw_if_index");
19146       return -99;
19147     }
19148
19149   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19150
19151   mp->sw_if_index = ntohl (sw_if_index);
19152   mp->ip4_table_index = ntohl (ip4_table_index);
19153   mp->ip6_table_index = ntohl (ip6_table_index);
19154   mp->is_add = is_add;
19155
19156   S (mp);
19157   W (ret);
19158   return ret;
19159 }
19160
19161 static int
19162 api_flow_classify_dump (vat_main_t * vam)
19163 {
19164   unformat_input_t *i = vam->input;
19165   vl_api_flow_classify_dump_t *mp;
19166   vl_api_control_ping_t *mp_ping;
19167   u8 type = FLOW_CLASSIFY_N_TABLES;
19168   int ret;
19169
19170   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19171     ;
19172   else
19173     {
19174       errmsg ("classify table type must be specified");
19175       return -99;
19176     }
19177
19178   if (!vam->json_output)
19179     {
19180       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19181     }
19182
19183   M (FLOW_CLASSIFY_DUMP, mp);
19184   mp->type = type;
19185   /* send it... */
19186   S (mp);
19187
19188   /* Use a control ping for synchronization */
19189   M (CONTROL_PING, mp_ping);
19190   S (mp_ping);
19191
19192   /* Wait for a reply... */
19193   W (ret);
19194   return ret;
19195 }
19196
19197 static int
19198 api_feature_enable_disable (vat_main_t * vam)
19199 {
19200   unformat_input_t *i = vam->input;
19201   vl_api_feature_enable_disable_t *mp;
19202   u8 *arc_name = 0;
19203   u8 *feature_name = 0;
19204   u32 sw_if_index = ~0;
19205   u8 enable = 1;
19206   int ret;
19207
19208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19209     {
19210       if (unformat (i, "arc_name %s", &arc_name))
19211         ;
19212       else if (unformat (i, "feature_name %s", &feature_name))
19213         ;
19214       else
19215         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19216         ;
19217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19218         ;
19219       else if (unformat (i, "disable"))
19220         enable = 0;
19221       else
19222         break;
19223     }
19224
19225   if (arc_name == 0)
19226     {
19227       errmsg ("missing arc name");
19228       return -99;
19229     }
19230   if (vec_len (arc_name) > 63)
19231     {
19232       errmsg ("arc name too long");
19233     }
19234
19235   if (feature_name == 0)
19236     {
19237       errmsg ("missing feature name");
19238       return -99;
19239     }
19240   if (vec_len (feature_name) > 63)
19241     {
19242       errmsg ("feature name too long");
19243     }
19244
19245   if (sw_if_index == ~0)
19246     {
19247       errmsg ("missing interface name or sw_if_index");
19248       return -99;
19249     }
19250
19251   /* Construct the API message */
19252   M (FEATURE_ENABLE_DISABLE, mp);
19253   mp->sw_if_index = ntohl (sw_if_index);
19254   mp->enable = enable;
19255   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19256   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19257   vec_free (arc_name);
19258   vec_free (feature_name);
19259
19260   S (mp);
19261   W (ret);
19262   return ret;
19263 }
19264
19265 static int
19266 api_sw_interface_tag_add_del (vat_main_t * vam)
19267 {
19268   unformat_input_t *i = vam->input;
19269   vl_api_sw_interface_tag_add_del_t *mp;
19270   u32 sw_if_index = ~0;
19271   u8 *tag = 0;
19272   u8 enable = 1;
19273   int ret;
19274
19275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19276     {
19277       if (unformat (i, "tag %s", &tag))
19278         ;
19279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19280         ;
19281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19282         ;
19283       else if (unformat (i, "del"))
19284         enable = 0;
19285       else
19286         break;
19287     }
19288
19289   if (sw_if_index == ~0)
19290     {
19291       errmsg ("missing interface name or sw_if_index");
19292       return -99;
19293     }
19294
19295   if (enable && (tag == 0))
19296     {
19297       errmsg ("no tag specified");
19298       return -99;
19299     }
19300
19301   /* Construct the API message */
19302   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19303   mp->sw_if_index = ntohl (sw_if_index);
19304   mp->is_add = enable;
19305   if (enable)
19306     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19307   vec_free (tag);
19308
19309   S (mp);
19310   W (ret);
19311   return ret;
19312 }
19313
19314 static void vl_api_l2_xconnect_details_t_handler
19315   (vl_api_l2_xconnect_details_t * mp)
19316 {
19317   vat_main_t *vam = &vat_main;
19318
19319   print (vam->ofp, "%15d%15d",
19320          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19321 }
19322
19323 static void vl_api_l2_xconnect_details_t_handler_json
19324   (vl_api_l2_xconnect_details_t * mp)
19325 {
19326   vat_main_t *vam = &vat_main;
19327   vat_json_node_t *node = NULL;
19328
19329   if (VAT_JSON_ARRAY != vam->json_tree.type)
19330     {
19331       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19332       vat_json_init_array (&vam->json_tree);
19333     }
19334   node = vat_json_array_add (&vam->json_tree);
19335
19336   vat_json_init_object (node);
19337   vat_json_object_add_uint (node, "rx_sw_if_index",
19338                             ntohl (mp->rx_sw_if_index));
19339   vat_json_object_add_uint (node, "tx_sw_if_index",
19340                             ntohl (mp->tx_sw_if_index));
19341 }
19342
19343 static int
19344 api_l2_xconnect_dump (vat_main_t * vam)
19345 {
19346   vl_api_l2_xconnect_dump_t *mp;
19347   vl_api_control_ping_t *mp_ping;
19348   int ret;
19349
19350   if (!vam->json_output)
19351     {
19352       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19353     }
19354
19355   M (L2_XCONNECT_DUMP, mp);
19356
19357   S (mp);
19358
19359   /* Use a control ping for synchronization */
19360   M (CONTROL_PING, mp_ping);
19361   S (mp_ping);
19362
19363   W (ret);
19364   return ret;
19365 }
19366
19367 static int
19368 api_sw_interface_set_mtu (vat_main_t * vam)
19369 {
19370   unformat_input_t *i = vam->input;
19371   vl_api_sw_interface_set_mtu_t *mp;
19372   u32 sw_if_index = ~0;
19373   u32 mtu = 0;
19374   int ret;
19375
19376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19377     {
19378       if (unformat (i, "mtu %d", &mtu))
19379         ;
19380       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19381         ;
19382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19383         ;
19384       else
19385         break;
19386     }
19387
19388   if (sw_if_index == ~0)
19389     {
19390       errmsg ("missing interface name or sw_if_index");
19391       return -99;
19392     }
19393
19394   if (mtu == 0)
19395     {
19396       errmsg ("no mtu specified");
19397       return -99;
19398     }
19399
19400   /* Construct the API message */
19401   M (SW_INTERFACE_SET_MTU, mp);
19402   mp->sw_if_index = ntohl (sw_if_index);
19403   mp->mtu = ntohs ((u16) mtu);
19404
19405   S (mp);
19406   W (ret);
19407   return ret;
19408 }
19409
19410 static int
19411 api_p2p_ethernet_add (vat_main_t * vam)
19412 {
19413   unformat_input_t *i = vam->input;
19414   vl_api_p2p_ethernet_add_t *mp;
19415   u32 parent_if_index = ~0;
19416   u32 sub_id = ~0;
19417   u8 remote_mac[6];
19418   u8 mac_set = 0;
19419   int ret;
19420
19421   memset (remote_mac, 0, sizeof (remote_mac));
19422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19423     {
19424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19425         ;
19426       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19427         ;
19428       else
19429         if (unformat
19430             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19431         mac_set++;
19432       else if (unformat (i, "sub_id %d", &sub_id))
19433         ;
19434       else
19435         {
19436           clib_warning ("parse error '%U'", format_unformat_error, i);
19437           return -99;
19438         }
19439     }
19440
19441   if (parent_if_index == ~0)
19442     {
19443       errmsg ("missing interface name or sw_if_index");
19444       return -99;
19445     }
19446   if (mac_set == 0)
19447     {
19448       errmsg ("missing remote mac address");
19449       return -99;
19450     }
19451   if (sub_id == ~0)
19452     {
19453       errmsg ("missing sub-interface id");
19454       return -99;
19455     }
19456
19457   M (P2P_ETHERNET_ADD, mp);
19458   mp->parent_if_index = ntohl (parent_if_index);
19459   mp->subif_id = ntohl (sub_id);
19460   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19461
19462   S (mp);
19463   W (ret);
19464   return ret;
19465 }
19466
19467 static int
19468 api_p2p_ethernet_del (vat_main_t * vam)
19469 {
19470   unformat_input_t *i = vam->input;
19471   vl_api_p2p_ethernet_del_t *mp;
19472   u32 parent_if_index = ~0;
19473   u8 remote_mac[6];
19474   u8 mac_set = 0;
19475   int ret;
19476
19477   memset (remote_mac, 0, sizeof (remote_mac));
19478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19479     {
19480       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19481         ;
19482       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19483         ;
19484       else
19485         if (unformat
19486             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19487         mac_set++;
19488       else
19489         {
19490           clib_warning ("parse error '%U'", format_unformat_error, i);
19491           return -99;
19492         }
19493     }
19494
19495   if (parent_if_index == ~0)
19496     {
19497       errmsg ("missing interface name or sw_if_index");
19498       return -99;
19499     }
19500   if (mac_set == 0)
19501     {
19502       errmsg ("missing remote mac address");
19503       return -99;
19504     }
19505
19506   M (P2P_ETHERNET_DEL, mp);
19507   mp->parent_if_index = ntohl (parent_if_index);
19508   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19509
19510   S (mp);
19511   W (ret);
19512   return ret;
19513 }
19514
19515 static int
19516 api_lldp_config (vat_main_t * vam)
19517 {
19518   unformat_input_t *i = vam->input;
19519   vl_api_lldp_config_t *mp;
19520   int tx_hold = 0;
19521   int tx_interval = 0;
19522   u8 *sys_name = NULL;
19523   int ret;
19524
19525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19526     {
19527       if (unformat (i, "system-name %s", &sys_name))
19528         ;
19529       else if (unformat (i, "tx-hold %d", &tx_hold))
19530         ;
19531       else if (unformat (i, "tx-interval %d", &tx_interval))
19532         ;
19533       else
19534         {
19535           clib_warning ("parse error '%U'", format_unformat_error, i);
19536           return -99;
19537         }
19538     }
19539
19540   vec_add1 (sys_name, 0);
19541
19542   M (LLDP_CONFIG, mp);
19543   mp->tx_hold = htonl (tx_hold);
19544   mp->tx_interval = htonl (tx_interval);
19545   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19546   vec_free (sys_name);
19547
19548   S (mp);
19549   W (ret);
19550   return ret;
19551 }
19552
19553 static int
19554 api_sw_interface_set_lldp (vat_main_t * vam)
19555 {
19556   unformat_input_t *i = vam->input;
19557   vl_api_sw_interface_set_lldp_t *mp;
19558   u32 sw_if_index = ~0;
19559   u32 enable = 1;
19560   u8 *port_desc = NULL;
19561   int ret;
19562
19563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19564     {
19565       if (unformat (i, "disable"))
19566         enable = 0;
19567       else
19568         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19569         ;
19570       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19571         ;
19572       else if (unformat (i, "port-desc %s", &port_desc))
19573         ;
19574       else
19575         break;
19576     }
19577
19578   if (sw_if_index == ~0)
19579     {
19580       errmsg ("missing interface name or sw_if_index");
19581       return -99;
19582     }
19583
19584   /* Construct the API message */
19585   vec_add1 (port_desc, 0);
19586   M (SW_INTERFACE_SET_LLDP, mp);
19587   mp->sw_if_index = ntohl (sw_if_index);
19588   mp->enable = enable;
19589   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19590   vec_free (port_desc);
19591
19592   S (mp);
19593   W (ret);
19594   return ret;
19595 }
19596
19597 static int
19598 q_or_quit (vat_main_t * vam)
19599 {
19600 #if VPP_API_TEST_BUILTIN == 0
19601   longjmp (vam->jump_buf, 1);
19602 #endif
19603   return 0;                     /* not so much */
19604 }
19605
19606 static int
19607 q (vat_main_t * vam)
19608 {
19609   return q_or_quit (vam);
19610 }
19611
19612 static int
19613 quit (vat_main_t * vam)
19614 {
19615   return q_or_quit (vam);
19616 }
19617
19618 static int
19619 comment (vat_main_t * vam)
19620 {
19621   return 0;
19622 }
19623
19624 static int
19625 cmd_cmp (void *a1, void *a2)
19626 {
19627   u8 **c1 = a1;
19628   u8 **c2 = a2;
19629
19630   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19631 }
19632
19633 static int
19634 help (vat_main_t * vam)
19635 {
19636   u8 **cmds = 0;
19637   u8 *name = 0;
19638   hash_pair_t *p;
19639   unformat_input_t *i = vam->input;
19640   int j;
19641
19642   if (unformat (i, "%s", &name))
19643     {
19644       uword *hs;
19645
19646       vec_add1 (name, 0);
19647
19648       hs = hash_get_mem (vam->help_by_name, name);
19649       if (hs)
19650         print (vam->ofp, "usage: %s %s", name, hs[0]);
19651       else
19652         print (vam->ofp, "No such msg / command '%s'", name);
19653       vec_free (name);
19654       return 0;
19655     }
19656
19657   print (vam->ofp, "Help is available for the following:");
19658
19659     /* *INDENT-OFF* */
19660     hash_foreach_pair (p, vam->function_by_name,
19661     ({
19662       vec_add1 (cmds, (u8 *)(p->key));
19663     }));
19664     /* *INDENT-ON* */
19665
19666   vec_sort_with_function (cmds, cmd_cmp);
19667
19668   for (j = 0; j < vec_len (cmds); j++)
19669     print (vam->ofp, "%s", cmds[j]);
19670
19671   vec_free (cmds);
19672   return 0;
19673 }
19674
19675 static int
19676 set (vat_main_t * vam)
19677 {
19678   u8 *name = 0, *value = 0;
19679   unformat_input_t *i = vam->input;
19680
19681   if (unformat (i, "%s", &name))
19682     {
19683       /* The input buffer is a vector, not a string. */
19684       value = vec_dup (i->buffer);
19685       vec_delete (value, i->index, 0);
19686       /* Almost certainly has a trailing newline */
19687       if (value[vec_len (value) - 1] == '\n')
19688         value[vec_len (value) - 1] = 0;
19689       /* Make sure it's a proper string, one way or the other */
19690       vec_add1 (value, 0);
19691       (void) clib_macro_set_value (&vam->macro_main,
19692                                    (char *) name, (char *) value);
19693     }
19694   else
19695     errmsg ("usage: set <name> <value>");
19696
19697   vec_free (name);
19698   vec_free (value);
19699   return 0;
19700 }
19701
19702 static int
19703 unset (vat_main_t * vam)
19704 {
19705   u8 *name = 0;
19706
19707   if (unformat (vam->input, "%s", &name))
19708     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19709       errmsg ("unset: %s wasn't set", name);
19710   vec_free (name);
19711   return 0;
19712 }
19713
19714 typedef struct
19715 {
19716   u8 *name;
19717   u8 *value;
19718 } macro_sort_t;
19719
19720
19721 static int
19722 macro_sort_cmp (void *a1, void *a2)
19723 {
19724   macro_sort_t *s1 = a1;
19725   macro_sort_t *s2 = a2;
19726
19727   return strcmp ((char *) (s1->name), (char *) (s2->name));
19728 }
19729
19730 static int
19731 dump_macro_table (vat_main_t * vam)
19732 {
19733   macro_sort_t *sort_me = 0, *sm;
19734   int i;
19735   hash_pair_t *p;
19736
19737     /* *INDENT-OFF* */
19738     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19739     ({
19740       vec_add2 (sort_me, sm, 1);
19741       sm->name = (u8 *)(p->key);
19742       sm->value = (u8 *) (p->value[0]);
19743     }));
19744     /* *INDENT-ON* */
19745
19746   vec_sort_with_function (sort_me, macro_sort_cmp);
19747
19748   if (vec_len (sort_me))
19749     print (vam->ofp, "%-15s%s", "Name", "Value");
19750   else
19751     print (vam->ofp, "The macro table is empty...");
19752
19753   for (i = 0; i < vec_len (sort_me); i++)
19754     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19755   return 0;
19756 }
19757
19758 static int
19759 dump_node_table (vat_main_t * vam)
19760 {
19761   int i, j;
19762   vlib_node_t *node, *next_node;
19763
19764   if (vec_len (vam->graph_nodes) == 0)
19765     {
19766       print (vam->ofp, "Node table empty, issue get_node_graph...");
19767       return 0;
19768     }
19769
19770   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19771     {
19772       node = vam->graph_nodes[i];
19773       print (vam->ofp, "[%d] %s", i, node->name);
19774       for (j = 0; j < vec_len (node->next_nodes); j++)
19775         {
19776           if (node->next_nodes[j] != ~0)
19777             {
19778               next_node = vam->graph_nodes[node->next_nodes[j]];
19779               print (vam->ofp, "  [%d] %s", j, next_node->name);
19780             }
19781         }
19782     }
19783   return 0;
19784 }
19785
19786 static int
19787 value_sort_cmp (void *a1, void *a2)
19788 {
19789   name_sort_t *n1 = a1;
19790   name_sort_t *n2 = a2;
19791
19792   if (n1->value < n2->value)
19793     return -1;
19794   if (n1->value > n2->value)
19795     return 1;
19796   return 0;
19797 }
19798
19799
19800 static int
19801 dump_msg_api_table (vat_main_t * vam)
19802 {
19803   api_main_t *am = &api_main;
19804   name_sort_t *nses = 0, *ns;
19805   hash_pair_t *hp;
19806   int i;
19807
19808   /* *INDENT-OFF* */
19809   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19810   ({
19811     vec_add2 (nses, ns, 1);
19812     ns->name = (u8 *)(hp->key);
19813     ns->value = (u32) hp->value[0];
19814   }));
19815   /* *INDENT-ON* */
19816
19817   vec_sort_with_function (nses, value_sort_cmp);
19818
19819   for (i = 0; i < vec_len (nses); i++)
19820     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19821   vec_free (nses);
19822   return 0;
19823 }
19824
19825 static int
19826 get_msg_id (vat_main_t * vam)
19827 {
19828   u8 *name_and_crc;
19829   u32 message_index;
19830
19831   if (unformat (vam->input, "%s", &name_and_crc))
19832     {
19833       message_index = vl_api_get_msg_index (name_and_crc);
19834       if (message_index == ~0)
19835         {
19836           print (vam->ofp, " '%s' not found", name_and_crc);
19837           return 0;
19838         }
19839       print (vam->ofp, " '%s' has message index %d",
19840              name_and_crc, message_index);
19841       return 0;
19842     }
19843   errmsg ("name_and_crc required...");
19844   return 0;
19845 }
19846
19847 static int
19848 search_node_table (vat_main_t * vam)
19849 {
19850   unformat_input_t *line_input = vam->input;
19851   u8 *node_to_find;
19852   int j;
19853   vlib_node_t *node, *next_node;
19854   uword *p;
19855
19856   if (vam->graph_node_index_by_name == 0)
19857     {
19858       print (vam->ofp, "Node table empty, issue get_node_graph...");
19859       return 0;
19860     }
19861
19862   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19863     {
19864       if (unformat (line_input, "%s", &node_to_find))
19865         {
19866           vec_add1 (node_to_find, 0);
19867           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19868           if (p == 0)
19869             {
19870               print (vam->ofp, "%s not found...", node_to_find);
19871               goto out;
19872             }
19873           node = vam->graph_nodes[p[0]];
19874           print (vam->ofp, "[%d] %s", p[0], node->name);
19875           for (j = 0; j < vec_len (node->next_nodes); j++)
19876             {
19877               if (node->next_nodes[j] != ~0)
19878                 {
19879                   next_node = vam->graph_nodes[node->next_nodes[j]];
19880                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19881                 }
19882             }
19883         }
19884
19885       else
19886         {
19887           clib_warning ("parse error '%U'", format_unformat_error,
19888                         line_input);
19889           return -99;
19890         }
19891
19892     out:
19893       vec_free (node_to_find);
19894
19895     }
19896
19897   return 0;
19898 }
19899
19900
19901 static int
19902 script (vat_main_t * vam)
19903 {
19904 #if (VPP_API_TEST_BUILTIN==0)
19905   u8 *s = 0;
19906   char *save_current_file;
19907   unformat_input_t save_input;
19908   jmp_buf save_jump_buf;
19909   u32 save_line_number;
19910
19911   FILE *new_fp, *save_ifp;
19912
19913   if (unformat (vam->input, "%s", &s))
19914     {
19915       new_fp = fopen ((char *) s, "r");
19916       if (new_fp == 0)
19917         {
19918           errmsg ("Couldn't open script file %s", s);
19919           vec_free (s);
19920           return -99;
19921         }
19922     }
19923   else
19924     {
19925       errmsg ("Missing script name");
19926       return -99;
19927     }
19928
19929   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19930   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19931   save_ifp = vam->ifp;
19932   save_line_number = vam->input_line_number;
19933   save_current_file = (char *) vam->current_file;
19934
19935   vam->input_line_number = 0;
19936   vam->ifp = new_fp;
19937   vam->current_file = s;
19938   do_one_file (vam);
19939
19940   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19941   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19942   vam->ifp = save_ifp;
19943   vam->input_line_number = save_line_number;
19944   vam->current_file = (u8 *) save_current_file;
19945   vec_free (s);
19946
19947   return 0;
19948 #else
19949   clib_warning ("use the exec command...");
19950   return -99;
19951 #endif
19952 }
19953
19954 static int
19955 echo (vat_main_t * vam)
19956 {
19957   print (vam->ofp, "%v", vam->input->buffer);
19958   return 0;
19959 }
19960
19961 /* List of API message constructors, CLI names map to api_xxx */
19962 #define foreach_vpe_api_msg                                             \
19963 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19964 _(sw_interface_dump,"")                                                 \
19965 _(sw_interface_set_flags,                                               \
19966   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19967 _(sw_interface_add_del_address,                                         \
19968   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19969 _(sw_interface_set_table,                                               \
19970   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19971 _(sw_interface_set_mpls_enable,                                         \
19972   "<intfc> | sw_if_index [disable | dis]")                              \
19973 _(sw_interface_set_vpath,                                               \
19974   "<intfc> | sw_if_index <id> enable | disable")                        \
19975 _(sw_interface_set_vxlan_bypass,                                        \
19976   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19977 _(sw_interface_set_l2_xconnect,                                         \
19978   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19979   "enable | disable")                                                   \
19980 _(sw_interface_set_l2_bridge,                                           \
19981   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19982   "[shg <split-horizon-group>] [bvi]\n"                                 \
19983   "enable | disable")                                                   \
19984 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19985 _(bridge_domain_add_del,                                                \
19986   "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") \
19987 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19988 _(l2fib_add_del,                                                        \
19989   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19990 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19991 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19992 _(l2_flags,                                                             \
19993   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19994 _(bridge_flags,                                                         \
19995   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19996 _(tap_connect,                                                          \
19997   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19998 _(tap_modify,                                                           \
19999   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20000 _(tap_delete,                                                           \
20001   "<vpp-if-name> | sw_if_index <id>")                                   \
20002 _(sw_interface_tap_dump, "")                                            \
20003 _(ip_add_del_route,                                                     \
20004   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20005   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20006   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20007   "[multipath] [count <n>]")                                            \
20008 _(ip_mroute_add_del,                                                    \
20009   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20010   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20011 _(mpls_route_add_del,                                                   \
20012   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20013   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20014   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20015   "[multipath] [count <n>]")                                            \
20016 _(mpls_ip_bind_unbind,                                                  \
20017   "<label> <addr/len>")                                                 \
20018 _(mpls_tunnel_add_del,                                                  \
20019   " via <addr> [table-id <n>]\n"                                        \
20020   "sw_if_index <id>] [l2]  [del]")                                      \
20021 _(proxy_arp_add_del,                                                    \
20022   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20023 _(proxy_arp_intfc_enable_disable,                                       \
20024   "<intfc> | sw_if_index <id> enable | disable")                        \
20025 _(sw_interface_set_unnumbered,                                          \
20026   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20027 _(ip_neighbor_add_del,                                                  \
20028   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20029   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20030 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20031 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20032 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20033   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20034   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20035   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20036 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20037 _(reset_fib, "vrf <n> [ipv6]")                                          \
20038 _(dhcp_proxy_config,                                                    \
20039   "svr <v46-address> src <v46-address>\n"                               \
20040    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20041 _(dhcp_proxy_set_vss,                                                   \
20042   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20043 _(dhcp_proxy_dump, "ip6")                                               \
20044 _(dhcp_client_config,                                                   \
20045   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20046 _(set_ip_flow_hash,                                                     \
20047   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20048 _(sw_interface_ip6_enable_disable,                                      \
20049   "<intfc> | sw_if_index <id> enable | disable")                        \
20050 _(sw_interface_ip6_set_link_local_address,                              \
20051   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20052 _(ip6nd_proxy_add_del,                                                  \
20053   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20054 _(ip6nd_proxy_dump, "")                                                 \
20055 _(sw_interface_ip6nd_ra_prefix,                                         \
20056   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20057   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20058   "[nolink] [isno]")                                                    \
20059 _(sw_interface_ip6nd_ra_config,                                         \
20060   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20061   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20062   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20063 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20064 _(l2_patch_add_del,                                                     \
20065   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20066   "enable | disable")                                                   \
20067 _(sr_localsid_add_del,                                                  \
20068   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20069   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20070 _(classify_add_del_table,                                               \
20071   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20072   " [del] [del-chain] mask <mask-value>\n"                              \
20073   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20074   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20075 _(classify_add_del_session,                                             \
20076   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20077   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20078   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20079   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20080 _(classify_set_interface_ip_table,                                      \
20081   "<intfc> | sw_if_index <nn> table <nn>")                              \
20082 _(classify_set_interface_l2_tables,                                     \
20083   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20084   "  [other-table <nn>]")                                               \
20085 _(get_node_index, "node <node-name")                                    \
20086 _(add_node_next, "node <node-name> next <next-node-name>")              \
20087 _(l2tpv3_create_tunnel,                                                 \
20088   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20089   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20090   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20091 _(l2tpv3_set_tunnel_cookies,                                            \
20092   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20093   "[new_remote_cookie <nn>]\n")                                         \
20094 _(l2tpv3_interface_enable_disable,                                      \
20095   "<intfc> | sw_if_index <nn> enable | disable")                        \
20096 _(l2tpv3_set_lookup_key,                                                \
20097   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20098 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20099 _(vxlan_add_del_tunnel,                                                 \
20100   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20101   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20102   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20103 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20104 _(gre_add_del_tunnel,                                                   \
20105   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20106 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20107 _(l2_fib_clear_table, "")                                               \
20108 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20109 _(l2_interface_vlan_tag_rewrite,                                        \
20110   "<intfc> | sw_if_index <nn> \n"                                       \
20111   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20112   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20113 _(create_vhost_user_if,                                                 \
20114         "socket <filename> [server] [renumber <dev_instance>] "         \
20115         "[mac <mac_address>]")                                          \
20116 _(modify_vhost_user_if,                                                 \
20117         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20118         "[server] [renumber <dev_instance>]")                           \
20119 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20120 _(sw_interface_vhost_user_dump, "")                                     \
20121 _(show_version, "")                                                     \
20122 _(vxlan_gpe_add_del_tunnel,                                             \
20123   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20124   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20125   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20126   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20127 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20128 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20129 _(interface_name_renumber,                                              \
20130   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20131 _(input_acl_set_interface,                                              \
20132   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20133   "  [l2-table <nn>] [del]")                                            \
20134 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20135 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20136 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20137 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20138 _(ip_dump, "ipv4 | ipv6")                                               \
20139 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20140 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20141   "  spid_id <n> ")                                                     \
20142 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20143   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20144   "  integ_alg <alg> integ_key <hex>")                                  \
20145 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20146   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20147   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20148   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20149 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20150 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20151   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20152   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20153   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20154 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20155 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20156   "(auth_data 0x<data> | auth_data <data>)")                            \
20157 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20158   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20159 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20160   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20161   "(local|remote)")                                                     \
20162 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20163 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20164 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20165 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20166 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20167 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20168 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20169 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20170 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20171 _(delete_loopback,"sw_if_index <nn>")                                   \
20172 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20173 _(map_add_domain,                                                       \
20174   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20175   "ip6-src <ip6addr> "                                                  \
20176   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20177 _(map_del_domain, "index <n>")                                          \
20178 _(map_add_del_rule,                                                     \
20179   "index <n> psid <n> dst <ip6addr> [del]")                             \
20180 _(map_domain_dump, "")                                                  \
20181 _(map_rule_dump, "index <map-domain>")                                  \
20182 _(want_interface_events,  "enable|disable")                             \
20183 _(want_stats,"enable|disable")                                          \
20184 _(get_first_msg_id, "client <name>")                                    \
20185 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20186 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20187   "fib-id <nn> [ip4][ip6][default]")                                    \
20188 _(get_node_graph, " ")                                                  \
20189 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20190 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20191 _(ioam_disable, "")                                                     \
20192 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20193                             " sw_if_index <sw_if_index> p <priority> "  \
20194                             "w <weight>] [del]")                        \
20195 _(one_add_del_locator, "locator-set <locator_name> "                    \
20196                         "iface <intf> | sw_if_index <sw_if_index> "     \
20197                         "p <priority> w <weight> [del]")                \
20198 _(one_add_del_local_eid,"vni <vni> eid "                                \
20199                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20200                          "locator-set <locator_name> [del]"             \
20201                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20202 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20203 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20204 _(one_enable_disable, "enable|disable")                                 \
20205 _(one_map_register_enable_disable, "enable|disable")                    \
20206 _(one_map_register_fallback_threshold, "<value>")                       \
20207 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20208 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20209                                "[seid <seid>] "                         \
20210                                "rloc <locator> p <prio> "               \
20211                                "w <weight> [rloc <loc> ... ] "          \
20212                                "action <action> [del-all]")             \
20213 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20214                           "<local-eid>")                                \
20215 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20216 _(one_use_petr, "ip-address> | disable")                                \
20217 _(one_map_request_mode, "src-dst|dst-only")                             \
20218 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20219 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20220 _(one_locator_set_dump, "[local | remote]")                             \
20221 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20222 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20223                        "[local] | [remote]")                            \
20224 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20225 _(one_l2_arp_bd_get, "")                                                \
20226 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20227 _(one_stats_enable_disable, "enable|disalbe")                           \
20228 _(show_one_stats_enable_disable, "")                                    \
20229 _(one_eid_table_vni_dump, "")                                           \
20230 _(one_eid_table_map_dump, "l2|l3")                                      \
20231 _(one_map_resolver_dump, "")                                            \
20232 _(one_map_server_dump, "")                                              \
20233 _(one_adjacencies_get, "vni <vni>")                                     \
20234 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20235 _(show_one_rloc_probe_state, "")                                        \
20236 _(show_one_map_register_state, "")                                      \
20237 _(show_one_status, "")                                                  \
20238 _(one_stats_dump, "")                                                   \
20239 _(one_stats_flush, "")                                                  \
20240 _(one_get_map_request_itr_rlocs, "")                                    \
20241 _(one_map_register_set_ttl, "<ttl>")                                    \
20242 _(show_one_nsh_mapping, "")                                             \
20243 _(show_one_pitr, "")                                                    \
20244 _(show_one_use_petr, "")                                                \
20245 _(show_one_map_request_mode, "")                                        \
20246 _(show_one_map_register_ttl, "")                                        \
20247 _(show_one_map_register_fallback_threshold, "")                         \
20248 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20249                             " sw_if_index <sw_if_index> p <priority> "  \
20250                             "w <weight>] [del]")                        \
20251 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20252                         "iface <intf> | sw_if_index <sw_if_index> "     \
20253                         "p <priority> w <weight> [del]")                \
20254 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20255                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20256                          "locator-set <locator_name> [del]"             \
20257                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20258 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20259 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20260 _(lisp_enable_disable, "enable|disable")                                \
20261 _(lisp_map_register_enable_disable, "enable|disable")                   \
20262 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20263 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20264                                "[seid <seid>] "                         \
20265                                "rloc <locator> p <prio> "               \
20266                                "w <weight> [rloc <loc> ... ] "          \
20267                                "action <action> [del-all]")             \
20268 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20269                           "<local-eid>")                                \
20270 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20271 _(lisp_use_petr, "<ip-address> | disable")                              \
20272 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20273 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20274 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20275 _(lisp_locator_set_dump, "[local | remote]")                            \
20276 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20277 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20278                        "[local] | [remote]")                            \
20279 _(lisp_eid_table_vni_dump, "")                                          \
20280 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20281 _(lisp_map_resolver_dump, "")                                           \
20282 _(lisp_map_server_dump, "")                                             \
20283 _(lisp_adjacencies_get, "vni <vni>")                                    \
20284 _(gpe_fwd_entry_vnis_get, "")                                           \
20285 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20286 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20287                                 "[table <table-id>]")                   \
20288 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20289 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20290 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20291 _(gpe_get_encap_mode, "")                                               \
20292 _(lisp_gpe_add_del_iface, "up|down")                                    \
20293 _(lisp_gpe_enable_disable, "enable|disable")                            \
20294 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20295   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20296 _(show_lisp_rloc_probe_state, "")                                       \
20297 _(show_lisp_map_register_state, "")                                     \
20298 _(show_lisp_status, "")                                                 \
20299 _(lisp_get_map_request_itr_rlocs, "")                                   \
20300 _(show_lisp_pitr, "")                                                   \
20301 _(show_lisp_use_petr, "")                                               \
20302 _(show_lisp_map_request_mode, "")                                       \
20303 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20304 _(af_packet_delete, "name <host interface name>")                       \
20305 _(policer_add_del, "name <policer name> <params> [del]")                \
20306 _(policer_dump, "[name <policer name>]")                                \
20307 _(policer_classify_set_interface,                                       \
20308   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20309   "  [l2-table <nn>] [del]")                                            \
20310 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20311 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20312     "[master|slave]")                                                   \
20313 _(netmap_delete, "name <interface name>")                               \
20314 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20315 _(mpls_fib_dump, "")                                                    \
20316 _(classify_table_ids, "")                                               \
20317 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20318 _(classify_table_info, "table_id <nn>")                                 \
20319 _(classify_session_dump, "table_id <nn>")                               \
20320 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20321     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20322     "[template_interval <nn>] [udp_checksum]")                          \
20323 _(ipfix_exporter_dump, "")                                              \
20324 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20325 _(ipfix_classify_stream_dump, "")                                       \
20326 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20327 _(ipfix_classify_table_dump, "")                                        \
20328 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20329 _(sw_interface_span_dump, "[l2]")                                           \
20330 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20331 _(pg_create_interface, "if_id <nn>")                                    \
20332 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20333 _(pg_enable_disable, "[stream <id>] disable")                           \
20334 _(ip_source_and_port_range_check_add_del,                               \
20335   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20336 _(ip_source_and_port_range_check_interface_add_del,                     \
20337   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20338   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20339 _(ipsec_gre_add_del_tunnel,                                             \
20340   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20341 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20342 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20343 _(l2_interface_pbb_tag_rewrite,                                         \
20344   "<intfc> | sw_if_index <nn> \n"                                       \
20345   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20346   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20347 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20348 _(flow_classify_set_interface,                                          \
20349   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20350 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20351 _(ip_fib_dump, "")                                                      \
20352 _(ip_mfib_dump, "")                                                     \
20353 _(ip6_fib_dump, "")                                                     \
20354 _(ip6_mfib_dump, "")                                                    \
20355 _(feature_enable_disable, "arc_name <arc_name> "                        \
20356   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20357 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20358 "[disable]")                                                            \
20359 _(l2_xconnect_dump, "")                                                 \
20360 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20361 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20362 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20363 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20364 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20365 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20366 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]")
20367
20368 /* List of command functions, CLI names map directly to functions */
20369 #define foreach_cli_function                                    \
20370 _(comment, "usage: comment <ignore-rest-of-line>")              \
20371 _(dump_interface_table, "usage: dump_interface_table")          \
20372 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20373 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20374 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20375 _(dump_stats_table, "usage: dump_stats_table")                  \
20376 _(dump_macro_table, "usage: dump_macro_table ")                 \
20377 _(dump_node_table, "usage: dump_node_table")                    \
20378 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20379 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20380 _(echo, "usage: echo <message>")                                \
20381 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20382 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20383 _(help, "usage: help")                                          \
20384 _(q, "usage: quit")                                             \
20385 _(quit, "usage: quit")                                          \
20386 _(search_node_table, "usage: search_node_table <name>...")      \
20387 _(set, "usage: set <variable-name> <value>")                    \
20388 _(script, "usage: script <file-name>")                          \
20389 _(unset, "usage: unset <variable-name>")
20390 #define _(N,n)                                  \
20391     static void vl_api_##n##_t_handler_uni      \
20392     (vl_api_##n##_t * mp)                       \
20393     {                                           \
20394         vat_main_t * vam = &vat_main;           \
20395         if (vam->json_output) {                 \
20396             vl_api_##n##_t_handler_json(mp);    \
20397         } else {                                \
20398             vl_api_##n##_t_handler(mp);         \
20399         }                                       \
20400     }
20401 foreach_vpe_api_reply_msg;
20402 #if VPP_API_TEST_BUILTIN == 0
20403 foreach_standalone_reply_msg;
20404 #endif
20405 #undef _
20406
20407 void
20408 vat_api_hookup (vat_main_t * vam)
20409 {
20410 #define _(N,n)                                                  \
20411     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20412                            vl_api_##n##_t_handler_uni,          \
20413                            vl_noop_handler,                     \
20414                            vl_api_##n##_t_endian,               \
20415                            vl_api_##n##_t_print,                \
20416                            sizeof(vl_api_##n##_t), 1);
20417   foreach_vpe_api_reply_msg;
20418 #if VPP_API_TEST_BUILTIN == 0
20419   foreach_standalone_reply_msg;
20420 #endif
20421 #undef _
20422
20423 #if (VPP_API_TEST_BUILTIN==0)
20424   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20425
20426   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20427
20428   vam->function_by_name = hash_create_string (0, sizeof (uword));
20429
20430   vam->help_by_name = hash_create_string (0, sizeof (uword));
20431 #endif
20432
20433   /* API messages we can send */
20434 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20435   foreach_vpe_api_msg;
20436 #undef _
20437
20438   /* Help strings */
20439 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20440   foreach_vpe_api_msg;
20441 #undef _
20442
20443   /* CLI functions */
20444 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20445   foreach_cli_function;
20446 #undef _
20447
20448   /* Help strings */
20449 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20450   foreach_cli_function;
20451 #undef _
20452 }
20453
20454 #if VPP_API_TEST_BUILTIN
20455 static clib_error_t *
20456 vat_api_hookup_shim (vlib_main_t * vm)
20457 {
20458   vat_api_hookup (&vat_main);
20459   return 0;
20460 }
20461
20462 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20463 #endif
20464
20465 /*
20466  * fd.io coding-style-patch-verification: ON
20467  *
20468  * Local Variables:
20469  * eval: (c-set-style "gnu")
20470  * End:
20471  */